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