WIN32K code cleanup.
[reactos.git] / reactos / subsys / win32k / ntuser / input.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: input.c,v 1.6 2003/05/18 17:16:17 ea Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Window classes
24 * FILE: subsys/win32k/ntuser/class.c
25 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * REVISION HISTORY:
27 * 06-06-2001 CSH Created
28 */
29
30 /* INCLUDES ******************************************************************/
31
32 #include <ddk/ntddk.h>
33 #include <win32k/win32k.h>
34 #include <win32k/userobj.h>
35 #include <include/class.h>
36 #include <include/error.h>
37 #include <include/winsta.h>
38 #include <include/msgqueue.h>
39 #include <ddk/ntddmou.h>
40 #include <include/mouse.h>
41
42 #define NDEBUG
43 #include <debug.h>
44
45 /* GLOBALS *******************************************************************/
46
47 static HANDLE MouseDeviceHandle;
48 static HANDLE KeyboardThreadHandle;
49 static CLIENT_ID KeyboardThreadId;
50 static HANDLE KeyboardDeviceHandle;
51 static KEVENT InputThreadsStart;
52 static BOOLEAN InputThreadsRunning = FALSE;
53
54 /* FUNCTIONS *****************************************************************/
55
56 NTSTATUS STDCALL STATIC
57 KeyboardThreadMain(PVOID StartContext)
58 {
59 UNICODE_STRING KeyboardDeviceName;
60 OBJECT_ATTRIBUTES KeyboardObjectAttributes;
61 IO_STATUS_BLOCK Iosb;
62 NTSTATUS Status;
63
64 RtlInitUnicodeStringFromLiteral(&KeyboardDeviceName, L"\\??\\Keyboard");
65 InitializeObjectAttributes(&KeyboardObjectAttributes,
66 &KeyboardDeviceName,
67 0,
68 NULL,
69 NULL);
70 Status = NtOpenFile(&KeyboardDeviceHandle,
71 FILE_ALL_ACCESS,
72 &KeyboardObjectAttributes,
73 &Iosb,
74 0,
75 FILE_SYNCHRONOUS_IO_ALERT);
76 if (!NT_SUCCESS(Status))
77 {
78 DbgPrint("W32K: Failed to open keyboard.\n");
79 return(Status);
80 }
81
82 for (;;)
83 {
84 /*
85 * Wait to start input.
86 */
87 Status = KeWaitForSingleObject(&InputThreadsStart,
88 0,
89 UserMode,
90 TRUE,
91 NULL);
92 /*
93 * Receive and process keyboard input.
94 */
95 while (InputThreadsRunning)
96 {
97 KEY_EVENT_RECORD KeyEvent;
98 LPARAM lParam;
99
100 Status = NtReadFile (KeyboardDeviceHandle,
101 NULL,
102 NULL,
103 NULL,
104 &Iosb,
105 &KeyEvent,
106 sizeof(KEY_EVENT_RECORD),
107 NULL,
108 NULL);
109 if (Status == STATUS_ALERTED && !InputThreadsRunning)
110 {
111 break;
112 }
113 if (!NT_SUCCESS(Status))
114 {
115 DbgPrint("W32K: Failed to read from keyboard.\n");
116 return(Status);
117 }
118
119 /*
120 * Post a keyboard message.
121 */
122 if (KeyEvent.bKeyDown)
123 {
124 /* FIXME: Bit 24 indicates if this is an extended key. */
125 lParam = KeyEvent.wRepeatCount |
126 ((KeyEvent.wVirtualScanCode << 16) & 0x00FF0000) | 0x40000000;
127 MsqPostKeyboardMessage(WM_KEYDOWN, KeyEvent.wVirtualKeyCode,
128 lParam);
129 }
130 else
131 {
132 /* FIXME: Bit 24 indicates if this is an extended key. */
133 lParam = KeyEvent.wRepeatCount |
134 ((KeyEvent.wVirtualScanCode << 16) & 0x00FF0000) | 0xC0000000;
135 MsqPostKeyboardMessage(WM_KEYUP, KeyEvent.wVirtualKeyCode,
136 lParam);
137 }
138 }
139 }
140 }
141
142 NTSTATUS STDCALL
143 NtUserAcquireOrReleaseInputOwnership(BOOLEAN Release)
144 {
145 if (Release && InputThreadsRunning)
146 {
147 KeClearEvent(&InputThreadsStart);
148 InputThreadsRunning = FALSE;
149 NtAlertThread(KeyboardThreadHandle);
150 }
151 else if (!Release && !InputThreadsRunning)
152 {
153 InputThreadsRunning = TRUE;
154 KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
155 }
156 return(STATUS_SUCCESS);
157 }
158
159 NTSTATUS FASTCALL
160 InitInputImpl(VOID)
161 {
162 NTSTATUS Status;
163 UNICODE_STRING MouseDeviceName;
164 OBJECT_ATTRIBUTES MouseObjectAttributes;
165 IO_STATUS_BLOCK Iosb;
166 PIRP Irp;
167 PFILE_OBJECT FileObject;
168 GDI_INFORMATION GdiInfo;
169 KEVENT IoEvent;
170 PIO_STACK_LOCATION StackPtr;
171
172 KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
173
174 Status = PsCreateSystemThread(&KeyboardThreadHandle,
175 THREAD_ALL_ACCESS,
176 NULL,
177 NULL,
178 &KeyboardThreadId,
179 KeyboardThreadMain,
180 NULL);
181 if (!NT_SUCCESS(Status))
182 {
183 DbgPrint("W32K: Failed to create keyboard thread.\n");
184 }
185
186 /*
187 * Connect to the mouse class driver.
188 */
189 RtlInitUnicodeStringFromLiteral(&MouseDeviceName, L"\\??\\MouseClass");
190 InitializeObjectAttributes(&MouseObjectAttributes,
191 &MouseDeviceName,
192 0,
193 NULL,
194 NULL);
195 Status = NtOpenFile(&MouseDeviceHandle,
196 FILE_ALL_ACCESS,
197 &MouseObjectAttributes,
198 &Iosb,
199 0,
200 0);
201 if (!NT_SUCCESS(Status))
202 {
203 DbgPrint("W32K: Failed to open mouse.\n");
204 return(Status);
205 }
206 Status = ObReferenceObjectByHandle(MouseDeviceHandle,
207 FILE_READ_DATA | FILE_WRITE_DATA,
208 IoFileObjectType,
209 KernelMode,
210 (PVOID *) &FileObject,
211 NULL);
212
213 if (!NT_SUCCESS(Status))
214 {
215 DbgPrint("W32K: Failed to reference mouse file object.\n");
216 return(Status);
217 }
218 KeInitializeEvent(&IoEvent, FALSE, NotificationEvent);
219 GdiInfo.CallBack = MouseGDICallBack;
220 Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
221 FileObject->DeviceObject,
222 &GdiInfo,
223 sizeof(GdiInfo),
224 NULL,
225 0,
226 TRUE,
227 &FileObject->Event,
228 &Iosb);
229 StackPtr = IoGetNextIrpStackLocation(Irp);
230 StackPtr->FileObject = FileObject;
231 StackPtr->DeviceObject = FileObject->DeviceObject;
232 StackPtr->Parameters.DeviceIoControl.InputBufferLength = sizeof(GdiInfo);
233 StackPtr->Parameters.DeviceIoControl.OutputBufferLength = 0;
234
235 Status = IoCallDriver(FileObject->DeviceObject, Irp);
236 if (Status == STATUS_PENDING)
237 {
238 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE,
239 NULL);
240 Status = Iosb.Status;
241 }
242 if (!NT_SUCCESS(Status))
243 {
244 DbgPrint("W32K: Failed to connect to mouse driver.\n");
245 return(Status);
246 }
247
248 return(STATUS_SUCCESS);
249 }
250
251 NTSTATUS FASTCALL
252 CleanupInputImp(VOID)
253 {
254 return(STATUS_SUCCESS);
255 }
256
257 /* EOF */