Selaa lähdekoodia

X11: Add dynamic loading of libXrandr

Camilla Löwy 8 vuotta sitten
vanhempi
commit
15d102b75e
3 muutettua tiedostoa jossa 115 lisäystä ja 17 poistoa
  1. 1 3
      CMakeLists.txt
  2. 61 14
      src/x11_init.c
  3. 53 0
      src/x11_platform.h

+ 1 - 3
CMakeLists.txt

@@ -245,12 +245,10 @@ if (_GLFW_X11)
 
     # Check for XRandR (modern resolution switching and gamma control)
     if (NOT X11_Xrandr_FOUND)
-        message(FATAL_ERROR "The RandR library and headers were not found")
+        message(FATAL_ERROR "The RandR headers were not found")
     endif()
 
     list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}")
-    list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}")
-    list(APPEND glfw_PKG_DEPS "xrandr")
 
     # Check for Xinerama (legacy multi-monitor support)
     if (NOT X11_Xinerama_FOUND)

+ 61 - 14
src/x11_init.c

@@ -505,22 +505,63 @@ static GLFWbool initExtensions(void)
         }
     }
 
-    if (XRRQueryExtension(_glfw.x11.display,
-                          &_glfw.x11.randr.eventBase,
-                          &_glfw.x11.randr.errorBase))
+    _glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
+    if (_glfw.x11.randr.handle)
     {
-        if (XRRQueryVersion(_glfw.x11.display,
-                            &_glfw.x11.randr.major,
-                            &_glfw.x11.randr.minor))
+        _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
+            dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
+        _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
+            dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
+        _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
+            dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
+        _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
+            dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
+        _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
+            dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
+        _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
+            dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
+        _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
+            dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
+        _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
+            dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
+        _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
+            dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
+        _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
+            dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
+        _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
+            dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
+        _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
+            dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
+        _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
+            dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
+        _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
+            dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
+        _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
+            dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
+        _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
+            dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
+        _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
+            dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
+        _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
+            dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
+
+        if (XRRQueryExtension(_glfw.x11.display,
+                              &_glfw.x11.randr.eventBase,
+                              &_glfw.x11.randr.errorBase))
         {
-            // The GLFW RandR path requires at least version 1.3
-            if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
-                _glfw.x11.randr.available = GLFW_TRUE;
-        }
-        else
-        {
-            _glfwInputError(GLFW_PLATFORM_ERROR,
-                            "X11: Failed to query RandR version");
+            if (XRRQueryVersion(_glfw.x11.display,
+                                &_glfw.x11.randr.major,
+                                &_glfw.x11.randr.minor))
+            {
+                // The GLFW RandR path requires at least version 1.3
+                if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
+                    _glfw.x11.randr.available = GLFW_TRUE;
+            }
+            else
+            {
+                _glfwInputError(GLFW_PLATFORM_ERROR,
+                                "X11: Failed to query RandR version");
+            }
         }
     }
 
@@ -836,6 +877,12 @@ void _glfwPlatformTerminate(void)
         _glfw.x11.x11xcb.handle = NULL;
     }
 
