- Turn some BOOLs into BOOLEANs in condrv.
- Move some coninput functions into condrv.

svn path=/trunk/; revision=59326
This commit is contained in:
Hermès Bélusca-Maïto 2013-06-23 23:19:42 +00:00
parent 6b0f55c9e9
commit 60f250a72d
7 changed files with 415 additions and 251 deletions

View file

@ -18,6 +18,7 @@ list(APPEND SOURCE
init.c
lineinput.c
settings.c
condrv/coninput.c
condrv/conoutput.c
condrv/console.c
condrv/graphics.c

View file

@ -0,0 +1,304 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/coninput.c
* PURPOSE: Console Input functions
* PROGRAMMERS: Jeffrey Morlan
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "include/conio.h"
#include "conio.h"
#include "handle.h"
#include "lineinput.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \
(Access), (LockConsole), INPUT_BUFFER)
#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \
(Access), (LockConsole), INPUT_BUFFER)
#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \
ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
typedef struct ConsoleInput_t
{
LIST_ENTRY ListEntry;
INPUT_RECORD InputEvent;
} ConsoleInput;
typedef struct _GET_INPUT_INFO
{
PCSR_THREAD CallingThread; // The thread which called the input API.
PVOID HandleEntry; // The handle data associated with the wait thread.
PCONSOLE_INPUT_BUFFER InputBuffer; // The input buffer corresponding to the handle.
} GET_INPUT_INFO, *PGET_INPUT_INFO;
/* PRIVATE FUNCTIONS **********************************************************/
#if 0
static VOID FASTCALL
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);
}
}
#endif
NTSTATUS FASTCALL
ConioProcessInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent)
{
ConsoleInput *ConInRec;
/* Check for pause or unpause */
if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
{
WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
{
DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT &&
(vk == VK_PAUSE || (vk == 'S' &&
(cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
{
ConioPause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
}
}
else
{
if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
{
ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
}
}
}
/* Add event to the queue */
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;
ConInRec->InputEvent = *InputEvent;
InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
SetEvent(Console->InputBuffer.ActiveEvent);
CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue,
WaitAny,
NULL,
NULL);
if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue))
{
CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue);
}
return STATUS_SUCCESS;
}
VOID FASTCALL
PurgeInputBuffer(PCONSOLE Console)
{
PLIST_ENTRY CurrentEntry;
ConsoleInput* Event;
while (!IsListEmpty(&Console->InputBuffer.InputEvents))
{
CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents);
Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
ConsoleFreeHeap(Event);
}
CloseHandle(Console->InputBuffer.ActiveEvent);
}
VOID NTAPI
ConDrvProcessKey(IN PCONSOLE Console,
IN BOOLEAN Down,
IN UINT VirtualKeyCode,
IN UINT VirtualScanCode,
IN WCHAR UnicodeChar,
IN ULONG ShiftState,
IN BYTE KeyStateCtrl)
{
INPUT_RECORD er;
/* process Ctrl-C and Ctrl-Break */
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) )
{
DPRINT1("Console_Api Ctrl-C\n");
ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
if (Console->LineBuffer && !Console->LineComplete)
{
/* Line input is in progress; end it */
Console->LinePos = Console->LineSize = 0;
Console->LineComplete = TRUE;
}
return;
}
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
(VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) )
{
if (!Down) return;
/* scroll up or down */
if (VK_UP == VirtualKeyCode)
{
/* only scroll up if there is room to scroll up into */
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y++;
}
}
else
{
/* only scroll down if there is room to scroll down into */
if (Console->ActiveBuffer->CursorPosition.Y != 0)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y--;
}
}
ConioDrawConsole(Console);
return;
}
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = 1;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
ConioProcessInputEvent(Console, &er);
}
/* PUBLIC SERVER APIS *********************************************************/
NTSTATUS NTAPI
ConDrvWriteConsoleInput(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer,
IN BOOLEAN Unicode,
IN PINPUT_RECORD InputRecord,
IN ULONG NumEventsToWrite,
OUT PULONG NumEventsWritten)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG i;
if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
return STATUS_INVALID_PARAMETER;
/* Validity checks */
ASSERT(Console == InputBuffer->Header.Console);
ASSERT( (InputRecord != NULL && NumEventsToWrite >= 0) ||
(InputRecord == NULL && NumEventsToWrite == 0) );
if (NumEventsWritten) *NumEventsWritten = 0;
for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
{
if (InputRecord->EventType == KEY_EVENT && !Unicode)
{
CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar;
ConsoleInputAnsiCharToUnicodeChar(Console,
&InputRecord->Event.KeyEvent.uChar.UnicodeChar,
&AsciiChar);
}
Status = ConioProcessInputEvent(Console, InputRecord++);
}
if (NumEventsWritten) *NumEventsWritten = i;
return Status;
}
NTSTATUS NTAPI
ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer)
{
PLIST_ENTRY CurrentEntry;
ConsoleInput* Event;
if (Console == NULL || InputBuffer == NULL)
return STATUS_INVALID_PARAMETER;
/* Validity check */
ASSERT(Console == InputBuffer->Header.Console);
/* Discard all entries in the input event queue */
while (!IsListEmpty(&InputBuffer->InputEvents))
{
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
ConsoleFreeHeap(Event);
}
ResetEvent(InputBuffer->ActiveEvent);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer,
OUT PULONG NumEvents)
{
PLIST_ENTRY CurrentInput;
if (Console == NULL || InputBuffer == NULL || NumEvents == NULL)
return STATUS_INVALID_PARAMETER;
/* Validity check */
ASSERT(Console == InputBuffer->Header.Console);
*NumEvents = 0;
/* If there are any events ... */
CurrentInput = InputBuffer->InputEvents.Flink;
while (CurrentInput != &InputBuffer->InputEvents)
{
CurrentInput = CurrentInput->Flink;
(*NumEvents)++;
}
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -227,7 +227,7 @@ ConDrvSetConsoleCursorInfo(IN PCONSOLE Console,
IN PCONSOLE_CURSOR_INFO CursorInfo)
{
ULONG Size;
BOOL Visible, Success = TRUE;
BOOLEAN Visible, Success = TRUE;
if (Console == NULL || Buffer == NULL || CursorInfo == NULL)
return STATUS_INVALID_PARAMETER;

View file

@ -549,7 +549,7 @@ ConDrvRegisterFrontEnd(IN PCONSOLE Console,
Console->TermIFace.Console = Console;
/* Initialize the frontend AFTER having attached it to the console */
DPRINT("Finish initialization of frontend\n");
DPRINT1("Finish initialization of frontend\n");
Status = Console->TermIFace.Vtbl->InitFrontEnd(&Console->TermIFace, Console);
if (!NT_SUCCESS(Status))
{
@ -565,9 +565,9 @@ ConDrvRegisterFrontEnd(IN PCONSOLE Console,
/* Copy buffer contents to screen */
// FrontEnd.Draw();
// ConioDrawConsole(Console);
DPRINT("Console drawn\n");
DPRINT1("Console drawn\n");
DPRINT("Terminal FrontEnd initialization done\n");
DPRINT1("Terminal FrontEnd initialization done\n");
return STATUS_SUCCESS;
}
@ -584,7 +584,7 @@ ConDrvDeregisterFrontEnd(IN PCONSOLE Console)
/* Detach the frontend from the console */
RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace));
DPRINT("Terminal FrontEnd unregistered\n");
DPRINT1("Terminal FrontEnd unregistered\n");
return STATUS_SUCCESS;
}
@ -597,26 +597,28 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
* Forbid validation of any console by other threads
* during the deletion of this console.
*/
ConDrvLockConsoleListExclusive();
// ConDrvLockConsoleListExclusive();
/* Check the existence of the console, and if it's ok, continue */
if (!ConDrvValidateConsolePointer(Console))
{
/* Unlock the console list and return */
ConDrvUnlockConsoleList();
return;
}
// /* Check the existence of the console, and if it's ok, continue */
// if (!ConDrvValidateConsolePointer(Console))
// {
// /* Unlock the console list and return */
// ConDrvUnlockConsoleList();
// return;
// }
/*
* If the console is already being destroyed
* (thus not running), just return.
*/
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
{
/* Unlock the console list and return */
ConDrvUnlockConsoleList();
return;
}
// /*
// * If the console is already being destroyed
// * (thus not running), just return.
// */
// if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE))
// {
// /* Unlock the console list and return */
// ConDrvUnlockConsoleList();
// return;
// }
if (!ConDrvValidateConsole(Console, CONSOLE_RUNNING, TRUE)) return;
/*
* We are about to be destroyed. Signal it to other people
@ -625,6 +627,9 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
*/
Console->State = CONSOLE_TERMINATING;
/* We really delete the console. Reset the count to be sure. */
Console->ReferenceCount = 0;
/*
* Allow other threads to finish their job: basically, unlock
* all other calls to EnterCriticalSection(&Console->Lock); by
@ -634,14 +639,25 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
* can see that we are in fact already deleting the console.
*/
LeaveCriticalSection(&Console->Lock);
ConDrvUnlockConsoleList();
// ConDrvUnlockConsoleList();
/* FIXME: Send a terminate message to all the processes owning this console */
/* Close all the applications which are linked to this console */
/*
* FIXME: Windows will wait up to 5 seconds for the thread to exit.
* We shouldn't wait here, though, since the console lock is entered.
* A copy of the thread list probably needs to be made.
*/
// ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT);
// DPRINT1("Apps closed\n");
// FIXME: Be sure that, starting from here, there is NO app running
// on this console anymore !!!!!
/* Cleanup the UI-oriented part */
DPRINT("Deregister console\n");
DPRINT1("Deregister console\n");
ConDrvDeregisterFrontEnd(Console);
DPRINT("Console deregistered\n");
DPRINT1("Console deregistered\n");
/***
* Check that the console is in terminating state before continuing
@ -649,30 +665,36 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
* ...unless to cancel console deletion ?).
***/
ConDrvLockConsoleListExclusive();
// ConDrvLockConsoleListExclusive();
/* Re-check the existence of the console, and if it's ok, continue */
if (!ConDrvValidateConsolePointer(Console))
{
/* Unlock the console list and return */
ConDrvUnlockConsoleList();
return;
}
// /* Re-check the existence of the console, and if it's ok, continue */
// if (!ConDrvValidateConsolePointer(Console))
// {
// /* Unlock the console list and return */
// ConDrvUnlockConsoleList();
// return;
// }
if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE))
{
ConDrvUnlockConsoleList();
return;
}
// if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE))
// {
// ConDrvUnlockConsoleList();
// return;
// }
if (!ConDrvValidateConsole(Console, CONSOLE_TERMINATING, TRUE)) return;
/* We are now in destruction */
Console->State = CONSOLE_IN_DESTRUCTION;
/////////////////////
ConDrvLockConsoleListExclusive();
/////////////////////
/* Remove the console from the list */
RemoveEntryList(&Console->Entry);
/* We really delete the console. Reset the count to be sure. */
Console->ReferenceCount = 0;
/* Unlock the console list */
ConDrvUnlockConsoleList();
/* Discard all entries in the input event queue */
PurgeInputBuffer(Console);
@ -704,8 +726,8 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
ConsoleFreeHeap(Console);
DPRINT("ConDrvDeleteConsole - Console destroyed\n");
/* Unlock the console list and return */
ConDrvUnlockConsoleList();
// /* Unlock the console list and return */
// ConDrvUnlockConsoleList();
}

