[PATCH] winex11.drv: Wait for process_attach to complete before enabling xrandr.

Zhiyi Zhang zzhang at codeweavers.com
Fri Oct 25 07:57:25 CDT 2019


This is one way to do it. But as Alexandre suggested, the device change
events should be handled in explorer.exe and I sent https://source.winehq.org/patches/data/171245
to fix it earlier. However patch 171244 was later found to trigger a X session deadlock blocking
the patch set. I have fixed the deadlock and will send a newer version soon.

On 10/25/19 4:30 PM, Rémi Bernon wrote:
> X11DRV_XRandR_Init is called in process_attach and calling
> thread_init_display there would make thread data to be initialized
> before its completion.
>
> It breaks some assumtions that could be made in x11drv_init_thread_data,
> for example that DesktopWindow has already been created.
>
> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> ---
>  dlls/winex11.drv/x11drv.h      |  1 +
>  dlls/winex11.drv/x11drv_main.c |  1 +
>  dlls/winex11.drv/xrandr.c      | 38 ++++++++++++++++++++++++----------
>  3 files changed, 29 insertions(+), 11 deletions(-)
>
> diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> index 135faa8989b..fdd2fbb5057 100644
> --- a/dlls/winex11.drv/x11drv.h
> +++ b/dlls/winex11.drv/x11drv.h
> @@ -668,6 +668,7 @@ struct x11drv_mode_info *X11DRV_Settings_SetHandlers(const char *name,
>
>  void X11DRV_XF86VM_Init(void) DECLSPEC_HIDDEN;
>  void X11DRV_XRandR_Init(void) DECLSPEC_HIDDEN;
> +void X11DRV_XRandR_Enable(void) DECLSPEC_HIDDEN;
>
>  /* X11 display device handler. Used to initialize display device registry data */
>
> diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
> index 21807af3f18..109d37ce4c3 100644
> --- a/dlls/winex11.drv/x11drv_main.c
> +++ b/dlls/winex11.drv/x11drv_main.c
> @@ -680,6 +680,7 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
>      TlsSetValue( thread_data_tls_index, data );
>
>      if (use_xim) X11DRV_SetupXIM();
> +    X11DRV_XRandR_Enable();
>
>      return data;
>  }
> diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
> index 6bb2b18ce7f..ecbb3ec85a3 100644
> --- a/dlls/winex11.drv/xrandr.c
> +++ b/dlls/winex11.drv/xrandr.c
> @@ -1069,30 +1069,33 @@ static BOOL xrandr14_device_change_event( HWND hwnd, XEvent *event )
>
>  #endif
>
> +static int xrandr_load_version = 0;
> +static int xrandr_minor = 0;
> +static int xrandr_major = 0;
> +
>  void X11DRV_XRandR_Init(void)
>  {
>      struct x11drv_display_device_handler handler;
> -    int event_base, error_base, minor, ret;
> -    static int major;
> +    int event_base, error_base;
>      Bool ok;
>
> -    if (major) return; /* already initialized? */
> +    if (xrandr_major) return; /* already initialized? */
>      if (!usexrandr) return; /* disabled in config */
>      if (root_window != DefaultRootWindow( gdi_display )) return;
> -    if (!(ret = load_xrandr())) return;  /* can't load the Xrandr library */
> +    if (!(xrandr_load_version = load_xrandr())) return;  /* can't load the Xrandr library */
>
>      /* see if Xrandr is available */
>      if (!pXRRQueryExtension( gdi_display, &event_base, &error_base )) return;
>      X11DRV_expect_error( gdi_display, XRandRErrorHandler, NULL );
> -    ok = pXRRQueryVersion( gdi_display, &major, &minor );
> +    ok = pXRRQueryVersion( gdi_display, &xrandr_major, &xrandr_minor );
>      if (X11DRV_check_error() || !ok) return;
>
> -    TRACE("Found XRandR %d.%d.\n", major, minor);
> +    TRACE("Found XRandR %d.%d.\n", xrandr_major, xrandr_minor);
>
>  #ifdef HAVE_XRRGETSCREENRESOURCES
> -    if (ret >= 2 && (major > 1 || (major == 1 && minor >= 2)))
> +    if (xrandr_load_version >= 2 && (xrandr_major > 1 || (xrandr_major == 1 && xrandr_minor >= 2)))
>      {
> -        if (major > 1 || (major == 1 && minor >= 3))
> +        if (xrandr_major > 1 || (xrandr_major == 1 && xrandr_minor >= 3))
>              pXRRGetScreenResourcesCurrent = wine_dlsym( xrandr_handle, "XRRGetScreenResourcesCurrent", NULL, 0 );
>          if (!pXRRGetScreenResourcesCurrent)
>              pXRRGetScreenResourcesCurrent = pXRRGetScreenResources;
> @@ -1103,7 +1106,7 @@ void X11DRV_XRandR_Init(void)
>          xrandr10_init_modes();
>
>  #ifdef HAVE_XRRGETPROVIDERRESOURCES
> -    if (ret >= 4 && (major > 1 || (major == 1 && minor >= 4)))
> +    if (xrandr_load_version >= 4 && (xrandr_major > 1 || (xrandr_major == 1 && xrandr_minor >= 4)))
>      {
>          handler.name = "XRandR 1.4";
>          handler.priority = 200;
> @@ -1115,8 +1118,6 @@ void X11DRV_XRandR_Init(void)
>          handler.pFreeMonitors = xrandr14_free_monitors;
>          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,
> @@ -1127,6 +1128,17 @@ void X11DRV_XRandR_Init(void)
>  #endif
>  }
>
> +void X11DRV_XRandR_Enable(void)
> +{
> +#ifdef HAVE_XRRGETPROVIDERRESOURCES
> +    struct x11drv_thread_data *data = x11drv_thread_data();
> +
> +    if (xrandr_load_version >= 4 && (xrandr_major > 1 || (xrandr_major == 1 && xrandr_minor >= 4)))
> +        pXRRSelectInput( data->display, root_window,
> +                         RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RRProviderChangeNotifyMask);
> +#endif
> +}
> +
>  #else /* SONAME_LIBXRANDR */
>
>  void X11DRV_XRandR_Init(void)
> @@ -1134,4 +1146,8 @@ void X11DRV_XRandR_Init(void)
>      TRACE("XRandR support not compiled in.\n");
>  }
>
> +void X11DRV_XRandR_Enable(void)
> +{
> +}
> +
>  #endif /* SONAME_LIBXRANDR */
> --
> 2.24.0.rc0
>




More information about the wine-devel mailing list