ReactOS 0.4.15-dev-7953-g1f49173
coninput.c File Reference
#include <consrv.h>
#include <debug.h>
Include dependency graph for coninput.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS AddInputEvents (PCONSOLE Console, PINPUT_RECORD InputRecords, ULONG NumEventsToWrite, PULONG NumEventsWritten, BOOLEAN AppendToEnd)
 
static VOID PurgeInputBuffer (IN PCONSOLE_INPUT_BUFFER InputBuffer)
 
NTSTATUS NTAPI ConDrvInitInputBuffer (IN PCONSOLE Console, IN ULONG InputBufferSize)
 
VOID NTAPI ConDrvDeinitInputBuffer (IN PCONSOLE Console)
 
NTSTATUS NTAPI ConDrvReadConsole (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN Unicode, OUT PVOID Buffer, IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl, IN PVOID Parameter OPTIONAL, IN ULONG NumCharsToRead, OUT PULONG NumCharsRead OPTIONAL)
 
NTSTATUS NTAPI ConDrvGetConsoleInput (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN KeepEvents, IN BOOLEAN WaitForMoreEvents, OUT PINPUT_RECORD InputRecord, IN ULONG NumEventsToRead, OUT PULONG NumEventsRead OPTIONAL)
 
NTSTATUS NTAPI ConDrvWriteConsoleInput (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, IN BOOLEAN AppendToEnd, IN PINPUT_RECORD InputRecord, IN ULONG NumEventsToWrite, OUT PULONG NumEventsWritten OPTIONAL)
 
NTSTATUS NTAPI ConDrvFlushConsoleInputBuffer (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer)
 
NTSTATUS NTAPI ConDrvGetConsoleNumberOfInputEvents (IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, OUT PULONG NumberOfEvents)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file coninput.c.

Function Documentation

◆ AddInputEvents()

static NTSTATUS AddInputEvents ( PCONSOLE  Console,
PINPUT_RECORD  InputRecords,
ULONG  NumEventsToWrite,
PULONG  NumEventsWritten,
BOOLEAN  AppendToEnd 
)
static

Definition at line 21 of file coninput.c.

