2 * ReactOS W32 Subsystem
3 * Copyright (C) 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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * PURPOSE: HotKey support
23 * FILE: subsys/win32k/ntuser/hotkey.c
24 * PROGRAMER: Eric Kohl
26 * 02-11-2003 EK Created
33 FIXME: Hotkey notifications are triggered by keyboard input (physical or programatically)
34 and since only desktops on WinSta0 can recieve input in seems very wrong to allow
35 windows/threads on destops not belonging to WinSta0 to set hotkeys (recieve notifications).
41 /* INCLUDES ******************************************************************/
48 /* GLOBALS *******************************************************************/
50 LIST_ENTRY gHotkeyList
;
52 /* FUNCTIONS *****************************************************************/
59 InitializeListHead(&gHotkeyList
);
61 return STATUS_SUCCESS
;
69 return STATUS_SUCCESS
;
74 GetHotKey (UINT fsModifiers
,
76 struct _ETHREAD
**Thread
,
80 PHOT_KEY_ITEM HotKeyItem
;
82 LIST_FOR_EACH(HotKeyItem
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
84 if (HotKeyItem
->fsModifiers
== fsModifiers
&&
88 *Thread
= HotKeyItem
->Thread
;
91 *hWnd
= HotKeyItem
->hWnd
;
104 UnregisterWindowHotKeys(PWND Window
)
106 PHOT_KEY_ITEM HotKeyItem
, tmp
;
108 LIST_FOR_EACH_SAFE(HotKeyItem
, tmp
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
110 if (HotKeyItem
->hWnd
== Window
->head
.h
)
112 RemoveEntryList (&HotKeyItem
->ListEntry
);
113 ExFreePool (HotKeyItem
);
120 UnregisterThreadHotKeys(struct _ETHREAD
*Thread
)
122 PHOT_KEY_ITEM HotKeyItem
, tmp
;
124 LIST_FOR_EACH_SAFE(HotKeyItem
, tmp
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
126 if (HotKeyItem
->Thread
== Thread
)
128 RemoveEntryList (&HotKeyItem
->ListEntry
);
129 ExFreePool (HotKeyItem
);
137 IsHotKey (UINT fsModifiers
, UINT vk
)
139 PHOT_KEY_ITEM HotKeyItem
;
141 LIST_FOR_EACH(HotKeyItem
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
143 if (HotKeyItem
->fsModifiers
== fsModifiers
&& HotKeyItem
->vk
== vk
)
153 // Get/SetHotKey message support.
156 DefWndGetHotKey( HWND hwnd
)
158 PHOT_KEY_ITEM HotKeyItem
;
160 DPRINT1("DefWndGetHotKey\n");
162 if (IsListEmpty(&gHotkeyList
)) return 0;
164 LIST_FOR_EACH(HotKeyItem
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
166 if ( HotKeyItem
->hWnd
== hwnd
&&
167 HotKeyItem
->id
== IDHOT_REACTOS
)
169 return MAKELONG(HotKeyItem
->vk
, HotKeyItem
->fsModifiers
);
176 DefWndSetHotKey( PWND pWnd
, WPARAM wParam
)
178 UINT fsModifiers
, vk
;
179 PHOT_KEY_ITEM HotKeyItem
;
181 BOOL HaveSameWnd
= FALSE
;
184 DPRINT1("DefWndSetHotKey wParam 0x%x\n", wParam
);
186 // A hot key cannot be associated with a child window.
187 if (pWnd
->style
& WS_CHILD
) return 0;
189 // VK_ESCAPE, VK_SPACE, and VK_TAB are invalid hot keys.
190 if ( LOWORD(wParam
) == VK_ESCAPE
||
191 LOWORD(wParam
) == VK_SPACE
||
192 LOWORD(wParam
) == VK_TAB
) return -1;
195 fsModifiers
= HIWORD(wParam
);
196 hWnd
= UserHMGetHandle(pWnd
);
200 LIST_FOR_EACH(HotKeyItem
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
202 if ( HotKeyItem
->fsModifiers
== fsModifiers
&&
203 HotKeyItem
->vk
== vk
&&
204 HotKeyItem
->id
== IDHOT_REACTOS
)
206 if (HotKeyItem
->hWnd
!= hWnd
)
207 Ret
= 2; // Another window already has the same hot key.
213 LIST_FOR_EACH(HotKeyItem
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
215 if ( HotKeyItem
->hWnd
== hWnd
&&
216 HotKeyItem
->id
== IDHOT_REACTOS
)
226 { // Setting wParam to NULL removes the hot key associated with a window.
227 UnregisterWindowHotKeys(pWnd
);
230 { /* A window can only have one hot key. If the window already has a hot key
231 associated with it, the new hot key replaces the old one. */
232 HotKeyItem
->fsModifiers
= fsModifiers
;
239 return 1; // Do nothing, exit.
241 HotKeyItem
= ExAllocatePoolWithTag (PagedPool
, sizeof(HOT_KEY_ITEM
), USERTAG_HOTKEY
);
242 if (HotKeyItem
== NULL
)
247 HotKeyItem
->Thread
= pWnd
->head
.pti
->pEThread
;
248 HotKeyItem
->hWnd
= hWnd
;
249 HotKeyItem
->id
= IDHOT_REACTOS
; // Don't care, these hot keys are unrelated to the hot keys set by RegisterHotKey.
250 HotKeyItem
->fsModifiers
= fsModifiers
;
253 InsertHeadList (&gHotkeyList
, &HotKeyItem
->ListEntry
);
258 /* SYSCALLS *****************************************************************/
262 NtUserRegisterHotKey(HWND hWnd
,
267 PHOT_KEY_ITEM HotKeyItem
;
269 PETHREAD HotKeyThread
;
270 DECLARE_RETURN(BOOL
);
272 DPRINT("Enter NtUserRegisterHotKey\n");
273 UserEnterExclusive();
277 HotKeyThread
= PsGetCurrentThread();
281 if(!(Window
= UserGetWindowObject(hWnd
)))
285 HotKeyThread
= Window
->head
.pti
->pEThread
;
288 /* Check for existing hotkey */
289 if (IsHotKey (fsModifiers
, vk
))
294 HotKeyItem
= ExAllocatePoolWithTag (PagedPool
, sizeof(HOT_KEY_ITEM
), USERTAG_HOTKEY
);
295 if (HotKeyItem
== NULL
)
300 HotKeyItem
->Thread
= HotKeyThread
;
301 HotKeyItem
->hWnd
= hWnd
;
303 HotKeyItem
->fsModifiers
= fsModifiers
;
306 InsertHeadList (&gHotkeyList
, &HotKeyItem
->ListEntry
);
311 DPRINT("Leave NtUserRegisterHotKey, ret=%i\n",_ret_
);
318 NtUserUnregisterHotKey(HWND hWnd
, int id
)
320 PHOT_KEY_ITEM HotKeyItem
;
322 DECLARE_RETURN(BOOL
);
324 DPRINT("Enter NtUserUnregisterHotKey\n");
325 UserEnterExclusive();
327 if(!(Window
= UserGetWindowObject(hWnd
)))
332 LIST_FOR_EACH(HotKeyItem
, &gHotkeyList
, HOT_KEY_ITEM
, ListEntry
)
334 if (HotKeyItem
->hWnd
== hWnd
&& HotKeyItem
->id
== id
)
336 RemoveEntryList (&HotKeyItem
->ListEntry
);
337 ExFreePoolWithTag(HotKeyItem
, USERTAG_HOTKEY
);
346 DPRINT("Leave NtUserUnregisterHotKey, ret=%i\n",_ret_
);