diff --git a/dlls/winemac.drv/Makefile.in b/dlls/winemac.drv/Makefile.in index 96f14edb55c..6329e8e76c8 100644 --- a/dlls/winemac.drv/Makefile.in +++ b/dlls/winemac.drv/Makefile.in @@ -1,5 +1,5 @@ MODULE = winemac.drv -IMPORTS = uuid setupapi rpcrt4 user32 gdi32 advapi32 +IMPORTS = uuid rpcrt4 user32 gdi32 advapi32 win32u DELAYIMPORTS = ole32 shell32 imm32 EXTRALIBS = -framework AppKit -framework Carbon -framework Security -framework OpenGL -framework IOKit -framework CoreVideo $(METAL_LIBS) diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index ffafb0bd1d2..2ac8f32fa18 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -25,13 +25,6 @@ #include "winuser.h" #include "winreg.h" #include "ddrawi.h" -#include "rpc.h" -#include "cfgmgr32.h" -#include "initguid.h" -#include "devguid.h" -#include "devpkey.h" -#include "ntddvdeo.h" -#include "setupapi.h" #define WIN32_NO_STATUS #include "winternl.h" #include "wine/unicode.h" @@ -53,76 +46,16 @@ struct display_mode_descriptor BOOL CDECL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmode, DWORD flags); -DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2); -DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_GPU_LUID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 1); -DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 2); - -/* Wine specific monitor properties */ -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5); - static const char initial_mode_key[] = "Initial Display Mode"; static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0}; -static const WCHAR driver_date_dataW[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0}; -static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0}; -static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0}; -static const WCHAR pciW[] = {'P','C','I',0}; -static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0}; -static const WCHAR symbolic_link_valueW[]= {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0}; -static const WCHAR gpu_idW[] = {'G','P','U','I','D',0}; -static const WCHAR monitor_id_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0}; static const WCHAR adapter_prefixW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'}; -static const WCHAR adapter_name_fmtW[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','%','d',0}; -static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0}; -static const WCHAR guid_fmtW[] = { - '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%','0','2','x','%','0','2','x','-', - '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0}; -static const WCHAR gpu_instance_fmtW[] = { - 'P','C','I','\\', - 'V','E','N','_','%','0','4','X','&', - 'D','E','V','_','%','0','4','X','&', - 'S','U','B','S','Y','S','_','%','0','8','X','&', - 'R','E','V','_','%','0','2','X','\\', - '%','0','8','X',0}; -static const WCHAR gpu_hardware_id_fmtW[] = { - 'P','C','I','\\', - 'V','E','N','_','%','0','4','X','&', - 'D','E','V','_','%','0','4','X','&', - 'S','U','B','S','Y','S','_','0','0','0','0','0','0','0','0','&', - 'R','E','V','_','0','0',0}; 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 adapter_key_fmtW[] = { - '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','\\', - 'V','i','d','e','o','\\', - '%','s','\\', - '%','0','4','x',0}; static const WCHAR device_video_fmtW[] = { '\\','D','e','v','i','c','e','\\', 'V','i','d','e','o','%','d',0}; -static const WCHAR machine_prefixW[] = { - '\\','R','e','g','i','s','t','r','y','\\', - 'M','a','c','h','i','n','e','\\',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 monitor_instance_fmtW[] = { - 'D','I','S','P','L','A','Y','\\', - 'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r','\\', - '%','0','4','X','&','%','0','4','X',0}; -static const WCHAR monitor_hardware_idW[] = { - 'M','O','N','I','T','O','R','\\', - 'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r',0,0}; static CFArrayRef modes; @@ -1441,403 +1374,79 @@ void macdrv_displays_changed(const macdrv_event *event) } } -/*********************************************************************** - * link_device - * - * Set device interface link state to enabled. The link state should be set via - * IoSetDeviceInterfaceState(). However, IoSetDeviceInterfaceState() requires a PnP driver, which - * currently doesn't exist for display devices. - * - * Return FALSE on failure and TRUE on success. - */ -static BOOL link_device(const WCHAR *instance, const GUID *guid) +static BOOL force_display_devices_refresh; + +void CDECL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, + BOOL force, void *param ) { - static const WCHAR device_instanceW[] = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0}; - static const WCHAR hash_controlW[] = {'#','\\','C','o','n','t','r','o','l',0}; - static const WCHAR linkedW[] = {'L','i','n','k','e','d',0}; - static const DWORD enabled = 1; - WCHAR device_key_name[MAX_PATH], device_instance[MAX_PATH]; - HKEY iface_key, device_key, control_key; - DWORD length, index = 0; - BOOL ret = FALSE; - LSTATUS lr; + struct macdrv_adapter *adapters, *adapter; + struct macdrv_monitor *monitors, *monitor; + struct macdrv_gpu *gpus, *gpu; + INT gpu_count, adapter_count, monitor_count; + DWORD len; - iface_key = SetupDiOpenClassRegKeyExW(guid, KEY_ALL_ACCESS, DIOCR_INTERFACE, NULL, NULL); - while (1) + if (!force && !force_display_devices_refresh) return; + force_display_devices_refresh = FALSE; + + /* Initialize GPUs */ + if (macdrv_get_gpus(&gpus, &gpu_count)) { - length = ARRAY_SIZE(device_key_name); - lr = RegEnumKeyExW(iface_key, index++, device_key_name, &length, NULL, NULL, NULL, NULL); - if (lr) - break; + ERR("could not get GPUs\n"); + return; + } + TRACE("GPU count: %d\n", gpu_count); - lr = RegOpenKeyExW(iface_key, device_key_name, 0, KEY_ALL_ACCESS, &device_key); - if (lr) - continue; - - length = sizeof(device_instance); - lr = RegQueryValueExW(device_key, device_instanceW, NULL, NULL, (BYTE *)device_instance, &length); - if (lr || lstrcmpiW(device_instance, instance)) + for (gpu = gpus; gpu < gpus + gpu_count; gpu++) + { + struct gdi_gpu gdi_gpu = { - RegCloseKey(device_key); - continue; + .id = gpu->id, + .vendor_id = gpu->vendor_id, + .device_id = gpu->device_id, + .subsys_id = gpu->subsys_id, + .revision_id = gpu->revision_id, + }; + RtlUTF8ToUnicodeN(gdi_gpu.name, sizeof(gdi_gpu.name), &len, gpu->name, strlen(gpu->name)); + device_manager->add_gpu(&gdi_gpu, param); + + /* Initialize adapters */ + if (macdrv_get_adapters(gpu->id, &adapters, &adapter_count)) break; + TRACE("GPU: %llx %s, adapter count: %d\n", gpu->id, debugstr_a(gpu->name), adapter_count); + + for (adapter = adapters; adapter < adapters + adapter_count; adapter++) + { + struct gdi_adapter gdi_adapter = + { + .id = adapter->id, + .state_flags = adapter->state_flags, + }; + device_manager->add_adapter( &gdi_adapter, param ); + + if (macdrv_get_monitors(adapter->id, &monitors, &monitor_count)) break; + TRACE("adapter: %#x, monitor count: %d\n", adapter->id, monitor_count); + + /* Initialize monitors */ + for (monitor = monitors; monitor < monitors + monitor_count; monitor++) + { + struct gdi_monitor gdi_monitor = + { + .rc_monitor = rect_from_cgrect(monitor->rc_monitor), + .rc_work = rect_from_cgrect(monitor->rc_work), + .state_flags = monitor->state_flags, + }; + RtlUTF8ToUnicodeN(gdi_monitor.name, sizeof(gdi_monitor.name), &len, + monitor->name, strlen(monitor->name)); + TRACE("monitor: %s\n", debugstr_a(monitor->name)); + device_manager->add_monitor( &gdi_monitor, param ); + } + + macdrv_free_monitors(monitors); } - lr = RegCreateKeyExW(device_key, hash_controlW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &control_key, NULL); - RegCloseKey(device_key); - if (lr) - break; - - lr = RegSetValueExW(control_key, linkedW, 0, REG_DWORD, (const BYTE *)&enabled, sizeof(enabled)); - if (!lr) - ret = TRUE; - - RegCloseKey(control_key); - break; - } - RegCloseKey(iface_key); - return ret; -} - -/*********************************************************************** - * macdrv_init_gpu - * - * Initialize a GPU instance. - * Return its GUID string in guid_string, driver value in driver parameter and LUID in gpu_luid. - * - * Return FALSE on failure and TRUE on success. - */ -static BOOL macdrv_init_gpu(HDEVINFO devinfo, const struct macdrv_gpu *gpu, int gpu_index, WCHAR *guid_string, - WCHAR *driver, LUID *gpu_luid) -{ - static const WCHAR adapter_stringW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','A','d','a','p','t','e','r','S','t','r','i','n','g',0}; - static const WCHAR bios_stringW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','B','i','o','s','S','t','r','i','n','g',0}; - static const WCHAR chip_typeW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','C','h','i','p','T','y','p','e',0}; - static const WCHAR dac_typeW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','D','a','c','T','y','p','e',0}; - static const WCHAR ramdacW[] = {'I','n','t','e','r','g','r','a','t','e','d',' ','R','A','M','D','A','C',0}; - static const BOOL present = TRUE; - SP_DEVINFO_DATA device_data = {sizeof(device_data)}; - WCHAR instanceW[MAX_PATH]; - DEVPROPTYPE property_type; - WCHAR nameW[MAX_PATH]; - WCHAR bufferW[1024]; - FILETIME filetime; - HKEY hkey = NULL; - GUID guid; - LUID luid; - INT written; - DWORD size; - BOOL ret = FALSE; - - sprintfW(instanceW, gpu_instance_fmtW, gpu->vendor_id, gpu->device_id, gpu->subsys_id, gpu->revision_id, gpu_index); - MultiByteToWideChar(CP_UTF8, 0, gpu->name, -1, nameW, ARRAY_SIZE(nameW)); - if (!SetupDiOpenDeviceInfoW(devinfo, instanceW, NULL, 0, &device_data)) - { - SetupDiCreateDeviceInfoW(devinfo, instanceW, &GUID_DEVCLASS_DISPLAY, nameW, NULL, 0, &device_data); - if (!SetupDiRegisterDeviceInfo(devinfo, &device_data, 0, NULL, NULL, NULL)) - goto done; + macdrv_free_adapters(adapters); } - /* Register GUID_DEVINTERFACE_DISPLAY_ADAPTER */ - if (!SetupDiCreateDeviceInterfaceW(devinfo, &device_data, &GUID_DEVINTERFACE_DISPLAY_ADAPTER, NULL, 0, NULL)) - goto done; - - if (!link_device(instanceW, &GUID_DEVINTERFACE_DISPLAY_ADAPTER)) - goto done; - - /* Register GUID_DISPLAY_DEVICE_ARRIVAL */ - if (!SetupDiCreateDeviceInterfaceW(devinfo, &device_data, &GUID_DISPLAY_DEVICE_ARRIVAL, NULL, 0, NULL)) - goto done; - - if (!link_device(instanceW, &GUID_DISPLAY_DEVICE_ARRIVAL)) - goto done; - - /* Write HardwareID registry property, REG_MULTI_SZ */ - written = sprintfW(bufferW, gpu_hardware_id_fmtW, gpu->vendor_id, gpu->device_id); - bufferW[written + 1] = 0; - if (!SetupDiSetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_HARDWAREID, (const BYTE *)bufferW, - (written + 2) * sizeof(WCHAR))) - goto done; - - /* Write DEVPKEY_Device_IsPresent property */ - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, DEVPROP_TYPE_BOOLEAN, - (const BYTE *)&present, sizeof(present), 0)) - goto done; - - /* Write DEVPROPKEY_GPU_LUID property */ - if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_GPU_LUID, &property_type, - (BYTE *)&luid, sizeof(luid), NULL, 0)) - { - if (!AllocateLocallyUniqueId(&luid)) - goto done; - - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_GPU_LUID, - DEVPROP_TYPE_UINT64, (const BYTE *)&luid, sizeof(luid), 0)) - goto done; - } - *gpu_luid = luid; - TRACE("GPU id:0x%s name:%s LUID:%08x:%08x.\n", wine_dbgstr_longlong(gpu->id), gpu->name, - luid.HighPart, luid.LowPart); - - /* Open driver key. - * This is where HKLM\System\CurrentControlSet\Control\Video\{GPU GUID}\{Adapter Index} links to */ - hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); - - size = (lstrlenW(nameW) + 1) * sizeof(WCHAR); - /* Write DriverDesc value */ - if (RegSetValueExW(hkey, driver_descW, 0, REG_SZ, (const BYTE *)nameW, size)) - goto done; - /* Write DriverDateData value, using current time as driver date, needed by Evoland */ - GetSystemTimeAsFileTime(&filetime); - if (RegSetValueExW(hkey, driver_date_dataW, 0, REG_BINARY, (BYTE *)&filetime, sizeof(filetime))) - goto done; - /* The following hardware information value type may be REG_BINARY or REG_SZ */ - if (RegSetValueExW(hkey, adapter_stringW, 0, REG_BINARY, (const BYTE *)nameW, size)) - goto done; - if (RegSetValueExW(hkey, bios_stringW, 0, REG_BINARY, (const BYTE *)nameW, size)) - goto done; - if (RegSetValueExW(hkey, chip_typeW, 0, REG_BINARY, (const BYTE *)nameW, size)) - goto done; - if (RegSetValueExW(hkey, dac_typeW, 0, REG_BINARY, (const BYTE *)ramdacW, sizeof(ramdacW))) - goto done; - RegCloseKey(hkey); - hkey = NULL; - - /* Retrieve driver value for adapters */ - if (!SetupDiGetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW, sizeof(bufferW), - NULL)) - goto done; - lstrcpyW(driver, nt_classW); - lstrcatW(driver, bufferW); - - /* Write GUID in VideoID in .../instance/Device Parameters, reuse the GUID if it's existent */ - hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL); - - size = sizeof(bufferW); - if (RegQueryValueExW(hkey, video_idW, 0, NULL, (BYTE *)bufferW, &size)) - { - UuidCreate(&guid); - sprintfW(bufferW, guid_fmtW, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], - guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); - if (RegSetValueExW(hkey, video_idW, 0, REG_SZ, (const BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR))) - goto done; - } - lstrcpyW(guid_string, bufferW); - - ret = TRUE; -done: - RegCloseKey(hkey); - if (!ret) - ERR("Failed to initialize GPU\n"); - return ret; -} - -/*********************************************************************** - * macdrv_init_adapter - * - * Initialize an adapter. - * - * Return FALSE on failure and TRUE on success. - */ -static BOOL macdrv_init_adapter(HKEY video_hkey, int video_index, int gpu_index, int adapter_index, int monitor_count, - const struct macdrv_gpu *gpu, const WCHAR *guid_string, const WCHAR *gpu_driver, - const struct macdrv_adapter *adapter) -{ - WCHAR adapter_keyW[MAX_PATH]; - WCHAR key_nameW[MAX_PATH]; - WCHAR bufferW[1024]; - HKEY hkey = NULL; - BOOL ret = FALSE; - LSTATUS ls; - INT i; - - sprintfW(key_nameW, device_video_fmtW, video_index); - lstrcpyW(bufferW, machine_prefixW); - sprintfW(adapter_keyW, adapter_key_fmtW, guid_string, adapter_index); - lstrcatW(bufferW, adapter_keyW); - - /* Write value of \Device\Video? (adapter key) in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */ - if (RegSetValueExW(video_hkey, key_nameW, 0, REG_SZ, (const BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR))) - goto done; - - /* Create HKLM\System\CurrentControlSet\Control\Video\{GPU GUID}\{Adapter Index} link to GPU driver */ - ls = RegCreateKeyExW(HKEY_LOCAL_MACHINE, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, - KEY_ALL_ACCESS, NULL, &hkey, NULL); - if (ls == ERROR_ALREADY_EXISTS) - RegCreateKeyExW(HKEY_LOCAL_MACHINE, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_OPEN_LINK, - KEY_ALL_ACCESS, NULL, &hkey, NULL); - if (RegSetValueExW(hkey, symbolic_link_valueW, 0, REG_LINK, (const BYTE *)gpu_driver, - lstrlenW(gpu_driver) * sizeof(WCHAR))) - goto done; - RegCloseKey(hkey); - hkey = NULL; - - /* FIXME: - * Following information is Wine specific, it doesn't really exist on Windows. It is used so that we can - * implement EnumDisplayDevices etc by querying registry only. This information is most likely reported by the - * device driver on Windows */ - RegCreateKeyExW(HKEY_CURRENT_CONFIG, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL); - - /* Write GPU instance path so that we can find the GPU instance via adapters quickly. Another way is trying to match - * them via the GUID in Device Parameters/VideoID, but it would require enumerating all GPU instances */ - sprintfW(bufferW, gpu_instance_fmtW, gpu->vendor_id, gpu->device_id, gpu->subsys_id, gpu->revision_id, gpu_index); - if (RegSetValueExW(hkey, gpu_idW, 0, REG_SZ, (const BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR))) - goto done; - - /* Write all monitor instance paths under this adapter */ - for (i = 0; i < monitor_count; i++) - { - sprintfW(key_nameW, monitor_id_fmtW, i); - sprintfW(bufferW, monitor_instance_fmtW, video_index, i); - if (RegSetValueExW(hkey, key_nameW, 0, REG_SZ, (const BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR))) - goto done; - } - - /* Write StateFlags */ - if (RegSetValueExW(hkey, state_flagsW, 0, REG_DWORD, (const BYTE *)&adapter->state_flags, - sizeof(adapter->state_flags))) - goto done; - - ret = TRUE; -done: - RegCloseKey(hkey); - if (!ret) - ERR("Failed to initialize adapter\n"); - return ret; -} - -/*********************************************************************** - * macdrv_init_monitor - * - * Initialize an monitor. - * - * Return FALSE on failure and TRUE on success. - */ -static BOOL macdrv_init_monitor(HDEVINFO devinfo, const struct macdrv_monitor *monitor, int monitor_index, - int video_index, const LUID *gpu_luid, UINT output_id) -{ - SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)}; - WCHAR nameW[MAX_PATH]; - WCHAR bufferW[MAX_PATH]; - DWORD length; - HKEY hkey; - RECT rect; - BOOL ret = FALSE; - - /* Create GUID_DEVCLASS_MONITOR instance */ - sprintfW(bufferW, monitor_instance_fmtW, video_index, monitor_index); - MultiByteToWideChar(CP_UTF8, 0, monitor->name, -1, nameW, ARRAY_SIZE(nameW)); - SetupDiCreateDeviceInfoW(devinfo, bufferW, &GUID_DEVCLASS_MONITOR, nameW, NULL, 0, &device_data); - if (!SetupDiRegisterDeviceInfo(devinfo, &device_data, 0, NULL, NULL, NULL)) - goto done; - - /* Register GUID_DEVINTERFACE_MONITOR */ - if (!SetupDiCreateDeviceInterfaceW(devinfo, &device_data, &GUID_DEVINTERFACE_MONITOR, NULL, 0, NULL)) - goto done; - - if (!link_device(bufferW, &GUID_DEVINTERFACE_MONITOR)) - goto done; - - /* Write HardwareID registry property */ - if (!SetupDiSetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_HARDWAREID, - (const BYTE *)monitor_hardware_idW, sizeof(monitor_hardware_idW))) - goto done; - - /* Write DEVPROPKEY_MONITOR_GPU_LUID */ - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_MONITOR_GPU_LUID, - DEVPROP_TYPE_INT64, (const BYTE *)gpu_luid, sizeof(*gpu_luid), 0)) - goto done; - - /* Write DEVPROPKEY_MONITOR_OUTPUT_ID */ - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_MONITOR_OUTPUT_ID, - DEVPROP_TYPE_UINT32, (const BYTE *)&output_id, sizeof(output_id), 0)) - goto done; - - /* Create driver key */ - hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); - RegCloseKey(hkey); - - /* FIXME: - * Following properties are Wine specific, see comments in macdrv_init_adapter for details */ - /* StateFlags */ - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32, - (const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0)) - goto done; - /* RcMonitor */ - rect = rect_from_cgrect(monitor->rc_monitor); - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY, - (const BYTE *)&rect, sizeof(rect), 0)) - goto done; - /* RcWork */ - rect = rect_from_cgrect(monitor->rc_work); - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY, - (const BYTE *)&rect, sizeof(rect), 0)) - goto done; - /* Adapter name */ - length = sprintfW(bufferW, adapter_name_fmtW, video_index + 1); - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING, - (const BYTE *)bufferW, (length + 1) * sizeof(WCHAR), 0)) - goto done; - - ret = TRUE; -done: - if (!ret) - ERR("Failed to initialize monitor\n"); - return ret; -} - -static void prepare_devices(HKEY video_hkey) -{ - static const BOOL not_present = FALSE; - SP_DEVINFO_DATA device_data = {sizeof(device_data)}; - HDEVINFO devinfo; - DWORD i = 0; - - /* Remove all monitors */ - devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, displayW, NULL, 0); - while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data)) - { - if (!SetupDiRemoveDevice(devinfo, &device_data)) - ERR("Failed to remove monitor\n"); - } - SetupDiDestroyDeviceInfoList(devinfo); - - /* Clean up old adapter keys for reinitialization */ - RegDeleteTreeW(video_hkey, NULL); - - /* FIXME: - * Currently SetupDiGetClassDevsW with DIGCF_PRESENT is unsupported, So we need to clean up not present devices in - * case application uses SetupDiGetClassDevsW to enumerate devices. Wrong devices could exist in registry as a result - * of prefix copying or having devices unplugged. But then we couldn't simply delete GPUs because we need to retain - * the same GUID for the same GPU. */ - i = 0; - devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, pciW, NULL, 0); - while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data)) - { - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, DEVPROP_TYPE_BOOLEAN, - (const BYTE *)¬_present, sizeof(not_present), 0)) - ERR("Failed to set GPU present property\n"); - } - SetupDiDestroyDeviceInfoList(devinfo); -} - -static void cleanup_devices(void) -{ - SP_DEVINFO_DATA device_data = {sizeof(device_data)}; - HDEVINFO devinfo; - DWORD type; - DWORD i = 0; - BOOL present; - - devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, pciW, NULL, 0); - while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data)) - { - present = FALSE; - SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, &type, (BYTE *)&present, - sizeof(present), NULL, 0); - if (!present && !SetupDiRemoveDevice(devinfo, &device_data)) - ERR("Failed to remove GPU\n"); - } - SetupDiDestroyDeviceInfoList(devinfo); + macdrv_free_gpus(gpus); } /*********************************************************************** @@ -1847,94 +1456,9 @@ static void cleanup_devices(void) */ void macdrv_init_display_devices(BOOL force) { - HANDLE mutex; - struct macdrv_gpu *gpus = NULL; - struct macdrv_adapter *adapters = NULL; - struct macdrv_monitor *monitors = NULL; - INT gpu_count, adapter_count, monitor_count; - INT gpu, adapter, monitor; - HDEVINFO gpu_devinfo = NULL, monitor_devinfo = NULL; - HKEY video_hkey = NULL; - INT video_index = 0; - DWORD disposition = 0; - WCHAR guidW[40]; - WCHAR driverW[1024]; - LUID gpu_luid; - UINT output_id = 0; + UINT32 num_path, num_mode; - mutex = get_display_device_init_mutex(); - - if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, video_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &video_hkey, - &disposition)) - { - ERR("Failed to create video device key\n"); - goto done; - } - - /* Avoid unnecessary reinit */ - if (!force && disposition != REG_CREATED_NEW_KEY) - goto done; - - TRACE("\n"); - - prepare_devices(video_hkey); - - gpu_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL); - monitor_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_MONITOR, NULL); - - /* Initialize GPUs */ - if (macdrv_get_gpus(&gpus, &gpu_count)) - goto done; - TRACE("GPU count: %d\n", gpu_count); - if (!gpu_count) - ERR("No GPUs detected\n"); - - for (gpu = 0; gpu < gpu_count; gpu++) - { - if (!macdrv_init_gpu(gpu_devinfo, &gpus[gpu], gpu, guidW, driverW, &gpu_luid)) - goto done; - - /* Initialize adapters */ - if (macdrv_get_adapters(gpus[gpu].id, &adapters, &adapter_count)) - goto done; - TRACE("GPU: %#llx %s, adapter count: %d\n", gpus[gpu].id, gpus[gpu].name, adapter_count); - - for (adapter = 0; adapter < adapter_count; adapter++) - { - if (macdrv_get_monitors(adapters[adapter].id, &monitors, &monitor_count)) - goto done; - TRACE("adapter: %#x, monitor count: %d\n", adapters[adapter].id, monitor_count); - - if (!macdrv_init_adapter(video_hkey, video_index, gpu, adapter, monitor_count, &gpus[gpu], guidW, driverW, - &adapters[adapter])) - goto done; - - /* Initialize monitors */ - for (monitor = 0; monitor < monitor_count; monitor++) - { - TRACE("monitor: %#x %s\n", monitor, monitors[monitor].name); - if (!macdrv_init_monitor(monitor_devinfo, &monitors[monitor], monitor, video_index, &gpu_luid, output_id++)) - goto done; - } - - macdrv_free_monitors(monitors); - monitors = NULL; - video_index++; - } - - macdrv_free_adapters(adapters); - adapters = NULL; - } - -done: - cleanup_devices(); - SetupDiDestroyDeviceInfoList(monitor_devinfo); - SetupDiDestroyDeviceInfoList(gpu_devinfo); - RegCloseKey(video_hkey); - - release_display_device_init_mutex(mutex); - - macdrv_free_gpus(gpus); - macdrv_free_adapters(adapters); - macdrv_free_monitors(monitors); + if (force) force_display_devices_refresh = TRUE; + /* trigger refresh in win32u */ + NtUserGetDisplayConfigBufferSizes( QDC_ONLY_ACTIVE_PATHS, &num_path, &num_mode ); } diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 78ed899f04c..46a1a74a51d 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -281,6 +281,7 @@ static const struct user_driver_funcs macdrv_funcs = .pDestroyCursorIcon = macdrv_DestroyCursorIcon, .pDestroyWindow = macdrv_DestroyWindow, .pEnumDisplaySettingsEx = macdrv_EnumDisplaySettingsEx, + .pUpdateDisplayDevices = macdrv_UpdateDisplayDevices, .pGetCursorPos = macdrv_GetCursorPos, .pGetKeyboardLayoutList = macdrv_GetKeyboardLayoutList, .pGetKeyNameText = macdrv_GetKeyNameText, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index d73a52fa35f..1df51ef847c 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -130,6 +130,8 @@ extern LONG CDECL macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW dev HWND hwnd, DWORD flags, LPVOID lpvoid) DECLSPEC_HIDDEN; extern BOOL CDECL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmode, DWORD flags) DECLSPEC_HIDDEN; +extern void CDECL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, + BOOL force, void *param ) DECLSPEC_HIDDEN; extern BOOL CDECL macdrv_GetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp) DECLSPEC_HIDDEN; extern BOOL CDECL macdrv_SetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp) DECLSPEC_HIDDEN; extern BOOL CDECL macdrv_ClipCursor(LPCRECT clip) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index d8d16b1f4df..63c6a8199e0 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -299,8 +299,8 @@ static BOOL process_attach(void) return FALSE; } - macdrv_init_display_devices(FALSE); init_user_driver(); + macdrv_init_display_devices(FALSE); return TRUE; }