diff --git a/reactos/subsys/win32k/include/hotkey.h b/reactos/subsys/win32k/include/hotkey.h new file mode 100644 index 00000000000..baaa493cb65 --- /dev/null +++ b/reactos/subsys/win32k/include/hotkey.h @@ -0,0 +1,28 @@ +#ifndef __WIN32K_HOTKEY_H +#define __WIN32K_HOTKEY_H + +#include +#include + +NTSTATUS FASTCALL +InitHotKeyImpl (VOID); + +NTSTATUS FASTCALL +CleanupHotKeyImpl (VOID); + +BOOL +GetHotKey (UINT fsModifiers, + UINT vk, + struct _ETHREAD **Thread, + HWND *hWnd, + int *id); + +VOID +UnregisterWindowHotKeys(HWND hWnd); + +VOID +UnregisterThreadHotKeys(struct _ETHREAD *Thread); + +#endif /* __WIN32K_HOTKEY_H */ + +/* EOF */ diff --git a/reactos/subsys/win32k/include/msgqueue.h b/reactos/subsys/win32k/include/msgqueue.h index b9a94593b17..0e27f397bb5 100644 --- a/reactos/subsys/win32k/include/msgqueue.h +++ b/reactos/subsys/win32k/include/msgqueue.h @@ -127,6 +127,8 @@ IntSendMessage(HWND hWnd, BOOL KernelMessage); VOID STDCALL MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); +VOID STDCALL +MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam); VOID FASTCALL MsqInsertSystemMessage(MSG* Msg, BOOL RemMouseMoveMsg); diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 1bc189ae18c..1136805f1d4 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dllmain.c,v 1.46 2003/10/16 22:07:37 weiden Exp $ +/* $Id: dllmain.c,v 1.47 2003/11/03 18:51:40 ekohl Exp $ * * Entry Point for win32k.sys */ @@ -39,6 +39,7 @@ #include #include #include +#include #define NDEBUG #include @@ -155,6 +156,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread, #endif RemoveTimersThread(Thread->Cid.UniqueThread); + UnregisterThreadHotKeys(Thread); DestroyThreadWindows(Thread); } @@ -166,8 +168,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread, * This definition doesn't work */ // WINBOOL STDCALL DllMain(VOID) -NTSTATUS -STDCALL +NTSTATUS STDCALL DllMain ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) @@ -224,13 +225,20 @@ DllMain ( DbgPrint("Failed to initialize window implementation!\n"); return STATUS_UNSUCCESSFUL; } - + Status = InitMenuImpl(); if (!NT_SUCCESS(Status)) { DbgPrint("Failed to initialize menu implementation!\n"); return STATUS_UNSUCCESSFUL; - } + } + + Status = InitHotKeyImpl(); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Failed to initialize hot key implementation!\n"); + return STATUS_UNSUCCESSFUL; + } Status = InitInputImpl(); if (!NT_SUCCESS(Status)) @@ -257,8 +265,7 @@ DllMain ( } -BOOLEAN -STDCALL +BOOLEAN STDCALL Win32kInitialize (VOID) { DPRINT("in Win32kInitialize\n"); @@ -268,7 +275,8 @@ Win32kInitialize (VOID) InitGdiObjectHandleTable (); // Initialize FreeType library - if(!InitFontSupport()) return FALSE; + if (!InitFontSupport()) + return FALSE; // Create stock objects, ie. precreated objects commonly used by win32 applications CreateStockObjects(); diff --git a/reactos/subsys/win32k/ntuser/hotkey.c b/reactos/subsys/win32k/ntuser/hotkey.c index 79216e8e00e..4d90e405d44 100644 --- a/reactos/subsys/win32k/ntuser/hotkey.c +++ b/reactos/subsys/win32k/ntuser/hotkey.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: hotkey.c,v 1.1 2003/11/02 16:33:33 ekohl Exp $ +/* $Id: hotkey.c,v 1.2 2003/11/03 18:52:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -37,11 +37,165 @@ #define NDEBUG #include + /* GLOBALS *******************************************************************/ +typedef struct _HOT_KEY_ITEM +{ + LIST_ENTRY ListEntry; + struct _ETHREAD *Thread; + HWND hWnd; + int id; + UINT fsModifiers; + UINT vk; +} HOT_KEY_ITEM, *PHOT_KEY_ITEM; + + +static LIST_ENTRY HotKeyListHead; +static FAST_MUTEX HotKeyListLock; + /* FUNCTIONS *****************************************************************/ +NTSTATUS FASTCALL +InitHotKeyImpl(VOID) +{ + InitializeListHead(&HotKeyListHead); + ExInitializeFastMutex(&HotKeyListLock); + + return STATUS_SUCCESS; +} + + +NTSTATUS FASTCALL +CleanupHotKeyImpl(VOID) +{ + + return STATUS_SUCCESS; +} + + +BOOL +GetHotKey (UINT fsModifiers, + UINT vk, + struct _ETHREAD **Thread, + HWND *hWnd, + int *id) +{ + PLIST_ENTRY Entry; + PHOT_KEY_ITEM HotKeyItem; + + ExAcquireFastMutex (&HotKeyListLock); + + Entry = HotKeyListHead.Flink; + while (Entry != &HotKeyListHead) + { + HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD(Entry, + HOT_KEY_ITEM, + ListEntry); + if (HotKeyItem->fsModifiers == fsModifiers && + HotKeyItem->vk == vk) + { + if (Thread != NULL) + *Thread = HotKeyItem->Thread; + + if (hWnd != NULL) + *hWnd = HotKeyItem->hWnd; + + if (id != NULL) + *id = HotKeyItem->id; + + ExReleaseFastMutex (&HotKeyListLock); + + return TRUE; + } + + Entry = Entry->Flink; + } + + ExReleaseFastMutex (&HotKeyListLock); + + return FALSE; +} + + +VOID +UnregisterWindowHotKeys(HWND hWnd) +{ + PLIST_ENTRY Entry; + PHOT_KEY_ITEM HotKeyItem; + + ExAcquireFastMutex (&HotKeyListLock); + + Entry = HotKeyListHead.Flink; + while (Entry != &HotKeyListHead) + { + HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, + HOT_KEY_ITEM, + ListEntry); + Entry = Entry->Flink; + if (HotKeyItem->hWnd == hWnd) + { + RemoveEntryList (&HotKeyItem->ListEntry); + ExFreePool (HotKeyItem); + } + } + + ExReleaseFastMutex (&HotKeyListLock); +} + + +VOID +UnregisterThreadHotKeys(struct _ETHREAD *Thread) +{ + PLIST_ENTRY Entry; + PHOT_KEY_ITEM HotKeyItem; + + ExAcquireFastMutex (&HotKeyListLock); + + Entry = HotKeyListHead.Flink; + while (Entry != &HotKeyListHead) + { + HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, + HOT_KEY_ITEM, + ListEntry); + Entry = Entry->Flink; + if (HotKeyItem->Thread == Thread) + { + RemoveEntryList (&HotKeyItem->ListEntry); + ExFreePool (HotKeyItem); + } + } + + ExReleaseFastMutex (&HotKeyListLock); +} + + +static BOOL +IsHotKey (UINT fsModifiers, + UINT vk) +{ + PLIST_ENTRY Entry; + PHOT_KEY_ITEM HotKeyItem; + + Entry = HotKeyListHead.Flink; + while (Entry != &HotKeyListHead) + { + HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, + HOT_KEY_ITEM, + ListEntry); + if (HotKeyItem->fsModifiers == fsModifiers && + HotKeyItem->vk == vk) + { + return TRUE; + } + + Entry = Entry->Flink; + } + + return FALSE; +} + BOOL STDCALL NtUserRegisterHotKey(HWND hWnd, @@ -49,9 +203,34 @@ NtUserRegisterHotKey(HWND hWnd, UINT fsModifiers, UINT vk) { - UNIMPLEMENTED + PHOT_KEY_ITEM HotKeyItem; - return FALSE; + ExAcquireFastMutex (&HotKeyListLock); + + /* Check for existing hotkey */ + if (IsHotKey (fsModifiers, vk)) + return FALSE; + + HotKeyItem = ExAllocatePool (PagedPool, + sizeof(HOT_KEY_ITEM)); + if (HotKeyItem == NULL) + { + ExReleaseFastMutex (&HotKeyListLock); + return FALSE; + } + + HotKeyItem->Thread = PsGetCurrentThread(); + HotKeyItem->hWnd = hWnd; + HotKeyItem->id = id; + HotKeyItem->fsModifiers = fsModifiers; + HotKeyItem->vk = vk; + + InsertHeadList (&HotKeyListHead, + &HotKeyItem->ListEntry); + + ExReleaseFastMutex (&HotKeyListLock); + + return TRUE; } @@ -59,7 +238,30 @@ BOOL STDCALL NtUserUnregisterHotKey(HWND hWnd, int id) { - UNIMPLEMENTED + PLIST_ENTRY Entry; + PHOT_KEY_ITEM HotKeyItem; + + ExAcquireFastMutex (&HotKeyListLock); + + Entry = HotKeyListHead.Flink; + while (Entry != &HotKeyListHead) + { + HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry, + HOT_KEY_ITEM, + ListEntry); + if (HotKeyItem->hWnd == hWnd && + HotKeyItem->id == id) + { + RemoveEntryList (&HotKeyItem->ListEntry); + ExFreePool (HotKeyItem); + ExReleaseFastMutex (&HotKeyListLock); + return TRUE; + } + + Entry = Entry->Flink; + } + + ExReleaseFastMutex (&HotKeyListLock); return FALSE; } diff --git a/reactos/subsys/win32k/ntuser/input.c b/reactos/subsys/win32k/ntuser/input.c index ef161309e43..de25bfa8aa5 100644 --- a/reactos/subsys/win32k/ntuser/input.c +++ b/reactos/subsys/win32k/ntuser/input.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: input.c,v 1.16 2003/11/02 16:33:33 ekohl Exp $ +/* $Id: input.c,v 1.17 2003/11/03 18:52:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -39,6 +39,7 @@ #include #include #include +#include #define NDEBUG #include @@ -101,7 +102,10 @@ KeyboardThreadMain(PVOID StartContext) { KEY_EVENT_RECORD KeyEvent; LPARAM lParam = 0; - BOOLEAN SysKey; + UINT fsModifiers; + struct _ETHREAD *Thread; + HWND hWnd; + int id; Status = NtReadFile (KeyboardDeviceHandle, NULL, @@ -126,9 +130,37 @@ KeyboardThreadMain(PVOID StartContext) return; //(Status); } - SysKey = KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED); DPRINT( "Key: %s\n", KeyEvent.bKeyDown ? "down" : "up" ); + fsModifiers = 0; + if (KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + fsModifiers |= MOD_ALT; + + if (KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + fsModifiers |= MOD_CONTROL; + + if (KeyEvent.dwControlKeyState & SHIFT_PRESSED) + fsModifiers |= MOD_SHIFT; + + /* FIXME: Support MOD_WIN */ + + if (GetHotKey(fsModifiers, + KeyEvent.wVirtualKeyCode, + &Thread, + &hWnd, + &id)) + { + if (KeyEvent.bKeyDown) + { + DPRINT("Hot key pressed (hWnd %lx, id %d)\n", hWnd, id); + MsqPostHotKeyMessage (Thread, + hWnd, + (WPARAM)id, + MAKELPARAM((WORD)fsModifiers, (WORD)KeyEvent.wVirtualKeyCode)); + } + } + else + /* * Post a keyboard message. */ @@ -143,12 +175,13 @@ KeyboardThreadMain(PVOID StartContext) lParam |= (1 << 24); } - if (SysKey) + if (fsModifiers & MOD_ALT) { - lParam |= (1 << 29); /* Context mode. 1 if ALT if pressed while the key is pressed */ + /* Context mode. 1 if ALT if pressed while the key is pressed */ + lParam |= (1 << 29); } - MsqPostKeyboardMessage(SysKey ? WM_SYSKEYDOWN : WM_KEYDOWN, + MsqPostKeyboardMessage((fsModifiers & MOD_ALT) ? WM_SYSKEYDOWN : WM_KEYDOWN, KeyEvent.wVirtualKeyCode, lParam); } @@ -163,12 +196,13 @@ KeyboardThreadMain(PVOID StartContext) lParam |= (1 << 24); } - if (SysKey) + if (fsModifiers & MOD_ALT) { - lParam |= (1 << 29); /* Context mode. 1 if ALT if pressed while the key is pressed */ + /* Context mode. 1 if ALT if pressed while the key is pressed */ + lParam |= (1 << 29); } - MsqPostKeyboardMessage(SysKey ? WM_SYSKEYUP : WM_KEYUP, + MsqPostKeyboardMessage((fsModifiers & MOD_ALT) ? WM_SYSKEYUP : WM_KEYUP, KeyEvent.wVirtualKeyCode, lParam); } @@ -177,6 +211,7 @@ KeyboardThreadMain(PVOID StartContext) } } + NTSTATUS STDCALL NtUserAcquireOrReleaseInputOwnership(BOOLEAN Release) { diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index 2d393aea3ee..0bc98c7b3ea 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: msgqueue.c,v 1.29 2003/11/02 14:08:34 navaraf Exp $ +/* $Id: msgqueue.c,v 1.30 2003/11/03 18:52:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -523,6 +523,66 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) } } +VOID STDCALL +MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + PWINDOW_OBJECT Window; + PUSER_MESSAGE Message; + PW32THREAD Win32Thread; + PW32PROCESS Win32Process; + MSG Mesg; + NTSTATUS Status; + + Status = ObReferenceObjectByPointer (Thread, + THREAD_ALL_ACCESS, + PsThreadType, + KernelMode); + if (!NT_SUCCESS(Status)) + return; + + Win32Thread = ((PETHREAD)Thread)->Win32Thread; + if (Win32Thread == NULL || Win32Thread->MessageQueue == NULL) + { + ObDereferenceObject ((PETHREAD)Thread); + return; + } + + Win32Process = ((PETHREAD)Thread)->ThreadsProcess->Win32Process; + if (Win32Process == NULL || Win32Process->WindowStation == NULL) + { + ObDereferenceObject ((PETHREAD)Thread); + return; + } + + Status = ObmReferenceObjectByHandle(Win32Process->WindowStation->HandleTable, + hWnd, otWindow, (PVOID*)&Window); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject ((PETHREAD)Thread); + return; + } + + Mesg.hwnd = hWnd; + Mesg.message = WM_HOTKEY; + Mesg.wParam = wParam; + Mesg.lParam = lParam; +// Mesg.pt.x = PsGetWin32Process()->WindowStation->SystemCursor.x; +// Mesg.pt.y = PsGetWin32Process()->WindowStation->SystemCursor.y; +// KeQueryTickCount(&LargeTickCount); +// Mesg.time = LargeTickCount.u.LowPart; + Message = MsqCreateMessage(&Mesg); + MsqPostMessage(Window->MessageQueue, Message); + ObmDereferenceObject(Window); + ObDereferenceObject (Thread); + +// ExAcquireFastMutex(&pThread->MessageQueue->Lock); +// InsertHeadList(&pThread->MessageQueue->PostedMessagesListHead, +// &Message->ListEntry); +// KeSetEvent(&pThread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); +// ExReleaseFastMutex(&pThread->MessageQueue->Lock); + +} + VOID FASTCALL MsqInitializeMessage(PUSER_MESSAGE Message, LPMSG Msg) diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 86f2393e799..e95c831380c 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.128 2003/11/02 14:08:34 navaraf Exp $ +/* $Id: window.c,v 1.129 2003/11/03 18:52:21 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -47,6 +47,7 @@ #include #include #include +#include #define NDEBUG #include @@ -362,6 +363,9 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window, if (Window->Self == hwndShellListView) hwndShellListView = 0; + /* Unregister hot keys */ + UnregisterWindowHotKeys (Window->Self); + /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */ #if 0 /* FIXME */