Source code for adafruit_hid.keyboard_layout_us

# SPDX-FileCopyrightText: 2017 Dan Halbert for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`adafruit_hid.keyboard_layout_us.KeyboardLayoutUS`
=======================================================

* Author(s): Dan Halbert
"""

from .keycode import Keycode


[docs]class KeyboardLayoutUS: """Map ASCII characters to appropriate keypresses on a standard US PC keyboard. Non-ASCII characters and most control characters will raise an exception. """ # The ASCII_TO_KEYCODE bytes object is used as a table to maps ASCII 0-127 # to the corresponding # keycode on a US 104-key keyboard. # The user should not normally need to use this table, # but it is not marked as private. # # Because the table only goes to 127, we use the top bit of each byte (ox80) to indicate # that the shift key should be pressed. So any values 0x{8,9,a,b}* are shifted characters. # # The Python compiler will concatenate all these bytes literals into a single bytes object. # Micropython/CircuitPython will store the resulting bytes constant in flash memory # if it's in a .mpy file, so it doesn't use up valuable RAM. # # \x00 entries have no keyboard key and so won't be sent. SHIFT_FLAG = 0x80 ASCII_TO_KEYCODE = ( b"\x00" # NUL b"\x00" # SOH b"\x00" # STX b"\x00" # ETX b"\x00" # EOT b"\x00" # ENQ b"\x00" # ACK b"\x00" # BEL \a b"\x2a" # BS BACKSPACE \b (called DELETE in the usb.org document) b"\x2b" # TAB \t b"\x28" # LF \n (called Return or ENTER in the usb.org document) b"\x00" # VT \v b"\x00" # FF \f b"\x00" # CR \r b"\x00" # SO b"\x00" # SI b"\x00" # DLE b"\x00" # DC1 b"\x00" # DC2 b"\x00" # DC3 b"\x00" # DC4 b"\x00" # NAK b"\x00" # SYN b"\x00" # ETB b"\x00" # CAN b"\x00" # EM b"\x00" # SUB b"\x29" # ESC b"\x00" # FS b"\x00" # GS b"\x00" # RS b"\x00" # US b"\x2c" # SPACE b"\x9e" # ! x1e|SHIFT_FLAG (shift 1) b"\xb4" # " x34|SHIFT_FLAG (shift ') b"\xa0" # # x20|SHIFT_FLAG (shift 3) b"\xa1" # $ x21|SHIFT_FLAG (shift 4) b"\xa2" # % x22|SHIFT_FLAG (shift 5) b"\xa4" # & x24|SHIFT_FLAG (shift 7) b"\x34" # ' b"\xa6" # ( x26|SHIFT_FLAG (shift 9) b"\xa7" # ) x27|SHIFT_FLAG (shift 0) b"\xa5" # * x25|SHIFT_FLAG (shift 8) b"\xae" # + x2e|SHIFT_FLAG (shift =) b"\x36" # , b"\x2d" # - b"\x37" # . b"\x38" # / b"\x27" # 0 b"\x1e" # 1 b"\x1f" # 2 b"\x20" # 3 b"\x21" # 4 b"\x22" # 5 b"\x23" # 6 b"\x24" # 7 b"\x25" # 8 b"\x26" # 9 b"\xb3" # : x33|SHIFT_FLAG (shift ;) b"\x33" # ; b"\xb6" # < x36|SHIFT_FLAG (shift ,) b"\x2e" # = b"\xb7" # > x37|SHIFT_FLAG (shift .) b"\xb8" # ? x38|SHIFT_FLAG (shift /) b"\x9f" # @ x1f|SHIFT_FLAG (shift 2) b"\x84" # A x04|SHIFT_FLAG (shift a) b"\x85" # B x05|SHIFT_FLAG (etc.) b"\x86" # C x06|SHIFT_FLAG b"\x87" # D x07|SHIFT_FLAG b"\x88" # E x08|SHIFT_FLAG b"\x89" # F x09|SHIFT_FLAG b"\x8a" # G x0a|SHIFT_FLAG b"\x8b" # H x0b|SHIFT_FLAG b"\x8c" # I x0c|SHIFT_FLAG b"\x8d" # J x0d|SHIFT_FLAG b"\x8e" # K x0e|SHIFT_FLAG b"\x8f" # L x0f|SHIFT_FLAG b"\x90" # M x10|SHIFT_FLAG b"\x91" # N x11|SHIFT_FLAG b"\x92" # O x12|SHIFT_FLAG b"\x93" # P x13|SHIFT_FLAG b"\x94" # Q x14|SHIFT_FLAG b"\x95" # R x15|SHIFT_FLAG b"\x96" # S x16|SHIFT_FLAG b"\x97" # T x17|SHIFT_FLAG b"\x98" # U x18|SHIFT_FLAG b"\x99" # V x19|SHIFT_FLAG b"\x9a" # W x1a|SHIFT_FLAG b"\x9b" # X x1b|SHIFT_FLAG b"\x9c" # Y x1c|SHIFT_FLAG b"\x9d" # Z x1d|SHIFT_FLAG b"\x2f" # [ b"\x31" # \ backslash b"\x30" # ] b"\xa3" # ^ x23|SHIFT_FLAG (shift 6) b"\xad" # _ x2d|SHIFT_FLAG (shift -) b"\x35" # ` b"\x04" # 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"\x10" # m b"\x11" # n b"\x12" # o b"\x13" # p b"\x14" # q b"\x15" # r b"\x16" # s b"\x17" # t b"\x18" # u b"\x19" # v b"\x1a" # w b"\x1b" # x b"\x1c" # y b"\x1d" # z b"\xaf" # { x2f|SHIFT_FLAG (shift [) b"\xb1" # | x31|SHIFT_FLAG (shift \) b"\xb0" # } x30|SHIFT_FLAG (shift ]) b"\xb5" # ~ x35|SHIFT_FLAG (shift `) b"\x4c" # DEL DELETE (called Forward Delete in usb.org document) ) def __init__(self, keyboard): """Specify the layout for the given keyboard. :param keyboard: a Keyboard object. Write characters to this keyboard when requested. Example:: kbd = Keyboard(usb_hid.devices) layout = KeyboardLayoutUS(kbd) """ self.keyboard = keyboard
[docs] def write(self, string): """Type the string by pressing and releasing keys on my keyboard. :param string: A string of ASCII characters. :raises ValueError: if any of the characters are not ASCII or have no keycode (such as some control characters). Example:: # Write abc followed by Enter to the keyboard layout.write('abc\\n') """ for char in string: keycode = self._char_to_keycode(char) # If this is a shifted char, clear the SHIFT flag and press the SHIFT key. if keycode & self.SHIFT_FLAG: keycode &= ~self.SHIFT_FLAG self.keyboard.press(Keycode.SHIFT) self.keyboard.press(keycode) self.keyboard.release_all()
[docs] def keycodes(self, char): """Return a tuple of keycodes needed to type the given character. :param char: A single ASCII character in a string. :type char: str of length one. :returns: tuple of Keycode keycodes. :raises ValueError: if ``char`` is not ASCII or there is no keycode for it. Examples:: # Returns (Keycode.TAB,) keycodes('\t') # Returns (Keycode.A,) keycode('a') # Returns (Keycode.SHIFT, Keycode.A) keycode('A') # Raises ValueError because it's a accented e and is not ASCII keycode('é') """ keycode = self._char_to_keycode(char) if keycode & self.SHIFT_FLAG: return (Keycode.SHIFT, keycode & ~self.SHIFT_FLAG) return (keycode,)
def _char_to_keycode(self, char): """Return the HID keycode for the given ASCII character, with the SHIFT_FLAG possibly set. If the character requires pressing the Shift key, the SHIFT_FLAG bit is set. You must clear this bit before passing the keycode in a USB report. """ char_val = ord(char) if char_val > 128: raise ValueError("Not an ASCII character.") keycode = self.ASCII_TO_KEYCODE[char_val] if keycode == 0: raise ValueError("No keycode available for character.") return keycode