[PATCH v2 0/7] MR5262: win32u: Refactor monitor cache to only store the necessary information.
-- v2: win32u: Enumerate monitors from their device keys. win32u: Get rid of the monitor flags. win32u: Get rid of the adapter display_device. win32u: Get rid of the monitor state_flags. win32u: Get rid of the monitor display_device. win32u: Split writing monitor to registry to a separate helper. win32u: Add an adapter struct to the device manager context. https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 44 +++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 6c4223f0cdb..dee9632d527 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -125,7 +125,8 @@ struct adapter unsigned int id; struct gpu *gpu; const WCHAR *config_key; - unsigned int mode_count; + UINT monitor_count; + UINT mode_count; DEVMODEW *modes; }; @@ -994,13 +995,12 @@ static unsigned int format_date( WCHAR *bufferW, LONGLONG time ) struct device_manager_ctx { - unsigned int gpu_count; - unsigned int video_count; - unsigned int monitor_count; - unsigned int output_count; - unsigned int mode_count; + UINT gpu_count; + UINT adapter_count; + UINT monitor_count; HANDLE mutex; struct gpu gpu; + struct adapter adapter; HKEY adapter_key; /* for the virtual desktop settings */ BOOL is_primary; @@ -1276,9 +1276,6 @@ static void add_gpu( const struct gdi_gpu *gpu, void *param ) lstrcpyW( ctx->gpu.name, gpu->name ); ctx->gpu.vulkan_uuid = gpu->vulkan_uuid; - ctx->monitor_count = 0; - ctx->mode_count = 0; - sprintf( ctx->gpu.path, "PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\%08X", gpu->vendor_id, gpu->device_id, gpu->subsys_id, gpu->revision_id, ctx->gpu.index ); if (!(hkey = reg_create_ascii_key( enum_key, ctx->gpu.path, 0, NULL ))) return; @@ -1329,7 +1326,7 @@ static void add_gpu( const struct gdi_gpu *gpu, void *param ) static void add_adapter( const struct gdi_adapter *adapter, void *param ) { struct device_manager_ctx *ctx = param; - unsigned int adapter_index, video_index, len; + unsigned int adapter_index, len; char name[64], buffer[MAX_PATH]; WCHAR bufferW[MAX_PATH]; HKEY hkey; @@ -1343,24 +1340,23 @@ static void add_adapter( const struct gdi_adapter *adapter, void *param ) } adapter_index = ctx->gpu.adapter_count++; - video_index = ctx->video_count++; - ctx->monitor_count = 0; - ctx->mode_count = 0; - snprintf( buffer, ARRAY_SIZE(buffer), "\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\%s\\%04x", - ctx->gpu.guid, adapter_index ); + memset( &ctx->adapter, 0, sizeof(ctx->adapter) ); + ctx->adapter.gpu = &ctx->gpu; + ctx->adapter.id = ctx->adapter_count++; + + snprintf( buffer, ARRAY_SIZE(buffer), "%s\\Video\\%s\\%04x", control_keyA, ctx->gpu.guid, adapter_index ); len = asciiz_to_unicode( bufferW, buffer ) - sizeof(WCHAR); hkey = reg_create_ascii_key( NULL, buffer, REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, NULL ); if (!hkey) hkey = reg_create_ascii_key( NULL, buffer, REG_OPTION_VOLATILE | REG_OPTION_OPEN_LINK, NULL ); - sprintf( name, "\\Device\\Video%u", video_index ); + sprintf( name, "\\Device\\Video%u", ctx->adapter.id ); set_reg_ascii_value( video_key, name, buffer ); if (hkey) { - sprintf( buffer, "\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\" - "%s\\%04X", guid_devclass_displayA, ctx->gpu_count - 1 ); + sprintf( buffer, "%s\\Class\\%s\\%04X", control_keyA, guid_devclass_displayA, ctx->gpu.index ); len = asciiz_to_unicode( bufferW, buffer ) - sizeof(WCHAR); set_reg_value( hkey, symbolic_link_valueW, REG_LINK, bufferW, len ); NtClose( hkey ); @@ -1387,8 +1383,8 @@ static void add_monitor( const struct gdi_monitor *monitor, void *param ) HKEY hkey, subkey; unsigned int len; - monitor_index = ctx->monitor_count++; - output_index = ctx->output_count++; + monitor_index = ctx->adapter.monitor_count++; + output_index = ctx->monitor_count++; TRACE( "%u %s %s\n", monitor_index, wine_dbgstr_rect(&monitor->rc_monitor), wine_dbgstr_rect(&monitor->rc_work) ); @@ -1399,7 +1395,7 @@ static void add_monitor( const struct gdi_monitor *monitor, void *param ) strcpy( monitor_id_string, "Default_Monitor" ); sprintf( buffer, "MonitorID%u", monitor_index ); - sprintf( instance, "DISPLAY\\%s\\%04X&%04X", monitor_id_string, ctx->video_count - 1, monitor_index ); + sprintf( instance, "DISPLAY\\%s\\%04X&%04X", monitor_id_string, ctx->adapter.id, monitor_index ); set_reg_ascii_value( ctx->adapter_key, buffer, instance ); hkey = reg_create_ascii_key( enum_key, instance, 0, NULL ); @@ -1491,10 +1487,10 @@ static void add_mode( const DEVMODEW *mode, BOOL current, void *param ) nopos_mode.dmPosition.y = 0; nopos_mode.dmFields &= ~DM_POSITION; - if (write_adapter_mode( ctx->adapter_key, ctx->mode_count, &nopos_mode )) + if (write_adapter_mode( ctx->adapter_key, ctx->adapter.mode_count, &nopos_mode )) { - ctx->mode_count++; - set_reg_value( ctx->adapter_key, mode_countW, REG_DWORD, &ctx->mode_count, sizeof(ctx->mode_count) ); + ctx->adapter.mode_count++; + set_reg_value( ctx->adapter_key, mode_countW, REG_DWORD, &ctx->adapter.mode_count, sizeof(ctx->adapter.mode_count) ); if (current) { if (!read_adapter_mode( ctx->adapter_key, ENUM_REGISTRY_SETTINGS, &nopos_mode )) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 87 +++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index dee9632d527..bfe8a084ffc 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -148,6 +148,7 @@ struct edid_monitor_info struct monitor { struct list entry; + char path[MAX_PATH]; struct display_device dev; struct adapter *adapter; HANDLE handle; @@ -1372,45 +1373,24 @@ static void add_adapter( const struct gdi_adapter *adapter, void *param ) sizeof(adapter->state_flags) ); } -static void add_monitor( const struct gdi_monitor *monitor, void *param ) +static BOOL write_monitor_to_registry( struct monitor *monitor, const BYTE *edid, UINT edid_len ) { - struct device_manager_ctx *ctx = param; - char buffer[MAX_PATH], instance[64]; - unsigned int monitor_index, output_index; - struct edid_monitor_info monitor_info; - char monitor_id_string[16]; + char buffer[MAX_PATH], *tmp; WCHAR bufferW[MAX_PATH]; HKEY hkey, subkey; unsigned int len; - monitor_index = ctx->adapter.monitor_count++; - output_index = ctx->monitor_count++; - - TRACE( "%u %s %s\n", monitor_index, wine_dbgstr_rect(&monitor->rc_monitor), wine_dbgstr_rect(&monitor->rc_work) ); - - get_monitor_info_from_edid( &monitor_info, monitor->edid, monitor->edid_len ); - if (monitor_info.flags & MONITOR_INFO_HAS_MONITOR_ID) - strcpy( monitor_id_string, monitor_info.monitor_id_string ); - else - strcpy( monitor_id_string, "Default_Monitor" ); - - sprintf( buffer, "MonitorID%u", monitor_index ); - sprintf( instance, "DISPLAY\\%s\\%04X&%04X", monitor_id_string, ctx->adapter.id, monitor_index ); - set_reg_ascii_value( ctx->adapter_key, buffer, instance ); - - hkey = reg_create_ascii_key( enum_key, instance, 0, NULL ); - if (!hkey) return; - - link_device( instance, guid_devinterface_monitorA ); + if (!(hkey = reg_create_ascii_key( enum_key, monitor->path, 0, NULL ))) return FALSE; set_reg_ascii_value( hkey, "DeviceDesc", "Generic Non-PnP Monitor" ); set_reg_ascii_value( hkey, "Class", "Monitor" ); - sprintf( buffer, "%s\\%04X", guid_devclass_monitorA, output_index ); + sprintf( buffer, "%s\\%04X", guid_devclass_monitorA, monitor->output_id ); set_reg_ascii_value( hkey, "Driver", buffer ); set_reg_ascii_value( hkey, "ClassGUID", guid_devclass_monitorA ); - sprintf( buffer, "MONITOR\\%s", monitor_id_string ); + sprintf( buffer, "MONITOR\\%s", monitor->path + 8 ); + if ((tmp = strrchr( buffer, '\\' ))) *tmp = 0; len = asciiz_to_unicode( bufferW, buffer ); bufferW[len / sizeof(WCHAR)] = 0; set_reg_value( hkey, hardware_idW, REG_MULTI_SZ, bufferW, len + sizeof(WCHAR) ); @@ -1420,8 +1400,8 @@ static void add_monitor( const struct gdi_monitor *monitor, void *param ) static const WCHAR bad_edidW[] = {'B','A','D','_','E','D','I','D',0}; static const WCHAR edidW[] = {'E','D','I','D',0}; - if (monitor->edid_len) - set_reg_value( subkey, edidW, REG_BINARY, monitor->edid, monitor->edid_len ); + if (edid_len) + set_reg_value( subkey, edidW, REG_BINARY, edid, edid_len ); else set_reg_value( subkey, bad_edidW, REG_BINARY, NULL, 0 ); NtClose( subkey ); @@ -1448,7 +1428,7 @@ static void add_monitor( const struct gdi_monitor *monitor, void *param ) if ((subkey = reg_create_ascii_key( hkey, devpropkey_monitor_gpu_luidA, 0, NULL ))) { set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_INT64, - &ctx->gpu.luid, sizeof(ctx->gpu.luid) ); + &monitor->adapter->gpu->luid, sizeof(monitor->adapter->gpu->luid) ); NtClose( subkey ); } @@ -1456,15 +1436,54 @@ static void add_monitor( const struct gdi_monitor *monitor, void *param ) if ((subkey = reg_create_ascii_key( hkey, devpropkey_monitor_output_idA, 0, NULL ))) { set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_UINT32, - &output_index, sizeof(output_index) ); + &monitor->output_id, sizeof(monitor->output_id) ); NtClose( subkey ); } NtClose( hkey ); - sprintf( buffer, "Class\\%s\\%04X", guid_devclass_monitorA, output_index ); - hkey = reg_create_ascii_key( control_key, buffer, 0, NULL ); - if (hkey) NtClose( hkey ); + + sprintf( buffer, "Class\\%s\\%04X", guid_devclass_monitorA, monitor->output_id ); + if (!(hkey = reg_create_ascii_key( control_key, buffer, 0, NULL ))) return FALSE; + NtClose( hkey ); + + link_device( monitor->path, guid_devinterface_monitorA ); + + return TRUE; +} + +static void add_monitor( const struct gdi_monitor *gdi_monitor, void *param ) +{ + struct device_manager_ctx *ctx = param; + struct monitor monitor = {0}; + char buffer[MAX_PATH]; + char monitor_id_string[16]; + + monitor.adapter = &ctx->adapter; + monitor.id = ctx->adapter.monitor_count; + monitor.output_id = ctx->monitor_count; + monitor.rc_monitor = gdi_monitor->rc_monitor; + monitor.rc_work = gdi_monitor->rc_work; + + TRACE( "%u %s %s\n", monitor.id, wine_dbgstr_rect(&gdi_monitor->rc_monitor), wine_dbgstr_rect(&gdi_monitor->rc_work) ); + + get_monitor_info_from_edid( &monitor.edid_info, gdi_monitor->edid, gdi_monitor->edid_len ); + if (monitor.edid_info.flags & MONITOR_INFO_HAS_MONITOR_ID) + strcpy( monitor_id_string, monitor.edid_info.monitor_id_string ); + else + strcpy( monitor_id_string, "Default_Monitor" ); + + sprintf( buffer, "MonitorID%u", monitor.id ); + sprintf( monitor.path, "DISPLAY\\%s\\%04X&%04X", monitor_id_string, ctx->adapter.id, monitor.id ); + set_reg_ascii_value( ctx->adapter_key, buffer, monitor.path ); + + if (!write_monitor_to_registry( &monitor, gdi_monitor->edid, gdi_monitor->edid_len )) + WARN( "Failed to write monitor to registry\n" ); + else + { + ctx->adapter.monitor_count++; + ctx->monitor_count++; + } } static void add_mode( const DEVMODEW *mode, BOOL current, void *param ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 229 ++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 105 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index bfe8a084ffc..57ee2e5682f 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -77,11 +77,7 @@ static const char guid_devclass_monitorA[] = "{4D36E96E-E325-11CE-BFC1-08002BE1 static const char guid_devinterface_display_adapterA[] = "{5B45201D-F2F2-4F3B-85BB-30FF1F953599}"; static const char guid_display_device_arrivalA[] = "{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}"; - static const char guid_devinterface_monitorA[] = "{E6F07B5F-EE97-4A90-B076-33F57BF4EAA7}"; -static const WCHAR guid_devinterface_monitorW[] = - {'{','E','6','F','0','7','B','5','F','-','E','E','9','7','-','4','A','9','0','-', - 'B','0','7','6','-','3','3','F','5','7','B','F','4','E','A','A','7','}',0}; #define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra)) @@ -140,7 +136,7 @@ struct edid_monitor_info unsigned short manufacturer, product_code; char monitor_id_string[8]; /* MONITOR_INFO_HAS_MONITOR_NAME */ - WCHAR monitor_name[14]; + char monitor_name[14]; /* MONITOR_INFO_HAS_PREFERRED_MODE */ unsigned int preferred_width, preferred_height; }; @@ -149,7 +145,6 @@ struct monitor { struct list entry; char path[MAX_PATH]; - struct display_device dev; struct adapter *adapter; HANDLE handle; unsigned int id; @@ -158,6 +153,7 @@ struct monitor RECT rc_monitor; RECT rc_work; BOOL is_clone; + UINT state_flags; struct edid_monitor_info edid_info; }; @@ -178,7 +174,6 @@ static struct monitor virtual_monitor = .rc_monitor.bottom = 768, .rc_work.right = 1024, .rc_work.bottom = 768, - .dev.state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED, }; /* the various registry keys that are used to store parameters */ @@ -701,16 +696,13 @@ static BOOL read_monitor_settings( struct adapter *adapter, UINT index, struct m char buffer[4096]; BOOL is_primary = !!(adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - WCHAR *device_name, *value_str = (WCHAR *)value->Data, *ptr; + WCHAR *value_str = (WCHAR *)value->Data; HKEY hkey, subkey; - DWORD size, len; + DWORD size; + UINT i; monitor->flags = is_primary ? MONITORINFOF_PRIMARY : 0; - /* DeviceName */ - sprintf( buffer, "\\\\.\\DISPLAY%d\\Monitor%d", adapter->id + 1, index ); - asciiz_to_unicode( monitor->dev.device_name, buffer ); - if (!(hkey = reg_open_key( config_key, adapter->config_key, lstrlenW( adapter->config_key ) * sizeof(WCHAR) ))) return FALSE; @@ -720,17 +712,8 @@ static BOOL read_monitor_settings( struct adapter *adapter, UINT index, struct m size = query_reg_ascii_value( hkey, buffer, value, sizeof(buffer) ); NtClose( hkey ); if (!size || value->Type != REG_SZ) return FALSE; - len = asciiz_to_unicode( monitor->dev.interface_name, "\\\\\?\\" ) / sizeof(WCHAR) - 1; - memcpy( monitor->dev.interface_name + len, value_str, value->DataLength - sizeof(WCHAR) ); - len += value->DataLength / sizeof(WCHAR) - 1; - monitor->dev.interface_name[len++] = '#'; - memcpy( monitor->dev.interface_name + len, guid_devinterface_monitorW, - sizeof(guid_devinterface_monitorW) ); - - /* Replace '\\' with '#' after prefix */ - for (ptr = monitor->dev.interface_name + ARRAYSIZE("\\\\\?\\") - 1; *ptr; ptr++) - if (*ptr == '\\') *ptr = '#'; + for (i = 0; i < value->DataLength / sizeof(WCHAR); i++) monitor->path[i] = value_str[i]; if (!(hkey = reg_open_key( enum_key, value_str, value->DataLength - sizeof(WCHAR) ))) return FALSE; @@ -764,37 +747,6 @@ static BOOL read_monitor_settings( struct adapter *adapter, UINT index, struct m } monitor->rc_work = *(const RECT *)value->Data; - /* DeviceString */ - if (!query_reg_ascii_value( hkey, "DeviceDesc", value, sizeof(buffer) ) || value->Type != REG_SZ) - { - NtClose( hkey ); - return FALSE; - } - memcpy( monitor->dev.device_string, value->Data, value->DataLength ); - - /* DeviceKey */ - if (!query_reg_ascii_value( hkey, "Driver", value, sizeof(buffer) ) || value->Type != REG_SZ) - { - NtClose( hkey ); - return FALSE; - } - size = asciiz_to_unicode( monitor->dev.device_key, - "\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\" ); - device_name = &monitor->dev.device_key[size / sizeof(WCHAR) - 1]; - memcpy( device_name, value_str, value->DataLength ); - - /* DeviceID */ - if (!query_reg_ascii_value( hkey, "HardwareID", value, sizeof(buffer) ) || - (value->Type != REG_SZ && value->Type != REG_MULTI_SZ)) - { - NtClose( hkey ); - return FALSE; - } - size = lstrlenW( value_str ); - memcpy( monitor->dev.device_id, value_str, size * sizeof(WCHAR) ); - monitor->dev.device_id[size++] = '\\'; - lstrcpyW( monitor->dev.device_id + size, device_name ); - /* EDID */ if ((subkey = reg_open_ascii_key( hkey, "Device Parameters" ))) { @@ -1045,6 +997,7 @@ static BOOL read_gpu_from_registry( struct gpu *gpu ) KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; WCHAR *value_str = (WCHAR *)value->Data; HKEY hkey, subkey; + unsigned int i; if (!(hkey = reg_open_ascii_key( enum_key, gpu->path ))) return FALSE; @@ -1061,6 +1014,17 @@ static BOOL read_gpu_from_registry( struct gpu *gpu ) NtClose( subkey ); } + if ((subkey = reg_create_ascii_key( hkey, "Device Parameters", 0, NULL ))) + { + if (query_reg_ascii_value( subkey, "VideoID", value, sizeof(buffer) ) == sizeof(gpu->guid) * sizeof(WCHAR)) + { + WCHAR *guidW = (WCHAR *)value->Data; + for (i = 0; i < sizeof(gpu->guid); i++) gpu->guid[i] = guidW[i]; + TRACE( "got guid %s\n", debugstr_a(gpu->guid) ); + } + NtClose( subkey ); + } + if ((subkey = reg_open_ascii_key( hkey, devpropkey_gpu_vulkan_uuidA ))) { if (query_reg_value( subkey, NULL, value, sizeof(buffer) ) == sizeof(GUID)) @@ -1718,14 +1682,14 @@ static BOOL update_display_cache_from_registry(void) monitor->id = monitor_id; monitor->adapter = adapter_acquire( adapter ); - monitor->dev.state_flags |= DISPLAY_DEVICE_ATTACHED; + monitor->state_flags |= DISPLAY_DEVICE_ATTACHED; if (adapter->dev.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { - if (!IsRectEmpty(&monitor->rc_monitor)) monitor->dev.state_flags |= DISPLAY_DEVICE_ACTIVE; + if (!IsRectEmpty(&monitor->rc_monitor)) monitor->state_flags |= DISPLAY_DEVICE_ACTIVE; LIST_FOR_EACH_ENTRY( monitor2, &monitors, struct monitor, entry ) { - if (!(monitor2->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!(monitor2->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; if (EqualRect( &monitor2->rc_monitor, &monitor->rc_monitor )) { monitor->is_clone = TRUE; @@ -2284,7 +2248,7 @@ RECT get_virtual_screen_rect( UINT dpi ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; union_rect( &rect, &rect, &monitor->rc_monitor ); } @@ -2305,7 +2269,7 @@ static BOOL is_window_rect_full_screen( const RECT *rect ) { RECT monrect; - if (!(monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) + if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; monrect = map_dpi_rect( monitor->rc_monitor, get_monitor_dpi( monitor->handle ), @@ -2393,7 +2357,7 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in { LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) + if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; count++; } @@ -2577,7 +2541,7 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) + if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; if (!monitor->adapter) @@ -2634,52 +2598,52 @@ done: } /* display_lock mutex must be held */ -static struct display_device *find_monitor_device( struct display_device *adapter, UINT index ) +static struct monitor *find_monitor_by_index( struct adapter *adapter, UINT index ) { struct monitor *monitor; LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) - if (&monitor->adapter->dev == adapter && index == monitor->id) - return &monitor->dev; + if (monitor->adapter == adapter && index == monitor->id) + return monitor; - WARN( "Failed to find adapter %s monitor with id %u.\n", debugstr_w(adapter->device_name), index ); + WARN( "Failed to find adapter %s monitor with id %u.\n", debugstr_w(adapter->dev.device_name), index ); return NULL; } /* display_lock mutex must be held */ -static struct display_device *find_adapter_device_by_id( UINT index ) +static struct adapter *find_adapter_by_index( UINT index ) { struct adapter *adapter; LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) - if (index == adapter->id) return &adapter->dev; + if (index == adapter->id) return adapter; WARN( "Failed to find adapter with id %u.\n", index ); return NULL; } /* display_lock mutex must be held */ -static struct display_device *find_primary_adapter_device(void) +static struct adapter *find_primary_adapter(void) { struct adapter *adapter; LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) if (adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) - return &adapter->dev; + return adapter; WARN( "Failed to find primary adapter.\n" ); return NULL; } /* display_lock mutex must be held */ -static struct display_device *find_adapter_device_by_name( UNICODE_STRING *name ) +static struct adapter *find_adapter_by_name( UNICODE_STRING *name ) { SIZE_T len = name->Length / sizeof(WCHAR); struct adapter *adapter; LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) if (!wcsnicmp( name->Buffer, adapter->dev.device_name, len ) && !adapter->dev.device_name[len]) - return &adapter->dev; + return adapter; WARN( "Failed to find adapter with name %s.\n", debugstr_us(name) ); return NULL; @@ -2690,28 +2654,46 @@ static struct display_device *find_adapter_device_by_name( UNICODE_STRING *name */ static struct adapter *find_adapter( UNICODE_STRING *name ) { - struct display_device *device; struct adapter *adapter; if (!lock_display_devices()) return NULL; - if (name && name->Length) device = find_adapter_device_by_name( name ); - else device = find_primary_adapter_device(); + if (name && name->Length) adapter = find_adapter_by_name( name ); + else adapter = find_primary_adapter(); - if (!device) adapter = NULL; - else adapter = adapter_acquire( CONTAINING_RECORD( device, struct adapter, dev ) ); + if (adapter) adapter = adapter_acquire( adapter ); unlock_display_devices(); return adapter; } +static void monitor_get_interface_name( struct monitor *monitor, WCHAR *interface_name ) +{ + char buffer[MAX_PATH] = {0}, *tmp; + const char *id; + + *interface_name = 0; + if (!monitor->adapter) return; + + if (!(monitor->edid_info.flags & MONITOR_INFO_HAS_MONITOR_ID)) id = "Default_Monitor"; + else id = monitor->edid_info.monitor_id_string; + + sprintf( buffer, "\\\\?\\DISPLAY\\%s\\%04X&%04X#%s", id, monitor->adapter->id, + monitor->id, guid_devinterface_monitorA ); + for (tmp = buffer + 4; *tmp; tmp++) if (*tmp == '\\') *tmp = '#'; + + asciiz_to_unicode( interface_name, buffer ); +} + /*********************************************************************** * NtUserEnumDisplayDevices (win32u.@) */ NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags ) { - struct display_device *found = NULL; + struct monitor *monitor = NULL; + struct adapter *adapter = NULL; + BOOL found = FALSE; TRACE( "%s %u %p %#x\n", debugstr_us( device ), (int)index, info, (int)flags ); @@ -2719,22 +2701,64 @@ NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index, if (!lock_display_devices()) return STATUS_UNSUCCESSFUL; - if (!device || !device->Length) found = find_adapter_device_by_id( index ); - else if ((found = find_adapter_device_by_name( device ))) found = find_monitor_device( found, index ); + if (!device || !device->Length) + { + if ((adapter = find_adapter_by_index( index ))) found = TRUE; + } + else if ((adapter = find_adapter_by_name( device ))) + { + if ((monitor = find_monitor_by_index( adapter, index ))) found = TRUE; + } if (found) { + char buffer[MAX_PATH], *tmp; + if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceName) + sizeof(info->DeviceName)) - lstrcpyW( info->DeviceName, found->device_name ); + { + if (monitor) sprintf( buffer, "\\\\.\\DISPLAY%d\\Monitor%d", adapter->id + 1, monitor->id ); + else sprintf( buffer, "\\\\.\\DISPLAY%d", adapter->id + 1 ); + asciiz_to_unicode( info->DeviceName, buffer ); + } if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceString) + sizeof(info->DeviceString)) - lstrcpyW( info->DeviceString, found->device_string ); + { + if (monitor) asciiz_to_unicode( info->DeviceString, "Generic Non-PnP Monitor" ); + else lstrcpyW( info->DeviceString, adapter->dev.device_string ); + } if (info->cb >= offsetof(DISPLAY_DEVICEW, StateFlags) + sizeof(info->StateFlags)) - info->StateFlags = found->state_flags; + { + if (monitor) info->StateFlags = monitor->state_flags; + else info->StateFlags = adapter->dev.state_flags; + } if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(info->DeviceID)) - lstrcpyW( info->DeviceID, (flags & EDD_GET_DEVICE_INTERFACE_NAME) - ? found->interface_name : found->device_id ); + { + if (flags & EDD_GET_DEVICE_INTERFACE_NAME) + { + if (monitor) monitor_get_interface_name( monitor, info->DeviceID ); + else *info->DeviceID = 0; + } + else + { + if (monitor) + { + sprintf( buffer, "MONITOR\\%s", monitor->path + 8 ); + if (!(tmp = strrchr( buffer, '\\' ))) tmp = buffer + strlen( buffer ); + sprintf( tmp, "\\%s\\%04X", guid_devclass_monitorA, monitor->output_id ); + } + else + { + strcpy( buffer, adapter->gpu->path ); + if ((tmp = strrchr( buffer, '\\' ))) *tmp = 0; + } + asciiz_to_unicode( info->DeviceID, buffer ); + } + } if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(info->DeviceKey)) - lstrcpyW( info->DeviceKey, found->device_key ); + { + if (monitor) sprintf( buffer, "%s\\Class\\%s\\%04X", control_keyA, guid_devclass_monitorA, monitor->output_id ); + else sprintf( buffer, "%s\\Video\\%s\\%04x", control_keyA, adapter->gpu->guid, adapter->id ); + asciiz_to_unicode( info->DeviceKey, buffer ); + } } unlock_display_devices(); return found ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; @@ -3131,9 +3155,8 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod HWND hwnd, DWORD flags, void *lparam ) { WCHAR primary_name[CCHDEVICENAME]; - struct display_device *primary; + struct adapter *primary, *adapter; DEVMODEW *mode, *displays; - struct adapter *adapter; LONG ret; if (!lock_display_devices()) return DISP_CHANGE_FAILED; @@ -3153,8 +3176,8 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod place_all_displays( displays ); - if (!(primary = find_primary_adapter_device())) primary_name[0] = 0; - else wcscpy( primary_name, primary->device_name ); + if (!(primary = find_primary_adapter())) primary_name[0] = 0; + else wcscpy( primary_name, primary->dev.device_name ); /* use the default implementation in virtual desktop mode */ if (is_virtual_desktop()) ret = E_NOTIMPL; @@ -3306,42 +3329,38 @@ static unsigned int active_monitor_count(void) LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) { - if ((monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) count++; + if ((monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) count++; } return count; } INT get_display_depth( UNICODE_STRING *name ) { - struct display_device *device; + struct adapter *adapter; BOOL is_primary; INT depth; if (!lock_display_devices()) return 32; - if (name && name->Length) - device = find_adapter_device_by_name( name ); - else - device = find_primary_adapter_device(); + if (name && name->Length) adapter = find_adapter_by_name( name ); + else adapter = find_primary_adapter(); - if (!device) + if (!adapter) { unlock_display_devices(); return 32; } - is_primary = !!(device->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + is_primary = !!(adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); /* use the default implementation in virtual desktop mode */ if (is_virtual_desktop()) depth = -1; - else depth = user_driver->pGetDisplayDepth( device->device_name, is_primary ); + else depth = user_driver->pGetDisplayDepth( adapter->dev.device_name, is_primary ); if (depth < 0) { - struct adapter *adapter = CONTAINING_RECORD( device, struct adapter, dev ); DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; - if (!adapter_get_current_settings( adapter, ¤t_mode )) depth = 32; else depth = current_mode.dmBitsPerPel; } @@ -3395,7 +3414,7 @@ BOOL WINAPI NtUserEnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc { RECT monrect; - if (!(monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; monrect = map_dpi_rect( monitor->rc_monitor, get_monitor_dpi( monitor->handle ), get_thread_dpi() ); @@ -3441,7 +3460,7 @@ BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (monitor->handle != handle) continue; - if (!(monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) break; + if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) break; /* FIXME: map dpi */ info->rcMonitor = monitor->rc_monitor; @@ -3493,7 +3512,7 @@ HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) { RECT intersect, monitor_rect; - if (!(monitor->dev.state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; monitor_rect = map_dpi_rect( monitor->rc_monitor, get_monitor_dpi( monitor->handle ), system_dpi ); if (intersect_rect( &intersect, &monitor_rect, &r )) @@ -6414,7 +6433,7 @@ NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEAD target_name->outputTechnology = DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL; snprintf( buffer, ARRAY_SIZE(buffer), "Display%u", monitor->output_id + 1 ); asciiz_to_unicode( target_name->monitorFriendlyDeviceName, buffer ); - lstrcpyW( target_name->monitorDevicePath, monitor->dev.interface_name ); + monitor_get_interface_name( monitor, target_name->monitorDevicePath ); if (monitor->edid_info.flags & MONITOR_INFO_HAS_MONITOR_ID) { target_name->edidManufactureId = monitor->edid_info.manufacturer; @@ -6423,7 +6442,7 @@ NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEAD } if (monitor->edid_info.flags & MONITOR_INFO_HAS_MONITOR_NAME) { - wcscpy( target_name->monitorFriendlyDeviceName, monitor->edid_info.monitor_name ); + asciiz_to_unicode( target_name->monitorFriendlyDeviceName, monitor->edid_info.monitor_name ); target_name->flags.friendlyNameFromEdid = 1; } ret = STATUS_SUCCESS; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 42 +++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 57ee2e5682f..c0cc99b0233 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -153,7 +153,6 @@ struct monitor RECT rc_monitor; RECT rc_work; BOOL is_clone; - UINT state_flags; struct edid_monitor_info edid_info; }; @@ -1552,6 +1551,14 @@ static void clear_display_devices(void) } } +static BOOL is_monitor_active( struct monitor *monitor ) +{ + struct adapter *adapter; + if (!(adapter = monitor->adapter)) return TRUE; + if (!(adapter->dev.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) return FALSE; + return !IsRectEmpty(&monitor->rc_monitor); +} + static void enum_device_keys( const char *root, const WCHAR *classW, UINT class_size, void (*callback)(const char *) ) { char buffer[1024]; @@ -1682,14 +1689,11 @@ static BOOL update_display_cache_from_registry(void) monitor->id = monitor_id; monitor->adapter = adapter_acquire( adapter ); - monitor->state_flags |= DISPLAY_DEVICE_ATTACHED; if (adapter->dev.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { - if (!IsRectEmpty(&monitor->rc_monitor)) monitor->state_flags |= DISPLAY_DEVICE_ACTIVE; - LIST_FOR_EACH_ENTRY( monitor2, &monitors, struct monitor, entry ) { - if (!(monitor2->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!is_monitor_active( monitor2 )) continue; if (EqualRect( &monitor2->rc_monitor, &monitor->rc_monitor )) { monitor->is_clone = TRUE; @@ -2248,7 +2252,7 @@ RECT get_virtual_screen_rect( UINT dpi ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!is_monitor_active( monitor )) continue; union_rect( &rect, &rect, &monitor->rc_monitor ); } @@ -2269,8 +2273,7 @@ static BOOL is_window_rect_full_screen( const RECT *rect ) { RECT monrect; - if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) - continue; + if (!is_monitor_active( monitor )) continue; monrect = map_dpi_rect( monitor->rc_monitor, get_monitor_dpi( monitor->handle ), get_thread_dpi() ); @@ -2357,8 +2360,7 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in { LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) - continue; + if (!is_monitor_active( monitor )) continue; count++; } unlock_display_devices(); @@ -2541,8 +2543,7 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) - continue; + if (!is_monitor_active( monitor )) continue; if (!monitor->adapter) continue; @@ -2727,8 +2728,12 @@ NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index, } if (info->cb >= offsetof(DISPLAY_DEVICEW, StateFlags) + sizeof(info->StateFlags)) { - if (monitor) info->StateFlags = monitor->state_flags; - else info->StateFlags = adapter->dev.state_flags; + if (!monitor) info->StateFlags = adapter->dev.state_flags; + else + { + info->StateFlags = DISPLAY_DEVICE_ATTACHED; + if (is_monitor_active( monitor )) info->StateFlags |= DISPLAY_DEVICE_ACTIVE; + } } if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(info->DeviceID)) { @@ -3329,7 +3334,8 @@ static unsigned int active_monitor_count(void) LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry) { - if ((monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) count++; + if (!is_monitor_active( monitor )) continue; + count++; } return count; } @@ -3414,7 +3420,7 @@ BOOL WINAPI NtUserEnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc { RECT monrect; - if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!is_monitor_active( monitor )) continue; monrect = map_dpi_rect( monitor->rc_monitor, get_monitor_dpi( monitor->handle ), get_thread_dpi() ); @@ -3460,7 +3466,7 @@ BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (monitor->handle != handle) continue; - if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) break; + if (!is_monitor_active( monitor )) continue; /* FIXME: map dpi */ info->rcMonitor = monitor->rc_monitor; @@ -3512,7 +3518,7 @@ HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) { RECT intersect, monitor_rect; - if (!(monitor->state_flags & DISPLAY_DEVICE_ACTIVE)) continue; + if (!is_monitor_active( monitor )) continue; monitor_rect = map_dpi_rect( monitor->rc_monitor, get_monitor_dpi( monitor->handle ), system_dpi ); if (intersect_rect( &intersect, &monitor_rect, &r )) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 145 +++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 70 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index c0cc99b0233..a2f617fde33 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -81,17 +81,6 @@ static const char guid_devinterface_monitorA[] = "{E6F07B5F-EE97-4A90-B076-33F57 #define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra)) -/* Cached display device information */ -struct display_device -{ - WCHAR device_name[32]; /* DeviceName in DISPLAY_DEVICEW */ - WCHAR device_string[128]; /* DeviceString in DISPLAY_DEVICEW */ - DWORD state_flags; /* StateFlags in DISPLAY_DEVICEW */ - WCHAR device_id[128]; /* DeviceID in DISPLAY_DEVICEW */ - WCHAR interface_name[128]; /* DeviceID in DISPLAY_DEVICEW when EDD_GET_DEVICE_INTERFACE_NAME is set */ - WCHAR device_key[128]; /* DeviceKey in DISPLAY_DEVICEW */ -}; - struct pci_id { UINT16 vendor; @@ -117,10 +106,10 @@ struct adapter { LONG refcount; struct list entry; - struct display_device dev; unsigned int id; struct gpu *gpu; - const WCHAR *config_key; + UINT state_flags; + WCHAR config_key[MAX_PATH]; UINT monitor_count; UINT mode_count; DEVMODEW *modes; @@ -489,14 +478,19 @@ static BOOL adapter_set_registry_settings( const struct adapter *adapter, const static BOOL adapter_get_current_settings( const struct adapter *adapter, DEVMODEW *mode ) { - BOOL is_primary = !!(adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + BOOL is_primary = !!(adapter->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + WCHAR device_nameW[CCHDEVICENAME]; + char device_name[CCHDEVICENAME]; HANDLE mutex; HKEY hkey; BOOL ret; + sprintf( device_name, "\\\\.\\DISPLAY%d", adapter->id + 1 ); + asciiz_to_unicode( device_nameW, device_name ); + /* 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 ); + else ret = user_driver->pGetCurrentDisplaySettings( device_nameW, is_primary, mode ); if (ret) return TRUE; @@ -628,20 +622,8 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i return FALSE; /* DeviceKey */ - memcpy( info->dev.device_key, value_str, value->DataLength ); - info->config_key = info->dev.device_key + sizeof("\\Registry\\Machine\\") - 1; - - if (!(hkey = reg_open_key( NULL, value_str, value->DataLength - sizeof(WCHAR) ))) - return FALSE; - - /* DeviceString */ - if (query_reg_ascii_value( hkey, "DriverDesc", value, sizeof(buffer) ) && value->Type == REG_SZ) - memcpy( info->dev.device_string, value_str, value->DataLength ); - NtClose( hkey ); - - /* DeviceName */ - sprintf( buffer, "\\\\.\\DISPLAY%d", index + 1 ); - asciiz_to_unicode( info->dev.device_name, buffer ); + size = sizeof("\\Registry\\Machine\\") - 1; + memcpy( info->config_key, value_str + size, value->DataLength - size ); if (!(hkey = reg_open_key( config_key, info->config_key, lstrlenW( info->config_key ) * sizeof(WCHAR) ))) @@ -649,10 +631,7 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i /* StateFlags */ if (query_reg_ascii_value( hkey, "StateFlags", value, sizeof(buffer) ) && value->Type == REG_DWORD) - info->dev.state_flags = *(const DWORD *)value->Data; - - /* Interface name */ - info->dev.interface_name[0] = 0; + info->state_flags = *(const DWORD *)value->Data; /* ModeCount */ if (query_reg_ascii_value( hkey, "ModeCount", value, sizeof(buffer) ) && value->Type == REG_DWORD) @@ -678,22 +657,13 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i if (!size || value->Type != REG_SZ || !info->mode_count || !info->modes) return FALSE; for (i = 0; i < value->DataLength / sizeof(WCHAR); i++) gpu_path[i] = value_str[i]; - if (!(hkey = reg_open_key( enum_key, value_str, value->DataLength - sizeof(WCHAR) ))) - return FALSE; - - size = query_reg_ascii_value( hkey, "HardwareID", value, sizeof(buffer) ); - NtClose( hkey ); - if (!size || (value->Type != REG_SZ && value->Type != REG_MULTI_SZ)) - return FALSE; - - lstrcpyW( info->dev.device_id, value_str ); return TRUE; } static BOOL read_monitor_settings( struct adapter *adapter, UINT index, struct monitor *monitor ) { char buffer[4096]; - BOOL is_primary = !!(adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + BOOL is_primary = !!(adapter->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; WCHAR *value_str = (WCHAR *)value->Data; HKEY hkey, subkey; @@ -1555,7 +1525,7 @@ static BOOL is_monitor_active( struct monitor *monitor ) { struct adapter *adapter; if (!(adapter = monitor->adapter)) return TRUE; - if (!(adapter->dev.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) return FALSE; + if (!(adapter->state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) return FALSE; return !IsRectEmpty(&monitor->rc_monitor); } @@ -1689,7 +1659,7 @@ static BOOL update_display_cache_from_registry(void) monitor->id = monitor_id; monitor->adapter = adapter_acquire( adapter ); - if (adapter->dev.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) + if (adapter->state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { LIST_FOR_EACH_ENTRY( monitor2, &monitors, struct monitor, entry ) { @@ -2290,16 +2260,32 @@ static BOOL is_window_rect_full_screen( const RECT *rect ) return ret; } +static UINT get_display_index( const UNICODE_STRING *name ) +{ + static const WCHAR displayW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'}; + WCHAR *end, display[64] = {0}; + int index; + + memcpy( display, name->Buffer, min( name->Length, 63 * sizeof(WCHAR) ) ); + if (wcsnicmp( display, displayW, ARRAY_SIZE(displayW) )) return 0; + if (!(index = wcstoul( display + ARRAY_SIZE(displayW), &end, 10 )) || *end) return 0; + return index; +} + RECT get_display_rect( const WCHAR *display ) { struct monitor *monitor; + UNICODE_STRING name; RECT rect = {0}; + UINT index; + RtlInitUnicodeString( &name, display ); + if (!(index = get_display_index( &name ))) return rect; if (!lock_display_devices()) return rect; LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!monitor->adapter || wcsicmp( monitor->adapter->dev.device_name, display )) continue; + if (!monitor->adapter || monitor->adapter->id + 1 != index) continue; rect = monitor->rc_monitor; break; } @@ -2607,7 +2593,7 @@ static struct monitor *find_monitor_by_index( struct adapter *adapter, UINT inde if (monitor->adapter == adapter && index == monitor->id) return monitor; - WARN( "Failed to find adapter %s monitor with id %u.\n", debugstr_w(adapter->dev.device_name), index ); + WARN( "Failed to find adapter %u monitor with id %u.\n", adapter->id, index ); return NULL; } @@ -2629,7 +2615,7 @@ static struct adapter *find_primary_adapter(void) struct adapter *adapter; LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) - if (adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) + if (adapter->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) return adapter; WARN( "Failed to find primary adapter.\n" ); @@ -2639,11 +2625,13 @@ static struct adapter *find_primary_adapter(void) /* display_lock mutex must be held */ static struct adapter *find_adapter_by_name( UNICODE_STRING *name ) { - SIZE_T len = name->Length / sizeof(WCHAR); struct adapter *adapter; + UINT index; + + if (!(index = get_display_index( name ))) return NULL; LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry) - if (!wcsnicmp( name->Buffer, adapter->dev.device_name, len ) && !adapter->dev.device_name[len]) + if (adapter->id + 1 == index) return adapter; WARN( "Failed to find adapter with name %s.\n", debugstr_us(name) ); @@ -2724,11 +2712,15 @@ NTSTATUS WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index, if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceString) + sizeof(info->DeviceString)) { if (monitor) asciiz_to_unicode( info->DeviceString, "Generic Non-PnP Monitor" ); - else lstrcpyW( info->DeviceString, adapter->dev.device_string ); + else + { + sprintf( buffer, "\\\\.\\DISPLAY%d", adapter->id + 1 ); + asciiz_to_unicode( info->DeviceString, buffer ); + } } if (info->cb >= offsetof(DISPLAY_DEVICEW, StateFlags) + sizeof(info->StateFlags)) { - if (!monitor) info->StateFlags = adapter->dev.state_flags; + if (!monitor) info->StateFlags = adapter->state_flags; else { info->StateFlags = DISPLAY_DEVICE_ATTACHED; @@ -2936,7 +2928,7 @@ static BOOL adapter_get_full_mode( const struct adapter *adapter, const DEVMODEW return adapter_mode != NULL; } -static DEVMODEW *get_display_settings( const WCHAR *devname, const DEVMODEW *devmode ) +static DEVMODEW *get_display_settings( struct adapter *target, const DEVMODEW *devmode ) { DEVMODEW *mode, *displays; struct adapter *adapter; @@ -2948,12 +2940,14 @@ static DEVMODEW *get_display_settings( const WCHAR *devname, const DEVMODEW *dev LIST_FOR_EACH_ENTRY( adapter, &adapters, struct adapter, entry ) { + char buffer[CCHDEVICENAME]; + mode->dmSize = sizeof(DEVMODEW); - if (devmode && !wcsicmp( devname, adapter->dev.device_name )) + if (devmode && adapter->id == target->id ) memcpy( &mode->dmFields, &devmode->dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); else { - if (!devname) ret = adapter_get_registry_settings( adapter, mode ); + if (!target) ret = adapter_get_registry_settings( adapter, mode ); else ret = adapter_get_current_settings( adapter, mode ); if (!ret) { @@ -2962,7 +2956,8 @@ static DEVMODEW *get_display_settings( const WCHAR *devname, const DEVMODEW *dev } } - lstrcpyW( mode->dmDeviceName, adapter->dev.device_name ); + sprintf( buffer, "\\\\.\\DISPLAY%d", adapter->id + 1 ); + asciiz_to_unicode( mode->dmDeviceName, buffer ); mode = NEXT_DEVMODEW(mode); } @@ -3156,7 +3151,7 @@ static BOOL all_detached_settings( const DEVMODEW *displays ) return TRUE; } -static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmode, +static LONG apply_display_settings( struct adapter *target, const DEVMODEW *devmode, HWND hwnd, DWORD flags, void *lparam ) { WCHAR primary_name[CCHDEVICENAME]; @@ -3165,7 +3160,7 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod LONG ret; if (!lock_display_devices()) return DISP_CHANGE_FAILED; - if (!(displays = get_display_settings( devname, devmode ))) + if (!(displays = get_display_settings( target, devmode ))) { unlock_display_devices(); return DISP_CHANGE_FAILED; @@ -3182,7 +3177,12 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod place_all_displays( displays ); if (!(primary = find_primary_adapter())) primary_name[0] = 0; - else wcscpy( primary_name, primary->dev.device_name ); + else + { + char device_name[CCHDEVICENAME]; + sprintf( device_name, "\\\\.\\DISPLAY%d", primary->id + 1 ); + asciiz_to_unicode( primary_name, device_name ); + } /* use the default implementation in virtual desktop mode */ if (is_virtual_desktop()) ret = E_NOTIMPL; @@ -3195,7 +3195,7 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod LIST_FOR_EACH_ENTRY( adapter, &adapters, struct adapter, entry ) { if (!adapter_set_current_settings( adapter, mode )) - WARN( "Failed to write adapter %s current mode.\n", debugstr_w(adapter->dev.device_name) ); + WARN( "Failed to write adapter %u current mode.\n", adapter->id ); mode = NEXT_DEVMODEW(mode); } ret = DISP_CHANGE_SUCCESSFUL; @@ -3248,7 +3248,7 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm if (!adapter_get_full_mode( adapter, devmode, &full_mode )) ret = DISP_CHANGE_BADMODE; else if ((flags & CDS_UPDATEREGISTRY) && !adapter_set_registry_settings( adapter, &full_mode )) ret = DISP_CHANGE_NOTUPDATED; else if (flags & (CDS_TEST | CDS_NORESET)) ret = DISP_CHANGE_SUCCESSFUL; - else ret = apply_display_settings( adapter->dev.device_name, &full_mode, hwnd, flags, lparam ); + else ret = apply_display_settings( adapter, &full_mode, hwnd, flags, lparam ); adapter_release( adapter ); if (ret) ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret ); @@ -3282,8 +3282,7 @@ static BOOL adapter_enum_display_settings( const struct adapter *adapter, UINT i } } - WARN( "device %s, index %#x, flags %#x display mode not found.\n", - debugstr_w( adapter->dev.device_name ), index, flags ); + WARN( "device %d, index %#x, flags %#x display mode not found.\n", adapter->id, index, flags ); RtlSetLastWin32Error( ERROR_NO_MORE_FILES ); return FALSE; } @@ -3342,6 +3341,8 @@ static unsigned int active_monitor_count(void) INT get_display_depth( UNICODE_STRING *name ) { + WCHAR device_nameW[CCHDEVICENAME]; + char device_name[CCHDEVICENAME]; struct adapter *adapter; BOOL is_primary; INT depth; @@ -3358,11 +3359,13 @@ INT get_display_depth( UNICODE_STRING *name ) return 32; } - is_primary = !!(adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + is_primary = !!(adapter->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); + sprintf( device_name, "\\\\.\\DISPLAY%d", adapter->id + 1 ); + asciiz_to_unicode( device_nameW, device_name ); /* use the default implementation in virtual desktop mode */ if (is_virtual_desktop()) depth = -1; - else depth = user_driver->pGetDisplayDepth( adapter->dev.device_name, is_primary ); + else depth = user_driver->pGetDisplayDepth( device_nameW, is_primary ); if (depth < 0) { @@ -3474,10 +3477,10 @@ BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) info->dwFlags = monitor->flags; if (info->cbSize >= sizeof(MONITORINFOEXW)) { - if (monitor->adapter) - lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, monitor->adapter->dev.device_name ); - else - asciiz_to_unicode( ((MONITORINFOEXW *)info)->szDevice, "WinDisc" ); + char buffer[CCHDEVICENAME]; + if (monitor->adapter) sprintf( buffer, "\\\\.\\DISPLAY%d", monitor->adapter->id + 1 ); + else strcpy( buffer, "WinDisc" ); + asciiz_to_unicode( ((MONITORINFOEXW *)info)->szDevice, buffer ); } unlock_display_devices(); @@ -6381,6 +6384,7 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEADER *packet ) { NTSTATUS ret = STATUS_UNSUCCESSFUL; + char buffer[CCHDEVICENAME]; TRACE( "packet %p.\n", packet ); @@ -6406,7 +6410,8 @@ NTSTATUS WINAPI NtUserDisplayConfigGetDeviceInfo( DISPLAYCONFIG_DEVICE_INFO_HEAD if (source_name->header.id != adapter->id) continue; if (memcmp( &source_name->header.adapterId, &adapter->gpu->luid, sizeof(adapter->gpu->luid) )) continue; - lstrcpyW( source_name->viewGdiDeviceName, adapter->dev.device_name ); + sprintf( buffer, "\\\\.\\DISPLAY%d", adapter->id + 1 ); + asciiz_to_unicode( source_name->viewGdiDeviceName, buffer ); ret = STATUS_SUCCESS; break; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index a2f617fde33..00a9d30691b 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -137,7 +137,6 @@ struct monitor struct adapter *adapter; HANDLE handle; unsigned int id; - unsigned int flags; unsigned int output_id; RECT rc_monitor; RECT rc_work; @@ -157,7 +156,6 @@ BOOL enable_thunk_lock = FALSE; static struct monitor virtual_monitor = { .handle = VIRTUAL_HMONITOR, - .flags = MONITORINFOF_PRIMARY, .rc_monitor.right = 1024, .rc_monitor.bottom = 768, .rc_work.right = 1024, @@ -663,15 +661,12 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i static BOOL read_monitor_settings( struct adapter *adapter, UINT index, struct monitor *monitor ) { char buffer[4096]; - BOOL is_primary = !!(adapter->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; WCHAR *value_str = (WCHAR *)value->Data; HKEY hkey, subkey; DWORD size; UINT i; - monitor->flags = is_primary ? MONITORINFOF_PRIMARY : 0; - if (!(hkey = reg_open_key( config_key, adapter->config_key, lstrlenW( adapter->config_key ) * sizeof(WCHAR) ))) return FALSE; @@ -1529,6 +1524,13 @@ static BOOL is_monitor_active( struct monitor *monitor ) return !IsRectEmpty(&monitor->rc_monitor); } +static BOOL is_monitor_primary( struct monitor *monitor ) +{ + struct adapter *adapter; + if (!(adapter = monitor->adapter)) return TRUE; + return !!(adapter->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); +} + static void enum_device_keys( const char *root, const WCHAR *classW, UINT class_size, void (*callback)(const char *) ) { char buffer[1024]; @@ -2303,7 +2305,7 @@ RECT get_primary_monitor_rect( UINT dpi ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->flags & MONITORINFOF_PRIMARY)) continue; + if (!is_monitor_primary( monitor )) continue; rect = monitor->rc_monitor; break; } @@ -3474,7 +3476,7 @@ BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) /* FIXME: map dpi */ info->rcMonitor = monitor->rc_monitor; info->rcWork = monitor->rc_work; - info->dwFlags = monitor->flags; + info->dwFlags = is_monitor_primary( monitor ) ? MONITORINFOF_PRIMARY : 0; if (info->cbSize >= sizeof(MONITORINFOEXW)) { char buffer[CCHDEVICENAME]; @@ -3553,7 +3555,7 @@ HMONITOR monitor_from_rect( const RECT *rect, UINT flags, UINT dpi ) } } - if (monitor->flags & MONITORINFOF_PRIMARY) primary = monitor->handle; + if (is_monitor_primary( monitor )) primary = monitor->handle; } unlock_display_devices(); @@ -5123,7 +5125,7 @@ BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT w LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { - if (!(monitor->flags & MONITORINFOF_PRIMARY)) continue; + if (!is_monitor_primary( monitor )) continue; work_area = monitor->rc_work; break; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/win32u/sysparams.c | 87 +++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 00a9d30691b..03a0796cc19 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -74,6 +74,9 @@ static const WCHAR guid_devclass_displayW[] = {'{','4','D','3','6','E','9','6','8','-','E','3','2','5','-','1','1','C','E','-', 'B','F','C','1','-','0','8','0','0','2','B','E','1','0','3','1','8','}',0}; static const char guid_devclass_monitorA[] = "{4D36E96E-E325-11CE-BFC1-08002BE10318}"; +static const WCHAR guid_devclass_monitorW[] = + {'{','4','D','3','6','E','9','6','E','-','E','3','2','5','-','1','1','C','E','-', + 'B','F','C','1','-','0','8','0','0','2','B','E','1','0','3','1','8','}',0}; static const char guid_devinterface_display_adapterA[] = "{5B45201D-F2F2-4F3B-85BB-30FF1F953599}"; static const char guid_display_device_arrivalA[] = "{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}"; @@ -658,28 +661,14 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i return TRUE; } -static BOOL read_monitor_settings( struct adapter *adapter, UINT index, struct monitor *monitor ) +static BOOL read_monitor_from_registry( struct monitor *monitor ) { char buffer[4096]; KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - WCHAR *value_str = (WCHAR *)value->Data; HKEY hkey, subkey; DWORD size; - UINT i; - - if (!(hkey = reg_open_key( config_key, adapter->config_key, - lstrlenW( adapter->config_key ) * sizeof(WCHAR) ))) - return FALSE; - - /* Interface name */ - sprintf( buffer, "MonitorID%u", index ); - size = query_reg_ascii_value( hkey, buffer, value, sizeof(buffer) ); - NtClose( hkey ); - if (!size || value->Type != REG_SZ) return FALSE; - for (i = 0; i < value->DataLength / sizeof(WCHAR); i++) monitor->path[i] = value_str[i]; - if (!(hkey = reg_open_key( enum_key, value_str, value->DataLength - sizeof(WCHAR) ))) - return FALSE; + if (!(hkey = reg_open_ascii_key( enum_key, monitor->path ))) return FALSE; /* Output ID */ size = query_reg_subkey_value( hkey, devpropkey_monitor_output_idA, @@ -723,6 +712,22 @@ static BOOL read_monitor_settings( struct adapter *adapter, UINT index, struct m return TRUE; } +static BOOL read_adapter_monitor_path( HKEY hkey, UINT index, char *path ) +{ + char buffer[4096]; + KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; + WCHAR *value_str = (WCHAR *)value->Data; + DWORD size; + UINT i; + + sprintf( buffer, "MonitorID%u", index ); + size = query_reg_ascii_value( hkey, buffer, value, sizeof(buffer) ); + if (!size || value->Type != REG_SZ) return FALSE; + + for (i = 0; i < value->DataLength / sizeof(WCHAR); i++) path[i] = value_str[i]; + return TRUE; +} + static void reg_empty_key( HKEY root, const char *key_name ) { char buffer[4096]; @@ -1596,6 +1601,25 @@ static struct gpu *find_gpu_from_path( const char *path ) return NULL; } +static void enum_monitors( const char *path ) +{ + struct monitor *monitor; + if (!(monitor = calloc( 1, sizeof(*monitor) ))) return; + strcpy( monitor->path, path ); + list_add_tail( &monitors, &monitor->entry ); +} + +static struct monitor *find_monitor_from_path( const char *path ) +{ + struct monitor *monitor; + + LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) + if (!strcmp( monitor->path, path )) return monitor; + + ERR( "Failed to find monitor with path %s\n", debugstr_a(path) ); + return NULL; +} + static BOOL update_display_cache_from_registry(void) { char path[MAX_PATH]; @@ -1606,6 +1630,7 @@ static BOOL update_display_cache_from_registry(void) HANDLE mutex = NULL; NTSTATUS status; struct gpu *gpu; + HKEY hkey; BOOL ret; /* If user driver did initialize the registry, then exit */ @@ -1627,6 +1652,7 @@ static BOOL update_display_cache_from_registry(void) clear_display_devices(); 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 ); LIST_FOR_EACH_ENTRY( gpu, &gpus, struct gpu, entry ) { @@ -1634,6 +1660,12 @@ static BOOL update_display_cache_from_registry(void) WARN( "Failed to read gpu from registry\n" ); } + LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) + { + if (!read_monitor_from_registry( monitor )) + WARN( "Failed to read monitor from registry\n" ); + } + for (adapter_id = 0;; adapter_id++) { if (!(adapter = calloc( 1, sizeof(*adapter) ))) break; @@ -1649,23 +1681,27 @@ static BOOL update_display_cache_from_registry(void) } list_add_tail( &adapters, &adapter->entry ); + + size = lstrlenW( adapter->config_key ) * sizeof(WCHAR); + if (!(hkey = reg_open_key( config_key, adapter->config_key, size ))) continue; + for (monitor_id = 0;; monitor_id++) { - if (!(monitor = calloc( 1, sizeof(*monitor) ))) break; - if (!read_monitor_settings( adapter, monitor_id, monitor )) - { - free( monitor ); - break; - } + struct monitor *monitor; + + if (!read_adapter_monitor_path( hkey, monitor_id, path )) break; + if (!(monitor = find_monitor_from_path( path ))) continue; monitor->id = monitor_id; monitor->adapter = adapter_acquire( adapter ); + monitor->handle = UlongToHandle( ++monitor_count ); + adapter->monitor_count++; if (adapter->state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { LIST_FOR_EACH_ENTRY( monitor2, &monitors, struct monitor, entry ) { - if (!is_monitor_active( monitor2 )) continue; + if (monitor == monitor2 || !is_monitor_active( monitor2 )) continue; if (EqualRect( &monitor2->rc_monitor, &monitor->rc_monitor )) { monitor->is_clone = TRUE; @@ -1673,10 +1709,9 @@ static BOOL update_display_cache_from_registry(void) } } } - - monitor->handle = UlongToHandle( ++monitor_count ); - list_add_tail( &monitors, &monitor->entry ); } + + NtClose( hkey ); } if ((ret = !list_empty( &adapters ) && !list_empty( &monitors ))) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5262
v2: Fix `win32u: Get rid of the monitor display_device.` which broke `NtUserEnumDisplayDevices` when device name is NULL. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_63973
Test failure in nsi is probably unrelated, d2d1 also looks more like a heap corruption from the vkd3d update? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_63994
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
}
+static void monitor_get_interface_name( struct monitor *monitor, WCHAR *interface_name ) +{ + char buffer[MAX_PATH] = {0}, *tmp; + const char *id; + + *interface_name = 0; + if (!monitor->adapter) return; + + if (!(monitor->edid_info.flags & MONITOR_INFO_HAS_MONITOR_ID)) id = "Default_Monitor"; + else id = monitor->edid_info.monitor_id_string; + + sprintf( buffer, "\\\\?\\DISPLAY\\%s\\%04X&%04X#%s", id, monitor->adapter->id, + monitor->id, guid_devinterface_monitorA ); + for (tmp = buffer + 4; *tmp; tmp++) if (*tmp == '\\') *tmp = '#'; Put the if on a newline.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64162
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
} }
+static BOOL is_monitor_active( struct monitor *monitor ) +{ + struct adapter *adapter; + if (!(adapter = monitor->adapter)) return TRUE; + if (!(adapter->dev.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) return FALSE; + return !IsRectEmpty(&monitor->rc_monitor);
Spaces around &monitor->rc_monitor. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64163
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceString) + sizeof(info->DeviceString)) { if (monitor) asciiz_to_unicode( info->DeviceString, "Generic Non-PnP Monitor" ); - else lstrcpyW( info->DeviceString, adapter->dev.device_string ); + else + { + sprintf( buffer, "\\\\.\\DISPLAY%d", adapter->id + 1 ); + asciiz_to_unicode( info->DeviceString, buffer );
This is wrong. DeviceString is something like "AMD Radeon RX 6600 (RADV NAVI23)" not "\\\\.\\DISPLAY*" -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64164
After this MR, EnumDisplayMonitors() doesn't report any monitors when two monitors are mirrored. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64165
Usually, EnumDisplayMonitors() returns primary monitors first. However, after this MR, monitors are returned in the reversed order. Some applications might depend on this so let's keep the old behavior. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64166
[EnumAdapters.zip](/uploads/c557879758fb3fbdfa08f503b89cf9cd/EnumAdapters.zip) Attached is the source code for a sample program that I use to test these monitor APIs. You can compile it with VS2022. Please compare the outputs before and after the MR in 1 monitor, 2 monitors, and mirrored monitor configurations. Also, check against the output on Windows in the same configuration. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64167
Also, the reason why there is a struct display_device as a cache is that we want EnumDisplayDevicesW() to be as fast as possible. So please test the performance overhead after this MR. The original performance bug is https://bugs.winehq.org/show_bug.cgi?id=51047. Please test that the game performance doesn't regress. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64169
Zhiyi Zhang (@zhiyi) commented about dlls/win32u/sysparams.c:
unsigned short manufacturer, product_code; char monitor_id_string[8]; /* MONITOR_INFO_HAS_MONITOR_NAME */ - WCHAR monitor_name[14]; + char monitor_name[14];
Unless necessary, I prefer keeping strings in Unicode as much as possible. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5262#note_64173
participants (2)
-
Rémi Bernon -
Zhiyi Zhang (@zhiyi)