The old display settings handler interface can only support one adapter.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/winex11.drv/desktop.c | 41 +++++++++++++++++++++++++++++++ dlls/winex11.drv/settings.c | 48 +++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 27 +++++++++++++++++++++ 3 files changed, 116 insertions(+)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index b5894d5e028..d3dcf90fb9d 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -2,6 +2,7 @@ * X11DRV desktop window handling * * Copyright 2001 Alexandre Julliard + * Copyright 2020 Zhiyi Zhang for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +23,9 @@ #include <X11/cursorfont.h> #include <X11/Xlib.h>
+#define NONAMELESSSTRUCT +#define NONAMELESSUNION + #include "x11drv.h"
/* avoid conflict with field names in included win32 headers */ @@ -152,6 +156,35 @@ static LONG X11DRV_desktop_SetCurrentMode(int mode) return DISP_CHANGE_SUCCESSFUL; }
+/* Virtual desktop display settings handler */ +static BOOL X11DRV_desktop_get_id( const WCHAR *device_name, ULONG_PTR *id ) +{ + WCHAR primary_adapter[CCHDEVICENAME]; + + if (!get_primary_adapter( primary_adapter ) || lstrcmpiW( primary_adapter, device_name )) + return FALSE; + + *id = 0; + return TRUE; +} + +static BOOL X11DRV_desktop_get_current_mode( ULONG_PTR id, DEVMODEW *mode ) +{ + RECT primary_rect = get_primary_monitor_rect(); + + mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | + DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION; + mode->u1.s2.dmDisplayOrientation = DMDO_DEFAULT; + 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 void query_desktop_work_area( RECT *rc_work ) { static const WCHAR trayW[] = {'S','h','e','l','l','_','T','r','a','y','W','n','d',0}; @@ -242,6 +275,7 @@ static void X11DRV_desktop_free_monitors( struct x11drv_monitor *monitors ) void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) { RECT primary_rect = get_host_primary_monitor_rect(); + struct x11drv_settings_handler settings_handler;
root_window = win; managed_mode = FALSE; /* no managed windows in desktop mode */ @@ -270,6 +304,13 @@ void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) make_modes(); X11DRV_Settings_AddDepthModes(); dd_mode_count = X11DRV_Settings_GetModeCount(); + + /* TODO: Remove the old display settings handler once the migration to the new interface is done */ + settings_handler.name = "Virtual Desktop"; + settings_handler.priority = 1000; + settings_handler.get_id = X11DRV_desktop_get_id; + settings_handler.get_current_mode = X11DRV_desktop_get_current_mode; + X11DRV_Settings_SetHandler( &settings_handler ); }
diff --git a/dlls/winex11.drv/settings.c b/dlls/winex11.drv/settings.c index bbbb6fdf0a3..e0dee951543 100644 --- a/dlls/winex11.drv/settings.c +++ b/dlls/winex11.drv/settings.c @@ -2,6 +2,7 @@ * Wine X11drv display settings functions * * Copyright 2003 Alexander James Pasadyn + * Copyright 2020 Zhiyi Zhang for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -125,6 +126,18 @@ unsigned int X11DRV_Settings_GetModeCount(void) return dd_mode_count; }
+/* TODO: Remove the old display settings handler interface once all backends are migrated to the new interface */ +static struct x11drv_settings_handler handler; + +void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handler) +{ + if (new_handler->priority > handler.priority) + { + handler = *new_handler; + TRACE("Display settings are now handled by: %s.\n", handler.name); + } +} + /*********************************************************************** * Default handlers if resolution switching is not enabled * @@ -308,7 +321,42 @@ BOOL CDECL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmo { static const WCHAR dev_name[CCHDEVICENAME] = { 'W','i','n','e',' ','X','1','1',' ','d','r','i','v','e','r',0 }; + ULONG_PTR id;
+ /* Use the new interface if it is available */ + if (!handler.name || (n != ENUM_REGISTRY_SETTINGS && n != ENUM_CURRENT_SETTINGS)) + goto old_interface; + + if (n == ENUM_REGISTRY_SETTINGS) + { + if (!read_registry_settings(name, devmode)) + { + ERR("Failed to get %s registry display settings.\n", wine_dbgstr_w(name)); + return FALSE; + } + goto done; + } + + if (n == ENUM_CURRENT_SETTINGS) + { + if (!handler.get_id(name, &id) || !handler.get_current_mode(id, devmode)) + { + ERR("Failed to get %s current display settings.\n", wine_dbgstr_w(name)); + return FALSE; + } + goto done; + } + +done: + /* Set generic fields */ + devmode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod); + devmode->dmDriverExtra = 0; + devmode->dmSpecVersion = DM_SPECVERSION; + devmode->dmDriverVersion = DM_SPECVERSION; + lstrcpyW(devmode->dmDeviceName, dev_name); + return TRUE; + +old_interface: devmode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod); devmode->dmSpecVersion = DM_SPECVERSION; devmode->dmDriverVersion = DM_SPECVERSION; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 9bbb48f1eeb..49059e09b70 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -657,6 +657,33 @@ struct x11drv_mode_info unsigned int refresh_rate; };
+/* Required functions for changing and enumerating display settings */ +struct x11drv_settings_handler +{ + /* A name to tell what host driver is used */ + const char *name; + + /* 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 can not be found and TRUE on success */ + BOOL (*get_id)(const WCHAR *device_name, ULONG_PTR *id); + + /* get_current_mode() will be called to get the current display mode of the device of id + * + * Following fields in DEVMODE must be valid: + * dmFields, dmDisplayOrientation, dmBitsPerPel, dmPelsWidth, dmPelsHeight, dmDisplayFlags, + * 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); +}; + +extern void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *handler) DECLSPEC_HIDDEN; + extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) DECLSPEC_HIDDEN; extern void X11DRV_resize_desktop(BOOL) DECLSPEC_HIDDEN; extern BOOL is_virtual_desktop(void) DECLSPEC_HIDDEN;