From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 105 ++++++++++++----------------------- dlls/win32u/win32u_private.h | 2 +- dlls/win32u/winstation.c | 4 +- dlls/winex11.drv/xinerama.c | 5 +- dlls/winex11.drv/xrandr.c | 3 +- 5 files changed, 42 insertions(+), 77 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 988da5a7641..5fdaa74856d 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -921,6 +921,7 @@ struct device_manager_ctx struct source source; HKEY source_key; /* for the virtual desktop settings */ + BOOL source_attached; BOOL is_primary; UINT primary_bpp; UINT primary_width; @@ -1306,6 +1307,10 @@ static void add_source( const char *name, UINT state_flags, void *param ) ctx->source_key = NULL; }
+ ctx->is_primary = !!(state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + if (state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) ctx->source_attached = TRUE; + else state_flags &= ~DISPLAY_DEVICE_PRIMARY_DEVICE; + memset( &ctx->source, 0, sizeof(ctx->source) ); ctx->source.gpu = &ctx->gpu; ctx->source.id = ctx->source_count; @@ -1449,6 +1454,13 @@ static void add_mode( const DEVMODEW *mode, BOOL current, void *param ) add_source( "Default", source_flags, ctx ); }
+ if (ctx->is_primary && current) + { + ctx->primary_bpp = mode->dmBitsPerPel; + ctx->primary_width = mode->dmPelsWidth; + ctx->primary_height = mode->dmPelsHeight; + } + nopos_mode = *mode; nopos_mode.dmPosition.x = 0; nopos_mode.dmPosition.y = 0; @@ -1783,12 +1795,6 @@ static BOOL default_update_display_devices( const struct gdi_device_manager *man 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 ) { @@ -1821,44 +1827,9 @@ 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 ) -{ - 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_mode( const DEVMODEW *mode, BOOL current, void *param ) -{ - struct device_manager_ctx *ctx = param; - - if (ctx->is_primary && current) - { - ctx->primary_bpp = mode->dmBitsPerPel; - ctx->primary_width = mode->dmPelsWidth; - ctx->primary_height = mode->dmPelsHeight; - } -} - -static const struct gdi_device_manager desktop_device_manager = -{ - desktop_add_gpu, - desktop_add_source, - desktop_add_monitor, - desktop_add_mode, -}; - -static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ctx *ctx ) +static BOOL add_virtual_source( struct device_manager_ctx *ctx, BOOL use_current ) { 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 { @@ -1898,7 +1869,6 @@ 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; unsigned int depths[] = {8, 16, 0}; DEVMODEW current, mode = @@ -1908,13 +1878,9 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct }; 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; - - max_width = desktop_ctx.primary_width; - max_height = desktop_ctx.primary_height; - depths[ARRAY_SIZE(depths) - 1] = desktop_ctx.primary_bpp; + max_width = ctx->primary_width; + max_height = ctx->primary_height; + depths[ARRAY_SIZE(depths) - 1] = ctx->primary_bpp;
if (!get_default_desktop_size( &screen_width, &screen_height )) { @@ -1922,13 +1888,12 @@ 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 )) + add_source( "Virtual", source_flags, ctx ); + if (!use_current || !read_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, ¤t )) { current = mode; current.dmFields |= DM_POSITION; - current.dmBitsPerPel = desktop_ctx.primary_bpp; + current.dmBitsPerPel = ctx->primary_bpp; current.dmPelsWidth = screen_width; current.dmPelsHeight = screen_height; } @@ -1973,13 +1938,25 @@ static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ct return TRUE; }
-BOOL update_display_cache( BOOL force ) +static BOOL update_display_devices( BOOL force, BOOL use_current, struct device_manager_ctx *ctx ) +{ + if (user_driver->pUpdateDisplayDevices( &device_manager, force, ctx )) + { + if (is_virtual_desktop() && ctx->source_count && !ctx->source_attached) + return add_virtual_source( ctx, use_current ); + return TRUE; + } + + return default_update_display_devices( &device_manager, force, ctx ); +} + +BOOL update_display_cache( BOOL force, BOOL use_current ) { 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 */ @@ -1993,15 +1970,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, use_current, &ctx );
release_display_manager_ctx( &ctx ); if (!ret) WARN( "Failed to update display devices\n" ); @@ -2020,7 +1989,7 @@ BOOL update_display_cache( BOOL force ) return FALSE; }
- return update_display_cache( TRUE ); + return update_display_cache( TRUE, use_current ); }
return TRUE; @@ -2028,7 +1997,7 @@ BOOL update_display_cache( BOOL force )
static BOOL lock_display_devices(void) { - if (!update_display_cache( FALSE )) return FALSE; + if (!update_display_cache( FALSE, TRUE )) return FALSE; pthread_mutex_lock( &display_lock ); return TRUE; } @@ -3232,7 +3201,7 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo free( displays ); if (ret) return ret;
- if (!update_display_cache( TRUE )) + if (!update_display_cache( TRUE, TRUE )) WARN( "Failed to update display cache after mode change.\n" );
if ((source = find_source( NULL ))) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index ff861db4dd9..d0d13ed78dd 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -187,7 +187,7 @@ extern RECT rect_thread_to_win_dpi( HWND hwnd, RECT rect ); extern HMONITOR monitor_from_point( POINT pt, UINT flags, UINT dpi ); extern HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ); extern HMONITOR monitor_from_window( HWND hwnd, UINT flags, UINT dpi ); -extern BOOL update_display_cache( BOOL force ); +extern BOOL update_display_cache( BOOL force, BOOL use_current ); extern void user_lock(void); extern void user_unlock(void); extern void user_check_not_lock(void); diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index 6ddd5411f94..a6167f015be 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -184,7 +184,7 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *dev }
/* force update display cache to use virtual desktop display settings */ - if (flags & DF_WINE_VIRTUAL_DESKTOP) update_display_cache( TRUE ); + if (flags & DF_WINE_VIRTUAL_DESKTOP) update_display_cache( TRUE, FALSE ); return ret; }
@@ -264,7 +264,7 @@ BOOL WINAPI NtUserSetThreadDesktop( HDESK handle ) thread_info->client_info.top_window = 0; thread_info->client_info.msg_window = 0; if (key_state_info) key_state_info->time = 0; - if (was_virtual_desktop != is_virtual_desktop()) update_display_cache( TRUE ); + if (was_virtual_desktop != is_virtual_desktop()) update_display_cache( TRUE, FALSE ); } return ret; } diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c index 426ea6c11d4..4422a7f73b6 100644 --- a/dlls/winex11.drv/xinerama.c +++ b/dlls/winex11.drv/xinerama.c @@ -259,7 +259,7 @@ static BOOL xinerama_get_adapters( ULONG_PTR gpu_id, struct x11drv_adapter **new if (i == primary_index) adapters[index].state_flags |= DISPLAY_DEVICE_PRIMARY_DEVICE;
- if (!IsRectEmpty( &monitors[i].rcMonitor )) + if (!IsRectEmpty( &monitors[i].rcMonitor ) && !is_virtual_desktop()) adapters[index].state_flags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
index++; @@ -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..8054b6ed4e2 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -983,7 +983,7 @@ static BOOL xrandr14_get_adapters( ULONG_PTR gpu_id, struct x11drv_adapter **new /* Use RROutput as adapter id. The reason of not using RRCrtc is that we need to detect inactive but * attached monitors */ adapters[adapter_count].id = outputs[i]; - if (!detached) + if (!detached && !is_virtual_desktop()) adapters[adapter_count].state_flags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP; if (is_crtc_primary( primary_rect, crtc_info )) { @@ -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 */