From 06c03bca13b66b332275fb5d5c0b4f6519f4b55e Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Thu, 12 Sep 2024 19:34:55 -0400 Subject: [PATCH] zti buffer for keylock Signed-off-by: Neil Johnson --- tnz/zti.py | 341 +++++++++++++++++------------------------------------ 1 file changed, 110 insertions(+), 231 deletions(-) diff --git a/tnz/zti.py b/tnz/zti.py index 1169670..b264099 100644 --- a/tnz/zti.py +++ b/tnz/zti.py @@ -25,6 +25,7 @@ TERM_PROGRAM (see _termlib.py) TNZ_COLORS (see tnz.py) TNZ_LOGGING (see tnz.py) + ZTI_AIDBUFSIZE (9 is default) ZTI_AUTOSIZE ZTI_SECLEVEL (see tnz.py) ZTI_TITLE @@ -1980,6 +1981,7 @@ def __r2d2(self, win, waitc, timeout): self.__refresh() refresh = False paste = None + keylock_aidbuf = [] # aid callables buffered for KEYLOCK = 1 try: while True: @@ -2005,10 +2007,12 @@ def __r2d2(self, win, waitc, timeout): return 12 if tns.ddmdata or tns.ddmdict: + # TODO what if keylock_aidbuf? return 10 # have ddmdata if self.downloadaction: self.downloadaction = False + # TODO what if keylock_aidbuf? return 11 # have download action if ((self.rewrite or @@ -2040,6 +2044,7 @@ def __r2d2(self, win, waitc, timeout): if self.cmdqueue: # plugin added cmd to process? self.shell_mode() + # TODO what if keylock_aidbuf? return 1 # timeout? cstr = self.__tty_read(win, tout) @@ -2060,10 +2065,12 @@ def __r2d2(self, win, waitc, timeout): return 12 # seslost if tns.ddmdata or tns.ddmdict: + # TODO what if keylock_aidbuf? return 10 # have ddmdata if self.downloadaction: self.downloadaction = False + # TODO what if keylock_aidbuf? return 11 # have download action # check for Alt+letter shortcut @@ -2093,6 +2100,7 @@ def __r2d2(self, win, waitc, timeout): # process input + aid_callable = None if not cstr: # session update pass @@ -2110,6 +2118,9 @@ def __r2d2(self, win, waitc, timeout): elif cstr == "\x1b" or cstr == "KEY_ESC": # ESC _logger.debug("keyed Esc") + if keylock_aidbuf: # if not all keys were processed + curses.beep() # signal user something happened + return cstr elif cstr == "KEY_RESIZE": @@ -2129,6 +2140,10 @@ def __r2d2(self, win, waitc, timeout): curses.flash() + elif (keylock_aidbuf and + not tns.pwait and not tns.system_lock_wait): + pass # process keylock_aidbuf below + elif cstr.startswith("\x1b[200~"): # bracketed paste paste = cstr[6:] @@ -2136,6 +2151,7 @@ def __r2d2(self, win, waitc, timeout): paste = paste[:-6] if paste: if tns.pwait or tns.system_lock_wait: + keylock_aidbuf.clear() # cancel, paste curses.flash() curses.beep() else: @@ -2148,6 +2164,7 @@ def __r2d2(self, win, waitc, timeout): paste += cstr[:-6] if paste: if tns.pwait or tns.system_lock_wait: + keylock_aidbuf.clear() # cancel, paste curses.flash() curses.beep() else: @@ -2172,16 +2189,13 @@ def __r2d2(self, win, waitc, timeout): win.erase() win.noutrefresh() - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.clear() + aid_callable = tns.clear elif len(cstr) == 1 and cstr.isprintable(): keylock = ati.value("KEYLOCK", trace=False) if keylock == "1": + keylock_aidbuf.clear() # cancel, key data curses.flash() else: if insmode: @@ -2191,22 +2205,16 @@ def __r2d2(self, win, waitc, timeout): elif cstr == "\r": _logger.debug("keyed Enter") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.enter() - self.rewrite_keylock = True + aid_callable = tns.enter elif cstr == "\n": _logger.debug("keyed Shift+Enter") - + # TODO need to handle keylock tns.key_newline() elif cstr == "\t": _logger.debug("keyed Tab") - + # TODO need to handle keylock tns.key_tab(zti=self) self.rewrite_cursor = True @@ -2214,7 +2222,7 @@ def __r2d2(self, win, waitc, timeout): cstr == "KEY_BACKSPACE" or cstr == "\x7f"): _logger.debug("keyed Backspace") - + # TODO need to handle keylock tns.key_backspace(zti=self) self.rewrite_cursor = True @@ -2223,12 +2231,12 @@ def __r2d2(self, win, waitc, timeout): cstr == "\x1b[F" or # Shift+End cstr == "KEY_SEND"): # Shift+End _logger.debug("keyed Shift+End or Ctrl+K") - + # TODO need to handle keylock tns.key_eraseeof(zti=self) elif cstr == "KEY_END": # End _logger.debug("keyed End") - + # TODO need to handle keylock tns.key_end() self.rewrite_cursor = True @@ -2236,25 +2244,26 @@ def __r2d2(self, win, waitc, timeout): cstr == "\x1b H" or cstr == "KEY_HOME"): _logger.debug("keyed Home") - + # TODO need to handle keylock tns.key_home(zti=self) self.rewrite_cursor = True elif cstr == "KEY_DC": _logger.debug("keyed Delete") - + # TODO need to handle keylock tns.key_delete(zti=self) elif (cstr == "KEY_BTAB" or # Shift+Tab cstr == "\x1b[~"): # Shift+Tab Windows->ssh _logger.debug("keyed Shift+Tab") - + # TODO need to handle keylock tns.key_backtab(zti=self) self.rewrite_cursor = True elif altc > 0: if tns.pwait or tns.system_lock_wait: + keylock_aidbuf.clear() # cancel, Alt+letter curses.flash() curses.beep() else: @@ -2265,45 +2274,33 @@ def __r2d2(self, win, waitc, timeout): elif cstr == "KEY_PPAGE": # PgUp _logger.debug("keyed PgUp") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf7() - self.rewrite_keylock = True + aid_callable = tns.pf7 elif cstr == "KEY_NPAGE": # PgDn _logger.debug("keyed PgDn") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf8() - self.rewrite_keylock = True + aid_callable = tns.pf8 elif cstr == "KEY_UP": _logger.debug("keyed Up") - + # TODO need to handle keylock tns.key_curup(zti=self) self.rewrite_cursor = True elif cstr == "KEY_DOWN": _logger.debug("keyed Dn") - + # TODO need to handle keylock tns.key_curdown(zti=self) self.rewrite_cursor = True elif cstr == "KEY_LEFT": _logger.debug("keyed Left") - + # TODO need to handle keylock tns.key_curleft(zti=self) self.rewrite_cursor = True elif cstr == "KEY_RIGHT": _logger.debug("keyed Right") - + # TODO need to handle keylock tns.key_curright(zti=self) self.rewrite_cursor = True @@ -2311,7 +2308,7 @@ def __r2d2(self, win, waitc, timeout): "\x1bb", # Alt+LEFT (Terminal.app) "\x1b[1;3D"): # Alt+LEFT (Windows) _logger.debug("keyed Alt+Left") - + # TODO need to handle keylock tns.key_word_left() self.rewrite_cursor = True @@ -2319,7 +2316,7 @@ def __r2d2(self, win, waitc, timeout): "\x1bf", # Alt+RIGHT (Terminal.app) "\x1b[1;3C"): # Alt+RIGHT (Windows) _logger.debug("keyed Alt+Right") - + # TODO need to handle keylock tns.key_word_right() self.rewrite_cursor = True @@ -2341,6 +2338,7 @@ def __r2d2(self, win, waitc, timeout): if tns.pwait or tns.system_lock_wait: # Assume Attention needed for z/VM tns.send_aid(0x6c) # AID_PA1 + keylock_aidbuf.clear() # cancel, PA1 else: tns.pa1() self.rewrite_keylock = True @@ -2350,295 +2348,132 @@ def __r2d2(self, win, waitc, timeout): cstr == "\x1b\x1b[1~" or # ESC+Home (Alt+Home) cstr == "ALT_HOME"): # Alt+Home _logger.debug("keyed Alt+2 or Alt+Home") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pa2() - self.rewrite_keylock = True + aid_callable = tns.pa2 elif (cstr == "\x1b3" or # ESC+3 (Alt+3) cstr == "ALT_3"): # ESC+3 (Alt+3) _logger.debug("keyed Alt+3") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pa3() - self.rewrite_keylock = True + aid_callable = tns.pa3 elif (cstr == "\x1ba" or # ESC+a (Alt+A) cstr == "ALT_A" or # ESC+a (Alt+A) cstr == "\x03"): # Ctrl+C _logger.debug("keyed Alt+A or Ctrl+C") - + keylock_aidbuf.clear() tns.attn() elif (cstr == "\x1bc" or # ESC+c (Alt+c) cstr == "ALT_C"): # ESC+c (Alt+c) _logger.debug("keyed Alt+C") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.clear() - self.rewrite = True - self.rewrite_keylock = True + aid_callable = tns.clear elif (cstr == "KEY_F(1)" or cstr == "\x1b[11~"): _logger.debug("keyed F1") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf1() - self.rewrite_keylock = True + aid_callable = tns.pf1 elif (cstr == "KEY_F(2)" or cstr == "\x1b[12~"): _logger.debug("keyed F2") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf2() - self.rewrite_keylock = True + aid_callable = tns.pf2 elif (cstr == "KEY_F(3)" or cstr == "\x1b[13~"): _logger.debug("keyed F3") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf3() - self.rewrite_keylock = True + aid_callable = tns.pf3 elif (cstr == "KEY_F(4)" or cstr == "\x1b[14~"): _logger.debug("keyed F4") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf4() - self.rewrite_keylock = True + aid_callable = tns.pf4 elif cstr == "KEY_F(5)": _logger.debug("keyed F5") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf5() - self.rewrite_keylock = True + aid_callable = tns.pf5 elif cstr == "KEY_F(6)": _logger.debug("keyed F6") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf6() - self.rewrite_keylock = True + aid_callable = tns.pf6 elif cstr == "KEY_F(7)": _logger.debug("keyed F7") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf7() - self.rewrite_keylock = True + aid_callable = tns.pf7 elif cstr == "KEY_F(8)": _logger.debug("keyed F8") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf8() - self.rewrite_keylock = True + aid_callable = tns.pf8 elif cstr == "KEY_F(9)": _logger.debug("keyed F9") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf9() - self.rewrite_keylock = True + aid_callable = tns.pf9 elif cstr == "KEY_F(10)": _logger.debug("keyed F10") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf10() - self.rewrite_keylock = True + aid_callable = tns.pf10 elif cstr == "KEY_F(11)": _logger.debug("keyed F11") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf11() - self.rewrite_keylock = True + aid_callable = tns.pf11 elif cstr == "KEY_F(12)": _logger.debug("keyed F12") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf12() - self.rewrite_keylock = True + aid_callable = tns.pf12 elif cstr == "KEY_F(13)": _logger.debug("keyed Shift+F1") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf13() - self.rewrite_keylock = True + aid_callable = tns.pf13 elif cstr == "KEY_F(14)": _logger.debug("keyed Shift+F2") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf14() - self.rewrite_keylock = True + aid_callable = tns.pf14 elif (cstr == "KEY_F(15)" or # Shift+F3 cstr == "\x1b[25~"): # Shift+F3 _logger.debug("keyed Shift+F3") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf15() - self.rewrite_keylock = True + aid_callable = tns.pf15 elif (cstr == "KEY_F(16)" or # Shift+F4 cstr == "\x1b[26~"): # Shift+F4 _logger.debug("keyed Shift+F4") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf16() - self.rewrite_keylock = True + aid_callable = tns.pf16 elif (cstr == "KEY_F(17)" or # Shift+F5 cstr == "\x1b[28~"): # Shift+F5 _logger.debug("keyed Shift+F5") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf17() - self.rewrite_keylock = True + aid_callable = tns.pf17 elif (cstr == "KEY_F(18)" or # Shift+F6 cstr == "\x1b[29~"): # Shift+F6 _logger.debug("keyed Shift+F6") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf18() - self.rewrite_keylock = True + aid_callable = tns.pf18 elif (cstr == "KEY_F(19)" or # Shift+F7 cstr == "\x1b[31~"): # Shift+F7 _logger.debug("keyed Shift+F7") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf19() - self.rewrite_keylock = True + aid_callable = tns.pf19 elif (cstr == "KEY_F(20)" or # Shift+F8 cstr == "\x1b[32~"): # Shift+F8 _logger.debug("keyed Shift+F8") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf20() - self.rewrite_keylock = True + aid_callable = tns.pf20 elif (cstr == "KEY_F(21)" or # Shift+F9 cstr == "\x1b[33~"): # Shift+F9 _logger.debug("keyed Shift+F9") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf21() - self.rewrite_keylock = True + aid_callable = tns.pf21 elif (cstr == "KEY_F(22)" or # Shift+F10 cstr == "\x1b[34~"): # Shift+F10 _logger.debug("keyed Shift+F10") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf22() - self.rewrite_keylock = True + aid_callable = tns.pf22 elif cstr == "KEY_F(23)": _logger.debug("keyed Shift+F11") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf23() - self.rewrite_keylock = True + aid_callable = tns.pf23 elif cstr == "KEY_F(24)": _logger.debug("keyed Shift+F12") - - if tns.pwait or tns.system_lock_wait: - curses.flash() - curses.beep() - else: - tns.pf24() - self.rewrite_keylock = True + aid_callable = tns.pf24 elif (cstr == "\x1b\x1b[5~" or # Alt+PgUp Putty cstr == "\x1b[5;3~" or # Alt+PgUp Git Bash @@ -2646,6 +2481,9 @@ def __r2d2(self, win, waitc, timeout): cstr == "ALT_PGUP" or # Alt+PgDn Windows cstr == "\x1bKEY_PPAGE"): # Alt+PgUp z/OS _logger.debug("keyed Alt+PgUp") + if keylock_aidbuf: # if not all keys were processed + keylock_aidbuf.clear() # cancel, Alt+PgUp + curses.beep() # signal user something happened session = ati.ati.session sessions = ati.ati.sessions @@ -2667,6 +2505,9 @@ def __r2d2(self, win, waitc, timeout): cstr == "ALT_PGDN" or # Alt+PgDn Windows cstr == "\x1bKEY_NPAGE"): # Alt+PgDn z/OS _logger.debug("keyed Alt+PgDn") + if keylock_aidbuf: # if not all keys were processed + keylock_aidbuf.clear() # cancel, Alt+PgDn + curses.beep() # signal user something happened session = ati.ati.session sessions = ati.ati.sessions @@ -2730,6 +2571,7 @@ def __r2d2(self, win, waitc, timeout): if ((mbstate & curses.BUTTON1_DOUBLE_CLICKED) != 0): if tns.pwait or tns.system_lock_wait: + keylock_aidbuf.clear() # cancel, click curses.flash() curses.beep() else: @@ -2768,6 +2610,10 @@ def __r2d2(self, win, waitc, timeout): session = None if session: + if keylock_aidbuf: + keylock_aidbuf.clear() + curses.beep() + ati.ati.session = session if ati.ati.seslost: return @@ -2787,6 +2633,39 @@ def __r2d2(self, win, waitc, timeout): else: _logger.warning("Unknown key: %r", cstr) + # Process or buffer the AID (e.g. enter) as needed + + if aid_callable: + if tns.pwait or tns.system_lock_wait: + bufsize = os.environ.get("ZTI_AIDBUFSIZE", "9") + try: + bufsize = int(bufsize) + except ValueError: + bufsize = 9 + + if len(keylock_aidbuf) >= bufsize: # if full + curses.flash() # signal user - full buff + curses.beep() # something happened + else: + keylock_aidbuf.append(aid_callable) + + aid_callable = None + + if aid_callable or keylock_aidbuf: + if not tns.pwait and not tns.system_lock_wait: + if not aid_callable: + aid_callable = keylock_aidbuf.pop(0) + elif keylock_aidbuf: + keylock_aidbuf.append(aid_callable) + aid_callable = keylock_aidbuf.pop(0) + + aid_callable() + if aid_callable is tns.clear: + self.rewrite = True + + self.rewrite_keylock = True + aid_callable = None + if tout == 0: return 0 # timeout