From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 118 +++++++++++++++++------------------- dlls/winex11.drv/xinerama.c | 3 - dlls/winex11.drv/xrandr.c | 1 - 3 files changed, 54 insertions(+), 68 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 26bddad7b59..077a3c35163 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1313,6 +1313,10 @@ static void add_source( const char *name, UINT state_flags, void *param )
TRACE( "name %s, state_flags %#x\n", name, state_flags );
+ /* in virtual desktop mode, report all physical sources as detached */ + ctx->is_primary = !!(state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + if (is_virtual_desktop()) state_flags &= ~(DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE); + memset( &ctx->source, 0, sizeof(ctx->source) ); ctx->source.gpu = &ctx->gpu; ctx->source.id = ctx->source_count; @@ -1448,11 +1452,17 @@ static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW { struct device_manager_ctx *ctx = param; const DEVMODEW *mode; - DEVMODEW dummy; + DEVMODEW dummy, detached = *current;
TRACE( "current %s, modes_count %u, modes %p, param %p\n", debugstr_devmodew( current ), modes_count, modes, param );
- if (!read_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, &dummy )) + if (ctx->is_primary) ctx->primary = *current; + + detached.dmPelsWidth = 0; + detached.dmPelsHeight = 0; + if (!(ctx->source.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) current = &detached; + + if (current == &detached || !read_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, &dummy )) write_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, current ); write_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, current );
@@ -1720,7 +1730,7 @@ static BOOL update_display_cache_from_registry(void) return ret; }
-static BOOL default_update_display_devices( const struct gdi_device_manager *manager, BOOL force, struct device_manager_ctx *ctx ) +static BOOL default_update_display_devices( BOOL force, struct device_manager_ctx *ctx ) { /* default implementation: expose an adapter and a monitor with a few standard modes, * and read / write current display settings from / to the registry. @@ -1747,8 +1757,8 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man
if (!force) return TRUE;
- manager->add_gpu( &gpu, ctx ); - manager->add_source( "Default", source_flags, ctx ); + add_gpu( &gpu, ctx ); + add_source( "Default", source_flags, ctx );
if (!read_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, &mode )) { @@ -1760,18 +1770,12 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man monitor.rc_work.right = mode.dmPelsWidth; monitor.rc_work.bottom = mode.dmPelsHeight;
- manager->add_monitor( &monitor, ctx ); - manager->add_modes( &mode, ARRAY_SIZE(modes), modes, ctx ); + add_monitor( &monitor, ctx ); + add_modes( &mode, ARRAY_SIZE(modes), modes, ctx );
return TRUE; }
-static BOOL update_display_devices( const struct gdi_device_manager *manager, BOOL force, struct device_manager_ctx *ctx ) -{ - if (user_driver->pUpdateDisplayDevices( manager, force, ctx )) return TRUE; - return default_update_display_devices( manager, force, ctx ); -} - /* parse the desktop size specification */ static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height ) { @@ -1804,38 +1808,8 @@ static BOOL get_default_desktop_size( unsigned int *width, unsigned int *height return TRUE; }
-static void desktop_add_gpu( const struct gdi_gpu *gpu, void *param ) -{ -} - -static void desktop_add_source( const char *name, UINT state_flags, void *param ) +static BOOL add_virtual_source( struct device_manager_ctx *ctx ) { - struct device_manager_ctx *ctx = param; - ctx->is_primary = !!(state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); -} - -static void desktop_add_monitor( const struct gdi_monitor *monitor, void *param ) -{ -} - -static void desktop_add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param ) -{ - struct device_manager_ctx *ctx = param; - if (ctx->is_primary) ctx->primary = *current; -} - -static const struct gdi_device_manager desktop_device_manager = -{ - desktop_add_gpu, - desktop_add_source, - desktop_add_monitor, - desktop_add_modes, -}; - -static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ctx *ctx ) -{ - static const DWORD source_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE; - static const struct gdi_gpu gpu; struct gdi_monitor monitor = {0}; static struct screen_size { @@ -1875,19 +1849,34 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct {2560, 1600} };
- struct device_manager_ctx desktop_ctx = {0}; UINT screen_width, screen_height, max_width, max_height, modes_count; unsigned int depths[] = {8, 16, 0}; + struct source virtual_source = + { + .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE, + .id = ctx->source_count, + .gpu = &ctx->gpu, + }; DEVMODEW current, *modes; UINT i, j;
- if (!force) return TRUE; - /* in virtual desktop mode, read the device list from the user driver but expose virtual devices */ - if (!update_display_devices( &desktop_device_manager, TRUE, &desktop_ctx )) return FALSE; + /* Wine specific config key where source settings will be held, symlinked with the logically indexed config key */ + snprintf( virtual_source.path, sizeof(virtual_source.path), "%s\%s\Video\%s\Sources\%s", config_keyA, + control_keyA + strlen( "\Registry\Machine" ), virtual_source.gpu->guid, "Virtual" ); + + if (!write_source_to_registry( &virtual_source, &ctx->source_key )) + { + WARN( "Failed to write source to registry\n" ); + return FALSE; + } + + ctx->source = virtual_source; + ctx->gpu.source_count++; + ctx->source_count++;
- max_width = desktop_ctx.primary.dmPelsWidth; - max_height = desktop_ctx.primary.dmPelsHeight; - depths[ARRAY_SIZE(depths) - 1] = desktop_ctx.primary.dmBitsPerPel; + max_width = ctx->primary.dmPelsWidth; + max_height = ctx->primary.dmPelsHeight; + depths[ARRAY_SIZE(depths) - 1] = ctx->primary.dmBitsPerPel;
if (!get_default_desktop_size( &screen_width, &screen_height )) { @@ -1895,11 +1884,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct screen_height = max_height; }
- add_gpu( &gpu, ctx ); - add_source( "Default", source_flags, ctx ); if (!read_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, ¤t )) { - current = desktop_ctx.primary; + current = ctx->primary; current.dmPelsWidth = screen_width; current.dmPelsHeight = screen_height; } @@ -1950,13 +1937,24 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct return TRUE; }
+static BOOL update_display_devices( BOOL force, struct device_manager_ctx *ctx ) +{ + if (user_driver->pUpdateDisplayDevices( &device_manager, force, ctx )) + { + if (ctx->source_count && is_virtual_desktop()) return add_virtual_source( ctx ); + return TRUE; + } + + return default_update_display_devices( force, ctx ); +} + BOOL update_display_cache( BOOL force ) { static const WCHAR wine_service_station_name[] = {'_','_','w','i','n','e','s','e','r','v','i','c','e','_','w','i','n','s','t','a','t','i','o','n',0}; HWINSTA winstation = NtUserGetProcessWindowStation(); struct device_manager_ctx ctx = {0}; - BOOL was_virtual_desktop, ret; + BOOL ret; WCHAR name[MAX_PATH];
/* services do not have any adapters, only a virtual monitor */ @@ -1970,15 +1968,7 @@ BOOL update_display_cache( BOOL force ) return TRUE; }
- if ((was_virtual_desktop = is_virtual_desktop())) ret = TRUE; - else ret = update_display_devices( &device_manager, force, &ctx ); - - /* as update_display_devices calls the user driver, it starts explorer and may change the virtual desktop state */ - if (ret && is_virtual_desktop()) - { - reset_display_manager_ctx( &ctx ); - ret = desktop_update_display_devices( force || !was_virtual_desktop, &ctx ); - } + ret = update_display_devices( force, &ctx );
release_display_manager_ctx( &ctx ); if (!ret) WARN( "Failed to update display devices\n" ); diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c index 426ea6c11d4..fbf80819204 100644 --- a/dlls/winex11.drv/xinerama.c +++ b/dlls/winex11.drv/xinerama.c @@ -344,9 +344,6 @@ void xinerama_init( unsigned int width, unsigned int height ) int i; RECT rect;
- if (is_virtual_desktop()) - return; - pthread_mutex_lock( &xinerama_mutex );
SetRect( &rect, 0, 0, width, height ); diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 0e7b9a07818..002ab77c086 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -1662,7 +1662,6 @@ void X11DRV_XRandR_Init(void)
if (major) return; /* already initialized? */ if (!usexrandr) return; /* disabled in config */ - if (is_virtual_desktop()) return; if (!(ret = load_xrandr())) return; /* can't load the Xrandr library */
/* see if Xrandr is available */