https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d15f12614397d14264e67…
commit d15f12614397d14264e676aed343d1b56937efcd
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Nov 22 01:49:16 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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++;