mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[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.
This commit is contained in:
parent
c29d6806b8
commit
d15f126143
1 changed files with 51 additions and 34 deletions
|
@ -2923,27 +2923,28 @@ KdbpPagerInternal(
|
||||||
{
|
{
|
||||||
TerminalInitialized = TRUE;
|
TerminalInitialized = TRUE;
|
||||||
|
|
||||||
KdpDprintf("\x1b[7h"); /* Enable linewrap */
|
/* Enable line-wrap */
|
||||||
|
KdpDprintf("\x1b[?7h");
|
||||||
|
|
||||||
/* Query terminal type */
|
/*
|
||||||
/*DbgPrint("\x1b[Z");*/
|
* Query terminal type.
|
||||||
KdpDprintf("\x05");
|
* Historically it was done with CTRL-E ('\x05'), however nowadays
|
||||||
|
* terminals respond to it with an empty (or a user-configurable)
|
||||||
Length = 0;
|
* string. Instead, use the VT52-compatible 'ESC Z' sequence or the
|
||||||
|
* VT100-compatible 'ESC[c' one.
|
||||||
|
*/
|
||||||
|
KdpDprintf("\x1b[c");
|
||||||
KeStallExecutionProcessor(100000);
|
KeStallExecutionProcessor(100000);
|
||||||
|
|
||||||
|
Length = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
/* Verify we get an answer, but don't care about it */
|
||||||
c = KdbpTryGetCharSerial(5000);
|
c = KdbpTryGetCharSerial(5000);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
++Length;
|
||||||
InBuffer[Length++] = c;
|
|
||||||
if (Length >= (sizeof(InBuffer) - 1))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InBuffer[Length] = '\0';
|
|
||||||
if (Length > 0)
|
if (Length > 0)
|
||||||
TerminalConnected = TRUE;
|
TerminalConnected = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2953,21 +2954,34 @@ KdbpPagerInternal(
|
||||||
/* Refresh terminal size each time when number of rows printed is 0 */
|
/* Refresh terminal size each time when number of rows printed is 0 */
|
||||||
(KdbNumberOfRowsPrinted) == 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" */
|
/* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
|
||||||
TerminalReportsSize = FALSE;
|
TerminalReportsSize = FALSE;
|
||||||
KeStallExecutionProcessor(100000);
|
|
||||||
KdpDprintf("\x1b[18t");
|
KdpDprintf("\x1b[18t");
|
||||||
c = KdbpTryGetCharSerial(5000);
|
KeStallExecutionProcessor(100000);
|
||||||
|
|
||||||
|
c = KdbpTryGetCharSerial(5000);
|
||||||
if (c == KEY_ESC)
|
if (c == KEY_ESC)
|
||||||
{
|
{
|
||||||
c = KdbpTryGetCharSerial(5000);
|
c = KdbpTryGetCharSerial(5000);
|
||||||
if (c == '[')
|
if (c == '[')
|
||||||
{
|
{
|
||||||
Length = 0;
|
Length = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
c = KdbpTryGetCharSerial(5000);
|
c = KdbpTryGetCharSerial(5000);
|
||||||
|
@ -2978,15 +2992,15 @@ KdbpPagerInternal(
|
||||||
if (isalpha(c) || Length >= (sizeof(InBuffer) - 1))
|
if (isalpha(c) || Length >= (sizeof(InBuffer) - 1))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
InBuffer[Length] = '\0';
|
InBuffer[Length] = '\0';
|
||||||
|
|
||||||
if (InBuffer[0] == '8' && InBuffer[1] == ';')
|
if (InBuffer[0] == '8' && InBuffer[1] == ';')
|
||||||
{
|
{
|
||||||
for (i = 2; (i < Length) && (InBuffer[i] != ';'); i++);
|
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 */
|
/* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
|
||||||
KdbNumberOfRowsTerminal = strtoul(InBuffer + 2, NULL, 0);
|
KdbNumberOfRowsTerminal = strtoul(InBuffer + 2, NULL, 0);
|
||||||
|
@ -3003,19 +3017,22 @@ KdbpPagerInternal(
|
||||||
if (KdbNumberOfRowsTerminal <= 0)
|
if (KdbNumberOfRowsTerminal <= 0)
|
||||||
{
|
{
|
||||||
/* Set number of rows to the default */
|
/* Set number of rows to the default */
|
||||||
if (!DoPage)
|
if (KdpDebugMode.Screen && !SerialTerminal)
|
||||||
KdbNumberOfRowsTerminal = 23; //Mna.: for SCREEN debugport
|
KdbNumberOfRowsTerminal = (SCREEN_HEIGHT / (13 /*BOOTCHAR_HEIGHT*/ + 1));
|
||||||
else
|
else
|
||||||
KdbNumberOfRowsTerminal = 24;
|
KdbNumberOfRowsTerminal = 24;
|
||||||
}
|
}
|
||||||
else if (KdbNumberOfColsTerminal <= 0)
|
if (KdbNumberOfColsTerminal <= 0)
|
||||||
{
|
{
|
||||||
/* Set number of cols to the default */
|
/* Set number of cols to the default */
|
||||||
if (!DoPage)
|
if (KdpDebugMode.Screen && !SerialTerminal)
|
||||||
KdbNumberOfColsTerminal = 75; //Mna.: for SCREEN debugport
|
KdbNumberOfColsTerminal = (SCREEN_WIDTH / 8 /*BOOTCHAR_WIDTH*/);
|
||||||
else
|
else
|
||||||
KdbNumberOfColsTerminal = 80;
|
KdbNumberOfColsTerminal = 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KdpDprintf("Cols/Rows: %dx%d\n",
|
||||||
|
// KdbNumberOfColsTerminal, KdbNumberOfRowsTerminal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through the strings */
|
/* Loop through the strings */
|
||||||
|
@ -3398,7 +3415,7 @@ KdbpReadCommand(
|
||||||
if (NextKey == '\n' || NextKey == -1) /* \n or no response at all */
|
if (NextKey == '\n' || NextKey == -1) /* \n or no response at all */
|
||||||
NextKey = '\0';
|
NextKey = '\0';
|
||||||
|
|
||||||
KdbpPrint("\n");
|
KdpDprintf("\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Repeat the last command if the user presses enter. Reduces the
|
* Repeat the last command if the user presses enter. Reduces the
|
||||||
|
@ -3425,9 +3442,9 @@ KdbpReadCommand(
|
||||||
*Buffer = 0;
|
*Buffer = 0;
|
||||||
|
|
||||||
if (EchoOn)
|
if (EchoOn)
|
||||||
KdbpPrint("%c %c", KEY_BS, KEY_BS);
|
KdpDprintf("%c %c", KEY_BS, KEY_BS);
|
||||||
else
|
else
|
||||||
KdbpPrint(" %c", KEY_BS);
|
KdpDprintf(" %c", KEY_BS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ScanCode == KEY_SCAN_UP)
|
else if (ScanCode == KEY_SCAN_UP)
|
||||||
|
@ -3459,16 +3476,16 @@ KdbpReadCommand(
|
||||||
*Buffer = 0;
|
*Buffer = 0;
|
||||||
|
|
||||||
if (EchoOn)
|
if (EchoOn)
|
||||||
KdbpPrint("%c %c", KEY_BS, KEY_BS);
|
KdpDprintf("%c %c", KEY_BS, KEY_BS);
|
||||||
else
|
else
|
||||||
KdbpPrint(" %c", KEY_BS);
|
KdpDprintf(" %c", KEY_BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
|
i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
|
||||||
memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
|
memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
|
||||||
Orig[i] = '\0';
|
Orig[i] = '\0';
|
||||||
Buffer = Orig + i;
|
Buffer = Orig + i;
|
||||||
KdbpPrint("%s", Orig);
|
KdpDprintf("%s", Orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ScanCode == KEY_SCAN_DOWN)
|
else if (ScanCode == KEY_SCAN_DOWN)
|
||||||
|
@ -3488,23 +3505,23 @@ KdbpReadCommand(
|
||||||
*Buffer = 0;
|
*Buffer = 0;
|
||||||
|
|
||||||
if (EchoOn)
|
if (EchoOn)
|
||||||
KdbpPrint("%c %c", KEY_BS, KEY_BS);
|
KdpDprintf("%c %c", KEY_BS, KEY_BS);
|
||||||
else
|
else
|
||||||
KdbpPrint(" %c", KEY_BS);
|
KdpDprintf(" %c", KEY_BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
|
i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
|
||||||
memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
|
memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
|
||||||
Orig[i] = '\0';
|
Orig[i] = '\0';
|
||||||
Buffer = Orig + i;
|
Buffer = Orig + i;
|
||||||
KdbpPrint("%s", Orig);
|
KdpDprintf("%s", Orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (EchoOn)
|
if (EchoOn)
|
||||||
KdbpPrint("%c", Key);
|
KdpDprintf("%c", Key);
|
||||||
|
|
||||||
*Buffer = Key;
|
*Buffer = Key;
|
||||||
Buffer++;
|
Buffer++;
|
||||||
|
|
Loading…
Reference in a new issue