Merge from amd64-branch:
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / hotkey.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 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 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.
18 */
19 /*
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
25 * REVISION HISTORY:
26 * 02-11-2003 EK Created
27 */
28
29
30
31 /*
32
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).
36
37 -Gunnar
38 */
39
40
41 /* INCLUDES ******************************************************************/
42
43 #include <w32k.h>
44
45 #define NDEBUG
46 #include <debug.h>
47
48 /* GLOBALS *******************************************************************/
49
50 LIST_ENTRY gHotkeyList;
51
52 /* FUNCTIONS *****************************************************************/
53
54 NTSTATUS FASTCALL
55 InitHotkeyImpl(VOID)
56 {
57 InitializeListHead(&gHotkeyList);
58
59 return STATUS_SUCCESS;
60 }
61
62
63 #if 0 //not used
64 NTSTATUS FASTCALL
65 CleanupHotKeys(VOID)
66 {
67
68 return STATUS_SUCCESS;
69 }
70 #endif
71
72
73 BOOL FASTCALL
74 GetHotKey (UINT fsModifiers,
75 UINT vk,
76 struct _ETHREAD **Thread,
77 HWND *hWnd,
78 int *id)
79 {
80 PHOT_KEY_ITEM HotKeyItem;
81
82 LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
83 {
84 if (HotKeyItem->fsModifiers == fsModifiers &&
85 HotKeyItem->vk == vk)
86 {
87 if (Thread != NULL)
88 *Thread = HotKeyItem->Thread;
89
90 if (hWnd != NULL)
91 *hWnd = HotKeyItem->hWnd;
92
93 if (id != NULL)
94 *id = HotKeyItem->id;
95
96 return TRUE;
97 }
98 }
99
100 return FALSE;
101 }
102
103
104 VOID FASTCALL
105 UnregisterWindowHotKeys(PWINDOW_OBJECT Window)
106 {
107 PHOT_KEY_ITEM HotKeyItem, tmp;
108
109 LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
110 {
111 if (HotKeyItem->hWnd == Window->hSelf)
112 {
113 RemoveEntryList (&HotKeyItem->ListEntry);
114 ExFreePool (HotKeyItem);
115 }
116 }
117
118 }
119
120
121 VOID FASTCALL
122 UnregisterThreadHotKeys(struct _ETHREAD *Thread)
123 {
124 PHOT_KEY_ITEM HotKeyItem, tmp;
125
126 LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
127 {
128 if (HotKeyItem->Thread == Thread)
129 {
130 RemoveEntryList (&HotKeyItem->ListEntry);
131 ExFreePool (HotKeyItem);
132 }
133 }
134
135 }
136
137
138 static
139 BOOL FASTCALL
140 IsHotKey (UINT fsModifiers, UINT vk)
141 {
142 PHOT_KEY_ITEM HotKeyItem;
143
144 LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
145 {
146 if (HotKeyItem->fsModifiers == fsModifiers && HotKeyItem->vk == vk)
147 {
148 return TRUE;
149 }
150 }
151
152 return FALSE;
153 }
154
155
156
157 /* SYSCALLS *****************************************************************/
158
159
160 BOOL APIENTRY
161 NtUserRegisterHotKey(HWND hWnd,
162 int id,
163 UINT fsModifiers,
164 UINT vk)
165 {
166 PHOT_KEY_ITEM HotKeyItem;
167 PWINDOW_OBJECT Window;
168 PETHREAD HotKeyThread;
169 DECLARE_RETURN(BOOL);
170
171 DPRINT("Enter NtUserRegisterHotKey\n");
172 UserEnterExclusive();
173
174 if (hWnd == NULL)
175 {
176 HotKeyThread = PsGetCurrentThread();
177 }
178 else
179 {
180 if(!(Window = UserGetWindowObject(hWnd)))
181 {
182 RETURN( FALSE);
183 }
184 HotKeyThread = Window->pti->pEThread;
185 }
186
187 /* Check for existing hotkey */
188 if (IsHotKey (fsModifiers, vk))
189 {
190 RETURN( FALSE);
191 }
192
193 HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM), TAG_HOTKEY);
194 if (HotKeyItem == NULL)
195 {
196 RETURN( FALSE);
197 }
198
199 HotKeyItem->Thread = HotKeyThread;
200 HotKeyItem->hWnd = hWnd;
201 HotKeyItem->id = id;
202 HotKeyItem->fsModifiers = fsModifiers;
203 HotKeyItem->vk = vk;
204
205 InsertHeadList (&gHotkeyList, &HotKeyItem->ListEntry);
206
207 RETURN( TRUE);
208
209 CLEANUP:
210 DPRINT("Leave NtUserRegisterHotKey, ret=%i\n",_ret_);
211 UserLeave();
212 END_CLEANUP;
213 }
214
215
216 BOOL APIENTRY
217 NtUserUnregisterHotKey(HWND hWnd, int id)
218 {
219 PHOT_KEY_ITEM HotKeyItem;
220 PWINDOW_OBJECT Window;
221 DECLARE_RETURN(BOOL);
222
223 DPRINT("Enter NtUserUnregisterHotKey\n");
224 UserEnterExclusive();
225
226 if(!(Window = UserGetWindowObject(hWnd)))
227 {
228 RETURN( FALSE);
229 }
230
231 LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
232 {
233 if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id)
234 {
235 RemoveEntryList (&HotKeyItem->ListEntry);
236 ExFreePool (HotKeyItem);
237
238 RETURN( TRUE);
239 }
240 }
241
242 RETURN( FALSE);
243
244 CLEANUP:
245 DPRINT("Leave NtUserUnregisterHotKey, ret=%i\n",_ret_);
246 UserLeave();
247 END_CLEANUP;
248 }
249
250 /* EOF */