winex11.drv: Migrate the virtual desktop display settings handler to a new interface.

The old display settings handler interface can only support one adapter.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2020-07-22 15:24:30 +08:00 committed by Alexandre Julliard
parent 6436600db5
commit dd13b27410
3 changed files with 116 additions and 0 deletions

View File

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

View File

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

View File

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