user32: Factor out dispatch_win_proc_params.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-03-23 14:00:21 +01:00 committed by Alexandre Julliard
parent c36a25897c
commit a821155f21
3 changed files with 143 additions and 80 deletions

View File

@ -47,19 +47,6 @@ extern void USER_unload_driver(void) DECLSPEC_HIDDEN;
struct received_message_info;
/* type of message-sending functions that need special WM_CHAR handling */
enum wm_char_mapping
{
WMCHAR_MAP_POSTMESSAGE,
WMCHAR_MAP_SENDMESSAGE,
WMCHAR_MAP_SENDMESSAGETIMEOUT,
WMCHAR_MAP_RECVMESSAGE,
WMCHAR_MAP_DISPATCHMESSAGE,
WMCHAR_MAP_CALLWINDOWPROC,
WMCHAR_MAP_COUNT,
WMCHAR_MAP_NOMAPPING = WMCHAR_MAP_COUNT
};
/* data to store state for A/W mappings of WM_CHAR */
struct wm_char_mapping_data
{

View File

@ -37,7 +37,7 @@ WINE_DECLARE_DEBUG_CHANNEL(msg);
WINE_DECLARE_DEBUG_CHANNEL(relay);
#define MAX_WINPROC_RECURSION 64
#define WINPROC_PROC16 ((WINDOWPROC *)1) /* placeholder for 16-bit window procs */
#define WINPROC_PROC16 ((void *)1) /* placeholder for 16-bit window procs */
static inline void *get_buffer( void *static_buffer, size_t size, size_t need )
{
@ -709,6 +709,89 @@ static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UIN
}
static void dispatch_win_proc_params( struct win_proc_params *params )
{
if (!params->ansi)
{
if (params->procW == WINPROC_PROC16)
WINPROC_CallProcWtoA( wow_handlers.call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->func );
else if (params->is_dialog)
{
if (!params->ansi_dst)
{
if (params->procW)
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->procW );
else
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->func );
}
else
{
if (params->procA)
WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->procA );
else
WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->func );
}
}
else if (params->procW)
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->procW );
else if (params->procA)
WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->procA );
else if (!params->ansi_dst)
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->func );
else
WINPROC_CallProcWtoA( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->func );
}
else
{
if (params->procA == WINPROC_PROC16)
wow_handlers.call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->func );
else if (params->is_dialog)
{
if (!params->ansi_dst)
{
if (params->procW)
WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->procW, params->mapping );
else
WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->func, params->mapping );
}
else
{
if (params->procA)
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->procA );
else
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->func );
}
}
else if (params->procA)
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->procA );
else if (params->procW)
WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->procW, params->mapping );
else if (!params->ansi_dst)
WINPROC_CallProcAtoW( call_window_proc, params->hwnd, params->msg, params->wparam,
params->lparam, params->result, params->func, params->mapping );
else
call_window_proc( params->hwnd, params->msg, params->wparam, params->lparam,
params->result, params->func );
}
}
/**********************************************************************
* WINPROC_call_window
*
@ -718,10 +801,9 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
LRESULT *result, BOOL unicode, enum wm_char_mapping mapping )
{
struct user_thread_info *thread_info = get_user_thread_info();
BOOL unicode_win, is_dialog;
WND *wndPtr;
WNDPROC func;
struct win_proc_params params;
WINDOWPROC *proc;
WND *wndPtr;
if (!(wndPtr = WIN_GetPtr( hwnd ))) return FALSE;
if (wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return FALSE;
@ -730,75 +812,39 @@ BOOL WINPROC_call_window( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
WIN_ReleasePtr( wndPtr );
return FALSE;
}
func = wndPtr->winproc;
params.func = wndPtr->winproc;
proc = handle_to_proc( wndPtr->winproc );
unicode_win = wndPtr->flags & WIN_ISUNICODE;
is_dialog = wndPtr->dlgInfo != NULL;
params.ansi_dst = !(wndPtr->flags & WIN_ISUNICODE);
params.is_dialog = wndPtr->dlgInfo != NULL;
WIN_ReleasePtr( wndPtr );
params.hwnd = hwnd;
params.msg = msg;
params.wparam = wParam;
params.lparam = lParam;
params.result = result;
params.ansi = !unicode;
params.mapping = mapping;
if (!proc)
{
params.procW = params.procA = NULL;
}
else if (proc == WINPROC_PROC16)
{
params.procW = params.procA = WINPROC_PROC16;
}
else
{
params.procA = proc->procA;
params.procW = proc->procW;
}
if (thread_info->recursion_count > MAX_WINPROC_RECURSION) return FALSE;
thread_info->recursion_count++;
if (unicode)
{
if (proc == WINPROC_PROC16)
WINPROC_CallProcWtoA( wow_handlers.call_window_proc, hwnd, msg, wParam, lParam, result, func );
else if (is_dialog)
{
if (unicode_win)
{
if (proc && proc->procW)
call_window_proc( hwnd, msg, wParam, lParam, result, proc->procW );
else
call_window_proc( hwnd, msg, wParam, lParam, result, func );
}
else
{
if (proc && proc->procA)
WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procA );
else
WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, result, func );
}
}
else if (proc && proc->procW)
call_window_proc( hwnd, msg, wParam, lParam, result, proc->procW );
else if (proc)
WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procA );
else if (unicode_win)
call_window_proc( hwnd, msg, wParam, lParam, result, func );
else
WINPROC_CallProcWtoA( call_window_proc, hwnd, msg, wParam, lParam, result, func );
}
else
{
if (proc == WINPROC_PROC16)
wow_handlers.call_window_proc( hwnd, msg, wParam, lParam, result, func );
else if (is_dialog)
{
if (unicode_win)
{
if (proc && proc->procW)
WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procW, mapping );
else
WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, func, mapping );
}
else
{
if (proc && proc->procA)
call_window_proc( hwnd, msg, wParam, lParam, result, proc->procA );
else
call_window_proc( hwnd, msg, wParam, lParam, result, func );
}
}
else if (proc && proc->procA)
call_window_proc( hwnd, msg, wParam, lParam, result, proc->procA );
else if (proc)
WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, proc->procW, mapping );
else if (unicode_win)
WINPROC_CallProcAtoW( call_window_proc, hwnd, msg, wParam, lParam, result, func, mapping );
else
call_window_proc( hwnd, msg, wParam, lParam, result, func );
}
dispatch_win_proc_params( &params );
thread_info->recursion_count--;
return TRUE;
}

View File

@ -61,6 +61,36 @@ struct win_event_hook_params
WCHAR module[MAX_PATH];
};
/* type of message-sending functions that need special WM_CHAR handling */
enum wm_char_mapping
{
WMCHAR_MAP_POSTMESSAGE,
WMCHAR_MAP_SENDMESSAGE,
WMCHAR_MAP_SENDMESSAGETIMEOUT,
WMCHAR_MAP_RECVMESSAGE,
WMCHAR_MAP_DISPATCHMESSAGE,
WMCHAR_MAP_CALLWINDOWPROC,
WMCHAR_MAP_COUNT,
WMCHAR_MAP_NOMAPPING = WMCHAR_MAP_COUNT
};
/* NtUserCallWindowProc params */
struct win_proc_params
{
WNDPROC func;
HWND hwnd;
UINT msg;
WPARAM wparam;
LPARAM lparam;
LRESULT *result;
BOOL ansi;
BOOL ansi_dst;
BOOL is_dialog;
enum wm_char_mapping mapping;
WNDPROC procA;
WNDPROC procW;
};
/* NtUserCallWindowsHook params */
struct win_hook_params
{