26{
28 ULONG i = 0;
29 BOOLEAN SetWaitEvent = FALSE;
30
31 if (NumEventsWritten) *NumEventsWritten = 0;
32
33 /*
34 * When adding many single events, in the case of repeated mouse move or
35 * key down events, we try to coalesce them so that we do not saturate
36 * too quickly the input buffer.
37 */
38 if (NumEventsToWrite == 1 && !IsListEmpty(&Console->InputBuffer.InputEvents))
39 {
40 PINPUT_RECORD InputRecord = InputRecords; // Only one element
41 PINPUT_RECORD LastInputRecord;
42 ConsoleInput* ConInRec; // Input
43
44 /* Get the "next" event of the input buffer */
45 if (AppendToEnd)
46 {
47 /* Get the tail element */
48 ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Blink,
49 ConsoleInput, ListEntry);
50 }
51 else
52 {
53 /* Get the head element */
54 ConInRec = CONTAINING_RECORD(Console->InputBuffer.InputEvents.Flink,
55 ConsoleInput, ListEntry);
56 }
57 LastInputRecord = &ConInRec->InputEvent;
58
59 if (InputRecord->EventType == MOUSE_EVENT &&
61 {
62 if (LastInputRecord->EventType == MOUSE_EVENT &&
63 LastInputRecord->Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
64 {
65 /* Update the mouse position */
66 LastInputRecord->Event.MouseEvent.dwMousePosition.X =
67 InputRecord->Event.MouseEvent.dwMousePosition.X;
68 LastInputRecord->Event.MouseEvent.dwMousePosition.Y =
69 InputRecord->Event.MouseEvent.dwMousePosition.Y;
70
71 i = 1;
72 // return STATUS_SUCCESS;
74 }
75 }
76 else if (InputRecord->EventType == KEY_EVENT &&
77 InputRecord->Event.KeyEvent.bKeyDown)
78 {
79 if (LastInputRecord->EventType == KEY_EVENT &&
80 LastInputRecord->Event.KeyEvent.bKeyDown &&
81 (LastInputRecord->Event.KeyEvent.wVirtualScanCode == // Same scancode
82 InputRecord->Event.KeyEvent.wVirtualScanCode) &&
83 (LastInputRecord->Event.KeyEvent.uChar.UnicodeChar == // Same character
84 InputRecord->Event.KeyEvent.uChar.UnicodeChar) &&
85 (LastInputRecord->Event.KeyEvent.dwControlKeyState == // Same Ctrl/Alt/Shift state
86 InputRecord->Event.KeyEvent.dwControlKeyState) )
87 {
88 /* Update the repeat count */
89 LastInputRecord->Event.KeyEvent.wRepeatCount +=
90 InputRecord->Event.KeyEvent.wRepeatCount;
91
92 i = 1;
93 // return STATUS_SUCCESS;
95 }
96 }
97 }
98
99 /* If we coalesced the only one element, we can quit */
100 if (i == 1 && Status == STATUS_SUCCESS /* && NumEventsToWrite == 1 */)
101 goto Done;
102
103 /*
104 * No event coalesced, add them in the usual way.
105 */
106
107 if (AppendToEnd)
108 {
109 /* Go to the beginning of the list */
110 // InputRecords = InputRecords;
111 }
112 else
113 {
114 /* Go to the end of the list */
115 InputRecords = &InputRecords[NumEventsToWrite - 1];
116 }
117
118 /* Set the event if the list is going to be non-empty */
119 if (IsListEmpty(&Console->InputBuffer.InputEvents))
120 SetWaitEvent = TRUE;
121
122 for (i = 0; i < NumEventsToWrite && NT_SUCCESS(Status); ++i)
123 {
124 PINPUT_RECORD InputRecord;
125 ConsoleInput* ConInRec;
126
127 if (AppendToEnd)
128 {
129 /* Select the event and go to the next one */
130 InputRecord = InputRecords++;
131 }
132 else
133 {
134 /* Select the event and go to the previous one */
135 InputRecord = InputRecords--;
136 }
137
138 /* Add event to the queue */
139 ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
140 if (ConInRec == NULL)
141 {
142 // return STATUS_INSUFFICIENT_RESOURCES;
144 continue;
145 }
146
147 ConInRec->InputEvent = *InputRecord;
148
149 if (AppendToEnd)
150 {
151 /* Append the event to the end of the queue */
152 InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
153 }
154 else
155 {
156 /* Append the event to the beginning of the queue */
157 InsertHeadList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
158 }
159 _InterlockedIncrement((PLONG)&Console->InputBuffer.NumberOfEvents);
160
161 // return STATUS_SUCCESS;
163 }
164
165 if (SetWaitEvent) NtSetEvent(Console->InputBuffer.ActiveEvent, NULL);
166
167Done:
168 if (NumEventsWritten) *NumEventsWritten = i;
169
170 return Status;
171}
unsigned char BOOLEAN
CConsole Console
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
#define STATUS_SUCCESS
Definition: shellext.h:65
INPUT_RECORD InputEvent
Definition: coninput.h:15
LIST_ENTRY ListEntry
Definition: coninput.h:14
ULONG Y
Definition: bl.h:1340
ULONG X
Definition: bl.h:1339
MOUSE_EVENT_RECORD MouseEvent
Definition: wincon.h:276
union _INPUT_RECORD::@3292 Event
WORD EventType
Definition: wincon.h:273
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:275
union _KEY_EVENT_RECORD::@3291 uChar
WORD wVirtualScanCode
Definition: wincon.h:243
DWORD dwControlKeyState
Definition: wincon.h:248
WORD wRepeatCount
Definition: wincon.h:241
WCHAR UnicodeChar
Definition: wincon.h:245
DWORD dwEventFlags
Definition: wincon.h:257
COORD dwMousePosition
Definition: wincon.h:254
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14
#define MOUSE_EVENT
Definition: wincon.h:129
#define KEY_EVENT
Definition: wincon.h:128
#define MOUSE_MOVED
Definition: wincon.h:168

Referenced by ConDrvWriteConsoleInput().

◆ ConDrvDeinitInputBuffer()

VOID NTAPI ConDrvDeinitInputBuffer ( IN PCONSOLE  Console)

Definition at line 221 of file coninput.c.

222{
223 PurgeInputBuffer(&Console->InputBuffer);
224 NtClose(Console->InputBuffer.ActiveEvent);
225}
static VOID PurgeInputBuffer(IN PCONSOLE_INPUT_BUFFER InputBuffer)
Definition: coninput.c:174
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402

Referenced by ConDrvDeleteConsole(), and ConDrvInitConsole().

◆ ConDrvFlushConsoleInputBuffer()

NTSTATUS NTAPI ConDrvFlushConsoleInputBuffer ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer 
)

