winemac.drv: Add GPU initialization functions.
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Ken Thomases <ken@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7f87c89227
commit
d8d1fe486b
|
@ -1,5 +1,5 @@
|
|||
MODULE = winemac.drv
|
||||
IMPORTS = uuid user32 gdi32 advapi32
|
||||
IMPORTS = uuid setupapi rpcrt4 user32 gdi32 advapi32
|
||||
DELAYIMPORTS = ole32 shell32 imm32
|
||||
EXTRALIBS = -framework AppKit -framework Carbon -framework Security -framework OpenGL -framework IOKit -framework CoreVideo $(METAL_LIBS)
|
||||
|
||||
|
|
|
@ -103,3 +103,261 @@ void macdrv_free_displays(struct macdrv_display* displays)
|
|||
{
|
||||
free(displays);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_entry_property_uint32
|
||||
*
|
||||
* Get an io registry entry property of type uint32 and store it in value parameter.
|
||||
*
|
||||
* Returns non-zero value on failure.
|
||||
*/
|
||||
static int get_entry_property_uint32(io_registry_entry_t entry, CFStringRef property_name, uint32_t* value)
|
||||
{
|
||||
CFDataRef data = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, property_name, kCFAllocatorDefault, 0);
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
if (CFGetTypeID(data) != CFDataGetTypeID() || CFDataGetLength(data) != sizeof(uint32_t))
|
||||
{
|
||||
CFRelease(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CFDataGetBytes(data, CFRangeMake(0, sizeof(uint32_t)), (UInt8*)value);
|
||||
CFRelease(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_entry_property_string
|
||||
*
|
||||
* Get an io registry entry property of type string and write it in buffer parameter.
|
||||
*
|
||||
* Returns non-zero value on failure.
|
||||
*/
|
||||
static int get_entry_property_string(io_registry_entry_t entry, CFStringRef property_name, char* buffer,
|
||||
size_t buffer_size)
|
||||
{
|
||||
CFTypeRef type_ref;
|
||||
CFDataRef data_ref;
|
||||
CFStringRef string_ref;
|
||||
size_t length;
|
||||
int ret = -1;
|
||||
|
||||
type_ref = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, property_name, kCFAllocatorDefault, 0);
|
||||
if (!type_ref)
|
||||
goto done;
|
||||
|
||||
if (CFGetTypeID(type_ref) == CFDataGetTypeID())
|
||||
{
|
||||
data_ref = type_ref;
|
||||
length = CFDataGetLength(data_ref);
|
||||
if (length + 1 > buffer_size)
|
||||
goto done;
|
||||
CFDataGetBytes(data_ref, CFRangeMake(0, length), (UInt8*)buffer);
|
||||
buffer[length] = 0;
|
||||
}
|
||||
else if (CFGetTypeID(type_ref) == CFStringGetTypeID())
|
||||
{
|
||||
string_ref = type_ref;
|
||||
if (!CFStringGetCString(string_ref, buffer, buffer_size, kCFStringEncodingUTF8))
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
goto done;
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
if (type_ref)
|
||||
CFRelease(type_ref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_get_gpu_info_from_entry
|
||||
*
|
||||
* Starting from entry, search upwards to find the PCI GPU. And get GPU information from the PCI GPU entry.
|
||||
*
|
||||
* Returns non-zero value on failure.
|
||||
*/
|
||||
static int macdrv_get_gpu_info_from_entry(struct macdrv_gpu* gpu, io_registry_entry_t entry)
|
||||
{
|
||||
io_registry_entry_t parent_entry;
|
||||
io_registry_entry_t gpu_entry;
|
||||
kern_return_t result;
|
||||
int ret = -1;
|
||||
char buffer[64];
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
gpu_entry = entry;
|
||||
while (![@"IOPCIDevice" isEqualToString:[(NSString*)IOObjectCopyClass(gpu_entry) autorelease]]
|
||||
|| get_entry_property_string(gpu_entry, CFSTR("IOName"), buffer, sizeof(buffer))
|
||||
|| strcmp(buffer, "display"))
|
||||
{
|
||||
result = IORegistryEntryGetParentEntry(gpu_entry, kIOServicePlane, &parent_entry);
|
||||
if (gpu_entry != entry)
|
||||
IOObjectRelease(gpu_entry);
|
||||
if (result != kIOReturnSuccess)
|
||||
{
|
||||
[pool release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpu_entry = parent_entry;
|
||||
}
|
||||
|
||||
if (IORegistryEntryGetRegistryEntryID(gpu_entry, &gpu->id) != kIOReturnSuccess)
|
||||
goto done;
|
||||
if (get_entry_property_uint32(gpu_entry, CFSTR("vendor-id"), &gpu->vendor_id))
|
||||
goto done;
|
||||
if (get_entry_property_uint32(gpu_entry, CFSTR("device-id"), &gpu->device_id))
|
||||
goto done;
|
||||
if (get_entry_property_uint32(gpu_entry, CFSTR("subsystem-id"), &gpu->subsys_id))
|
||||
goto done;
|
||||
if (get_entry_property_uint32(gpu_entry, CFSTR("revision-id"), &gpu->revision_id))
|
||||
goto done;
|
||||
if (get_entry_property_string(gpu_entry, CFSTR("model"), gpu->name, sizeof(gpu->name)))
|
||||
goto done;
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
if (gpu_entry != entry)
|
||||
IOObjectRelease(gpu_entry);
|
||||
[pool release];
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_get_gpu_info_from_display_id
|
||||
*
|
||||
* Get GPU information from a display id.
|
||||
* This is a fallback for 32bit build or older Mac OS version where Metal is unavailable.
|
||||
*
|
||||
* Returns non-zero value on failure.
|
||||
*/
|
||||
static int macdrv_get_gpu_info_from_display_id(struct macdrv_gpu* gpu, CGDirectDisplayID display_id)
|
||||
{
|
||||
io_registry_entry_t entry = CGDisplayIOServicePort(display_id);
|
||||
return macdrv_get_gpu_info_from_entry(gpu, entry);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_get_gpus_from_iokit
|
||||
*
|
||||
* Get a list of GPUs from IOKit.
|
||||
* This is a fallback for 32bit build or older Mac OS version where Metal is unavailable.
|
||||
*
|
||||
* Returns non-zero value on failure with parameters unchanged and zero on success.
|
||||
*/
|
||||
static int macdrv_get_gpus_from_iokit(struct macdrv_gpu** new_gpus, int* count)
|
||||
{
|
||||
static const int MAX_GPUS = 4;
|
||||
struct macdrv_gpu primary_gpu = {0};
|
||||
io_registry_entry_t entry;
|
||||
io_iterator_t iterator;
|
||||
struct macdrv_gpu* gpus;
|
||||
int integrated_index = -1;
|
||||
int primary_index = 0;
|
||||
int gpu_count = 0;
|
||||
int ret = -1;
|
||||
int i;
|
||||
|
||||
gpus = calloc(MAX_GPUS, sizeof(*gpus));
|
||||
if (!gpus)
|
||||
goto done;
|
||||
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOPCIDevice"), &iterator)
|
||||
!= kIOReturnSuccess)
|
||||
goto done;
|
||||
|
||||
while ((entry = IOIteratorNext(iterator)))
|
||||
{
|
||||
if (!macdrv_get_gpu_info_from_entry(&gpus[gpu_count], entry))
|
||||
{
|
||||
gpu_count++;
|
||||
assert(gpu_count < MAX_GPUS);
|
||||
}
|
||||
IOObjectRelease(entry);
|
||||
}
|
||||
IOObjectRelease(iterator);
|
||||
|
||||
macdrv_get_gpu_info_from_display_id(&primary_gpu, CGMainDisplayID());
|
||||
|
||||
/* If there are more than two GPUs and an Intel card exists,
|
||||
* assume an automatic graphics pair exists and hide the integrated GPU */
|
||||
if (gpu_count > 1)
|
||||
{
|
||||
for (i = 0; i < gpu_count; i++)
|
||||
{
|
||||
/* FIXME:
|
||||
* Find integrated GPU without Metal support.
|
||||
* Assuming integrated GPU vendor is Intel for now */
|
||||
if (gpus[i].vendor_id == 0x8086)
|
||||
{
|
||||
integrated_index = i;
|
||||
}
|
||||
|
||||
if (gpus[i].id == primary_gpu.id)
|
||||
{
|
||||
primary_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (integrated_index != -1)
|
||||
{
|
||||
if (integrated_index != gpu_count - 1)
|
||||
gpus[integrated_index] = gpus[gpu_count - 1];
|
||||
|
||||
/* FIXME:
|
||||
* Find the dedicated GPU in an automatic graphics switching pair and use that as primary GPU.
|
||||
* Choose the first dedicated GPU as primary */
|
||||
if (primary_index == integrated_index)
|
||||
primary_index = 0;
|
||||
else if (primary_index == gpu_count - 1)
|
||||
primary_index = integrated_index;
|
||||
|
||||
gpu_count--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the first GPU is primary */
|
||||
if (primary_index)
|
||||
{
|
||||
struct macdrv_gpu tmp;
|
||||
tmp = gpus[0];
|
||||
gpus[0] = gpus[primary_index];
|
||||
gpus[primary_index] = tmp;
|
||||
}
|
||||
|
||||
*new_gpus = gpus;
|
||||
*count = gpu_count;
|
||||
ret = 0;
|
||||
done:
|
||||
if (ret)
|
||||
macdrv_free_gpus(gpus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_get_gpus
|
||||
*
|
||||
* Get a list of GPUs currently in the system. The first GPU is primary.
|
||||
* Call macdrv_free_gpus() when you are done using the data.
|
||||
*
|
||||
* Returns non-zero value on failure with parameters unchanged and zero on success.
|
||||
*/
|
||||
int macdrv_get_gpus(struct macdrv_gpu** new_gpus, int* count)
|
||||
{
|
||||
return macdrv_get_gpus_from_iokit(new_gpus, count);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_free_gpus
|
||||
*
|
||||
* Frees a GPU list allocated from macdrv_get_gpus()
|
||||
*/
|
||||
void macdrv_free_gpus(struct macdrv_gpu* gpus)
|
||||
{
|
||||
if (gpus)
|
||||
free(gpus);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,13 @@
|
|||
#include "winuser.h"
|
||||
#include "winreg.h"
|
||||
#include "ddrawi.h"
|
||||
#include "rpc.h"
|
||||
#include "initguid.h"
|
||||
#include "devguid.h"
|
||||
#include "devpkey.h"
|
||||
#include "setupapi.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "winternl.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(display);
|
||||
|
@ -47,6 +54,30 @@ BOOL CDECL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW
|
|||
|
||||
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 pciW[] = {'P','C','I',0};
|
||||
static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',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 CFArrayRef modes;
|
||||
|
@ -1397,3 +1428,178 @@ void macdrv_displays_changed(const macdrv_event *event)
|
|||
MAKELPARAM(width, height));
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_init_gpu
|
||||
*
|
||||
* Initialize a GPU instance.
|
||||
*
|
||||
* Return FALSE on failure and TRUE on success.
|
||||
*/
|
||||
static BOOL macdrv_init_gpu(HDEVINFO devinfo, const struct macdrv_gpu *gpu, int gpu_index)
|
||||
{
|
||||
static const BOOL present = TRUE;
|
||||
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
|
||||
WCHAR instanceW[MAX_PATH];
|
||||
WCHAR nameW[MAX_PATH];
|
||||
WCHAR bufferW[1024];
|
||||
FILETIME filetime;
|
||||
HKEY hkey = NULL;
|
||||
GUID guid;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Write DriverDesc value */
|
||||
if (RegSetValueExW(hkey, driver_descW, 0, REG_SZ, (const BYTE *)nameW, (lstrlenW(nameW) + 1) * sizeof(WCHAR)))
|
||||
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;
|
||||
RegCloseKey(hkey);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
done:
|
||||
RegCloseKey(hkey);
|
||||
if (!ret)
|
||||
ERR("Failed to initialize GPU\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void prepare_devices(void)
|
||||
{
|
||||
static const BOOL not_present = FALSE;
|
||||
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
|
||||
HDEVINFO devinfo;
|
||||
DWORD i = 0;
|
||||
|
||||
/* 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. */
|
||||
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_init_display_devices
|
||||
*
|
||||
* Initialize display device registry data.
|
||||
*/
|
||||
void macdrv_init_display_devices(void)
|
||||
{
|
||||
static const WCHAR init_mutexW[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t',0};
|
||||
HANDLE mutex;
|
||||
struct macdrv_gpu *gpus = NULL;
|
||||
INT gpu_count;
|
||||
INT gpu;
|
||||
HDEVINFO gpu_devinfo = NULL;
|
||||
HKEY video_hkey = NULL;
|
||||
DWORD disposition = 0;
|
||||
|
||||
mutex = CreateMutexW(NULL, FALSE, init_mutexW);
|
||||
WaitForSingleObject(mutex, INFINITE);
|
||||
|
||||
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 (disposition != REG_CREATED_NEW_KEY)
|
||||
goto done;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
prepare_devices();
|
||||
|
||||
gpu_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
|
||||
|
||||
/* Initialize GPUs */
|
||||
if (macdrv_get_gpus(&gpus, &gpu_count))
|
||||
goto done;
|
||||
|
||||
for (gpu = 0; gpu < gpu_count; gpu++)
|
||||
{
|
||||
if (!macdrv_init_gpu(gpu_devinfo, &gpus[gpu], gpu))
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
cleanup_devices();
|
||||
SetupDiDestroyDeviceInfoList(gpu_devinfo);
|
||||
RegCloseKey(video_hkey);
|
||||
|
||||
ReleaseMutex(mutex);
|
||||
CloseHandle(mutex);
|
||||
|
||||
macdrv_free_gpus(gpus);
|
||||
}
|
||||
|
|
|
@ -223,6 +223,7 @@ extern CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP
|
|||
extern void macdrv_status_item_mouse_move(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void check_retina_status(void) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_init_display_devices(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/**************************************************************************
|
||||
* Mac IME driver
|
||||
|
|
|
@ -257,10 +257,27 @@ static inline CGPoint cgpoint_win_from_mac(CGPoint point)
|
|||
|
||||
|
||||
/* display */
|
||||
|
||||
/* Represent a physical GPU in the PCI slots */
|
||||
struct macdrv_gpu
|
||||
{
|
||||
/* PCI GPU io registry entry id */
|
||||
uint64_t id;
|
||||
/* Name, in UTF-8 encoding */
|
||||
char name[128];
|
||||
/* PCI ID */
|
||||
uint32_t vendor_id;
|
||||
uint32_t device_id;
|
||||
uint32_t subsys_id;
|
||||
uint32_t revision_id;
|
||||
};
|
||||
|
||||
extern int macdrv_get_displays(struct macdrv_display** displays, int* count) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDEN;
|
||||
extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
||||
CGDisplayModeRef display_mode) DECLSPEC_HIDDEN;
|
||||
extern int macdrv_get_gpus(struct macdrv_gpu** gpus, int* count) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_free_gpus(struct macdrv_gpu* gpus) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/* event */
|
||||
|
|
Loading…
Reference in New Issue