+    if (_glfw.x11.randr.handle)
+    {
+        dlclose(_glfw.x11.randr.handle);
+        _glfw.x11.randr.handle = NULL;
+    }
+
     if (_glfw.x11.helperWindowHandle)
     {
         if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==

+ 53 - 0
src/x11_platform.h

@@ -47,6 +47,41 @@
 // The XInput extension provides raw mouse motion input
 #include <X11/extensions/XInput2.h>
 
+typedef XRRCrtcGamma* (* PFN_XRRAllocGamma)(int);
+typedef void (* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo*);
+typedef void (* PFN_XRRFreeGamma)(XRRCrtcGamma*);
+typedef void (* PFN_XRRFreeOutputInfo)(XRROutputInfo*);
+typedef void (* PFN_XRRFreeScreenResources)(XRRScreenResources*);
+typedef XRRCrtcGamma* (* PFN_XRRGetCrtcGamma)(Display*,RRCrtc);
+typedef int (* PFN_XRRGetCrtcGammaSize)(Display*,RRCrtc);
+typedef XRRCrtcInfo* (* PFN_XRRGetCrtcInfo) (Display*,XRRScreenResources*,RRCrtc);
+typedef XRROutputInfo* (* PFN_XRRGetOutputInfo)(Display*,XRRScreenResources*,RROutput);
+typedef RROutput (* PFN_XRRGetOutputPrimary)(Display*,Window);
+typedef XRRScreenResources* (* PFN_XRRGetScreenResourcesCurrent)(Display*,Window);
+typedef Bool (* PFN_XRRQueryExtension)(Display*,int*,int*);
+typedef Status (* PFN_XRRQueryVersion)(Display*,int*,int*);
+typedef void (* PFN_XRRSelectInput)(Display*,Window,int);
+typedef Status (* PFN_XRRSetCrtcConfig)(Display*,XRRScreenResources*,RRCrtc,Time,int,int,RRMode,Rotation,RROutput*,int);
+typedef void (* PFN_XRRSetCrtcGamma)(Display*,RRCrtc,XRRCrtcGamma*);
+typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
+#define XRRAllocGamma _glfw.x11.randr.AllocGamma
+#define XRRFreeCrtcInfo _glfw.x11.randr.FreeCrtcInfo
+#define XRRFreeGamma _glfw.x11.randr.FreeGamma
+#define XRRFreeOutputInfo _glfw.x11.randr.FreeOutputInfo
+#define XRRFreeScreenResources _glfw.x11.randr.FreeScreenResources
+#define XRRGetCrtcGamma _glfw.x11.randr.GetCrtcGamma
+#define XRRGetCrtcGammaSize _glfw.x11.randr.GetCrtcGammaSize
+#define XRRGetCrtcInfo _glfw.x11.randr.GetCrtcInfo
+#define XRRGetOutputInfo _glfw.x11.randr.GetOutputInfo
+#define XRRGetOutputPrimary _glfw.x11.randr.GetOutputPrimary
+#define XRRGetScreenResourcesCurrent _glfw.x11.randr.GetScreenResourcesCurrent
+#define XRRQueryExtension _glfw.x11.randr.QueryExtension
+#define XRRQueryVersion _glfw.x11.randr.QueryVersion
+#define XRRSelectInput _glfw.x11.randr.SelectInput
+#define XRRSetCrtcConfig _glfw.x11.randr.SetCrtcConfig
+#define XRRSetCrtcGamma _glfw.x11.randr.SetCrtcGamma
+#define XRRUpdateConfiguration _glfw.x11.randr.UpdateConfiguration
+
 typedef XID xcb_window_t;
 typedef XID xcb_visualid_t;
 typedef struct xcb_connection_t xcb_connection_t;
@@ -227,12 +262,30 @@ typedef struct _GLFWlibraryX11
 
     struct {
         GLFWbool    available;
+        void*       handle;
         int         eventBase;
         int         errorBase;
         int         major;
         int         minor;
         GLFWbool    gammaBroken;
         GLFWbool    monitorBroken;
+        PFN_XRRAllocGamma AllocGamma;
+        PFN_XRRFreeCrtcInfo FreeCrtcInfo;
+        PFN_XRRFreeGamma FreeGamma;
+        PFN_XRRFreeOutputInfo FreeOutputInfo;
+        PFN_XRRFreeScreenResources FreeScreenResources;
+        PFN_XRRGetCrtcGamma GetCrtcGamma;
+        PFN_XRRGetCrtcGammaSize GetCrtcGammaSize;
+        PFN_XRRGetCrtcInfo GetCrtcInfo;
+        PFN_XRRGetOutputInfo GetOutputInfo;
+        PFN_XRRGetOutputPrimary GetOutputPrimary;
+        PFN_XRRGetScreenResourcesCurrent GetScreenResourcesCurrent;
+        PFN_XRRQueryExtension QueryExtension;
+        PFN_XRRQueryVersion QueryVersion;
+        PFN_XRRSelectInput SelectInput;
+        PFN_XRRSetCrtcConfig SetCrtcConfig;
+        PFN_XRRSetCrtcGamma SetCrtcGamma;
+        PFN_XRRUpdateConfiguration UpdateConfiguration;
     } randr;
 
     struct {