winex11.drv: Support virtual desktop display mode enumeration using the new display settings handler interface.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
dd13b27410
commit
0b0ac41981
|
@ -168,6 +168,72 @@ static BOOL X11DRV_desktop_get_id( const WCHAR *device_name, ULONG_PTR *id )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void add_desktop_mode( DEVMODEW *mode, DWORD depth, DWORD width, DWORD height )
|
||||
{
|
||||
mode->dmSize = sizeof(*mode);
|
||||
mode->dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT |
|
||||
DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY;
|
||||
mode->u1.s2.dmDisplayOrientation = DMDO_DEFAULT;
|
||||
mode->dmBitsPerPel = depth;
|
||||
mode->dmPelsWidth = width;
|
||||
mode->dmPelsHeight = height;
|
||||
mode->u2.dmDisplayFlags = 0;
|
||||
mode->dmDisplayFrequency = 60;
|
||||
}
|
||||
|
||||
static BOOL X11DRV_desktop_get_modes( ULONG_PTR id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count )
|
||||
{
|
||||
UINT depth_idx, size_idx, mode_idx = 0;
|
||||
UINT screen_width, screen_height;
|
||||
RECT primary_rect;
|
||||
DEVMODEW *modes;
|
||||
|
||||
primary_rect = get_primary_monitor_rect();
|
||||
screen_width = primary_rect.right - primary_rect.left;
|
||||
screen_height = primary_rect.bottom - primary_rect.top;
|
||||
|
||||
/* Allocate memory for modes in different color depths */
|
||||
if (!(modes = heap_calloc( (ARRAY_SIZE(screen_sizes) + 2) * DEPTH_COUNT, sizeof(*modes))) )
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (depth_idx = 0; depth_idx < DEPTH_COUNT; ++depth_idx)
|
||||
{
|
||||
for (size_idx = 0; size_idx < ARRAY_SIZE(screen_sizes); ++size_idx)
|
||||
{
|
||||
if (screen_sizes[size_idx].width > max_width ||
|
||||
screen_sizes[size_idx].height > max_height)
|
||||
continue;
|
||||
|
||||
if (screen_sizes[size_idx].width == max_width &&
|
||||
screen_sizes[size_idx].height == max_height)
|
||||
continue;
|
||||
|
||||
if (screen_sizes[size_idx].width == screen_width &&
|
||||
screen_sizes[size_idx].height == screen_height)
|
||||
continue;
|
||||
|
||||
add_desktop_mode( &modes[mode_idx++], depths[depth_idx], screen_sizes[size_idx].width,
|
||||
screen_sizes[size_idx].height );
|
||||
}
|
||||
|
||||
add_desktop_mode( &modes[mode_idx++], depths[depth_idx], screen_width, screen_height );
|
||||
if (max_width != screen_width || max_height != screen_height)
|
||||
add_desktop_mode( &modes[mode_idx++], depths[depth_idx], max_width, max_height );
|
||||
}
|
||||
|
||||
*new_modes = modes;
|
||||
*mode_count = mode_idx;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void X11DRV_desktop_free_modes( DEVMODEW *modes )
|
||||
{
|
||||
heap_free( modes );
|
||||
}
|
||||
|
||||
static BOOL X11DRV_desktop_get_current_mode( ULONG_PTR id, DEVMODEW *mode )
|
||||
{
|
||||
RECT primary_rect = get_primary_monitor_rect();
|
||||
|
@ -309,6 +375,8 @@ void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height )
|
|||
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;
|
||||
X11DRV_Settings_SetHandler( &settings_handler );
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ static unsigned int dd_max_modes = 0;
|
|||
*/
|
||||
static const unsigned int depths_24[] = {8, 16, 24};
|
||||
static const unsigned int depths_32[] = {8, 16, 32};
|
||||
const unsigned int *depths;
|
||||
|
||||
/* pointers to functions that actually do the hard stuff */
|
||||
static int (*pGetCurrentMode)(void);
|
||||
|
@ -158,6 +159,9 @@ static LONG X11DRV_nores_SetCurrentMode(int mode)
|
|||
void X11DRV_Settings_Init(void)
|
||||
{
|
||||
RECT primary = get_host_primary_monitor_rect();
|
||||
|
||||
depths = screen_bpp == 32 ? depths_32 : depths_24;
|
||||
|
||||
X11DRV_Settings_SetHandlers("NoRes",
|
||||
X11DRV_nores_GetCurrentMode,
|
||||
X11DRV_nores_SetCurrentMode,
|
||||
|
@ -321,10 +325,12 @@ 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 };
|
||||
DEVMODEW *modes;
|
||||
UINT mode_count;
|
||||
ULONG_PTR id;
|
||||
|
||||
/* Use the new interface if it is available */
|
||||
if (!handler.name || (n != ENUM_REGISTRY_SETTINGS && n != ENUM_CURRENT_SETTINGS))
|
||||
if (!handler.name)
|
||||
goto old_interface;
|
||||
|
||||
if (n == ENUM_REGISTRY_SETTINGS)
|
||||
|
@ -347,6 +353,23 @@ BOOL CDECL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmo
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!handler.get_id(name, &id) || !handler.get_modes(id, flags, &modes, &mode_count))
|
||||
{
|
||||
ERR("Failed to get %s supported display modes.\n", wine_dbgstr_w(name));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (n >= mode_count)
|
||||
{
|
||||
WARN("handler:%s device:%s mode index:%#x not found.\n", handler.name, wine_dbgstr_w(name), n);
|
||||
handler.free_modes(modes);
|
||||
SetLastError(ERROR_NO_MORE_FILES);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(devmode, (BYTE *)modes + (sizeof(*modes) + modes[0].dmDriverExtra) * n, sizeof(*devmode));
|
||||
handler.free_modes(modes);
|
||||
|
||||
done:
|
||||
/* Set generic fields */
|
||||
devmode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod);
|
||||
|
|
|
@ -657,6 +657,9 @@ struct x11drv_mode_info
|
|||
unsigned int refresh_rate;
|
||||
};
|
||||
|
||||
#define DEPTH_COUNT 3
|
||||
extern const unsigned int *depths DECLSPEC_HIDDEN;
|
||||
|
||||
/* Required functions for changing and enumerating display settings */
|
||||
struct x11drv_settings_handler
|
||||
{
|
||||
|
@ -672,6 +675,20 @@ struct x11drv_settings_handler
|
|||
* Return FALSE if the device can not be found and TRUE on success */
|
||||
BOOL (*get_id)(const WCHAR *device_name, ULONG_PTR *id);
|
||||
|
||||
/* 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
|
||||
*
|
||||
* Following fields in DEVMODE must be valid:
|
||||
* dmSize, dmDriverExtra, dmFields, dmDisplayOrientation, dmBitsPerPel, dmPelsWidth, dmPelsHeight,
|
||||
* dmDisplayFlags and dmDisplayFrequency
|
||||
*
|
||||
* Return FALSE on failure with parameters unchanged and error code set. Return TRUE on success */
|
||||
BOOL (*get_modes)(ULONG_PTR id, DWORD flags, DEVMODEW **modes, UINT *mode_count);
|
||||
|
||||
/* free_modes() will be called to free the mode list returned from get_modes() */
|
||||
void (*free_modes)(DEVMODEW *modes);
|
||||
|
||||
/* get_current_mode() will be called to get the current display mode of the device of id
|
||||
*
|
||||
* Following fields in DEVMODE must be valid:
|
||||
|
|
Loading…
Reference in New Issue