From 1bf89da3e82af341e0259b0535d3f1c017334353 Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Fri, 16 Feb 2024 18:16:03 +0100 Subject: [PATCH] Use loops --- code.py | 73 ++++++++ lib/adafruit_hid/__init__.mpy | Bin 0 -> 761 bytes lib/adafruit_hid/consumer_control.mpy | Bin 0 -> 612 bytes lib/adafruit_hid/consumer_control_code.mpy | Bin 0 -> 354 bytes lib/adafruit_hid/keyboard.mpy | Bin 0 -> 1203 bytes lib/adafruit_hid/keyboard_layout_base.mpy | Bin 0 -> 1271 bytes lib/adafruit_hid/keyboard_layout_us.mpy | Bin 0 -> 330 bytes lib/adafruit_hid/keycode.mpy | Bin 0 -> 1729 bytes lib/adafruit_hid/mouse.mpy | Bin 0 -> 799 bytes lib/keyboard_layout_win_fr.py | 202 +++++++++++++++++++++ lib/keycode_win_fr.py | 152 ++++++++++++++++ 11 files changed, 427 insertions(+) create mode 100644 code.py create mode 100644 lib/adafruit_hid/__init__.mpy create mode 100644 lib/adafruit_hid/consumer_control.mpy create mode 100644 lib/adafruit_hid/consumer_control_code.mpy create mode 100644 lib/adafruit_hid/keyboard.mpy create mode 100644 lib/adafruit_hid/keyboard_layout_base.mpy create mode 100644 lib/adafruit_hid/keyboard_layout_us.mpy create mode 100644 lib/adafruit_hid/keycode.mpy create mode 100644 lib/adafruit_hid/mouse.mpy create mode 100644 lib/keyboard_layout_win_fr.py create mode 100644 lib/keycode_win_fr.py diff --git a/code.py b/code.py new file mode 100644 index 0000000..14191b8 --- /dev/null +++ b/code.py @@ -0,0 +1,73 @@ +# Raspberry Pi Pico Stopmo pad +# +# Using CircuitPython : https://circuitpython.org/board/raspberry_pi_pico/ +# Using Adafruit USB_HID Library : https://github.com/adafruit/Adafruit_CircuitPython_HID/releases +# +# Buttons default mapping +# Red = F +# Green = G +# Blue = H +# Black = I +# +# Yellow on : multimedia mode +# +# Forked from +# DroneBot Workshop 2021 +# https://dronebotworkshop.com + +import time +import board +import digitalio +import usb_hid + +# Regulare keys +from adafruit_hid.keyboard import Keyboard +from keyboard_layout_win_fr import KeyboardLayout +from keycode_win_fr import Keycode + +# multimedia keys +# ~ from adafruit_hid.consumer_control import ConsumerControl +# ~ from adafruit_hid.consumer_control_code import ConsumerControlCode +# ~ cc = ConsumerControl(usb_hid.devices) + +# KB setup +keyboard = Keyboard(usb_hid.devices) +keyboard_layout = KeyboardLayout(keyboard) + +# Buttons setup +# Change GPIOs according to HW +buttons_gpio = { +# name GPIO Keycode State DigitalIO (switch) + "red" : dict(gpio=board.GP18, keycode=Keycode.G, state=False, DIO=None), + "green" : dict(gpio=board.GP19, keycode=Keycode.H, state=False, DIO=None), + "blue" : dict(gpio=board.GP16, keycode=Keycode.I, state=False, DIO=None), + "black" : dict(gpio=board.GP20, keycode=Keycode.J, state=False, DIO=None), + "yellow": dict(gpio=board.GP17, keycode=Keycode.K, state=False, DIO=None), + "switch": dict(gpio=board.GP21, keycode=Keycode.LEFT_SHIFT, state=False, DIO=None, switch_setup=dict(gpio=board.GP7, DIO=None)) +} + +# GPIO setup +for btn in buttons_gpio: + buttons_gpio[btn]['DIO'] = digitalio.DigitalInOut(buttons_gpio[btn]['gpio']) + buttons_gpio[btn]['DIO'].direction = digitalio.Direction.INPUT + buttons_gpio[btn]['DIO'].pull = digitalio.Pull.DOWN + # Switch setup + if 'switch_setup' in buttons_gpio[btn]: + buttons_gpio[btn]['switch_setup']['DIO'] = digitalio.DigitalInOut(buttons_gpio[btn]['switch_setup']['gpio']) + buttons_gpio[btn]['switch_setup']['DIO'].direction = digitalio.Direction.OUTPUT + +btn_scan_delay = 1/200 + +while True: + for btn in buttons_gpio: + if buttons_gpio[btn]['DIO'].value and not buttons_gpio[btn]['state']: + keyboard.press(buttons_gpio[btn]['keycode']) + buttons_gpio[btn]['state'] = not buttons_gpio[btn]['state'] + if 'switch_setup' in buttons_gpio[btn]: + buttons_gpio[btn]['switch_setup']['DIO'].value = True + if not buttons_gpio[btn]['DIO'].value and buttons_gpio[btn]['state']: + keyboard.release(buttons_gpio[btn]['keycode']) + buttons_gpio[btn]['state'] = not buttons_gpio[btn]['state'] + if 'switch_setup' in buttons_gpio[btn]: + buttons_gpio[btn]['switch_setup']['DIO'].value = False + time.sleep(btn_scan_delay) \ No newline at end of file diff --git a/lib/adafruit_hid/__init__.mpy b/lib/adafruit_hid/__init__.mpy new file mode 100644 index 0000000000000000000000000000000000000000..458606e3a188bb816eba1353c02a4f84aabaf27e GIT binary patch literal 761 zcmZXSK~K~`6vwA5xa@+P-ELE(E3skB8er317sP~%*lkDw4{nfP4Q4FuESoDhb5 z;?)r%fp|rFwD&^e#fAl+Sa8#Wn^qMAUR0eR2${o37|>~{q9D{sSQ2A|Ze~=;=IzQT zBRg1?tT7-0g(eY>cL@z+Raz;5jS{H-Fh{xF7NG>5TV>%{T*I#t9Jp8*jKC7w-?c$hFUBvw#fjBRD)aWDfJA8R=vD z2yb@92t<%*K0U5q1`otJE5oga(z1UJUGoKZ4xR3zn*av@HF z6ioR>%GeEq0J{u(=GlSKfgc5S`5jhBi2M)-0%rT9-&Ds!)hb6jg{rqy#DIsZj%M4wW(XwzWuX<6XBz z2x$!zsa1cB!(ZXRk-x&GMu^MI?7o>dZ)OJN!j}1M_h}21zT-J3apH6P%=ezTVZf3( zjcpn5IGnYk#amM-qfT>fw)UHyi3eg_zrz-cARXa`KaXZ~P6O_6KMb&XPGcqm@%rnp zp(b>A(gXu0Iy~&5E~2uu!g!pxoS;-ACw}1B9zFM6x`XO~8i=6js18EY4(Nx32Dkqe zzKHzbv{96xBv2FfZY7nVz58$|JNzD&#B>kA@x(&f=HTxD(y#P)3j~c_gqZcI^V#&7 z8HC(qNfd=Kr=IBt=D?3#IsN{EpM`;GwLh9+Y|g?98mC8h8wlTQ_OJ9ye2GC$L4asQ z0vqEUbnqMq=oTVyZ57B`6jR2mB2i;HqYk5E7fR{yr-XGyY>RsreW+EJnvpQ)l-iLr zH`?0mBh^&y&uN(OAKmXLdt|P5pC2LLO%3{Ax)M2bsbj8*p6}mZ-KM zGw`y9rqcCbn&)l&V{=1~rn@hUvLarIss*(zqZT>td)p6qsFhxhGK|HtSDI${fk7CR m$H^OJxGYI?Iz4S|8(0@dqS6L&m|;b{$uLT#SvS`I&-??$`K_`5 literal 0 HcmV?d00001 diff --git a/lib/adafruit_hid/consumer_control_code.mpy b/lib/adafruit_hid/consumer_control_code.mpy new file mode 100644 index 0000000000000000000000000000000000000000..618edcabf0c692818004173ef8d3b000ce4f4d09 GIT binary patch literal 354 zcmZ{gu}i~16o)S@Vi1KW@)QRRHxws@TCMAOxoT>2iFcP)r)zC0M%0wp4sHoJ`bT>a zTXc{&ydU51d&{FMwF7tPY@yZeC>cHE^K_;k)8u%Zy}r#~Cb>3YmS@jqCzGS;`_L_H zq?*WS&>zF>N}#51)xf$LBkKbp&#HfJ6n4Y?XV50v0R&DR&>k+Eur3%4g@?-%*zFLh zbSD%8Qh`?04Sa6mDeOy1xaRCuX(b4~#^o6_zF8z#-w$KC;BBy_3L{*e!y4-{s&E;= zcGM$xIwG-TxV#5Dh?NOX;P%5_95C%MDpQg9*VdYO6J{gS#piy1O{# zi6IV_WAz90FZ6BK#*zA%#HrNR<>zP=j=3_}Z>f)W-4i**3^znV(J=^p~AFmL|0`G@nvxgmqMhf_oU z(0}9rUhobAh_NCtH$eXUN>;dCUKjF(%-Vf4XTZ#78zmDzKvxZ1%G@dB^QPwzAv2<| zzELQx6r-^8Awa+zhv-U2#)=ZRAdifjxT@f|6`_eKRGZECB?OM*HuRoQ6-8mP1VL>J zGVZixHGUZ-so84p;kRT%Znq}1m+8pu4wltk+@64lYhqDQ)T-K5;#0_Fp!O~u-?0x~ zKpuDlWSKbbrHOmM(>RH=pAUG+F|05v~v^fh-mIfoCV z4il7cjTQR17L_OW_9T2yW335D1~)8a&3|=F3$3;&H6$$iY#M7z!23m$r7JMTGioa# ztL8_-h4f+_0`Sl?KE5(tgJ6*Tm5>x#nk6|h6L}Zt!kP;_(YVlY5?0cG_ceBgLkgxZ zW?WWdSxV5sX`M;#vXj(^^MAQZZ*!fTQ)8VM3AtsCM$3F821wdTwjL9zT;CkL-a0(b zyy;go*1muXQPgEWUj_l<7ZGIVOoL4V>1S%TmOoEAw{myFCYbS({W^b=V!j16a zt+mJp!1pod|8GM=O;YtFd~%%i(2fh_i}LaBUv8#9r(pgmNe9W+*~zHL`W2FPnPG!}$~1twhv%8U`W5}8Pos@>eDdJ>o!G3K{78iq zRu&`Sa3~UrMAk!L;B#~CasO%B(rxsA{s$FMG|*FWM$*^G*0Yn-@-L4vR+3&Ik7##l zFywUf8Y>B*qkD JJSXFO@-M8qg&F_= literal 0 HcmV?d00001 diff --git a/lib/adafruit_hid/keyboard_layout_base.mpy b/lib/adafruit_hid/keyboard_layout_base.mpy new file mode 100644 index 0000000000000000000000000000000000000000..56d387fee08b292cae832de340a9e3c5f5a9ea06 GIT binary patch literal 1271 zcmbtT%WfK17(NF=z?ith#e-|R&B(+UunU+VT3KEAGPWV67%)~umFO_Q*r1F(Xc+9E z$jZUBt6J?tbP=hGZU(R)pmF;G$tGF2mHGmxZ_t0ZY`U#x@t^} zL*}?p77mm~RV9^bIrKto7G*&x6G>>w4V4syx)`iA3mmn0!q51$S443SqKq}ys7Yb~ z&)C#vt$KVoYh-c0#V|X=eDE+MtiJEb1N796ynpfcX#NRC&jF$?iDC@`Eo${h><2N{ zSTG!X%(8@>h)TUG9~0t1EJKJQ)?`9*5zIUql}Pp(t^>iSfyJ2;#`Tqos@Cc&q0nJf ztu%_kl6({zwHI0&^|?`1O3-h*saBvsJi!Mc{9@J;$CE#OS}1tA!8c!+U-hoe(+8Kf zE9T03Ie$5U?8wamA0vyV=URw$?Zp#YIkJ^p+wQAt$=r5!s0t(R#xB1(*E(Qlvx)6^ zjzA32O##GmYkM1s1j+4^oz1*%TSDwq9HKU}r0-%7W?iYxOKbR1@!snG=@#o_vnk*C^rTo6&BI@uHRCAhK)|w*L z>zdOY!}+%6{H({b6eNE4_ivih>@sW48Svt2PGzkysUzx z9xC5kezb?t8#{eQZCgHXCbg7ajwe072DgCPWanpetGOn-G5q^A{lMEPDA!#meit+3 z*JbKJr`;&lb$$&<;(@;ZhvqWf{P53>=JfO+(1G}yxz_8RPPP}tfHJT1v#L(h;Csq?mK>*c3tRe z&A9;k=z!?)ZrzfFC#c4Ey?_Bc>z0042cF%2Ll&Ls|8Jxv%}p;l=`YkAT=FlV0YlCC z#T{=O?g|+1m-HLDgQPapy~+?7GySI7GoA<6q7-f z2~1{StYHvg=Ir5b5K>?eWDpl)5EEb)V~|p25L0jrcJ}m)5Al!pc8zrQcX16&W@Jce zWPkxJZ4DR`Mr(o?I`g(HSh#43$+G23*O}>>Td2#)D<~={tEj4NHr}SUeaHNk*0%PJ z&aUpB-oE|`6DLicGIiSY88c_io-b`DN1ZXRAfegQ!tVG&U=aS2H& NX&Kq|8#iqA0RU^>U9SKD literal 0 HcmV?d00001 diff --git a/lib/adafruit_hid/keycode.mpy b/lib/adafruit_hid/keycode.mpy new file mode 100644 index 0000000000000000000000000000000000000000..8a5c6318459ce9f7cb95c397ca4b4d3f7c6178e2 GIT binary patch literal 1729 zcmb7_S#ujj5XV-mCqU~Z$o zvAz4^;8OR@p#R9(t;@Zg{?^=u%j-qTXhBKKPqs$6vVhc5PfOj%XRc*Z6Ibq`sfUXH z`>E`|;&4)F>>Vop>!}>7{5^BHm^_up8`)8I?2mPn-QVsvXD_$s?YDYeo6_zD4e}G9 z&AtRee;Gve6%fX&AZo9HkgtQNzX780CWz)05awGTPQDGI^$rN@Dv0*GAnf-*IPZgS zKLD}xAqejp2>&Ax!N(xNPe3ex3ZnBFh?UPltX>DPb_3FmEpI|P=r~_MHfVZMehHbn z6MA2H<0z^vb4X2tTY?V;5*3JrY*mR%$oF^A2@3V(wj;_&XYmt**`)~ z`iAbxpP*3Hjh64~hWweg(W}2eK8mWknxBpQUm@Ez?a=>?mo0_5<^K*dmaGTes>h3E zfJb1~Q~M@~`M9p7`%NrC)^$R=h6_;eW!p3y%dxQx*`?44Brd{C!_${#S2qlPPdo}) z!)dp5JO(*edZtsu<1kxyypHbGx_(sh1Qhu7{jTL0EqoO2s?XzNY)kk!+XZ}rZ5f|r zyNFM*J&IIeIfkUO97n3MoIo-lU7tUKR8u;SB$bws>M-MarX6&BgF9{`H2~OkENiqQ zHTg(-=u0FMa;EJ|FF-m8nWod`Tni>$y&=1yi)2BrCN0V5q&B1_cY$muM8h?w!=)X7 zQSWrmb2>;aOh>(q!zGwj^SW{9K|XZHfe-h!2Ov(kR_G(GBoiWlkXB(jp1@opttBA?igYTO9+8UlbW%?ti}cK1 z%50d?Rfpu>u{b2eab?jL4xr6yr<;dPEOx0qCx4 znT8&ij3R9-LOYV*@N`mOL^{$L#l!;AKxrB2Ii-t8XO%Ko=ae#8=an*A&nsoNc34Zy z)&-@^)(c9RtzD&D@1oK&4*87H_ck0mV8Zy)O~x(`H)0n2rdbc7>!=(YZbE*Mw-Pq^1A> literal 0 HcmV?d00001 diff --git a/lib/adafruit_hid/mouse.mpy b/lib/adafruit_hid/mouse.mpy new file mode 100644 index 0000000000000000000000000000000000000000..d6641877977f1971aef053d7939948c7943323b7 GIT binary patch literal 799 zcmY*V&2JJx6rTZFy0nE|*iH*nA+%``nrbK^9z2kiDs8OVLQ!JOE`@2karuy4`f*~G z7L%$cxu)RR%D(6q#d{Oi(gmQgXj3W`gaY1?@;C&&0FFZhvq>)?ESthlYPi(t z52^bVskAk2rbDvowbzslgA&2zVQ`-VQ$G?Gl3j-2Q91%x+lnC+H6gf~2k_tqdmRqG z;Nz2idg4bTO|Hq{c+>fOs%Zrr7)1cFW&}JMLbn%hriJ(x!F2snSuh$LconfmAsP~7sVJ%R^8;G)8yo}ND7j3ST~P#1UyJ2yN^T1a z6&f_w*10rTyDAlNxu&+GPoX~Mp?uVWp07?2KaA4uP!(6oRf89RBYW3##j1f2e~BY= zWH=0T7egMbw|+j%==?|wWP8w!nyQvdie?G%K87U3_{;_J>n{V!{DU&G+eslS{%JrA zvj2vA0p4dNYs4M|I`3%3V78aKGLA#bmnNK|&kMvo5ex>y;qdI_B$!VTo%d1rN1cc5 z82m)jaSVPw3261-x{K2?r`-xRGH1Q&Afvn7JnFdH-CB3`QNh;9`MdV%`TOIu^A9cZ zec^4rP2-#TF^#Y5-G7+&O#8OoZH#3t=|*0TJo8UaclH_7GIT2{V?;y3!8^LV-Iwwe gJI9chz}a7vN&!-*Iky-11NEpWYND' + b'\x90' # '?' + b'\x27' # '@' + b'\x94' # 'A' + b'\x85' # 'B' + b'\x86' # 'C' + b'\x87' # 'D' + b'\x88' # 'E' + b'\x89' # 'F' + b'\x8a' # 'G' + b'\x8b' # 'H' + b'\x8c' # 'I' + b'\x8d' # 'J' + b'\x8e' # 'K' + b'\x8f' # 'L' + b'\xb3' # 'M' + b'\x91' # 'N' + b'\x92' # 'O' + b'\x93' # 'P' + b'\x84' # 'Q' + b'\x95' # 'R' + b'\x96' # 'S' + b'\x97' # 'T' + b'\x98' # 'U' + b'\x99' # 'V' + b'\x9d' # 'W' + b'\x9b' # 'X' + b'\x9c' # 'Y' + b'\x9a' # 'Z' + b'\x22' # '[' + b'\x25' # '\\' + b'\x2d' # ']' + b'\x26' # '^' + b'\x25' # '_' + b'\x00' # '`' (Dead key) + b'\x14' # 'a' + b'\x05' # 'b' + b'\x06' # 'c' + b'\x07' # 'd' + b'\x08' # 'e' + b'\x09' # 'f' + b'\x0a' # 'g' + b'\x0b' # 'h' + b'\x0c' # 'i' + b'\x0d' # 'j' + b'\x0e' # 'k' + b'\x0f' # 'l' + b'\x33' # 'm' + b'\x11' # 'n' + b'\x12' # 'o' + b'\x13' # 'p' + b'\x04' # 'q' + b'\x15' # 'r' + b'\x16' # 's' + b'\x17' # 't' + b'\x18' # 'u' + b'\x19' # 'v' + b'\x1d' # 'w' + b'\x1b' # 'x' + b'\x1c' # 'y' + b'\x1a' # 'z' + b'\x21' # '{' + b'\x23' # '|' + b'\x2e' # '}' + b'\x00' # '~' (Dead key) + b'\x00' + ) + NEED_ALTGR = '#@[\\]^{|}¤€' + HIGHER_ASCII = { + 0xe9: 0x1f, # 'é' + 0xe8: 0x24, # 'è' + 0xe7: 0x26, # 'ç' + 0xe0: 0x27, # 'à' + 0xb0: 0xad, # '°' + 0x20ac: 0x08, # '€' + 0xa3: 0xb0, # '£' + 0xa4: 0x30, # '¤' + 0xf9: 0x34, # 'ù' + 0xb2: 0x35, # '²' + 0xb5: 0xb1, # 'µ' + 0xa7: 0xb8, # '§' + } + COMBINED_KEYS = { + 0xe3: 0x1fe1, # 'ã' + 0xc3: 0x1fc1, # 'Ã' + 0xf1: 0x1fee, # 'ñ' + 0xd1: 0x1fce, # 'Ñ' + 0xf5: 0x1fef, # 'õ' + 0xd5: 0x1fcf, # 'Õ' + 0x7e: 0x1fa0, # '~' + 0xe0: 0x24e1, # 'à' + 0xe8: 0x24e5, # 'è' + 0xec: 0x24e9, # 'ì' + 0xf2: 0x24ef, # 'ò' + 0xf9: 0x24f5, # 'ù' + 0xc0: 0x24c1, # 'À' + 0xc8: 0x24c5, # 'È' + 0xcc: 0x24c9, # 'Ì' + 0xd2: 0x24cf, # 'Ò' + 0xd9: 0x24d5, # 'Ù' + 0x60: 0x24a0, # '`' + 0xe2: 0x2f61, # 'â' + 0xea: 0x2f65, # 'ê' + 0xee: 0x2f69, # 'î' + 0xf4: 0x2f6f, # 'ô' + 0xfb: 0x2f75, # 'û' + 0xc2: 0x2f41, # 'Â' + 0xca: 0x2f45, # 'Ê' + 0xce: 0x2f49, # 'Î' + 0xd4: 0x2f4f, # 'Ô' + 0xdb: 0x2f55, # 'Û' + 0x5e: 0x2f20, # '^' + 0xe4: 0xaf61, # 'ä' + 0xeb: 0xaf65, # 'ë' + 0xef: 0xaf69, # 'ï' + 0xf6: 0xaf6f, # 'ö' + 0xfc: 0xaf75, # 'ü' + 0xff: 0xaf79, # 'ÿ' + 0xc4: 0xaf41, # 'Ä' + 0xcb: 0xaf45, # 'Ë' + 0xcf: 0xaf49, # 'Ï' + 0xd6: 0xaf4f, # 'Ö' + 0xdc: 0xaf55, # 'Ü' + 0xa8: 0xaf20, # '¨' + } diff --git a/lib/keycode_win_fr.py b/lib/keycode_win_fr.py new file mode 100644 index 0000000..0e6a67d --- /dev/null +++ b/lib/keycode_win_fr.py @@ -0,0 +1,152 @@ +# SPDX-FileCopyrightText: 2021 Neradoc NeraOnGit@ri1.fr +# +# SPDX-License-Identifier: MIT +""" +This file was automatically generated using Circuitpython_Keyboard_Layouts +""" + + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/Neradoc/Circuitpython_Keyboard_Layouts.git" + + +class Keycode: + A = 0x14 + B = 0x05 + C = 0x06 + D = 0x07 + E = 0x08 + F = 0x09 + G = 0x0a + H = 0x0b + I = 0x0c + J = 0x0d + K = 0x0e + L = 0x0f + M = 0x33 + N = 0x11 + O = 0x12 + P = 0x13 + Q = 0x04 + R = 0x15 + S = 0x16 + T = 0x17 + U = 0x18 + V = 0x19 + W = 0x1d + X = 0x1b + Y = 0x1c + Z = 0x1a + ALT = 0xe2 + END = 0x4d + F1 = 0x3a + F2 = 0x3b + F3 = 0x3c + F4 = 0x3d + F5 = 0x3e + F6 = 0x3f + F7 = 0x40 + F8 = 0x41 + F9 = 0x42 + F10 = 0x43 + F11 = 0x44 + F12 = 0x45 + F13 = 0x68 + F14 = 0x69 + F15 = 0x6a + F16 = 0x6b + F17 = 0x6c + F18 = 0x6d + F19 = 0x6e + F20 = 0x6f + F21 = 0x70 + F22 = 0x71 + F23 = 0x72 + F24 = 0x73 + GUI = 0xe3 + ONE = 0x1e + SIX = 0x23 + TAB = 0x2b + TWO = 0x1f + FIVE = 0x22 + FOUR = 0x21 + HOME = 0x4a + NINE = 0x26 + ZERO = 0x27 + ALTGR = 0xe6 + COMMA = 0x10 + EIGHT = 0x25 + ENTER = 0x28 + GRAVE = 0x24 + OEM_8 = 0x38 + PAUSE = 0x48 + QUOTE = 0x35 + SEVEN = 0x24 + SHIFT = 0xe1 + SPACE = 0x2c + THREE = 0x20 + TILDE = 0x1f + TREMA = 0x2f + ACCENT_CIRCONFLEXE = 0x2f + APPLICATION = 0x65 + BACKSLASH = 0x31 + BACKSPACE = 0x2a + CAPS_LOCK = 0x39 + COMMAND = 0xe3 + CONTROL = 0xe0 + DELETE = 0x4c + DOWN_ARROW = 0x51 + EQUALS = 0x2e + ESCAPE = 0x29 + FORWARD_SLASH = 0x37 + GRAVE_ACCENT = 0x34 + INSERT = 0x49 + KEYPAD_ASTERISK = 0x55 + KEYPAD_EIGHT = 0x60 + KEYPAD_FIVE = 0x5d + KEYPAD_FORWARD_SLASH = 0x54 + KEYPAD_FOUR = 0x5c + KEYPAD_MINUS = 0x56 + KEYPAD_NINE = 0x61 + KEYPAD_NUMLOCK = 0x53 + KEYPAD_ONE = 0x59 + KEYPAD_PERIOD = 0x63 + KEYPAD_PLUS = 0x57 + KEYPAD_SEVEN = 0x5f + KEYPAD_SIX = 0x5e + KEYPAD_THREE = 0x5b + KEYPAD_TWO = 0x5a + KEYPAD_ZERO = 0x62 + LEFT_ALT = 0xe2 + LEFT_ARROW = 0x50 + LEFT_BRACKET = 0x2d + LEFT_CONTROL = 0xe0 + LEFT_GUI = 0xe3 + LEFT_SHIFT = 0xe1 + OEM_102 = 0x64 + OPTION = 0xe2 + PAGE_DOWN = 0x4e + PAGE_UP = 0x4b + PERIOD = 0x36 + PRINT_SCREEN = 0x46 + RETURN = 0x28 + RIGHT_ALT = 0xe6 + RIGHT_ARROW = 0x4f + RIGHT_BRACKET = 0x2f + RIGHT_CONTROL = 0xe4 + RIGHT_GUI = 0xe7 + RIGHT_SHIFT = 0xe5 + SCROLL_LOCK = 0x47 + SEMICOLON = 0x30 + SPACEBAR = 0x2c + UP_ARROW = 0x52 + WINDOWS = 0xe3 + + @classmethod + def modifier_bit(cls, keycode): + """Return the modifer bit to be set in an HID keycode report if this is a + modifier key; otherwise return 0.""" + return ( + 1 << (keycode - 0xE0) if cls.LEFT_CONTROL <= keycode <= cls.RIGHT_GUI else 0 + ) + \ No newline at end of file