Definition at line 357 of file coninput.c.

359{
360 if (Console == NULL || InputBuffer == NULL)
362
363 /* Validity check */
364 ASSERT(Console == InputBuffer->Header.Console);
365
366 /* Discard all entries in the input event queue */
368 NtClearEvent(InputBuffer->ActiveEvent);
369
370 return STATUS_SUCCESS;
371}
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS NTAPI NtClearEvent(IN HANDLE EventHandle)
Definition: event.c:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953

Referenced by CON_API().

◆ ConDrvGetConsoleInput()

NTSTATUS NTAPI ConDrvGetConsoleInput ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
IN BOOLEAN  KeepEvents,
IN BOOLEAN  WaitForMoreEvents,
OUT PINPUT_RECORD  InputRecord,
IN ULONG  NumEventsToRead,
OUT PULONG NumEventsRead  OPTIONAL 
)

Definition at line 264 of file coninput.c.

271{
272 PLIST_ENTRY CurrentInput;
274 ULONG i = 0;
275
276 if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
278
279 /* Validity checks */
280 ASSERT(Console == InputBuffer->Header.Console);
281 ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToRead == 0));
282
283 if (NumEventsRead) *NumEventsRead = 0;
284
285 if (IsListEmpty(&InputBuffer->InputEvents))
286 {
287 /*
288 * No input is available. Wait for more input if requested,
289 * otherwise, we don't wait, so we return success.
290 */
291 return (WaitForMoreEvents ? STATUS_PENDING : STATUS_SUCCESS);
292 }
293
294 /* Only get input if there is any */
295 CurrentInput = InputBuffer->InputEvents.Flink;
296 i = 0;
297 while ((CurrentInput != &InputBuffer->InputEvents) && (i < NumEventsToRead))
298 {
299 Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry);
300
301 *InputRecord = Input->InputEvent;
302
303 ++InputRecord;
304 ++i;
305 CurrentInput = CurrentInput->Flink;
306
307 /* Remove the events from the queue if needed */
308 if (!KeepEvents)
309 {
310 _InterlockedDecrement((PLONG)&InputBuffer->NumberOfEvents);
311 RemoveEntryList(&Input->ListEntry);
313 }
314 }
315
316 if (NumEventsRead) *NumEventsRead = i;
317
318 if (IsListEmpty(&InputBuffer->InputEvents))
319 {
320 NtClearEvent(InputBuffer->ActiveEvent);
321 }
322
323 // FIXME: If we add back UNICODE support, it's here that we need to do the translation.
324
325 /* We read all the inputs available, we return success */
326 return STATUS_SUCCESS;
327}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
#define STATUS_PENDING
Definition: ntstatus.h:82
@ Input
Definition: arc.h:84
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15

Referenced by ReadInputBuffer().

◆ ConDrvGetConsoleNumberOfInputEvents()

NTSTATUS NTAPI ConDrvGetConsoleNumberOfInputEvents ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
OUT PULONG  NumberOfEvents 
)

Definition at line 374 of file coninput.c.

377{
378 if (Console == NULL || InputBuffer == NULL || NumberOfEvents == NULL)
380
381 /* Validity check */
382 ASSERT(Console == InputBuffer->Header.Console);
383
384 *NumberOfEvents = InputBuffer->NumberOfEvents;
385 return STATUS_SUCCESS;
386}

Referenced by CON_API().

◆ ConDrvInitInputBuffer()

NTSTATUS NTAPI ConDrvInitInputBuffer ( IN PCONSOLE  Console,
IN ULONG  InputBufferSize 
)

Definition at line 192 of file coninput.c.

