mirror of
https://github.com/reactos/reactos.git
synced 2025-01-13 01:22:03 +00:00
[WIN32CSR] Implement some basic line editing capability
svn path=/trunk/; revision=47584
This commit is contained in:
parent
f4f8ee78d1
commit
7da6d0a6e2
2 changed files with 128 additions and 21 deletions
|
@ -22,25 +22,143 @@
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ConioLineInputSetPos(PCSRSS_CONSOLE Console, UINT Pos)
|
||||||
|
{
|
||||||
|
if (Pos != Console->LinePos && Console->Mode & ENABLE_ECHO_INPUT)
|
||||||
|
{
|
||||||
|
PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
|
||||||
|
UINT OldCursorX = Buffer->CurrentX;
|
||||||
|
UINT OldCursorY = Buffer->CurrentY;
|
||||||
|
INT XY = OldCursorY * Buffer->MaxX + OldCursorX;
|
||||||
|
|
||||||
|
XY += (Pos - Console->LinePos);
|
||||||
|
if (XY < 0)
|
||||||
|
XY = 0;
|
||||||
|
else if (XY >= Buffer->MaxY * Buffer->MaxX)
|
||||||
|
XY = Buffer->MaxY * Buffer->MaxX - 1;
|
||||||
|
|
||||||
|
Buffer->CurrentX = XY % Buffer->MaxX;
|
||||||
|
Buffer->CurrentY = XY / Buffer->MaxX;
|
||||||
|
ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console->LinePos = Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ConioLineInputEdit(PCSRSS_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
|
||||||
|
{
|
||||||
|
UINT Pos = Console->LinePos;
|
||||||
|
UINT NewSize = Console->LineSize - NumToDelete + NumToInsert;
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
/* Make sure there's always enough room for ending \r\n */
|
||||||
|
if (NewSize + 2 > Console->LineMaxSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memmove(&Console->LineBuffer[Pos + NumToInsert],
|
||||||
|
&Console->LineBuffer[Pos + NumToDelete],
|
||||||
|
(Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR));
|
||||||
|
memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (Console->Mode & ENABLE_ECHO_INPUT)
|
||||||
|
{
|
||||||
|
for (i = Pos; i < NewSize; i++)
|
||||||
|
{
|
||||||
|
CHAR AsciiChar;
|
||||||
|
WideCharToMultiByte(Console->OutputCodePage, 0,
|
||||||
|
&Console->LineBuffer[i], 1,
|
||||||
|
&AsciiChar, 1, NULL, NULL);
|
||||||
|
ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE);
|
||||||
|
}
|
||||||
|
for (; i < Console->LineSize; i++)
|
||||||
|
{
|
||||||
|
ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE);
|
||||||
|
}
|
||||||
|
Console->LinePos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console->LineSize = NewSize;
|
||||||
|
ConioLineInputSetPos(Console, Pos + NumToInsert);
|
||||||
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
|
ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
|
||||||
{
|
{
|
||||||
|
UINT Pos = Console->LinePos;
|
||||||
|
switch (KeyEvent->wVirtualKeyCode)
|
||||||
|
{
|
||||||
|
case VK_ESCAPE:
|
||||||
|
/* Clear entire line */
|
||||||
|
ConioLineInputSetPos(Console, 0);
|
||||||
|
ConioLineInputEdit(Console, Console->LineSize, 0, NULL);
|
||||||
|
return;
|
||||||
|
case VK_HOME:
|
||||||
|
/* Move to start of line. With ctrl, erase everything left of cursor */
|
||||||
|
ConioLineInputSetPos(Console, 0);
|
||||||
|
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||||
|
ConioLineInputEdit(Console, Pos, 0, NULL);
|
||||||
|
return;
|
||||||
|
case VK_END:
|
||||||
|
/* Move to end of line. With ctrl, erase everything right of cursor */
|
||||||
|
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||||
|
ConioLineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
|
||||||
|
else
|
||||||
|
ConioLineInputSetPos(Console, Console->LineSize);
|
||||||
|
return;
|
||||||
|
case VK_LEFT:
|
||||||
|
/* Move left. With ctrl, move to beginning of previous word */
|
||||||
|
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||||
|
{
|
||||||
|
while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
|
||||||
|
while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pos -= (Pos > 0);
|
||||||
|
}
|
||||||
|
ConioLineInputSetPos(Console, Pos);
|
||||||
|
return;
|
||||||
|
case VK_RIGHT:
|
||||||
|
/* Move right. With ctrl, move to beginning of next word */
|
||||||
|
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||||
|
{
|
||||||
|
while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
|
||||||
|
while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pos += (Pos < Console->LineSize);
|
||||||
|
}
|
||||||
|
ConioLineInputSetPos(Console, Pos);
|
||||||
|
return;
|
||||||
|
case VK_DELETE:
|
||||||
|
/* Remove character to right of cursor */
|
||||||
|
if (Pos != Console->LineSize)
|
||||||
|
ConioLineInputEdit(Console, 1, 0, NULL);
|
||||||
|
return;
|
||||||
|
case VK_F6:
|
||||||
|
/* Insert a ^Z character */
|
||||||
|
KeyEvent->uChar.UnicodeChar = 26;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT)
|
if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT)
|
||||||
{
|
{
|
||||||
/* backspace handling - if we are in charge of echoing it then we handle it here
|
/* backspace handling - if processed input enabled then we handle it here
|
||||||
* otherwise we treat it like a normal char.
|
* otherwise we treat it like a normal char. */
|
||||||
*/
|
if (Pos > 0)
|
||||||
if (Console->LineSize > 0)
|
|
||||||
{
|
{
|
||||||
Console->LineSize--;
|
ConioLineInputSetPos(Console, Pos - 1);
|
||||||
if (Console->Mode & ENABLE_ECHO_INPUT)
|
ConioLineInputEdit(Console, 1, 0, NULL);
|
||||||
ConioWriteConsole(Console, Console->ActiveBuffer, "\b", 1, TRUE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (KeyEvent->uChar.UnicodeChar == L'\r')
|
else if (KeyEvent->uChar.UnicodeChar == L'\r')
|
||||||
{
|
{
|
||||||
HistoryAddEntry(Console);
|
HistoryAddEntry(Console);
|
||||||
|
|
||||||
|
ConioLineInputSetPos(Console, Console->LineSize);
|
||||||
Console->LineBuffer[Console->LineSize++] = L'\r';
|
Console->LineBuffer[Console->LineSize++] = L'\r';
|
||||||
if (Console->Mode & ENABLE_ECHO_INPUT)
|
if (Console->Mode & ENABLE_ECHO_INPUT)
|
||||||
ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE);
|
ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE);
|
||||||
|
@ -55,19 +173,8 @@ ConioLineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
|
||||||
}
|
}
|
||||||
else if (KeyEvent->uChar.UnicodeChar != L'\0')
|
else if (KeyEvent->uChar.UnicodeChar != L'\0')
|
||||||
{
|
{
|
||||||
if (Console->LineSize + 2 < Console->LineMaxSize)
|
/* Normal character */
|
||||||
{
|
ConioLineInputEdit(Console, 0, 1, &KeyEvent->uChar.UnicodeChar);
|
||||||
Console->LineBuffer[Console->LineSize++] = KeyEvent->uChar.UnicodeChar;
|
|
||||||
/* echo to screen if enabled */
|
|
||||||
if (Console->Mode & ENABLE_ECHO_INPUT)
|
|
||||||
{
|
|
||||||
CHAR AsciiChar;
|
|
||||||
WideCharToMultiByte(Console->OutputCodePage, 0,
|
|
||||||
&KeyEvent->uChar.UnicodeChar, 1,
|
|
||||||
&AsciiChar, 1, NULL, NULL);
|
|
||||||
ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue