From: Fan WenJie fanwj@mail.ustc.edu.cn
fix: https://bugs.winehq.org/show_bug.cgi?id=56993 Signed-off-by: Fan WenJie fanwj@mail.ustc.edu.cn --- dlls/win32u/sysparams.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index edf1a705168..95e860ed502 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -84,6 +84,8 @@ static const char guid_devinterface_display_adapterA[] = "{5B45201D-F2F2-4F3B-85 static const char guid_display_device_arrivalA[] = "{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}"; static const char guid_devinterface_monitorA[] = "{E6F07B5F-EE97-4A90-B076-33F57BF4EAA7}";
+static struct source *find_primary_source(void); + #define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra))
struct gpu @@ -152,6 +154,7 @@ BOOL enable_thunk_lock = FALSE; #define VIRTUAL_HMONITOR ((HMONITOR)(UINT_PTR)(0x10000 + 1)) static struct monitor virtual_monitor = { + .path = "DISPLAY\DEFAULT_MONITOR\FFFF&FFFF", .handle = VIRTUAL_HMONITOR, .rc_monitor.right = 1024, .rc_monitor.bottom = 768, @@ -1388,9 +1391,11 @@ static BOOL write_monitor_to_registry( struct monitor *monitor, const BYTE *edid WCHAR bufferW[1024]; HKEY hkey, subkey; unsigned int len; + struct source* source = monitor->source;
if (!(hkey = reg_create_ascii_key( enum_key, monitor->path, 0, NULL ))) return FALSE;
+ if (!source) source = find_primary_source(); set_reg_ascii_value( hkey, "DeviceDesc", "Generic Non-PnP Monitor" );
set_reg_ascii_value( hkey, "Class", "Monitor" ); @@ -1437,7 +1442,7 @@ static BOOL write_monitor_to_registry( struct monitor *monitor, const BYTE *edid if ((subkey = reg_create_ascii_key( hkey, devpropkey_monitor_gpu_luidA, 0, NULL ))) { set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_INT64, - &monitor->source->gpu->luid, sizeof(monitor->source->gpu->luid) ); + &source->gpu->luid, sizeof(source->gpu->luid) ); NtClose( subkey ); }
@@ -1558,8 +1563,7 @@ static void clear_display_devices(void)
if (list_head( &monitors ) == &virtual_monitor.entry) { - list_init( &monitors ); - return; + list_remove(&virtual_monitor.entry); }
while (!list_empty( &monitors )) @@ -1720,6 +1724,12 @@ static BOOL update_display_cache_from_registry(void) enum_device_keys( "PCI", guid_devclass_displayW, sizeof(guid_devclass_displayW), enum_gpus ); enum_device_keys( "DISPLAY", guid_devclass_monitorW, sizeof(guid_devclass_monitorW), enum_monitors );
+ if (is_virtual_desktop()) + { + if (list_head( &monitors ) != &virtual_monitor.entry) + list_add_head( &monitors, &virtual_monitor.entry ); + } + LIST_FOR_EACH_ENTRY( gpu, &gpus, struct gpu, entry ) { if (!read_gpu_from_registry( gpu )) @@ -1988,10 +1998,9 @@ static BOOL add_virtual_source( struct device_manager_ctx *ctx ) 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 +3266,13 @@ 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 +3333,13 @@ 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; + write_monitor_to_registry(&virtual_monitor, NULL, 0); + ret = DISP_CHANGE_SUCCESSFUL; + } else ret = user_driver->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam );
if (ret == E_NOTIMPL)