From 2d36b21595b1b554e78491603d977d9d425af4fb Mon Sep 17 00:00:00 2001 From: Cefn Hoile Date: Fri, 8 Jun 2018 10:29:50 +0100 Subject: Added extra codes from miniterm_mpy.py and finalised setconsolemode shenanigans. --- serial/tools/miniterm.py | 54 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py index 83d8dbd..a113db3 100644 --- a/serial/tools/miniterm.py +++ b/serial/tools/miniterm.py @@ -88,7 +88,6 @@ class ConsoleBase(object): if os.name == 'nt': # noqa import msvcrt import ctypes - import ctypes.wintypes as wintypes import platform class Out(object): @@ -104,28 +103,51 @@ if os.name == 'nt': # noqa os.write(self.fd, s) class Console(ConsoleBase): - nav = { + fncodes = { + ';': '\1bOP', # F1 + '<': '\1bOQ', # F2 + '=': '\1bOR', # F3 + '>': '\1bOS', # F4 + '?': '\1b[15~', # F5 + '@': '\1b[17~', # F6 + 'A': '\1b[18~', # F7 + 'B': '\1b[19~', # F8 + 'C': '\1b[20~', # F9 + 'D': '\1b[21~', # F10 + } + navcodes = { 'H': '\x1b[A', # UP 'P': '\x1b[B', # DOWN 'K': '\x1b[D', # LEFT 'M': '\x1b[C', # RIGHT 'G': '\x1b[H', # HOME 'O': '\x1b[F', # END + 'R': '\x1b[2~', # INSERT + 'S': '\x1b[3~', # DELETE + 'I': '\x1b[5~', # PGUP + 'Q': '\x1b[6~', # PGDN } def __init__(self): super(Console, self).__init__() - if not hasattr(wintypes, 'LPDWORD'): # PY2 - wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) - self._saved_cm = mode = wintypes.DWORD() - ctypes.windll.kernel32.GetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), ctypes.byref(self._saved_cm)) self._saved_ocp = ctypes.windll.kernel32.GetConsoleOutputCP() self._saved_icp = ctypes.windll.kernel32.GetConsoleCP() ctypes.windll.kernel32.SetConsoleOutputCP(65001) ctypes.windll.kernel32.SetConsoleCP(65001) - # ANSI handling available through SetConsoleMode since v1511 + # ANSI handling available through SetConsoleMode since v1511 https://en.wikipedia.org/wiki/ANSI_escape_code#cite_note-win10th2-1 if platform.release() == '10' and int(platform.version().split('.')[2]) > 10586: - ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), 0x7) + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + import ctypes.wintypes as wintypes + if not hasattr(wintypes, 'LPDWORD'): # PY2 + wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) + SetConsoleMode = ctypes.windll.kernel32.SetConsoleMode + GetConsoleMode = ctypes.windll.kernel32.GetConsoleMode + GetStdHandle = ctypes.windll.kernel32.GetStdHandle + mode = wintypes.DWORD() + GetConsoleMode(GetStdHandle(-11), ctypes.byref(mode)) + if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0: + SetConsoleMode(GetStdHandle(-11), mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) + self._saved_cm = mode self.output = codecs.getwriter('UTF-8')(Out(sys.stdout.fileno()), 'replace') # the change of the code page is not propagated to Python, manually fix it sys.stderr = codecs.getwriter('UTF-8')(Out(sys.stderr.fileno()), 'replace') @@ -135,19 +157,23 @@ if os.name == 'nt': # noqa def __del__(self): ctypes.windll.kernel32.SetConsoleOutputCP(self._saved_ocp) ctypes.windll.kernel32.SetConsoleCP(self._saved_icp) - ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), self._saved_cm) + try: + ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), self._saved_cm) + except AttributeError: # in case no _saved_cm + pass def getkey(self): while True: z = msvcrt.getwch() if z == unichr(13): return unichr(10) - elif z in unichr(0): # functions keys, ignore - msvcrt.getwch() - elif z in unichr(0xe0): # map special keys - code = msvcrt.getwch() + elif z is unichr(0) or z is unichr(0xe0): try: - return self.nav[code] + code = msvcrt.getwch() + if z is unichr(0): + return self.fncodes[code] + else: + return self.navcodes[code] except KeyError: pass else: -- cgit v1.2.1