mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-07 13:34:06 +00:00
user32: Move EnumDisplayDevicesA/W to sysparams.c.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
dd202c1175
commit
db839e0f1a
|
@ -28,14 +28,7 @@
|
|||
#include "wine/windef16.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
#include "controls.h"
|
||||
#include "initguid.h"
|
||||
#include "devguid.h"
|
||||
#include "setupapi.h"
|
||||
#include "user_private.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
|
@ -43,66 +36,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
||||
|
||||
/* Wine specific monitor properties */
|
||||
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
|
||||
|
||||
static const WCHAR default_adapter_name[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
|
||||
static const WCHAR default_monitor_name[] =
|
||||
{'\\','\\','.','\\',
|
||||
'D','I','S','P','L','A','Y','1','\\',
|
||||
'M','o','n','i','t','o','r','0',0};
|
||||
static const WCHAR default_adapter_string[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0};
|
||||
static const WCHAR default_monitor_string[] =
|
||||
{'G','e','n','e','r','i','c',' ','N','o','n','-','P','n','P',' ','M','o','n','i','t','o','r',0};
|
||||
static const WCHAR default_adapter_id[] =
|
||||
{'P','C','I','\\',
|
||||
'V','E','N','_','0','0','0','0','&',
|
||||
'D','E','V','_','0','0','0','0','&',
|
||||
'S','U','B','S','Y','S','_','0','0','0','0','0','0','0','0','&',
|
||||
'R','E','V','_','0','0',0};
|
||||
static const WCHAR default_monitor_id[] =
|
||||
{'M','O','N','I','T','O','R','\\',
|
||||
'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r','\\',
|
||||
'{','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','0','0','0',0};
|
||||
static const WCHAR default_monitor_interface_id[] =
|
||||
{'\\','\\','\?','\\',
|
||||
'D','I','S','P','L','A','Y','#','D','e','f','a','u','l','t','_','M','o','n','i','t','o','r','#',
|
||||
'4','&','1','7','f','0','f','f','5','4','&','0','&','U','I','D','0','#',
|
||||
'{','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};
|
||||
|
||||
static const WCHAR monitor_fmtW[] =
|
||||
{'\\','\\','.','\\',
|
||||
'D','I','S','P','L','A','Y','%','d','\\',
|
||||
'M','o','n','i','t','o','r','%','d',0};
|
||||
static const WCHAR adapter_fmtW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0};
|
||||
static const WCHAR displayW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
|
||||
static const WCHAR video_keyW[] =
|
||||
{'H','A','R','D','W','A','R','E','\\',
|
||||
'D','E','V','I','C','E','M','A','P','\\',
|
||||
'V','I','D','E','O','\\',0};
|
||||
static const WCHAR video_value_fmtW[] =
|
||||
{'\\','D','e','v','i','c','e','\\',
|
||||
'V','i','d','e','o','%','d',0};
|
||||
static const WCHAR monitor_interface_prefixW[] = {'\\','\\','\?','\\',0};
|
||||
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};
|
||||
static const WCHAR backslashW[] = {'\\',0};
|
||||
static const WCHAR nt_classW[] =
|
||||
{'\\','R','e','g','i','s','t','r','y','\\',
|
||||
'M','a','c','h','i','n','e','\\',
|
||||
'S','y','s','t','e','m','\\',
|
||||
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
|
||||
'C','o','n','t','r','o','l','\\',
|
||||
'C','l','a','s','s','\\',0};
|
||||
static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
|
||||
static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
|
||||
static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
|
||||
static const WCHAR mointor_id_value_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0};
|
||||
|
||||
#define IMM_INIT_MAGIC 0x19650412
|
||||
static HWND (WINAPI *imm_get_ui_window)(HKL);
|
||||
BOOL (WINAPI *imm_register_window)(HWND) = NULL;
|
||||
|
@ -307,252 +240,6 @@ DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EnumDisplayDevicesA (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpDispDev,
|
||||
DWORD dwFlags )
|
||||
{
|
||||
UNICODE_STRING deviceW;
|
||||
DISPLAY_DEVICEW ddW;
|
||||
BOOL ret;
|
||||
|
||||
if(lpDevice)
|
||||
RtlCreateUnicodeStringFromAsciiz(&deviceW, lpDevice);
|
||||
else
|
||||
deviceW.Buffer = NULL;
|
||||
|
||||
ddW.cb = sizeof(ddW);
|
||||
ret = EnumDisplayDevicesW(deviceW.Buffer, i, &ddW, dwFlags);
|
||||
RtlFreeUnicodeString(&deviceW);
|
||||
|
||||
if(!ret) return ret;
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceName, -1, lpDispDev->DeviceName, sizeof(lpDispDev->DeviceName), NULL, NULL);
|
||||
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceString, -1, lpDispDev->DeviceString, sizeof(lpDispDev->DeviceString), NULL, NULL);
|
||||
lpDispDev->StateFlags = ddW.StateFlags;
|
||||
|
||||
if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceID) + sizeof(lpDispDev->DeviceID))
|
||||
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceID, -1, lpDispDev->DeviceID, sizeof(lpDispDev->DeviceID), NULL, NULL);
|
||||
if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceKey) + sizeof(lpDispDev->DeviceKey))
|
||||
WideCharToMultiByte(CP_ACP, 0, ddW.DeviceKey, -1, lpDispDev->DeviceKey, sizeof(lpDispDev->DeviceKey), NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EnumDisplayDevicesW (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice,
|
||||
DWORD dwFlags )
|
||||
{
|
||||
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;
|
||||
|
||||
TRACE("%s %d %p %#x\n", debugstr_w(lpDevice), i, lpDisplayDevice, dwFlags);
|
||||
|
||||
/* Find adapter */
|
||||
if (!lpDevice)
|
||||
{
|
||||
sprintfW(key_nameW, video_value_fmtW, i);
|
||||
size = sizeof(bufferW);
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, video_keyW, key_nameW, RRF_RT_REG_SZ, NULL, bufferW, &size))
|
||||
return FALSE;
|
||||
|
||||
/* DeviceKey */
|
||||
if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
|
||||
lstrcpyW(lpDisplayDevice->DeviceKey, bufferW);
|
||||
|
||||
/* DeviceName */
|
||||
sprintfW(lpDisplayDevice->DeviceName, adapter_fmtW, i + 1);
|
||||
|
||||
/* Strip \Registry\Machine\ */
|
||||
lstrcpyW(key_nameW, bufferW + 18);
|
||||
|
||||
/* DeviceString */
|
||||
size = sizeof(lpDisplayDevice->DeviceString);
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, key_nameW, driver_descW, RRF_RT_REG_SZ, NULL,
|
||||
lpDisplayDevice->DeviceString, &size))
|
||||
return FALSE;
|
||||
|
||||
/* StateFlags */
|
||||
size = sizeof(lpDisplayDevice->StateFlags);
|
||||
if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, state_flagsW, RRF_RT_REG_DWORD, NULL,
|
||||
&lpDisplayDevice->StateFlags, &size))
|
||||
return FALSE;
|
||||
|
||||
/* DeviceID */
|
||||
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
|
||||
{
|
||||
if (dwFlags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
lpDisplayDevice->DeviceID[0] = 0;
|
||||
else
|
||||
{
|
||||
size = sizeof(bufferW);
|
||||
if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, gpu_idW, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
|
||||
bufferW, &size))
|
||||
return FALSE;
|
||||
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(lpDisplayDevice->DeviceID, bufferW);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Find monitor */
|
||||
else
|
||||
{
|
||||
/* Check adapter name */
|
||||
if (strncmpiW(lpDevice, displayW, ARRAY_SIZE(displayW)))
|
||||
return FALSE;
|
||||
|
||||
adapter_index = strtolW(lpDevice + ARRAY_SIZE(displayW), NULL, 10);
|
||||
sprintfW(key_nameW, video_value_fmtW, adapter_index - 1);
|
||||
|
||||
size = sizeof(bufferW);
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, video_keyW, key_nameW, RRF_RT_REG_SZ, NULL, bufferW, &size))
|
||||
return FALSE;
|
||||
|
||||
/* DeviceName */
|
||||
sprintfW(lpDisplayDevice->DeviceName, monitor_fmtW, adapter_index, i);
|
||||
|
||||
/* Get monitor instance */
|
||||
/* Strip \Registry\Machine\ first */
|
||||
lstrcpyW(key_nameW, bufferW + 18);
|
||||
sprintfW(bufferW, mointor_id_value_fmtW, i);
|
||||
|
||||
size = sizeof(instanceW);
|
||||
if (RegGetValueW(HKEY_CURRENT_CONFIG, key_nameW, bufferW, RRF_RT_REG_SZ, NULL, instanceW, &size))
|
||||
return FALSE;
|
||||
|
||||
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 *)&lpDisplayDevice->StateFlags, sizeof(lpDisplayDevice->StateFlags), NULL, 0))
|
||||
goto done;
|
||||
|
||||
/* DeviceString */
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DEVICEDESC, NULL,
|
||||
(BYTE *)lpDisplayDevice->DeviceString,
|
||||
sizeof(lpDisplayDevice->DeviceString), NULL))
|
||||
goto done;
|
||||
|
||||
/* DeviceKey */
|
||||
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
|
||||
{
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
|
||||
sizeof(bufferW), NULL))
|
||||
goto done;
|
||||
|
||||
lstrcpyW(lpDisplayDevice->DeviceKey, nt_classW);
|
||||
lstrcatW(lpDisplayDevice->DeviceKey, bufferW);
|
||||
}
|
||||
|
||||
/* DeviceID */
|
||||
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
|
||||
{
|
||||
if (dwFlags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
{
|
||||
lstrcpyW(lpDisplayDevice->DeviceID, monitor_interface_prefixW);
|
||||
lstrcatW(lpDisplayDevice->DeviceID, instanceW);
|
||||
lstrcatW(lpDisplayDevice->DeviceID, guid_devinterface_monitorW);
|
||||
/* Replace '\\' with '#' after prefix */
|
||||
for (next_charW = lpDisplayDevice->DeviceID + strlenW(monitor_interface_prefixW); *next_charW;
|
||||
next_charW++)
|
||||
{
|
||||
if (*next_charW == '\\')
|
||||
*next_charW = '#';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
|
||||
sizeof(bufferW), NULL))
|
||||
goto done;
|
||||
|
||||
lstrcpyW(lpDisplayDevice->DeviceID, bufferW);
|
||||
lstrcatW(lpDisplayDevice->DeviceID, backslashW);
|
||||
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
|
||||
sizeof(bufferW), NULL))
|
||||
goto done;
|
||||
|
||||
lstrcatW(lpDisplayDevice->DeviceID, 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 (i)
|
||||
return FALSE;
|
||||
|
||||
/* If user driver did initialize the registry, then exit */
|
||||
if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, video_keyW, &hkey))
|
||||
{
|
||||
RegCloseKey(hkey);
|
||||
return FALSE;
|
||||
}
|
||||
WARN("Reporting fallback display devices\n");
|
||||
|
||||
/* Adapter */
|
||||
if (!lpDevice)
|
||||
{
|
||||
memcpy(lpDisplayDevice->DeviceName, default_adapter_name, sizeof(default_adapter_name));
|
||||
memcpy(lpDisplayDevice->DeviceString, default_adapter_string, sizeof(default_adapter_string));
|
||||
lpDisplayDevice->StateFlags =
|
||||
DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE;
|
||||
if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
|
||||
{
|
||||
if (dwFlags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
lpDisplayDevice->DeviceID[0] = 0;
|
||||
else
|
||||
memcpy(lpDisplayDevice->DeviceID, default_adapter_id, sizeof(default_adapter_id));
|
||||
}
|
||||
}
|
||||
/* Monitor */
|
||||
else
|
||||
{
|
||||
if (lstrcmpiW(default_adapter_name, lpDevice))
|
||||
return FALSE;
|
||||
|
||||
memcpy(lpDisplayDevice->DeviceName, default_monitor_name, sizeof(default_monitor_name));
|
||||
memcpy(lpDisplayDevice->DeviceString, default_monitor_string, sizeof(default_monitor_string));
|
||||
lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED;
|
||||
if (lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
|
||||
{
|
||||
if (dwFlags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
memcpy(lpDisplayDevice->DeviceID, default_monitor_interface_id, sizeof(default_monitor_interface_id));
|
||||
else
|
||||
memcpy(lpDisplayDevice->DeviceID, default_monitor_id, sizeof(default_monitor_id));
|
||||
}
|
||||
}
|
||||
|
||||
if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
|
||||
lpDisplayDevice->DeviceKey[0] = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* QueryDisplayConfig (USER32.@)
|
||||
*/
|
||||
|
|
|
@ -34,10 +34,14 @@
|
|||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/wingdi16.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "initguid.h"
|
||||
#include "devguid.h"
|
||||
#include "setupapi.h"
|
||||
#include "controls.h"
|
||||
#include "win.h"
|
||||
#include "user_private.h"
|
||||
|
@ -245,6 +249,56 @@ static const WCHAR CSu[] = {'%','u',0};
|
|||
static const WCHAR CSd[] = {'%','d',0};
|
||||
static const WCHAR CSrgb[] = {'%','u',' ','%','u',' ','%','u',0};
|
||||
|
||||
/* Wine specific monitor properties */
|
||||
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
|
||||
|
||||
/* Strings for monitor functions */
|
||||
static const WCHAR DEFAULT_ADAPTER_NAME[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
|
||||
static const WCHAR DEFAULT_MONITOR_NAME[] = {'\\','\\','.','\\',
|
||||
'D','I','S','P','L','A','Y','1','\\',
|
||||
'M','o','n','i','t','o','r','0',0};
|
||||
static const WCHAR DEFAULT_ADAPTER_STRING[] = {'W','i','n','e',' ','A','d','a','p','t','e','r',0};
|
||||
static const WCHAR DEFAULT_MONITOR_STRING[] = {'G','e','n','e','r','i','c',' ','N','o','n','-','P','n','P',' ','M','o','n','i','t','o','r',0};
|
||||
static const WCHAR DEFAULT_ADAPTER_ID[] = {'P','C','I','\\',
|
||||
'V','E','N','_','0','0','0','0','&',
|
||||
'D','E','V','_','0','0','0','0','&',
|
||||
'S','U','B','S','Y','S','_','0','0','0','0','0','0','0','0','&',
|
||||
'R','E','V','_','0','0',0};
|
||||
static const WCHAR DEFAULT_MONITOR_ID[] = {'M','O','N','I','T','O','R','\\',
|
||||
'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r','\\',
|
||||
'{','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','0','0','0',0};
|
||||
static const WCHAR DEFAULT_MONITOR_INTERFACE_ID[] = {'\\','\\','\?','\\',
|
||||
'D','I','S','P','L','A','Y','#','D','e','f','a','u','l','t','_','M','o','n','i','t','o','r','#',
|
||||
'4','&','1','7','f','0','f','f','5','4','&','0','&','U','I','D','0','#',
|
||||
'{','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};
|
||||
static const WCHAR BACKSLASH[] = {'\\',0};
|
||||
static const WCHAR DRIVER_DESC[] = {'D','r','i','v','e','r','D','e','s','c',0};
|
||||
static const WCHAR STATE_FLAGS[] = {'S','t','a','t','e','F','l','a','g','s',0};
|
||||
static const WCHAR GPU_ID[] = {'G','P','U','I','D',0};
|
||||
static const WCHAR DISPLAY[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
|
||||
static const WCHAR MONITOR_ID_VALUE_FMT[] = {'M','o','n','i','t','o','r','I','D','%','d',0};
|
||||
static const WCHAR VIDEO_KEY[] = {'H','A','R','D','W','A','R','E','\\',
|
||||
'D','E','V','I','C','E','M','A','P','\\',
|
||||
'V','I','D','E','O','\\',0};
|
||||
static const WCHAR NT_CLASS[] = {'\\','R','e','g','i','s','t','r','y','\\',
|
||||
'M','a','c','h','i','n','e','\\',
|
||||
'S','y','s','t','e','m','\\',
|
||||
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
|
||||
'C','o','n','t','r','o','l','\\',
|
||||
'C','l','a','s','s','\\',0};
|
||||
static const WCHAR ADAPTER_FMT[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0};
|
||||
static const WCHAR MONITOR_FMT[] = {'\\','\\','.','\\',
|
||||
'D','I','S','P','L','A','Y','%','d','\\',
|
||||
'M','o','n','i','t','o','r','%','d',0};
|
||||
static const WCHAR VIDEO_VALUE_FMT[] = {'\\','D','e','v','i','c','e','\\',
|
||||
'V','i','d','e','o','%','d',0};
|
||||
static const WCHAR MONITOR_INTERFACE_PREFIX[] = {'\\','\\','\?','\\',0};
|
||||
static const WCHAR GUID_DEVINTERFACE_MONITOR[] = {'#','{','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};
|
||||
|
||||
static HDC display_dc;
|
||||
static CRITICAL_SECTION display_dc_section;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
|
@ -3772,6 +3826,250 @@ BOOL WINAPI EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPA
|
|||
return USER_Driver->pEnumDisplayMonitors( 0, NULL, enum_mon_callback, (LPARAM)&data );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EnumDisplayDevicesA (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI EnumDisplayDevicesA( LPCSTR device, DWORD index, DISPLAY_DEVICEA *info, DWORD flags )
|
||||
{
|
||||
UNICODE_STRING deviceW;
|
||||
DISPLAY_DEVICEW ddW;
|
||||
BOOL ret;
|
||||
|
||||
if (device)
|
||||
RtlCreateUnicodeStringFromAsciiz( &deviceW, device );
|
||||
else
|
||||
deviceW.Buffer = NULL;
|
||||
|
||||
ddW.cb = sizeof(ddW);
|
||||
ret = EnumDisplayDevicesW( deviceW.Buffer, index, &ddW, flags );
|
||||
RtlFreeUnicodeString( &deviceW );
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
WideCharToMultiByte( CP_ACP, 0, ddW.DeviceName, -1, info->DeviceName, sizeof(info->DeviceName), NULL, NULL );
|
||||
WideCharToMultiByte( CP_ACP, 0, ddW.DeviceString, -1, info->DeviceString, sizeof(info->DeviceString), NULL, NULL );
|
||||
info->StateFlags = ddW.StateFlags;
|
||||
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEA, DeviceID) + sizeof(info->DeviceID))
|
||||
WideCharToMultiByte( CP_ACP, 0, ddW.DeviceID, -1, info->DeviceID, sizeof(info->DeviceID), NULL, NULL );
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEA, DeviceKey) + sizeof(info->DeviceKey))
|
||||
WideCharToMultiByte( CP_ACP, 0, ddW.DeviceKey, -1, info->DeviceKey, sizeof(info->DeviceKey), NULL, NULL );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EnumDisplayDevicesW (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI EnumDisplayDevicesW( LPCWSTR device, DWORD index, DISPLAY_DEVICEW *info, DWORD flags )
|
||||
{
|
||||
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;
|
||||
|
||||
TRACE("%s %d %p %#x\n", debugstr_w( device ), index, info, flags);
|
||||
|
||||
/* Find adapter */
|
||||
if (!device)
|
||||
{
|
||||
sprintfW( key_nameW, VIDEO_VALUE_FMT, index );
|
||||
size = sizeof(bufferW);
|
||||
if (RegGetValueW( HKEY_LOCAL_MACHINE, VIDEO_KEY, key_nameW, RRF_RT_REG_SZ, NULL, bufferW, &size ))
|
||||
return FALSE;
|
||||
|
||||
/* DeviceKey */
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(info->DeviceKey))
|
||||
lstrcpyW( info->DeviceKey, bufferW );
|
||||
|
||||
/* DeviceName */
|
||||
sprintfW( info->DeviceName, ADAPTER_FMT, index + 1 );
|
||||
|
||||
/* Strip \Registry\Machine\ */
|
||||
lstrcpyW( key_nameW, bufferW + 18 );
|
||||
|
||||
/* DeviceString */
|
||||
size = sizeof(info->DeviceString);
|
||||
if (RegGetValueW( HKEY_LOCAL_MACHINE, key_nameW, DRIVER_DESC, RRF_RT_REG_SZ, NULL,
|
||||
info->DeviceString, &size ))
|
||||
return FALSE;
|
||||
|
||||
/* StateFlags */
|
||||
size = sizeof(info->StateFlags);
|
||||
if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, STATE_FLAGS, RRF_RT_REG_DWORD, NULL,
|
||||
&info->StateFlags, &size ))
|
||||
return FALSE;
|
||||
|
||||
/* DeviceID */
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(info->DeviceID))
|
||||
{
|
||||
if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
info->DeviceID[0] = 0;
|
||||
else
|
||||
{
|
||||
size = sizeof(bufferW);
|
||||
if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, GPU_ID, RRF_RT_REG_SZ | RRF_ZEROONFAILURE, NULL,
|
||||
bufferW, &size ))
|
||||
return FALSE;
|
||||
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->DeviceID, bufferW );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Find monitor */
|
||||
else
|
||||
{
|
||||
/* Check adapter name */
|
||||
if (strncmpiW( device, DISPLAY, ARRAY_SIZE(DISPLAY) ))
|
||||
return FALSE;
|
||||
|
||||
adapter_index = strtolW( device + ARRAY_SIZE(DISPLAY), NULL, 10 );
|
||||
sprintfW( key_nameW, VIDEO_VALUE_FMT, adapter_index - 1 );
|
||||
|
||||
size = sizeof(bufferW);
|
||||
if (RegGetValueW( HKEY_LOCAL_MACHINE, VIDEO_KEY, key_nameW, RRF_RT_REG_SZ, NULL, bufferW, &size ))
|
||||
return FALSE;
|
||||
|
||||
/* DeviceName */
|
||||
sprintfW( info->DeviceName, MONITOR_FMT, adapter_index, index );
|
||||
|
||||
/* Get monitor instance */
|
||||
/* Strip \Registry\Machine\ first */
|
||||
lstrcpyW( key_nameW, bufferW + 18 );
|
||||
sprintfW( bufferW, MONITOR_ID_VALUE_FMT, index );
|
||||
|
||||
size = sizeof(instanceW);
|
||||
if (RegGetValueW( HKEY_CURRENT_CONFIG, key_nameW, bufferW, RRF_RT_REG_SZ, NULL, instanceW, &size ))
|
||||
return FALSE;
|
||||
|
||||
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->StateFlags, sizeof(info->StateFlags), NULL, 0 ))
|
||||
goto done;
|
||||
|
||||
/* DeviceString */
|
||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_DEVICEDESC, NULL,
|
||||
(BYTE *)info->DeviceString,
|
||||
sizeof(info->DeviceString), NULL ))
|
||||
goto done;
|
||||
|
||||
/* DeviceKey */
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(info->DeviceKey))
|
||||
{
|
||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
|
||||
sizeof(bufferW), NULL ))
|
||||
goto done;
|
||||
|
||||
lstrcpyW( info->DeviceKey, NT_CLASS );
|
||||
lstrcatW( info->DeviceKey, bufferW );
|
||||
}
|
||||
|
||||
/* DeviceID */
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(info->DeviceID))
|
||||
{
|
||||
if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
{
|
||||
lstrcpyW( info->DeviceID, MONITOR_INTERFACE_PREFIX );
|
||||
lstrcatW( info->DeviceID, instanceW );
|
||||
lstrcatW( info->DeviceID, GUID_DEVINTERFACE_MONITOR );
|
||||
/* Replace '\\' with '#' after prefix */
|
||||
for (next_charW = info->DeviceID + strlenW( MONITOR_INTERFACE_PREFIX ); *next_charW;
|
||||
next_charW++)
|
||||
{
|
||||
if (*next_charW == '\\')
|
||||
*next_charW = '#';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_HARDWAREID, NULL, (BYTE *)bufferW,
|
||||
sizeof(bufferW), NULL ))
|
||||
goto done;
|
||||
|
||||
lstrcpyW( info->DeviceID, bufferW );
|
||||
lstrcatW( info->DeviceID, BACKSLASH );
|
||||
|
||||
if (!SetupDiGetDeviceRegistryPropertyW( set, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW,
|
||||
sizeof(bufferW), NULL ))
|
||||
goto done;
|
||||
|
||||
lstrcatW( info->DeviceID, 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, VIDEO_KEY, &hkey ))
|
||||
{
|
||||
RegCloseKey( hkey );
|
||||
return FALSE;
|
||||
}
|
||||
WARN("Reporting fallback display devices\n");
|
||||
|
||||
/* Adapter */
|
||||
if (!device)
|
||||
{
|
||||
memcpy( info->DeviceName, DEFAULT_ADAPTER_NAME, sizeof(DEFAULT_ADAPTER_NAME) );
|
||||
memcpy( info->DeviceString, DEFAULT_ADAPTER_STRING, sizeof(DEFAULT_ADAPTER_STRING) );
|
||||
info->StateFlags =
|
||||
DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_VGA_COMPATIBLE;
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(info->DeviceID))
|
||||
{
|
||||
if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
info->DeviceID[0] = 0;
|
||||
else
|
||||
memcpy( info->DeviceID, DEFAULT_ADAPTER_ID, sizeof(DEFAULT_ADAPTER_ID) );
|
||||
}
|
||||
}
|
||||
/* Monitor */
|
||||
else
|
||||
{
|
||||
if (lstrcmpiW( DEFAULT_ADAPTER_NAME, device ))
|
||||
return FALSE;
|
||||
|
||||
memcpy( info->DeviceName, DEFAULT_MONITOR_NAME, sizeof(DEFAULT_MONITOR_NAME) );
|
||||
memcpy( info->DeviceString, DEFAULT_MONITOR_STRING, sizeof(DEFAULT_MONITOR_STRING) );
|
||||
info->StateFlags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED;
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(info->DeviceID))
|
||||
{
|
||||
if (flags & EDD_GET_DEVICE_INTERFACE_NAME)
|
||||
memcpy( info->DeviceID, DEFAULT_MONITOR_INTERFACE_ID, sizeof(DEFAULT_MONITOR_INTERFACE_ID) );
|
||||
else
|
||||
memcpy( info->DeviceID, DEFAULT_MONITOR_ID, sizeof(DEFAULT_MONITOR_ID) );
|
||||
}
|
||||
}
|
||||
|
||||
if (info->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(info->DeviceKey))
|
||||
info->DeviceKey[0] = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* GetAutoRotationState [USER32.@]
|
||||
|
|
Loading…
Reference in a new issue