[PATCH 2/2] user32: Add a new __wine_set_desktop callback.

Rémi Bernon rbernon at codeweavers.com
Fri Nov 19 05:23:39 CST 2021


Since fd675485be8686ec5e3b4667d3f3e9739a4a07ce, the graphics driver
initialization sequence changed for the desktop process. The desktop
thread loads the graphics driver directly, and that makes it fill the
user driver callbacks without going through load_driver anymore.

This makes register_builtin_classes to not be called anymore in the
desktop process, and IME window creation to fail when the systray window
is created.

It is noticeable as ImeSetActiveContext and ImmReleaseContext are
printing a FIXME, and possible side effects aren't completely obvious,
but we should probably make sure builtin classes are registered.

This restores a call to register_builtin_classes by redirecting graphics
driver wine_create_desktop callback through user32.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/user32/driver.c                      | 21 ++++++++++++++++++++-
 dlls/user32/user32.spec                   |  1 +
 dlls/wineandroid.drv/android.h            |  1 +
 dlls/wineandroid.drv/init.c               |  1 +
 dlls/wineandroid.drv/window.c             |  4 ++--
 dlls/wineandroid.drv/wineandroid.drv.spec |  3 ---
 dlls/winex11.drv/desktop.c                |  4 ++--
 dlls/winex11.drv/init.c                   |  1 +
 dlls/winex11.drv/winex11.drv.spec         |  3 ---
 dlls/winex11.drv/x11drv.h                 |  1 +
 include/wine/gdi_driver.h                 |  3 +++
 programs/explorer/desktop.c               | 17 ++---------------
 12 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 06b02adeab5..31443643d5c 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -216,6 +216,11 @@ static void CDECL nulldrv_ThreadDetach( void )
 {
 }
 
+static BOOL CDECL nulldrv_CreateDesktop( UINT width, UINT heigth )
+{
+    return FALSE;
+}
+
 
 /**********************************************************************
  * Lazy loading user driver
@@ -374,7 +379,9 @@ static struct user_driver_funcs lazy_load_driver =
     /* system parameters */
     nulldrv_SystemParametersInfo,
     /* thread management */
-    nulldrv_ThreadDetach
+    nulldrv_ThreadDetach,
+    /* desktop creation */
+    nulldrv_CreateDesktop,
 };
 
 void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version )
@@ -408,3 +415,15 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v
 
     __wine_set_display_driver( driver, version );
 }
+
+BOOL CDECL __wine_set_desktop( HMODULE module, const WCHAR *name, UINT width, UINT height, HDESK desktop )
+{
+    /* we're in the desktop thread already but we need to set the ready
+     * flag so that later user32 calls won't trigger a SendMessageW while
+     * holding the user lock when registering classes. */
+    wait_graphics_driver_ready();
+
+    register_builtin_classes();
+    if (!desktop) return FALSE;
+    return USER_Driver->pCreateDesktop( width, height );
+}
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 78946be86b3..77952d84489 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -839,3 +839,4 @@
 @ cdecl __wine_send_input(long ptr ptr)
 @ cdecl __wine_set_pixel_format(long long)
 @ cdecl __wine_set_user_driver(ptr long)
+@ cdecl __wine_set_desktop(ptr ptr long long ptr)
diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h
index 73ac0e702cc..e0f3c760c83 100644
--- a/dlls/wineandroid.drv/android.h
+++ b/dlls/wineandroid.drv/android.h
@@ -106,6 +106,7 @@ extern void CDECL ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT s
                                             const RECT *window_rect, const RECT *client_rect,
                                             const RECT *visible_rect, const RECT *valid_rects,
                                             struct window_surface *surface ) DECLSPEC_HIDDEN;
+extern BOOL CDECL ANDROID_CreateDesktop( UINT width, UINT height ) DECLSPEC_HIDDEN;
 
 extern unsigned int screen_width DECLSPEC_HIDDEN;
 extern unsigned int screen_height DECLSPEC_HIDDEN;
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index 180a6650ffd..bdfbec60c0e 100644
--- a/dlls/wineandroid.drv/init.c
+++ b/dlls/wineandroid.drv/init.c
@@ -310,6 +310,7 @@ static const struct user_driver_funcs android_drv_funcs =
     .pWindowMessage = ANDROID_WindowMessage,
     .pWindowPosChanging = ANDROID_WindowPosChanging,
     .pWindowPosChanged = ANDROID_WindowPosChanged,
+    .pCreateDesktop = ANDROID_CreateDesktop,
 };
 
 
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
index 997bce15964..a5ae628d8a0 100644
--- a/dlls/wineandroid.drv/window.c
+++ b/dlls/wineandroid.drv/window.c
@@ -1651,9 +1651,9 @@ LRESULT CDECL ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
 
 
 /***********************************************************************
- *           ANDROID_create_desktop
+ *           ANDROID_CreateDesktop
  */
