Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
688c5658
Commit
688c5658
authored
Jan 22, 1999
by
Marcus Meissner
Committed by
Alexandre Julliard
Jan 22, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed accelerator handling. ACCEL16 used internal, ACCEL32 for Win32
API, PE_ACCEL for PE Accelerators. See documentation/accelerators.
parent
f25ac7cc
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
47 deletions
+91
-47
accelerators
documentation/accelerators
+38
-0
winuser.h
include/winuser.h
+11
-1
resource.c
loader/resource.c
+40
-45
input.c
windows/input.c
+2
-1
No files found.
documentation/accelerators
0 → 100644
View file @
688c5658
Some notes concerning accelerators.
There are _three_ differently sized accelerator structures exposed to the
user. The general layout is:
BYTE fVirt;
WORD key;
WORD cmd;
We now have three different appearances:
- Accelerators in NE resources. These have a size of 5 byte and do not have
any padding. This is also the internal layout of the global handle HACCEL
(16 and 32) in Windows 95 and WINE. Exposed to the user as Win16 global
handles HACCEL16 and HACCEL32 by the Win16/Win32 API.
- Accelerators in PE resources. These have a size of 8 byte. Layout is:
BYTE fVirt;
BYTE pad0;
WORD key;
WORD cmd;
WORD pad1;
They are exposed to the user only by direct accessing PE resources.
- Accelerators in the Win32 API. These have a size of 6 byte. Layout is:
BYTE fVirt;
BYTE pad0;
WORD key;
WORD cmd;
These are exposed to the user by the CopyAcceleratorTable and
CreateAcceleratorTable in the Win32 API.
Why two types of accelerators in the Win32 API? We can only guess, but
my best bet is that the Win32 resource compiler can/does not handle struct
packing. Win32 ACCEL is defined using #pragma(2) for the compiler but without
any packing for RC, so it will assume #pragma(4).
Findings researched by Uwe Bonnes, Ulrich Weigand and Marcus Meissner.
include/winuser.h
View file @
688c5658
...
@@ -119,15 +119,25 @@ typedef struct {
...
@@ -119,15 +119,25 @@ typedef struct {
HBITMAP32
hbmColor
;
HBITMAP32
hbmColor
;
}
ICONINFO
,
*
LPICONINFO
;
}
ICONINFO
,
*
LPICONINFO
;
/* this is the 6 byte accel struct used in Win32 when presented to the user */
typedef
struct
typedef
struct
{
{
BYTE
fVirt
;
BYTE
fVirt
;
BYTE
pad0
;
BYTE
pad0
;
WORD
key
;
WORD
key
;
WORD
cmd
;
WORD
cmd
;
WORD
pad1
;
}
ACCEL32
,
*
LPACCEL32
;
}
ACCEL32
,
*
LPACCEL32
;
/* this is the 8 byte accel struct used in Win32 resources (internal only) */
typedef
struct
{
BYTE
fVirt
;
BYTE
pad0
;
WORD
key
;
WORD
cmd
;
WORD
pad1
;
}
PE_ACCEL
,
*
LPPE_ACCEL
;
DECL_WINELIB_TYPE
(
ACCEL
)
DECL_WINELIB_TYPE
(
ACCEL
)
DECL_WINELIB_TYPE
(
LPACCEL
)
DECL_WINELIB_TYPE
(
LPACCEL
)
...
...
loader/resource.c
View file @
688c5658
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
#include <fcntl.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include "windows.h"
#include "windows.h"
#include "wine/winuser16.h"
#include "gdi.h"
#include "gdi.h"
#include "global.h"
#include "global.h"
#include "heap.h"
#include "heap.h"
...
@@ -425,7 +426,7 @@ HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
...
@@ -425,7 +426,7 @@ HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
HACCEL32
WINAPI
LoadAccelerators32W
(
HINSTANCE32
instance
,
LPCWSTR
lpTableName
)
HACCEL32
WINAPI
LoadAccelerators32W
(
HINSTANCE32
instance
,
LPCWSTR
lpTableName
)
{
{
HRSRC32
hRsrc
;
HRSRC32
hRsrc
;
HACCEL32
hRetval
;
HACCEL32
h
Mem
,
h
Retval
;
DWORD
size
;
DWORD
size
;
if
(
HIWORD
(
lpTableName
))
if
(
HIWORD
(
lpTableName
))
...
@@ -441,16 +442,24 @@ HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
...
@@ -441,16 +442,24 @@ HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
hRetval
=
0
;
hRetval
=
0
;
}
}
else
{
else
{
h
Retval
=
LoadResource32
(
instance
,
hRsrc
);
h
Mem
=
LoadResource32
(
instance
,
hRsrc
);
size
=
SizeofResource32
(
instance
,
hRsrc
);
size
=
SizeofResource32
(
instance
,
hRsrc
);
if
(
size
>=
sizeof
(
ACCEL32
))
if
(
size
>=
sizeof
(
PE_ACCEL
))
{
{
LPACCEL32
accel_table
=
(
LPACCEL32
)
hRetval
;
LPPE_ACCEL
accel_table
=
(
LPPE_ACCEL
)
hMem
;
/* mark last element as such - sometimes it is not marked in image */
LPACCEL16
accel16
;
accel_table
[
size
/
sizeof
(
ACCEL32
)
-
1
].
fVirt
|=
0x80
;
int
i
,
nrofaccells
=
size
/
sizeof
(
PE_ACCEL
);
hRetval
=
GlobalAlloc16
(
0
,
sizeof
(
ACCEL16
)
*
nrofaccells
);
accel16
=
(
LPACCEL16
)
GlobalLock16
(
hRetval
);
for
(
i
=
0
;
i
<
nrofaccells
;
i
++
)
{
accel16
[
i
].
fVirt
=
accel_table
[
i
].
fVirt
;
accel16
[
i
].
key
=
accel_table
[
i
].
key
;
accel16
[
i
].
cmd
=
accel_table
[
i
].
cmd
;
}
accel16
[
i
-
1
].
fVirt
|=
0x80
;
}
}
}
}
TRACE
(
accel
,
"returning HACCEL 0x%x
\n
"
,
hRsrc
);
TRACE
(
accel
,
"returning HACCEL 0x%x
\n
"
,
hRsrc
);
return
hRetval
;
return
hRetval
;
}
}
...
@@ -484,18 +493,19 @@ INT32 WINAPI CopyAcceleratorTable32A(HACCEL32 src, LPACCEL32 dst, INT32 entries)
...
@@ -484,18 +493,19 @@ INT32 WINAPI CopyAcceleratorTable32A(HACCEL32 src, LPACCEL32 dst, INT32 entries)
INT32
WINAPI
CopyAcceleratorTable32W
(
HACCEL32
src
,
LPACCEL32
dst
,
INT32
WINAPI
CopyAcceleratorTable32W
(
HACCEL32
src
,
LPACCEL32
dst
,
INT32
entries
)
INT32
entries
)
{
{
int
i
;
int
i
,
xsize
;
LPACCEL
32
accel
=
(
LPACCEL32
)
src
;
LPACCEL
16
accel
=
(
LPACCEL16
)
GlobalLock16
(
src
)
;
BOOL32
done
=
FALSE
;
BOOL32
done
=
FALSE
;
/* Do parameter checking to avoid the explosions and the screaming
/* Do parameter checking to avoid the explosions and the screaming
as far as possible. */
as far as possible. */
if
((
dst
&&
(
entries
<
1
))
||
(
src
==
(
HACCEL32
)
NULL
))
{
if
((
dst
&&
(
entries
<
1
))
||
(
src
==
(
HACCEL32
)
NULL
)
||
!
accel
)
{
WARN
(
accel
,
"Application sent invalid parameters (%p %p %d).
\n
"
,
WARN
(
accel
,
"Application sent invalid parameters (%p %p %d).
\n
"
,
(
LPVOID
)
src
,
(
LPVOID
)
dst
,
entries
);
(
LPVOID
)
src
,
(
LPVOID
)
dst
,
entries
);
return
0
;
return
0
;
}
}
xsize
=
GlobalSize16
(
src
)
/
sizeof
(
ACCEL16
);
if
(
xsize
>
entries
)
entries
=
xsize
;
i
=
0
;
i
=
0
;
while
(
!
done
)
{
while
(
!
done
)
{
...
@@ -506,7 +516,9 @@ INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
...
@@ -506,7 +516,9 @@ INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
/* Copy data to the destination structure array (if dst == NULL,
/* Copy data to the destination structure array (if dst == NULL,
we're just supposed to count the number of entries). */
we're just supposed to count the number of entries). */
if
(
dst
)
{
if
(
dst
)
{
memcpy
(
&
dst
[
i
],
&
accel
[
i
],
sizeof
(
ACCEL32
));
dst
[
i
].
fVirt
=
accel
[
i
].
fVirt
;
dst
[
i
].
key
=
accel
[
i
].
key
;
dst
[
i
].
cmd
=
accel
[
i
].
cmd
;
/* Check if we've reached the end of the application supplied
/* Check if we've reached the end of the application supplied
accelerator table. */
accelerator table. */
...
@@ -518,7 +530,7 @@ INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
...
@@ -518,7 +530,7 @@ INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
}
}
/* The highest order bit seems to mark the end of the accelerator
/* The highest order bit seems to mark the end of the accelerator
resource table
. (?)
*/
resource table
, but not always. Use GlobalSize() check too.
*/
if
((
accel
[
i
].
fVirt
&
0x80
)
!=
0
)
done
=
TRUE
;
if
((
accel
[
i
].
fVirt
&
0x80
)
!=
0
)
done
=
TRUE
;
i
++
;
i
++
;
...
@@ -534,7 +546,9 @@ INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
...
@@ -534,7 +546,9 @@ INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
*/
*/
HACCEL32
WINAPI
CreateAcceleratorTable32A
(
LPACCEL32
lpaccel
,
INT32
cEntries
)
HACCEL32
WINAPI
CreateAcceleratorTable32A
(
LPACCEL32
lpaccel
,
INT32
cEntries
)
{
{
HACCEL32
hAccel
;
HACCEL32
hAccel
;
LPACCEL16
accel
;
int
i
;
/* Do parameter checking just in case someone's trying to be
/* Do parameter checking just in case someone's trying to be
funny. */
funny. */
...
@@ -549,18 +563,22 @@ HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
...
@@ -549,18 +563,22 @@ HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
/* Allocate memory and copy the table. */
/* Allocate memory and copy the table. */
hAccel
=
(
HACCEL32
)
HeapAlloc
(
GetProcessHeap
(),
0
,
hAccel
=
GlobalAlloc16
(
0
,
cEntries
*
sizeof
(
ACCEL16
));
cEntries
*
sizeof
(
ACCEL32
));
TRACE
(
accel
,
"handle %
p
\n
"
,
(
LPVOID
)
hAccel
);
TRACE
(
accel
,
"handle %
x
\n
"
,
hAccel
);
if
(
!
hAccel
)
{
if
(
!
hAccel
)
{
ERR
(
accel
,
"Out of memory.
\n
"
);
ERR
(
accel
,
"Out of memory.
\n
"
);
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
(
HACCEL32
)
NULL
;
return
(
HACCEL32
)
NULL
;
}
}
memcpy
((
LPACCEL32
)
hAccel
,
lpaccel
,
cEntries
*
sizeof
(
ACCEL32
));
accel
=
GlobalLock16
(
hAccel
);
for
(
i
=
0
;
i
<
cEntries
;
i
++
)
{
accel
[
i
].
fVirt
=
lpaccel
[
i
].
fVirt
;
accel
[
i
].
key
=
lpaccel
[
i
].
key
;
accel
[
i
].
cmd
=
lpaccel
[
i
].
cmd
;
}
/* Set the end-of-table terminator. */
/* Set the end-of-table terminator. */
((
LPACCEL32
)
hAccel
)
[
cEntries
-
1
].
fVirt
|=
0x80
;
accel
[
cEntries
-
1
].
fVirt
|=
0x80
;
TRACE
(
accel
,
"Allocated accelerator handle %x
\n
"
,
hAccel
);
TRACE
(
accel
,
"Allocated accelerator handle %x
\n
"
,
hAccel
);
return
hAccel
;
return
hAccel
;
...
@@ -582,31 +600,8 @@ HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
...
@@ -582,31 +600,8 @@ HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
BOOL32
WINAPI
DestroyAcceleratorTable
(
HACCEL32
handle
)
BOOL32
WINAPI
DestroyAcceleratorTable
(
HACCEL32
handle
)
{
{
FIXME
(
accel
,
"(0x%x): stub
\n
"
,
handle
);
FIXME
(
accel
,
"(0x%x): stub
\n
"
,
handle
);
/* FIXME: GlobalFree16(handle); */
return
TRUE
;
/* Weird.. I thought this should work. According to the API
specification, DestroyAcceleratorTable() should only be called on
HACCEL32's made by CreateAcceleratorTable(), but Microsoft Visual
Studio 97 calls this function with a series of different handle
values without ever calling CreateAcceleratorTable(). Something
is very fishy in Denmark... */
/* Update: looks like the calls to this function matches the calls
to LoadAccelerators() in M$ Visual Studio, except that the handle
values are off by some variable size from the HACCEL's returned
from LoadAccelerators(). WTH? */
/* Parameter checking to avoid any embarassing situations. */
#if 0
if(!handle) {
WARN(accel, "Application sent NULL ptr.\n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle);
#endif
return
TRUE
;
}
}
/**********************************************************************
/**********************************************************************
...
...
windows/input.c
View file @
688c5658
...
@@ -603,7 +603,8 @@ static BOOL32 KBD_translate_accelerator(HWND32 hWnd,LPMSG32 msg,
...
@@ -603,7 +603,8 @@ static BOOL32 KBD_translate_accelerator(HWND32 hWnd,LPMSG32 msg,
*/
*/
INT32
WINAPI
TranslateAccelerator32
(
HWND32
hWnd
,
HACCEL32
hAccel
,
LPMSG32
msg
)
INT32
WINAPI
TranslateAccelerator32
(
HWND32
hWnd
,
HACCEL32
hAccel
,
LPMSG32
msg
)
{
{
LPACCEL32
lpAccelTbl
=
(
LPACCEL32
)
LockResource32
(
hAccel
);
/* YES, Accel16! */
LPACCEL16
lpAccelTbl
=
(
LPACCEL16
)
LockResource16
(
hAccel
);
int
i
;
int
i
;
TRACE
(
accel
,
"hwnd=0x%x hacc=0x%x msg=0x%x wp=0x%x lp=0x%lx
\n
"
,
hWnd
,
hAccel
,
msg
->
message
,
msg
->
wParam
,
msg
->
lParam
);
TRACE
(
accel
,
"hwnd=0x%x hacc=0x%x msg=0x%x wp=0x%x lp=0x%lx
\n
"
,
hWnd
,
hAccel
,
msg
->
message
,
msg
->
wParam
,
msg
->
lParam
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment