| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| """ |
| 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"] |
|
|