https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d15f12614397d14264e676...
commit d15f12614397d14264e676aed343d1b56937efcd Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Tue Nov 22 01:49:16 2022 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Tue Nov 22 02:10:55 2022 +0100
[NTOS:KDBG] Fix the ANSI escape sequences used to get terminal characteristics when printing with paging.
- Line-wrapping is enabled with 'ESC[?7h' (the '?' was forgotten). Notice that the following reference also shows it wrong: https://www.cse.psu.edu/~kxc104/class/cse472/09s/hw/hw7/vt100ansi.htm
- Terminal type is actually queried with 'ESC Z' (VT52-compatible), or with 'ESC[c' (VT100-compatible). The antediluvian CTRL-E ('\x05') control code gives instead a user-configurable (usually empty) string, so it's not reliable. Also, we don't really care about the returned result, we just need to know that one has been sent.
Cross-checked with online documentation: * "Digital VT100 User Guide" (EK-VT100-UG-001) (1st edition, August 1978, reviewed November 1978). * https://www.real-world-systems.com/docs/ANSIcode.html * https://geoffg.net/Downloads/Terminal/TerminalEscapeCodes.pdf * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html * https://en.wikipedia.org/wiki/Enquiry_character
- Retrieve the size of the *controlling terminal* with escape sequences only when it's a serial one: serial output is enabled *and* KDSERIAL is set (i.e. user input through serial). See code for the actual logic (the corresponding truth table is left as an exercise for the reader).
- Fix also a "Buffer" vs. "InBuffer" mismatch, that caused the whole code to fail.
- For fallback terminal size values, use meaningful ones when SCREEN is instead the controlling "terminal" (based on full-size BOOTVID values).
- When echoing read characters during line-cooking, do direct output by using KdpDprintf() instead of going through the heavy KdbpPrint() function. This fixes some input artifacts like: 1. extra slowdowns due to querying terminal size at each keypress, and 2. getting obnoxious "--- Press q to abort ..." prompts in the middle of typing a long comamnd because you are at the very bottom of the screen. --- ntoskrnl/kdbg/kdb_cli.c | 85 +++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 34 deletions(-)
diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c index 806ace30fb2..ac4e70b7fbc 100644 --- a/ntoskrnl/kdbg/kdb_cli.c +++ b/ntoskrnl/kdbg/kdb_cli.c @@ -2923,27 +2923,28 @@ KdbpPagerInternal( { TerminalInitialized = TRUE;
- KdpDprintf("\x1b[7h"); /* Enable linewrap */ + /* Enable line-wrap */ + KdpDprintf("\x1b[?7h");
- /* Query terminal type */ - /*DbgPrint("\x1b[Z");*/ - KdpDprintf("\x05"); - - Length = 0; + /* + * Query terminal type. + * Historically it was done with CTRL-E ('\x05'), however nowadays + * terminals respond to it with an empty (or a user-configurable) + * string. Instead, use the VT52-compatible 'ESC Z' sequence or the + * VT100-compatible 'ESC[c' one. + */ + KdpDprintf("\x1b[c"); KeStallExecutionProcessor(100000);
+ Length = 0; for (;;) { + /* Verify we get an answer, but don't care about it */ c = KdbpTryGetCharSerial(5000); if (c == -1) break; - - InBuffer[Length++] = c; - if (Length >= (sizeof(InBuffer) - 1)) - break; + ++Length; } - - InBuffer[Length] = '\0'; if (Length > 0) TerminalConnected = TRUE; } @@ -2953,21 +2954,34 @@ KdbpPagerInternal( /* Refresh terminal size each time when number of rows printed is 0 */ (KdbNumberOfRowsPrinted) == 0) { - if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected && TerminalReportsSize) + /* Retrieve the size of the serial terminal only when it is the + * controlling terminal: serial output is enabled *and* KDSERIAL + * is set (i.e. user input through serial). */ + BOOLEAN SerialTerminal = +#if 0 + // Old logic where KDSERIAL also enables serial output. + (KdbDebugState & KD_DEBUG_KDSERIAL) || + (KdpDebugMode.Serial && !KdpDebugMode.Screen); +#else + // New logic where KDSERIAL does not necessarily enable serial output. + KdpDebugMode.Serial && + ((KdbDebugState & KD_DEBUG_KDSERIAL) || !KdpDebugMode.Screen); +#endif + + if (SerialTerminal && TerminalConnected && TerminalReportsSize) { /* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */ TerminalReportsSize = FALSE; - KeStallExecutionProcessor(100000); KdpDprintf("\x1b[18t"); - c = KdbpTryGetCharSerial(5000); + KeStallExecutionProcessor(100000);
+ c = KdbpTryGetCharSerial(5000); if (c == KEY_ESC) { c = KdbpTryGetCharSerial(5000); if (c == '[') { Length = 0; - for (;;) { c = KdbpTryGetCharSerial(5000); @@ -2978,15 +2992,15 @@ KdbpPagerInternal( if (isalpha(c) || Length >= (sizeof(InBuffer) - 1)) break; } - InBuffer[Length] = '\0'; + if (InBuffer[0] == '8' && InBuffer[1] == ';') { for (i = 2; (i < Length) && (InBuffer[i] != ';'); i++);
- if (Buffer[i] == ';') + if (InBuffer[i] == ';') { - Buffer[i++] = '\0'; + InBuffer[i++] = '\0';
/* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */ KdbNumberOfRowsTerminal = strtoul(InBuffer + 2, NULL, 0); @@ -3003,19 +3017,22 @@ KdbpPagerInternal( if (KdbNumberOfRowsTerminal <= 0) { /* Set number of rows to the default */ - if (!DoPage) - KdbNumberOfRowsTerminal = 23; //Mna.: for SCREEN debugport + if (KdpDebugMode.Screen && !SerialTerminal) + KdbNumberOfRowsTerminal = (SCREEN_HEIGHT / (13 /*BOOTCHAR_HEIGHT*/ + 1)); else KdbNumberOfRowsTerminal = 24; } - else if (KdbNumberOfColsTerminal <= 0) + if (KdbNumberOfColsTerminal <= 0) { /* Set number of cols to the default */ - if (!DoPage) - KdbNumberOfColsTerminal = 75; //Mna.: for SCREEN debugport + if (KdpDebugMode.Screen && !SerialTerminal) + KdbNumberOfColsTerminal = (SCREEN_WIDTH / 8 /*BOOTCHAR_WIDTH*/); else KdbNumberOfColsTerminal = 80; } + + // KdpDprintf("Cols/Rows: %dx%d\n", + // KdbNumberOfColsTerminal, KdbNumberOfRowsTerminal); }
/* Loop through the strings */ @@ -3398,7 +3415,7 @@ KdbpReadCommand( if (NextKey == '\n' || NextKey == -1) /* \n or no response at all */ NextKey = '\0';
- KdbpPrint("\n"); + KdpDprintf("\n");
/* * Repeat the last command if the user presses enter. Reduces the @@ -3425,9 +3442,9 @@ KdbpReadCommand( *Buffer = 0;
if (EchoOn) - KdbpPrint("%c %c", KEY_BS, KEY_BS); + KdpDprintf("%c %c", KEY_BS, KEY_BS); else - KdbpPrint(" %c", KEY_BS); + KdpDprintf(" %c", KEY_BS); } } else if (ScanCode == KEY_SCAN_UP) @@ -3459,16 +3476,16 @@ KdbpReadCommand( *Buffer = 0;
if (EchoOn) - KdbpPrint("%c %c", KEY_BS, KEY_BS); + KdpDprintf("%c %c", KEY_BS, KEY_BS); else - KdbpPrint(" %c", KEY_BS); + KdpDprintf(" %c", KEY_BS); }
i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1); memcpy(Orig, KdbCommandHistory[CmdHistIndex], i); Orig[i] = '\0'; Buffer = Orig + i; - KdbpPrint("%s", Orig); + KdpDprintf("%s", Orig); } } else if (ScanCode == KEY_SCAN_DOWN) @@ -3488,23 +3505,23 @@ KdbpReadCommand( *Buffer = 0;
if (EchoOn) - KdbpPrint("%c %c", KEY_BS, KEY_BS); + KdpDprintf("%c %c", KEY_BS, KEY_BS); else - KdbpPrint(" %c", KEY_BS); + KdpDprintf(" %c", KEY_BS); }
i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1); memcpy(Orig, KdbCommandHistory[CmdHistIndex], i); Orig[i] = '\0'; Buffer = Orig + i; - KdbpPrint("%s", Orig); + KdpDprintf("%s", Orig); } } } else { if (EchoOn) - KdbpPrint("%c", Key); + KdpDprintf("%c", Key);
*Buffer = Key; Buffer++;