1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

win32u: Get rid of the monitor display_device.

This commit is contained in:
Rémi Bernon 2024-02-27 14:32:27 +01:00 committed by Alexandre Julliard
parent 3bcd6f1aab
commit caf9585c3c

View file

@ -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))
@ -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, &current_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;