Zhiyi Zhang : winex11.drv: Handle display device events in the desktop thread.
Alexandre Julliard
julliard at winehq.org
Fri Nov 1 15:37:48 CDT 2019
Module: wine
Branch: master
Commit: 413aad39135b0b0f8255500b85fcc05337a5f138
URL: https://source.winehq.org/git/wine.git/?a=commit;h=413aad39135b0b0f8255500b85fcc05337a5f138
Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date: Fri Nov 1 21:20:21 2019 +0800
winex11.drv: Handle display device events in the desktop thread.
This fixes a regression from 22795243b2d21e1a667215f54c3a15634735749c,
which calls thread_init_display() and eventually XOpenIM() before
X11DRV_InitXIM() is called.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47821
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winex11.drv/display.c | 6 ++++++
dlls/winex11.drv/window.c | 1 +
dlls/winex11.drv/x11drv.h | 5 +++++
dlls/winex11.drv/xinerama.c | 1 +
dlls/winex11.drv/xrandr.c | 35 +++++++++++++++++++++++------------
5 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index a323b795b8..ee867343ae 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -241,6 +241,12 @@ void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler
}
}
+void X11DRV_DisplayDevices_RegisterEventHandlers(void)
+{
+ if (handler.register_event_handlers)
+ handler.register_event_handlers();
+}
+
/* Initialize a GPU instance and return its GUID string in guid_string and driver value in driver parameter */
static BOOL X11DRV_InitGpu(HDEVINFO devinfo, const struct x11drv_gpu *gpu, INT gpu_index, WCHAR *guid_string,
WCHAR *driver)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 4e01eb201c..f3c6a1b3cb 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1833,6 +1833,7 @@ BOOL CDECL X11DRV_CreateWindow( HWND hwnd )
XFlush( data->display );
SetPropA( hwnd, clip_window_prop, (HANDLE)data->clip_window );
X11DRV_InitClipboard();
+ X11DRV_DisplayDevices_RegisterEventHandlers();
}
return TRUE;
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a06cf3ffd8..35e27334db 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -743,10 +743,15 @@ struct x11drv_display_device_handler
/* free_monitors will be called to free a monitor list from get_monitors */
void (*free_monitors)(struct x11drv_monitor *monitors);
+
+ /* register_event_handlers will be called to register event handlers.
+ * This function pointer is optional and can be NULL when driver doesn't support it */
+ void (*register_event_handlers)(void);
};
extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN;
extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN;
+extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN;
/* XIM support */
extern BOOL X11DRV_InitXIM( const char *input_style ) DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c
index b5620d3403..57c77d6273 100644
--- a/dlls/winex11.drv/xinerama.c
+++ b/dlls/winex11.drv/xinerama.c
@@ -344,5 +344,6 @@ void xinerama_init( unsigned int width, unsigned int height )
handler.free_gpus = xinerama_free_gpus;
handler.free_adapters = xinerama_free_adapters;
handler.free_monitors = xinerama_free_monitors;
+ handler.register_event_handlers = NULL;
X11DRV_DisplayDevices_SetHandler( &handler );
}
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index 412400e3f6..0a64613fac 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -1063,10 +1063,29 @@ static void xrandr14_free_monitors( struct x11drv_monitor *monitors )
heap_free( monitors );
}
-static BOOL xrandr14_device_change_event( HWND hwnd, XEvent *event )
+static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event )
{
- X11DRV_DisplayDevices_Init( TRUE );
- return TRUE;
+ if (hwnd == GetDesktopWindow() && GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
+ X11DRV_DisplayDevices_Init( TRUE );
+ return FALSE;
+}
+
+static void xrandr14_register_event_handlers(void)
+{
+ Display *display = thread_init_display();
+ int event_base, error_base;
+
+ if (!pXRRQueryExtension( display, &event_base, &error_base ))
+ return;
+
+ pXRRSelectInput( display, root_window,
+ RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RRProviderChangeNotifyMask );
+ X11DRV_register_event_handler( event_base + RRNotify_CrtcChange, xrandr14_device_change_handler,
+ "XRandR CrtcChange" );
+ X11DRV_register_event_handler( event_base + RRNotify_OutputChange, xrandr14_device_change_handler,
+ "XRandR OutputChange" );
+ X11DRV_register_event_handler( event_base + RRNotify_ProviderChange, xrandr14_device_change_handler,
+ "XRandR ProviderChange" );
}
#endif
@@ -1115,16 +1134,8 @@ void X11DRV_XRandR_Init(void)
handler.free_gpus = xrandr14_free_gpus;
handler.free_adapters = xrandr14_free_adapters;
handler.free_monitors = xrandr14_free_monitors;
+ handler.register_event_handlers = xrandr14_register_event_handlers;
X11DRV_DisplayDevices_SetHandler( &handler );
-
- pXRRSelectInput( thread_init_display(), root_window,
- RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RRProviderChangeNotifyMask);
- X11DRV_register_event_handler( event_base + RRNotify_CrtcChange, xrandr14_device_change_event,
- "XRandR CrtcChange" );
- X11DRV_register_event_handler( event_base + RRNotify_OutputChange, xrandr14_device_change_event,
- "XRandR OutputChange" );
- X11DRV_register_event_handler( event_base + RRNotify_ProviderChange, xrandr14_device_change_event,
- "XRandR ProviderChange" );
}
#endif
}
More information about the wine-cvs
mailing list