From: Fan WenJie fanwj@mail.ustc.edu.cn
Signed-off-by: Fan WenJie fanwj@mail.ustc.edu.cn --- dlls/win32u/sysparams.c | 186 +++++----------------------------------- 1 file changed, 20 insertions(+), 166 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index edf1a705168..3e8175fc08d 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1767,6 +1767,12 @@ static BOOL update_display_cache_from_registry(void)
if ((ret = !list_empty( &sources ) && !list_empty( &monitors ))) last_query_display_time = key.LastWriteTime.QuadPart; + + if (is_virtual_desktop()) + { + if (list_head( &monitors ) != &virtual_monitor.entry) + list_add_head( &monitors, &virtual_monitor.entry ); + } pthread_mutex_unlock( &display_lock ); release_display_device_init_mutex( mutex ); return ret; @@ -1822,176 +1828,12 @@ static NTSTATUS default_update_display_devices( struct device_manager_ctx *ctx ) return STATUS_SUCCESS; }
-/* parse the desktop size specification */ -static BOOL parse_size( const WCHAR *size, DWORD *width, DWORD *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( DWORD *width, DWORD *height ) -{ - 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_ascii_value( hkey, "Default", 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 add_virtual_modes( struct device_manager_ctx *ctx, const DEVMODEW *current, - const DEVMODEW *initial, const DEVMODEW *maximum ) -{ - 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} - }; - UINT depths[] = {8, 16, initial->dmBitsPerPel}, i, j, modes_count; - DEVMODEW *modes; - - if (!(modes = malloc( ARRAY_SIZE(depths) * (ARRAY_SIZE(screen_sizes) + 2) * sizeof(*modes) ))) return; - - for (modes_count = i = 0; i < ARRAY_SIZE(depths); ++i) - { - DEVMODEW mode = - { - .dmSize = sizeof(mode), - .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmDisplayFrequency = 60, - .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 > maximum->dmPelsWidth || mode.dmPelsHeight > maximum->dmPelsHeight) continue; - if (mode.dmPelsWidth == maximum->dmPelsWidth && mode.dmPelsHeight == maximum->dmPelsHeight) continue; - if (mode.dmPelsWidth == initial->dmPelsWidth && mode.dmPelsHeight == initial->dmPelsHeight) continue; - modes[modes_count++] = mode; - } - - mode.dmPelsWidth = initial->dmPelsWidth; - mode.dmPelsHeight = initial->dmPelsHeight; - modes[modes_count++] = mode; - - if (maximum->dmPelsWidth != initial->dmPelsWidth || maximum->dmPelsWidth != initial->dmPelsHeight) - { - mode.dmPelsWidth = maximum->dmPelsWidth; - mode.dmPelsHeight = maximum->dmPelsHeight; - modes[modes_count++] = mode; - } - } - - add_modes( current, modes_count, modes, ctx ); - free( modes ); -} - -static BOOL add_virtual_source( struct device_manager_ctx *ctx ) -{ - DEVMODEW current = {.dmSize = sizeof(current)}, initial = ctx->primary, maximum = ctx->primary; - 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, - }; - struct gdi_monitor monitor = {0}; - - /* 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 STATUS_UNSUCCESSFUL; - } - - ctx->source = virtual_source; - ctx->gpu.source_count++; - ctx->source_count++; - - if (!get_default_desktop_size( &initial.dmPelsWidth, &initial.dmPelsHeight )) - { - initial.dmPelsWidth = maximum.dmPelsWidth; - initial.dmPelsHeight = maximum.dmPelsHeight; - } - - if (!read_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, ¤t )) - { - current = ctx->primary; - current.dmDisplayFrequency = 60; - current.dmPelsWidth = initial.dmPelsWidth; - current.dmPelsHeight = initial.dmPelsHeight; - } - - 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 ); - add_virtual_modes( ctx, ¤t, &initial, &maximum ); - - return STATUS_SUCCESS; -} - static UINT update_display_devices( struct device_manager_ctx *ctx ) { UINT status;
if (!(status = user_driver->pUpdateDisplayDevices( &device_manager, ctx ))) { - if (ctx->source_count && is_virtual_desktop()) return add_virtual_source( ctx ); return status; }
@@ -3257,7 +3099,14 @@ static void display_mode_changed( BOOL broadcast ) ERR( "Failed to update display cache after mode change.\n" ); return; } - if (!get_primary_source_mode( ¤t_mode )) + + if (is_virtual_desktop()) + { + current_mode.dmPelsWidth = virtual_monitor.rc_monitor.right - virtual_monitor.rc_monitor.left; + current_mode.dmPelsHeight = virtual_monitor.rc_monitor.bottom - virtual_monitor.rc_monitor.top; + current_mode.dmBitsPerPel = 32; + } + else if (!get_primary_source_mode( ¤t_mode )) { ERR( "Failed to get primary source current display settings.\n" ); return; @@ -3318,7 +3167,12 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo }
/* use the default implementation in virtual desktop mode */ - if (is_virtual_desktop()) ret = E_NOTIMPL; + if (is_virtual_desktop()) + { + RECT rect = { 0, 0, displays->dmPelsWidth, displays->dmPelsHeight }; + virtual_monitor.rc_monitor = virtual_monitor.rc_work = rect; + ret = DISP_CHANGE_SUCCESSFUL; + } else ret = user_driver->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam );
if (ret == E_NOTIMPL)