X11: Add dynamic loading of libXrandr

This commit is contained in:
Camilla Löwy 2017-08-16 19:46:09 +02:00
parent 0019f7a45e
commit 15d102b75e
3 changed files with 115 additions and 17 deletions

View File

@ -245,12 +245,10 @@ if (_GLFW_X11)
# Check for XRandR (modern resolution switching and gamma control) # Check for XRandR (modern resolution switching and gamma control)
if (NOT X11_Xrandr_FOUND) 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() endif()
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}") 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) # Check for Xinerama (legacy multi-monitor support)
if (NOT X11_Xinerama_FOUND) if (NOT X11_Xinerama_FOUND)

View File

@ -505,22 +505,63 @@ static GLFWbool initExtensions(void)
} }
} }
if (XRRQueryExtension(_glfw.x11.display, _glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
&_glfw.x11.randr.eventBase, if (_glfw.x11.randr.handle)
&_glfw.x11.randr.errorBase))
{ {
if (XRRQueryVersion(_glfw.x11.display, _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
&_glfw.x11.randr.major, dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
&_glfw.x11.randr.minor)) _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 (XRRQueryVersion(_glfw.x11.display,
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) &_glfw.x11.randr.major,
_glfw.x11.randr.available = GLFW_TRUE; &_glfw.x11.randr.minor))
} {
else // The GLFW RandR path requires at least version 1.3
{ if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
_glfwInputError(GLFW_PLATFORM_ERROR, _glfw.x11.randr.available = GLFW_TRUE;
"X11: Failed to query RandR version"); }
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to query RandR version");
}
} }
} }
@ -836,6 +877,12 @@ void _glfwPlatformTerminate(void)
_glfw.x11.x11xcb.handle = NULL; _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 (_glfw.x11.helperWindowHandle)
{ {
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) == if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==

View File

@ -47,6 +47,41 @@
// The XInput extension provides raw mouse motion input // The XInput extension provides raw mouse motion input
#include <X11/extensions/XInput2.h> #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_window_t;
typedef XID xcb_visualid_t; typedef XID xcb_visualid_t;
typedef struct xcb_connection_t xcb_connection_t; typedef struct xcb_connection_t xcb_connection_t;
@ -227,12 +262,30 @@ typedef struct _GLFWlibraryX11
struct { struct {
GLFWbool available; GLFWbool available;
void* handle;
int eventBase; int eventBase;
int errorBase; int errorBase;
int major; int major;
int minor; int minor;
GLFWbool gammaBroken; GLFWbool gammaBroken;
GLFWbool monitorBroken; 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; } randr;
struct { struct {