Simplifying the code and avoiding the need to call back into win32u to get the primary adapter, for https://gitlab.winehq.org/wine/wine/-/merge_requests/551.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/desktop.c | 30 ++++++++++++++++++++------ dlls/winex11.drv/display.c | 42 ++++++++++++++++++++++--------------- dlls/winex11.drv/x11drv.h | 6 +++--- dlls/winex11.drv/xrandr.c | 20 +++++++++++------- dlls/winex11.drv/xvidmode.c | 13 ++++++------ 5 files changed, 71 insertions(+), 40 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index c6a08291f6a..05e00a2b333 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -123,13 +123,14 @@ BOOL is_virtual_desktop(void) }
/* Virtual desktop display settings handler */ -static BOOL X11DRV_desktop_get_id( const WCHAR *device_name, ULONG_PTR *id ) +static BOOL X11DRV_desktop_get_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary ) { WCHAR primary_adapter[CCHDEVICENAME];
if (!get_primary_adapter( primary_adapter ) || wcsicmp( primary_adapter, device_name )) return FALSE;
+ *is_primary = 1; *id = 0; return TRUE; } @@ -201,28 +202,45 @@ static void X11DRV_desktop_free_modes( DEVMODEW *modes ) free( modes ); }
-static BOOL X11DRV_desktop_get_current_mode( ULONG_PTR id, DEVMODEW *mode ) +static BOOL X11DRV_desktop_get_current_mode( ULONG_PTR id, BOOL is_primary, DEVMODEW *mode ) { RECT primary_rect = NtUserGetPrimaryMonitorRect();
mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION; mode->u1.s2.dmDisplayOrientation = DMDO_DEFAULT; + mode->u2.dmDisplayFlags = 0; + mode->u1.s2.dmPosition.x = 0; + mode->u1.s2.dmPosition.y = 0; + + if (!is_primary) + { + FIXME("Non-primary adapters are unsupported.\n"); + mode->dmBitsPerPel = 0; + mode->dmPelsWidth = 0; + mode->dmPelsHeight = 0; + mode->dmDisplayFrequency = 0; + return TRUE; + } + mode->dmBitsPerPel = screen_bpp; mode->dmPelsWidth = primary_rect.right - primary_rect.left; mode->dmPelsHeight = primary_rect.bottom - primary_rect.top; - mode->u2.dmDisplayFlags = 0; mode->dmDisplayFrequency = 60; - mode->u1.s2.dmPosition.x = 0; - mode->u1.s2.dmPosition.y = 0; return TRUE; }
-static LONG X11DRV_desktop_set_current_mode( ULONG_PTR id, const DEVMODEW *mode ) +static LONG X11DRV_desktop_set_current_mode( ULONG_PTR id, BOOL is_primary, const DEVMODEW *mode ) { if (mode->dmFields & DM_BITSPERPEL && mode->dmBitsPerPel != screen_bpp) WARN("Cannot change screen color depth from %dbits to %dbits!\n", screen_bpp, mode->dmBitsPerPel);
+ if (!is_primary) + { + FIXME("Non-primary adapters are unsupported.\n"); + return DISP_CHANGE_SUCCESSFUL; + } + desktop_width = mode->dmPelsWidth; desktop_height = mode->dmPelsHeight; return DISP_CHANGE_SUCCESSFUL; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 572b81aa491..3e20f9be22b 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -66,14 +66,15 @@ void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handle * Default handlers if resolution switching is not enabled * */ -static BOOL nores_get_id(const WCHAR *device_name, ULONG_PTR *id) +static BOOL nores_get_id(const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary) { WCHAR primary_adapter[CCHDEVICENAME];
if (!get_primary_adapter( primary_adapter )) return FALSE;
- *id = !wcsicmp( device_name, primary_adapter ) ? 1 : 0; + *is_primary = !wcsicmp( device_name, primary_adapter ); + *id = *is_primary ? 1 : 0; return TRUE; }
@@ -110,7 +111,7 @@ static void nores_free_modes(DEVMODEW *modes) free(modes); }
-static BOOL nores_get_current_mode(ULONG_PTR id, DEVMODEW *mode) +static BOOL nores_get_current_mode(ULONG_PTR id, BOOL is_primary, DEVMODEW *mode) { RECT primary = get_host_primary_monitor_rect();
@@ -121,7 +122,7 @@ static BOOL nores_get_current_mode(ULONG_PTR id, DEVMODEW *mode) mode->dmPosition.x = 0; mode->dmPosition.y = 0;
- if (id != 1) + if (!is_primary) { FIXME("Non-primary adapters are unsupported.\n"); mode->dmBitsPerPel = 0; @@ -138,7 +139,7 @@ static BOOL nores_get_current_mode(ULONG_PTR id, DEVMODEW *mode) return TRUE; }
-static LONG nores_set_current_mode(ULONG_PTR id, const DEVMODEW *mode) +static LONG nores_set_current_mode(ULONG_PTR id, BOOL is_primary, const DEVMODEW *mode) { WARN("NoRes settings handler, ignoring mode change request.\n"); return DISP_CHANGE_SUCCESSFUL; @@ -268,10 +269,11 @@ static DWORD get_display_depth(ULONG_PTR display_id) */ BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW devmode ) { + BOOL is_primary; DEVMODEW mode; ULONG_PTR id;
- if (!settings_handler.get_id( name, &id ) || !settings_handler.get_current_mode( id, &mode )) + if (!settings_handler.get_id( name, &id, &is_primary ) || !settings_handler.get_current_mode( id, is_primary, &mode )) { ERR("Failed to get %s current display settings.\n", wine_dbgstr_w(name)); return FALSE; @@ -348,7 +350,13 @@ static void free_full_mode(DEVMODEW *mode) free(mode); }
-static LONG apply_display_settings( DEVMODEW *displays, ULONG_PTR *ids, BOOL do_attach ) +struct display_info +{ + ULONG_PTR id; + BOOL is_primary; +}; + +static LONG apply_display_settings( DEVMODEW *displays, struct display_info *infos, BOOL do_attach ) { DEVMODEW *full_mode; BOOL attached_mode; @@ -357,14 +365,14 @@ static LONG apply_display_settings( DEVMODEW *displays, ULONG_PTR *ids, BOOL do_
for (count = 0, mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode), count++) { - ULONG_PTR *id = ids + count; + struct display_info *info = infos + count;
attached_mode = !is_detached_mode(mode); if ((attached_mode && !do_attach) || (!attached_mode && do_attach)) continue;
/* FIXME: get a full mode again because X11 driver extra data isn't portable */ - full_mode = get_full_mode(*id, mode); + full_mode = get_full_mode(info->id, mode); if (!full_mode) return DISP_CHANGE_BADMODE;
@@ -375,9 +383,9 @@ static LONG apply_display_settings( DEVMODEW *displays, ULONG_PTR *ids, BOOL do_ full_mode->dmPelsHeight, full_mode->dmDisplayFrequency, full_mode->dmBitsPerPel, full_mode->dmDisplayOrientation);
- ret = settings_handler.set_current_mode(*id, full_mode); + ret = settings_handler.set_current_mode(info->id, info->is_primary, full_mode); if (attached_mode && ret == DISP_CHANGE_SUCCESSFUL) - set_display_depth(*id, full_mode->dmBitsPerPel); + set_display_depth(info->id, full_mode->dmBitsPerPel); free_full_mode(full_mode); if (ret != DISP_CHANGE_SUCCESSFUL) return ret; @@ -394,7 +402,7 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, { INT left_most = INT_MAX, top_most = INT_MAX; LONG count, ret = DISP_CHANGE_BADPARAM; - ULONG_PTR *ids; + struct display_info *infos; DEVMODEW *mode;
/* Convert virtual screen coordinates to root coordinates, and find display ids. @@ -406,23 +414,23 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, top_most = min( top_most, mode->dmPosition.y ); }
- if (!(ids = calloc( count, sizeof(*ids) ))) return DISP_CHANGE_FAILED; + if (!(infos = calloc( count, sizeof(*infos) ))) return DISP_CHANGE_FAILED; for (count = 0, mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode), count++) { - if (!settings_handler.get_id( mode->dmDeviceName, ids + count )) goto done; + if (!settings_handler.get_id( mode->dmDeviceName, &infos[count].id, &infos[count].is_primary )) goto done; mode->dmPosition.x -= left_most; mode->dmPosition.y -= top_most; }
/* Detach displays first to free up CRTCs */ - ret = apply_display_settings( displays, ids, FALSE ); + ret = apply_display_settings( displays, infos, FALSE ); if (ret == DISP_CHANGE_SUCCESSFUL) - ret = apply_display_settings( displays, ids, TRUE ); + ret = apply_display_settings( displays, infos, TRUE ); if (ret == DISP_CHANGE_SUCCESSFUL) X11DRV_DisplayDevices_Init(TRUE);
done: - free( ids ); + free( infos ); return ret; }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f8f8fe3d4d1..856436a9e02 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -710,7 +710,7 @@ struct x11drv_settings_handler * Following functions use this id to identify the device. * * Return FALSE if the device cannot be found and TRUE on success */ - BOOL (*get_id)(const WCHAR *device_name, ULONG_PTR *id); + BOOL (*get_id)(const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary);
/* get_modes() will be called to get a list of supported modes of the device of id in modes * with respect to flags, which could be 0, EDS_RAWMODE or EDS_ROTATEDMODE. If the implementation @@ -733,13 +733,13 @@ struct x11drv_settings_handler * dmDisplayFrequency and dmPosition * * Return FALSE on failure with parameters unchanged and error code set. Return TRUE on success */ - BOOL (*get_current_mode)(ULONG_PTR id, DEVMODEW *mode); + BOOL (*get_current_mode)(ULONG_PTR id, BOOL is_primary, DEVMODEW *mode);
/* set_current_mode() will be called to change the display mode of the display device of id. * mode must be a valid mode from get_modes() with optional fields, such as dmPosition set. * * Return DISP_CHANGE_*, same as ChangeDisplaySettingsExW() return values */ - LONG (*set_current_mode)(ULONG_PTR id, const DEVMODEW *mode); + LONG (*set_current_mode)(ULONG_PTR id, BOOL is_primary, const DEVMODEW *mode); };
extern void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *handler) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index c7f922b1aae..f76043a701f 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -144,7 +144,7 @@ static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg) }
/* XRandR 1.0 display settings handler */ -static BOOL xrandr10_get_id( const WCHAR *device_name, ULONG_PTR *id ) +static BOOL xrandr10_get_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary ) { WCHAR primary_adapter[CCHDEVICENAME];
@@ -154,7 +154,8 @@ static BOOL xrandr10_get_id( const WCHAR *device_name, ULONG_PTR *id ) /* RandR 1.0 only supports changing the primary adapter settings. * For non-primary adapters, an id is still provided but getting * and changing non-primary adapters' settings will be ignored. */ - *id = !wcsicmp( device_name, primary_adapter ) ? 1 : 0; + *is_primary = !wcsicmp( device_name, primary_adapter ); + *id = *is_primary ? 1 : 0; return TRUE; }
@@ -240,7 +241,7 @@ static void xrandr10_free_modes( DEVMODEW *modes ) free( modes ); }
-static BOOL xrandr10_get_current_mode( ULONG_PTR id, DEVMODEW *mode ) +static BOOL xrandr10_get_current_mode( ULONG_PTR id, BOOL is_primary, DEVMODEW *mode ) { XRRScreenConfiguration *screen_config; XRRScreenSize *sizes; @@ -282,7 +283,7 @@ static BOOL xrandr10_get_current_mode( ULONG_PTR id, DEVMODEW *mode ) return TRUE; }
-static LONG xrandr10_set_current_mode( ULONG_PTR id, const DEVMODEW *mode ) +static LONG xrandr10_set_current_mode( ULONG_PTR id, BOOL is_primary, const DEVMODEW *mode ) { XRRScreenConfiguration *screen_config; Rotation rotation; @@ -290,7 +291,7 @@ static LONG xrandr10_set_current_mode( ULONG_PTR id, const DEVMODEW *mode ) Window root; Status stat;
- if (id != 1) + if (!is_primary) { FIXME("Non-primary adapters are unsupported.\n"); return DISP_CHANGE_SUCCESSFUL; @@ -332,6 +333,7 @@ static struct current_mode { ULONG_PTR id; BOOL loaded; + BOOL primary; DEVMODEW mode; } *current_modes; static int current_mode_count; @@ -1224,7 +1226,7 @@ static void xrandr14_register_event_handlers(void) }
/* XRandR 1.4 display settings handler */ -static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id ) +static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary ) { struct current_mode *tmp_modes, *new_current_modes = NULL; INT gpu_count, adapter_count, new_current_mode_count = 0; @@ -1265,6 +1267,7 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id ) { new_current_modes[new_current_mode_count + adapter_idx].id = adapters[adapter_idx].id; new_current_modes[new_current_mode_count + adapter_idx].loaded = FALSE; + new_current_modes[new_current_mode_count + adapter_idx].primary = !!(adapters[adapter_idx].state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); } new_current_mode_count += adapter_count; xrandr14_free_adapters( adapters ); @@ -1286,6 +1289,7 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id ) }
*id = current_modes[display_idx].id; + *is_primary = current_modes[display_idx].primary; pthread_mutex_unlock( &xrandr_mutex ); return TRUE; } @@ -1435,7 +1439,7 @@ static void xrandr14_free_modes( DEVMODEW *modes ) free( modes ); }
-static BOOL xrandr14_get_current_mode( ULONG_PTR id, DEVMODEW *mode ) +static BOOL xrandr14_get_current_mode( ULONG_PTR id, BOOL is_primary, DEVMODEW *mode ) { struct current_mode *mode_ptr = NULL; XRRScreenResources *screen_resources; @@ -1541,7 +1545,7 @@ done: return ret; }
-static LONG xrandr14_set_current_mode( ULONG_PTR id, const DEVMODEW *mode ) +static LONG xrandr14_set_current_mode( ULONG_PTR id, BOOL is_primary, const DEVMODEW *mode ) { unsigned int screen_width, screen_height; RROutput output = (RROutput)id, *outputs; diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index 95342a84223..ca9444712d6 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -85,7 +85,7 @@ static int XVidModeErrorHandler(Display *dpy, XErrorEvent *event, void *arg) }
/* XF86VidMode display settings handler */ -static BOOL xf86vm_get_id(const WCHAR *device_name, ULONG_PTR *id) +static BOOL xf86vm_get_id(const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary) { WCHAR primary_adapter[CCHDEVICENAME];
@@ -95,7 +95,8 @@ static BOOL xf86vm_get_id(const WCHAR *device_name, ULONG_PTR *id) /* XVidMode only supports changing the primary adapter settings. * For non-primary adapters, an id is still provided but getting * and changing non-primary adapters' settings will be ignored. */ - *id = !wcsicmp( device_name, primary_adapter ) ? 1 : 0; + *is_primary = !wcsicmp( device_name, primary_adapter ); + *id = *is_primary ? 1 : 0; return TRUE; }
@@ -174,7 +175,7 @@ static void xf86vm_free_modes(DEVMODEW *modes) free(modes); }
-static BOOL xf86vm_get_current_mode(ULONG_PTR id, DEVMODEW *mode) +static BOOL xf86vm_get_current_mode(ULONG_PTR id, BOOL is_primary, DEVMODEW *mode) { XF86VidModeModeLine xf86vm_mode; INT dotclock; @@ -187,7 +188,7 @@ static BOOL xf86vm_get_current_mode(ULONG_PTR id, DEVMODEW *mode) mode->u1.s2.dmPosition.x = 0; mode->u1.s2.dmPosition.y = 0;
- if (id != 1) + if (!is_primary) { FIXME("Non-primary adapters are unsupported.\n"); mode->dmBitsPerPel = 0; @@ -215,12 +216,12 @@ static BOOL xf86vm_get_current_mode(ULONG_PTR id, DEVMODEW *mode) return TRUE; }
-static LONG xf86vm_set_current_mode(ULONG_PTR id, const DEVMODEW *mode) +static LONG xf86vm_set_current_mode(ULONG_PTR id, BOOL is_primary, const DEVMODEW *mode) { XF86VidModeModeInfo *xf86vm_mode; Bool ret;
- if (id != 1) + if (!is_primary) { FIXME("Non-primary adapters are unsupported.\n"); return DISP_CHANGE_SUCCESSFUL;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/desktop.c | 2 +- dlls/winex11.drv/display.c | 6 +++--- dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/xinerama.c | 2 +- dlls/winex11.drv/xrandr.c | 9 ++------- 5 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index 05e00a2b333..7dc149b2e95 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -260,7 +260,7 @@ static void query_desktop_work_area( RECT *rc_work ) TRACE( "found tray %p %s work area %s\n", hwnd, wine_dbgstr_rect( &rect ), wine_dbgstr_rect( rc_work ) ); }
-static BOOL X11DRV_desktop_get_gpus( struct gdi_gpu **new_gpus, int *count ) +static BOOL X11DRV_desktop_get_gpus( struct gdi_gpu **new_gpus, int *count, BOOL get_properties ) { static const WCHAR wine_adapterW[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0}; struct gdi_gpu *gpu; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 3e20f9be22b..4465f3765b5 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -464,7 +464,7 @@ RECT get_host_primary_monitor_rect(void) RECT rect = {0};
/* The first monitor is always primary */ - if (host_handler.get_gpus(&gpus, &gpu_count) && gpu_count && + if (host_handler.get_gpus(&gpus, &gpu_count, TRUE) && gpu_count && host_handler.get_adapters(gpus[0].id, &adapters, &adapter_count) && adapter_count && host_handler.get_monitors(adapters[0].id, &monitors, &monitor_count) && monitor_count) rect = monitors[0].rc_monitor; @@ -480,7 +480,7 @@ BOOL get_host_primary_gpu(struct gdi_gpu *gpu) struct gdi_gpu *gpus; INT gpu_count;
- if (host_handler.get_gpus(&gpus, &gpu_count) && gpu_count) + if (host_handler.get_gpus(&gpus, &gpu_count, TRUE) && gpu_count) { *gpu = gpus[0]; host_handler.free_gpus(gpus); @@ -586,7 +586,7 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage TRACE("via %s\n", wine_dbgstr_a(handler->name));
/* Initialize GPUs */ - if (!handler->get_gpus( &gpus, &gpu_count )) return FALSE; + if (!handler->get_gpus( &gpus, &gpu_count, TRUE )) return FALSE; TRACE("GPU count: %d\n", gpu_count);
for (gpu = 0; gpu < gpu_count; gpu++) diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 856436a9e02..b5f948fa232 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -772,7 +772,7 @@ struct x11drv_display_device_handler /* get_gpus will be called to get a list of GPUs. First GPU has to be where the primary adapter is. * * Return FALSE on failure with parameters unchanged */ - BOOL (*get_gpus)(struct gdi_gpu **gpus, int *count); + BOOL (*get_gpus)(struct gdi_gpu **gpus, int *count, BOOL get_properties);
/* get_adapters will be called to get a list of adapters in EnumDisplayDevices context under a GPU. * The first adapter has to be primary if GPU is primary. diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c index 847b8fb6efb..94254f43098 100644 --- a/dlls/winex11.drv/xinerama.c +++ b/dlls/winex11.drv/xinerama.c @@ -122,7 +122,7 @@ static inline int query_screens(void)
#endif /* SONAME_LIBXINERAMA */
-static BOOL xinerama_get_gpus( struct gdi_gpu **new_gpus, int *count ) +static BOOL xinerama_get_gpus( struct gdi_gpu **new_gpus, int *count, BOOL get_properties ) { static const WCHAR wine_adapterW[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0}; struct gdi_gpu *gpus; diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index f76043a701f..42cbe213333 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -760,7 +760,7 @@ done:
/* Get a list of GPUs reported by XRandR 1.4. Set get_properties to FALSE if GPU properties are * not needed to avoid unnecessary querying */ -static BOOL xrandr14_get_gpus2( struct gdi_gpu **new_gpus, int *count, BOOL get_properties ) +static BOOL xrandr14_get_gpus( struct gdi_gpu **new_gpus, int *count, BOOL get_properties ) { static const WCHAR wine_adapterW[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0}; struct gdi_gpu *gpus = NULL; @@ -857,11 +857,6 @@ done: return ret; }
-static BOOL xrandr14_get_gpus( struct gdi_gpu **new_gpus, int *count ) -{ - return xrandr14_get_gpus2( new_gpus, count, TRUE ); -} - static void xrandr14_free_gpus( struct gdi_gpu *gpus ) { free( gpus ); @@ -1244,7 +1239,7 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_p pthread_mutex_lock( &xrandr_mutex ); if (!current_modes) { - if (!xrandr14_get_gpus2( &gpus, &gpu_count, FALSE )) + if (!xrandr14_get_gpus( &gpus, &gpu_count, FALSE )) { pthread_mutex_unlock( &xrandr_mutex ); return FALSE;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/desktop.c | 14 ---- dlls/winex11.drv/display.c | 154 ++++++++++++++++++++++++++++-------- dlls/winex11.drv/x11drv.h | 8 +- dlls/winex11.drv/xrandr.c | 136 +------------------------------ dlls/winex11.drv/xvidmode.c | 17 ---- 5 files changed, 122 insertions(+), 207 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index 7dc149b2e95..a0e24b837b9 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -122,19 +122,6 @@ BOOL is_virtual_desktop(void) return root_window != DefaultRootWindow( gdi_display ); }
-/* Virtual desktop display settings handler */ -static BOOL X11DRV_desktop_get_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary ) -{ - WCHAR primary_adapter[CCHDEVICENAME]; - - if (!get_primary_adapter( primary_adapter ) || wcsicmp( primary_adapter, device_name )) - return FALSE; - - *is_primary = 1; - *id = 0; - return TRUE; -} - static void add_desktop_mode( DEVMODEW *mode, DWORD depth, DWORD width, DWORD height ) { mode->dmSize = sizeof(*mode); @@ -356,7 +343,6 @@ void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) /* Initialize virtual desktop display settings handler */ settings_handler.name = "Virtual Desktop"; settings_handler.priority = 1000; - settings_handler.get_id = X11DRV_desktop_get_id; settings_handler.get_modes = X11DRV_desktop_get_modes; settings_handler.free_modes = X11DRV_desktop_free_modes; settings_handler.get_current_mode = X11DRV_desktop_get_current_mode; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 4465f3765b5..57cf8ca44ef 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -53,31 +53,135 @@ const unsigned int *depths;
static pthread_mutex_t settings_mutex = PTHREAD_MUTEX_INITIALIZER;
-void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handler) +static struct current_mode { - if (new_handler->priority > settings_handler.priority) + ULONG_PTR id; + BOOL loaded; + BOOL primary; + DEVMODEW mode; +} *current_modes; +static int current_mode_count; + +void invalidate_current_mode_cache(void) +{ + pthread_mutex_lock( &settings_mutex ); + free( current_modes); + current_modes = NULL; + current_mode_count = 0; + pthread_mutex_unlock( &settings_mutex ); +} + +static BOOL get_current_mode( ULONG_PTR id, BOOL is_primary, DEVMODEW *mode ) +{ + struct current_mode *mode_ptr = NULL; + BOOL ret = FALSE; + INT mode_idx; + + pthread_mutex_lock( &settings_mutex ); + for (mode_idx = 0; mode_idx < current_mode_count; ++mode_idx) { - settings_handler = *new_handler; - TRACE("Display settings are now handled by: %s.\n", settings_handler.name); + if (current_modes[mode_idx].id != id) + continue; + + if (!current_modes[mode_idx].loaded) + { + mode_ptr = ¤t_modes[mode_idx]; + break; + } + + memcpy( mode, ¤t_modes[mode_idx].mode, sizeof(*mode) ); + pthread_mutex_unlock( &settings_mutex ); + return TRUE; + } + + if ((ret = settings_handler.get_current_mode( id, is_primary, mode )) && mode_ptr) + { + memcpy( &mode_ptr->mode, mode, sizeof(*mode) ); + mode_ptr->mode.dmSize = sizeof(*mode); + mode_ptr->mode.dmDriverExtra = 0; + mode_ptr->loaded = TRUE; } + pthread_mutex_unlock( &settings_mutex ); + return ret; }
-/*********************************************************************** - * Default handlers if resolution switching is not enabled - * - */ -static BOOL nores_get_id(const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary) +static BOOL get_adapter_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary ) { - WCHAR primary_adapter[CCHDEVICENAME]; + struct current_mode *tmp_modes, *new_current_modes = NULL; + INT gpu_count, adapter_count, new_current_mode_count = 0; + INT gpu_idx, adapter_idx, display_idx; + struct gdi_adapter *adapters; + struct gdi_gpu *gpus; + WCHAR *end; + + /* Parse \.\DISPLAY%d */ + display_idx = wcstol( device_name + 11, &end, 10 ) - 1; + if (*end) + return FALSE; + + /* Update cache */ + pthread_mutex_lock( &settings_mutex ); + if (!current_modes) + { + if (!host_handler.get_gpus( &gpus, &gpu_count, FALSE )) + { + pthread_mutex_unlock( &settings_mutex ); + return FALSE; + } + + for (gpu_idx = 0; gpu_idx < gpu_count; ++gpu_idx) + { + if (!host_handler.get_adapters( gpus[gpu_idx].id, &adapters, &adapter_count )) + break; + + tmp_modes = realloc( new_current_modes, (new_current_mode_count + adapter_count) * sizeof(*tmp_modes) ); + if (!tmp_modes) + { + host_handler.free_adapters( adapters ); + break; + } + new_current_modes = tmp_modes;
- if (!get_primary_adapter( primary_adapter )) + for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx) + { + new_current_modes[new_current_mode_count + adapter_idx].id = adapters[adapter_idx].id; + new_current_modes[new_current_mode_count + adapter_idx].loaded = FALSE; + new_current_modes[new_current_mode_count + adapter_idx].primary = !!(adapters[adapter_idx].state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + } + new_current_mode_count += adapter_count; + host_handler.free_adapters( adapters ); + } + host_handler.free_gpus( gpus ); + + if (new_current_modes) + { + free( current_modes ); + current_modes = new_current_modes; + current_mode_count = new_current_mode_count; + } + } + + if (display_idx >= current_mode_count) + { + pthread_mutex_unlock( &settings_mutex ); return FALSE; + }
- *is_primary = !wcsicmp( device_name, primary_adapter ); - *id = *is_primary ? 1 : 0; + *id = current_modes[display_idx].id; + *is_primary = current_modes[display_idx].primary; + pthread_mutex_unlock( &settings_mutex ); return TRUE; }
+void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handler) +{ + if (new_handler->priority > settings_handler.priority) + { + settings_handler = *new_handler; + TRACE("Display settings are now handled by: %s.\n", settings_handler.name); + } +} + static BOOL nores_get_modes(ULONG_PTR id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count) { RECT primary = get_host_primary_monitor_rect(); @@ -154,7 +258,6 @@ void X11DRV_Settings_Init(void)
nores_handler.name = "NoRes"; nores_handler.priority = 1; - nores_handler.get_id = nores_get_id; nores_handler.get_modes = nores_get_modes; nores_handler.free_modes = nores_free_modes; nores_handler.get_current_mode = nores_get_current_mode; @@ -197,24 +300,6 @@ void init_registry_display_settings(void) } }
-BOOL get_primary_adapter(WCHAR *name) -{ - DISPLAY_DEVICEW dd; - DWORD i; - - dd.cb = sizeof(dd); - for (i = 0; !NtUserEnumDisplayDevices( NULL, i, &dd, 0 ); ++i) - { - if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) - { - lstrcpyW(name, dd.DeviceName); - return TRUE; - } - } - - return FALSE; -} - static void set_display_depth(ULONG_PTR display_id, DWORD depth) { struct x11drv_display_depth *display_depth; @@ -273,7 +358,7 @@ BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW devmode ) DEVMODEW mode; ULONG_PTR id;
- if (!settings_handler.get_id( name, &id, &is_primary ) || !settings_handler.get_current_mode( id, is_primary, &mode )) + if (!get_adapter_id( name, &id, &is_primary ) || !get_current_mode( id, is_primary, &mode )) { ERR("Failed to get %s current display settings.\n", wine_dbgstr_w(name)); return FALSE; @@ -391,6 +476,7 @@ static LONG apply_display_settings( DEVMODEW *displays, struct display_info *inf return ret; }
+ invalidate_current_mode_cache(); return DISP_CHANGE_SUCCESSFUL; }
@@ -417,7 +503,7 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, if (!(infos = calloc( count, sizeof(*infos) ))) return DISP_CHANGE_FAILED; for (count = 0, mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode), count++) { - if (!settings_handler.get_id( mode->dmDeviceName, &infos[count].id, &infos[count].is_primary )) goto done; + if (!get_adapter_id( mode->dmDeviceName, &infos[count].id, &infos[count].is_primary )) goto done; mode->dmPosition.x -= left_most; mode->dmPosition.y -= top_most; } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index b5f948fa232..ec9a25d1acc 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -706,12 +706,6 @@ struct x11drv_settings_handler /* Higher priority can override handlers with a lower priority */ UINT priority;
- /* get_id() will be called to map a device name, e.g., \.\DISPLAY1 to a driver specific id. - * Following functions use this id to identify the device. - * - * Return FALSE if the device cannot be found and TRUE on success */ - BOOL (*get_id)(const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary); - /* get_modes() will be called to get a list of supported modes of the device of id in modes * with respect to flags, which could be 0, EDS_RAWMODE or EDS_ROTATEDMODE. If the implementation * uses dmDriverExtra then every DEVMODEW in the list must have the same dmDriverExtra value @@ -747,11 +741,11 @@ extern void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *han extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) DECLSPEC_HIDDEN; extern void X11DRV_resize_desktop(void) DECLSPEC_HIDDEN; extern void init_registry_display_settings(void) DECLSPEC_HIDDEN; +extern void invalidate_current_mode_cache(void) DECLSPEC_HIDDEN; extern BOOL is_virtual_desktop(void) DECLSPEC_HIDDEN; extern BOOL is_desktop_fullscreen(void) DECLSPEC_HIDDEN; extern BOOL is_detached_mode(const DEVMODEW *) DECLSPEC_HIDDEN; extern BOOL create_desktop_win_data( Window win ) DECLSPEC_HIDDEN; -extern BOOL get_primary_adapter(WCHAR *) DECLSPEC_HIDDEN; void X11DRV_Settings_Init(void) DECLSPEC_HIDDEN;
void X11DRV_XF86VM_Init(void) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 42cbe213333..94873f1bf55 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -143,22 +143,6 @@ static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg) return 1; }
-/* XRandR 1.0 display settings handler */ -static BOOL xrandr10_get_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary ) -{ - WCHAR primary_adapter[CCHDEVICENAME]; - - if (!get_primary_adapter( primary_adapter )) - return FALSE; - - /* RandR 1.0 only supports changing the primary adapter settings. - * For non-primary adapters, an id is still provided but getting - * and changing non-primary adapters' settings will be ignored. */ - *is_primary = !wcsicmp( device_name, primary_adapter ); - *id = *is_primary ? 1 : 0; - return TRUE; -} - static void add_xrandr10_mode( DEVMODEW *mode, DWORD depth, DWORD width, DWORD height, DWORD frequency, SizeID size_id ) { @@ -329,26 +313,6 @@ static LONG xrandr10_set_current_mode( ULONG_PTR id, BOOL is_primary, const DEVM
#ifdef HAVE_XRRGETPROVIDERRESOURCES
-static struct current_mode -{ - ULONG_PTR id; - BOOL loaded; - BOOL primary; - DEVMODEW mode; -} *current_modes; -static int current_mode_count; - -static pthread_mutex_t xrandr_mutex = PTHREAD_MUTEX_INITIALIZER; - -static void xrandr14_invalidate_current_mode_cache(void) -{ - pthread_mutex_lock( &xrandr_mutex ); - free( current_modes); - current_modes = NULL; - current_mode_count = 0; - pthread_mutex_unlock( &xrandr_mutex ); -} - static XRRScreenResources *xrandr_get_screen_resources(void) { XRRScreenResources *resources = pXRRGetScreenResourcesCurrent( gdi_display, root_window ); @@ -1192,7 +1156,7 @@ static void xrandr14_free_monitors( struct gdi_monitor *monitors, int count )
static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event ) { - xrandr14_invalidate_current_mode_cache(); + invalidate_current_mode_cache(); if (hwnd == NtUserGetDesktopWindow() && NtUserGetWindowThread( hwnd, NULL ) == GetCurrentThreadId()) { X11DRV_DisplayDevices_Init( TRUE ); @@ -1220,75 +1184,6 @@ static void xrandr14_register_event_handlers(void) "XRandR ProviderChange" ); }
-/* XRandR 1.4 display settings handler */ -static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary ) -{ - struct current_mode *tmp_modes, *new_current_modes = NULL; - INT gpu_count, adapter_count, new_current_mode_count = 0; - INT gpu_idx, adapter_idx, display_idx; - struct gdi_adapter *adapters; - struct gdi_gpu *gpus; - WCHAR *end; - - /* Parse \.\DISPLAY%d */ - display_idx = wcstol( device_name + 11, &end, 10 ) - 1; - if (*end) - return FALSE; - - /* Update cache */ - pthread_mutex_lock( &xrandr_mutex ); - if (!current_modes) - { - if (!xrandr14_get_gpus( &gpus, &gpu_count, FALSE )) - { - pthread_mutex_unlock( &xrandr_mutex ); - return FALSE; - } - - for (gpu_idx = 0; gpu_idx < gpu_count; ++gpu_idx) - { - if (!xrandr14_get_adapters( gpus[gpu_idx].id, &adapters, &adapter_count )) - break; - - tmp_modes = realloc( new_current_modes, (new_current_mode_count + adapter_count) * sizeof(*tmp_modes) ); - if (!tmp_modes) - { - xrandr14_free_adapters( adapters ); - break; - } - new_current_modes = tmp_modes; - - for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx) - { - new_current_modes[new_current_mode_count + adapter_idx].id = adapters[adapter_idx].id; - new_current_modes[new_current_mode_count + adapter_idx].loaded = FALSE; - new_current_modes[new_current_mode_count + adapter_idx].primary = !!(adapters[adapter_idx].state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); - } - new_current_mode_count += adapter_count; - xrandr14_free_adapters( adapters ); - } - xrandr14_free_gpus( gpus ); - - if (new_current_modes) - { - free( current_modes ); - current_modes = new_current_modes; - current_mode_count = new_current_mode_count; - } - } - - if (display_idx >= current_mode_count) - { - pthread_mutex_unlock( &xrandr_mutex ); - return FALSE; - } - - *id = current_modes[display_idx].id; - *is_primary = current_modes[display_idx].primary; - pthread_mutex_unlock( &xrandr_mutex ); - return TRUE; -} - static void add_xrandr14_mode( DEVMODEW *mode, XRRModeInfo *info, DWORD depth, DWORD frequency, DWORD orientation ) { @@ -1436,7 +1331,6 @@ static void xrandr14_free_modes( DEVMODEW *modes )
static BOOL xrandr14_get_current_mode( ULONG_PTR id, BOOL is_primary, DEVMODEW *mode ) { - struct current_mode *mode_ptr = NULL; XRRScreenResources *screen_resources; XRROutputInfo *output_info = NULL; RROutput output = (RROutput)id; @@ -1446,23 +1340,6 @@ static BOOL xrandr14_get_current_mode( ULONG_PTR id, BOOL is_primary, DEVMODEW * RECT primary; INT mode_idx;
- pthread_mutex_lock( &xrandr_mutex ); - for (mode_idx = 0; mode_idx < current_mode_count; ++mode_idx) - { - if (current_modes[mode_idx].id != id) - continue; - - if (!current_modes[mode_idx].loaded) - { - mode_ptr = ¤t_modes[mode_idx]; - break; - } - - memcpy( mode, ¤t_modes[mode_idx].mode, sizeof(*mode) ); - pthread_mutex_unlock( &xrandr_mutex ); - return TRUE; - } - screen_resources = xrandr_get_screen_resources(); if (!screen_resources) goto done; @@ -1523,14 +1400,6 @@ static BOOL xrandr14_get_current_mode( ULONG_PTR id, BOOL is_primary, DEVMODEW * ret = TRUE;
done: - if (ret && mode_ptr) - { - memcpy( &mode_ptr->mode, mode, sizeof(*mode) ); - mode_ptr->mode.dmSize = sizeof(*mode); - mode_ptr->mode.dmDriverExtra = 0; - mode_ptr->loaded = TRUE; - } - pthread_mutex_unlock( &xrandr_mutex ); if (crtc_info) pXRRFreeCrtcInfo( crtc_info ); if (output_info) @@ -1647,7 +1516,6 @@ done: if (output_info) pXRRFreeOutputInfo( output_info ); pXRRFreeScreenResources( screen_resources ); - xrandr14_invalidate_current_mode_cache(); return ret; }
@@ -1676,7 +1544,6 @@ void X11DRV_XRandR_Init(void)
settings_handler.name = "XRandR 1.0"; settings_handler.priority = 200; - settings_handler.get_id = xrandr10_get_id; settings_handler.get_modes = xrandr10_get_modes; settings_handler.free_modes = xrandr10_free_modes; settings_handler.get_current_mode = xrandr10_get_current_mode; @@ -1734,7 +1601,6 @@ void X11DRV_XRandR_Init(void)
settings_handler.name = "XRandR 1.4"; settings_handler.priority = 300; - settings_handler.get_id = xrandr14_get_id; settings_handler.get_modes = xrandr14_get_modes; settings_handler.free_modes = xrandr14_free_modes; settings_handler.get_current_mode = xrandr14_get_current_mode; diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index ca9444712d6..e0e59a8f801 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -84,22 +84,6 @@ static int XVidModeErrorHandler(Display *dpy, XErrorEvent *event, void *arg) return 1; }
-/* XF86VidMode display settings handler */ -static BOOL xf86vm_get_id(const WCHAR *device_name, ULONG_PTR *id, BOOL *is_primary) -{ - WCHAR primary_adapter[CCHDEVICENAME]; - - if (!get_primary_adapter( primary_adapter )) - return FALSE; - - /* XVidMode only supports changing the primary adapter settings. - * For non-primary adapters, an id is still provided but getting - * and changing non-primary adapters' settings will be ignored. */ - *is_primary = !wcsicmp( device_name, primary_adapter ); - *id = *is_primary ? 1 : 0; - return TRUE; -} - static void add_xf86vm_mode(DEVMODEW *mode, DWORD depth, const XF86VidModeModeInfo *mode_info) { mode->dmSize = sizeof(*mode); @@ -312,7 +296,6 @@ void X11DRV_XF86VM_Init(void)
xf86vm_handler.name = "XF86VidMode"; xf86vm_handler.priority = 100; - xf86vm_handler.get_id = xf86vm_get_id; xf86vm_handler.get_modes = xf86vm_get_modes; xf86vm_handler.free_modes = xf86vm_free_modes; xf86vm_handler.get_current_mode = xf86vm_get_current_mode;
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=125187
Your paranoid android.
=== debian11 (build log) ===
Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24867. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24867. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24867.
Sorry, this changes the behavior when virtual desktop mode is used, ignoring the host_handler / desktop_handler redirection in some case.
This merge request was closed by Rémi Bernon.
I don't think it'll work either, the various combination of backends makes it hard and I think in some cases we don't receive notifications about changing devices and the process may just refresh the win32u device from the registry cache without notifying winex11.
I'll close this and go back to the solution passing primary adapter name / bool to the driver callbacks.