Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change keyboard layout #10

Closed
matzeeg3 opened this issue Aug 27, 2021 · 35 comments · Fixed by #30
Closed

change keyboard layout #10

matzeeg3 opened this issue Aug 27, 2021 · 35 comments · Fixed by #30

Comments

@matzeeg3
Copy link

hi there,
i try to use it and until now i liked it a lot.
but i have an issue. i have to setup a different keyboard layout.
hope someone can help i this case.
thanks a lot
kind regards
matze

@peterfritz
Copy link
Contributor

peterfritz commented Aug 27, 2021

Hi, there's quite a lot regarding keyboard layouts happening in the HID module used by this project. In pull request #61 of the Adafruit CircuitPython HID module, @AngainorDev is trying to make it easier to add more keyboard layouts without increasing too much the bundle size for it to remain compatible with boards that have a smaller flash memory.
As soon as they approve the PR, the pico-ducky code will be able to easily accept other languages.

I encourage you take a look at his PR and keyboard layout code and maybe, while you're at it, start messing around to figure out how to create one for your language 😉

@Neradoc
Copy link
Contributor

Neradoc commented Aug 29, 2021

I started a repository of keyboard layouts, which is now the preferred way of adding layouts.
This sits here: https://github.com/Neradoc/Circuitpython_Keyboard_Layouts