194{
197
198 ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console);
199
201 NULL,
203 NULL,
204 NULL);
205
206 Status = NtCreateEvent(&Console->InputBuffer.ActiveEvent, EVENT_ALL_ACCESS,
208 if (!NT_SUCCESS(Status))
209 return Status;
210
211 Console->InputBuffer.InputBufferSize = InputBufferSize;
212 Console->InputBuffer.NumberOfEvents = 0;
213 InitializeListHead(&Console->InputBuffer.InputEvents);
214 Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
216
217 return STATUS_SUCCESS;
218}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define OBJ_INHERIT
Definition: winternl.h:225
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
@ NotificationEvent
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
VOID ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object, IN CONSOLE_IO_OBJECT_TYPE Type, IN PCONSOLE Console)
Definition: handle.c:211
@ INPUT_BUFFER
Definition: conio.h:28
#define ENABLE_ECHO_INPUT
Definition: wincon.h:80
#define ENABLE_MOUSE_INPUT
Definition: wincon.h:82
#define ENABLE_LINE_INPUT
Definition: wincon.h:79
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78

Referenced by ConDrvInitConsole().

◆ ConDrvReadConsole()

NTSTATUS NTAPI ConDrvReadConsole ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
IN BOOLEAN  Unicode,
OUT PVOID  Buffer,
IN OUT PCONSOLE_READCONSOLE_CONTROL  ReadControl,
IN PVOID Parameter  OPTIONAL,
IN ULONG  NumCharsToRead,
OUT PULONG NumCharsRead  OPTIONAL 
)

Definition at line 231 of file coninput.c.

239{
240 // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
241 // NTSTATUS Status; = STATUS_PENDING;
242
243 if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL || */
244 ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
245 {
247 }
248
249 /* Validity checks */
250 ASSERT(Console == InputBuffer->Header.Console);
251 ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
252
253 /* Call the line-discipline */
254 return TermReadStream(Console,
255 Unicode,
256 Buffer,
257 ReadControl,
258 Parameter,
259 NumCharsToRead,
260 NumCharsRead);
261}
Definition: bufpool.h:45
#define TermReadStream(Console, Unicode, Buffer, ReadControl, Parameter, NumCharsToRead, NumCharsRead)
Definition: term.h:13
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

Referenced by ReadChars().

◆ ConDrvWriteConsoleInput()

NTSTATUS NTAPI ConDrvWriteConsoleInput ( IN PCONSOLE  Console,
IN PCONSOLE_INPUT_BUFFER  InputBuffer,
IN BOOLEAN  AppendToEnd,
IN PINPUT_RECORD  InputRecord,
IN ULONG  NumEventsToWrite,
OUT PULONG NumEventsWritten  OPTIONAL 
)

Definition at line 330 of file coninput.c.

336{
337 if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
339
340 /* Validity checks */
341 ASSERT(Console == InputBuffer->Header.Console);
342 ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToWrite == 0));
343
344 /* Now, add the events */
345 if (NumEventsWritten) *NumEventsWritten = 0;
346
347 // FIXME: If we add back UNICODE support, it's here that we need to do the translation.
348
349 return AddInputEvents(Console,
350 InputRecord,
351 NumEventsToWrite,
352 NumEventsWritten,
353 AppendToEnd);
354}
static NTSTATUS AddInputEvents(PCONSOLE Console, PINPUT_RECORD InputRecords, ULONG NumEventsToWrite, PULONG NumEventsWritten, BOOLEAN AppendToEnd)
Definition: coninput.c:21

Referenced by ConioAddInputEvents(), and ConioResizeBuffer().

◆ PurgeInputBuffer()

static VOID PurgeInputBuffer ( IN PCONSOLE_INPUT_BUFFER  InputBuffer)
static

Definition at line 174 of file coninput.c.

175{
176 PLIST_ENTRY CurrentEntry;
178
179 /* Discard all entries in the input event queue */
180 _InterlockedExchange((PLONG)&InputBuffer->NumberOfEvents, 0);
181 while (!IsListEmpty(&InputBuffer->InputEvents))
182 {
183 CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
184 Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
186 }
187
188 // NtClose(Console->InputBuffer.ActiveEvent);
189}
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)

Referenced by ConDrvDeinitInputBuffer(), and ConDrvFlushConsoleInputBuffer().