diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 1020dd7ed..6c8166b78 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1792,6 +1792,10 @@ curses: fix an off-by-one error when deciding whether a long line on the bottom line of the message window can fit ">>" (curses' "--More--") curses: selecting a partial stack, unselecting it, and then selecting it normally did not reset the quantity to the whole stack +curses: if user's terminal was set to 'application keypad mode' (DEC VTxxx + nomenclature; set via 2 char "ESC =") and the terminfo or termcap + entry told the terminal to send 8-bit escape sequences (via 3 char + "ESC SPC G"), nethack wasn't recognizing number pad keys macOS: Xcode project was failing to build if the path to the NetHack source tree contained a space; the issue was within some shell script code contained within the project diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 6eb337eb2..738948635 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -32,7 +32,7 @@ static boolean modifiers_available = FALSE; static int modified(int ch); static void update_modifiers(void); -static int parse_escape_sequence(boolean *); +static int parse_escape_sequence(int, boolean *); int curses_getch(void) @@ -866,11 +866,12 @@ curses_convert_keys(int key) /* Handle arrow and keypad keys, but only when getting a command (or a command-like keystroke for getpos() or getdir()). */ switch (key) { + case M('O'): /* 8-bit version of ESC 'O' c for keypad key */ case '\033': /* ESC or ^[ */ /* changes ESC c to M-c or number pad key to corresponding digit (but we only get here via key==ESC if curses' getch() didn't change the latter to KEY_xyz) */ - ret = parse_escape_sequence(&numpad_esc); + ret = parse_escape_sequence(key, &numpad_esc); reject = ((uchar) ret < 1 || ret > 255); as_is = !numpad_esc; /* don't perform phonepad inversion */ break; @@ -1068,11 +1069,11 @@ curses_mouse_support(int mode) /* 0: off, 1: on, 2: alternate on */ #endif } -/* caller just got an input character of ESC; +/* caller just got an input character of ESC or M-O; note: curses converts a lot of escape sequences to single values greater than 255 and those won't look like ESC to caller so won't get here */ static int -parse_escape_sequence(boolean *keypadnum) +parse_escape_sequence(int key, boolean *keypadnum) { #ifndef PDCURSES int ret; @@ -1082,12 +1083,26 @@ parse_escape_sequence(boolean *keypadnum) timeout(10); ret = getch(); - if (ret == 'O') { /* Numeric keypad */ - /* ESC O */ - ret = getch(); + if (ret == 'O' || key == M('O')) { /* handle numeric keypad */ + /* + * ESC O or M-O . + * + * For the former, we don't have the next char yet so get it now. + * If there isn't one, treat ESC O as if user typed M-O (which + * is probably the case, via alt+shift+O combo sending two char + * "ESC O"). + * + * For the latter, it there wasn't another char then 'ret' will + * be ERR and we'll treat the result as M-O. However, if there + * is another char and it is O meant as two characters "M-O O" + * we'll be fooled, but that's not a valid escape sequence so + * don't worry about those two characters arriving together. + */ + if (key == '\033') + ret = getch(); if (ret == ERR) { - ret = 'O'; /* there was no third char; treat as M-O below */ + ret = 'O'; /* there was no additional char; treat as M-O below */ } else if (ret >= 112 && ret <= 121) { /* 'p'..'y' */ *keypadnum = TRUE; /* convert 'p'..'y' to '0'..'9' below */ } @@ -1106,6 +1121,7 @@ parse_escape_sequence(boolean *keypadnum) return ret; #else + nhUse(key); nhUse(keypadnum); return '\033'; #endif /* !PDCURSES */