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;