Prechádzať zdrojové kódy

Enabled enumeration of mirroring displays.

This exposes all monitors in every mirroring group, which is needed for
robust detection of an Oculus Rift.
Camilla Berglund 11 rokov pred
rodič
commit
1b6d8a6ed6
5 zmenil súbory, kde vykonal 92 pridanie a 114 odobranie
  1. 2 2
      include/GLFW/glfw3native.h
  2. 11 3
      src/cocoa_monitor.m
  3. 48 56
      src/win32_monitor.c
  4. 2 1
      src/win32_platform.h
  5. 29 52
      src/x11_monitor.c

+ 2 - 2
include/GLFW/glfw3native.h

@@ -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.
- *  @return The the device name of the specified monitor.
+/*! @brief Returns the display 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);

+ 11 - 3
src/cocoa_monitor.m

@@ -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;

+ 48 - 56
src/win32_monitor.c

@@ -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;
-    int primaryIndex = 0;
+    DWORD adapterIndex, displayIndex;
 
 
     *count = 0;
     *count = 0;
 
 
-    for (;;)
+    for (adapterIndex = 0;  ;  adapterIndex++)
     {
     {
-        DISPLAY_DEVICEW adapter, display;
-        char* name;
-        HDC dc;
+        DISPLAY_DEVICEW adapter;
 
 
         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_MIRRORING_DRIVER) ||
-            !(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
-        {
+        if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
             continue;
             continue;
-        }
 
 
-        if (found == size)
+        for (displayIndex = 0;  ;  displayIndex++)
         {
         {
-            if (size)
-                size *= 2;
-            else
-                size = 4;
+            DISPLAY_DEVICEW display;
+            char* name;
+            HDC dc;
 
 
-            monitors = (_GLFWmonitor**) realloc(monitors, sizeof(_GLFWmonitor*) * size);
-        }
+            ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
+            display.cb = sizeof(DISPLAY_DEVICEW);
 
 
-        ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
-        display.cb = sizeof(DISPLAY_DEVICEW);
+            if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
+                break;
 
 
-        EnumDisplayDevicesW(adapter.DeviceName, 0, &display, 0);
-        dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL);
+            if (found == size)
+            {
+                size += 4;
+                monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size);
+            }
 
 
-        if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
-            primaryIndex = found;
+            name = _glfwCreateUTF8FromWideString(display.DeviceString);
+            if (!name)
+            {
+                _glfwInputError(GLFW_PLATFORM_ERROR,
+                                "Failed to convert string to UTF-8");
+                continue;
+            }
 
 
-        name = _glfwCreateUTF8FromWideString(display.DeviceString);
-        if (!name)
-        {
-            _glfwFreeMonitors(monitors, found);
-            _glfwInputError(GLFW_PLATFORM_ERROR,
-                            "Failed to convert string to UTF-8");
+            dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL);
 
 
-            free(monitors);
-            return NULL;
-        }
+            monitors[found] = _glfwAllocMonitor(name,
+                                                GetDeviceCaps(dc, HORZSIZE),
+                                                GetDeviceCaps(dc, VERTSIZE));
 
 
-        monitors[found] = _glfwAllocMonitor(name,
-                                             GetDeviceCaps(dc, HORZSIZE),
-                                             GetDeviceCaps(dc, VERTSIZE));
+            DeleteDC(dc);
+            free(name);
 
 
-        free(name);
-        DeleteDC(dc);
+            wcscpy(monitors[found]->win32.adapterName, adapter.DeviceName);
+            wcscpy(monitors[found]->win32.displayName, display.DeviceName);
 
 
-        wcscpy(monitors[found]->win32.name, adapter.DeviceName);
-        found++;
-    }
+            if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE &&
+                displayIndex == 0)
+            {
+                _GLFW_SWAP_POINTERS(monitors[0], monitors[found]);
+            }
 
 
-    if (primaryIndex > 0)
-    {
-        _GLFWmonitor* temp = monitors[0];
-        monitors[0] = monitors[primaryIndex];
-        monitors[primaryIndex] = temp;
+            found++;
+        }
     }
     }
 
 
     *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;
 }
 }
 
 

+ 2 - 1
src/win32_platform.h

@@ -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;

+ 29 - 52
src/x11_monitor.c

@@ -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;
-
-        sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root);
-        primary = XRRGetOutputPrimary(_glfw.x11.display, _glfw.x11.root);
-
-        monitors = calloc(sr->ncrtc, sizeof(_GLFWmonitor*));
+        XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
+                                                       _glfw.x11.root);
+        RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
+                                               _glfw.x11.root);
 
 
         for (i = 0;  i < sr->ncrtc;  i++)
         for (i = 0;  i < sr->ncrtc;  i++)
         {
         {
-            int j;
-            XRROutputInfo* oi;
-            XRRCrtcInfo* ci;
-            RROutput output;
-
-            ci = XRRGetCrtcInfo(_glfw.x11.display, sr, sr->crtcs[i]);
-            if (ci->noutput == 0)
-            {
-                XRRFreeCrtcInfo(ci);
-                continue;
-            }
-
-            output = ci->outputs[0];
+            XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display,
+                                             sr, sr->crtcs[i]);
 
 
             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;
-                    break;
+                    XRRFreeOutputInfo(oi);
+                    continue;
                 }
                 }
-            }
 
 
-            oi = XRRGetOutputInfo(_glfw.x11.display, sr, output);
-            if (oi->connection != RR_Connected)
-            {
+                if (found == size)
+                {
+                    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;
-            }
 
 
-            monitors[found] = _glfwAllocMonitor(oi->name,
-                                                oi->mm_width, oi->mm_height);
+                if (ci->outputs[j] == primary)
+                    _GLFW_SWAP_POINTERS(monitors[0], monitors[found]);
 
 
-            monitors[found]->x11.output = output;
-            monitors[found]->x11.crtc   = oi->crtc;
+                found++;
+            }
 
 
-            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;
         }
         }
     }
     }