Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/sysparams.c | 181 +++++++++++++++------------------------- 1 file changed, 67 insertions(+), 114 deletions(-)
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index 5842c0ae0c0..2266e88b710 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -108,18 +108,9 @@ DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4ab #define NULLDRV_DEFAULT_HMONITOR ((HMONITOR)(UINT_PTR)(0x10000 + 1))
/* Cached display device information */ -struct display_device -{ - struct list entry; /* Device list entry */ - struct list children; /* Child device list entry. For adapters, this is monitor list. For monitors, this is unused. */ - WCHAR device_name[32]; /* as DeviceName in DISPLAY_DEVICEW */ - WCHAR device_string[128]; /* as DeviceString in DISPLAY_DEVICEW */ - DWORD state_flags; /* as StateFlags in DISPLAY_DEVICEW */ - WCHAR device_id[128]; /* as DeviceID in DISPLAY_DEVICEW */ - WCHAR device_key[128]; /* as DeviceKey in DISPLAY_DEVICEW */ -}; +static DISPLAY_DEVICEW display_devices[512]; +static DISPLAY_DEVICEW *display_devices_end = display_devices;
-static struct list adapters = LIST_INIT(adapters); static FILETIME last_query_display_time; static CRITICAL_SECTION display_section; static CRITICAL_SECTION_DEBUG display_critsect_debug = @@ -130,7 +121,7 @@ static CRITICAL_SECTION_DEBUG display_critsect_debug = }; static CRITICAL_SECTION display_section = { &display_critsect_debug, -1, 0, 0, 0, 0 };
-static BOOL enum_display_device( WCHAR *device, DWORD index, struct display_device *info ); +static BOOL enum_display_device( WCHAR *device, DWORD index, DISPLAY_DEVICEW *info );
/* Cached monitor information */ static MONITORINFOEXW *monitors; @@ -3826,9 +3817,8 @@ HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags) /* Return FALSE on failure and TRUE on success */ static BOOL update_display_cache(void) { - struct display_device device, *adapter, *adapter2, *monitor, *monitor2; + DISPLAY_DEVICEW *adapter, *device; DWORD adapter_idx, monitor_idx; - struct list *monitor_list; FILETIME filetime = {0}; HANDLE mutex = NULL; BOOL ret = FALSE; @@ -3846,41 +3836,23 @@ static BOOL update_display_cache(void) mutex = get_display_device_init_mutex(); EnterCriticalSection( &display_section );
- LIST_FOR_EACH_ENTRY_SAFE(adapter, adapter2, &adapters, struct display_device, entry) + adapter_idx = 0; + device = display_devices; + while (device < display_devices + ARRAY_SIZE(display_devices) && + enum_display_device( NULL, adapter_idx++, device )) { - LIST_FOR_EACH_ENTRY_SAFE(monitor, monitor2, &adapter->children, struct display_device, entry) - { - list_remove( &monitor->entry ); - heap_free( monitor ); - } - list_remove( &adapter->entry ); - heap_free( adapter ); - } - - for (adapter_idx = 0; enum_display_device( NULL, adapter_idx, &device ); ++adapter_idx) - { - adapter = heap_alloc( sizeof(*adapter) ); - if (!adapter) - goto fail; - - memcpy( adapter, &device, sizeof(device) ); - monitor_list = &adapter->children; - list_init( monitor_list ); - list_add_tail( &adapters, &adapter->entry ); - for (monitor_idx = 0; enum_display_device( adapter->device_name, monitor_idx, &device ); ++monitor_idx) - { - monitor = heap_alloc( sizeof(*monitor) ); - if (!monitor) - goto fail; - - memcpy( monitor, &device, sizeof(device) ); - list_add_tail( monitor_list, &monitor->entry ); - } + monitor_idx = 0; + adapter = device++; + while (device < display_devices + ARRAY_SIZE(display_devices) && + enum_display_device( adapter->DeviceName, monitor_idx++, device )) + device++; } + if (device == display_devices + ARRAY_SIZE(display_devices)) + FIXME( "More than %u display devices detected, ignoring.\n", ARRAY_SIZE(display_devices) ); + display_devices_end = device;
last_query_display_time = filetime; ret = TRUE; -fail: LeaveCriticalSection( &display_section ); release_display_device_init_mutex( mutex ); return ret; @@ -4219,87 +4191,68 @@ BOOL WINAPI EnumDisplayDevicesA( LPCSTR device, DWORD index, DISPLAY_DEVICEA *in /*********************************************************************** * EnumDisplayDevicesW (USER32.@) */ -BOOL WINAPI EnumDisplayDevicesW( LPCWSTR device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags ) +BOOL WINAPI EnumDisplayDevicesW( const WCHAR *devname, DWORD index, DISPLAY_DEVICEW *info, DWORD flags ) { - struct display_device *adapter, *monitor, *found = NULL; + DISPLAY_DEVICEW *device; WCHAR buffer[MAX_PATH]; - DWORD device_idx = 0; + DWORD size;
- TRACE("%s %u %p %#x\n", debugstr_w( device ), index, info, flags); + TRACE( "devname %s, index %u, info %p, flags %#x\n", debugstr_w(devname), index, info, flags );
if (!update_display_cache()) return FALSE;
EnterCriticalSection( &display_section ); /* Enumerate adapters */ - if (!device) + if (!devname) { - LIST_FOR_EACH_ENTRY(adapter, &adapters, struct display_device, entry) + for (device = display_devices; device < display_devices_end; device++) { - if (index == device_idx++) - { - found = adapter; - break; - } + if (wcsstr( device->DeviceName, L"\Monitor" )) continue; + if (!index--) break; } } /* Enumerate monitors */ else { - LIST_FOR_EACH_ENTRY(adapter, &adapters, struct display_device, entry) - { - if (!lstrcmpiW( device, adapter->device_name )) - { - found = adapter; - break; - } - } + for (device = display_devices; device < display_devices_end; device++) + if (!wcscmp( device->DeviceName, devname )) break;
- if (found) + for (device = device + 1; device < display_devices_end; device++) { - found = NULL; - LIST_FOR_EACH_ENTRY(monitor, &adapter->children, struct display_device, entry) - { - if (index == device_idx++) - { - found = monitor; - break; - } - } + if (!wcsstr( device->DeviceName, L"\Monitor" )) device = display_devices_end; + else if (!index--) break; } }
- if (!found) + if (device >= display_devices_end) { LeaveCriticalSection( &display_section ); return FALSE; }
- if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceName) + sizeof(info->DeviceName)) - lstrcpyW( info->DeviceName, found->device_name ); - if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceString) + sizeof(info->DeviceString)) - lstrcpyW( info->DeviceString, found->device_string ); - if (info->cb >= offsetof(DISPLAY_DEVICEW, StateFlags) + sizeof(info->StateFlags)) - info->StateFlags = found->state_flags; + size = info->cb; + memcpy( info, device, info->cb ); + info->cb = size; + if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(info->DeviceID)) { - if (!device || (flags & EDD_GET_DEVICE_INTERFACE_NAME)) - lstrcpyW( info->DeviceID, found->device_id ); + if (!devname || (flags & EDD_GET_DEVICE_INTERFACE_NAME)) + lstrcpyW( info->DeviceID, device->DeviceID ); else { - swscanf( found->device_id, L"\\?\DISPLAY#%[^#]#%*[^#]#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}", buffer ); + swscanf( device->DeviceID, L"\\?\DISPLAY#%[^#]#%*[^#]#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}", buffer ); swprintf( info->DeviceID, ARRAY_SIZE(info->DeviceID), L"MONITOR\%s\{4d36e96e-e325-11ce-bfc1-08002be10318}\%s", - buffer, wcsrchr( found->device_key, '\' ) + 1 ); + buffer, wcsrchr( device->DeviceKey, '\' ) + 1 ); } } - if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(info->DeviceKey)) - lstrcpyW( info->DeviceKey, found->device_key ); + LeaveCriticalSection( &display_section ); return TRUE; }
/* Call this function with the display_device_init mutex held */ -static BOOL enum_display_device( WCHAR *device, DWORD index, struct display_device *info ) +static BOOL enum_display_device( WCHAR *device, DWORD index, DISPLAY_DEVICEW *info ) { SP_DEVINFO_DATA device_data = {sizeof(device_data)}; HDEVINFO set = INVALID_HANDLE_VALUE; @@ -4322,24 +4275,24 @@ static BOOL enum_display_device( WCHAR *device, DWORD index, struct display_devi goto done;
/* DeviceKey */ - lstrcpyW( info->device_key, bufferW ); + lstrcpyW( info->DeviceKey, bufferW );
/* DeviceName */ - swprintf( info->device_name, ARRAY_SIZE(info->device_name), L"\\.\DISPLAY%d", index + 1 ); + swprintf( info->DeviceName, ARRAY_SIZE(info->DeviceName), L"\\.\DISPLAY%d", index + 1 );
/* Strip \Registry\Machine\ */ lstrcpyW( key_nameW, bufferW + 18 );
/* DeviceString */ - size = sizeof(info->device_string); + size = sizeof(info->DeviceString); if (RegGetValueW( HKEY_LOCAL_MACHINE, key_nameW, L"DriverDesc", RRF_RT_REG_SZ, NULL, - info->device_string, &size )) + info->DeviceString, &size )) goto done;
/* StateFlags */ - size = sizeof(info->state_flags); + size = sizeof(info->StateFlags); if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, L"StateFlags", RRF_RT_REG_DWORD, NULL, - &info->state_flags, &size )) + &info->StateFlags, &size )) goto done;
/* DeviceID */ @@ -4352,7 +4305,7 @@ static BOOL enum_display_device( WCHAR *device, DWORD index, struct display_devi || !SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW, sizeof(bufferW), NULL )) goto done; - lstrcpyW( info->device_id, bufferW ); + lstrcpyW( info->DeviceID, bufferW ); } /* Find monitor */ else @@ -4369,7 +4322,7 @@ static BOOL enum_display_device( WCHAR *device, DWORD index, struct display_devi goto done;
/* DeviceName */ - swprintf( info->device_name, ARRAY_SIZE(info->device_name), L"\\.\DISPLAY%d\Monitor%d", adapter_index, index ); + swprintf( info->DeviceName, ARRAY_SIZE(info->DeviceName), L"\\.\DISPLAY%d\Monitor%d", adapter_index, index );
/* Get monitor instance */ /* Strip \Registry\Machine\ first */ @@ -4386,13 +4339,13 @@ static BOOL enum_display_device( WCHAR *device, DWORD index, struct display_devi
/* StateFlags */ if (!SetupDiGetDevicePropertyW( set, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type, - (BYTE *)&info->state_flags, sizeof(info->state_flags), NULL, 0 )) + (BYTE *)&info->StateFlags, sizeof(info->StateFlags), NULL, 0 )) goto done;
/* DeviceString */ if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_DEVICEDESC, NULL, - (BYTE *)info->device_string, - sizeof(info->device_string), NULL )) + (BYTE *)info->DeviceString, + sizeof(info->DeviceString), NULL )) goto done;
/* DeviceKey */ @@ -4400,15 +4353,15 @@ static BOOL enum_display_device( WCHAR *device, DWORD index, struct display_devi sizeof(bufferW), NULL )) goto done;
- lstrcpyW( info->device_key, L"\Registry\Machine\System\CurrentControlSet\Control\Class\" ); - lstrcatW( info->device_key, bufferW ); + lstrcpyW( info->DeviceKey, L"\Registry\Machine\System\CurrentControlSet\Control\Class\" ); + lstrcatW( info->DeviceKey, bufferW );
/* Interface name */ - lstrcpyW( info->device_id, L"\\?\" ); - lstrcatW( info->device_id, instanceW ); - lstrcatW( info->device_id, L"#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" ); + lstrcpyW( info->DeviceID, L"\\?\" ); + lstrcatW( info->DeviceID, instanceW ); + lstrcatW( info->DeviceID, L"#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" ); /* Replace '\' with '#' after prefix */ - for (next_charW = info->device_id + lstrlenW( L"\\?\" ); *next_charW; next_charW++) + for (next_charW = info->DeviceID + lstrlenW( L"\\?\" ); *next_charW; next_charW++) { if (*next_charW == '\') *next_charW = '#'; @@ -4436,11 +4389,11 @@ done: /* Adapter */ if (!device) { - lstrcpyW( info->device_name, L"\\.\DISPLAY1" ); - lstrcpyW( info->device_string, L"Wine Adapter" ); - info->state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE; - lstrcpyW( info->device_id, L"PCI\VEN_0000&DEV_0000&SUBSYS_00000000&REV_00" ); - lstrcpyW( info->device_key, L"\Registry\Machine\System\CurrentControlSet\Control\Video\{71c91c84-1064-400f-a994-95e3ff2716d6}\0000" ); + lstrcpyW( info->DeviceName, L"\\.\DISPLAY1" ); + lstrcpyW( info->DeviceString, L"Wine Adapter" ); + info->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE; + lstrcpyW( info->DeviceID, L"PCI\VEN_0000&DEV_0000&SUBSYS_00000000&REV_00" ); + lstrcpyW( info->DeviceKey, L"\Registry\Machine\System\CurrentControlSet\Control\Video\{71c91c84-1064-400f-a994-95e3ff2716d6}\0000" ); } /* Monitor */ else @@ -4448,11 +4401,11 @@ done: if (lstrcmpiW( L"\\.\DISPLAY1", device )) return FALSE;
- lstrcpyW( info->device_name, L"\\.\DISPLAY1\Monitor0" ); - lstrcpyW( info->device_string, L"Generic Non-PnP Monitor" ); - info->state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED; - lstrcpyW( info->device_id, L"\\?\DISPLAY#Default_Monitor#4&17f0ff54&0&UID0#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" ); - lstrcpyW( info->device_key, L"\Registry\Machine\System\CurrentControlSet\Control\Class\{4d36e96e-e325-11ce-bfc1-08002be10318}\0000" ); + lstrcpyW( info->DeviceName, L"\\.\DISPLAY1\Monitor0" ); + lstrcpyW( info->DeviceString, L"Generic Non-PnP Monitor" ); + info->StateFlags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED; + lstrcpyW( info->DeviceID, L"\\?\DISPLAY#Default_Monitor#4&17f0ff54&0&UID0#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" ); + lstrcpyW( info->DeviceKey, L"\Registry\Machine\System\CurrentControlSet\Control\Class\{4d36e96e-e325-11ce-bfc1-08002be10318}\0000" ); }
return TRUE;