I am experimenting with an online automated generator (for windows layouts), if you want to try: [removed, it's broken]

Or feel free to open an issue on the layout repo, or ask me on the Adafruit discord #help-with-circuitpython (no PM) - I've already seen a few people using pico-ducky ask the same question over there.

@lucas2kdk
Copy link

Anyone got a solution for a Danish keyboard?

@matzeeg3
Copy link
Author

I started a repository of keyboard layouts, which is now the preferred way of adding layouts.
This sits here: https://github.com/Neradoc/Circuitpython_Keyboard_Layouts

I am experimenting with an online automated generator (for windows layouts), if you want to try:
https://www.neradoc.me/layouts/

Or feel free to open an issue on the layout repo, or ask me on the Adafruit discord #help-with-circuitpython (no PM) - I've already seen a few people using pico-ducky ask the same question over there.

i tryed the online generator but it did not work

@Neradoc
Copy link
Contributor

Neradoc commented Sep 1, 2021

Oh yeah the page is easily defeated by browser security rules that stop it from downloading the layout file from kbdlayout.info. I completely forgot that. I could make a server-side version of the script on the page, but I have concerns with security. I should remove the link, sorry.

The idea is rather to make them myself with a python script I'm working on and add them to the layout repo as people request them. But first I want to have a good enough version of the generator, so I don't have to give a pass to all of the files later, especially if they have hand-made fixes. At least not too soon.

Right now, it doesn't handle dead/composite keys very well (having write("ô") type ^ then o).

It would be better to ask about layouts over there:
https://github.com/Neradoc/Circuitpython_Keyboard_Layouts

Here is the danish version. @lucas2kdk
da-layout.zip

You put the files into the board's CIRCUITPY or its lib directory.
You then need to modify the ducky code as follows with the correct language files.
Change this:

from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

to this (note the language part of the module names)

from keyboard_layout_win_da import KeyboardLayout
from keycode_win_da import Keycode

And this:

layout = KeyboardLayoutUS(kbd)

to this:

layout = KeyboardLayout(kbd)

@NadSeries
Copy link

It will be great if you could provide an italian keyboard layout for the pico ducky

@magnificent3
Copy link

Does anyone have a Portuguese layout?

@dbisu
Copy link
Owner

dbisu commented Sep 5, 2021

I have pushed a branch, Kronos, as a test for German keyboard layout.
Also, I think based on the site http://kbdlayout.info/ it should be possible to create other keyboard layout/scan code support.

@Neradoc
Copy link
Contributor

Neradoc commented Sep 5, 2021

Yeah it is possible, and I fixed the page for the javascript error: https://www.neradoc.me/layouts/

You can try it locally from that branch, though you'll need to know your way around python and shell scripts a little. Look at tests/make_validated.sh for usage. I should merge all that in the layout repository as well as a bunch of keyboard layouts that I made with it as they were requested and tested at least a bit by users. (Mostly from people using pico-ducky).

Pico ducky could use a trick like this to avoid having to change the code when changing keyboard, by only renaming the layout and keycode files to keyboard_layout_ducky and keycode_ducky (not changing the extension).

try:
    from keyboard_layout_ducky import KeyboardLayout
except ImportError:
    from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS as KeyboardLayout
# Keycodes
    from keycode_ducky import Keycode
except ImportError:
    from adafruit_hid.keycode import Keycode

And change layout = ... with that line:

layout = KeyboardLayout(kbd)

@NadSeries
Copy link

Ok great!! Thanks a lot it was painful trying to map all the US character over an italian keyboard(and sometimes certain characters like { } wasn't available or rather they could not be injected). I used http://kbdlayout.info/ and https://www.neradoc.me/layouts/, it works just fine for me.

@dbisu
Copy link
Owner

dbisu commented Sep 12, 2021

I've updated the code in the kronos branch to offer more generic import of new keyboard layouts from Neradoc/Circuitpython_Keyboard_Layouts
I also added keyboard-layouts.md with instructions on how to add non-US keyboard layouts.
I would appreciate it if someone with a non-US keyboard could try this out to validate the instructions.

@Timovl
Copy link

Timovl commented Sep 14, 2021

Is there an azerty layout? And how do I implement this in the code.py file?

@GamehunterKaan
Copy link

@Timovl > Is there an azerty layout? And how do I implement this in the code.py file?

Take A Look At These 2 Pages.
https://github.com/Neradoc/Circuitpython_Keyboard_Layouts/blob/main/PICODUCKY.md
https://www.neradoc.me/layouts/

@NiklasRichter2222
Copy link

i do have a problem with the German keyboard i tried both methodes and nothing worked
Screenshot 2021-09-22 191108
Screenshot 2021-09-22 191129

@NiklasRichter2222
Copy link

and is there any way to implement üöä for me

@GamehunterKaan
Copy link

@NiklasRichter2222 This Is The Correct Code.py for German Keyboard.

from adafruit_hid.keyboard import Keyboard
from keyboard_layout_win_gr import KeyboardLayout
from keycode_win_gr import Keycode
import time
import digitalio
from board import *

duckyCommands = ["WINDOWS", "GUI", "APP", "MENU", "SHIFT", "ALT", "CONTROL", "CTRL", "DOWNARROW", "DOWN",
"LEFTARROW", "LEFT", "RIGHTARROW", "RIGHT", "UPARROW", "UP", "BREAK", "PAUSE", "CAPSLOCK", "DELETE", "END",
"ESC", "ESCAPE", "HOME", "INSERT", "NUMLOCK", "PAGEUP", "PAGEDOWN", "PRINTSCREEN", "SCROLLLOCK", "SPACE",
"TAB", "ENTER", " a", " b", " c", " d", " e", " f", " g", " h", " i", " j", " k", " l", " m", " n", " o", " p", " q", " r", " s", " t",
" u", " v", " w", " x", " y", " z", " A", " B", " C", " D", " E", " F", " G", " H", " I", " J", " K", " L", " M", " N", " O", " P",
" Q", " R", " S", " T", " U", " V", " W", " X", " Y", " Z", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"]

keycodeCommands = [Keycode.WINDOWS, Keycode.GUI, Keycode.APPLICATION, Keycode.APPLICATION, Keycode.SHIFT, Keycode.ALT, Keycode.CONTROL,
Keycode.CONTROL, Keycode.DOWN_ARROW, Keycode.DOWN_ARROW ,Keycode.LEFT_ARROW, Keycode.LEFT_ARROW, Keycode.RIGHT_ARROW, Keycode.RIGHT_ARROW,
Keycode.UP_ARROW, Keycode.UP_ARROW, Keycode.PAUSE, Keycode.PAUSE, Keycode.CAPS_LOCK, Keycode.DELETE, Keycode.END, Keycode.ESCAPE,
Keycode.ESCAPE, Keycode.HOME, Keycode.INSERT, Keycode.KEYPAD_NUMLOCK, Keycode.PAGE_UP, Keycode.PAGE_DOWN, Keycode.PRINT_SCREEN,
Keycode.SCROLL_LOCK, Keycode.SPACE, Keycode.TAB, Keycode.ENTER, Keycode.A, Keycode.B, Keycode.C, Keycode.D, Keycode.E, Keycode.F, Keycode.G,
Keycode.H, Keycode.I, Keycode.J, Keycode.K, Keycode.L, Keycode.M, Keycode.N, Keycode.O, Keycode.P, Keycode.Q, Keycode.R, Keycode.S, Keycode.T,
Keycode.U, Keycode.V, Keycode.W, Keycode.X, Keycode.Y, Keycode.Z, Keycode.A, Keycode.B, Keycode.C, Keycode.D, Keycode.E, Keycode.F,
Keycode.G, Keycode.H, Keycode.I, Keycode.J, Keycode.K, Keycode.L, Keycode.M, Keycode.N, Keycode.O, Keycode.P,
Keycode.Q, Keycode.R, Keycode.S, Keycode.T, Keycode.U, Keycode.V, Keycode.W, Keycode.X, Keycode.Y, Keycode.Z,
Keycode.F1, Keycode.F2, Keycode.F3, Keycode.F4, Keycode.F5, Keycode.F6, Keycode.F7, Keycode.F8, Keycode.F9,
Keycode.F10, Keycode.F11, Keycode.F12]

def convertLine(line):
    newline = []
    print(line)
    for j in range(len(keycodeCommands)):
		    if line.find(duckyCommands[j]) != -1:
		    	newline.append(keycodeCommands[j])
    print(newline)
    return newline

def runScriptLine(line):
    for k in line:
        kbd.press(k)
    kbd.release_all()

def sendString(line):
    layout.write(line)

def parseLine(line):
    if(line[0:3] == "REM"):
        # ignore ducky script comments
        pass
    elif(line[0:5] == "DELAY"):
        time.sleep(float(line[6:])/1000)
    elif(line[0:6] == "STRING"):
        sendString(line[7:])
    elif(line[0:13] == "DEFAULT_DELAY"):
        defaultDelay = int(line[14:]) * 10
    elif(line[0:12] == "DEFAULTDELAY"):
        defaultDelay = int(line[13:]) * 10
    else:
        newScriptLine = convertLine(line)
        runScriptLine(newScriptLine)

kbd = Keyboard(usb_hid.devices)
layout = KeyboardLayout(kbd)

# sleep at the start to allow the device to be recognized by the host computer
time.sleep(.5)

# check GP0 for setup mode
# see setup mode for instructions
progStatus = False
progStatusPin = digitalio.DigitalInOut(GP0)
progStatusPin.switch_to_input(pull=digitalio.Pull.UP)
progStatus = not progStatusPin.value
defaultDelay = 0
if(progStatus == False):
    # not in setup mode, inject the payload
    duckyScriptPath = "payload.dd"
    f = open(duckyScriptPath,"r",encoding='utf-8')
    print("Running payload.dd")
    previousLine = ""
    duckyScript = f.readlines()
    for line in duckyScript:
        line = line.rstrip()
        if(line[0:6] == "REPEAT"):
            for i in range(int(line[7:])):
                #repeat the last command
                parseLine(previousLine)
                time.sleep(float(defaultDelay)/1000)
        else:
            parseLine(line)
            previousLine = line
        time.sleep(float(defaultDelay)/1000)

    print("Done")
else:
    print("Update your payload")

@Neradoc
Copy link
Contributor

Neradoc commented Sep 22, 2021

i do have a problem with the German keyboard i tried both methodes and nothing worked

You installed the language modules inside another module (adafruit_hid), they go in the lib/ directory.
(And your code is wrong for the imports, see GamehunterKaan's post).
Maybe these instructions are clearer ? I don't pretend to be good at writing guides, but there's a screenshot... 🤷

@NiklasRichter2222
Copy link

Thanks it worked

@DeDragonCZ
Copy link

Any way to do Czech keyboard..?

@NiklasRichter2222
Copy link

Any way to do Czech keyboard..?
Yes

@NiklasRichter2222
Copy link

You go to this Website and do what thay say there
https://www.neradoc.me/layouts/

@NiklasRichter2222
Copy link

NiklasRichter2222 commented Sep 23, 2021

You download the .py files(the Big Button not one of the two small ones) and put all the files exept the example Code in to the lib Folder

@NiklasRichter2222
Copy link

NiklasRichter2222 commented Sep 23, 2021

You replace the code in the code.py file with this one and it should work

import usb_hid
from adafruit_hid.keyboard import Keyboard
from keyboard_layout_win_cz import KeyboardLayout
from keycode_win_cz import Keycode
import time
import digitalio
from board import *

duckyCommands = ["WINDOWS", "GUI", "APP", "MENU", "SHIFT", "ALT", "CONTROL", "CTRL", "DOWNARROW", "DOWN",
"LEFTARROW", "LEFT", "RIGHTARROW", "RIGHT", "UPARROW", "UP", "BREAK", "PAUSE", "CAPSLOCK", "DELETE", "END",
"ESC", "ESCAPE", "HOME", "INSERT", "NUMLOCK", "PAGEUP", "PAGEDOWN", "PRINTSCREEN", "SCROLLLOCK", "SPACE",
"TAB", "ENTER", " a", " b", " c", " d", " e", " f", " g", " h", " i", " j", " k", " l", " m", " n", " o", " p", " q", " r", " s", " t",
" u", " v", " w", " x", " y", " z", " A", " B", " C", " D", " E", " F", " G", " H", " I", " J", " K", " L", " M", " N", " O", " P",
" Q", " R", " S", " T", " U", " V", " W", " X", " Y", " Z", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"]

keycodeCommands = [Keycode.WINDOWS, Keycode.GUI, Keycode.APPLICATION, Keycode.APPLICATION, Keycode.SHIFT, Keycode.ALT, Keycode.CONTROL,
Keycode.CONTROL, Keycode.DOWN_ARROW, Keycode.DOWN_ARROW ,Keycode.LEFT_ARROW, Keycode.LEFT_ARROW, Keycode.RIGHT_ARROW, Keycode.RIGHT_ARROW,
Keycode.UP_ARROW, Keycode.UP_ARROW, Keycode.PAUSE, Keycode.PAUSE, Keycode.CAPS_LOCK, Keycode.DELETE, Keycode.END, Keycode.ESCAPE,
Keycode.ESCAPE, Keycode.HOME, Keycode.INSERT, Keycode.KEYPAD_NUMLOCK, Keycode.PAGE_UP, Keycode.PAGE_DOWN, Keycode.PRINT_SCREEN,
Keycode.SCROLL_LOCK, Keycode.SPACE, Keycode.TAB, Keycode.ENTER, Keycode.A, Keycode.B, Keycode.C, Keycode.D, Keycode.E, Keycode.F, Keycode.G,
Keycode.H, Keycode.I, Keycode.J, Keycode.K, Keycode.L, Keycode.M, Keycode.N, Keycode.O, Keycode.P, Keycode.Q, Keycode.R, Keycode.S, Keycode.T,
Keycode.U, Keycode.V, Keycode.W, Keycode.X, Keycode.Y, Keycode.Z, Keycode.A, Keycode.B, Keycode.C, Keycode.D, Keycode.E, Keycode.F,
Keycode.G, Keycode.H, Keycode.I, Keycode.J, Keycode.K, Keycode.L, Keycode.M, Keycode.N, Keycode.O, Keycode.P,
Keycode.Q, Keycode.R, Keycode.S, Keycode.T, Keycode.U, Keycode.V, Keycode.W, Keycode.X, Keycode.Y, Keycode.Z,
Keycode.F1, Keycode.F2, Keycode.F3, Keycode.F4, Keycode.F5, Keycode.F6, Keycode.F7, Keycode.F8, Keycode.F9,
Keycode.F10, Keycode.F11, Keycode.F12]

def convertLine(line):
    newline = []
    print(line)
    for j in range(len(keycodeCommands)):
    	    if line.find(duckyCommands[j]) != -1:
    	    	newline.append(keycodeCommands[j])
    print(newline)
    return newline

def runScriptLine(line):
    for k in line:
        kbd.press(k)
    kbd.release_all()

def sendString(line):
    layout.write(line)

def parseLine(line):
    if(line[0:3] == "REM"):
        # ignore ducky script comments
        pass
    elif(line[0:5] == "DELAY"):
        time.sleep(float(line[6:])/1000)
    elif(line[0:6] == "STRING"):
        sendString(line[7:])
    elif(line[0:13] == "DEFAULT_DELAY"):
        defaultDelay = int(line[14:]) * 10
    elif(line[0:12] == "DEFAULTDELAY"):
        defaultDelay = int(line[13:]) * 10
    else:
        newScriptLine = convertLine(line)
        runScriptLine(newScriptLine)

kbd = Keyboard(usb_hid.devices)
layout = KeyboardLayout(kbd)

# sleep at the start to allow the device to be recognized by the host computer
time.sleep(.5)

# check GP0 for setup mode
# see setup mode for instructions
progStatus = False
progStatusPin = digitalio.DigitalInOut(GP0)
progStatusPin.switch_to_input(pull=digitalio.Pull.UP)
progStatus = not progStatusPin.value
defaultDelay = 0
if(progStatus == False):
     # not in setup mode, inject the payload
    duckyScriptPath = "payload.dd"
    f = open(duckyScriptPath,"r",encoding='utf-8')
    print("Running payload.dd")
    previousLine = ""
    duckyScript = f.readlines()
    for line in duckyScript:
        line = line.rstrip()
        if(line[0:6] == "REPEAT"):
            for i in range(int(line[7:])):
                #repeat the last command
                parseLine(previousLine)
                time.sleep(float(defaultDelay)/1000)
        else:
            parseLine(line)
            previousLine = line
        time.sleep(float(defaultDelay)/1000)

    print("Done")
else:
    print("Update your payload")

@dhalbert
Copy link

@Neradoc Perhaps a PR to enhance the README to point to your layouts library would be good?

@DeDragonCZ
Copy link

Hey, thanks for the help!

@dbisu
Copy link
Owner

dbisu commented Oct 17, 2021

I've created a branch, keyboard-layouts, to help make including the Neradoc keyboard layouts easier.
https://github.com/dbisu/pico-ducky/tree/keyboard-layouts
Let me know if this helps and I'll create a PR to include these changes.

@MrBrambor
Copy link

MrBrambor commented Oct 27, 2021

Any possibility to switch between 2 layouts using only a hardware switch, without having to rewrite the code each time?

@peterfritz
Copy link
Contributor

peterfritz commented Oct 27, 2021

@MrBrambor What would the use case be? It seems like it would only bloat the code slowing down the payload execution.

@MrBrambor
Copy link

Well it would be useful for me cause for example I would want to prank my friends with rickroll but a lot (let's say 40%) of my friends use different layout so I wouldn't have to use 2 picos or have to switch code files.

@dbisu
Copy link
Owner

dbisu commented Oct 27, 2021

Submit a feature request issue and I'll see about adding that in the future. I've got some other features I'm working on in the short term, so might be a bit before it would get implemented.

@GamehunterKaan
Copy link

Any possibility to switch between 2 layouts using only a hardware switch, without having to rewrite the code each time?

I think you can check the pins with if statements and import the layout depending on that.

@dbisu dbisu linked a pull request Oct 31, 2021 that will close this issue
@dbisu dbisu closed this as completed in #30 Oct 31, 2021
@gomarrota
Copy link

any way to do spanish keyboard? :(

@dbisu
Copy link
Owner

dbisu commented Nov 23, 2021

ES is the locale code for Spanish.
https://github.com/dbisu/pico-ducky/releases/download/v1.2/pico-ducky-v1.2_win_es.zip

@gomarrota
Copy link

thank u so much this helped me a lot

@ivoiot
Copy link

ivoiot commented Aug 28, 2023

I'm having a problem with italian layout setting on my raspberry pi pico. when i execute some scrit with the simbol '{' or '}' it get stucked. any suggestion to fix it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.