-- v3: win32u: Move virtual desktop display settings logic from winex11. win32u: Split default UpdateDisplayDevices implementation to a helper.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 118 ++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 52 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index b941d01e3b7..14ca306219a 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1718,11 +1718,75 @@ static BOOL is_same_devmode( const DEVMODEW *a, const DEVMODEW *b ) a->dmDisplayFrequency == b->dmDisplayFrequency; }
+static BOOL default_update_display_devices( const struct gdi_device_manager *manager, 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. + */ + static const DEVMODEW modes[] = + { + { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmBitsPerPel = 32, .dmPelsWidth = 640, .dmPelsHeight = 480, .dmDisplayFrequency = 60, }, + { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmBitsPerPel = 32, .dmPelsWidth = 800, .dmPelsHeight = 600, .dmDisplayFrequency = 60, }, + { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmBitsPerPel = 32, .dmPelsWidth = 1024, .dmPelsHeight = 768, .dmDisplayFrequency = 60, }, + { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmBitsPerPel = 16, .dmPelsWidth = 640, .dmPelsHeight = 480, .dmDisplayFrequency = 60, }, + { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmBitsPerPel = 16, .dmPelsWidth = 800, .dmPelsHeight = 600, .dmDisplayFrequency = 60, }, + { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmBitsPerPel = 16, .dmPelsWidth = 1024, .dmPelsHeight = 768, .dmDisplayFrequency = 60, }, + }; + static const struct gdi_gpu gpu; + static const struct gdi_adapter adapter = + { + .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE, + }; + struct gdi_monitor monitor = + { + .state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED, + }; + DEVMODEW mode = {{0}}; + UINT i; + + if (!force) return TRUE; + + manager->add_gpu( &gpu, ctx ); + manager->add_adapter( &adapter, ctx ); + + if (!read_adapter_mode( ctx->adapter_key, ENUM_CURRENT_SETTINGS, &mode )) + { + mode = modes[2]; + mode.dmFields |= DM_POSITION; + } + monitor.rc_monitor.right = mode.dmPelsWidth; + monitor.rc_monitor.bottom = mode.dmPelsHeight; + monitor.rc_work.right = mode.dmPelsWidth; + monitor.rc_work.bottom = mode.dmPelsHeight; + + manager->add_monitor( &monitor, ctx ); + for (i = 0; i < ARRAY_SIZE(modes); ++i) + { + if (is_same_devmode( modes + i, &mode )) manager->add_mode( &mode, TRUE, ctx ); + else manager->add_mode( modes + i, FALSE, 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 ); +} + static BOOL update_display_cache( BOOL force ) { HWINSTA winstation = NtUserGetProcessWindowStation(); struct device_manager_ctx ctx = {0}; USEROBJECTFLAGS flags; + BOOL ret;
/* services do not have any adapters, only a virtual monitor */ if (NtUserGetObjectInformation( winstation, UOI_FLAGS, &flags, sizeof(flags), NULL ) @@ -1735,59 +1799,9 @@ static BOOL update_display_cache( BOOL force ) return TRUE; }
- if (!user_driver->pUpdateDisplayDevices( &device_manager, force, &ctx ) && force) - { - /* default implementation: expose an adapter and a monitor with a few standard modes, - * and read / write current display settings from / to the registry. - */ - static const DEVMODEW modes[] = - { - { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmBitsPerPel = 32, .dmPelsWidth = 640, .dmPelsHeight = 480, .dmDisplayFrequency = 60, }, - { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmBitsPerPel = 32, .dmPelsWidth = 800, .dmPelsHeight = 600, .dmDisplayFrequency = 60, }, - { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmBitsPerPel = 32, .dmPelsWidth = 1024, .dmPelsHeight = 768, .dmDisplayFrequency = 60, }, - { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmBitsPerPel = 16, .dmPelsWidth = 640, .dmPelsHeight = 480, .dmDisplayFrequency = 60, }, - { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmBitsPerPel = 16, .dmPelsWidth = 800, .dmPelsHeight = 600, .dmDisplayFrequency = 60, }, - { .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmBitsPerPel = 16, .dmPelsWidth = 1024, .dmPelsHeight = 768, .dmDisplayFrequency = 60, }, - }; - static const struct gdi_gpu gpu; - static const struct gdi_adapter adapter = - { - .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE, - }; - struct gdi_monitor monitor = - { - .state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED, - }; - DEVMODEW mode = {{0}}; - UINT i; - - add_gpu( &gpu, &ctx ); - add_adapter( &adapter, &ctx ); - - if (!read_adapter_mode( ctx.adapter_key, ENUM_CURRENT_SETTINGS, &mode )) - { - mode = modes[2]; - mode.dmFields |= DM_POSITION; - } - monitor.rc_monitor.right = mode.dmPelsWidth; - monitor.rc_monitor.bottom = mode.dmPelsHeight; - monitor.rc_work.right = mode.dmPelsWidth; - monitor.rc_work.bottom = mode.dmPelsHeight; - - add_monitor( &monitor, &ctx ); - for (i = 0; i < ARRAY_SIZE(modes); ++i) - { - if (is_same_devmode( modes + i, &mode )) add_mode( &mode, TRUE, &ctx ); - else add_mode( modes + i, FALSE, &ctx ); - } - } + ret = update_display_devices( &device_manager, force, &ctx ); release_display_manager_ctx( &ctx ); + if (!ret) WARN( "Failed to update display devices\n" );
if (!update_display_cache_from_registry()) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 253 +++++++++++++++++++++++++++-- dlls/win32u/win32u_private.h | 1 + dlls/win32u/winstation.c | 2 + dlls/winex11.drv/desktop.c | 300 +---------------------------------- dlls/winex11.drv/display.c | 45 ++---- dlls/winex11.drv/x11drv.h | 1 - 6 files changed, 258 insertions(+), 344 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 14ca306219a..44ee33c80f0 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -603,7 +603,11 @@ static BOOL adapter_get_current_settings( const struct adapter *adapter, DEVMODE HKEY hkey; BOOL ret;
- if ((ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, is_primary, mode ))) return TRUE; + /* use the default implementation in virtual desktop mode */ + if (is_virtual_desktop()) ret = FALSE; + else ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, is_primary, mode ); + + if (ret) return TRUE;
/* default implementation: read current display settings from the registry. */
@@ -1144,6 +1148,11 @@ struct device_manager_ctx WCHAR gpu_guid[64]; LUID gpu_luid; HKEY adapter_key; + /* for the virtual desktop settings */ + BOOL is_primary; + UINT primary_bpp; + UINT primary_width; + UINT primary_height; };
static void link_device( const WCHAR *instance, const WCHAR *class ) @@ -1594,19 +1603,30 @@ static const struct gdi_device_manager device_manager = add_mode, };
-static void release_display_manager_ctx( struct device_manager_ctx *ctx ) +static void reset_display_manager_ctx( struct device_manager_ctx *ctx ) { - if (ctx->mutex) - { - pthread_mutex_unlock( &display_lock ); - release_display_device_init_mutex( ctx->mutex ); - } + HANDLE mutex = ctx->mutex; + if (ctx->adapter_key) { NtClose( ctx->adapter_key ); last_query_display_time = 0; } if (ctx->gpu_count) cleanup_devices(); + + memset( ctx, 0, sizeof(*ctx) ); + if ((ctx->mutex = mutex)) prepare_devices(); +} + +static void release_display_manager_ctx( struct device_manager_ctx *ctx ) +{ + if (ctx->mutex) + { + pthread_mutex_unlock( &display_lock ); + release_display_device_init_mutex( ctx->mutex ); + ctx->mutex = 0; + } + reset_display_manager_ctx( ctx ); }
static void clear_display_devices(void) @@ -1781,12 +1801,203 @@ static BOOL update_display_devices( const struct gdi_device_manager *manager, BO return default_update_display_devices( manager, force, ctx ); }
-static BOOL update_display_cache( BOOL force ) +/* parse the desktop size specification */ +static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height ) +{ + WCHAR *end; + + *width = wcstoul( size, &end, 10 ); + if (end == size) return FALSE; + if (*end != 'x') return FALSE; + size = end + 1; + *height = wcstoul( size, &end, 10 ); + return !*end; +} + +/* retrieve the default desktop size from the registry */ +static BOOL get_default_desktop_size( unsigned int *width, unsigned int *height ) +{ + static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',0}; + WCHAR buffer[4096]; + KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; + DWORD size; + HKEY hkey; + + /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */ + if (!(hkey = reg_open_hkcu_key( "Software\Wine\Explorer\Desktops" ))) return FALSE; + + size = query_reg_value( hkey, defaultW, value, sizeof(buffer) ); + NtClose( hkey ); + if (!size || value->Type != REG_SZ) return FALSE; + + if (!parse_size( (const WCHAR *)value->Data, width, height )) return FALSE; + return TRUE; +} + +static void desktop_add_gpu( const struct gdi_gpu *gpu, void *param ) +{ +} + +static void desktop_add_adapter( const struct gdi_adapter *adapter, void *param ) +{ + struct device_manager_ctx *ctx = param; + ctx->is_primary = !!(adapter->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_adapter, + desktop_add_monitor, + desktop_add_mode, +}; + +static BOOL desktop_update_display_devices( BOOL force, struct device_manager_ctx *ctx ) +{ + static const struct gdi_gpu gpu; + static const struct gdi_adapter adapter = + { + .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE, + }; + struct gdi_monitor monitor = + { + .state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED, + }; + static struct screen_size + { + unsigned int width; + unsigned int height; + } screen_sizes[] = { + /* 4:3 */ + { 320, 240}, + { 400, 300}, + { 512, 384}, + { 640, 480}, + { 768, 576}, + { 800, 600}, + {1024, 768}, + {1152, 864}, + {1280, 960}, + {1400, 1050}, + {1600, 1200}, + {2048, 1536}, + /* 5:4 */ + {1280, 1024}, + {2560, 2048}, + /* 16:9 */ + {1280, 720}, + {1366, 768}, + {1600, 900}, + {1920, 1080}, + {2560, 1440}, + {3840, 2160}, + /* 16:10 */ + { 320, 200}, + { 640, 400}, + {1280, 800}, + {1440, 900}, + {1680, 1050}, + {1920, 1200}, + {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 = + { + .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmDisplayFrequency = 60, + }; + 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; + + if (!get_default_desktop_size( &screen_width, &screen_height )) + { + screen_width = max_width; + screen_height = max_height; + } + + add_gpu( &gpu, ctx ); + add_adapter( &adapter, ctx ); + if (!read_adapter_mode( ctx->adapter_key, ENUM_CURRENT_SETTINGS, ¤t )) + { + current = mode; + current.dmFields |= DM_POSITION; + current.dmBitsPerPel = desktop_ctx.primary_bpp; + current.dmPelsWidth = screen_width; + current.dmPelsHeight = screen_height; + } + + monitor.rc_monitor.right = current.dmPelsWidth; + monitor.rc_monitor.bottom = current.dmPelsHeight; + monitor.rc_work.right = current.dmPelsWidth; + monitor.rc_work.bottom = current.dmPelsHeight; + add_monitor( &monitor, ctx ); + + for (i = 0; i < ARRAY_SIZE(depths); ++i) + { + mode.dmBitsPerPel = depths[i]; + + for (j = 0; j < ARRAY_SIZE(screen_sizes); ++j) + { + mode.dmPelsWidth = screen_sizes[j].width; + mode.dmPelsHeight = screen_sizes[j].height; + + if (mode.dmPelsWidth > max_width || mode.dmPelsHeight > max_height) continue; + if (mode.dmPelsWidth == max_width && mode.dmPelsHeight == max_height) continue; + if (mode.dmPelsWidth == screen_width && mode.dmPelsHeight == screen_height) continue; + + if (is_same_devmode( &mode, ¤t )) add_mode( ¤t, TRUE, ctx ); + else add_mode( &mode, FALSE, ctx ); + } + + mode.dmPelsWidth = screen_width; + mode.dmPelsHeight = screen_height; + if (is_same_devmode( &mode, ¤t )) add_mode( ¤t, TRUE, ctx ); + else add_mode( &mode, FALSE, ctx ); + + if (max_width != screen_width || max_height != screen_height) + { + mode.dmPelsWidth = max_width; + mode.dmPelsHeight = max_height; + if (is_same_devmode( &mode, ¤t )) add_mode( ¤t, TRUE, ctx ); + else add_mode( &mode, FALSE, ctx ); + } + } + + return TRUE; +} + +BOOL update_display_cache( BOOL force ) { HWINSTA winstation = NtUserGetProcessWindowStation(); struct device_manager_ctx ctx = {0}; + BOOL was_virtual_desktop, ret; USEROBJECTFLAGS flags; - BOOL ret;
/* services do not have any adapters, only a virtual monitor */ if (NtUserGetObjectInformation( winstation, UOI_FLAGS, &flags, sizeof(flags), NULL ) @@ -1799,7 +2010,16 @@ static BOOL update_display_cache( BOOL force ) return TRUE; }
- ret = update_display_devices( &device_manager, force, &ctx ); + 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 ); + } + release_display_manager_ctx( &ctx ); if (!ret) WARN( "Failed to update display devices\n" );
@@ -2909,7 +3129,11 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod if (!(primary = find_adapter_device_by_id( 0 ))) primary_name[0] = 0; else wcscpy( primary_name, primary->device_name );
- if ((ret = user_driver->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam )) == E_NOTIMPL) + /* use the default implementation in virtual desktop mode */ + if (is_virtual_desktop()) ret = E_NOTIMPL; + else ret = user_driver->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam ); + + if (ret == E_NOTIMPL) { /* default implementation: write current display settings to the registry. */ mode = displays; @@ -3081,7 +3305,12 @@ INT get_display_depth( UNICODE_STRING *name ) }
is_primary = !!(device->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); - if ((depth = user_driver->pGetDisplayDepth( device->device_name, is_primary )) < 0) + + /* use the default implementation in virtual desktop mode */ + if (is_virtual_desktop()) depth = -1; + else depth = user_driver->pGetDisplayDepth( device->device_name, is_primary ); + + if (depth < 0) { struct adapter *adapter = CONTAINING_RECORD( device, struct adapter, dev ); DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index ee117ed2637..922fd22fe46 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -182,6 +182,7 @@ extern RECT rect_thread_to_win_dpi( HWND hwnd, RECT rect ) DECLSPEC_HIDDEN; extern HMONITOR monitor_from_point( POINT pt, UINT flags, UINT dpi ) DECLSPEC_HIDDEN; extern HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) DECLSPEC_HIDDEN; extern HMONITOR monitor_from_window( HWND hwnd, UINT flags, UINT dpi ) DECLSPEC_HIDDEN; +extern BOOL update_display_cache( BOOL force ) DECLSPEC_HIDDEN; extern void user_lock(void) DECLSPEC_HIDDEN; extern void user_unlock(void) DECLSPEC_HIDDEN; extern void user_check_not_lock(void) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index 6877136e144..9b97a4b4076 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -183,6 +183,8 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *dev return 0; }
+ /* force update display cache to use virtual desktop display settings */ + if (flags & DF_WINE_CREATE_DESKTOP) update_display_cache( TRUE ); return ret; }
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index 8a5682c1acb..7870e7b3145 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -38,279 +38,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
-static unsigned int max_width; -static unsigned int max_height; -static unsigned int desktop_width; -static unsigned int desktop_height; - -static struct screen_size { - unsigned int width; - unsigned int height; -} screen_sizes[] = { - /* 4:3 */ - { 320, 240}, - { 400, 300}, - { 512, 384}, - { 640, 480}, - { 768, 576}, - { 800, 600}, - {1024, 768}, - {1152, 864}, - {1280, 960}, - {1400, 1050}, - {1600, 1200}, - {2048, 1536}, - /* 5:4 */ - {1280, 1024}, - {2560, 2048}, - /* 16:9 */ - {1280, 720}, - {1366, 768}, - {1600, 900}, - {1920, 1080}, - {2560, 1440}, - {3840, 2160}, - /* 16:10 */ - { 320, 200}, - { 640, 400}, - {1280, 800}, - {1440, 900}, - {1680, 1050}, - {1920, 1200}, - {2560, 1600} -}; +static RECT host_primary_rect;
#define _NET_WM_STATE_REMOVE 0 #define _NET_WM_STATE_ADD 1
-/* parse the desktop size specification */ -static BOOL parse_size( const WCHAR *size, unsigned int *width, unsigned int *height ) -{ - WCHAR *end; - - *width = wcstoul( size, &end, 10 ); - if (end == size) return FALSE; - if (*end != 'x') return FALSE; - size = end + 1; - *height = wcstoul( size, &end, 10 ); - return !*end; -} - -/* retrieve the default desktop size from the registry */ -static BOOL get_default_desktop_size( unsigned int *width, unsigned int *height ) -{ - static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',0}; - WCHAR buffer[4096]; - KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - DWORD size; - HKEY hkey; - - /* @@ Wine registry key: HKCU\Software\Wine\Explorer\Desktops */ - if (!(hkey = open_hkcu_key( "Software\Wine\Explorer\Desktops" ))) return FALSE; - - size = query_reg_value( hkey, defaultW, value, sizeof(buffer) ); - NtClose( hkey ); - if (!size || value->Type != REG_SZ) return FALSE; - - if (!parse_size( (const WCHAR *)value->Data, width, height )) return FALSE; - return TRUE; -} - /* Return TRUE if Wine is currently in virtual desktop mode */ BOOL is_virtual_desktop(void) { return root_window != DefaultRootWindow( gdi_display ); }
-/* Virtual desktop display settings handler */ -static BOOL X11DRV_desktop_get_id( const WCHAR *device_name, BOOL is_primary, x11drv_settings_id *id ) -{ - if (!is_primary) return FALSE; - id->id = 0; - 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( x11drv_settings_id id, DWORD flags, DEVMODEW **new_modes, UINT *mode_count ) -{ - UINT depth_idx, size_idx, mode_idx = 0; - UINT screen_width, screen_height; - DEVMODEW *modes; - - if (!get_default_desktop_size( &screen_width, &screen_height )) - { - screen_width = max_width; - screen_height = max_height; - } - - /* Allocate memory for modes in different color depths */ - if (!(modes = calloc( (ARRAY_SIZE(screen_sizes) + 2) * DEPTH_COUNT, sizeof(*modes))) ) - { - RtlSetLastWin32Error( 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 ) -{ - free( modes ); -} - -static BOOL X11DRV_desktop_get_current_mode( x11drv_settings_id id, DEVMODEW *mode ) -{ - RECT primary_rect = NtUserGetPrimaryMonitorRect(); - - 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 LONG X11DRV_desktop_set_current_mode( x11drv_settings_id id, const DEVMODEW *mode ) -{ - if (mode->dmFields & DM_BITSPERPEL && mode->dmBitsPerPel != screen_bpp) - WARN("Cannot change screen color depth from %dbits to %dbits!\n", - screen_bpp, (int)mode->dmBitsPerPel); - - desktop_width = mode->dmPelsWidth; - desktop_height = mode->dmPelsHeight; - return DISP_CHANGE_SUCCESSFUL; -} - -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}; - UNICODE_STRING str = RTL_CONSTANT_STRING( trayW ); - RECT rect; - HWND hwnd = NtUserFindWindowEx( 0, 0, &str, NULL, 0 ); - - if (!hwnd || !NtUserIsWindowVisible( hwnd )) return; - if (!NtUserGetWindowRect( hwnd, &rect )) return; - if (rect.top) rc_work->bottom = rect.top; - else rc_work->top = rect.bottom; - TRACE( "found tray %p %s work area %s\n", hwnd, wine_dbgstr_rect( &rect ), wine_dbgstr_rect( rc_work ) ); -} - -static BOOL X11DRV_desktop_get_gpus( struct gdi_gpu **new_gpus, int *count ) -{ - static const WCHAR wine_adapterW[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0}; - struct gdi_gpu *gpu; - - gpu = calloc( 1, sizeof(*gpu) ); - if (!gpu) return FALSE; - - if (!get_host_primary_gpu( gpu )) - { - WARN( "Failed to get host primary gpu.\n" ); - lstrcpyW( gpu->name, wine_adapterW ); - } - - *new_gpus = gpu; - *count = 1; - return TRUE; -} - -static void X11DRV_desktop_free_gpus( struct gdi_gpu *gpus ) -{ - free( gpus ); -} - -/* TODO: Support multi-head virtual desktop */ -static BOOL X11DRV_desktop_get_adapters( ULONG_PTR gpu_id, struct gdi_adapter **new_adapters, int *count ) -{ - struct gdi_adapter *adapter; - - adapter = calloc( 1, sizeof(*adapter) ); - if (!adapter) return FALSE; - - adapter->state_flags = DISPLAY_DEVICE_PRIMARY_DEVICE; - if (desktop_width && desktop_height) - adapter->state_flags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP; - - *new_adapters = adapter; - *count = 1; - return TRUE; -} - -static void X11DRV_desktop_free_adapters( struct gdi_adapter *adapters ) -{ - free( adapters ); -} - -static BOOL X11DRV_desktop_get_monitors( ULONG_PTR adapter_id, struct gdi_monitor **new_monitors, int *count ) -{ - struct gdi_monitor *monitor; - - monitor = calloc( 1, sizeof(*monitor) ); - if (!monitor) return FALSE; - - SetRect( &monitor->rc_monitor, 0, 0, desktop_width, desktop_height ); - SetRect( &monitor->rc_work, 0, 0, desktop_width, desktop_height ); - query_desktop_work_area( &monitor->rc_work ); - monitor->state_flags = DISPLAY_DEVICE_ATTACHED; - monitor->edid_len = 0; - monitor->edid = NULL; - if (desktop_width && desktop_height) - monitor->state_flags |= DISPLAY_DEVICE_ACTIVE; - - *new_monitors = monitor; - *count = 1; - return TRUE; -} - -static void X11DRV_desktop_free_monitors( struct gdi_monitor *monitors, int count ) -{ - free( monitors ); -} - /*********************************************************************** * X11DRV_init_desktop * @@ -318,39 +56,11 @@ static void X11DRV_desktop_free_monitors( struct gdi_monitor *monitors, int coun */ 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; - + host_primary_rect = get_host_primary_monitor_rect(); root_window = win; managed_mode = FALSE; /* no managed windows in desktop mode */ - desktop_width = width; - desktop_height = height; - max_width = primary_rect.right; - max_height = primary_rect.bottom; - - /* Initialize virtual desktop display settings handler */ - 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; - settings_handler.set_current_mode = X11DRV_desktop_set_current_mode; - X11DRV_Settings_SetHandler( &settings_handler ); - - /* Initialize virtual desktop mode display device handler */ - desktop_handler.name = "Virtual Desktop"; - desktop_handler.get_gpus = X11DRV_desktop_get_gpus; - desktop_handler.get_adapters = X11DRV_desktop_get_adapters; - desktop_handler.get_monitors = X11DRV_desktop_get_monitors; - desktop_handler.free_gpus = X11DRV_desktop_free_gpus; - desktop_handler.free_adapters = X11DRV_desktop_free_adapters; - desktop_handler.free_monitors = X11DRV_desktop_free_monitors; - desktop_handler.register_event_handlers = NULL; - TRACE("Display device functions are now handled by: Virtual Desktop\n"); }
- /*********************************************************************** * X11DRV_CreateDesktop * @@ -388,8 +98,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height ) BOOL is_desktop_fullscreen(void) { RECT primary_rect = NtUserGetPrimaryMonitorRect(); - return (primary_rect.right - primary_rect.left == max_width && - primary_rect.bottom - primary_rect.top == max_height); + return (primary_rect.right - primary_rect.left == host_primary_rect.right - host_primary_rect.left && + primary_rect.bottom - primary_rect.top == host_primary_rect.bottom - host_primary_rect.top); }
static void update_desktop_fullscreen( unsigned int width, unsigned int height) @@ -406,7 +116,7 @@ static void update_desktop_fullscreen( unsigned int width, unsigned int height) xev.xclient.display = display; xev.xclient.send_event = True; xev.xclient.format = 32; - if (width == max_width && height == max_height) + if (width == host_primary_rect.right - host_primary_rect.left && height == host_primary_rect.bottom - host_primary_rect.top) xev.xclient.data.l[0] = _NET_WM_STATE_ADD; else xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index ab3159dc923..f46c320e89b 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -29,7 +29,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
static struct x11drv_display_device_handler host_handler; -struct x11drv_display_device_handler desktop_handler; static struct x11drv_settings_handler settings_handler;
#define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra)) @@ -414,21 +413,6 @@ RECT get_host_primary_monitor_rect(void) return rect; }
-BOOL get_host_primary_gpu(struct gdi_gpu *gpu) -{ - struct gdi_gpu *gpus; - INT gpu_count; - - if (host_handler.get_gpus(&gpus, &gpu_count) && gpu_count) - { - *gpu = gpus[0]; - host_handler.free_gpus(gpus); - return TRUE; - } - - return FALSE; -} - RECT get_work_area(const RECT *monitor_rect) { Atom type; @@ -499,10 +483,7 @@ void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler
void X11DRV_DisplayDevices_RegisterEventHandlers(void) { - struct x11drv_display_device_handler *handler = is_virtual_desktop() ? &desktop_handler : &host_handler; - - if (handler->register_event_handlers) - handler->register_event_handlers(); + if (host_handler.register_event_handlers) host_handler.register_event_handlers(); }
/* Report whether a display device handler supports detecting dynamic device changes */ @@ -534,7 +515,6 @@ static const char *debugstr_devmodew( const DEVMODEW *devmode )
BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) { - struct x11drv_display_device_handler *handler; struct gdi_adapter *adapters; struct gdi_monitor *monitors; struct gdi_gpu *gpus; @@ -542,17 +522,14 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage INT gpu, adapter, monitor; DEVMODEW *modes, *mode; UINT mode_count; - BOOL virtual_desktop;
if (!force && !force_display_devices_refresh) return TRUE; force_display_devices_refresh = FALSE; - virtual_desktop = is_virtual_desktop(); - handler = virtual_desktop ? &desktop_handler : &host_handler;
- TRACE("via %s\n", wine_dbgstr_a(handler->name)); + TRACE( "via %s\n", debugstr_a(host_handler.name) );
/* Initialize GPUs */ - if (!handler->get_gpus( &gpus, &gpu_count )) return FALSE; + if (!host_handler.get_gpus( &gpus, &gpu_count )) return FALSE; TRACE("GPU count: %d\n", gpu_count);
for (gpu = 0; gpu < gpu_count; gpu++) @@ -560,7 +537,7 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage device_manager->add_gpu( &gpus[gpu], param );
/* Initialize adapters */ - if (!handler->get_adapters(gpus[gpu].id, &adapters, &adapter_count)) break; + if (!host_handler.get_adapters( gpus[gpu].id, &adapters, &adapter_count )) break; TRACE("GPU: %#lx %s, adapter count: %d\n", gpus[gpu].id, wine_dbgstr_w(gpus[gpu].name), adapter_count);
for (adapter = 0; adapter < adapter_count; adapter++) @@ -573,25 +550,21 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage
device_manager->add_adapter( &adapters[adapter], param );
- if (!handler->get_monitors(adapters[adapter].id, &monitors, &monitor_count)) break; + if (!host_handler.get_monitors( adapters[adapter].id, &monitors, &monitor_count )) break; TRACE("adapter: %#lx, monitor count: %d\n", adapters[adapter].id, monitor_count);
/* Initialize monitors */ for (monitor = 0; monitor < monitor_count; monitor++) device_manager->add_monitor( &monitors[monitor], param );
- handler->free_monitors(monitors, monitor_count); + host_handler.free_monitors( monitors, monitor_count );
/* Get the settings handler id for the adapter */ snprintf( buffer, sizeof(buffer), "\\.\DISPLAY%d", adapter + 1 ); asciiz_to_unicode( devname, buffer ); if (!settings_handler.get_id( devname, is_primary, &settings_id )) break;
- /* We don't need to set the win32u current mode when we are in - * virtual desktop mode, and, additionally, skipping this avoids a - * deadlock, since the desktop get_current_mode() implementation - * recurses into win32u. */ - if (!virtual_desktop) settings_handler.get_current_mode( settings_id, ¤t_mode ); + settings_handler.get_current_mode( settings_id, ¤t_mode ); if (!settings_handler.get_modes( settings_id, EDS_ROTATEDMODE, &modes, &mode_count )) continue;
@@ -613,10 +586,10 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage settings_handler.free_modes( modes ); }
- handler->free_adapters(adapters); + host_handler.free_adapters( adapters ); }
- handler->free_gpus(gpus); + host_handler.free_gpus( gpus ); return TRUE; }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index ef3f620dc52..3c41ce60854 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -805,7 +805,6 @@ struct x11drv_display_device_handler void (*register_event_handlers)(void); };
-extern BOOL get_host_primary_gpu(struct gdi_gpu *gpu) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN; extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=133987
Your paranoid android.
=== debian11 (32 bit report) ===
Report validation errors: quartz:vmr7 has no test summary line (early exit of the main process?) quartz:vmr7 has unaccounted for todo messages quartz:vmr7 has unaccounted for skip messages
v3: Use `ARRAY_SIZE(depths)` instead of hardcoded values, rename `desktop_update_display_cache` to `desktop_update_display_devices` to be consistent with the other functions.