From d64fb603a895bb26bf6797ca607602471f151449 Mon Sep 17 00:00:00 2001 From: Cefn Hoile Date: Fri, 8 Jun 2018 09:46:28 +0100 Subject: First proven version with minimal nav keys --- serial/tools/miniterm.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py index 3b8d5d2..83d8dbd 100644 --- a/serial/tools/miniterm.py +++ b/serial/tools/miniterm.py @@ -88,6 +88,8 @@ class ConsoleBase(object): if os.name == 'nt': # noqa import msvcrt import ctypes + import ctypes.wintypes as wintypes + import platform class Out(object): """file-like wrapper that uses os.write""" @@ -102,12 +104,28 @@ if os.name == 'nt': # noqa os.write(self.fd, s) class Console(ConsoleBase): + nav = { + 'H': '\x1b[A', # UP + 'P': '\x1b[B', # DOWN + 'K': '\x1b[D', # LEFT + 'M': '\x1b[C', # RIGHT + 'G': '\x1b[H', # HOME + 'O': '\x1b[F', # END + } + 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 + if platform.release() == '10' and int(platform.version().split('.')[2]) > 10586: + ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), 0x7) 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') @@ -117,14 +135,21 @@ 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) def getkey(self): while True: z = msvcrt.getwch() if z == unichr(13): return unichr(10) - elif z in (unichr(0), unichr(0x0e)): # functions keys, ignore + elif z in unichr(0): # functions keys, ignore msvcrt.getwch() + elif z in unichr(0xe0): # map special keys + code = msvcrt.getwch() + try: + return self.nav[code] + except KeyError: + pass else: return z @@ -986,3 +1011,4 @@ def main(default_port=None, default_baudrate=9600, default_rts=None, default_dtr # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if __name__ == '__main__': main() + -- cgit v1.2.1 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 From d46bab8f9222e816f13491dd4af70a1077ade7cd Mon Sep 17 00:00:00 2001 From: Cefn Hoile Date: Fri, 8 Jun 2018 10:31:34 +0100 Subject: Remove spurious newline --- serial/tools/miniterm.py | 1 - 1 file changed, 1 deletion(-) diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py index a113db3..5736e7a 100644 --- a/serial/tools/miniterm.py +++ b/serial/tools/miniterm.py @@ -1037,4 +1037,3 @@ def main(default_port=None, default_baudrate=9600, default_rts=None, default_dtr # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if __name__ == '__main__': main() - -- cgit v1.2.1 From 035053d61d3fc54a71914fd77da22e75b2779c26 Mon Sep 17 00:00:00 2001 From: Cefn Hoile Date: Fri, 8 Jun 2018 10:45:18 +0100 Subject: Manually wrap comment. Add note of Windows 10 compatibility. --- serial/tools/miniterm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py index 5736e7a..2ec155e 100644 --- a/serial/tools/miniterm.py +++ b/serial/tools/miniterm.py @@ -134,7 +134,8 @@ if os.name == 'nt': # noqa self._saved_icp = ctypes.windll.kernel32.GetConsoleCP() ctypes.windll.kernel32.SetConsoleOutputCP(65001) ctypes.windll.kernel32.SetConsoleCP(65001) - # ANSI handling available through SetConsoleMode since v1511 https://en.wikipedia.org/wiki/ANSI_escape_code#cite_note-win10th2-1 + # ANSI handling available through SetConsoleMode since Windows 10 v1511 + # https://en.wikipedia.org/wiki/ANSI_escape_code#cite_note-win10th2-1 if platform.release() == '10' and int(platform.version().split('.')[2]) > 10586: ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 import ctypes.wintypes as wintypes -- cgit v1.2.1