| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | """ |
| | Utilities relating to parsing raw characters from the keyboard, based on https://github.com/bchao1/bullet |
| | """ |
| |
|
| | import os |
| | import string |
| | import sys |
| |
|
| |
|
| | ARROW_KEY_FLAG = 1 << 8 |
| |
|
| | KEYMAP = { |
| | "tab": ord("\t"), |
| | "newline": ord("\r"), |
| | "esc": 27, |
| | "up": 65 + ARROW_KEY_FLAG, |
| | "down": 66 + ARROW_KEY_FLAG, |
| | "right": 67 + ARROW_KEY_FLAG, |
| | "left": 68 + ARROW_KEY_FLAG, |
| | "mod_int": 91, |
| | "undefined": sys.maxsize, |
| | "interrupt": 3, |
| | "insert": 50, |
| | "delete": 51, |
| | "pg_up": 53, |
| | "pg_down": 54, |
| | } |
| |
|
| | KEYMAP["arrow_begin"] = KEYMAP["up"] |
| | KEYMAP["arrow_end"] = KEYMAP["left"] |
| |
|
| | if sys.platform == "win32": |
| | WIN_CH_BUFFER = [] |
| | WIN_KEYMAP = { |
| | b"\xe0H": KEYMAP["up"] - ARROW_KEY_FLAG, |
| | b"\x00H": KEYMAP["up"] - ARROW_KEY_FLAG, |
| | b"\xe0P": KEYMAP["down"] - ARROW_KEY_FLAG, |
| | b"\x00P": KEYMAP["down"] - ARROW_KEY_FLAG, |
| | b"\xe0M": KEYMAP["right"] - ARROW_KEY_FLAG, |
| | b"\x00M": KEYMAP["right"] - ARROW_KEY_FLAG, |
| | b"\xe0K": KEYMAP["left"] - ARROW_KEY_FLAG, |
| | b"\x00K": KEYMAP["left"] - ARROW_KEY_FLAG, |
| | } |
| |
|
| | for i in range(10): |
| | KEYMAP[str(i)] = ord(str(i)) |
| |
|
| |
|
| | def get_raw_chars(): |
| | "Gets raw characters from inputs" |
| | if os.name == "nt": |
| | import msvcrt |
| |
|
| | encoding = "mbcs" |
| | |
| | while msvcrt.kbhit(): |
| | msvcrt.getch() |
| | if len(WIN_CH_BUFFER) == 0: |
| | |
| | ch = msvcrt.getch() |
| |
|
| | |
| | if ch in (b"\x00", b"\xe0"): |
| | ch2 = ch + msvcrt.getch() |
| | |
| | try: |
| | chx = chr(WIN_KEYMAP[ch2]) |
| | WIN_CH_BUFFER.append(chr(KEYMAP["mod_int"])) |
| | WIN_CH_BUFFER.append(chx) |
| | if ord(chx) in ( |
| | KEYMAP["insert"] - 1 << 9, |
| | KEYMAP["delete"] - 1 << 9, |
| | KEYMAP["pg_up"] - 1 << 9, |
| | KEYMAP["pg_down"] - 1 << 9, |
| | ): |
| | WIN_CH_BUFFER.append(chr(126)) |
| | ch = chr(KEYMAP["esc"]) |
| | except KeyError: |
| | ch = ch2[1] |
| | else: |
| | ch = ch.decode(encoding) |
| | else: |
| | ch = WIN_CH_BUFFER.pop(0) |
| | elif os.name == "posix": |
| | import termios |
| | import tty |
| |
|
| | fd = sys.stdin.fileno() |
| | old_settings = termios.tcgetattr(fd) |
| | try: |
| | tty.setraw(fd) |
| | ch = sys.stdin.read(1) |
| | finally: |
| | termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) |
| | return ch |
| |
|
| |
|
| | def get_character(): |
| | "Gets a character from the keyboard and returns the key code" |
| | char = get_raw_chars() |
| | if ord(char) in [KEYMAP["interrupt"], KEYMAP["newline"]]: |
| | return char |
| |
|
| | elif ord(char) == KEYMAP["esc"]: |
| | combo = get_raw_chars() |
| | if ord(combo) == KEYMAP["mod_int"]: |
| | key = get_raw_chars() |
| | if ord(key) >= KEYMAP["arrow_begin"] - ARROW_KEY_FLAG and ord(key) <= KEYMAP["arrow_end"] - ARROW_KEY_FLAG: |
| | return chr(ord(key) + ARROW_KEY_FLAG) |
| | else: |
| | return KEYMAP["undefined"] |
| | else: |
| | return get_raw_chars() |
| |
|
| | else: |
| | if char in string.printable: |
| | return char |
| | else: |
| | return KEYMAP["undefined"] |
| |
|