summaryrefslogtreecommitdiff
path: root/src/drivers/X11
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-06-22 07:04:00 +0000
committerManolo Gouy <Manolo>2016-06-22 07:04:00 +0000
commit943d1cf9870a08cbe65ad9235b1ca4347ec9c7dc (patch)
treee298b233ce2f2d80cd0a5b5aa238677f1e637dd4 /src/drivers/X11
parenta7af6ab04c8f9ad5571542ab33ddc709bed9b624 (diff)
Use Xrandr to get the true DPI of the display under the X11 platform.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11790 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers/X11')
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.cxx58
1 files changed, 49 insertions, 9 deletions
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
index be26205e7..34a932764 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -264,11 +264,45 @@ int Fl_X11_Screen_Driver::h() {
return fl_workarea_xywh[3];
}
+#define USE_XRANDR (HAVE_DLSYM && HAVE_DLFCN_H) // means attempt to dynamically load libXrandr.so
+#if USE_XRANDR
+#include <dlfcn.h>
+typedef struct {
+ int width, height;
+ int mwidth, mheight;
+} XRRScreenSize;
+typedef XRRScreenSize* (*XRRSizes_type)(Display *dpy, int screen, int *nsizes);
+#endif // USE_XRANDR
void Fl_X11_Screen_Driver::init()
{
if (!fl_display) open_display();
- // FIXME: Rewrite using RandR instead
+
+ int dpi_by_randr = 0;
+ float dpih, dpiv;
+#if USE_XRANDR
+ static XRRSizes_type XRRSizes_f = NULL;
+ if (!XRRSizes_f) {
+ void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY);
+ if (!libxrandr_addr) libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY);
+# ifdef __APPLE_CC__ // allows testing on Darwin + X11
+ if (!libxrandr_addr) libxrandr_addr = dlopen("/opt/X11/lib/libXrandr.dylib", RTLD_LAZY);
+# endif
+ if (libxrandr_addr) XRRSizes_f = (XRRSizes_type)dlsym(libxrandr_addr, "XRRSizes");
+ }
+ if (XRRSizes_f) {
+ int nscreens;
+ XRRScreenSize *ssize = XRRSizes_f(fl_display, fl_screen, &nscreens);
+ // for(int i=0;i<nscreens;i++)
+ // printf("width=%d height=%d mwidth=%d mheight=%d\n",ssize[i].width,ssize[i].height,ssize[i].mwidth,ssize[i].mheight);
+ int mm = ssize[0].mwidth;
+ dpih = mm ? ssize[0].width*25.4f/mm : 0.0f;
+ mm = ssize[0].mheight;
+ dpiv = mm ? ssize[0].height*25.4f/mm : 0.0f;
+ dpi_by_randr = 1;
+ }
+#endif // USE_XRANDR
+
#if HAVE_XINERAMA
if (XineramaIsActive(fl_display)) {
XineramaScreenInfo *xsi = XineramaQueryScreens(fl_display, &num_screens);
@@ -281,10 +315,13 @@ void Fl_X11_Screen_Driver::init()
screens[i].width = xsi[i].width;
screens[i].height = xsi[i].height;
- int mm = DisplayWidthMM(fl_display, fl_screen);
- dpi[i][0] = mm ? screens[i].width*25.4f/mm : 0.0f;
- mm = DisplayHeightMM(fl_display, fl_screen);
- dpi[i][1] = mm ? screens[i].height*25.4f/mm : 0.0f;
+ if (dpi_by_randr) { dpi[i][0] = dpih; dpi[i][1] = dpiv; }
+ else {
+ int mm = DisplayWidthMM(fl_display, fl_screen);
+ dpi[i][0] = mm ? screens[i].width*25.4f/mm : 0.0f;
+ mm = DisplayHeightMM(fl_display, fl_screen);
+ dpi[i][1] = mm ? screens[i].height*25.4f/mm : 0.0f;
+ }
}
if (xsi) XFree(xsi);
} else
@@ -299,10 +336,13 @@ void Fl_X11_Screen_Driver::init()
screens[i].width = DisplayWidth(fl_display, i);
screens[i].height = DisplayHeight(fl_display, i);
- int mm = DisplayWidthMM(fl_display, i);
- dpi[i][0] = mm ? DisplayWidth(fl_display, i)*25.4f/mm : 0.0f;
- mm = DisplayHeightMM(fl_display, i);
- dpi[i][1] = mm ? DisplayHeight(fl_display, i)*25.4f/mm : 0.0f;
+ if (dpi_by_randr) { dpi[i][0] = dpih; dpi[i][1] = dpiv; }
+ else {
+ int mm = DisplayWidthMM(fl_display, fl_screen);
+ dpi[i][0] = mm ? screens[i].width*25.4f/mm : 0.0f;
+ mm = DisplayHeightMM(fl_display, fl_screen);
+ dpi[i][1] = mm ? screens[i].height*25.4f/mm : 0.0f;
+ }
}
}
}