winex11.drv: Handle display device events in the desktop thread.

This fixes a regression from 22795243b2,
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@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2019-11-01 21:20:21 +08:00 committed by Alexandre Julliard
parent 9ae8da6bb4
commit 413aad3913
5 changed files with 36 additions and 12 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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 );
}

View File

@ -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
}