Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
41b5e687
Commit
41b5e687
authored
May 09, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user: Separate the 16 and 32-bit versions of WINPROC_AllocProc.
parent
4c401906
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
106 additions
and
61 deletions
+106
-61
class.c
dlls/user/class.c
+14
-1
win.c
dlls/user/win.c
+1
-1
winproc.c
dlls/user/winproc.c
+87
-56
winproc.h
dlls/user/winproc.h
+1
-0
wnd16.c
dlls/user/wnd16.c
+3
-3
No files found.
dlls/user/class.c
View file @
41b5e687
...
...
@@ -178,6 +178,19 @@ static WNDPROC CLASS_GetProc( CLASS *classPtr, WINDOWPROCTYPE type )
/***********************************************************************
* CLASS_SetProc16
*
* Set the class winproc for a given proc type.
* Returns the previous window proc.
*/
static
void
CLASS_SetProc16
(
CLASS
*
classPtr
,
WNDPROC16
newproc
)
{
classPtr
->
winprocA
=
WINPROC_AllocProc16
(
newproc
);
classPtr
->
winprocW
=
0
;
}
/***********************************************************************
* CLASS_SetProc
*
* Set the class winproc for a given proc type.
...
...
@@ -953,7 +966,7 @@ LONG WINAPI SetClassLong16( HWND16 hwnd16, INT16 offset, LONG newval )
case
GCLP_WNDPROC
:
if
(
!
(
class
=
get_class_ptr
(
hwnd
,
TRUE
)))
return
0
;
retval
=
(
LONG
)
CLASS_GetProc16
(
class
);
CLASS_SetProc
(
class
,
(
WNDPROC
)
newval
,
WIN_PROC_16
);
CLASS_SetProc
16
(
class
,
(
WNDPROC16
)
newval
);
release_class_ptr
(
class
);
return
retval
;
case
GCLP_MENUNAME
:
...
...
dlls/user/win.c
View file @
41b5e687
...
...
@@ -2213,7 +2213,7 @@ LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
if
(
is_winproc
)
{
WNDPROC
new_proc
=
WINPROC_AllocProc
(
(
WNDPROC
)
newval
,
WIN_PROC_16
);
WNDPROC
new_proc
=
WINPROC_AllocProc
16
(
(
WNDPROC16
)
newval
);
WNDPROC
old_proc
=
(
WNDPROC
)
SetWindowLongA
(
WIN_Handle32
(
hwnd
),
offset
,
(
LONG_PTR
)
new_proc
);
return
(
LONG
)
WINPROC_GetProc16
(
(
WNDPROC
)
old_proc
);
}
...
...
dlls/user/winproc.c
View file @
41b5e687
...
...
@@ -22,6 +22,7 @@
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
...
...
@@ -142,99 +143,88 @@ static BOOL is_valid_winproc( WINDOWPROC *proc )
return
(
proc
->
type
!=
WIN_PROC_INVALID
);
}
/* find an existing winproc for a given function and type */
/* find an existing winproc for a given
16-bit
function and type */
/* FIXME: probably should do something more clever than a linear search */
static
inline
WINDOWPROC
*
find_winproc
(
WNDPROC
func
,
WINDOWPROCTYPE
type
)
static
inline
WINDOWPROC
*
find_winproc
16
(
WNDPROC16
func
)
{
unsigned
int
i
;
if
(
type
==
WIN_PROC_16
)
for
(
i
=
0
;
i
<
winproc_used
;
i
++
)
{
for
(
i
=
0
;
i
<
winproc_used
;
i
++
)
{
if
(
winproc_array
[
i
].
type
==
type
&&
winproc_array
[
i
].
thunk
.
t_from32
.
proc
==
(
WNDPROC16
)
func
)
return
&
winproc_array
[
i
];
}
if
(
winproc_array
[
i
].
type
==
WIN_PROC_16
&&
winproc_array
[
i
].
thunk
.
t_from32
.
proc
==
func
)
return
&
winproc_array
[
i
];
}
else
return
NULL
;
}
/* find an existing winproc for a given function and type */
/* FIXME: probably should do something more clever than a linear search */
static
inline
WINDOWPROC
*
find_winproc
(
WNDPROC
func
,
WINDOWPROCTYPE
type
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
winproc_used
;
i
++
)
{
for
(
i
=
0
;
i
<
winproc_used
;
i
++
)
{
if
(
winproc_array
[
i
].
type
==
type
&&
winproc_array
[
i
].
thunk
.
t_from16
.
proc
==
func
)
return
&
winproc_array
[
i
];
}
if
(
winproc_array
[
i
].
type
==
type
&&
winproc_array
[
i
].
thunk
.
t_from16
.
proc
==
func
)
return
&
winproc_array
[
i
];
}
return
NULL
;
}
/* initialize a new 16-bit winproc */
static
inline
void
set_winproc16
(
WINDOWPROC
*
proc
,
WNDPROC16
func
)
{
#ifdef __i386__
proc
->
thunk
.
t_from32
.
popl_eax
=
0x58
;
/* popl %eax */
proc
->
thunk
.
t_from32
.
pushl_func
=
0x68
;
/* pushl $proc */
proc
->
thunk
.
t_from32
.
proc
=
func
;
proc
->
thunk
.
t_from32
.
pushl_eax
=
0x50
;
/* pushl %eax */
proc
->
thunk
.
t_from32
.
jmp
=
0xe9
;
/* jmp relay*/
proc
->
thunk
.
t_from32
.
relay
=
/* relative jump */
(
void
(
*
)())((
DWORD
)
WINPROC_CallProc32ATo16
-
(
DWORD
)(
&
proc
->
thunk
.
t_from32
.
relay
+
1
));
#else
/* __i386__ */
proc
->
thunk
.
t_from32
.
proc
=
func
;
#endif
/* __i386__ */
proc
->
type
=
WIN_PROC_16
;
}
/* initialize a new winproc */
static
inline
void
set_winproc
(
WINDOWPROC
*
proc
,
WNDPROC
func
,
WINDOWPROCTYPE
type
)
{
#ifdef __i386__
static
FARPROC16
relay_32A
,
relay_32W
;
proc
->
thunk
.
t_from16
.
popl_eax
=
0x58
;
/* popl %eax */
proc
->
thunk
.
t_from16
.
pushl_func
=
0x68
;
/* pushl $proc */
proc
->
thunk
.
t_from16
.
proc
=
func
;
proc
->
thunk
.
t_from16
.
pushl_eax
=
0x50
;
/* pushl %eax */
proc
->
thunk
.
t_from16
.
ljmp
=
0xea
;
/* ljmp relay*/
switch
(
type
)
{
case
WIN_PROC_16
:
proc
->
thunk
.
t_from32
.
popl_eax
=
0x58
;
/* popl %eax */
proc
->
thunk
.
t_from32
.
pushl_func
=
0x68
;
/* pushl $proc */
proc
->
thunk
.
t_from32
.
proc
=
(
WNDPROC16
)
func
;
proc
->
thunk
.
t_from32
.
pushl_eax
=
0x50
;
/* pushl %eax */
proc
->
thunk
.
t_from32
.
jmp
=
0xe9
;
/* jmp relay*/
proc
->
thunk
.
t_from32
.
relay
=
/* relative jump */
(
void
(
*
)())((
DWORD
)
WINPROC_CallProc32ATo16
-
(
DWORD
)(
&
proc
->
thunk
.
t_from32
.
relay
+
1
));
break
;
case
WIN_PROC_32A
:
if
(
!
relay_32A
)
relay_32A
=
GetProcAddress16
(
GetModuleHandle16
(
"user"
),
"__wine_call_wndproc_32A"
);
proc
->
thunk
.
t_from16
.
popl_eax
=
0x58
;
/* popl %eax */
proc
->
thunk
.
t_from16
.
pushl_func
=
0x68
;
/* pushl $proc */
proc
->
thunk
.
t_from16
.
proc
=
func
;
proc
->
thunk
.
t_from16
.
pushl_eax
=
0x50
;
/* pushl %eax */
proc
->
thunk
.
t_from16
.
ljmp
=
0xea
;
/* ljmp relay*/
proc
->
thunk
.
t_from16
.
relay_offset
=
OFFSETOF
(
relay_32A
);
proc
->
thunk
.
t_from16
.
relay_sel
=
SELECTOROF
(
relay_32A
);
proc
->
jmp
.
jmp
=
0xe9
;
/* Fixup relative jump */
proc
->
jmp
.
proc
=
(
WNDPROC
)((
DWORD
)
func
-
(
DWORD
)(
&
proc
->
jmp
.
proc
+
1
));
break
;
case
WIN_PROC_32W
:
if
(
!
relay_32W
)
relay_32W
=
GetProcAddress16
(
GetModuleHandle16
(
"user"
),
"__wine_call_wndproc_32W"
);
proc
->
thunk
.
t_from16
.
popl_eax
=
0x58
;
/* popl %eax */
proc
->
thunk
.
t_from16
.
pushl_func
=
0x68
;
/* pushl $proc */
proc
->
thunk
.
t_from16
.
proc
=
func
;
proc
->
thunk
.
t_from16
.
pushl_eax
=
0x50
;
/* pushl %eax */
proc
->
thunk
.
t_from16
.
ljmp
=
0xea
;
/* ljmp relay*/
proc
->
thunk
.
t_from16
.
relay_offset
=
OFFSETOF
(
relay_32W
);
proc
->
thunk
.
t_from16
.
relay_sel
=
SELECTOROF
(
relay_32W
);
proc
->
jmp
.
jmp
=
0xe9
;
/* Fixup relative jump */
proc
->
jmp
.
proc
=
(
WNDPROC
)((
char
*
)
func
-
(
char
*
)(
&
proc
->
jmp
.
proc
+
1
));
break
;
default:
/* Should not happen */
assert
(
0
);
break
;
}
proc
->
jmp
.
jmp
=
0xe9
;
/* Fixup relative jump */
proc
->
jmp
.
proc
=
(
WNDPROC
)((
DWORD
)
func
-
(
DWORD
)(
&
proc
->
jmp
.
proc
+
1
));
#else
/* __i386__ */
switch
(
type
)
{
case
WIN_PROC_16
:
proc
->
thunk
.
t_from32
.
proc
=
(
WNDPROC16
)
func
;
break
;
case
WIN_PROC_32A
:
case
WIN_PROC_32W
:
proc
->
thunk
.
t_from16
.
proc
=
func
;
break
;
default:
/* Should not happen */
break
;
}
proc
->
thunk
.
t_from16
.
proc
=
func
;
#endif
/* __i386__ */
proc
->
type
=
type
;
}
...
...
@@ -570,6 +560,47 @@ WNDPROC WINPROC_GetProc( WNDPROC proc, WINDOWPROCTYPE type )
/**********************************************************************
* WINPROC_AllocProc16
*
* Allocate a window procedure for a window or class.
*
* Note that allocated winprocs are never freed; the idea is that even if an app creates a
* lot of windows, it will usually only have a limited number of window procedures, so the
* array won't grow too large, and this way we avoid the need to track allocations per window.
*/
WNDPROC
WINPROC_AllocProc16
(
WNDPROC16
func
)
{
WINDOWPROC
*
proc
;
if
(
!
func
)
return
NULL
;
EnterCriticalSection
(
&
winproc_cs
);
/* check if the function is already a win proc */
if
(
!
(
proc
=
WINPROC_GetPtr
(
(
WNDPROC
)
func
)))
{
/* then check if we already have a winproc for that function */
if
(
!
(
proc
=
find_winproc16
(
func
)))
{
if
(
winproc_used
>=
MAX_WINPROCS
)
FIXME
(
"too many winprocs, cannot allocate one for 16-bit %p
\n
"
,
func
);
else
{
proc
=
&
winproc_array
[
winproc_used
++
];
set_winproc16
(
proc
,
func
);
TRACE
(
"allocated %p for %p/16-bit (%d/%d used)
\n
"
,
proc
,
func
,
winproc_used
,
MAX_WINPROCS
);
}
}
else
TRACE
(
"reusing %p for %p/16-bit
\n
"
,
proc
,
func
);
}
LeaveCriticalSection
(
&
winproc_cs
);
return
(
WNDPROC
)
proc
;
}
/**********************************************************************
* WINPROC_AllocProc
*
* Allocate a window procedure for a window or class.
...
...
dlls/user/winproc.h
View file @
41b5e687
...
...
@@ -53,6 +53,7 @@ typedef struct
struct
tagWINDOWPROC
;
extern
WNDPROC16
WINPROC_GetProc16
(
WNDPROC
proc
);
extern
WNDPROC
WINPROC_AllocProc16
(
WNDPROC16
func
);
extern
WNDPROC
WINPROC_GetProc
(
WNDPROC
proc
,
WINDOWPROCTYPE
type
);
extern
WNDPROC
WINPROC_AllocProc
(
WNDPROC
func
,
WINDOWPROCTYPE
type
);
extern
WINDOWPROCTYPE
WINPROC_GetProcType
(
WNDPROC
proc
);
...
...
dlls/user/wnd16.c
View file @
41b5e687
...
...
@@ -72,7 +72,7 @@ INT16 WINAPI MessageBox16( HWND16 hwnd, LPCSTR text, LPCSTR title, UINT16 type )
*/
UINT16
WINAPI
SetTimer16
(
HWND16
hwnd
,
UINT16
id
,
UINT16
timeout
,
TIMERPROC16
proc
)
{
TIMERPROC
proc32
=
(
TIMERPROC
)
WINPROC_AllocProc
(
(
WNDPROC
)
proc
,
WIN_PROC_16
);
TIMERPROC
proc32
=
(
TIMERPROC
)
WINPROC_AllocProc
16
(
(
WNDPROC16
)
proc
);
return
SetTimer
(
WIN_Handle32
(
hwnd
),
id
,
timeout
,
proc32
);
}
...
...
@@ -82,7 +82,7 @@ UINT16 WINAPI SetTimer16( HWND16 hwnd, UINT16 id, UINT16 timeout, TIMERPROC16 pr
*/
UINT16
WINAPI
SetSystemTimer16
(
HWND16
hwnd
,
UINT16
id
,
UINT16
timeout
,
TIMERPROC16
proc
)
{
TIMERPROC
proc32
=
(
TIMERPROC
)
WINPROC_AllocProc
(
(
WNDPROC
)
proc
,
WIN_PROC_16
);
TIMERPROC
proc32
=
(
TIMERPROC
)
WINPROC_AllocProc
16
(
(
WNDPROC16
)
proc
);
return
SetSystemTimer
(
WIN_Handle32
(
hwnd
),
id
,
timeout
,
proc32
);
}
...
...
@@ -1323,7 +1323,7 @@ ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
wc32
.
cbSize
=
sizeof
(
wc32
);
wc32
.
style
=
wc
->
style
;
wc32
.
lpfnWndProc
=
WINPROC_AllocProc
(
(
WNDPROC
)
wc
->
lpfnWndProc
,
WIN_PROC_16
);
wc32
.
lpfnWndProc
=
WINPROC_AllocProc
16
(
wc
->
lpfnWndProc
);
wc32
.
cbClsExtra
=
wc
->
cbClsExtra
;
wc32
.
cbWndExtra
=
wc
->
cbWndExtra
;
wc32
.
hInstance
=
HINSTANCE_32
(
GetExePtr
(
wc
->
hInstance
));
...
...
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