View file

@ -606,7 +606,7 @@ ConioWriteConsole(PCONSOLE Console,
NTSTATUS NTAPI
ConDrvReadConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOL Unicode,
IN BOOLEAN Unicode,
OUT PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
@ -680,7 +680,7 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
NTSTATUS NTAPI
ConDrvWriteConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOL Unicode,
IN BOOLEAN Unicode,
IN PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
@ -1161,9 +1161,9 @@ ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console,
NTSTATUS NTAPI
ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOL Unicode,
IN BOOLEAN Unicode,
IN PSMALL_RECT ScrollRectangle,
IN BOOL UseClipRectangle,
IN BOOLEAN UseClipRectangle,
IN PSMALL_RECT ClipRectangle OPTIONAL,
IN PCOORD DestinationOrigin,
IN CHAR_INFO FillChar)

View file

@ -34,9 +34,6 @@
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
typedef struct ConsoleInput_t
{
LIST_ENTRY ListEntry;
@ -66,146 +63,6 @@ ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
}
}
NTSTATUS FASTCALL
ConioProcessInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent)
{
ConsoleInput *ConInRec;
/* Check for pause or unpause */
if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
{
WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
{
DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT &&
(vk == VK_PAUSE || (vk == 'S' &&
(cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
{
ConioPause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
}
}
else
{
if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
{
ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
}
}
}
/* Add event to the queue */
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;
ConInRec->InputEvent = *InputEvent;
InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
SetEvent(Console->InputBuffer.ActiveEvent);
CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue,
WaitAny,
NULL,
NULL);
if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue))
{
CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue);
}
return STATUS_SUCCESS;
}
VOID FASTCALL
PurgeInputBuffer(PCONSOLE Console)
{
PLIST_ENTRY CurrentEntry;
ConsoleInput* Event;
while (!IsListEmpty(&Console->InputBuffer.InputEvents))
{
CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents);
Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
ConsoleFreeHeap(Event);
}
CloseHandle(Console->InputBuffer.ActiveEvent);
}
VOID NTAPI
ConDrvProcessKey(IN PCONSOLE Console,
IN BOOLEAN Down,
IN UINT VirtualKeyCode,
IN UINT VirtualScanCode,
IN WCHAR UnicodeChar,
IN ULONG ShiftState,
IN BYTE KeyStateCtrl)
{
INPUT_RECORD er;
/* process Ctrl-C and Ctrl-Break */
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) )
{
DPRINT1("Console_Api Ctrl-C\n");
ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
if (Console->LineBuffer && !Console->LineComplete)
{
/* Line input is in progress; end it */
Console->LinePos = Console->LineSize = 0;
Console->LineComplete = TRUE;
}
return;
}
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
(VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) )
{
if (!Down) return;
/* scroll up or down */
if (VK_UP == VirtualKeyCode)
{
/* only scroll up if there is room to scroll up into */
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y++;
}
}
else
{
/* only scroll down if there is room to scroll down into */
if (Console->ActiveBuffer->CursorPosition.Y != 0)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y--;
}
}
ConioDrawConsole(Console);
return;
}
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = 1;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
ConioProcessInputEvent(Console, &er);
}
static NTSTATUS
WaitBeforeReading(IN PGET_INPUT_INFO InputInfo,
IN PCSR_API_MESSAGE ApiMessage,
@ -683,16 +540,19 @@ CSR_API(SrvGetConsoleInput)
return Status;
}
NTSTATUS NTAPI
ConDrvWriteConsoleInput(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer,
IN BOOLEAN Unicode,
IN PINPUT_RECORD InputRecord,
IN ULONG NumEventsToWrite,
OUT PULONG NumEventsWritten);
CSR_API(SrvWriteConsoleInput)
{
NTSTATUS Status;
PCONSOLE_WRITEINPUT WriteInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteInputRequest;
PINPUT_RECORD InputRecord;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE_INPUT_BUFFER InputBuffer;
PCONSOLE Console;
DWORD Length;
DWORD i;
ULONG NumEventsWritten = 0;
DPRINT("SrvWriteConsoleInput\n");
@ -704,92 +564,69 @@ CSR_API(SrvWriteConsoleInput)
return STATUS_INVALID_PARAMETER;
}
Status = ConSrvGetInputBuffer(ProcessData, WriteInputRequest->InputHandle, &InputBuffer, GENERIC_WRITE, TRUE);
Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
WriteInputRequest->InputHandle,
&InputBuffer, GENERIC_WRITE, TRUE);
if (!NT_SUCCESS(Status)) return Status;
Console = InputBuffer->Header.Console;
InputRecord = WriteInputRequest->InputRecord;
Length = WriteInputRequest->Length;
for (i = 0; i < Length && NT_SUCCESS(Status); i++)
{
if (!WriteInputRequest->Unicode &&
InputRecord->EventType == KEY_EVENT)
{
CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar;
ConsoleInputAnsiCharToUnicodeChar(Console,
&InputRecord->Event.KeyEvent.uChar.UnicodeChar,
&AsciiChar);
}
Status = ConioProcessInputEvent(Console, InputRecord++);
}
Status = ConDrvWriteConsoleInput(InputBuffer->Header.Console,
InputBuffer,
WriteInputRequest->Unicode,
WriteInputRequest->InputRecord,
WriteInputRequest->Length,
&NumEventsWritten);
WriteInputRequest->Length = NumEventsWritten;
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
WriteInputRequest->Length = i;
return Status;
}
NTSTATUS NTAPI
ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer);
CSR_API(SrvFlushConsoleInputBuffer)
{
NTSTATUS Status;
PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest;
PLIST_ENTRY CurrentEntry;
PCONSOLE_INPUT_BUFFER InputBuffer;
ConsoleInput* Event;
DPRINT("SrvFlushConsoleInputBuffer\n");
Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
FlushInputBufferRequest->InputHandle,
&InputBuffer,
GENERIC_WRITE,
TRUE);
FlushInputBufferRequest->InputHandle,
&InputBuffer, GENERIC_WRITE, TRUE);
if (!NT_SUCCESS(Status)) return Status;
/* Discard all entries in the input event queue */
while (!IsListEmpty(&InputBuffer->InputEvents))
{
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
ConsoleFreeHeap(Event);
}
ResetEvent(InputBuffer->ActiveEvent);
Status = ConDrvFlushConsoleInputBuffer(InputBuffer->Header.Console,
InputBuffer);
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
return STATUS_SUCCESS;
return Status;
}
NTSTATUS NTAPI
ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console,
IN PCONSOLE_INPUT_BUFFER InputBuffer,
OUT PULONG NumEvents);
CSR_API(SrvGetConsoleNumberOfInputEvents)
{
NTSTATUS Status;
PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumInputEventsRequest;
PCONSOLE_INPUT_BUFFER InputBuffer;
PLIST_ENTRY CurrentInput;
DWORD NumEvents;
DPRINT("SrvGetConsoleNumberOfInputEvents\n");
Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), GetNumInputEventsRequest->InputHandle, &InputBuffer, GENERIC_READ, TRUE);
Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
GetNumInputEventsRequest->InputHandle,
&InputBuffer, GENERIC_READ, TRUE);
if (!NT_SUCCESS(Status)) return Status;
CurrentInput = InputBuffer->InputEvents.Flink;
/* GetNumInputEventsRequest->NumInputEvents = */ NumEvents = 0;
/* If there are any events ... */
while (CurrentInput != &InputBuffer->InputEvents)
{
CurrentInput = CurrentInput->Flink;
NumEvents++;
}
Status = ConDrvGetConsoleNumberOfInputEvents(InputBuffer->Header.Console,
InputBuffer,
&GetNumInputEventsRequest->NumInputEvents);
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
GetNumInputEventsRequest->NumInputEvents = NumEvents;
return STATUS_SUCCESS;
return Status;
}
/* EOF */

View file

@ -411,7 +411,7 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
NTSTATUS NTAPI
ConDrvReadConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOL Unicode,
IN BOOLEAN Unicode,
OUT PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
@ -452,7 +452,7 @@ CSR_API(SrvReadConsoleOutput)
NTSTATUS NTAPI
ConDrvWriteConsoleOutput(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOL Unicode,
IN BOOLEAN Unicode,
IN PCHAR_INFO CharInfo/*Buffer*/,
IN PCOORD BufferSize,
IN PCOORD BufferCoord,
@ -762,9 +762,9 @@ CSR_API(SrvSetConsoleScreenBufferSize)
NTSTATUS NTAPI
ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN BOOL Unicode,
IN BOOLEAN Unicode,
IN PSMALL_RECT ScrollRectangle,
IN BOOL UseClipRectangle,
IN BOOLEAN UseClipRectangle,
IN PSMALL_RECT ClipRectangle OPTIONAL,
IN PCOORD DestinationOrigin,
IN CHAR_INFO FillChar);