mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:03:00 +00:00
[CONSRV]
Commit my work that I've done during my trip from Albi back to Paris (part 2/2): Remove terminal-specific line discipline code from CONDRV back to CONSRV. svn path=/branches/condrv_restructure/; revision=63979
This commit is contained in:
parent
742f7ebd4b
commit
e3e54a09b3
8 changed files with 531 additions and 345 deletions
|
@ -302,10 +302,7 @@ ConDrvReadConsole(IN PCONSOLE Console,
|
||||||
OUT PULONG NumCharsRead OPTIONAL)
|
OUT PULONG NumCharsRead OPTIONAL)
|
||||||
{
|
{
|
||||||
// STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
|
// STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
|
||||||
NTSTATUS Status = STATUS_PENDING;
|
// NTSTATUS Status; = STATUS_PENDING;
|
||||||
PLIST_ENTRY CurrentEntry;
|
|
||||||
ConsoleInput *Input;
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL || */
|
if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL || */
|
||||||
ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
|
ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
|
||||||
|
@ -317,128 +314,14 @@ ConDrvReadConsole(IN PCONSOLE Console,
|
||||||
ASSERT(Console == InputBuffer->Header.Console);
|
ASSERT(Console == InputBuffer->Header.Console);
|
||||||
ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
|
ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
|
||||||
|
|
||||||
/* We haven't read anything (yet) */
|
/* Call the line-discipline */
|
||||||
|
return TermReadStream(Console,
|
||||||
i = ReadControl->nInitialChars;
|
ExeName,
|
||||||
|
Unicode,
|
||||||
if (InputBuffer->Mode & ENABLE_LINE_INPUT)
|
Buffer,
|
||||||
{
|
ReadControl,
|
||||||
if (Console->LineBuffer == NULL)
|
NumCharsToRead,
|
||||||
{
|
NumCharsRead);
|
||||||
/* Starting a new line */
|
|
||||||
Console->LineMaxSize = max(256, NumCharsToRead);
|
|
||||||
|
|
||||||
Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
|
|
||||||
if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
|
|
||||||
|
|
||||||
Console->LinePos = Console->LineSize = ReadControl->nInitialChars;
|
|
||||||
Console->LineComplete = Console->LineUpPressed = FALSE;
|
|
||||||
Console->LineInsertToggle = Console->InsertMode;
|
|
||||||
Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pre-filling the buffer is only allowed in the Unicode API,
|
|
||||||
* so we don't need to worry about ANSI <-> Unicode conversion.
|
|
||||||
*/
|
|
||||||
memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
|
|
||||||
if (Console->LineSize == Console->LineMaxSize)
|
|
||||||
{
|
|
||||||
Console->LineComplete = TRUE;
|
|
||||||
Console->LinePos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't have a complete line yet, process the pending input */
|
|
||||||
while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
|
|
||||||
{
|
|
||||||
/* Remove input event from queue */
|
|
||||||
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
|
||||||
if (IsListEmpty(&InputBuffer->InputEvents))
|
|
||||||
{
|
|
||||||
ResetEvent(InputBuffer->ActiveEvent);
|
|
||||||
}
|
|
||||||
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
|
||||||
|
|
||||||
/* Only pay attention to key down */
|
|
||||||
if (Input->InputEvent.EventType == KEY_EVENT &&
|
|
||||||
Input->InputEvent.Event.KeyEvent.bKeyDown)
|
|
||||||
{
|
|
||||||
LineInputKeyDown(Console, ExeName,
|
|
||||||
&Input->InputEvent.Event.KeyEvent);
|
|
||||||
ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
|
|
||||||
}
|
|
||||||
ConsoleFreeHeap(Input);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we have a complete line to read from */
|
|
||||||
if (Console->LineComplete)
|
|
||||||
{
|
|
||||||
while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
|
|
||||||
{
|
|
||||||
WCHAR Char = Console->LineBuffer[Console->LinePos++];
|
|
||||||
|
|
||||||
if (Unicode)
|
|
||||||
{
|
|
||||||
((PWCHAR)Buffer)[i] = Char;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Console->LinePos == Console->LineSize)
|
|
||||||
{
|
|
||||||
/* Entire line has been read */
|
|
||||||
ConsoleFreeHeap(Console->LineBuffer);
|
|
||||||
Console->LineBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Character input */
|
|
||||||
while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
|
|
||||||
{
|
|
||||||
/* Remove input event from queue */
|
|
||||||
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
|
||||||
if (IsListEmpty(&InputBuffer->InputEvents))
|
|
||||||
{
|
|
||||||
ResetEvent(InputBuffer->ActiveEvent);
|
|
||||||
}
|
|
||||||
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
|
||||||
|
|
||||||
/* Only pay attention to valid ASCII chars, on key down */
|
|
||||||
if (Input->InputEvent.EventType == KEY_EVENT &&
|
|
||||||
Input->InputEvent.Event.KeyEvent.bKeyDown &&
|
|
||||||
Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
|
|
||||||
{
|
|
||||||
WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
|
|
||||||
|
|
||||||
if (Unicode)
|
|
||||||
{
|
|
||||||
((PWCHAR)Buffer)[i] = Char;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
|
|
||||||
/* Did read something */
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
ConsoleFreeHeap(Input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Only set if Status == STATUS_SUCCESS ???
|
|
||||||
if (NumCharsRead) *NumCharsRead = i;
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
|
|
|
@ -31,17 +31,51 @@ DummyDrawRegion(IN OUT PTERMINAL This,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
|
||||||
DummyWriteStream(IN OUT PTERMINAL This,
|
|
||||||
SMALL_RECT* Region,
|
/************ Line discipline ***************/
|
||||||
SHORT CursorStartX,
|
|
||||||
SHORT CursorStartY,
|
static NTSTATUS NTAPI
|
||||||
UINT ScrolledLines,
|
DummyReadStream(IN OUT PTERMINAL This,
|
||||||
PWCHAR Buffer,
|
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
|
||||||
UINT Length)
|
IN BOOLEAN Unicode,
|
||||||
|
/**PWCHAR Buffer,**/
|
||||||
|
OUT PVOID Buffer,
|
||||||
|
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
|
||||||
|
IN ULONG NumCharsToRead,
|
||||||
|
OUT PULONG NumCharsRead OPTIONAL)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* We were called because the console was in cooked mode.
|
||||||
|
* There is nothing to read, wait until a real terminal
|
||||||
|
* is plugged into the console.
|
||||||
|
*/
|
||||||
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS NTAPI
|
||||||
|
DummyWriteStream(IN OUT PTERMINAL This,
|
||||||
|
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||||
|
PWCHAR Buffer,
|
||||||
|
DWORD Length,
|
||||||
|
BOOL Attrib)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We were called because the console was in cooked mode.
|
||||||
|
* There is nothing to write, wait until a real terminal
|
||||||
|
* is plugged into the console.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// /* Stop here if the console is paused */
|
||||||
|
// if (Console->UnpauseEvent != NULL) return STATUS_PENDING;
|
||||||
|
|
||||||
|
return STATUS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ Line discipline ***************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL NTAPI
|
static BOOL NTAPI
|
||||||
DummySetCursorInfo(IN OUT PTERMINAL This,
|
DummySetCursorInfo(IN OUT PTERMINAL This,
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
|
||||||
|
@ -114,7 +148,10 @@ static TERMINAL_VTBL DummyVtbl =
|
||||||
DummyInitTerminal,
|
DummyInitTerminal,
|
||||||
DummyDeinitTerminal,
|
DummyDeinitTerminal,
|
||||||
DummyDrawRegion,
|
DummyDrawRegion,
|
||||||
|
|
||||||
|
DummyReadStream,
|
||||||
DummyWriteStream,
|
DummyWriteStream,
|
||||||
|
|
||||||
DummySetCursorInfo,
|
DummySetCursorInfo,
|
||||||
DummySetScreenInfo,
|
DummySetScreenInfo,
|
||||||
DummyResizeTerminal,
|
DummyResizeTerminal,
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
#define TAB_WIDTH 8
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
CONSOLE_IO_OBJECT_TYPE
|
CONSOLE_IO_OBJECT_TYPE
|
||||||
|
@ -33,7 +31,7 @@ static CONSOLE_SCREEN_BUFFER_VTBL TextVtbl =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static VOID
|
/*static*/ VOID
|
||||||
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff);
|
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff);
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +125,7 @@ ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
|
||||||
return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X];
|
return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X];
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
/*static*/ VOID
|
||||||
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
|
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
|
||||||
{
|
{
|
||||||
PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
|
PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
|
||||||
|
@ -354,169 +352,6 @@ ConioResizeBuffer(PCONSOLE Console,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
|
||||||
ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines)
|
|
||||||
{
|
|
||||||
/* If we hit bottom, slide the viewable screen */
|
|
||||||
if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y)
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.Y--;
|
|
||||||
if (++Buff->VirtualY == Buff->ScreenBufferSize.Y)
|
|
||||||
{
|
|
||||||
Buff->VirtualY = 0;
|
|
||||||
}
|
|
||||||
(*ScrolledLines)++;
|
|
||||||
ClearLineBuffer(Buff);
|
|
||||||
if (UpdateRect->Top != 0)
|
|
||||||
{
|
|
||||||
UpdateRect->Top--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateRect->Left = 0;
|
|
||||||
UpdateRect->Right = Buff->ScreenBufferSize.X - 1;
|
|
||||||
UpdateRect->Bottom = Buff->CursorPosition.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
ConioWriteConsole(PCONSOLE Console,
|
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
|
||||||
PWCHAR Buffer,
|
|
||||||
DWORD Length,
|
|
||||||
BOOL Attrib)
|
|
||||||
{
|
|
||||||
UINT i;
|
|
||||||
PCHAR_INFO Ptr;
|
|
||||||
SMALL_RECT UpdateRect;
|
|
||||||
SHORT CursorStartX, CursorStartY;
|
|
||||||
UINT ScrolledLines;
|
|
||||||
|
|
||||||
CursorStartX = Buff->CursorPosition.X;
|
|
||||||
CursorStartY = Buff->CursorPosition.Y;
|
|
||||||
UpdateRect.Left = Buff->ScreenBufferSize.X;
|
|
||||||
UpdateRect.Top = Buff->CursorPosition.Y;
|
|
||||||
UpdateRect.Right = -1;
|
|
||||||
UpdateRect.Bottom = Buff->CursorPosition.Y;
|
|
||||||
ScrolledLines = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < Length; i++)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If we are in processed mode, interpret special characters and
|
|
||||||
* display them correctly. Otherwise, just put them into the buffer.
|
|
||||||
*/
|
|
||||||
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
|
|
||||||
{
|
|
||||||
/* --- CR --- */
|
|
||||||
if (Buffer[i] == L'\r')
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.X = 0;
|
|
||||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
|
||||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* --- LF --- */
|
|
||||||
else if (Buffer[i] == L'\n')
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.X = 0;
|
|
||||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* --- BS --- */
|
|
||||||
else if (Buffer[i] == L'\b')
|
|
||||||
{
|
|
||||||
/* Only handle BS if we're not on the first pos of the first line */
|
|
||||||
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
|
|
||||||
{
|
|
||||||
if (0 == Buff->CursorPosition.X)
|
|
||||||
{
|
|
||||||
/* slide virtual position up */
|
|
||||||
Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1;
|
|
||||||
Buff->CursorPosition.Y--;
|
|
||||||
UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.X--;
|
|
||||||
}
|
|
||||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
|
||||||
Ptr->Char.UnicodeChar = L' ';
|
|
||||||
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
|
||||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
|
||||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* --- TAB --- */
|
|
||||||
else if (Buffer[i] == L'\t')
|
|
||||||
{
|
|
||||||
UINT EndX;
|
|
||||||
|
|
||||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
|
||||||
EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1);
|
|
||||||
EndX = min(EndX, (UINT)Buff->ScreenBufferSize.X);
|
|
||||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
|
||||||
while (Buff->CursorPosition.X < EndX)
|
|
||||||
{
|
|
||||||
Ptr->Char.UnicodeChar = L' ';
|
|
||||||
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
|
||||||
++Ptr;
|
|
||||||
Buff->CursorPosition.X++;
|
|
||||||
}
|
|
||||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
|
|
||||||
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
|
||||||
{
|
|
||||||
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.X = 0;
|
|
||||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.X--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// /* --- BEL ---*/
|
|
||||||
// else if (Buffer[i] == L'\a')
|
|
||||||
// {
|
|
||||||
// // FIXME: This MUST BE moved to the terminal emulator frontend!!
|
|
||||||
// DPRINT1("Bell\n");
|
|
||||||
// // SendNotifyMessage(Console->hWindow, PM_CONSOLE_BEEP, 0, 0);
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
|
||||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
|
||||||
|
|
||||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
|
||||||
Ptr->Char.UnicodeChar = Buffer[i];
|
|
||||||
if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
|
||||||
|
|
||||||
Buff->CursorPosition.X++;
|
|
||||||
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
|
||||||
{
|
|
||||||
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.X = 0;
|
|
||||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Buff->CursorPosition.X = CursorStartX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
|
|
||||||
{
|
|
||||||
TermWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY,
|
|
||||||
ScrolledLines, Buffer, Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS NTAPI
|
||||||
ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
|
ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
|
||||||
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||||
|
@ -807,6 +642,7 @@ ConDrvWriteConsole(IN PCONSOLE Console,
|
||||||
/* Stop here if the console is paused */
|
/* Stop here if the console is paused */
|
||||||
if (Console->UnpauseEvent != NULL) return STATUS_PENDING;
|
if (Console->UnpauseEvent != NULL) return STATUS_PENDING;
|
||||||
|
|
||||||
|
/* Convert the string to UNICODE */
|
||||||
if (Unicode)
|
if (Unicode)
|
||||||
{
|
{
|
||||||
Buffer = StringBuffer;
|
Buffer = StringBuffer;
|
||||||
|
@ -831,15 +667,16 @@ ConDrvWriteConsole(IN PCONSOLE Console,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send it */
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
{
|
{
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = ConioWriteConsole(Console,
|
Status = TermWriteStream(Console,
|
||||||
ScreenBuffer,
|
ScreenBuffer,
|
||||||
Buffer,
|
Buffer,
|
||||||
NumCharsToWrite,
|
NumCharsToWrite,
|
||||||
TRUE);
|
TRUE);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Written = NumCharsToWrite;
|
Written = NumCharsToWrite;
|
||||||
|
|
|
@ -18,6 +18,76 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********** HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK ************/
|
||||||
|
|
||||||
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* From MSDN:
|
||||||
|
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
|
||||||
|
* If they are the same, the function fails, and GetLastError returns
|
||||||
|
* ERROR_INVALID_PARAMETER."
|
||||||
|
*/
|
||||||
|
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
||||||
|
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
|
||||||
|
WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||||
|
|
||||||
|
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
|
||||||
|
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
|
||||||
|
MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
|
||||||
|
|
||||||
|
typedef struct ConsoleInput_t
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
INPUT_RECORD InputEvent;
|
||||||
|
} ConsoleInput;
|
||||||
|
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||||
|
{
|
||||||
|
if (InputEvent->EventType == KEY_EVENT)
|
||||||
|
{
|
||||||
|
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
|
||||||
|
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
|
||||||
|
ConsoleInputUnicodeCharToAnsiChar(Console,
|
||||||
|
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
|
||||||
|
&UnicodeChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||||
|
{
|
||||||
|
if (InputEvent->EventType == KEY_EVENT)
|
||||||
|
{
|
||||||
|
CHAR AsciiChar = InputEvent->Event.KeyEvent.uChar.AsciiChar;
|
||||||
|
InputEvent->Event.KeyEvent.uChar.AsciiChar = 0;
|
||||||
|
ConsoleInputAnsiCharToUnicodeChar(Console,
|
||||||
|
&InputEvent->Event.KeyEvent.uChar.UnicodeChar,
|
||||||
|
&AsciiChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/********** HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK ************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* CONSRV TERMINAL FRONTENDS INTERFACE ****************************************/
|
/* CONSRV TERMINAL FRONTENDS INTERFACE ****************************************/
|
||||||
|
|
||||||
/***************/
|
/***************/
|
||||||
|
@ -226,25 +296,366 @@ ConSrvTermDrawRegion(IN OUT PTERMINAL This,
|
||||||
FrontEnd->Vtbl->DrawRegion(FrontEnd, Region);
|
FrontEnd->Vtbl->DrawRegion(FrontEnd, Region);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
|
||||||
ConSrvTermWriteStream(IN OUT PTERMINAL This,
|
|
||||||
SMALL_RECT* Region,
|
/************ Line discipline ***************/
|
||||||
SHORT CursorStartX,
|
|
||||||
SHORT CursorStartY,
|
static NTSTATUS NTAPI
|
||||||
UINT ScrolledLines,
|
ConSrvTermReadStream(IN OUT PTERMINAL This,
|
||||||
PWCHAR Buffer,
|
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
|
||||||
UINT Length)
|
IN BOOLEAN Unicode,
|
||||||
|
/**PWCHAR Buffer,**/
|
||||||
|
OUT PVOID Buffer,
|
||||||
|
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
|
||||||
|
IN ULONG NumCharsToRead,
|
||||||
|
OUT PULONG NumCharsRead OPTIONAL)
|
||||||
{
|
{
|
||||||
PFRONTEND FrontEnd = This->Data;
|
PFRONTEND FrontEnd = This->Data;
|
||||||
FrontEnd->Vtbl->WriteStream(FrontEnd,
|
PCONSRV_CONSOLE Console = FrontEnd->Console;
|
||||||
Region,
|
PCONSOLE_INPUT_BUFFER InputBuffer = &Console->InputBuffer;
|
||||||
CursorStartX,
|
|
||||||
CursorStartY,
|
// STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
|
||||||
ScrolledLines,
|
NTSTATUS Status = STATUS_PENDING;
|
||||||
Buffer,
|
|
||||||
Length);
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
ConsoleInput *Input;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
/* Validity checks */
|
||||||
|
// ASSERT(Console == InputBuffer->Header.Console);
|
||||||
|
ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
|
||||||
|
|
||||||
|
/* We haven't read anything (yet) */
|
||||||
|
i = ReadControl->nInitialChars;
|
||||||
|
|
||||||
|
if (InputBuffer->Mode & ENABLE_LINE_INPUT)
|
||||||
|
{
|
||||||
|
/* COOKED mode, call the line discipline */
|
||||||
|
|
||||||
|
if (Console->LineBuffer == NULL)
|
||||||
|
{
|
||||||
|
/* Starting a new line */
|
||||||
|
Console->LineMaxSize = max(256, NumCharsToRead);
|
||||||
|
|
||||||
|
Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
|
||||||
|
if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
|
Console->LinePos = Console->LineSize = ReadControl->nInitialChars;
|
||||||
|
Console->LineComplete = Console->LineUpPressed = FALSE;
|
||||||
|
Console->LineInsertToggle = Console->InsertMode;
|
||||||
|
Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pre-filling the buffer is only allowed in the Unicode API,
|
||||||
|
* so we don't need to worry about ANSI <-> Unicode conversion.
|
||||||
|
*/
|
||||||
|
memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
|
||||||
|
if (Console->LineSize == Console->LineMaxSize)
|
||||||
|
{
|
||||||
|
Console->LineComplete = TRUE;
|
||||||
|
Console->LinePos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we don't have a complete line yet, process the pending input */
|
||||||
|
while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
|
||||||
|
{
|
||||||
|
/* Remove input event from queue */
|
||||||
|
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
||||||
|
if (IsListEmpty(&InputBuffer->InputEvents))
|
||||||
|
{
|
||||||
|
ResetEvent(InputBuffer->ActiveEvent);
|
||||||
|
}
|
||||||
|
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||||
|
|
||||||
|
/* Only pay attention to key down */
|
||||||
|
if (Input->InputEvent.EventType == KEY_EVENT &&
|
||||||
|
Input->InputEvent.Event.KeyEvent.bKeyDown)
|
||||||
|
{
|
||||||
|
LineInputKeyDown(Console, ExeName,
|
||||||
|
&Input->InputEvent.Event.KeyEvent);
|
||||||
|
ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
|
||||||
|
}
|
||||||
|
ConsoleFreeHeap(Input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have a complete line to read from */
|
||||||
|
if (Console->LineComplete)
|
||||||
|
{
|
||||||
|
while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
|
||||||
|
{
|
||||||
|
WCHAR Char = Console->LineBuffer[Console->LinePos++];
|
||||||
|
|
||||||
|
if (Unicode)
|
||||||
|
{
|
||||||
|
((PWCHAR)Buffer)[i] = Char;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Console->LinePos == Console->LineSize)
|
||||||
|
{
|
||||||
|
/* Entire line has been read */
|
||||||
|
ConsoleFreeHeap(Console->LineBuffer);
|
||||||
|
Console->LineBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* RAW mode */
|
||||||
|
|
||||||
|
/* Character input */
|
||||||
|
while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
|
||||||
|
{
|
||||||
|
/* Remove input event from queue */
|
||||||
|
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
||||||
|
if (IsListEmpty(&InputBuffer->InputEvents))
|
||||||
|
{
|
||||||
|
ResetEvent(InputBuffer->ActiveEvent);
|
||||||
|
}
|
||||||
|
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||||
|
|
||||||
|
/* Only pay attention to valid characters, on key down */
|
||||||
|
if (Input->InputEvent.EventType == KEY_EVENT &&
|
||||||
|
Input->InputEvent.Event.KeyEvent.bKeyDown &&
|
||||||
|
Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
|
||||||
|
{
|
||||||
|
WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
|
||||||
|
|
||||||
|
if (Unicode)
|
||||||
|
{
|
||||||
|
((PWCHAR)Buffer)[i] = Char;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
|
||||||
|
/* Did read something */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
ConsoleFreeHeap(Input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Only set if Status == STATUS_SUCCESS ???
|
||||||
|
if (NumCharsRead) *NumCharsRead = i;
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
#define TAB_WIDTH 8
|
||||||
|
|
||||||
|
// See condrv/text.c
|
||||||
|
/*static*/ VOID
|
||||||
|
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff);
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines)
|
||||||
|
{
|
||||||
|
/* If we hit bottom, slide the viewable screen */
|
||||||
|
if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y)
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.Y--;
|
||||||
|
if (++Buff->VirtualY == Buff->ScreenBufferSize.Y)
|
||||||
|
{
|
||||||
|
Buff->VirtualY = 0;
|
||||||
|
}
|
||||||
|
(*ScrolledLines)++;
|
||||||
|
ClearLineBuffer(Buff);
|
||||||
|
if (UpdateRect->Top != 0)
|
||||||
|
{
|
||||||
|
UpdateRect->Top--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateRect->Left = 0;
|
||||||
|
UpdateRect->Right = Buff->ScreenBufferSize.X - 1;
|
||||||
|
UpdateRect->Bottom = Buff->CursorPosition.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
ConioWriteConsole(PFRONTEND FrontEnd,
|
||||||
|
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||||
|
PWCHAR Buffer,
|
||||||
|
DWORD Length,
|
||||||
|
BOOL Attrib)
|
||||||
|
{
|
||||||
|
PCONSRV_CONSOLE Console = FrontEnd->Console;
|
||||||
|
|
||||||
|
UINT i;
|
||||||
|
PCHAR_INFO Ptr;
|
||||||
|
SMALL_RECT UpdateRect;
|
||||||
|
SHORT CursorStartX, CursorStartY;
|
||||||
|
UINT ScrolledLines;
|
||||||
|
|
||||||
|
CursorStartX = Buff->CursorPosition.X;
|
||||||
|
CursorStartY = Buff->CursorPosition.Y;
|
||||||
|
UpdateRect.Left = Buff->ScreenBufferSize.X;
|
||||||
|
UpdateRect.Top = Buff->CursorPosition.Y;
|
||||||
|
UpdateRect.Right = -1;
|
||||||
|
UpdateRect.Bottom = Buff->CursorPosition.Y;
|
||||||
|
ScrolledLines = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < Length; i++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we are in processed mode, interpret special characters and
|
||||||
|
* display them correctly. Otherwise, just put them into the buffer.
|
||||||
|
*/
|
||||||
|
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
|
||||||
|
{
|
||||||
|
/* --- CR --- */
|
||||||
|
if (Buffer[i] == L'\r')
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.X = 0;
|
||||||
|
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||||
|
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* --- LF --- */
|
||||||
|
else if (Buffer[i] == L'\n')
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.X = 0;
|
||||||
|
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* --- BS --- */
|
||||||
|
else if (Buffer[i] == L'\b')
|
||||||
|
{
|
||||||
|
/* Only handle BS if we're not on the first pos of the first line */
|
||||||
|
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
|
||||||
|
{
|
||||||
|
if (0 == Buff->CursorPosition.X)
|
||||||
|
{
|
||||||
|
/* slide virtual position up */
|
||||||
|
Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1;
|
||||||
|
Buff->CursorPosition.Y--;
|
||||||
|
UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.X--;
|
||||||
|
}
|
||||||
|
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
|
Ptr->Char.UnicodeChar = L' ';
|
||||||
|
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||||
|
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||||
|
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* --- TAB --- */
|
||||||
|
else if (Buffer[i] == L'\t')
|
||||||
|
{
|
||||||
|
UINT EndX;
|
||||||
|
|
||||||
|
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||||
|
EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1);
|
||||||
|
EndX = min(EndX, (UINT)Buff->ScreenBufferSize.X);
|
||||||
|
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
|
while (Buff->CursorPosition.X < EndX)
|
||||||
|
{
|
||||||
|
Ptr->Char.UnicodeChar = L' ';
|
||||||
|
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||||
|
++Ptr;
|
||||||
|
Buff->CursorPosition.X++;
|
||||||
|
}
|
||||||
|
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
|
||||||
|
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
||||||
|
{
|
||||||
|
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.X = 0;
|
||||||
|
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.X--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// /* --- BEL ---*/
|
||||||
|
// else if (Buffer[i] == L'\a')
|
||||||
|
// {
|
||||||
|
// // FIXME: This MUST BE moved to the terminal emulator frontend!!
|
||||||
|
// DPRINT1("Bell\n");
|
||||||
|
// // SendNotifyMessage(Console->hWindow, PM_CONSOLE_BEEP, 0, 0);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||||
|
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||||
|
|
||||||
|
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||||
|
Ptr->Char.UnicodeChar = Buffer[i];
|
||||||
|
if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||||
|
|
||||||
|
Buff->CursorPosition.X++;
|
||||||
|
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
||||||
|
{
|
||||||
|
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.X = 0;
|
||||||
|
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buff->CursorPosition.X = CursorStartX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
|
||||||
|
{
|
||||||
|
// TermWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY,
|
||||||
|
// ScrolledLines, Buffer, Length);
|
||||||
|
FrontEnd->Vtbl->WriteStream(FrontEnd,
|
||||||
|
&UpdateRect,
|
||||||
|
CursorStartX,
|
||||||
|
CursorStartY,
|
||||||
|
ScrolledLines,
|
||||||
|
Buffer,
|
||||||
|
Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS NTAPI
|
||||||
|
ConSrvTermWriteStream(IN OUT PTERMINAL This,
|
||||||
|
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||||
|
PWCHAR Buffer,
|
||||||
|
DWORD Length,
|
||||||
|
BOOL Attrib)
|
||||||
|
{
|
||||||
|
PFRONTEND FrontEnd = This->Data;
|
||||||
|
return ConioWriteConsole(FrontEnd,
|
||||||
|
Buff,
|
||||||
|
Buffer,
|
||||||
|
Length,
|
||||||
|
Attrib);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ Line discipline ***************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL NTAPI
|
static BOOL NTAPI
|
||||||
ConSrvTermSetCursorInfo(IN OUT PTERMINAL This,
|
ConSrvTermSetCursorInfo(IN OUT PTERMINAL This,
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
|
||||||
|
@ -335,7 +746,10 @@ static TERMINAL_VTBL ConSrvTermVtbl =
|
||||||
ConSrvTermInitTerminal,
|
ConSrvTermInitTerminal,
|
||||||
ConSrvTermDeinitTerminal,
|
ConSrvTermDeinitTerminal,
|
||||||
ConSrvTermDrawRegion,
|
ConSrvTermDrawRegion,
|
||||||
|
|
||||||
|
ConSrvTermReadStream,
|
||||||
ConSrvTermWriteStream,
|
ConSrvTermWriteStream,
|
||||||
|
|
||||||
ConSrvTermSetCursorInfo,
|
ConSrvTermSetCursorInfo,
|
||||||
ConSrvTermSetScreenInfo,
|
ConSrvTermSetScreenInfo,
|
||||||
ConSrvTermResizeTerminal,
|
ConSrvTermResizeTerminal,
|
||||||
|
|
|
@ -197,14 +197,31 @@ typedef struct _TERMINAL_VTBL
|
||||||
/* Interface used for both text-mode and graphics screen buffers */
|
/* Interface used for both text-mode and graphics screen buffers */
|
||||||
VOID (NTAPI *DrawRegion)(IN OUT PTERMINAL This,
|
VOID (NTAPI *DrawRegion)(IN OUT PTERMINAL This,
|
||||||
SMALL_RECT* Region);
|
SMALL_RECT* Region);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************ Line discipline ***************/
|
||||||
|
|
||||||
/* Interface used only for text-mode screen buffers */
|
/* Interface used only for text-mode screen buffers */
|
||||||
VOID (NTAPI *WriteStream)(IN OUT PTERMINAL This,
|
|
||||||
SMALL_RECT* Region,
|
NTSTATUS (NTAPI *ReadStream)(IN OUT PTERMINAL This,
|
||||||
SHORT CursorStartX,
|
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
|
||||||
SHORT CursorStartY,
|
IN BOOLEAN Unicode,
|
||||||
UINT ScrolledLines,
|
/**PWCHAR Buffer,**/
|
||||||
PWCHAR Buffer,
|
OUT PVOID Buffer,
|
||||||
UINT Length);
|
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
|
||||||
|
IN ULONG NumCharsToRead,
|
||||||
|
OUT PULONG NumCharsRead OPTIONAL);
|
||||||
|
NTSTATUS (NTAPI *WriteStream)(IN OUT PTERMINAL This,
|
||||||
|
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||||
|
PWCHAR Buffer,
|
||||||
|
DWORD Length,
|
||||||
|
BOOL Attrib);
|
||||||
|
|
||||||
|
/************ Line discipline ***************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL (NTAPI *SetCursorInfo)(IN OUT PTERMINAL This,
|
BOOL (NTAPI *SetCursorInfo)(IN OUT PTERMINAL This,
|
||||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||||
BOOL (NTAPI *SetScreenInfo)(IN OUT PTERMINAL This,
|
BOOL (NTAPI *SetScreenInfo)(IN OUT PTERMINAL This,
|
||||||
|
@ -341,10 +358,5 @@ VOID ConioDrawConsole(PCONSOLE Console);
|
||||||
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
|
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
|
||||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||||
COORD Size);
|
COORD Size);
|
||||||
NTSTATUS ConioWriteConsole(PCONSOLE Console,
|
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
|
||||||
PWCHAR Buffer,
|
|
||||||
DWORD Length,
|
|
||||||
BOOL Attrib);
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -222,10 +222,5 @@ VOID ConioDrawConsole(PCONSRV_CONSOLE Console);
|
||||||
NTSTATUS ConioResizeBuffer(PCONSRV_CONSOLE Console,
|
NTSTATUS ConioResizeBuffer(PCONSRV_CONSOLE Console,
|
||||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||||
COORD Size);
|
COORD Size);
|
||||||
NTSTATUS ConioWriteConsole(PCONSRV_CONSOLE Console,
|
|
||||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
|
||||||
PWCHAR Buffer,
|
|
||||||
DWORD Length,
|
|
||||||
BOOL Attrib);
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -12,9 +12,17 @@
|
||||||
|
|
||||||
#define TermDrawRegion(Console, Region) \
|
#define TermDrawRegion(Console, Region) \
|
||||||
(Console)->TermIFace.Vtbl->DrawRegion(&(Console)->TermIFace, (Region))
|
(Console)->TermIFace.Vtbl->DrawRegion(&(Console)->TermIFace, (Region))
|
||||||
#define TermWriteStream(Console, Region, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
|
|
||||||
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (Region), (CurStartX), (CurStartY), \
|
|
||||||
(ScrolledLines), (Buffer), (Length))
|
#define TermReadStream(Console, ExeName, /**/ Unicode, /**/ Buffer, ReadControl, NumCharsToRead, NumCharsRead) \
|
||||||
|
(Console)->TermIFace.Vtbl->ReadStream(&(Console)->TermIFace, (ExeName), /**/ (Unicode), /**/ \
|
||||||
|
(Buffer), (ReadControl), (NumCharsToRead), (NumCharsRead))
|
||||||
|
|
||||||
|
#define TermWriteStream(Console, ScreenBuffer, Buffer, Length, Attrib) \
|
||||||
|
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (ScreenBuffer), (Buffer), \
|
||||||
|
(Length), (Attrib))
|
||||||
|
|
||||||
|
|
||||||
#define TermSetCursorInfo(Console, ScreenBuffer) \
|
#define TermSetCursorInfo(Console, ScreenBuffer) \
|
||||||
(Console)->TermIFace.Vtbl->SetCursorInfo(&(Console)->TermIFace, (ScreenBuffer))
|
(Console)->TermIFace.Vtbl->SetCursorInfo(&(Console)->TermIFace, (ScreenBuffer))
|
||||||
#define TermSetScreenInfo(Console, ScreenBuffer, OldCursorX, OldCursorY) \
|
#define TermSetScreenInfo(Console, ScreenBuffer, OldCursorX, OldCursorY) \
|
||||||
|
|
|
@ -108,11 +108,11 @@ LineInputEdit(PCONSRV_CONSOLE Console,
|
||||||
{
|
{
|
||||||
for (i = Pos; i < NewSize; i++)
|
for (i = Pos; i < NewSize; i++)
|
||||||
{
|
{
|
||||||
ConioWriteConsole(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE);
|
TermWriteStream(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE);
|
||||||
}
|
}
|
||||||
for (; i < Console->LineSize; i++)
|
for (; i < Console->LineSize; i++)
|
||||||
{
|
{
|
||||||
ConioWriteConsole(Console, ActiveBuffer, L" ", 1, TRUE);
|
TermWriteStream(Console, ActiveBuffer, L" ", 1, TRUE);
|
||||||
}
|
}
|
||||||
Console->LinePos = i;
|
Console->LinePos = i;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +361,7 @@ LineInputKeyDown(PCONSRV_CONSOLE Console,
|
||||||
{
|
{
|
||||||
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
||||||
{
|
{
|
||||||
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
|
TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ LineInputKeyDown(PCONSRV_CONSOLE Console,
|
||||||
{
|
{
|
||||||
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
||||||
{
|
{
|
||||||
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
|
TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue