py3port: fix single-keypress terminal input

This commit is contained in:
The MMGen Project 2018-10-31 16:00:13 +00:00
commit cc3678619c
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
3 changed files with 20 additions and 18 deletions

View file

@ -127,16 +127,13 @@ def _get_random_data_from_user(uchars):
m = 'Enter {} random symbols' if opt.quiet else crmsg['usr_rand_notice']
msg(m.format(uchars))
prompt = 'You may begin typing. {} symbols left: '
msg_r(prompt.format(uchars))
import time
from mmgen.term import get_char_raw,kb_hold_protect
key_data,time_data = '',[]
key_data,time_data = bytes(),[]
for i in range(uchars):
kb_hold_protect()
key_data += get_char_raw()
msg_r('\r'+prompt.format(uchars-i-1))
key_data += get_char_raw('\r'+prompt.format(uchars-i))
time_data.append(time.time())
if opt.quiet: msg_r('\r')

View file

@ -396,7 +396,7 @@ class Mnemonic (SeedSourceUnenc):
def get_word():
s,pad = '',0
while True:
ch = get_char_raw('').decode()
ch = get_char_raw('',num_chars=1).decode()
if ch in '\b\x7f':
if s: s = s[:-1]
elif ch in '\n ':

View file

@ -38,6 +38,8 @@ except:
def _kb_hold_protect_unix():
if os.getenv('MMGEN_TEST_SUITE'): return
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
tty.setcbreak(fd)
@ -54,36 +56,39 @@ def _kb_hold_protect_unix():
# Use os.read(), not file.read(), to get a variable number of bytes without blocking.
# Request 5 bytes to cover escape sequences generated by F1, F2, .. Fn keys (5 bytes)
# as well as UTF8 chars (4 bytes max).
def _get_keypress_unix(prompt='',immed_chars='',prehold_protect=True):
msg_r(prompt)
def _get_keypress_unix(prompt='',immed_chars='',prehold_protect=True,num_chars=5):
fd_err = sys.stderr.fileno()
os.write(fd_err,prompt.encode())
timeout = float(0.3)
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
tty.setcbreak(fd)
immed_chars = immed_chars.encode()
if os.getenv('MMGEN_TEST_SUITE'): prehold_protect = False
while True:
# Protect against held-down key before read()
key = select([sys.stdin], [], [], timeout)[0]
ch = os.read(fd,5)
s = os.read(fd,num_chars)
if prehold_protect:
if key: continue
if immed_chars == 'ALL' or ch in immed_chars: break
if immed_chars == 'ALL_EXCEPT_ENTER' and not ch in '\n\r': break
if immed_chars == 'ALL' or s in immed_chars: break
if immed_chars == 'ALL_EXCEPT_ENTER' and not s in '\n\r': break
# Protect against long keypress
key = select([sys.stdin], [], [], timeout)[0]
if not key: break
termios.tcsetattr(fd, termios.TCSADRAIN, old)
return ch
return s
def _get_keypress_unix_raw(prompt='',immed_chars='',prehold_protect=None):
def _get_keypress_unix_raw(prompt='',immed_chars='',prehold_protect=None,num_chars=5):
msg_r(prompt)
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
tty.setcbreak(fd)
ch = os.read(fd,5)
ch = os.read(fd,num_chars)
termios.tcsetattr(fd, termios.TCSADRAIN, old)
return ch
def _get_keypress_unix_stub(prompt='',immed_chars='',prehold_protect=None):
def _get_keypress_unix_stub(prompt='',immed_chars='',prehold_protect=None,num_chars=None):
msg_r(prompt)
return sys.stdin.read(1).encode()
@ -102,7 +107,7 @@ def _kb_hold_protect_mswin():
if float(time.time() - hit_time) > timeout:
return
def _get_keypress_mswin(prompt='',immed_chars='',prehold_protect=True):
def _get_keypress_mswin(prompt='',immed_chars='',prehold_protect=True,num_chars=None):
msg_r(prompt)
timeout = float(0.5)
@ -125,14 +130,14 @@ def _get_keypress_mswin(prompt='',immed_chars='',prehold_protect=True):
if float(time.time() - hit_time) > timeout:
return ch
def _get_keypress_mswin_raw(prompt='',immed_chars='',prehold_protect=None):
def _get_keypress_mswin_raw(prompt='',immed_chars='',prehold_protect=None,num_chars=None):
msg_r(prompt)
ch = msvcrt.getch()
if ord(ch) == 3: raise KeyboardInterrupt
return ch
def _get_keypress_mswin_stub(prompt='',immed_chars='',prehold_protect=None):
def _get_keypress_mswin_stub(prompt='',immed_chars='',prehold_protect=None,num_chars=None):
msg_r(prompt)
return sys.stdin.read(1)