- Sync up Mm interface with WinLdr branch (introduce the concept of a memory type...
[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
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
31
32 /*
33
34 FIXME: Hotkey notifications are triggered by keyboard input (physical or programatically)
35 and since only desktops on WinSta0 can recieve input in seems very wrong to allow
36 windows/threads on destops not belonging to WinSta0 to set hotkeys (recieve notifications).
37
38 -Gunnar
39 */
40
41
42 /* INCLUDES ******************************************************************/
43
44 #include <w32k.h>
45
46 #define NDEBUG
47 #include <debug.h>
48
49 /* GLOBALS *******************************************************************/
50
51 LIST_ENTRY gHotkeyList;
52
53 /* FUNCTIONS *****************************************************************/
54
55 NTSTATUS FASTCALL
56 InitHotkeyImpl()
57 {
58 InitializeListHead(&gHotkeyList);
59
60 return STATUS_SUCCESS;
61 }
62
63
64 #if 0 //not used
65 NTSTATUS FASTCALL
66 CleanupHotKeys()
67 {
68
69 return STATUS_SUCCESS;
70 }
71 #endif
72
73
74 BOOL FASTCALL
75 GetHotKey (UINT fsModifiers,
76 UINT vk,
77 struct _ETHREAD **Thread,
78 HWND *hWnd,
79 int *id)
80 {
81 PHOT_KEY_ITEM HotKeyItem;
82
83 LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
84 {
85 if (HotKeyItem->fsModifiers == fsModifiers &&
86 HotKeyItem->vk == vk)
87 {
88 if (Thread != NULL)
89 *Thread = HotKeyItem->Thread;
90
91 if (hWnd != NULL)
92 *hWnd = HotKeyItem->hWnd;
93
94 if (id != NULL)
95 *id = HotKeyItem->id;
96
97 return TRUE;
98 }
99 }
100
101 return FALSE;
102 }
103
104
105 VOID FASTCALL
106 UnregisterWindowHotKeys(PWINDOW_OBJECT Window)
107 {
108 PHOT_KEY_ITEM HotKeyItem, tmp;
109
110 LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
111 {
112 if (HotKeyItem->hWnd == Window->hSelf)
113 {
114 RemoveEntryList (&HotKeyItem->ListEntry);
115 ExFreePool (HotKeyItem);
116 }
117 }
118
119 }
120
121
122 VOID FASTCALL
123 UnregisterThreadHotKeys(struct _ETHREAD *Thread)
124 {
125 PHOT_KEY_ITEM HotKeyItem, tmp;
126
127 LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
128 {
129 if (HotKeyItem->Thread == Thread)
130 {
131 RemoveEntryList (&HotKeyItem->ListEntry);
132 ExFreePool (HotKeyItem);
133 }
134 }
135
136 }
137
138
139 static
140 BOOL FASTCALL
141 IsHotKey (UINT fsModifiers, UINT vk)
142 {
143 PHOT_KEY_ITEM HotKeyItem;
144
145 LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
146 {
147 if (HotKeyItem->fsModifiers == fsModifiers && HotKeyItem->vk == vk)
148 {
149 return TRUE;
150 }
151 }
152
153 return FALSE;
154 }
155
156
157
158 /* SYSCALLS *****************************************************************/
159
160
161 BOOL STDCALL
162 NtUserRegisterHotKey(HWND hWnd,
163 int id,
164 UINT fsModifiers,
165 UINT vk)
166 {
167 PHOT_KEY_ITEM HotKeyItem;
168 PWINDOW_OBJECT Window;
169 PETHREAD HotKeyThread;
170 DECLARE_RETURN(BOOL);
171
172 DPRINT("Enter NtUserRegisterHotKey\n");
173 UserEnterExclusive();
174
175 if (hWnd == NULL)
176 {
177 HotKeyThread = PsGetCurrentThread();
178 }
179 else
180 {
181 if(!(Window = UserGetWindowObject(hWnd)))
182 {
183 RETURN( FALSE);
184 }
185 HotKeyThread = Window->OwnerThread;
186 }
187
188 /* Check for existing hotkey */
189 if (IsHotKey (fsModifiers, vk))
190 {
191 RETURN( FALSE);
192 }
193
194 HotKeyItem = ExAllocatePoolWithTag (PagedPool, sizeof(HOT_KEY_ITEM), TAG_HOTKEY);
195 if (HotKeyItem == NULL)
196 {
197 RETURN( FALSE);
198 }
199
200 HotKeyItem->Thread = HotKeyThread;
201 HotKeyItem->hWnd = hWnd;
202 HotKeyItem->id = id;
203 HotKeyItem->fsModifiers = fsModifiers;
204 HotKeyItem->vk = vk;
205
206 InsertHeadList (&gHotkeyList, &HotKeyItem->ListEntry);
207
208 RETURN( TRUE);
209
210 CLEANUP:
211 DPRINT("Leave NtUserRegisterHotKey, ret=%i\n",_ret_);
212 UserLeave();
213 END_CLEANUP;
214 }
215
216
217 BOOL STDCALL
218 NtUserUnregisterHotKey(HWND hWnd, int id)
219 {
220 PHOT_KEY_ITEM HotKeyItem;
221 PWINDOW_OBJECT Window;
222 DECLARE_RETURN(BOOL);
223
224 DPRINT("Enter NtUserUnregisterHotKey\n");
225 UserEnterExclusive();
226
227 if(!(Window = UserGetWindowObject(hWnd)))
228 {
229 RETURN( FALSE);
230 }
231
232 LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
233 {
234 if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id)
235 {
236 RemoveEntryList (&HotKeyItem->ListEntry);
237 ExFreePool (HotKeyItem);
238
239 RETURN( TRUE);
240 }
241 }
242
243 RETURN( FALSE);
244
245 CLEANUP:
246 DPRINT("Leave NtUserUnregisterHotKey, ret=%i\n",_ret_);
247 UserLeave();
248 END_CLEANUP;
249 }
250
251 /* EOF */