ReactOS 0.4.15-dev-7788-g1ad9096
keyboard.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS VT100 emulator
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/dd/green/keyboard.c
5 * PURPOSE: Keyboard part of green management
6 * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
7 */
8
9#include "green.h"
10
11#define NDEBUG
12#include <debug.h>
13
14static BOOLEAN
17 IN ULONG InputBufferSize,
19 OUT PULONG OutputBufferSize,
20 OUT PULONG BytesConsumed)
21{
22 BOOLEAN NormalKey = FALSE;
23 USHORT MakeCode;
24
25 if (InputBufferSize == 0)
26 return FALSE;
27
28 switch (*InputBuffer)
29 {
30 case 0x1b: MakeCode = 0x01; NormalKey = TRUE; break; /* ESC */
31
32 case '1': MakeCode = 0x02; NormalKey = TRUE; break;
33 case '2': MakeCode = 0x03; NormalKey = TRUE; break;
34 case '3': MakeCode = 0x04; NormalKey = TRUE; break;
35 case '4': MakeCode = 0x05; NormalKey = TRUE; break;
36 case '5': MakeCode = 0x06; NormalKey = TRUE; break;
37 case '6': MakeCode = 0x07; NormalKey = TRUE; break;
38 case '7': MakeCode = 0x08; NormalKey = TRUE; break;
39 case '8': MakeCode = 0x09; NormalKey = TRUE; break;
40 case '9': MakeCode = 0x0a; NormalKey = TRUE; break;
41 case '0': MakeCode = 0x0b; NormalKey = TRUE; break;
42 case '-': MakeCode = 0x0c; NormalKey = TRUE; break;
43 case '=': MakeCode = 0x0d; NormalKey = TRUE; break;
44 case '\b': MakeCode = 0x0e; NormalKey = TRUE; break;
45
46 case '\t': MakeCode = 0x0f; NormalKey = TRUE; break;
47 case 'q': MakeCode = 0x10; NormalKey = TRUE; break;
48 case 'w': MakeCode = 0x11; NormalKey = TRUE; break;
49 case 'e': MakeCode = 0x12; NormalKey = TRUE; break;
50 case 'r': MakeCode = 0x13; NormalKey = TRUE; break;
51 case 't': MakeCode = 0x14; NormalKey = TRUE; break;
52 case 'y': MakeCode = 0x15; NormalKey = TRUE; break;
53 case 'u': MakeCode = 0x16; NormalKey = TRUE; break;
54 case 'i': MakeCode = 0x17; NormalKey = TRUE; break;
55 case 'o': MakeCode = 0x18; NormalKey = TRUE; break;
56 case 'p': MakeCode = 0x19; NormalKey = TRUE; break;
57 case '[': MakeCode = 0x1a; NormalKey = TRUE; break;
58 case ']': MakeCode = 0x1b; NormalKey = TRUE; break;
59
60 case '\r': MakeCode = 0x1c; NormalKey = TRUE; break;
61
62 case 'a': MakeCode = 0x1e; NormalKey = TRUE; break;
63 case 's': MakeCode = 0x1f; NormalKey = TRUE; break;
64 case 'd': MakeCode = 0x20; NormalKey = TRUE; break;
65 case 'f': MakeCode = 0x21; NormalKey = TRUE; break;
66 case 'g': MakeCode = 0x22; NormalKey = TRUE; break;
67 case 'h': MakeCode = 0x23; NormalKey = TRUE; break;
68 case 'j': MakeCode = 0x24; NormalKey = TRUE; break;
69 case 'k': MakeCode = 0x25; NormalKey = TRUE; break;
70 case 'l': MakeCode = 0x26; NormalKey = TRUE; break;
71 case ';': MakeCode = 0x27; NormalKey = TRUE; break;
72 case '\'': MakeCode = 0x28; NormalKey = TRUE; break;
73
74 case '`': MakeCode = 0x29; NormalKey = TRUE; break;
75
76 case '\\': MakeCode = 0x2b; NormalKey = TRUE; break;
77
78 case 'z': MakeCode = 0x2c; NormalKey = TRUE; break;
79 case 'x': MakeCode = 0x2d; NormalKey = TRUE; break;
80 case 'c': MakeCode = 0x2e; NormalKey = TRUE; break;
81 case 'v': MakeCode = 0x2f; NormalKey = TRUE; break;
82 case 'b': MakeCode = 0x30; NormalKey = TRUE; break;
83 case 'n': MakeCode = 0x31; NormalKey = TRUE; break;
84 case 'm': MakeCode = 0x32; NormalKey = TRUE; break;
85 case ',': MakeCode = 0x33; NormalKey = TRUE; break;
86 case '.': MakeCode = 0x34; NormalKey = TRUE; break;
87 case '/': MakeCode = 0x35; NormalKey = TRUE; break;
88
89 case ' ': MakeCode = 0x39; NormalKey = TRUE; break;
90 }
91 if (NormalKey && *OutputBufferSize >= 2)
92 {
93 OutputBuffer[0].MakeCode = MakeCode;
94 OutputBuffer[0].Flags = KEY_MAKE;
95 OutputBuffer[1].MakeCode = MakeCode;
96 OutputBuffer[1].Flags = KEY_BREAK;
97 *BytesConsumed = 2;
98 return TRUE;
99 }
100
101 /* Consume strange character by ignoring it */
102 DPRINT1("Strange byte received 0x%02x ('%c')\n",
103 *InputBuffer, *InputBuffer >= 32 ? *InputBuffer : '.');
104 *BytesConsumed = 1;
105 return TRUE;
106}
107
112{
114 PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
116
117 DPRINT("KeyboardInitialize() called\n");
118
121 NULL,
124 TRUE,
125 &Fdo);
126 if (!NT_SUCCESS(Status))
127 return Status;
128
129 DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension;
130 RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION));
131 DeviceExtension->Common.Type = KeyboardFDO;
134 ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->KeyboardFdo = Fdo;
136 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
137
138 return STATUS_SUCCESS;
139}
140
141static VOID NTAPI
143 IN PKDPC Dpc,
144 IN PVOID pDeviceExtension, /* real type PKEYBOARD_DEVICE_EXTENSION */
145 IN PVOID Unused1,
146 IN PVOID Unused2)
147{
148 PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
149 ULONG Queue;
150 ULONG InputDataConsumed;
151
152 DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)pDeviceExtension;
153
154 Queue = DeviceExtension->ActiveQueue % 2;
155 InterlockedIncrement((PLONG)&DeviceExtension->ActiveQueue);
157 DeviceExtension->ClassInformation.ClassDeviceObject,
158 DeviceExtension->KeyboardInputData[Queue],
159 DeviceExtension->KeyboardInputData[Queue] + DeviceExtension->InputDataCount[Queue],
160 &InputDataConsumed);
161
162 DeviceExtension->InputDataCount[Queue] = 0;
163}
164
165static VOID NTAPI
168{
170 PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
171 PGREEN_DEVICE_EXTENSION GreenDeviceExtension;
172 PDEVICE_OBJECT LowerDevice;
173 UCHAR Buffer[16]; /* Arbitrary size */
176 PIRP Irp;
177 IO_STATUS_BLOCK ioStatus;
180 ULONG i, Queue;
181 ULONG SpaceInQueue;
182 ULONG BytesConsumed = 0;
185
186 DPRINT("KeyboardDeviceWorker() called\n");
187
189 DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
190 GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension;
191 LowerDevice = GreenDeviceExtension->Serial;
192 BufferSize = sizeof(Buffer);
193 Zero.QuadPart = 0;
194
195 /* Initialize device extension */
196 DeviceExtension->ActiveQueue = 0;
197 DeviceExtension->InputDataCount[0] = 0;
198 DeviceExtension->InputDataCount[1] = 0;
199 KeInitializeDpc(&DeviceExtension->KeyboardDpc, KeyboardDpcSendData, DeviceExtension);
200 RtlZeroMemory(&DeviceExtension->KeyboardInputData, sizeof(DeviceExtension->KeyboardInputData));
201
202 /* main read loop */
203 while (TRUE)
204 {
208 LowerDevice,
210 &Zero,
211 &event,
212 &ioStatus);
213 if (!Irp)
214 {
215 /* no memory actually, try later */
217 continue;
218 }
219
220 Status = IoCallDriver(LowerDevice, Irp);
221 if (Status == STATUS_PENDING)
222 {
224 Status = ioStatus.Status;
225 }
226 if (!NT_SUCCESS(Status))
227 continue;
228
229 /* Read all available data and process */
230 i = 0;
231 while (i < ioStatus.Information)
232 {
233 Queue = DeviceExtension->ActiveQueue % 2;
234
235 Input = &DeviceExtension->KeyboardInputData[Queue][DeviceExtension->InputDataCount[Queue]];
236
237 /* Translate current chars to scan codes */
238 SpaceInQueue = KEYBOARD_BUFFER_SIZE - DeviceExtension->InputDataCount[Queue];
240 &Buffer[i], /* input buffer */
241 ioStatus.Information - i, /* input buffer size */
242 Input, /* output buffer */
243 &SpaceInQueue, /* output buffer size */
244 &BytesConsumed)) /* bytes consumed in input buffer */
245 {
246 DPRINT("Got char 0x%02x (%c)\n", Buffer[i], Buffer[i] >= 32 ? Buffer[i] : ' ');
247 DeviceExtension->InputDataCount[Queue] += BytesConsumed;
248
249 /* Send the data to the keyboard class driver */
251 KeInsertQueueDpc(&DeviceExtension->KeyboardDpc, NULL, NULL);
253 i += BytesConsumed;
254 }
255 else
256 {
257 /* TranslateCharToScanCodes failed. Possible reasons:
258 * - not enough bytes in input buffer (escape control code; wait next received bytes)
259 * - not enough room in output buffer (wait for the Dpc to empty it)
260 *
261 * The best way to resolve this is to try later.
262 */
263 i++;
264 }
265 }
266 }
267
269}
270
274 IN PIRP Irp)
275{
277 PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
279
281 Irp->IoStatus.Information = 0;
282 DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
283
284 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
285 {
287 {
288 DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
289 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
290 {
292 break;
293 }
294
295 DeviceExtension->ClassInformation =
296 *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
297
298 /* Start read loop */
300 &DeviceExtension->WorkerThreadHandle,
301 (ACCESS_MASK)0L,
302 NULL,
303 NULL,
304 NULL,
307 break;
308 }
309 default:
310 {
311 DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
312 Stack->Parameters.DeviceIoControl.IoControlCode);
314 }
315 }
316
317 Irp->IoStatus.Status = Status;
319 return Status;
320}
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define BufferSize
Definition: mmc.h:75
#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
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
switch(r->id)
Definition: btrfs.c:3046
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:418
Status
Definition: gdiplustypes.h:25
struct _cl_event * event
Definition: glext.h:7739
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
@ KeyboardFDO
Definition: green.h:28
#define KEYBOARD_BUFFER_SIZE
Definition: green.h:19
struct _GREEN_DEVICE_EXTENSION * PGREEN_DEVICE_EXTENSION
struct _GREEN_DRIVER_EXTENSION * PGREEN_DRIVER_EXTENSION
struct _KEYBOARD_DEVICE_EXTENSION * PKEYBOARD_DEVICE_EXTENSION
struct _CONNECT_DATA * PCONNECT_DATA
#define IOCTL_INTERNAL_KEYBOARD_CONNECT
Definition: kbdmou.h:56
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
Definition: kbdmou.h:86
static BOOLEAN TranslateCharToScanCodes(IN PUCHAR InputBuffer, IN ULONG InputBufferSize, OUT KEYBOARD_INPUT_DATA *OutputBuffer, OUT PULONG OutputBufferSize, OUT PULONG BytesConsumed)
Definition: keyboard.c:15
static VOID NTAPI KeyboardDpcSendData(IN PKDPC Dpc, IN PVOID pDeviceExtension, IN PVOID Unused1, IN PVOID Unused2)
Definition: keyboard.c:142
NTSTATUS KeyboardAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo)
Definition: keyboard.c:109
static VOID NTAPI KeyboardDeviceWorker(PVOID Context)
Definition: keyboard.c:166
NTSTATUS KeyboardInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: keyboard.c:272
#define KernelMode
Definition: asm.h:34
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define KEY_BREAK
Definition: ntddkbd.h:71
#define KEY_MAKE
Definition: ntddkbd.h:70
@ NotificationEvent
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1904
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1145
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
#define STATUS_PENDING
Definition: ntstatus.h:82
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_KEYBOARD
Definition: winioctl.h:117
#define IRP_MJ_READ
Definition: rdpdr.c:46
@ Input
Definition: arc.h:84
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
GREEN_DEVICE_TYPE Type
Definition: green.h:40
PDEVICE_OBJECT LowerDevice
Definition: green.h:41
PVOID ClassService
Definition: kbdmou.h:82
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Serial
Definition: green.h:84
Definition: ketypes.h:699
COMMON_FDO_DEVICE_EXTENSION Common
Definition: green.h:47
ULONG InputDataCount[2]
Definition: green.h:55
CONNECT_DATA ClassInformation
Definition: green.h:50
KEYBOARD_INPUT_DATA KeyboardInputData[2][KEYBOARD_BUFFER_SIZE]
Definition: green.h:56
PDEVICE_OBJECT Green
Definition: green.h:48
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_ WDFDRIVER _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT Pdo
Definition: wdfminiport.h:72
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define DO_POWER_PAGABLE
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Suspended
Definition: ketypes.h:420
unsigned char UCHAR
Definition: xmlstorage.h:181