user: Support storing multiple winprocs in a single winproc handle.
Allows to remove special cases for window classes being Ascii and Unicode at the same time.
This commit is contained in:
parent
2a809c195d
commit
0667292eb5
|
@ -48,8 +48,7 @@ typedef struct tagCLASS
|
||||||
struct list entry; /* Entry in class list */
|
struct list entry; /* Entry in class list */
|
||||||
UINT style; /* Class style */
|
UINT style; /* Class style */
|
||||||
BOOL local; /* Local class? */
|
BOOL local; /* Local class? */
|
||||||
WNDPROC winprocA; /* Window procedure (ASCII) */
|
WNDPROC winproc; /* Window procedure */
|
||||||
WNDPROC winprocW; /* Window procedure (Unicode) */
|
|
||||||
INT cbClsExtra; /* Class extra bytes */
|
INT cbClsExtra; /* Class extra bytes */
|
||||||
INT cbWndExtra; /* Window extra bytes */
|
INT cbWndExtra; /* Window extra bytes */
|
||||||
LPWSTR menuName; /* Default menu name (Unicode followed by ASCII) */
|
LPWSTR menuName; /* Default menu name (Unicode followed by ASCII) */
|
||||||
|
@ -143,49 +142,6 @@ static BOOL set_server_info( HWND hwnd, INT offset, LONG newval )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* CLASS_GetProc
|
|
||||||
*
|
|
||||||
* Get the class winproc for a given proc type
|
|
||||||
*/
|
|
||||||
static WNDPROC CLASS_GetProc( CLASS *classPtr, BOOL unicode )
|
|
||||||
{
|
|
||||||
WNDPROC proc = classPtr->winprocA;
|
|
||||||
|
|
||||||
if (classPtr->winprocW)
|
|
||||||
{
|
|
||||||
/* if we have a Unicode proc, use it if we have no ASCII proc
|
|
||||||
* or if we have both and Unicode was requested
|
|
||||||
*/
|
|
||||||
if (!proc || unicode) proc = classPtr->winprocW;
|
|
||||||
}
|
|
||||||
return WINPROC_GetProc( proc, unicode );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* CLASS_SetProc
|
|
||||||
*
|
|
||||||
* Set the class winproc for a given proc type.
|
|
||||||
* Returns the previous window proc.
|
|
||||||
*/
|
|
||||||
static void CLASS_SetProc( CLASS *classPtr, WNDPROC newproc, BOOL unicode )
|
|
||||||
{
|
|
||||||
WNDPROC proc = WINPROC_AllocProc( newproc, unicode );
|
|
||||||
|
|
||||||
if (WINPROC_IsUnicode( proc, unicode ))
|
|
||||||
{
|
|
||||||
classPtr->winprocA = 0;
|
|
||||||
classPtr->winprocW = proc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
classPtr->winprocA = proc;
|
|
||||||
classPtr->winprocW = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CLASS_GetMenuNameA
|
* CLASS_GetMenuNameA
|
||||||
*
|
*
|
||||||
|
@ -417,9 +373,7 @@ static CLASS *register_builtin( const struct builtin_class_descr *descr )
|
||||||
|
|
||||||
classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor );
|
classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor );
|
||||||
classPtr->hbrBackground = descr->brush;
|
classPtr->hbrBackground = descr->brush;
|
||||||
|
classPtr->winproc = WINPROC_AllocProc( descr->procA, descr->procW );
|
||||||
if (descr->procA) classPtr->winprocA = WINPROC_AllocProc( descr->procA, FALSE );
|
|
||||||
if (descr->procW) classPtr->winprocW = WINPROC_AllocProc( descr->procW, TRUE );
|
|
||||||
release_class_ptr( classPtr );
|
release_class_ptr( classPtr );
|
||||||
return classPtr;
|
return classPtr;
|
||||||
}
|
}
|
||||||
|
@ -466,16 +420,9 @@ void CLASS_RegisterBuiltinClasses(void)
|
||||||
*/
|
*/
|
||||||
void CLASS_AddWindow( CLASS *class, WND *win, BOOL unicode )
|
void CLASS_AddWindow( CLASS *class, WND *win, BOOL unicode )
|
||||||
{
|
{
|
||||||
if (unicode)
|
|
||||||
{
|
|
||||||
if (!(win->winproc = class->winprocW)) win->winproc = class->winprocA;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(win->winproc = class->winprocA)) win->winproc = class->winprocW;
|
|
||||||
}
|
|
||||||
win->class = class;
|
win->class = class;
|
||||||
win->clsStyle = class->style;
|
win->clsStyle = class->style;
|
||||||
|
win->winproc = class->winproc;
|
||||||
if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= WIN_ISUNICODE;
|
if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= WIN_ISUNICODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +512,7 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
||||||
classPtr->hIconSm = wc->hIconSm;
|
classPtr->hIconSm = wc->hIconSm;
|
||||||
classPtr->hCursor = wc->hCursor;
|
classPtr->hCursor = wc->hCursor;
|
||||||
classPtr->hbrBackground = wc->hbrBackground;
|
classPtr->hbrBackground = wc->hbrBackground;
|
||||||
classPtr->winprocA = WINPROC_AllocProc( wc->lpfnWndProc, FALSE );
|
classPtr->winproc = WINPROC_AllocProc( wc->lpfnWndProc, NULL );
|
||||||
CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
|
CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
|
||||||
release_class_ptr( classPtr );
|
release_class_ptr( classPtr );
|
||||||
return atom;
|
return atom;
|
||||||
|
@ -603,7 +550,7 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
|
||||||
classPtr->hIconSm = wc->hIconSm;
|
classPtr->hIconSm = wc->hIconSm;
|
||||||
classPtr->hCursor = wc->hCursor;
|
classPtr->hCursor = wc->hCursor;
|
||||||
classPtr->hbrBackground = wc->hbrBackground;
|
classPtr->hbrBackground = wc->hbrBackground;
|
||||||
classPtr->winprocW = WINPROC_AllocProc( wc->lpfnWndProc, TRUE );
|
classPtr->winproc = WINPROC_AllocProc( NULL, wc->lpfnWndProc );
|
||||||
CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
|
CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
|
||||||
release_class_ptr( classPtr );
|
release_class_ptr( classPtr );
|
||||||
return atom;
|
return atom;
|
||||||
|
@ -782,7 +729,7 @@ DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
|
||||||
retvalue = (DWORD)class->hInstance;
|
retvalue = (DWORD)class->hInstance;
|
||||||
break;
|
break;
|
||||||
case GCLP_WNDPROC:
|
case GCLP_WNDPROC:
|
||||||
retvalue = (DWORD)CLASS_GetProc( class, TRUE );
|
retvalue = (DWORD)WINPROC_GetProc( class->winproc, TRUE );
|
||||||
break;
|
break;
|
||||||
case GCLP_MENUNAME:
|
case GCLP_MENUNAME:
|
||||||
retvalue = (DWORD)CLASS_GetMenuNameW( class );
|
retvalue = (DWORD)CLASS_GetMenuNameW( class );
|
||||||
|
@ -822,7 +769,7 @@ DWORD WINAPI GetClassLongA( HWND hwnd, INT offset )
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == GCLP_WNDPROC)
|
if (offset == GCLP_WNDPROC)
|
||||||
retvalue = (DWORD)CLASS_GetProc( class, FALSE );
|
retvalue = (DWORD)WINPROC_GetProc( class->winproc, FALSE );
|
||||||
else /* GCL_MENUNAME */
|
else /* GCL_MENUNAME */
|
||||||
retvalue = (DWORD)CLASS_GetMenuNameA( class );
|
retvalue = (DWORD)CLASS_GetMenuNameA( class );
|
||||||
|
|
||||||
|
@ -893,8 +840,8 @@ DWORD WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
|
||||||
retval = 0; /* Old value is now meaningless anyway */
|
retval = 0; /* Old value is now meaningless anyway */
|
||||||
break;
|
break;
|
||||||
case GCLP_WNDPROC:
|
case GCLP_WNDPROC:
|
||||||
retval = (DWORD)CLASS_GetProc( class, TRUE );
|
retval = (DWORD)WINPROC_GetProc( class->winproc, TRUE );
|
||||||
CLASS_SetProc( class, (WNDPROC)newval, TRUE );
|
class->winproc = WINPROC_AllocProc( NULL, (WNDPROC)newval );
|
||||||
break;
|
break;
|
||||||
case GCLP_HBRBACKGROUND:
|
case GCLP_HBRBACKGROUND:
|
||||||
retval = (DWORD)class->hbrBackground;
|
retval = (DWORD)class->hbrBackground;
|
||||||
|
@ -961,8 +908,8 @@ DWORD WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
|
||||||
|
|
||||||
if (offset == GCLP_WNDPROC)
|
if (offset == GCLP_WNDPROC)
|
||||||
{
|
{
|
||||||
retval = (DWORD)CLASS_GetProc( class, FALSE );
|
retval = (DWORD)WINPROC_GetProc( class->winproc, FALSE );
|
||||||
CLASS_SetProc( class, (WNDPROC)newval, FALSE );
|
class->winproc = WINPROC_AllocProc( (WNDPROC)newval, NULL );
|
||||||
}
|
}
|
||||||
else /* GCL_MENUNAME */
|
else /* GCL_MENUNAME */
|
||||||
{
|
{
|
||||||
|
@ -1084,7 +1031,7 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, WNDCLASSEXA *wc )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
wc->style = classPtr->style;
|
wc->style = classPtr->style;
|
||||||
wc->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, FALSE );
|
wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, FALSE );
|
||||||
wc->cbClsExtra = classPtr->cbClsExtra;
|
wc->cbClsExtra = classPtr->cbClsExtra;
|
||||||
wc->cbWndExtra = classPtr->cbWndExtra;
|
wc->cbWndExtra = classPtr->cbWndExtra;
|
||||||
wc->hInstance = (hInstance == user32_module) ? 0 : hInstance;
|
wc->hInstance = (hInstance == user32_module) ? 0 : hInstance;
|
||||||
|
@ -1119,7 +1066,7 @@ BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSEXW *wc
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
wc->style = classPtr->style;
|
wc->style = classPtr->style;
|
||||||
wc->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, TRUE );
|
wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, TRUE );
|
||||||
wc->cbClsExtra = classPtr->cbClsExtra;
|
wc->cbClsExtra = classPtr->cbClsExtra;
|
||||||
wc->cbWndExtra = classPtr->cbWndExtra;
|
wc->cbWndExtra = classPtr->cbWndExtra;
|
||||||
wc->hInstance = (hInstance == user32_module) ? 0 : hInstance;
|
wc->hInstance = (hInstance == user32_module) ? 0 : hInstance;
|
||||||
|
|
|
@ -3338,7 +3338,7 @@ UINT_PTR WINAPI SetTimer( HWND hwnd, UINT_PTR id, UINT timeout, TIMERPROC proc )
|
||||||
UINT_PTR ret;
|
UINT_PTR ret;
|
||||||
WNDPROC winproc = 0;
|
WNDPROC winproc = 0;
|
||||||
|
|
||||||
if (proc) winproc = WINPROC_AllocProc( (WNDPROC)proc, FALSE );
|
if (proc) winproc = WINPROC_AllocProc( (WNDPROC)proc, NULL );
|
||||||
|
|
||||||
SERVER_START_REQ( set_win_timer )
|
SERVER_START_REQ( set_win_timer )
|
||||||
{
|
{
|
||||||
|
@ -3369,7 +3369,7 @@ UINT_PTR WINAPI SetSystemTimer( HWND hwnd, UINT_PTR id, UINT timeout, TIMERPROC
|
||||||
UINT_PTR ret;
|
UINT_PTR ret;
|
||||||
WNDPROC winproc = 0;
|
WNDPROC winproc = 0;
|
||||||
|
|
||||||
if (proc) winproc = WINPROC_AllocProc( (WNDPROC)proc, FALSE );
|
if (proc) winproc = WINPROC_AllocProc( (WNDPROC)proc, NULL );
|
||||||
|
|
||||||
SERVER_START_REQ( set_win_timer )
|
SERVER_START_REQ( set_win_timer )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1987,7 +1987,8 @@ static LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, LONG_PTR newval, BOOL
|
||||||
{
|
{
|
||||||
UINT old_flags = wndPtr->flags;
|
UINT old_flags = wndPtr->flags;
|
||||||
retval = (ULONG_PTR)WINPROC_GetProc( wndPtr->winproc, unicode );
|
retval = (ULONG_PTR)WINPROC_GetProc( wndPtr->winproc, unicode );
|
||||||
wndPtr->winproc = WINPROC_AllocProc( (WNDPROC)newval, unicode );
|
if (unicode) wndPtr->winproc = WINPROC_AllocProc( NULL, (WNDPROC)newval );
|
||||||
|
else wndPtr->winproc = WINPROC_AllocProc( (WNDPROC)newval, NULL );
|
||||||
if (WINPROC_IsUnicode( wndPtr->winproc, unicode )) wndPtr->flags |= WIN_ISUNICODE;
|
if (WINPROC_IsUnicode( wndPtr->winproc, unicode )) wndPtr->flags |= WIN_ISUNICODE;
|
||||||
else wndPtr->flags &= ~WIN_ISUNICODE;
|
else wndPtr->flags &= ~WIN_ISUNICODE;
|
||||||
if (!((old_flags ^ wndPtr->flags) & WIN_ISUNICODE))
|
if (!((old_flags ^ wndPtr->flags) & WIN_ISUNICODE))
|
||||||
|
@ -2007,7 +2008,8 @@ static LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, LONG_PTR newval, BOOL
|
||||||
{
|
{
|
||||||
WNDPROC *ptr = (WNDPROC *)((char *)wndPtr->wExtra + DWLP_DLGPROC);
|
WNDPROC *ptr = (WNDPROC *)((char *)wndPtr->wExtra + DWLP_DLGPROC);
|
||||||
retval = (ULONG_PTR)WINPROC_GetProc( *ptr, unicode );
|
retval = (ULONG_PTR)WINPROC_GetProc( *ptr, unicode );
|
||||||
*ptr = WINPROC_AllocProc( (WNDPROC)newval, unicode );
|
if (unicode) *ptr = WINPROC_AllocProc( NULL, (WNDPROC)newval );
|
||||||
|
else *ptr = WINPROC_AllocProc( (WNDPROC)newval, NULL );
|
||||||
WIN_ReleasePtr( wndPtr );
|
WIN_ReleasePtr( wndPtr );
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,25 +46,14 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
||||||
|
|
||||||
typedef struct tagWINDOWPROC
|
typedef struct tagWINDOWPROC
|
||||||
{
|
|
||||||
BYTE type; /* Function type */
|
|
||||||
union
|
|
||||||
{
|
{
|
||||||
WNDPROC16 proc16; /* 16-bit window proc */
|
WNDPROC16 proc16; /* 16-bit window proc */
|
||||||
WNDPROC proc32; /* 32-bit window proc */
|
WNDPROC procA; /* ASCII window proc */
|
||||||
} u;
|
WNDPROC procW; /* Unicode window proc */
|
||||||
} WINDOWPROC;
|
} WINDOWPROC;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
WIN_PROC_INVALID,
|
|
||||||
WIN_PROC_16,
|
|
||||||
WIN_PROC_32A,
|
|
||||||
WIN_PROC_32W
|
|
||||||
} WINDOWPROCTYPE;
|
|
||||||
|
|
||||||
#define WINPROC_HANDLE (~0UL >> 16)
|
#define WINPROC_HANDLE (~0UL >> 16)
|
||||||
#define MAX_WINPROCS (0x10000 / sizeof(WINDOWPROC))
|
#define MAX_WINPROCS 8192
|
||||||
|
|
||||||
static WINDOWPROC winproc_array[MAX_WINPROCS];
|
static WINDOWPROC winproc_array[MAX_WINPROCS];
|
||||||
static UINT winproc_used;
|
static UINT winproc_used;
|
||||||
|
@ -86,37 +75,26 @@ static inline WINDOWPROC *find_winproc16( WNDPROC16 func )
|
||||||
|
|
||||||
for (i = 0; i < winproc_used; i++)
|
for (i = 0; i < winproc_used; i++)
|
||||||
{
|
{
|
||||||
if (winproc_array[i].type == WIN_PROC_16 && winproc_array[i].u.proc16 == func)
|
if (winproc_array[i].proc16 == func) return &winproc_array[i];
|
||||||
return &winproc_array[i];
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find an existing winproc for a given function and type */
|
/* find an existing winproc for a given function and type */
|
||||||
/* FIXME: probably should do something more clever than a linear search */
|
/* FIXME: probably should do something more clever than a linear search */
|
||||||
static inline WINDOWPROC *find_winproc( WNDPROC func, BOOL unicode )
|
static inline WINDOWPROC *find_winproc( WNDPROC funcA, WNDPROC funcW )
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < winproc_used; i++)
|
for (i = 0; i < winproc_used; i++)
|
||||||
{
|
{
|
||||||
if (winproc_array[i].u.proc32 == func &&
|
if (funcA && winproc_array[i].procA != funcA) continue;
|
||||||
winproc_array[i].type == (unicode ? WIN_PROC_32W : WIN_PROC_32A))
|
if (funcW && winproc_array[i].procW != funcW) continue;
|
||||||
return &winproc_array[i];
|
return &winproc_array[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize a new winproc */
|
|
||||||
static inline WINDOWPROC *init_winproc(void)
|
|
||||||
{
|
|
||||||
WINDOWPROC *proc;
|
|
||||||
|
|
||||||
if (winproc_used >= MAX_WINPROCS) return NULL;
|
|
||||||
proc = &winproc_array[winproc_used++];
|
|
||||||
return proc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return the window proc for a given handle, or NULL for an invalid handle */
|
/* return the window proc for a given handle, or NULL for an invalid handle */
|
||||||
static inline WINDOWPROC *handle_to_proc( WNDPROC handle )
|
static inline WINDOWPROC *handle_to_proc( WNDPROC handle )
|
||||||
{
|
{
|
||||||
|
@ -133,30 +111,31 @@ static inline WNDPROC proc_to_handle( WINDOWPROC *proc )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate and initialize a new winproc */
|
/* allocate and initialize a new winproc */
|
||||||
static inline WINDOWPROC *alloc_winproc( WNDPROC func, BOOL unicode )
|
static inline WINDOWPROC *alloc_winproc( WNDPROC funcA, WNDPROC funcW )
|
||||||
{
|
{
|
||||||
WINDOWPROC *proc;
|
WINDOWPROC *proc;
|
||||||
|
|
||||||
if (!func) return NULL;
|
|
||||||
|
|
||||||
/* check if the function is already a win proc */
|
/* check if the function is already a win proc */
|
||||||
if ((proc = handle_to_proc( func ))) return proc;
|
if (funcA && (proc = handle_to_proc( funcA ))) return proc;
|
||||||
|
if (funcW && (proc = handle_to_proc( funcW ))) return proc;
|
||||||
|
if (!funcA && !funcW) return NULL;
|
||||||
|
|
||||||
EnterCriticalSection( &winproc_cs );
|
EnterCriticalSection( &winproc_cs );
|
||||||
|
|
||||||
/* check if we already have a winproc for that function */
|
/* check if we already have a winproc for that function */
|
||||||
if (!(proc = find_winproc( func, unicode )))
|
if (!(proc = find_winproc( funcA, funcW )))
|
||||||
{
|
{
|
||||||
if ((proc = init_winproc()))
|
if (winproc_used < MAX_WINPROCS)
|
||||||
{
|
{
|
||||||
proc->type = unicode ? WIN_PROC_32W : WIN_PROC_32A;
|
proc = &winproc_array[winproc_used++];
|
||||||
proc->u.proc32 = func;
|
proc->procA = funcA;
|
||||||
TRACE( "allocated %p for %p %c (%d/%d used)\n",
|
proc->procW = funcW;
|
||||||
proc_to_handle(proc), func, unicode ? 'W' : 'A', winproc_used, MAX_WINPROCS );
|
TRACE( "allocated %p for %p/%p (%d/%d used)\n",
|
||||||
|
proc_to_handle(proc), funcA, funcW, winproc_used, MAX_WINPROCS );
|
||||||
}
|
}
|
||||||
else FIXME( "too many winprocs, cannot allocate one for %p %c\n", func, unicode ? 'W' : 'A' );
|
else FIXME( "too many winprocs, cannot allocate one for %p/%p\n", funcA, funcW );
|
||||||
}
|
}
|
||||||
else TRACE( "reusing %p for %p %c\n", proc_to_handle(proc), func, unicode ? 'W' : 'A' );
|
else TRACE( "reusing %p for %p/%p\n", proc_to_handle(proc), funcA, funcW );
|
||||||
|
|
||||||
LeaveCriticalSection( &winproc_cs );
|
LeaveCriticalSection( &winproc_cs );
|
||||||
return proc;
|
return proc;
|
||||||
|
@ -206,9 +185,10 @@ static inline WINDOWPROC *handle16_to_proc( WNDPROC16 handle )
|
||||||
static WNDPROC16 alloc_win16_thunk( WINDOWPROC *proc )
|
static WNDPROC16 alloc_win16_thunk( WINDOWPROC *proc )
|
||||||
{
|
{
|
||||||
static FARPROC16 relay;
|
static FARPROC16 relay;
|
||||||
WNDPROC16 ret = 0;
|
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
|
if (proc->proc16) return proc->proc16;
|
||||||
|
|
||||||
EnterCriticalSection( &winproc_cs );
|
EnterCriticalSection( &winproc_cs );
|
||||||
|
|
||||||
if (!thunk_array) /* allocate the array and its selector */
|
if (!thunk_array) /* allocate the array and its selector */
|
||||||
|
@ -242,10 +222,10 @@ static WNDPROC16 alloc_win16_thunk( WINDOWPROC *proc )
|
||||||
thunk->relay_offset = OFFSETOF(relay);
|
thunk->relay_offset = OFFSETOF(relay);
|
||||||
thunk->relay_sel = SELECTOROF(relay);
|
thunk->relay_sel = SELECTOROF(relay);
|
||||||
}
|
}
|
||||||
ret = (WNDPROC16)MAKESEGPTR( thunk_selector, i * sizeof(WINPROC_THUNK) );
|
proc->proc16 = (WNDPROC16)MAKESEGPTR( thunk_selector, i * sizeof(WINPROC_THUNK) );
|
||||||
done:
|
done:
|
||||||
LeaveCriticalSection( &winproc_cs );
|
LeaveCriticalSection( &winproc_cs );
|
||||||
return ret;
|
return proc->proc16;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* __i386__ */
|
#else /* __i386__ */
|
||||||
|
@ -503,13 +483,12 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
|
||||||
*/
|
*/
|
||||||
WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode )
|
WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode )
|
||||||
{
|
{
|
||||||
WINDOWPROC *ptr = alloc_winproc( proc, unicode );
|
WINDOWPROC *ptr;
|
||||||
|
|
||||||
|
if (unicode) ptr = alloc_winproc( NULL, proc );
|
||||||
|
else ptr = alloc_winproc( proc, NULL );
|
||||||
|
|
||||||
if (!ptr) return 0;
|
if (!ptr) return 0;
|
||||||
|
|
||||||
if (ptr->type == WIN_PROC_16)
|
|
||||||
return ptr->u.proc16;
|
|
||||||
else
|
|
||||||
return alloc_win16_thunk( ptr );
|
return alloc_win16_thunk( ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,8 +502,17 @@ WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode )
|
||||||
{
|
{
|
||||||
WINDOWPROC *ptr = handle_to_proc( proc );
|
WINDOWPROC *ptr = handle_to_proc( proc );
|
||||||
|
|
||||||
if (!ptr || ptr->type != (unicode ? WIN_PROC_32W : WIN_PROC_32A)) return proc;
|
if (!ptr) return proc;
|
||||||
return ptr->u.proc32; /* we can return the original proc in that case */
|
if (unicode)
|
||||||
|
{
|
||||||
|
if (ptr->procW) return ptr->procW;
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ptr->procA) return ptr->procA;
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -551,10 +539,10 @@ WNDPROC WINPROC_AllocProc16( WNDPROC16 func )
|
||||||
/* then check if we already have a winproc for that function */
|
/* then check if we already have a winproc for that function */
|
||||||
if (!(proc = find_winproc16( func )))
|
if (!(proc = find_winproc16( func )))
|
||||||
{
|
{
|
||||||
if ((proc = init_winproc()))
|
if (winproc_used < MAX_WINPROCS)
|
||||||
{
|
{
|
||||||
proc->type = WIN_PROC_16;
|
proc = &winproc_array[winproc_used++];
|
||||||
proc->u.proc16 = func;
|
proc->proc16 = func;
|
||||||
TRACE( "allocated %p for %p/16-bit (%d/%d used)\n",
|
TRACE( "allocated %p for %p/16-bit (%d/%d used)\n",
|
||||||
proc_to_handle(proc), func, winproc_used, MAX_WINPROCS );
|
proc_to_handle(proc), func, winproc_used, MAX_WINPROCS );
|
||||||
}
|
}
|
||||||
|
@ -577,11 +565,11 @@ WNDPROC WINPROC_AllocProc16( WNDPROC16 func )
|
||||||
* lot of windows, it will usually only have a limited number of window procedures, so the
|
* 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.
|
* array won't grow too large, and this way we avoid the need to track allocations per window.
|
||||||
*/
|
*/
|
||||||
WNDPROC WINPROC_AllocProc( WNDPROC func, BOOL unicode )
|
WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW )
|
||||||
{
|
{
|
||||||
WINDOWPROC *proc;
|
WINDOWPROC *proc;
|
||||||
|
|
||||||
if (!(proc = alloc_winproc( func, unicode ))) return NULL;
|
if (!(proc = alloc_winproc( funcA, funcW ))) return NULL;
|
||||||
return proc_to_handle( proc );
|
return proc_to_handle( proc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +584,8 @@ BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val )
|
||||||
WINDOWPROC *ptr = handle_to_proc( proc );
|
WINDOWPROC *ptr = handle_to_proc( proc );
|
||||||
|
|
||||||
if (!ptr) return def_val;
|
if (!ptr) return def_val;
|
||||||
return (ptr->type == WIN_PROC_32W);
|
if (ptr->procA && ptr->procW) return def_val; /* can be both */
|
||||||
|
return (ptr->procW != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3136,18 +3125,8 @@ static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd, UINT16 msg,
|
||||||
LRESULT WINAPI __wine_call_wndproc( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
|
LRESULT WINAPI __wine_call_wndproc( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam,
|
||||||
WINDOWPROC *proc )
|
WINDOWPROC *proc )
|
||||||
{
|
{
|
||||||
switch(proc->type)
|
if (proc->procA) return WINPROC_CallProc16To32A( proc->procA, hwnd, msg, wParam, lParam );
|
||||||
{
|
else return WINPROC_CallProc16To32W( proc->procW, hwnd, msg, wParam, lParam );
|
||||||
case WIN_PROC_16:
|
|
||||||
return WINPROC_CallWndProc16( proc->u.proc16, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32A:
|
|
||||||
return WINPROC_CallProc16To32A( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32W:
|
|
||||||
return WINPROC_CallProc16To32W( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
default:
|
|
||||||
WARN_(relay)("Invalid proc %p\n", proc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3213,18 +3192,9 @@ LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
|
||||||
if (!(proc = handle16_to_proc( func )))
|
if (!(proc = handle16_to_proc( func )))
|
||||||
return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
|
return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
|
||||||
|
|
||||||
switch(proc->type)
|
if (proc->procA) return WINPROC_CallProc16To32A( proc->procA, hwnd, msg, wParam, lParam );
|
||||||
{
|
if (proc->procW) return WINPROC_CallProc16To32W( proc->procW, hwnd, msg, wParam, lParam );
|
||||||
case WIN_PROC_16:
|
return WINPROC_CallWndProc16( proc->proc16, hwnd, msg, wParam, lParam );
|
||||||
return WINPROC_CallWndProc16( proc->u.proc16, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32A:
|
|
||||||
return WINPROC_CallProc16To32A( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32W:
|
|
||||||
return WINPROC_CallProc16To32W( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
default:
|
|
||||||
WARN_(relay)("Invalid proc %p\n", proc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3266,18 +3236,9 @@ LRESULT WINAPI CallWindowProcA(
|
||||||
if (!(proc = handle_to_proc( func )))
|
if (!(proc = handle_to_proc( func )))
|
||||||
return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
|
return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
|
||||||
|
|
||||||
switch(proc->type)
|
if (proc->procA) return WINPROC_CallWndProc( proc->procA, hwnd, msg, wParam, lParam );
|
||||||
{
|
if (proc->procW) return WINPROC_CallProc32ATo32W( proc->procW, hwnd, msg, wParam, lParam );
|
||||||
case WIN_PROC_16:
|
return WINPROC_CallProc32ATo16( proc->proc16, hwnd, msg, wParam, lParam );
|
||||||
return WINPROC_CallProc32ATo16( proc->u.proc16, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32A:
|
|
||||||
return WINPROC_CallWndProc( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32W:
|
|
||||||
return WINPROC_CallProc32ATo32W( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
default:
|
|
||||||
WARN_(relay)("Invalid proc %p\n", proc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3296,18 +3257,9 @@ LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
|
||||||
if (!(proc = handle_to_proc( func )))
|
if (!(proc = handle_to_proc( func )))
|
||||||
return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
|
return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
|
||||||
|
|
||||||
switch(proc->type)
|
if (proc->procW) return WINPROC_CallWndProc( proc->procW, hwnd, msg, wParam, lParam );
|
||||||
{
|
if (proc->procA) return WINPROC_CallProc32WTo32A( proc->procA, hwnd, msg, wParam, lParam );
|
||||||
case WIN_PROC_16:
|
return WINPROC_CallProc32WTo16( proc->proc16, hwnd, msg, wParam, lParam );
|
||||||
return WINPROC_CallProc32WTo16( proc->u.proc16, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32A:
|
|
||||||
return WINPROC_CallProc32WTo32A( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32W:
|
|
||||||
return WINPROC_CallWndProc( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
default:
|
|
||||||
WARN_(relay)("Invalid proc %p\n", proc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3323,18 +3275,9 @@ INT_PTR WINPROC_CallDlgProc16( DLGPROC16 func, HWND16 hwnd, UINT16 msg, WPARAM16
|
||||||
if (!(proc = handle16_to_proc( (WNDPROC16)func )))
|
if (!(proc = handle16_to_proc( (WNDPROC16)func )))
|
||||||
return LOWORD( WINPROC_CallWndProc16( (WNDPROC16)func, hwnd, msg, wParam, lParam ) );
|
return LOWORD( WINPROC_CallWndProc16( (WNDPROC16)func, hwnd, msg, wParam, lParam ) );
|
||||||
|
|
||||||
switch(proc->type)
|
if (proc->procA) return WINPROC_CallProc16To32A( proc->procA, hwnd, msg, wParam, lParam );
|
||||||
{
|
if (proc->procW) return WINPROC_CallProc16To32W( proc->procW, hwnd, msg, wParam, lParam );
|
||||||
case WIN_PROC_16:
|
return LOWORD( WINPROC_CallWndProc16( proc->proc16, hwnd, msg, wParam, lParam ) );
|
||||||
return LOWORD( WINPROC_CallWndProc16( proc->u.proc16, hwnd, msg, wParam, lParam ) );
|
|
||||||
case WIN_PROC_32A:
|
|
||||||
return WINPROC_CallProc16To32A( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32W:
|
|
||||||
return WINPROC_CallProc16To32W( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
default:
|
|
||||||
WARN_(relay)("Invalid proc %p\n", proc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3350,18 +3293,9 @@ INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
if (!(proc = handle_to_proc( (WNDPROC)func )))
|
if (!(proc = handle_to_proc( (WNDPROC)func )))
|
||||||
return WINPROC_CallWndProc( (WNDPROC)func, hwnd, msg, wParam, lParam );
|
return WINPROC_CallWndProc( (WNDPROC)func, hwnd, msg, wParam, lParam );
|
||||||
|
|
||||||
switch(proc->type)
|
if (proc->procA) return WINPROC_CallWndProc( proc->procA, hwnd, msg, wParam, lParam );
|
||||||
{
|
if (proc->procW) return WINPROC_CallProc32ATo32W( proc->procW, hwnd, msg, wParam, lParam );
|
||||||
case WIN_PROC_16:
|
return LOWORD( WINPROC_CallProc32ATo16( proc->proc16, hwnd, msg, wParam, lParam ) );
|
||||||
return LOWORD( WINPROC_CallProc32ATo16( proc->u.proc16, hwnd, msg, wParam, lParam ) );
|
|
||||||
case WIN_PROC_32A:
|
|
||||||
return WINPROC_CallWndProc( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32W:
|
|
||||||
return WINPROC_CallProc32ATo32W( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
default:
|
|
||||||
WARN_(relay)("Invalid proc %p\n", proc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3377,16 +3311,7 @@ INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
if (!(proc = handle_to_proc( (WNDPROC)func )))
|
if (!(proc = handle_to_proc( (WNDPROC)func )))
|
||||||
return WINPROC_CallWndProc( (WNDPROC)func, hwnd, msg, wParam, lParam );
|
return WINPROC_CallWndProc( (WNDPROC)func, hwnd, msg, wParam, lParam );
|
||||||
|
|
||||||
switch(proc->type)
|
if (proc->procW) return WINPROC_CallWndProc( proc->procW, hwnd, msg, wParam, lParam );
|
||||||
{
|
if (proc->procA) return WINPROC_CallProc32WTo32A( proc->procA, hwnd, msg, wParam, lParam );
|
||||||
case WIN_PROC_16:
|
return LOWORD( WINPROC_CallProc32WTo16( proc->proc16, hwnd, msg, wParam, lParam ));
|
||||||
return LOWORD( WINPROC_CallProc32WTo16( proc->u.proc16, hwnd, msg, wParam, lParam ));
|
|
||||||
case WIN_PROC_32A:
|
|
||||||
return WINPROC_CallProc32WTo32A( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
case WIN_PROC_32W:
|
|
||||||
return WINPROC_CallWndProc( proc->u.proc32, hwnd, msg, wParam, lParam );
|
|
||||||
default:
|
|
||||||
WARN_(relay)("Invalid proc %p\n", proc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct tagWINDOWPROC;
|
||||||
extern WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode );
|
extern WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode );
|
||||||
extern WNDPROC WINPROC_AllocProc16( WNDPROC16 func );
|
extern WNDPROC WINPROC_AllocProc16( WNDPROC16 func );
|
||||||
extern WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode );
|
extern WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode );
|
||||||
extern WNDPROC WINPROC_AllocProc( WNDPROC func, BOOL unicode );
|
extern WNDPROC WINPROC_AllocProc( WNDPROC funcA, WNDPROC funcW );
|
||||||
extern BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val );
|
extern BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val );
|
||||||
|
|
||||||
extern INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam,
|
extern INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam,
|
||||||
|
|
Loading…
Reference in New Issue