win32u: Implement NtUserEnumDisplayDevices.
And use it in user32. Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b502a3e3c6
commit
f6abd9d140
|
@ -106,31 +106,6 @@ DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4ab
|
||||||
|
|
||||||
#define NULLDRV_DEFAULT_HMONITOR ((HMONITOR)(UINT_PTR)(0x10000 + 1))
|
#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 when EDD_GET_DEVICE_INTERFACE_NAME is not set */
|
|
||||||
WCHAR interface_name[128]; /* as DeviceID in DISPLAY_DEVICEW when EDD_GET_DEVICE_INTERFACE_NAME is set */
|
|
||||||
WCHAR device_key[128]; /* as DeviceKey in DISPLAY_DEVICEW */
|
|
||||||
};
|
|
||||||
|
|
||||||
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 =
|
|
||||||
{
|
|
||||||
0, 0, &display_section,
|
|
||||||
{ &display_critsect_debug.ProcessLocksList, &display_critsect_debug.ProcessLocksList },
|
|
||||||
0, 0, { (DWORD_PTR)(__FILE__ ": display_section") }
|
|
||||||
};
|
|
||||||
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 );
|
|
||||||
|
|
||||||
/* Cached monitor information */
|
/* Cached monitor information */
|
||||||
static MONITORINFOEXW *monitors;
|
static MONITORINFOEXW *monitors;
|
||||||
|
@ -3816,69 +3791,6 @@ HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
|
||||||
return MonitorFromRect( &rect, dwFlags );
|
return MonitorFromRect( &rect, dwFlags );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return FALSE on failure and TRUE on success */
|
|
||||||
static BOOL update_display_cache(void)
|
|
||||||
{
|
|
||||||
struct display_device device, *adapter, *adapter2, *monitor, *monitor2;
|
|
||||||
DWORD adapter_idx, monitor_idx;
|
|
||||||
struct list *monitor_list;
|
|
||||||
FILETIME filetime = {0};
|
|
||||||
HANDLE mutex = NULL;
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
|
||||||
/* Update display cache from SetupAPI if it's outdated */
|
|
||||||
wait_graphics_driver_ready();
|
|
||||||
|
|
||||||
if (!video_key && RegOpenKeyW( HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\VIDEO", &video_key ))
|
|
||||||
return FALSE;
|
|
||||||
if (RegQueryInfoKeyW( video_key, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &filetime ))
|
|
||||||
return FALSE;
|
|
||||||
if (CompareFileTime( &filetime, &last_query_display_time ) < 1)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
mutex = get_display_device_init_mutex();
|
|
||||||
EnterCriticalSection( &display_section );
|
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(adapter, adapter2, &adapters, struct display_device, entry)
|
|
||||||
{
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_query_display_time = filetime;
|
|
||||||
ret = TRUE;
|
|
||||||
fail:
|
|
||||||
LeaveCriticalSection( &display_section );
|
|
||||||
release_display_device_init_mutex( mutex );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return FALSE on failure and TRUE on success */
|
/* Return FALSE on failure and TRUE on success */
|
||||||
static BOOL update_monitor_cache(void)
|
static BOOL update_monitor_cache(void)
|
||||||
{
|
{
|
||||||
|
@ -4214,250 +4126,9 @@ BOOL WINAPI EnumDisplayDevicesA( LPCSTR device, DWORD index, DISPLAY_DEVICEA *in
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI EnumDisplayDevicesW( LPCWSTR device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags )
|
BOOL WINAPI EnumDisplayDevicesW( LPCWSTR device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags )
|
||||||
{
|
{
|
||||||
struct display_device *adapter, *monitor, *found = NULL;
|
UNICODE_STRING str;
|
||||||
DWORD device_idx = 0;
|
RtlInitUnicodeString( &str, device );
|
||||||
|
return NtUserEnumDisplayDevices( &str, index, info, flags );
|
||||||
TRACE("%s %u %p %#x\n", debugstr_w( device ), index, info, flags);
|
|
||||||
|
|
||||||
if (!update_display_cache())
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
EnterCriticalSection( &display_section );
|
|
||||||
/* Enumerate adapters */
|
|
||||||
if (!device)
|
|
||||||
{
|
|
||||||
LIST_FOR_EACH_ENTRY(adapter, &adapters, struct display_device, entry)
|
|
||||||
{
|
|
||||||
if (index == device_idx++)
|
|
||||||
{
|
|
||||||
found = adapter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Enumerate monitors */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LIST_FOR_EACH_ENTRY(adapter, &adapters, struct display_device, entry)
|
|
||||||
{
|
|
||||||
if (!lstrcmpiW( device, adapter->device_name ))
|
|
||||||
{
|
|
||||||
found = adapter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
found = NULL;
|
|
||||||
LIST_FOR_EACH_ENTRY(monitor, &adapter->children, struct display_device, entry)
|
|
||||||
{
|
|
||||||
if (index == device_idx++)
|
|
||||||
{
|
|
||||||
found = monitor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
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 (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 )
|
|
||||||
{
|
|
||||||
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
|
|
||||||
HDEVINFO set = INVALID_HANDLE_VALUE;
|
|
||||||
WCHAR key_nameW[MAX_PATH];
|
|
||||||
WCHAR instanceW[MAX_PATH];
|
|
||||||
WCHAR bufferW[1024];
|
|
||||||
LONG adapter_index;
|
|
||||||
WCHAR *next_charW;
|
|
||||||
DWORD size;
|
|
||||||
DWORD type;
|
|
||||||
HKEY hkey;
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
|
||||||
/* Find adapter */
|
|
||||||
if (!device)
|
|
||||||
{
|
|
||||||
swprintf( key_nameW, ARRAY_SIZE(key_nameW), L"\\Device\\Video%d", index );
|
|
||||||
size = sizeof(bufferW);
|
|
||||||
if (RegGetValueW( HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\VIDEO", key_nameW, RRF_RT_REG_SZ, NULL, bufferW, &size ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* DeviceKey */
|
|
||||||
lstrcpyW( info->device_key, bufferW );
|
|
||||||
|
|
||||||
/* DeviceName */
|
|
||||||
swprintf( info->device_name, ARRAY_SIZE(info->device_name), L"\\\\.\\DISPLAY%d", index + 1 );
|
|
||||||
|
|
||||||
/* Strip \Registry\Machine\ */
|
|
||||||
lstrcpyW( key_nameW, bufferW + 18 );
|
|
||||||
|
|
||||||
/* DeviceString */
|
|
||||||
size = sizeof(info->device_string);
|
|
||||||
if (RegGetValueW( HKEY_LOCAL_MACHINE, key_nameW, L"DriverDesc", RRF_RT_REG_SZ, NULL,
|
|
||||||
info->device_string, &size ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* StateFlags */
|
|
||||||
size = sizeof(info->state_flags);
|
|
||||||
if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, L"StateFlags", RRF_RT_REG_DWORD, NULL,
|
|
||||||
&info->state_flags, &size ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Interface name */
|
|
||||||
info->interface_name[0] = 0;
|
|
||||||
|
|
||||||
/* DeviceID */
|
|
||||||
size = sizeof(bufferW);
|
|
||||||
if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, L"GPUID", RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
|
|
||||||
bufferW, &size ))
|
|
||||||
goto done;
|
|
||||||
set = SetupDiCreateDeviceInfoList( &GUID_DEVCLASS_DISPLAY, NULL );
|
|
||||||
if (!SetupDiOpenDeviceInfoW( set, bufferW, NULL, 0, &device_data )
|
|
||||||
|| !SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
|
|
||||||
sizeof(bufferW), NULL ))
|
|
||||||
goto done;
|
|
||||||
lstrcpyW( info->device_id, bufferW );
|
|
||||||
}
|
|
||||||
/* Find monitor */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Check adapter name */
|
|
||||||
if (wcsnicmp( device, L"\\\\.\\DISPLAY", lstrlenW(L"\\\\.\\DISPLAY") ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
adapter_index = wcstol( device + lstrlenW(L"\\\\.\\DISPLAY"), NULL, 10 );
|
|
||||||
swprintf( key_nameW, ARRAY_SIZE(key_nameW), L"\\Device\\Video%d", adapter_index - 1 );
|
|
||||||
|
|
||||||
size = sizeof(bufferW);
|
|
||||||
if (RegGetValueW( HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\VIDEO", key_nameW, RRF_RT_REG_SZ, NULL, bufferW, &size ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* DeviceName */
|
|
||||||
swprintf( info->device_name, ARRAY_SIZE(info->device_name), L"\\\\.\\DISPLAY%d\\Monitor%d", adapter_index, index );
|
|
||||||
|
|
||||||
/* Get monitor instance */
|
|
||||||
/* Strip \Registry\Machine\ first */
|
|
||||||
lstrcpyW( key_nameW, bufferW + 18 );
|
|
||||||
swprintf( bufferW, ARRAY_SIZE(bufferW), L"MonitorID%d", index );
|
|
||||||
|
|
||||||
size = sizeof(instanceW);
|
|
||||||
if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, bufferW, RRF_RT_REG_SZ, NULL, instanceW, &size ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
set = SetupDiCreateDeviceInfoList( &GUID_DEVCLASS_MONITOR, NULL );
|
|
||||||
if (!SetupDiOpenDeviceInfoW( set, instanceW, NULL, 0, &device_data ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* StateFlags */
|
|
||||||
if (!SetupDiGetDevicePropertyW( set, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type,
|
|
||||||
(BYTE *)&info->state_flags, sizeof(info->state_flags), NULL, 0 ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* DeviceString */
|
|
||||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_DEVICEDESC, NULL,
|
|
||||||
(BYTE *)info->device_string,
|
|
||||||
sizeof(info->device_string), NULL ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* DeviceKey */
|
|
||||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
|
|
||||||
sizeof(bufferW), NULL ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
lstrcpyW( info->device_key, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\" );
|
|
||||||
lstrcatW( info->device_key, bufferW );
|
|
||||||
|
|
||||||
/* Interface name */
|
|
||||||
lstrcpyW( info->interface_name, L"\\\\\?\\" );
|
|
||||||
lstrcatW( info->interface_name, instanceW );
|
|
||||||
lstrcatW( info->interface_name, L"#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" );
|
|
||||||
/* Replace '\\' with '#' after prefix */
|
|
||||||
for (next_charW = info->interface_name + lstrlenW( L"\\\\\?\\" ); *next_charW; next_charW++)
|
|
||||||
{
|
|
||||||
if (*next_charW == '\\')
|
|
||||||
*next_charW = '#';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DeviceID */
|
|
||||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
|
|
||||||
sizeof(bufferW), NULL ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
lstrcpyW( info->device_id, bufferW );
|
|
||||||
lstrcatW( info->device_id, L"\\" );
|
|
||||||
|
|
||||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
|
|
||||||
sizeof(bufferW), NULL ))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
lstrcatW( info->device_id, bufferW );
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = TRUE;
|
|
||||||
done:
|
|
||||||
SetupDiDestroyDeviceInfoList( set );
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Fallback to report at least one adapter and monitor, if user driver didn't initialize display device registry */
|
|
||||||
if (index)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* If user driver did initialize the registry, then exit */
|
|
||||||
if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\VIDEO", &hkey ))
|
|
||||||
{
|
|
||||||
RegCloseKey( hkey );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
WARN("Reporting fallback display devices\n");
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
info->interface_name[0] = 0;
|
|
||||||
lstrcpyW( info->device_id, L"PCI\\VEN_0000&DEV_0000&SUBSYS_00000000&REV_00" );
|
|
||||||
info->device_key[0] = 0;
|
|
||||||
}
|
|
||||||
/* Monitor */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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->interface_name, L"\\\\\?\\DISPLAY#Default_Monitor#4&17f0ff54&0&UID0#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}" );
|
|
||||||
lstrcpyW( info->device_id, L"MONITOR\\Default_Monitor\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0000" );
|
|
||||||
info->device_key[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|
|
@ -53,12 +53,6 @@ struct dc_attr_bucket
|
||||||
|
|
||||||
static struct list dc_attr_buckets = LIST_INIT( dc_attr_buckets );
|
static struct list dc_attr_buckets = LIST_INIT( dc_attr_buckets );
|
||||||
|
|
||||||
static inline const char *debugstr_us( const UNICODE_STRING *us )
|
|
||||||
{
|
|
||||||
if (!us) return "<null>";
|
|
||||||
return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL DC_DeleteObject( HGDIOBJ handle );
|
static BOOL DC_DeleteObject( HGDIOBJ handle );
|
||||||
|
|
||||||
static const struct gdi_obj_funcs dc_funcs =
|
static const struct gdi_obj_funcs dc_funcs =
|
||||||
|
|
|
@ -1169,6 +1169,7 @@ static struct unix_funcs unix_funcs =
|
||||||
NtGdiWidenPath,
|
NtGdiWidenPath,
|
||||||
NtUserActivateKeyboardLayout,
|
NtUserActivateKeyboardLayout,
|
||||||
NtUserCountClipboardFormats,
|
NtUserCountClipboardFormats,
|
||||||
|
NtUserEnumDisplayDevices,
|
||||||
NtUserGetDisplayConfigBufferSizes,
|
NtUserGetDisplayConfigBufferSizes,
|
||||||
NtUserGetKeyNameText,
|
NtUserGetKeyNameText,
|
||||||
NtUserGetKeyboardLayoutList,
|
NtUserGetKeyboardLayoutList,
|
||||||
|
|
|
@ -640,6 +640,5 @@ extern void CDECL free_heap_bits( struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
|
||||||
void set_gdi_client_ptr( HGDIOBJ handle, void *ptr ) DECLSPEC_HIDDEN;
|
void set_gdi_client_ptr( HGDIOBJ handle, void *ptr ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern SYSTEM_BASIC_INFORMATION system_info DECLSPEC_HIDDEN;
|
extern SYSTEM_BASIC_INFORMATION system_info DECLSPEC_HIDDEN;
|
||||||
extern const struct user_callbacks *user_callbacks DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
#endif /* __WINE_NTGDI_PRIVATE_H */
|
#endif /* __WINE_NTGDI_PRIVATE_H */
|
||||||
|
|
|
@ -1211,3 +1211,74 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in
|
||||||
TRACE( "returning %u paths %u modes\n", *num_path_info, *num_mode_info );
|
TRACE( "returning %u paths %u modes\n", *num_path_info, *num_mode_info );
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct adapter *find_adapter( UNICODE_STRING *name )
|
||||||
|
{
|
||||||
|
struct adapter *adapter;
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry)
|
||||||
|
{
|
||||||
|
if (!name || !name->Length) return adapter; /* use primary adapter */
|
||||||
|
if (!wcsnicmp( name->Buffer, adapter->dev.device_name, name->Length / sizeof(WCHAR) ) &&
|
||||||
|
!adapter->dev.device_name[name->Length / sizeof(WCHAR)])
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtUserEnumDisplayDevices (win32u.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
|
||||||
|
DISPLAY_DEVICEW *info, DWORD flags )
|
||||||
|
{
|
||||||
|
struct display_device *found = NULL;
|
||||||
|
struct adapter *adapter;
|
||||||
|
struct monitor *monitor;
|
||||||
|
|
||||||
|
TRACE( "%s %u %p %#x\n", debugstr_us( device ), index, info, flags );
|
||||||
|
|
||||||
|
if (!lock_display_devices()) return FALSE;
|
||||||
|
|
||||||
|
if (!device || !device->Length)
|
||||||
|
{
|
||||||
|
/* Enumerate adapters */
|
||||||
|
LIST_FOR_EACH_ENTRY(adapter, &adapters, struct adapter, entry)
|
||||||
|
{
|
||||||
|
if (index == adapter->id)
|
||||||
|
{
|
||||||
|
found = &adapter->dev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((adapter = find_adapter( device )))
|
||||||
|
{
|
||||||
|
/* Enumerate monitors */
|
||||||
|
LIST_FOR_EACH_ENTRY(monitor, &monitors, struct monitor, entry)
|
||||||
|
{
|
||||||
|
if (monitor->adapter == adapter && index == monitor->id)
|
||||||
|
{
|
||||||
|
found = &monitor->dev;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
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 (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(info->DeviceKey))
|
||||||
|
lstrcpyW( info->DeviceKey, found->device_key );
|
||||||
|
}
|
||||||
|
unlock_display_devices();
|
||||||
|
return !!found;
|
||||||
|
}
|
||||||
|
|
|
@ -875,7 +875,7 @@
|
||||||
@ stub NtUserEndDeferWindowPosEx
|
@ stub NtUserEndDeferWindowPosEx
|
||||||
@ stub NtUserEndMenu
|
@ stub NtUserEndMenu
|
||||||
@ stub NtUserEndPaint
|
@ stub NtUserEndPaint
|
||||||
@ stub NtUserEnumDisplayDevices
|
@ stdcall NtUserEnumDisplayDevices(ptr long ptr long)
|
||||||
@ stub NtUserEnumDisplayMonitors
|
@ stub NtUserEnumDisplayMonitors
|
||||||
@ stub NtUserEnumDisplaySettings
|
@ stub NtUserEnumDisplaySettings
|
||||||
@ stub NtUserEvent
|
@ stub NtUserEvent
|
||||||
|
|
|
@ -44,6 +44,8 @@ struct user_callbacks
|
||||||
HWND (WINAPI *pWindowFromDC)( HDC );
|
HWND (WINAPI *pWindowFromDC)( HDC );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct user_callbacks *user_callbacks DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
/* win32u functions */
|
/* win32u functions */
|
||||||
|
@ -196,6 +198,8 @@ struct unix_funcs
|
||||||
BOOL (WINAPI *pNtGdiWidenPath)( HDC hdc );
|
BOOL (WINAPI *pNtGdiWidenPath)( HDC hdc );
|
||||||
HKL (WINAPI *pNtUserActivateKeyboardLayout)( HKL layout, UINT flags );
|
HKL (WINAPI *pNtUserActivateKeyboardLayout)( HKL layout, UINT flags );
|
||||||
INT (WINAPI *pNtUserCountClipboardFormats)(void);
|
INT (WINAPI *pNtUserCountClipboardFormats)(void);
|
||||||
|
BOOL (WINAPI *pNtUserEnumDisplayDevices)( UNICODE_STRING *device, DWORD index,
|
||||||
|
DISPLAY_DEVICEW *info, DWORD flags );
|
||||||
LONG (WINAPI *pNtUserGetDisplayConfigBufferSizes)( UINT32 flags, UINT32 *num_path_info,
|
LONG (WINAPI *pNtUserGetDisplayConfigBufferSizes)( UINT32 flags, UINT32 *num_path_info,
|
||||||
UINT32 *num_mode_info );
|
UINT32 *num_mode_info );
|
||||||
INT (WINAPI *pNtUserGetKeyNameText)( LONG lparam, WCHAR *buffer, INT size );
|
INT (WINAPI *pNtUserGetKeyNameText)( LONG lparam, WCHAR *buffer, INT size );
|
||||||
|
@ -390,4 +394,10 @@ static inline BOOL is_win9x(void)
|
||||||
return NtCurrentTeb()->Peb->OSPlatformId == VER_PLATFORM_WIN32s;
|
return NtCurrentTeb()->Peb->OSPlatformId == VER_PLATFORM_WIN32s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *debugstr_us( const UNICODE_STRING *us )
|
||||||
|
{
|
||||||
|
if (!us) return "<null>";
|
||||||
|
return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) );
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __WINE_WIN32U_PRIVATE */
|
#endif /* __WINE_WIN32U_PRIVATE */
|
||||||
|
|
|
@ -606,6 +606,12 @@ INT WINAPI NtUserCountClipboardFormats(void)
|
||||||
return unix_funcs->pNtUserCountClipboardFormats();
|
return unix_funcs->pNtUserCountClipboardFormats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
|
||||||
|
DISPLAY_DEVICEW *info, DWORD flags )
|
||||||
|
{
|
||||||
|
return unix_funcs->pNtUserEnumDisplayDevices( device, index, info, flags );
|
||||||
|
}
|
||||||
|
|
||||||
LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_info,
|
LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_info,
|
||||||
UINT32 *num_mode_info )
|
UINT32 *num_mode_info )
|
||||||
{
|
{
|
||||||
|
@ -847,7 +853,7 @@ static HWND WINAPI call_WindowFromDC( HDC hdc )
|
||||||
return pWindowFromDC ? pWindowFromDC( hdc ) : NULL;
|
return pWindowFromDC ? pWindowFromDC( hdc ) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct user_callbacks user_callbacks =
|
static const struct user_callbacks user_funcs =
|
||||||
{
|
{
|
||||||
call_GetDesktopWindow,
|
call_GetDesktopWindow,
|
||||||
call_GetDpiForSystem,
|
call_GetDpiForSystem,
|
||||||
|
@ -863,6 +869,6 @@ static const struct user_callbacks user_callbacks =
|
||||||
|
|
||||||
extern void wrappers_init( unixlib_handle_t handle )
|
extern void wrappers_init( unixlib_handle_t handle )
|
||||||
{
|
{
|
||||||
const void *args = &user_callbacks;
|
const void *args = &user_funcs;
|
||||||
if (!__wine_unix_call( handle, 1, &args )) unix_funcs = args;
|
if (!__wine_unix_call( handle, 1, &args )) unix_funcs = args;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,8 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *d
|
||||||
ULONG heap_size );
|
ULONG heap_size );
|
||||||
HWINSTA WINAPI NtUserCreateWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK mask, ULONG arg3,
|
HWINSTA WINAPI NtUserCreateWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK mask, ULONG arg3,
|
||||||
ULONG arg4, ULONG arg5, ULONG arg6, ULONG arg7 );
|
ULONG arg4, ULONG arg5, ULONG arg6, ULONG arg7 );
|
||||||
|
BOOL WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
|
||||||
|
DISPLAY_DEVICEW *info, DWORD flags );
|
||||||
INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen );
|
INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen );
|
||||||
HWND WINAPI NtUserGetClipboardOwner(void);
|
HWND WINAPI NtUserGetClipboardOwner(void);
|
||||||
DWORD WINAPI NtUserGetClipboardSequenceNumber(void);
|
DWORD WINAPI NtUserGetClipboardSequenceNumber(void);
|
||||||
|
|
Loading…
Reference in New Issue