-remove hotkey lock
[reactos.git] / reactos / subsys / 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
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$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: HotKey support
24 * FILE: subsys/win32k/ntuser/hotkey.c
25 * PROGRAMER: Eric Kohl
26 * REVISION HISTORY:
27 * 02-11-2003 EK Created
28 */
29
30 /* INCLUDES ******************************************************************/
31
32 #include <w32k.h>
33
34 #define NDEBUG
35 #include <debug.h>
36
37 /* GLOBALS *******************************************************************/
38
39 /* FUNCTIONS *****************************************************************/
40
41 NTSTATUS FASTCALL
42 InitHotKeys(PWINSTATION_OBJECT WinStaObject)
43 {
44 InitializeListHead(&WinStaObject->HotKeyListHead);
45
46 return STATUS_SUCCESS;
47 }
48
49
50 NTSTATUS FASTCALL
51 CleanupHotKeys(PWINSTATION_OBJECT WinStaObject)
52 {
53
54 return STATUS_SUCCESS;
55 }
56
57
58 BOOL
59 GetHotKey (PWINSTATION_OBJECT WinStaObject,
60 UINT fsModifiers,
61 UINT vk,
62 struct _ETHREAD **Thread,
63 HWND *hWnd,
64 int *id)
65 {
66 PLIST_ENTRY Entry;
67 PHOT_KEY_ITEM HotKeyItem;
68
69 if(!WinStaObject)
70 {
71 return FALSE;
72 }
73
74 Entry = WinStaObject->HotKeyListHead.Flink;
75 while (Entry != &WinStaObject->HotKeyListHead)
76 {
77 HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD(Entry,
78 HOT_KEY_ITEM,
79 ListEntry);
80 if (HotKeyItem->fsModifiers == fsModifiers &&
81 HotKeyItem->vk == vk)
82 {
83 if (Thread != NULL)
84 *Thread = HotKeyItem->Thread;
85
86 if (hWnd != NULL)
87 *hWnd = HotKeyItem->hWnd;
88
89 if (id != NULL)
90 *id = HotKeyItem->id;
91
92
93 return TRUE;
94 }
95
96 Entry = Entry->Flink;
97 }
98
99 return FALSE;
100 }
101
102
103 VOID
104 UnregisterWindowHotKeys(PWINDOW_OBJECT Window)
105 {
106 PLIST_ENTRY Entry;
107 PHOT_KEY_ITEM HotKeyItem;
108 PWINSTATION_OBJECT WinStaObject = NULL;
109
110 if(Window->OwnerThread && Window->OwnerThread->ThreadsProcess)
111 WinStaObject = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation;
112
113 if(!WinStaObject)
114 return;
115
116 Entry = WinStaObject->HotKeyListHead.Flink;
117 while (Entry != &WinStaObject->HotKeyListHead)
118 {
119 HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
120 HOT_KEY_ITEM,
121 ListEntry);
122 Entry = Entry->Flink;
123 if (HotKeyItem->hWnd == Window->hSelf)
124 {
125 RemoveEntryList (&HotKeyItem->ListEntry);
126 ExFreePool (HotKeyItem);
127 }
128 }
129
130 }
131
132
133 VOID
134 UnregisterThreadHotKeys(struct _ETHREAD *Thread)
135 {
136 PLIST_ENTRY Entry;
137 PHOT_KEY_ITEM HotKeyItem;
138 PWINSTATION_OBJECT WinStaObject = NULL;
139
140 if(Thread->Tcb.Win32Thread && Thread->Tcb.Win32Thread->Desktop)
141 WinStaObject = Thread->Tcb.Win32Thread->Desktop->WindowStation;
142
143 if(!WinStaObject)
144 return;
145
146 Entry = WinStaObject->HotKeyListHead.Flink;
147 while (Entry != &WinStaObject->HotKeyListHead)
148 {
149 HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
150 HOT_KEY_ITEM,
151 ListEntry);
152 Entry = Entry->Flink;
153 if (HotKeyItem->Thread == Thread)
154 {
155 RemoveEntryList (&HotKeyItem->ListEntry);
156 ExFreePool (HotKeyItem);
157 }
158 }
159
160 }
161
162
163 static BOOL
164 IsHotKey (PWINSTATION_OBJECT WinStaObject,
165 UINT fsModifiers,
166 UINT vk)
167 {
168 PLIST_ENTRY Entry;
169 PHOT_KEY_ITEM HotKeyItem;
170
171 Entry = WinStaObject->HotKeyListHead.Flink;
172 while (Entry != &WinStaObject->HotKeyListHead)
173 {
174 HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
175 HOT_KEY_ITEM,
176 ListEntry);
177 if (HotKeyItem->fsModifiers == fsModifiers &&
178 HotKeyItem->vk == vk)
179 {
180 return TRUE;
181 }
182
183 Entry = Entry->Flink;
184 }
185
186 return FALSE;
187 }
188
189
190 BOOL STDCALL
191 NtUserRegisterHotKey(HWND hWnd,
192 int id,
193 UINT fsModifiers,
194 UINT vk)
195 {
196 PHOT_KEY_ITEM HotKeyItem;
197 PWINDOW_OBJECT Window;
198 PWINSTATION_OBJECT WinStaObject = NULL;
199 PETHREAD HotKeyThread;
200 DECLARE_RETURN(BOOL);
201
202 DPRINT("Enter NtUserRegisterHotKey\n");
203 UserEnterExclusive();
204
205 if (hWnd == NULL)
206 {
207 HotKeyThread = PsGetCurrentThread();
208 }
209 else
210 {
211 if(!(Window = UserGetWindowObject(hWnd)))
212 {
213 RETURN( FALSE);
214 }
215 HotKeyThread = Window->OwnerThread;
216 }
217
218
219 if(HotKeyThread->ThreadsProcess && HotKeyThread->ThreadsProcess->Win32Process)
220 WinStaObject = HotKeyThread->Tcb.Win32Thread->Desktop->WindowStation;
221
222 if(!WinStaObject)
223 {
224 RETURN( FALSE);
225 }
226
227 /* Check for existing hotkey */
228 if (IsHotKey (WinStaObject, fsModifiers, vk))
229 {
230 RETURN( FALSE);
231 }
232
233 HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM), TAG_HOTKEY);
234 if (HotKeyItem == NULL)
235 {
236 RETURN( FALSE);
237 }
238
239 HotKeyItem->Thread = HotKeyThread;
240 HotKeyItem->hWnd = hWnd;
241 HotKeyItem->id = id;
242 HotKeyItem->fsModifiers = fsModifiers;
243 HotKeyItem->vk = vk;
244
245 InsertHeadList (&WinStaObject->HotKeyListHead,
246 &HotKeyItem->ListEntry);
247
248 RETURN( TRUE);
249
250 CLEANUP:
251 DPRINT("Leave NtUserRegisterHotKey, ret=%i\n",_ret_);
252 UserLeave();
253 END_CLEANUP;
254 }
255
256
257 BOOL STDCALL
258 NtUserUnregisterHotKey(HWND hWnd,
259 int id)
260 {
261 PLIST_ENTRY Entry;
262 PHOT_KEY_ITEM HotKeyItem;
263 PWINDOW_OBJECT Window;
264 PWINSTATION_OBJECT WinStaObject = NULL;
265 DECLARE_RETURN(BOOL);
266
267 DPRINT("Enter NtUserUnregisterHotKey\n");
268 UserEnterExclusive();
269
270 if(!(Window = UserGetWindowObject(hWnd)))
271 {
272 RETURN( FALSE);
273 }
274
275 if(Window->OwnerThread->ThreadsProcess && Window->OwnerThread->ThreadsProcess->Win32Process)
276 WinStaObject = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation;
277
278 if(!WinStaObject)
279 {
280 RETURN( FALSE);
281 }
282
283 Entry = WinStaObject->HotKeyListHead.Flink;
284 while (Entry != &WinStaObject->HotKeyListHead)
285 {
286 HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
287 HOT_KEY_ITEM,
288 ListEntry);
289 if (HotKeyItem->hWnd == hWnd &&
290 HotKeyItem->id == id)
291 {
292 RemoveEntryList (&HotKeyItem->ListEntry);
293 ExFreePool (HotKeyItem);
294
295 RETURN( TRUE);
296 }
297
298 Entry = Entry->Flink;
299 }
300
301 RETURN( FALSE);
302
303 CLEANUP:
304 DPRINT("Leave NtUserUnregisterHotKey, ret=%i\n",_ret_);
305 UserLeave();
306 END_CLEANUP;
307 }
308
309 /* EOF */