Source code for adafruit_hid.keyboard_layout_us

# The MIT License (MIT)
#
# Copyright (c) 2017 Dan Halbert
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

"""
`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() 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