ReactOS 0.4.15-dev-7842-g558ab78
accel.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 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/*
20 * PROJECT: ReactOS user32.dll
21 * FILE: win32ss/user/user32/windows/accel.c
22 * PURPOSE: Accelerator tables
23 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
24 * UPDATE HISTORY:
25 * 09/05/2001 CSH Created
26 * 08/07/2003 KJK Fully implemented
27 */
28
29#include <user32.h>
30
31/* this is the 8 byte accel struct used in Win32 resources (internal only) */
32typedef struct
33{
40
41/* Cache entry */
43{
45 ULONG_PTR Usage; /* how many times the table has been loaded */
46 HACCEL Object; /* handle to the NtUser accelerator table object */
47 HGLOBAL Data; /* base address of the resource data */
48}
50
51/* FUNCTIONS *****************************************************************/
52
53/* Lock guarding the cache */
55
56/* Cache */
58
59/* Look up a handle or resource address in the cache */
61{
62 /*
63 to avoid using a double-link list and still allow elements to be removed,
64 return a pointer to the list link that points to the desired entry
65 */
67
68 for(; *ppEntry; ppEntry = &((*ppEntry)->Next))
69 if((*ppEntry)->Object == Object || (*ppEntry)->Data == Data) break;
70
71 return ppEntry;
72}
73
74/* Allocate an entry and insert it into the cache */
76{
79
80 /* failed to allocate an entry - not critical */
81 if(pEntry == NULL) return;
82
83 /* initialize the entry */
84 pEntry->Usage = 1;
85 pEntry->Object = Object;
86 pEntry->Data = Data;
87
88 /* insert the entry into the cache */
89 pEntry->Next = U32AccelCache;
91}
92
93/* Create an accelerator table from a loaded resource */
95{
96 HGLOBAL hAccTableData;
97 HACCEL hAccTable = NULL;
99 PE_ACCEL * pAccTableResData;
100 SIZE_T i = 0;
101 SIZE_T j = 0;
102 ACCEL * pAccTableData;
103
104 /* load the accelerator table */
105 hAccTableData = LoadResource(hInstance, hTableRes);
106
107 /* failure */
108 if(hAccTableData == NULL) return NULL;
109
111
112 /* see if this accelerator table has already been loaded */
113 pEntry = *U32AccelCacheFind(NULL, hAccTableData);
114
115 /* accelerator table already loaded */
116 if(pEntry)
117 {
118 /* increment the reference count */
119 ++ pEntry->Usage;
120
121 /* return the existing object */
122 hAccTable = pEntry->Object;
123
124 /* success */
125 goto l_Leave;
126 }
127
128 /* determine the number of entries in the table */
129 i = SizeofResource(hInstance, hTableRes) / sizeof(PE_ACCEL);
130
131 /* allocate the buffer for the table to be passed to Win32K */
132 pAccTableData = LocalAlloc(LMEM_FIXED, i * sizeof(ACCEL));
133
134 /* failure */
135 if(pAccTableData == NULL) goto l_Leave;
136
137 pAccTableResData = (PE_ACCEL *)hAccTableData;
138
139 /* copy the table */
140 for(j = 0; j < i; ++ j)
141 {
142 pAccTableData[j].fVirt = pAccTableResData[j].fVirt;
143 pAccTableData[j].key = pAccTableResData[j].key;
144 pAccTableData[j].cmd = pAccTableResData[j].cmd;
145 }
146 pAccTableData[i - 1].fVirt |= 0x80;
147
148 /* create a new accelerator table object */
149 hAccTable = NtUserCreateAcceleratorTable(pAccTableData, i);
150
151 /* free the buffer */
152 LocalFree(pAccTableData);
153
154 /* failure */
155 if(hAccTable == NULL) goto l_Leave;
156
157 /* success - cache the object */
158 U32AccelCacheAdd(hAccTable, pAccTableResData);
159
160l_Leave:
162 return hAccTable;
163}
164
165/* Checks if a message can be translated through an accelerator table */
167{
168 switch(uMsg)
169 {
170 case WM_KEYDOWN:
171 case WM_KEYUP:
172 case WM_CHAR:
173 case WM_SYSCHAR:
174 case WM_SYSKEYDOWN:
175 case WM_SYSKEYUP:
176 return TRUE;
177
178 default:
179 return FALSE;
180 }
181}
182
183/* WIN32 FUNCTIONS ***********************************************************/
184
185/*
186 * Dereference the specified accelerator table, removing it from the cache and
187 * deleting the associated NtUser object as appropriate
188 *
189 * @implemented
190 */
192{
193 U32_ACCEL_CACHE_ENTRY ** ppEntry;
194 ULONG_PTR nUsage = 0;
195
196 if (!hAccel)
197 return FALSE;
198
200
201 /* see if this accelerator table has been cached */
202 ppEntry = U32AccelCacheFind(hAccel, NULL);
203
204 /* accelerator table cached */
205 if(*ppEntry)
206 {
207 U32_ACCEL_CACHE_ENTRY * pEntry = *ppEntry;
208
209 /* decrement the reference count */
210 nUsage = pEntry->Usage = pEntry->Usage - 1;
211
212 /* reference count now zero: destroy the cache entry */
213 if(nUsage == 0)
214 {
215 /* unlink the cache entry */
216 *ppEntry = pEntry->Next;
217
218 /* free the cache entry */
220 }
221 }
222
224
225 if(nUsage > 0) return FALSE;
226
227 /* destroy the object */
229}
230
231
232/*
233 * Create an accelerator table from a named resource
234 *
235 * @implemented
236 */
238{
240 (
241 hInstance,
243 );
244}
245
246
247/*
248 * @implemented
249 */
251{
252 HRSRC Accel;
253
254 Accel = FindResourceExA(hInstance, (LPCSTR) RT_ACCELERATOR, lpTableName, 0);
255 if (NULL == Accel)
256 {
257 return NULL;
258 }
259
260 return U32LoadAccelerators(hInstance, Accel);
261}
262
263/*
264 * Translate a key press into a WM_COMMAND message
265 *
266 * @implemented
267 */
268int WINAPI TranslateAcceleratorW(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
269{
270 if(!U32IsValidAccelMessage(lpMsg->message)) return 0;
271
272 return NtUserTranslateAccelerator(hWnd, hAccTable, lpMsg);
273}
274
275
276/*
277 * @implemented
278 */
280(
281 HACCEL hAccelSrc,
282 LPACCEL lpAccelDst, /* can be NULL */
283 int cAccelEntries
284)
285{
286 int i;
287
288 cAccelEntries = CopyAcceleratorTableW(hAccelSrc, lpAccelDst, cAccelEntries);
289
290 if (lpAccelDst == NULL) return cAccelEntries;
291
292 for(i = 0; i < cAccelEntries; ++ i)
293 if(!(lpAccelDst[i].fVirt & FVIRTKEY))
294 {
296 (PCHAR)&lpAccelDst[i].key,
297 sizeof(lpAccelDst[i].key),
298 NULL,
299 (PWCHAR)&lpAccelDst[i].key,
300 sizeof(lpAccelDst[i].key)
301 );
302
303 if(!NT_SUCCESS(nErrCode)) lpAccelDst[i].key = 0;
304 }
305
306 return cAccelEntries;
307}
308
309
310/*
311 * @implemented
312 */
314{
315 int i;
316
317 if (!cEntries || !lpaccl) return (HACCEL)0;
318
319 for(i = 0; i < cEntries; ++ i)
320 if(!lpaccl[i].fVirt)
321 {
323 (
324 (PWCHAR)&lpaccl[i].key,
325 sizeof(lpaccl[i].key),
326 NULL,
327 (PCHAR)&lpaccl[i].key,
328 sizeof(lpaccl[i].key)
329 );
330
331 if(!NT_SUCCESS(nErrCode)) lpaccl[i].key = -1;
332 }
333
334 return CreateAcceleratorTableW(lpaccl, cEntries);
335}
336
337
338/*
339 * @implemented
340 */
341int WINAPI TranslateAcceleratorA(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
342{
343 switch (lpMsg->message)
344 {
345 case WM_KEYDOWN:
346 case WM_SYSKEYDOWN:
347 return TranslateAcceleratorW( hWnd, hAccTable, lpMsg );
348
349 case WM_CHAR:
350 case WM_SYSCHAR:
351 {
352 MSG msgW = *lpMsg;
353 char ch = LOWORD(lpMsg->wParam);
354 WCHAR wch;
355 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
356 msgW.wParam = MAKEWPARAM(wch, HIWORD(lpMsg->wParam));
357 return TranslateAcceleratorW( hWnd, hAccTable, &msgW );
358 }
359
360 default:
361 return 0;
362 }
363}
364
365/* EOF */
HACCEL WINAPI U32LoadAccelerators(HINSTANCE hInstance, HRSRC hTableRes)
Definition: accel.c:94
HACCEL WINAPI LoadAcceleratorsW(HINSTANCE hInstance, LPCWSTR lpTableName)
Definition: accel.c:237
HACCEL WINAPI LoadAcceleratorsA(HINSTANCE hInstance, LPCSTR lpTableName)
Definition: accel.c:250
void WINAPI U32AccelCacheAdd(HACCEL Object, HGLOBAL Data)
Definition: accel.c:75
int WINAPI TranslateAcceleratorW(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
Definition: accel.c:268
int WINAPI CopyAcceleratorTableA(HACCEL hAccelSrc, LPACCEL lpAccelDst, int cAccelEntries)
Definition: accel.c:280
struct PE_ACCEL * LPPE_ACCEL
int WINAPI TranslateAcceleratorA(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
Definition: accel.c:341
BOOL WINAPI DestroyAcceleratorTable(HACCEL hAccel)
Definition: accel.c:191
U32_ACCEL_CACHE_ENTRY **WINAPI U32AccelCacheFind(HANDLE Object, HGLOBAL Data)
Definition: accel.c:60
struct _USER_ACCEL_CACHE_ENTRY U32_ACCEL_CACHE_ENTRY
CRITICAL_SECTION U32AccelCacheLock
Definition: accel.c:54
U32_ACCEL_CACHE_ENTRY * U32AccelCache
Definition: accel.c:57
BOOL WINAPI U32IsValidAccelMessage(UINT uMsg)
Definition: accel.c:166
HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccl, int cEntries)
Definition: accel.c:313
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
HINSTANCE hInstance
Definition: charmap.c:19
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
HRSRC WINAPI FindResourceExA(HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang)
Definition: res.c:143
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
HACCEL NTAPI NtUserCreateAcceleratorTable(LPACCEL Entries, ULONG EntriesCount)
Definition: accelerator.c:225
int NTAPI NtUserTranslateAccelerator(HWND Window, HACCEL Table, LPMSG Message)
Definition: accelerator.c:367
BOOLEAN NTAPI NtUserDestroyAcceleratorTable(HACCEL Table)
Definition: accelerator.c:340
HACCEL hAccel
Definition: main.c:47
unsigned int UINT
Definition: ndis.h:50
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteN(_Out_ PCHAR MbString, _In_ ULONG MbSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:107
_Use_decl_annotations_ NTSTATUS NTAPI RtlMultiByteToUnicodeN(_Out_ PWCH UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH MbString, _In_ ULONG MbSize)
Definition: nlsboot.c:62
#define LOWORD(l)
Definition: pedump.c:82
Definition: accel.c:33
WORD cmd
Definition: accel.c:37
WORD pad1
Definition: accel.c:38
BYTE fVirt
Definition: accel.c:34
WORD key
Definition: accel.c:36
BYTE pad0
Definition: accel.c:35
Definition: accel.c:43
ULONG_PTR Usage
Definition: accel.c:45
HGLOBAL Data
Definition: accel.c:47
HACCEL Object
Definition: accel.c:46
struct _USER_ACCEL_CACHE_ENTRY * Next
Definition: accel.c:44
Definition: copy.c:22
WORD cmd
Definition: winuser.h:2925
BYTE fVirt
Definition: winuser.h:2923
WORD key
Definition: winuser.h:2924
UINT message
Definition: winuser.h:3115
WPARAM wParam
Definition: winuser.h:3116
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
#define HIWORD(l)
Definition: typedefs.h:247
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define LMEM_FIXED
Definition: winbase.h:368
#define WINAPI
Definition: msvc.h:6
_In_ UINT _In_ UINT cEntries
Definition: wingdi.h:3621
#define MAKEWPARAM(l, h)
Definition: winuser.h:4009
#define WM_KEYUP
Definition: winuser.h:1716
#define RT_ACCELERATOR
Definition: winuser.h:607
HACCEL WINAPI CreateAcceleratorTableW(_In_reads_(cAccel) LPACCEL paccel, _In_ int cAccel)
int WINAPI CopyAcceleratorTableW(_In_ HACCEL hAccelSrc, _Out_writes_to_opt_(cAccelEntries, return) LPACCEL lpAccelDst, _In_ int cAccelEntries)
#define FVIRTKEY
Definition: winuser.h:24
#define WM_SYSCHAR
Definition: winuser.h:1721
#define WM_SYSKEYUP
Definition: winuser.h:1720
#define WM_CHAR
Definition: winuser.h:1717
#define WM_KEYDOWN
Definition: winuser.h:1715
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193