ReactOS  0.4.14-dev-50-g13bb5e2
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) */
32 typedef 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 {
77  U32_ACCEL_CACHE_ENTRY * pEntry =
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;
90  U32AccelCache = pEntry;
91 }
92 
93 /* Create an accelerator table from a loaded resource */
95 {
96  HGLOBAL hAccTableData;
97  HACCEL hAccTable = NULL;
98  U32_ACCEL_CACHE_ENTRY * pEntry;
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 
160 l_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 */
219  LocalFree(pEntry);
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 {
239  return U32LoadAccelerators
240  (
241  hInstance,
242  FindResourceExW(hInstance, (LPCWSTR) RT_ACCELERATOR, lpTableName, 0)
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  */
268 int 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  {
295  NTSTATUS nErrCode = RtlUnicodeToMultiByteN(
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  */
341 int 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 */
signed char * PCHAR
Definition: retypes.h:7
struct PE_ACCEL * LPPE_ACCEL
HACCEL WINAPI U32LoadAccelerators(HINSTANCE hInstance, HRSRC hTableRes)
Definition: accel.c:94
BYTE pad0
Definition: accel.c:35
#define TRUE
Definition: types.h:120
#define MAKEWPARAM(l, h)
Definition: winuser.h:3948
HACCEL WINAPI CreateAcceleratorTableW(_In_reads_(cAccel) LPACCEL paccel, _In_ int cAccel)
#define WM_CHAR
Definition: winuser.h:1699
BOOL WINAPI U32IsValidAccelMessage(UINT uMsg)
Definition: accel.c:166
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
WORD pad1
Definition: accel.c:38
NTSYSAPI NTSTATUS WINAPI RtlMultiByteToUnicodeN(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD)
BYTE fVirt
Definition: winuser.h:2897
#define CP_ACP
Definition: compat.h:99
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
WORD cmd
Definition: winuser.h:2899
LONG NTSTATUS
Definition: precomp.h:26
HACCEL WINAPI LoadAcceleratorsA(HINSTANCE hInstance, LPCSTR lpTableName)
Definition: accel.c:250
HWND hWnd
Definition: settings.c:17
U32_ACCEL_CACHE_ENTRY **WINAPI U32AccelCacheFind(HANDLE Object, HGLOBAL Data)
Definition: accel.c:60
WPARAM wParam
Definition: winuser.h:3090
struct _USER_ACCEL_CACHE_ENTRY * Next
Definition: accel.c:44
uint16_t * PWCHAR
Definition: typedefs.h:54
HACCEL WINAPI LoadAcceleratorsW(HINSTANCE hInstance, LPCWSTR lpTableName)
Definition: accel.c:237
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI U32AccelCacheAdd(HACCEL Object, HGLOBAL Data)
Definition: accel.c:75
uint32_t ULONG_PTR
Definition: typedefs.h:63
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
HINSTANCE hInstance
Definition: charmap.c:20
struct _USER_ACCEL_CACHE_ENTRY U32_ACCEL_CACHE_ENTRY
HACCEL hAccel
Definition: main.c:47
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI CopyAcceleratorTableA(HACCEL hAccelSrc, LPACCEL lpAccelDst, int cAccelEntries)
Definition: accel.c:280
Definition: accel.c:32
#define WM_SYSCHAR
Definition: winuser.h:1703
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccl, int cEntries)
Definition: accel.c:313
smooth NULL
Definition: ftsmooth.c:416
HRSRC WINAPI FindResourceExA(HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang)
Definition: res.c:143
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define WM_KEYDOWN
Definition: winuser.h:1697
int WINAPI CopyAcceleratorTableW(_In_ HACCEL hAccelSrc, _Out_writes_to_opt_(cAccelEntries, return) LPACCEL lpAccelDst, _In_ int cAccelEntries)
int NTAPI NtUserTranslateAccelerator(HWND Window, HACCEL Table, LPMSG Message)
Definition: accelerator.c:375
const char * LPCSTR
Definition: xmlstorage.h:183
WORD key
Definition: winuser.h:2898
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
#define LMEM_FIXED
Definition: winbase.h:349
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define WINAPI
Definition: msvc.h:8
#define WM_KEYUP
Definition: winuser.h:1698
unsigned short WORD
Definition: ntddk_ex.h:93
HACCEL NTAPI NtUserCreateAcceleratorTable(LPACCEL Entries, ULONG EntriesCount)
Definition: accelerator.c:229
BYTE fVirt
Definition: accel.c:34
static IUnknown Object
Definition: main.c:512
_In_ UINT _In_ UINT cEntries
Definition: wingdi.h:3615
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
NTSYSAPI NTSTATUS NTAPI RtlUnicodeToMultiByteN(PCHAR MbString, ULONG MbSize, PULONG ResultSize, PCWCH UnicodeString, ULONG UnicodeSize)
BOOL WINAPI DestroyAcceleratorTable(HACCEL hAccel)
Definition: accel.c:191
HGLOBAL Data
Definition: accel.c:47
unsigned char BYTE
Definition: mem.h:68
#define RT_ACCELERATOR
Definition: winuser.h:606
WORD cmd
Definition: accel.c:37
WORD key
Definition: accel.c:36
U32_ACCEL_CACHE_ENTRY * U32AccelCache
Definition: accel.c:57
ULONG_PTR SIZE_T
Definition: typedefs.h:78
int WINAPI TranslateAcceleratorW(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
Definition: accel.c:268
BOOLEAN NTAPI NtUserDestroyAcceleratorTable(HACCEL Table)
Definition: accelerator.c:344
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define WM_SYSKEYUP
Definition: winuser.h:1702
ULONG_PTR Usage
Definition: accel.c:45
unsigned int UINT
Definition: ndis.h:50
CRITICAL_SECTION U32AccelCacheLock
Definition: accel.c:54
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
#define MultiByteToWideChar
Definition: compat.h:100
#define WM_SYSKEYDOWN
Definition: winuser.h:1701
#define HIWORD(l)
Definition: typedefs.h:246
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
UINT message
Definition: winuser.h:3089
#define FVIRTKEY
Definition: winuser.h:24
int WINAPI TranslateAcceleratorA(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
Definition: accel.c:341
#define LOWORD(l)
Definition: pedump.c:82
HACCEL Object
Definition: accel.c:46
Definition: accel.c:42
Definition: path.c:42