Преглед на файлове

Merge pull request #5173 from Hinsbart/fix_xrandr

x11: fix XRandr GetMonitors
Juan Linietsky преди 9 години
родител
ревизия
7526b14afd
променени са 2 файла, в които са добавени 28 реда и са изтрити 8 реда
  1. 25 8
      platform/x11/os_x11.cpp
  2. 3 0
      platform/x11/os_x11.h

+ 25 - 8
platform/x11/os_x11.cpp

@@ -120,15 +120,33 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
 
 	const char* err;
 	xrr_get_monitors = NULL;
+	xrr_free_monitors = NULL;
+	int xrandr_major = 0;
+	int xrandr_minor = 0;
+	int event_base, error_base;
+	xrandr_ext_ok = XRRQueryExtension(x11_display,&event_base, &error_base);
 	xrandr_handle = dlopen("libXrandr.so", RTLD_LAZY);
 	err = dlerror();
 	if (!xrandr_handle) {
-		fprintf(stderr, "could not load libXrandr.so, dpi detection disabled. Error: %s\n", err);
+		fprintf(stderr, "could not load libXrandr.so, Error: %s\n", err);
 	}
 	else {
-		xrr_get_monitors = (xrr_get_monitors_t) dlsym(xrandr_handle, "XRRGetMonitors");
-		if (!xrr_get_monitors)
-			fprintf(stderr, "could not find symbol XRRGetMonitors, dpi detection will only work on the first screen\nError: %s\n", err);
+		XRRQueryVersion(x11_display, &xrandr_major, &xrandr_minor);
+		if (((xrandr_major << 8) | xrandr_minor) >= 0x0105) {
+			xrr_get_monitors = (xrr_get_monitors_t) dlsym(xrandr_handle, "XRRGetMonitors");
+			if (!xrr_get_monitors) {
+				err = dlerror();
+				fprintf(stderr, "could not find symbol XRRGetMonitors\nError: %s\n", err);
+			}
+			else {
+				xrr_free_monitors = (xrr_free_monitors_t) dlsym(xrandr_handle, "XRRFreeMonitors");
+				if (!xrr_free_monitors) {
+					err = dlerror();
+					fprintf(stderr, "could not find XRRFreeMonitors\nError: %s\n", err);
+					xrr_get_monitors = NULL;
+				}
+			}
+		}
 	}
 
 	xim = XOpenIM (x11_display, NULL, NULL, NULL);
@@ -745,19 +763,18 @@ int OS_X11::get_screen_dpi(int p_screen) const {
 	ERR_FAIL_INDEX_V(p_screen, get_screen_count(), 0);
 
 	//Get physical monitor Dimensions through XRandR and calculate dpi
-	int event_base, error_base;
-	const Bool ext_okay = XRRQueryExtension(x11_display,&event_base, &error_base);
-
 	Size2 sc = get_screen_size(p_screen);
-	if (ext_okay) {
+	if (xrandr_ext_ok) {
 		int count = 0;
 		if (xrr_get_monitors) {
 			xrr_monitor_info *monitors = xrr_get_monitors(x11_display, x11_window, true, &count);
 			if (p_screen < count) {
 				double xdpi = sc.width  / (double) monitors[p_screen].mwidth  * 25.4;
 				double ydpi = sc.height / (double) monitors[p_screen].mheight * 25.4;
+				xrr_free_monitors(monitors);
 				return (xdpi + ydpi) / 2;
 			}
+			xrr_free_monitors(monitors);
 		}
 		else if (p_screen == 0) {
 			XRRScreenSize *sizes = XRRSizes(x11_display, 0, &count);

+ 3 - 0
platform/x11/os_x11.h

@@ -178,8 +178,11 @@ class OS_X11 : public OS_Unix {
 	void set_wm_fullscreen(bool p_enabled);
 
 	typedef xrr_monitor_info* (*xrr_get_monitors_t)(Display *dpy, Window window, Bool get_active, int *nmonitors);
+	typedef void (*xrr_free_monitors_t)(xrr_monitor_info* monitors);
 	xrr_get_monitors_t xrr_get_monitors;
+	xrr_free_monitors_t xrr_free_monitors;
 	void *xrandr_handle;
+	Bool xrandr_ext_ok;
 
 protected: