summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCefn Hoile <github.com@cefn.com>2018-06-08 10:29:50 +0100
committerCefn Hoile <github.com@cefn.com>2018-06-08 10:29:50 +0100
commit2d36b21595b1b554e78491603d977d9d425af4fb (patch)
treeda63b8ad86fc35e6f4992a81482058e007a9e50a
parentd64fb603a895bb26bf6797ca607602471f151449 (diff)
downloadpyserial-git-2d36b21595b1b554e78491603d977d9d425af4fb.tar.gz
Added extra codes from miniterm_mpy.py and finalised setconsolemode shenanigans.
-rw-r--r--serial/tools/miniterm.py54
1 files 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: