I also created a branch that I use for testing wow64: https://gitlab.winehq.org/jacek/wine/-/commits/wow
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/user_private.h | 2 ++ dlls/user32/win.c | 27 +++++++++++++++++++++++++-- dlls/user32/winproc.c | 31 +++++++++++++++++++++---------- dlls/win32u/class.c | 22 +++------------------- dlls/win32u/ntuser_private.h | 2 +- dlls/win32u/sysparams.c | 3 +++ dlls/win32u/window.c | 7 ------- include/ntuser.h | 19 ++++++------------- 8 files changed, 61 insertions(+), 52 deletions(-)
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 5944187d686..a67c22cdc39 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -33,6 +33,8 @@ #define GET_DWORD(ptr) (*(const DWORD *)(ptr)) #define GET_LONG(ptr) (*(const LONG *)(ptr))
+#define WINPROC_PROC16 ((void *)1) /* placeholder for 16-bit window procs */ + /* data to store state for A/W mappings of WM_CHAR */ struct wm_char_mapping_data { diff --git a/dlls/user32/win.c b/dlls/user32/win.c index d0a34841ce0..0060247f6b6 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -626,6 +626,17 @@ DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( HWND hwnd ) }
+static LONG_PTR get_window_long_ptr( HWND hwnd, int offset, LONG_PTR ret, BOOL ansi ) +{ + if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd )) + { + DLGPROC proc = NtUserGetDialogProc( (DLGPROC)ret, ansi ); + if (proc && proc != WINPROC_PROC16) return (LONG_PTR)proc; + } + return ret; +} + + /*********************************************************************** * GetDpiForWindow (USER32.@) */ @@ -660,6 +671,11 @@ LONG WINAPI GetWindowLongA( HWND hwnd, INT offset ) return 0; #endif default: + if (sizeof(void *) == sizeof(LONG)) + { + LONG_PTR ret = NtUserGetWindowLongA( hwnd, offset ); + return get_window_long_ptr( hwnd, offset, ret, TRUE ); + } return NtUserGetWindowLongA( hwnd, offset ); } } @@ -681,6 +697,11 @@ LONG WINAPI GetWindowLongW( HWND hwnd, INT offset ) return 0; #endif default: + if (sizeof(void *) == sizeof(LONG)) + { + LONG_PTR ret = NtUserGetWindowLongW( hwnd, offset ); + return get_window_long_ptr( hwnd, offset, ret, FALSE ); + } return NtUserGetWindowLongW( hwnd, offset ); } } @@ -1411,7 +1432,8 @@ BOOL WINAPI SetProcessDefaultLayout( DWORD layout ) */ LONG_PTR WINAPI GetWindowLongPtrW( HWND hwnd, INT offset ) { - return NtUserGetWindowLongPtrW( hwnd, offset ); + LONG_PTR ret = NtUserGetWindowLongPtrW( hwnd, offset ); + return get_window_long_ptr( hwnd, offset, ret, FALSE ); }
/***************************************************************************** @@ -1419,7 +1441,8 @@ LONG_PTR WINAPI GetWindowLongPtrW( HWND hwnd, INT offset ) */ LONG_PTR WINAPI GetWindowLongPtrA( HWND hwnd, INT offset ) { - return NtUserGetWindowLongPtrA( hwnd, offset ); + LONG_PTR ret = NtUserGetWindowLongPtrA( hwnd, offset ); + return get_window_long_ptr( hwnd, offset, ret, TRUE ); }
/***************************************************************************** diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index a22262b037b..7e2be5b1be0 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -37,8 +37,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msg); WINE_DECLARE_DEBUG_CHANNEL(relay);
-#define WINPROC_PROC16 ((void *)1) /* placeholder for 16-bit window procs */ - union packed_structs { struct packed_CREATESTRUCTW cs; @@ -1286,16 +1284,22 @@ LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg, WPARAM wParam */ INT_PTR WINPROC_CallDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { + DLGPROC func, proc; LRESULT result; - DLGPROC func;
- if (!(func = NtUserGetDialogProc( hwnd, DLGPROC_ANSI ))) return 0; +#ifdef _WIN64 + proc = (DLGPROC)NtUserGetWindowLongPtrA( hwnd, DWLP_DLGPROC ); +#else + proc = (DLGPROC)NtUserGetWindowLongA( hwnd, DWLP_DLGPROC ); +#endif + if (!proc) return 0; + if (!(func = NtUserGetDialogProc( proc, TRUE )) && + !(func = NtUserGetDialogProc( proc, FALSE ))) return 0;
if (func == WINPROC_PROC16) { INT_PTR ret; - if (!(func = NtUserGetDialogProc( hwnd, DLGPROC_WIN16 ))) return 0; - ret = wow_handlers.call_dialog_proc( hwnd, msg, wParam, lParam, &result, func ); + ret = wow_handlers.call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc ); SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result ); return ret; } @@ -1309,16 +1313,23 @@ INT_PTR WINPROC_CallDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam */ INT_PTR WINPROC_CallDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { + DLGPROC func, proc; LRESULT result; - DLGPROC func;
- if (!(func = NtUserGetDialogProc( hwnd, DLGPROC_UNICODE ))) return 0; +#ifdef _WIN64 + proc = (DLGPROC)NtUserGetWindowLongPtrW( hwnd, DWLP_DLGPROC ); +#else + proc = (DLGPROC)NtUserGetWindowLongW( hwnd, DWLP_DLGPROC ); +#endif + if (!proc) return 0; + if (!(func = NtUserGetDialogProc( proc, FALSE )) && + !(func = NtUserGetDialogProc( proc, TRUE ))) return 0;
if (func == WINPROC_PROC16) { INT_PTR ret; - if (!(func = NtUserGetDialogProc( hwnd, DLGPROC_WIN16 ))) return 0; - ret = WINPROC_CallProcWtoA( wow_handlers.call_dialog_proc, hwnd, msg, wParam, lParam, &result, func ); + ret = WINPROC_CallProcWtoA( wow_handlers.call_dialog_proc, + hwnd, msg, wParam, lParam, &result, proc ); SetWindowLongPtrW( hwnd, DWLP_MSGRESULT, result ); return ret; } diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 6058617b80e..6f368b50431 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -237,29 +237,13 @@ void get_winproc_params( struct win_proc_params *params, BOOL fixup_ansi_dst ) if (!params->procW) params->procW = params->func; }
-DLGPROC get_dialog_proc( HWND hwnd, enum dialog_proc_type type ) +DLGPROC get_dialog_proc( DLGPROC ret, BOOL ansi ) { WINDOWPROC *proc; - DLGPROC ret; - WND *win;
- if (!(win = get_win_ptr( hwnd ))) return NULL; - if (win == WND_OTHER_PROCESS || win == WND_DESKTOP) - { - ERR( "cannot get dlg proc %p from other process\n", hwnd ); - return 0; - } - ret = *(DLGPROC *)((char *)win->wExtra + DWLP_DLGPROC); - release_win_ptr( win ); - if (type == DLGPROC_WIN16 || !(proc = get_winproc_ptr( ret ))) return ret; + if (!(proc = get_winproc_ptr( ret ))) return ret; if (proc == WINPROC_PROC16) return WINPROC_PROC16; - - if (type == DLGPROC_ANSI) - ret = proc->procA ? proc->procA : proc->procW; - else - ret = proc->procW ? proc->procW : proc->procA; - - return ret; + return ansi ? proc->procA : proc->procW; }
/*********************************************************************** diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 9f93feea407..8287126258e 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -223,7 +223,7 @@ DWORD get_class_long( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN; WNDPROC get_class_winproc( struct tagCLASS *class ) DECLSPEC_HIDDEN; ULONG_PTR get_class_long_ptr( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN; WORD get_class_word( HWND hwnd, INT offset ) DECLSPEC_HIDDEN; -DLGPROC get_dialog_proc( HWND hwnd, enum dialog_proc_type type ) DECLSPEC_HIDDEN; +DLGPROC get_dialog_proc( DLGPROC proc, BOOL ansi ) DECLSPEC_HIDDEN; ATOM get_int_atom_value( UNICODE_STRING *name ) DECLSPEC_HIDDEN; WNDPROC get_winproc( WNDPROC proc, BOOL ansi ) DECLSPEC_HIDDEN; void get_winproc_params( struct win_proc_params *params, BOOL fixup_ansi_dst ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 52665f7a641..201004e1447 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -5054,6 +5054,9 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code { switch(code) { + case NtUserCallTwoParam_GetDialogProc: + return (ULONG_PTR)get_dialog_proc( (DLGPROC)arg1, arg2 ); + case NtUserCallTwoParam_GetMenuInfo: return get_menu_info( UlongToHandle(arg1), (MENUINFO *)arg2 );
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 0aa10d9ec65..997f6359917 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1056,10 +1056,6 @@ static LONG_PTR get_window_long_size( HWND hwnd, INT offset, UINT size, BOOL ans return 0; } retval = get_win_data( (char *)win->wExtra + offset, size ); - - /* Special case for dialog window procedure */ - if ((offset == DWLP_DLGPROC) && (size == sizeof(LONG_PTR)) && win->dlgInfo) - retval = (LONG_PTR)get_winproc( (WNDPROC)retval, ansi ); release_win_ptr( win ); return retval; } @@ -5481,9 +5477,6 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) case NtUserCallHwndParam_GetClientRect: return get_client_rect( hwnd, (RECT *)param );
- case NtUserCallHwndParam_GetDialogProc: - return (ULONG_PTR)get_dialog_proc( hwnd, param ); - case NtUserCallHwndParam_GetScrollInfo: { struct get_scroll_info_params *params = (void *)param; diff --git a/include/ntuser.h b/include/ntuser.h index 326d0371998..963b02dfd8c 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -1066,6 +1066,7 @@ static inline UINT NtUserSetProcessDefaultLayout( DWORD layout ) /* NtUserCallTwoParam codes, not compatible with Windows */ enum { + NtUserCallTwoParam_GetDialogProc, NtUserCallTwoParam_GetMenuInfo, NtUserCallTwoParam_GetMonitorInfo, NtUserCallTwoParam_GetSystemMetricsForDpi, @@ -1077,6 +1078,11 @@ enum NtUserAllocWinProc, };
+static inline DLGPROC NtUserGetDialogProc( DLGPROC proc, BOOL ansi ) +{ + return (DLGPROC)NtUserCallTwoParam( (UINT_PTR)proc, ansi, NtUserCallTwoParam_GetDialogProc ); +} + static inline BOOL NtUserGetMenuInfo( HMENU menu, MENUINFO *info ) { return NtUserCallTwoParam( HandleToUlong(menu), (ULONG_PTR)info, @@ -1239,7 +1245,6 @@ enum NtUserCallHwndParam_GetClassLongPtrW, NtUserCallHwndParam_GetClassWord, NtUserCallHwndParam_GetClientRect, - NtUserCallHwndParam_GetDialogProc, NtUserCallHwndParam_GetScrollInfo, NtUserCallHwndParam_GetWindowInfo, NtUserCallHwndParam_GetWindowLongA, @@ -1310,18 +1315,6 @@ static inline BOOL NtUserGetClientRect( HWND hwnd, RECT *rect ) return NtUserCallHwndParam( hwnd, (UINT_PTR)rect, NtUserCallHwndParam_GetClientRect ); }
-enum dialog_proc_type -{ - DLGPROC_ANSI, - DLGPROC_UNICODE, - DLGPROC_WIN16, -}; - -static inline DLGPROC NtUserGetDialogProc( HWND hwnd, enum dialog_proc_type type ) -{ - return (DLGPROC)NtUserCallHwndParam( hwnd, type, NtUserCallHwndParam_GetDialogProc ); -} - struct get_scroll_info_params { int bar;
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/win.c | 26 ++++++++++++++++++++++++++ dlls/win32u/window.c | 11 ----------- 2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 0060247f6b6..9507486754b 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -637,6 +637,18 @@ static LONG_PTR get_window_long_ptr( HWND hwnd, int offset, LONG_PTR ret, BOOL a }
+static LONG_PTR set_dialog_proc( HWND hwnd, LONG_PTR newval, BOOL ansi ) +{ + DLGPROC proc; + LONG_PTR ret; + newval = NtUserCallTwoParam( newval, ansi, NtUserAllocWinProc ); + ret = NtUserSetWindowLong( hwnd, DWLP_DLGPROC, newval, ansi ); + proc = NtUserGetDialogProc( (DLGPROC)ret, ansi ); + if (proc) ret = (UINT_PTR)proc; + return ret; +} + + /*********************************************************************** * GetDpiForWindow (USER32.@) */ @@ -723,6 +735,10 @@ LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongA( HWND hwnd, INT offset, LONG newval WARN( "Invalid offset %d\n", offset ); SetLastError( ERROR_INVALID_INDEX ); return 0; +#else + case DWLP_DLGPROC: + if (NtUserGetDialogInfo( hwnd )) return set_dialog_proc( hwnd, newval, TRUE ); + /* fall through */ #endif default: return NtUserSetWindowLong( hwnd, offset, newval, TRUE ); @@ -811,6 +827,10 @@ LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongW( WARN("Invalid offset %d\n", offset ); SetLastError( ERROR_INVALID_INDEX ); return 0; +#else + case DWLP_DLGPROC: + if (NtUserGetDialogInfo( hwnd )) return set_dialog_proc( hwnd, newval, FALSE ); + /* fall through */ #endif default: return NtUserSetWindowLong( hwnd, offset, newval, FALSE ); @@ -1450,6 +1470,9 @@ LONG_PTR WINAPI GetWindowLongPtrA( HWND hwnd, INT offset ) */ LONG_PTR WINAPI SetWindowLongPtrW( HWND hwnd, INT offset, LONG_PTR newval ) { + if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd )) + return set_dialog_proc( hwnd, newval, FALSE ); + return NtUserSetWindowLongPtr( hwnd, offset, newval, FALSE ); }
@@ -1458,6 +1481,9 @@ LONG_PTR WINAPI SetWindowLongPtrW( HWND hwnd, INT offset, LONG_PTR newval ) */ LONG_PTR WINAPI SetWindowLongPtrA( HWND hwnd, INT offset, LONG_PTR newval ) { + if (offset == DWLP_DLGPROC && NtUserGetDialogInfo( hwnd )) + return set_dialog_proc( hwnd, newval, TRUE ); + return NtUserSetWindowLongPtr( hwnd, offset, newval, TRUE ); }
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 997f6359917..b4a65b883f3 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1309,17 +1309,6 @@ LONG_PTR set_window_long( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOO case GWLP_HINSTANCE: case GWLP_USERDATA: break; - case DWLP_DLGPROC: - if ((win->cbWndExtra - sizeof(LONG_PTR) >= DWLP_DLGPROC) && - (size == sizeof(LONG_PTR)) && win->dlgInfo) - { - WNDPROC *ptr = (WNDPROC *)((char *)win->wExtra + DWLP_DLGPROC); - retval = (ULONG_PTR)get_winproc( *ptr, ansi ); - *ptr = alloc_winproc( (WNDPROC)newval, ansi ); - release_win_ptr( win ); - return retval; - } - /* fall through */ default: if (offset < 0 || offset > (int)(win->cbWndExtra - size)) {
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=121529
Your paranoid android.
=== debian11 (64 bit WoW report) ===
user32: win.c:10984: Test failed: Received WM_ACTIVATEAPP(0), did not expect it.
From: Jacek Caban jacek@codeweavers.com
--- dlls/win32u/sysparams.c | 7 ++++++- dlls/win32u/win32u_private.h | 2 +- dlls/win32u/window.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 201004e1447..454c4702612 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -375,7 +375,7 @@ union sysparam_all_entry
static UINT system_dpi; static RECT work_area; -DWORD process_layout = ~0u; +static DWORD process_layout = ~0u;
static HDC display_dc; static pthread_mutex_t display_dc_lock = PTHREAD_MUTEX_INITIALIZER; @@ -1631,6 +1631,11 @@ DPI_AWARENESS get_thread_dpi_awareness(void) } }
+DWORD get_process_layout(void) +{ + return process_layout == ~0u ? 0 : process_layout; +} + /********************************************************************** * get_thread_dpi */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index a0bc1d62882..e1d163ea8eb 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -326,7 +326,6 @@ extern void track_scroll_bar( HWND hwnd, int scrollbar, POINT pt ) DECLSPEC_HIDD
/* sysparams.c */ extern BOOL enable_thunk_lock DECLSPEC_HIDDEN; -extern DWORD process_layout DECLSPEC_HIDDEN; extern HBRUSH get_55aa_brush(void) DECLSPEC_HIDDEN; extern DWORD get_dialog_base_units(void) DECLSPEC_HIDDEN; extern LONG get_char_dimensions( HDC hdc, TEXTMETRICW *metric, LONG *height ) DECLSPEC_HIDDEN; @@ -335,6 +334,7 @@ extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN; extern BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) DECLSPEC_HIDDEN; extern UINT get_win_monitor_dpi( HWND hwnd ) DECLSPEC_HIDDEN; extern RECT get_primary_monitor_rect( UINT dpi ) DECLSPEC_HIDDEN; +extern DWORD get_process_layout(void) DECLSPEC_HIDDEN; extern COLORREF get_sys_color( int index ) DECLSPEC_HIDDEN; extern HBRUSH get_sys_color_brush( unsigned int index ) DECLSPEC_HIDDEN; extern HPEN get_sys_color_pen( unsigned int index ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index b4a65b883f3..d9c771e5d3d 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5094,7 +5094,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, (class_name->Length != sizeof(messageW) || wcsnicmp( class_name->Buffer, messageW, ARRAYSIZE(messageW) ))) { - if (process_layout & LAYOUT_RTL) cs.dwExStyle |= WS_EX_LAYOUTRTL; + if (get_process_layout() & LAYOUT_RTL) cs.dwExStyle |= WS_EX_LAYOUTRTL; parent = get_desktop_window(); } }
From: Jacek Caban jacek@codeweavers.com
--- dlls/wow64win/gdi.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c index 5ddadaa642b..6fa36b5f3a3 100644 --- a/dlls/wow64win/gdi.c +++ b/dlls/wow64win/gdi.c @@ -239,23 +239,20 @@ NTSTATUS WINAPI wow64_NtGdiDdDDICreateDevice( UINT *args ) UINT PatchLocationListSize; } *desc32 = get_ptr( &args );
- D3DKMT_CREATEDEVICE desc = - { - { desc32->hAdapter }, - desc32->Flags - }; + D3DKMT_CREATEDEVICE desc; NTSTATUS status;
+ if (!desc32) return STATUS_INVALID_PARAMETER; + desc.hAdapter = desc32->hAdapter; + desc.Flags = desc32->Flags; + desc.pCommandBuffer = UlongToPtr( desc32->pCommandBuffer ); + desc.CommandBufferSize = desc32->CommandBufferSize; + desc.pAllocationList = UlongToPtr( desc32->pAllocationList ); + desc.AllocationListSize = desc32->AllocationListSize; + desc.pPatchLocationList = UlongToPtr( desc32->pPatchLocationList ); + desc.PatchLocationListSize = desc32->PatchLocationListSize; if (!(status = NtGdiDdDDICreateDevice( &desc ))) - { desc32->hDevice = desc.hDevice; - desc32->pCommandBuffer = PtrToUlong( desc.pCommandBuffer ); - desc32->CommandBufferSize = desc.CommandBufferSize; - desc32->pAllocationList = PtrToUlong( desc.pAllocationList ); - desc32->AllocationListSize = desc.AllocationListSize; - desc32->pPatchLocationList = PtrToUlong( desc.pPatchLocationList ); - desc32->PatchLocationListSize = desc.PatchLocationListSize; - } return status; }
From: Jacek Caban jacek@codeweavers.com
On wow64 64-bit win32u.dll is always loaded, causing win32u.so to initialize at earlier stage than it would otherwise do. This patch makes it more consistent across environments. --- dlls/win32u/class.c | 12 ++++++++++++ dlls/win32u/gdiobj.c | 5 ++--- dlls/win32u/syscall.c | 8 +------- dlls/win32u/win32u_private.h | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 6f368b50431..28eabcc1f51 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -246,6 +246,14 @@ DLGPROC get_dialog_proc( DLGPROC ret, BOOL ansi ) return ansi ? proc->procA : proc->procW; }
+static void init_user(void) +{ + gdi_init(); + winstation_init(); + sysparams_init(); + register_desktop_class(); +} + /*********************************************************************** * NtUserInitializeClientPfnArrays (win32u.@) */ @@ -253,6 +261,8 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs const struct user_client_procs *client_procsW, const void *client_workers, HINSTANCE user_module ) { + static pthread_once_t init_once = PTHREAD_ONCE_INIT; + winproc_array[WINPROC_BUTTON].procA = client_procsA->pButtonWndProc; winproc_array[WINPROC_BUTTON].procW = client_procsW->pButtonWndProc; winproc_array[WINPROC_COMBO].procA = client_procsA->pComboWndProc; @@ -283,6 +293,8 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs winproc_array[WINPROC_MESSAGE].procW = client_procsW->pMessageWndProc;
user32_module = user_module; + + pthread_once( &init_once, init_user ); return STATUS_SUCCESS; }
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 881c76ee165..f8a1bd96f8f 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1153,7 +1153,7 @@ static struct unix_funcs unix_funcs = __wine_send_input, };
-NTSTATUS gdi_init(void) +void gdi_init(void) { pthread_mutexattr_t attr; unsigned int dpi; @@ -1165,11 +1165,10 @@ NTSTATUS gdi_init(void)
NtQuerySystemInformation( SystemBasicInformation, &system_info, sizeof(system_info), NULL ); init_gdi_shared(); - if (!gdi_shared) return STATUS_NO_MEMORY; + if (!gdi_shared) return;
dpi = font_init(); init_stock_objects( dpi ); - return 0; }
NTSTATUS callbacks_init( void *args ) diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index e36e7097047..5f78d8c6ab9 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -314,13 +314,7 @@ static SYSTEM_SERVICE_TABLE syscall_table =
static NTSTATUS init( void *dispatcher ) { - NTSTATUS status; - if ((status = ntdll_init_syscalls( 1, &syscall_table, dispatcher ))) return status; - if ((status = gdi_init())) return status; - winstation_init(); - sysparams_init(); - register_desktop_class(); - return STATUS_SUCCESS; + return ntdll_init_syscalls( 1, &syscall_table, dispatcher ); }
unixlib_entry_t __wine_unix_call_funcs[] = diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index e1d163ea8eb..298cafcf7bf 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -411,7 +411,7 @@ static inline void release_win_ptr( struct tagWND *ptr ) }
extern void wrappers_init( unixlib_handle_t handle ) DECLSPEC_HIDDEN; -extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN; +extern void gdi_init(void) DECLSPEC_HIDDEN; extern NTSTATUS callbacks_init( void *args ) DECLSPEC_HIDDEN; extern void winstation_init(void) DECLSPEC_HIDDEN; extern void sysparams_init(void) DECLSPEC_HIDDEN;
From: Jacek Caban jacek@codeweavers.com
--- dlls/winex11.drv/dllmain.c | 3 +- dlls/winex11.drv/event.c | 2 +- dlls/winex11.drv/unixlib.h | 4 +- dlls/winex11.drv/x11drv_main.c | 107 ++++++++++++++++++++++++++++++++- dlls/winex11.drv/xdnd.c | 2 +- 5 files changed, 111 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/dllmain.c b/dlls/winex11.drv/dllmain.c index 99a137f66e7..8ed0e40d1ac 100644 --- a/dlls/winex11.drv/dllmain.c +++ b/dlls/winex11.drv/dllmain.c @@ -67,6 +67,7 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) struct init_params params = { foreign_window_proc, + &show_systray, };
if (reason != DLL_PROCESS_ATTACH) return TRUE; @@ -81,8 +82,6 @@ BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; memcpy( callback_table + NtUserDriverCallbackFirst, kernel_callbacks, sizeof(kernel_callbacks) ); - - show_systray = params.show_systray; return TRUE; }
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index ddf5cd0433b..25ca9d885a7 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1802,7 +1802,7 @@ static void handle_xdnd_position_event( HWND hwnd, XClientMessageEvent *event ) XClientMessageEvent e; DWORD effect;
- params.hwnd = hwnd; + params.hwnd = HandleToUlong( hwnd ); params.point = root_to_virtual_screen( event->data.l[2] >> 16, event->data.l[2] & 0xFFFF ); params.effect = effect = xdnd_action_to_drop_effect( event->data.l[4] );
diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h index fa3685af33a..e8b243d67a1 100644 --- a/dlls/winex11.drv/unixlib.h +++ b/dlls/winex11.drv/unixlib.h @@ -50,7 +50,7 @@ struct create_desktop_params struct init_params { WNDPROC foreign_window_proc; - BOOL show_systray; + BOOL *show_systray; };
struct systray_dock_params @@ -123,7 +123,7 @@ struct format_entry /* x11drv_dnd_position_event params */ struct dnd_position_event_params { - HWND hwnd; + ULONG hwnd; POINT point; DWORD effect; }; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index e94977f8caf..7f9ada291a0 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -714,7 +714,7 @@ static NTSTATUS x11drv_init( void *arg )
init_user_driver(); X11DRV_DisplayDevices_Init(FALSE); - params->show_systray = show_systray; + *params->show_systray = show_systray; return STATUS_SUCCESS; }
@@ -1337,3 +1337,108 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count ); + + +#ifdef _WIN64 + +static NTSTATUS x11drv_wow64_init( void *arg ) +{ + struct + { + ULONG foreign_window_proc; + ULONG show_systray; + } *params32 = arg; + struct init_params params; + + params.foreign_window_proc = UlongToPtr( params32->foreign_window_proc ); + params.show_systray = UlongToPtr( params32->show_systray ); + return x11drv_init( ¶ms ); +} + +static NTSTATUS x11drv_wow64_systray_clear( void *arg ) +{ + HWND hwnd = UlongToPtr( *(ULONG *)arg ); + return x11drv_systray_clear( &hwnd ); +} + +static NTSTATUS x11drv_wow64_systray_dock( void *arg ) +{ + struct + { + UINT64 event_handle; + ULONG icon; + int cx; + int cy; + ULONG layered; + } *params32 = arg; + struct systray_dock_params params; + + params.event_handle = params32->event_handle; + params.icon = UlongToPtr( params32->icon ); + params.cx = params32->cx; + params.cy = params32->cy; + params.layered = UlongToPtr( params32->layered ); + return x11drv_systray_dock( ¶ms ); +} + +static NTSTATUS x11drv_wow64_systray_hide( void *arg ) +{ + HWND hwnd = UlongToPtr( *(ULONG *)arg ); + return x11drv_systray_hide( &hwnd ); +} + +static NTSTATUS x11drv_wow64_tablet_get_packet( void *arg ) +{ + FIXME( "%p\n", arg ); + return 0; +} + +static NTSTATUS x11drv_wow64_tablet_info( void *arg ) +{ + struct + { + UINT category; + UINT index; + ULONG output; + } *params32 = arg; + struct tablet_info_params params; + + params.category = params32->category; + params.index = params32->index; + params.output = UlongToPtr( params32->output ); + return x11drv_tablet_info( ¶ms ); +} + +static NTSTATUS x11drv_wow64_xim_preedit_state( void *arg ) +{ + struct + { + ULONG hwnd; + BOOL open; + } *params32 = arg; + struct xim_preedit_state_params params; + + params.hwnd = UlongToHandle( params32->hwnd ); + params.open = params32->open; + return x11drv_xim_preedit_state( ¶ms ); +} + +const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ + x11drv_create_desktop, + x11drv_wow64_init, + x11drv_wow64_systray_clear, + x11drv_wow64_systray_dock, + x11drv_wow64_systray_hide, + x11drv_systray_init, + x11drv_tablet_attach_queue, + x11drv_wow64_tablet_get_packet, + x11drv_wow64_tablet_info, + x11drv_tablet_load_info, + x11drv_wow64_xim_preedit_state, + x11drv_xim_reset, +}; + +C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count ); + +#endif /* _WIN64 */ diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 9137f46b5dc..21a4bb7f6fb 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -177,7 +177,7 @@ NTSTATUS WINAPI x11drv_dnd_position_event( void *arg, ULONG size ) HRESULT hr;
XDNDxy = params->point; - targetWindow = window_from_point_dnd( params->hwnd, XDNDxy ); + targetWindow = window_from_point_dnd( UlongToHandle( params->hwnd ), XDNDxy );
if (!XDNDAccepted || XDNDLastTargetWnd != targetWindow) {
This merge request was approved by Huw Davies.