mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 22:14:34 +00:00
Enabled enumeration of mirroring displays.
This exposes all monitors in every mirroring group, which is needed for robust detection of an Oculus Rift.
This commit is contained in:
parent
8fd69bc6c2
commit
1b6d8a6ed6
@ -108,8 +108,8 @@ extern "C" {
|
|||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||||
/*! @brief Returns the device name of the specified monitor.
|
/*! @brief Returns the display device name of the specified monitor.
|
||||||
* @return The the device name of the specified monitor.
|
* @return The the display device name of the specified monitor.
|
||||||
* @ingroup native
|
* @ingroup native
|
||||||
*/
|
*/
|
||||||
GLFWAPI const WCHAR* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
GLFWAPI const WCHAR* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||||
|
@ -252,18 +252,26 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
CGGetActiveDisplayList(0, NULL, &displayCount);
|
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||||
|
|
||||||
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||||
monitors = calloc(displayCount, sizeof(_GLFWmonitor*));
|
monitors = calloc(displayCount, sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
CGGetActiveDisplayList(displayCount, displays, &displayCount);
|
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||||
|
|
||||||
NSArray* screens = [NSScreen screens];
|
NSArray* screens = [NSScreen screens];
|
||||||
|
|
||||||
for (i = 0; i < displayCount; i++)
|
for (i = 0; i < displayCount; i++)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
if (CGDisplayIsAsleep(displays[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CGDirectDisplayID screenDisplayID = CGDisplayMirrorsDisplay(displays[i]);
|
||||||
|
if (screenDisplayID == kCGNullDirectDisplay)
|
||||||
|
screenDisplayID = displays[i];
|
||||||
|
|
||||||
const CGSize size = CGDisplayScreenSize(displays[i]);
|
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||||
char* name = getDisplayName(displays[i]);
|
char* name = getDisplayName(displays[i]);
|
||||||
|
|
||||||
@ -278,7 +286,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
NSDictionary* dictionary = [screen deviceDescription];
|
NSDictionary* dictionary = [screen deviceDescription];
|
||||||
NSNumber* number = [dictionary objectForKey:@"NSScreenNumber"];
|
NSNumber* number = [dictionary objectForKey:@"NSScreenNumber"];
|
||||||
|
|
||||||
if (monitors[found]->ns.displayID == [number unsignedIntegerValue])
|
if ([number unsignedIntegerValue] == screenDisplayID)
|
||||||
{
|
{
|
||||||
monitors[found]->ns.screen = screen;
|
monitors[found]->ns.screen = screen;
|
||||||
break;
|
break;
|
||||||
|
@ -70,7 +70,7 @@ GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
|||||||
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
|
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
|
||||||
dm.dmBitsPerPel = 32;
|
dm.dmBitsPerPel = 32;
|
||||||
|
|
||||||
if (ChangeDisplaySettingsExW(monitor->win32.name,
|
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
&dm,
|
&dm,
|
||||||
NULL,
|
NULL,
|
||||||
CDS_FULLSCREEN,
|
CDS_FULLSCREEN,
|
||||||
@ -90,7 +90,7 @@ void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
|
|||||||
{
|
{
|
||||||
if (monitor->win32.modeChanged)
|
if (monitor->win32.modeChanged)
|
||||||
{
|
{
|
||||||
ChangeDisplaySettingsExW(monitor->win32.name,
|
ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
NULL, NULL, CDS_FULLSCREEN, NULL);
|
NULL, NULL, CDS_FULLSCREEN, NULL);
|
||||||
monitor->win32.modeChanged = GL_FALSE;
|
monitor->win32.modeChanged = GL_FALSE;
|
||||||
}
|
}
|
||||||
@ -105,16 +105,13 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
{
|
{
|
||||||
int size = 0, found = 0;
|
int size = 0, found = 0;
|
||||||
_GLFWmonitor** monitors = NULL;
|
_GLFWmonitor** monitors = NULL;
|
||||||
DWORD adapterIndex = 0;
|
DWORD adapterIndex, displayIndex;
|
||||||
int primaryIndex = 0;
|
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
for (;;)
|
for (adapterIndex = 0; ; adapterIndex++)
|
||||||
{
|
{
|
||||||
DISPLAY_DEVICEW adapter, display;
|
DISPLAY_DEVICEW adapter;
|
||||||
char* name;
|
|
||||||
HDC dc;
|
|
||||||
|
|
||||||
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
||||||
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
@ -122,60 +119,55 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
adapterIndex++;
|
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
|
||||||
if ((adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ||
|
|
||||||
!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (found == size)
|
for (displayIndex = 0; ; displayIndex++)
|
||||||
{
|
{
|
||||||
if (size)
|
DISPLAY_DEVICEW display;
|
||||||
size *= 2;
|
char* name;
|
||||||
else
|
HDC dc;
|
||||||
size = 4;
|
|
||||||
|
|
||||||
monitors = (_GLFWmonitor**) realloc(monitors, sizeof(_GLFWmonitor*) * size);
|
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
||||||
|
display.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (found == size)
|
||||||
|
{
|
||||||
|
size += 4;
|
||||||
|
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = _glfwCreateUTF8FromWideString(display.DeviceString);
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Failed to convert string to UTF-8");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL);
|
||||||
|
|
||||||
|
monitors[found] = _glfwAllocMonitor(name,
|
||||||
|
GetDeviceCaps(dc, HORZSIZE),
|
||||||
|
GetDeviceCaps(dc, VERTSIZE));
|
||||||
|
|
||||||
|
DeleteDC(dc);
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
wcscpy(monitors[found]->win32.adapterName, adapter.DeviceName);
|
||||||
|
wcscpy(monitors[found]->win32.displayName, display.DeviceName);
|
||||||
|
|
||||||
|
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE &&
|
||||||
|
displayIndex == 0)
|
||||||
|
{
|
||||||
|
_GLFW_SWAP_POINTERS(monitors[0], monitors[found]);
|
||||||
|
}
|
||||||
|
|
||||||
|
found++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
|
||||||
display.cb = sizeof(DISPLAY_DEVICEW);
|
|
||||||
|
|
||||||
EnumDisplayDevicesW(adapter.DeviceName, 0, &display, 0);
|
|
||||||
dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL);
|
|
||||||
|
|
||||||
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
|
||||||
primaryIndex = found;
|
|
||||||
|
|
||||||
name = _glfwCreateUTF8FromWideString(display.DeviceString);
|
|
||||||
if (!name)
|
|
||||||
{
|
|
||||||
_glfwFreeMonitors(monitors, found);
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Failed to convert string to UTF-8");
|
|
||||||
|
|
||||||
free(monitors);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitors[found] = _glfwAllocMonitor(name,
|
|
||||||
GetDeviceCaps(dc, HORZSIZE),
|
|
||||||
GetDeviceCaps(dc, VERTSIZE));
|
|
||||||
|
|
||||||
free(name);
|
|
||||||
DeleteDC(dc);
|
|
||||||
|
|
||||||
wcscpy(monitors[found]->win32.name, adapter.DeviceName);
|
|
||||||
found++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (primaryIndex > 0)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* temp = monitors[0];
|
|
||||||
monitors[0] = monitors[primaryIndex];
|
|
||||||
monitors[primaryIndex] = temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*count = found;
|
*count = found;
|
||||||
@ -184,7 +176,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
|
|
||||||
GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||||
{
|
{
|
||||||
return wcscmp(first->win32.name, second->win32.name) == 0;
|
return wcscmp(first->win32.displayName, second->win32.displayName) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
@ -193,7 +185,7 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|||||||
ZeroMemory(&settings, sizeof(DEVMODEW));
|
ZeroMemory(&settings, sizeof(DEVMODEW));
|
||||||
settings.dmSize = sizeof(DEVMODEW);
|
settings.dmSize = sizeof(DEVMODEW);
|
||||||
|
|
||||||
EnumDisplaySettingsExW(monitor->win32.name,
|
EnumDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
ENUM_CURRENT_SETTINGS,
|
ENUM_CURRENT_SETTINGS,
|
||||||
&settings,
|
&settings,
|
||||||
EDS_ROTATEDMODE);
|
EDS_ROTATEDMODE);
|
||||||
@ -220,7 +212,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
|||||||
ZeroMemory(&dm, sizeof(DEVMODEW));
|
ZeroMemory(&dm, sizeof(DEVMODEW));
|
||||||
dm.dmSize = sizeof(DEVMODEW);
|
dm.dmSize = sizeof(DEVMODEW);
|
||||||
|
|
||||||
if (!EnumDisplaySettingsW(monitor->win32.name, modeIndex, &dm))
|
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
modeIndex++;
|
modeIndex++;
|
||||||
@ -275,7 +267,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|||||||
ZeroMemory(&dm, sizeof(DEVMODEW));
|
ZeroMemory(&dm, sizeof(DEVMODEW));
|
||||||
dm.dmSize = sizeof(DEVMODEW);
|
dm.dmSize = sizeof(DEVMODEW);
|
||||||
|
|
||||||
EnumDisplaySettingsW(monitor->win32.name, ENUM_CURRENT_SETTINGS, &dm);
|
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
|
||||||
|
|
||||||
mode->width = dm.dmPelsWidth;
|
mode->width = dm.dmPelsWidth;
|
||||||
mode->height = dm.dmPelsHeight;
|
mode->height = dm.dmPelsHeight;
|
||||||
@ -291,7 +283,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
HDC dc;
|
HDC dc;
|
||||||
WORD values[768];
|
WORD values[768];
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", monitor->win32.name, NULL, NULL);
|
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
||||||
GetDeviceGammaRamp(dc, values);
|
GetDeviceGammaRamp(dc, values);
|
||||||
DeleteDC(dc);
|
DeleteDC(dc);
|
||||||
|
|
||||||
@ -318,7 +310,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|||||||
memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
|
memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
|
||||||
memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
|
memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", monitor->win32.name, NULL, NULL);
|
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
||||||
SetDeviceGammaRamp(dc, values);
|
SetDeviceGammaRamp(dc, values);
|
||||||
DeleteDC(dc);
|
DeleteDC(dc);
|
||||||
}
|
}
|
||||||
@ -332,6 +324,6 @@ GLFWAPI const WCHAR* glfwGetWin32Monitor(GLFWmonitor* handle)
|
|||||||
{
|
{
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
return monitor->win32.name;
|
return monitor->win32.displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,8 @@ typedef struct _GLFWlibraryWin32
|
|||||||
typedef struct _GLFWmonitorWin32
|
typedef struct _GLFWmonitorWin32
|
||||||
{
|
{
|
||||||
// This size matches the static size of DISPLAY_DEVICE.DeviceName
|
// This size matches the static size of DISPLAY_DEVICE.DeviceName
|
||||||
WCHAR name[32];
|
WCHAR adapterName[32];
|
||||||
|
WCHAR displayName[32];
|
||||||
GLboolean modeChanged;
|
GLboolean modeChanged;
|
||||||
|
|
||||||
} _GLFWmonitorWin32;
|
} _GLFWmonitorWin32;
|
||||||
|
@ -200,87 +200,64 @@ void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
|
|||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
{
|
{
|
||||||
int i, found = 0;
|
int i, j, size = 0, found = 0;
|
||||||
_GLFWmonitor** monitors = NULL;
|
_GLFWmonitor** monitors = NULL;
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
if (_glfw.x11.randr.available)
|
if (_glfw.x11.randr.available)
|
||||||
{
|
{
|
||||||
RROutput primary;
|
XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
|
||||||
XRRScreenResources* sr;
|
_glfw.x11.root);
|
||||||
|
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
||||||
sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);
|
_glfw.x11.root);
|
||||||
primary = XRRGetOutputPrimary(_glfw.x11.display, _glfw.x11.root);
|
|
||||||
|
|
||||||
monitors = calloc(sr->ncrtc, sizeof(_GLFWmonitor*));
|
|
||||||
|
|
||||||
for (i = 0; i < sr->ncrtc; i++)
|
for (i = 0; i < sr->ncrtc; i++)
|
||||||
{
|
{
|
||||||
int j;
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display,
|
||||||
XRROutputInfo* oi;
|
sr, sr->crtcs[i]);
|
||||||
XRRCrtcInfo* ci;
|
|
||||||
RROutput output;
|
|
||||||
|
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, sr->crtcs[i]);
|
|
||||||
if (ci->noutput == 0)
|
|
||||||
{
|
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
output = ci->outputs[0];
|
|
||||||
|
|
||||||
for (j = 0; j < ci->noutput; j++)
|
for (j = 0; j < ci->noutput; j++)
|
||||||
{
|
{
|
||||||
if (ci->outputs[j] == primary)
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display,
|
||||||
|
sr, ci->outputs[j]);
|
||||||
|
if (oi->connection != RR_Connected)
|
||||||
{
|
{
|
||||||
output = primary;
|
XRRFreeOutputInfo(oi);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, output);
|
if (found == size)
|
||||||
if (oi->connection != RR_Connected)
|
{
|
||||||
{
|
size += 4;
|
||||||
|
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size);
|
||||||
|
}
|
||||||
|
|
||||||
|
monitors[found] = _glfwAllocMonitor(oi->name,
|
||||||
|
oi->mm_width,
|
||||||
|
oi->mm_height);
|
||||||
|
|
||||||
|
monitors[found]->x11.output = ci->outputs[j];
|
||||||
|
monitors[found]->x11.crtc = oi->crtc;
|
||||||
|
|
||||||
XRRFreeOutputInfo(oi);
|
XRRFreeOutputInfo(oi);
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
continue;
|
if (ci->outputs[j] == primary)
|
||||||
|
_GLFW_SWAP_POINTERS(monitors[0], monitors[found]);
|
||||||
|
|
||||||
|
found++;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitors[found] = _glfwAllocMonitor(oi->name,
|
|
||||||
oi->mm_width, oi->mm_height);
|
|
||||||
|
|
||||||
monitors[found]->x11.output = output;
|
|
||||||
monitors[found]->x11.crtc = oi->crtc;
|
|
||||||
|
|
||||||
XRRFreeOutputInfo(oi);
|
|
||||||
XRRFreeCrtcInfo(ci);
|
XRRFreeCrtcInfo(ci);
|
||||||
|
|
||||||
found++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
|
|
||||||
for (i = 0; i < found; i++)
|
|
||||||
{
|
|
||||||
if (monitors[i]->x11.output == primary)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* temp = monitors[0];
|
|
||||||
monitors[0] = monitors[i];
|
|
||||||
monitors[i] = temp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found == 0)
|
if (found == 0)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"X11: RandR monitor support seems broken");
|
"X11: RandR monitor support seems broken");
|
||||||
_glfw.x11.randr.monitorBroken = GL_TRUE;
|
_glfw.x11.randr.monitorBroken = GL_TRUE;
|
||||||
|
|
||||||
free(monitors);
|
|
||||||
monitors = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user