-BOOL CDECL ANDROID_create_desktop( UINT width, UINT height )
+BOOL CDECL ANDROID_CreateDesktop( UINT width, UINT height )
 {
     desktop_orig_wndproc = (WNDPROC)SetWindowLongPtrW( GetDesktopWindow(), GWLP_WNDPROC,
                                                        (LONG_PTR)desktop_wndproc_wrapper );
diff --git a/dlls/wineandroid.drv/wineandroid.drv.spec b/dlls/wineandroid.drv/wineandroid.drv.spec
index 2d7e76a04e8..612bf4634be 100644
--- a/dlls/wineandroid.drv/wineandroid.drv.spec
+++ b/dlls/wineandroid.drv/wineandroid.drv.spec
@@ -1,6 +1,3 @@
-# Desktop
-@ cdecl wine_create_desktop(long long) ANDROID_create_desktop
-
 # MMDevAPI driver functions
 @ stdcall -private GetPriority() AUDDRV_GetPriority
 @ stdcall -private GetEndpointIDs(long ptr ptr ptr ptr) AUDDRV_GetEndpointIDs
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c
index 71b3a0a5a27..617efb1a7a3 100644
--- a/dlls/winex11.drv/desktop.c
+++ b/dlls/winex11.drv/desktop.c
@@ -322,11 +322,11 @@ void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height )
 
 
 /***********************************************************************
- *		X11DRV_create_desktop
+ *		X11DRV_CreateDesktop
  *
  * Create the X11 desktop window for the desktop mode.
  */
-BOOL CDECL X11DRV_create_desktop( UINT width, UINT height )
+BOOL CDECL X11DRV_CreateDesktop( UINT width, UINT height )
 {
     static const WCHAR rootW[] = {'r','o','o','t',0};
     XSetWindowAttributes win_attr;
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index 854221bf948..32047e7aeac 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -426,6 +426,7 @@ static const struct user_driver_funcs x11drv_funcs =
     .pWindowPosChanged = X11DRV_WindowPosChanged,
     .pSystemParametersInfo = X11DRV_SystemParametersInfo,
     .pThreadDetach = X11DRV_ThreadDetach,
+    .pCreateDesktop = X11DRV_CreateDesktop,
 };
 
 
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 6e0ccfab4b0..d08e2e71e76 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -4,9 +4,6 @@
 @ cdecl LoadTabletInfo(long) X11DRV_LoadTabletInfo
 @ cdecl WTInfoW(long long ptr) X11DRV_WTInfoW
 
-# Desktop
-@ cdecl wine_create_desktop(long long) X11DRV_create_desktop
-
 # System tray
 @ cdecl wine_notify_icon(long ptr)
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 4b4ee8daaeb..43c02450806 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -241,6 +241,7 @@ extern void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT sw
 extern BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param,
                                                UINT flags ) DECLSPEC_HIDDEN;
 extern void CDECL X11DRV_ThreadDetach(void) DECLSPEC_HIDDEN;
+extern BOOL CDECL X11DRV_CreateDesktop( UINT width, UINT height ) DECLSPEC_HIDDEN;
 
 /* X11 driver internal functions */
 
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index 994b082d5b4..16337eb6235 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -287,9 +287,12 @@ struct user_driver_funcs
     BOOL    (CDECL *pSystemParametersInfo)(UINT,UINT,void*,UINT);
     /* thread management */
     void    (CDECL *pThreadDetach)(void);
+    /* desktop creation */
+    BOOL    (CDECL *pCreateDesktop)(UINT,UINT);
 };
 
 extern void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version );
+extern BOOL CDECL __wine_set_desktop( HMODULE module, const WCHAR *name, UINT width, UINT height, HDESK desktop );
 
 /* the DC hook support is only exported on Win16, the 32-bit version is a Wine extension */
 
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index 6d577dd0fd1..5ace15c73b0 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -32,6 +32,7 @@
 #include "exdisp.h"
 
 #include "wine/debug.h"
+#include "wine/gdi_driver.h"
 #include "explorer_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(explorer);
@@ -684,20 +685,6 @@ static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPAR
     return desktop_orig_wndproc( hwnd, message, wp, lp );
 }
 
-/* create the desktop and the associated driver window, and make it the current desktop */
-static BOOL create_desktop( HMODULE driver, const WCHAR *name, unsigned int width, unsigned int height )
-{
-    BOOL ret = FALSE;
-    BOOL (CDECL *create_desktop_func)(unsigned int, unsigned int);
-
-    if (driver)
-    {
-        create_desktop_func = (void *)GetProcAddress( driver, "wine_create_desktop" );
-        if (create_desktop_func) ret = create_desktop_func( width, height );
-    }
-    return ret;
-}
-
 /* parse the desktop size specification */
 static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height )
 {
@@ -1019,7 +1006,7 @@ void manage_desktop( WCHAR *arg )
 
         desktop_orig_wndproc = (WNDPROC)SetWindowLongPtrW( hwnd, GWLP_WNDPROC,
             (LONG_PTR)desktop_wnd_proc );
-        using_root = !desktop || !create_desktop( graphics_driver, name, width, height );
+        using_root = !__wine_set_desktop( graphics_driver, name, width, height, desktop );
         SendMessageW( hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO)));
         if (name) set_desktop_window_title( hwnd, name );
         SetWindowPos( hwnd, 0, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
-- 
2.33.1




More information about the wine-devel mailing list