Commit 56220c24 authored by Alexandre Julliard's avatar Alexandre Julliard

user: Have WINPROC_GetProc16 allocate a new winproc if necessary.

parent 99dc29d9
......@@ -151,9 +151,8 @@ static BOOL set_server_info( HWND hwnd, INT offset, LONG newval )
*/
static WNDPROC16 CLASS_GetProc16( CLASS *classPtr )
{
WNDPROC proc = classPtr->winprocA;
if (!proc) proc = classPtr->winprocW;
return WINPROC_GetProc16( proc );
if (classPtr->winprocA) return WINPROC_GetProc16( classPtr->winprocA, FALSE );
else return WINPROC_GetProc16( classPtr->winprocW, TRUE );
}
......
......@@ -369,7 +369,7 @@ LONG WINAPI DispatchMessage16( const MSG16* msg )
else SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return 0;
}
winproc = WINPROC_GetProc16( wndPtr->winproc );
winproc = WINPROC_GetProc16( wndPtr->winproc, wndPtr->flags & WIN_ISUNICODE );
WIN_ReleasePtr( wndPtr );
SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam );
......
......@@ -2162,7 +2162,7 @@ LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
}
}
retvalue = GetWindowLongA( WIN_Handle32(hwnd), offset );
if (is_winproc) retvalue = (LONG_PTR)WINPROC_GetProc16( (WNDPROC)retvalue );
if (is_winproc) retvalue = (LONG_PTR)WINPROC_GetProc16( (WNDPROC)retvalue, FALSE );
return retvalue;
}
......@@ -2212,7 +2212,7 @@ LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
{
WNDPROC new_proc = WINPROC_AllocProc16( (WNDPROC16)newval );
WNDPROC old_proc = (WNDPROC)SetWindowLongA( WIN_Handle32(hwnd), offset, (LONG_PTR)new_proc );
return (LONG)WINPROC_GetProc16( (WNDPROC)old_proc );
return (LONG)WINPROC_GetProc16( (WNDPROC)old_proc, FALSE );
}
else return SetWindowLongA( WIN_Handle32(hwnd), offset, newval );
}
......
......@@ -144,8 +144,8 @@ static inline WINDOWPROC *find_winproc( WNDPROC func, BOOL unicode )
return NULL;
}
/* allocate and initialize a new winproc */
static inline WINDOWPROC *alloc_winproc(void)
/* initialize a new winproc */
static inline WINDOWPROC *init_winproc(void)
{
WINDOWPROC *proc;
......@@ -217,6 +217,36 @@ static inline WNDPROC proc_to_handle( WINDOWPROC *proc )
return (WNDPROC)(ULONG_PTR)((proc - winproc_array) | (WINPROC_HANDLE << 16));
}
/* allocate and initialize a new winproc */
static inline WINDOWPROC *alloc_winproc( WNDPROC func, BOOL unicode )
{
WINDOWPROC *proc;
if (!func) return NULL;
/* check if the function is already a win proc */
if ((proc = handle_to_proc( func ))) return proc;
EnterCriticalSection( &winproc_cs );
/* check if we already have a winproc for that function */
if (!(proc = find_winproc( func, unicode )))
{
if ((proc = init_winproc()))
{
proc->type = unicode ? WIN_PROC_32W : WIN_PROC_32A;
proc->u.proc32 = func;
TRACE( "allocated %p for %p %c (%d/%d used)\n",
proc_to_handle(proc), func, unicode ? 'W' : 'A', winproc_used, MAX_WINPROCS );
}
else FIXME( "too many winprocs, cannot allocate one for %p %c\n", func, unicode ? 'W' : 'A' );
}
else TRACE( "reusing %p for %p %c\n", proc_to_handle(proc), func, unicode ? 'W' : 'A' );
LeaveCriticalSection( &winproc_cs );
return proc;
}
#ifdef __i386__
/* Some window procedures modify register they shouldn't, or are not
......@@ -456,9 +486,9 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
*
* Get a window procedure pointer that can be passed to the Windows program.
*/
WNDPROC16 WINPROC_GetProc16( WNDPROC proc )
WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode )
{
WINDOWPROC *ptr = handle_to_proc( proc );
WINDOWPROC *ptr = alloc_winproc( proc, unicode );
if (!ptr) return 0;
......@@ -507,7 +537,7 @@ WNDPROC WINPROC_AllocProc16( WNDPROC16 func )
/* then check if we already have a winproc for that function */
if (!(proc = find_winproc16( func )))
{
if ((proc = alloc_winproc()))
if ((proc = init_winproc()))
{
proc->type = WIN_PROC_16;
proc->u.proc16 = func;
......@@ -537,29 +567,7 @@ WNDPROC WINPROC_AllocProc( WNDPROC func, BOOL unicode )
{
WINDOWPROC *proc;
if (!func) return NULL;
/* check if the function is already a win proc */
if (!(proc = handle_to_proc( func )))
{
EnterCriticalSection( &winproc_cs );
/* then check if we already have a winproc for that function */
if (!(proc = find_winproc( func, unicode )))
{
if ((proc = alloc_winproc()))
{
proc->type = unicode ? WIN_PROC_32W : WIN_PROC_32A;
proc->u.proc32 = func;
TRACE( "allocated %p for %p %c (%d/%d used)\n",
proc_to_handle(proc), func, unicode ? 'W' : 'A', winproc_used, MAX_WINPROCS );
}
else FIXME( "too many winprocs, cannot allocate one for %p %c\n", func, unicode ? 'W' : 'A' );
}
else TRACE( "reusing %p for %p %c\n", proc_to_handle(proc), func, unicode ? 'W' : 'A' );
LeaveCriticalSection( &winproc_cs );
}
if (!(proc = alloc_winproc( func, unicode ))) return NULL;
return proc_to_handle( proc );
}
......
......@@ -44,7 +44,7 @@ typedef struct
struct tagWINDOWPROC;
extern WNDPROC16 WINPROC_GetProc16( WNDPROC proc );
extern WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode );
extern WNDPROC WINPROC_AllocProc16( WNDPROC16 func );
extern WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode );
extern WNDPROC WINPROC_AllocProc( WNDPROC func, BOOL unicode );
......
......@@ -1357,8 +1357,7 @@ BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInst16, SEGPTR name, WNDCLASSEX16 *
if (ret)
{
WNDPROC proc = WINPROC_AllocProc( wc32.lpfnWndProc, FALSE );
wc->lpfnWndProc = WINPROC_GetProc16( proc );
wc->lpfnWndProc = WINPROC_GetProc16( wc32.lpfnWndProc, FALSE );
wc->style = wc32.style;
wc->cbClsExtra = wc32.cbClsExtra;
wc->cbWndExtra = wc32.cbWndExtra;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment