2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
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.
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.
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.
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)
27 * 06-06-2001 CSH Created
30 /* INCLUDES ******************************************************************/
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>
45 /* GLOBALS *******************************************************************/
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;
54 /* FUNCTIONS *****************************************************************/
56 VOID STDCALL_FUNC STATIC
57 KeyboardThreadMain(PVOID StartContext)
59 UNICODE_STRING KeyboardDeviceName;
60 OBJECT_ATTRIBUTES KeyboardObjectAttributes;
64 RtlInitUnicodeStringFromLiteral(&KeyboardDeviceName, L"\\??\\Keyboard");
65 InitializeObjectAttributes(&KeyboardObjectAttributes,
70 Status = NtOpenFile(&KeyboardDeviceHandle,
72 &KeyboardObjectAttributes,
75 FILE_SYNCHRONOUS_IO_ALERT);
76 if (!NT_SUCCESS(Status))
78 DbgPrint("Win32K: Failed to open keyboard.\n");
85 * Wait to start input.
87 Status = KeWaitForSingleObject(&InputThreadsStart,
94 * Receive and process keyboard input.
96 while (InputThreadsRunning)
98 KEY_EVENT_RECORD KeyEvent;
102 Status = NtReadFile (KeyboardDeviceHandle,
108 sizeof(KEY_EVENT_RECORD),
111 DbgPrint( "KeyRaw: %s %04x\n",
112 KeyEvent.bKeyDown ? "down" : "up",
113 KeyEvent.wVirtualScanCode );
115 if (Status == STATUS_ALERTED && !InputThreadsRunning)
119 if (!NT_SUCCESS(Status))
121 DbgPrint("Win32K: Failed to read from keyboard.\n");
125 SysKey = KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED);
126 DbgPrint( "Key: %s\n", KeyEvent.bKeyDown ? "down" : "up" );
129 * Post a keyboard message.
131 if (KeyEvent.bKeyDown)
133 lParam = KeyEvent.wRepeatCount |
134 ((KeyEvent.wVirtualScanCode << 16) & 0x00FF0000) | 0x40000000;
136 /* Bit 24 indicates if this is an extended key */
137 if (KeyEvent.dwControlKeyState & ENHANCED_KEY)
144 lParam |= (1 << 29); /* Context mode. 1 if ALT if pressed while the key is pressed */
147 MsqPostKeyboardMessage(SysKey ? WM_SYSKEYDOWN : WM_KEYDOWN, KeyEvent.wVirtualKeyCode,
152 lParam = KeyEvent.wRepeatCount |
153 ((KeyEvent.wVirtualScanCode << 16) & 0x00FF0000) | 0xC0000000;
155 /* Bit 24 indicates if this is an extended key */
156 if (KeyEvent.dwControlKeyState & ENHANCED_KEY)
163 lParam |= (1 << 29); /* Context mode. 1 if ALT if pressed while the key is pressed */
165 MsqPostKeyboardMessage(SysKey ? WM_SYSKEYUP : WM_KEYUP, KeyEvent.wVirtualKeyCode,
173 NtUserAcquireOrReleaseInputOwnership(BOOLEAN Release)
175 if (Release && InputThreadsRunning)
177 KeClearEvent(&InputThreadsStart);
178 InputThreadsRunning = FALSE;
179 NtAlertThread(KeyboardThreadHandle);
181 else if (!Release && !InputThreadsRunning)
183 InputThreadsRunning = TRUE;
184 KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
186 return(STATUS_SUCCESS);
193 UNICODE_STRING MouseDeviceName;
194 OBJECT_ATTRIBUTES MouseObjectAttributes;
195 IO_STATUS_BLOCK Iosb;
197 PFILE_OBJECT FileObject;
198 GDI_INFORMATION GdiInfo;
200 PIO_STACK_LOCATION StackPtr;
202 KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
204 Status = PsCreateSystemThread(&KeyboardThreadHandle,
211 if (!NT_SUCCESS(Status))
213 DbgPrint("Win32K: Failed to create keyboard thread.\n");
217 * Connect to the mouse class driver.
219 RtlInitUnicodeStringFromLiteral(&MouseDeviceName, L"\\??\\MouseClass");
220 InitializeObjectAttributes(&MouseObjectAttributes,
225 Status = NtOpenFile(&MouseDeviceHandle,
227 &MouseObjectAttributes,
231 if (!NT_SUCCESS(Status))
233 DbgPrint("Win32K: Failed to open mouse.\n");
236 Status = ObReferenceObjectByHandle(MouseDeviceHandle,
237 FILE_READ_DATA | FILE_WRITE_DATA,
240 (PVOID *) &FileObject,
243 if (!NT_SUCCESS(Status))
245 DbgPrint("Win32K: Failed to reference mouse file object.\n");
248 KeInitializeEvent(&IoEvent, FALSE, NotificationEvent);
249 GdiInfo.CallBack = MouseGDICallBack;
250 Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
251 FileObject->DeviceObject,
260 //trigger FileObject/Event dereferencing
261 Irp->Tail.Overlay.OriginalFileObject = FileObject;
263 StackPtr = IoGetNextIrpStackLocation(Irp);
264 StackPtr->FileObject = FileObject;
265 StackPtr->DeviceObject = FileObject->DeviceObject;
266 StackPtr->Parameters.DeviceIoControl.InputBufferLength = sizeof(GdiInfo);
267 StackPtr->Parameters.DeviceIoControl.OutputBufferLength = 0;
269 Status = IoCallDriver(FileObject->DeviceObject, Irp);
270 if (Status == STATUS_PENDING)
272 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE,
274 Status = Iosb.Status;
276 if (!NT_SUCCESS(Status))
278 DbgPrint("Win32K: Failed to connect to mouse driver.\n");
282 return(STATUS_SUCCESS);
286 CleanupInputImp(VOID)
288 return(STATUS_SUCCESS);