Pali Rohár
2017-05-16 20:04:57 UTC
XServer with enabled XRANDR 1.2 extension does not provide correct
dimensions from DisplayWidthMM() and DisplayHeightMM() calls anymore.
Values are calculated from fixed DPI 96.
Therefore when XRANDR 1.2 extension is enabled and present, instead use
XRRGetScreenResources() and XRRGetOutputInfo() calls to get correct
dimensions and resolution information.
Signed-off-by: Pali Rohár <***@gmail.com>
---
Changes since v1:
* Fixed detection of presence of XRANDR 1.2
* Fixed resolution calculation when dimensions are zero
---
Makefile.am | 2 ++
configure.ac | 12 ++++++++
xdpyinfo.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 87 insertions(+), 18 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2f21dda..496094e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,7 @@ AM_CFLAGS = \
$(DPY_XCOMPOSITE_CFLAGS) \
$(DPY_XINERAMA_CFLAGS) \
$(DPY_DMX_CFLAGS) \
+ $(DPY_XRANDR_CFLAGS) \
$(DPY_XTST_CFLAGS)
xdpyinfo_LDADD = \
@@ -49,6 +50,7 @@ xdpyinfo_LDADD = \
$(DPY_XCOMPOSITE_LIBS) \
$(DPY_XINERAMA_LIBS) \
$(DPY_DMX_LIBS) \
+ $(DPY_XRANDR_LIBS) \
$(DPY_XTST_LIBS)
xdpyinfo_SOURCES = \
diff --git a/configure.ac b/configure.ac
index 73dce26..4473faa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -132,6 +132,18 @@ else
echo "without dmx"
fi
+AC_ARG_WITH(xrandr, AS_HELP_STRING([--without-xrandr],[Disable xrandr 1.2 support.]),
+ [USE_XRANDR="$withval"], [USE_XRANDR="yes"])
+if test "x$USE_XRANDR" != "xno" ; then
+ PKG_CHECK_MODULES(DPY_XRANDR, xrandr >= 1.2,
+ [SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $DPY_XRANDR_CFLAGS $DPY_X11_CFLAGS"
+ AC_CHECK_HEADERS([X11/extensions/Xrandr.h],,,[#include <X11/Xlib.h>])
+ CPPFLAGS="$SAVE_CPPFLAGS"],[echo "not found"])
+else
+ echo "without xrandr 1.2"
+fi
+
PKG_CHECK_MODULES(DPY_XTST, xtst,
[SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $DPY_XTST_CFLAGS $DPY_X11_CFLAGS"
diff --git a/xdpyinfo.c b/xdpyinfo.c
index 152e32c..409968c 100644
--- a/xdpyinfo.c
+++ b/xdpyinfo.c
@@ -76,6 +76,10 @@ in this Software without prior written authorization from The Open Group.
# define DMX
# endif
+# if HAVE_X11_EXTENSIONS_XRANDR_H
+# define XRANDR
+# endif
+
#endif
#ifdef WIN32
@@ -137,6 +141,9 @@ in this Software without prior written authorization from The Open Group.
#ifdef DMX
#include <X11/extensions/dmxext.h>
#endif
+#ifdef XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
#include <X11/Xos.h>
#include <stdio.h>
#include <stdlib.h>
@@ -455,27 +462,75 @@ print_screen_info(Display *dpy, int scr)
double xres, yres;
int ndepths = 0, *depths = NULL;
unsigned int width, height;
-
- /*
- * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
- *
- * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
- * = N pixels / (M inch / 25.4)
- * = N * 25.4 pixels / M inch
- */
-
- xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) /
- ((double) DisplayWidthMM(dpy,scr)));
- yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) /
- ((double) DisplayHeightMM(dpy,scr)));
+#ifdef XRANDR
+ int event_base, error_base;
+ int major, minor;
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output;
+ XRRCrtcInfo *crtc;
+#endif
printf ("\n");
printf ("screen #%d:\n", scr);
- printf (" dimensions: %dx%d pixels (%dx%d millimeters)\n",
- XDisplayWidth (dpy, scr), XDisplayHeight (dpy, scr),
- XDisplayWidthMM(dpy, scr), XDisplayHeightMM (dpy, scr));
- printf (" resolution: %dx%d dots per inch\n",
- (int) (xres + 0.5), (int) (yres + 0.5));
+
+#ifdef XRANDR
+ if (XRRQueryExtension (dpy, &event_base, &error_base) &&
+ XRRQueryVersion (dpy, &major, &minor) &&
+ (major > 1 || (major == 1 && minor >= 2)) &&
+ (res = XRRGetScreenResources (dpy, RootWindow (dpy, scr))))
+ {
+ for (i = 0; i < res->noutput; ++i) {
+ output = XRRGetOutputInfo (dpy, res, res->outputs[i]);
+ if (!output || !output->crtc || output->connection != RR_Connected)
+ continue;
+
+ crtc = XRRGetCrtcInfo (dpy, res, output->crtc);
+ if (!crtc) {
+ XRRFreeOutputInfo (output);
+ continue;
+ }
+
+ printf (" output: %s\n", output->name);
+ printf (" dimensions: %ux%u pixels (%lux%lu millimeters)\n",
+ crtc->width, crtc->height, output->mm_width, output->mm_height);
+
+ if (output->mm_width && output->mm_height) {
+ xres = ((((double) crtc->width) * 25.4) / ((double) output->mm_width));
+ yres = ((((double) crtc->height) * 25.4) / ((double) output->mm_height));
+ } else {
+ xres = 0;
+ yres = 0;
+ }
+ printf (" resolution: %dx%d dots per inch\n",
+ (int) (xres + 0.5), (int) (yres + 0.5));
+
+ XRRFreeCrtcInfo (crtc);
+ XRRFreeOutputInfo (output);
+ }
+ XRRFreeScreenResources (res);
+ }
+ else
+#endif
+ {
+ printf (" dimensions: %dx%d pixels (%dx%d millimeters)\n",
+ DisplayWidth (dpy, scr), DisplayHeight (dpy, scr),
+ DisplayWidthMM(dpy, scr), DisplayHeightMM (dpy, scr));
+
+ /*
+ * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
+ *
+ * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
+ * = N pixels / (M inch / 25.4)
+ * = N * 25.4 pixels / M inch
+ */
+ xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) /
+ ((double) DisplayWidthMM(dpy,scr)));
+ yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) /
+ ((double) DisplayHeightMM(dpy,scr)));
+ printf (" resolution: %dx%d dots per inch\n",
+ (int) (xres + 0.5), (int) (yres + 0.5));
+ }
+
depths = XListDepths (dpy, scr, &ndepths);
if (!depths) ndepths = 0;
printf (" depths (%d): ", ndepths);
dimensions from DisplayWidthMM() and DisplayHeightMM() calls anymore.
Values are calculated from fixed DPI 96.
Therefore when XRANDR 1.2 extension is enabled and present, instead use
XRRGetScreenResources() and XRRGetOutputInfo() calls to get correct
dimensions and resolution information.
Signed-off-by: Pali Rohár <***@gmail.com>
---
Changes since v1:
* Fixed detection of presence of XRANDR 1.2
* Fixed resolution calculation when dimensions are zero
---
Makefile.am | 2 ++
configure.ac | 12 ++++++++
xdpyinfo.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 87 insertions(+), 18 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2f21dda..496094e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,7 @@ AM_CFLAGS = \
$(DPY_XCOMPOSITE_CFLAGS) \
$(DPY_XINERAMA_CFLAGS) \
$(DPY_DMX_CFLAGS) \
+ $(DPY_XRANDR_CFLAGS) \
$(DPY_XTST_CFLAGS)
xdpyinfo_LDADD = \
@@ -49,6 +50,7 @@ xdpyinfo_LDADD = \
$(DPY_XCOMPOSITE_LIBS) \
$(DPY_XINERAMA_LIBS) \
$(DPY_DMX_LIBS) \
+ $(DPY_XRANDR_LIBS) \
$(DPY_XTST_LIBS)
xdpyinfo_SOURCES = \
diff --git a/configure.ac b/configure.ac
index 73dce26..4473faa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -132,6 +132,18 @@ else
echo "without dmx"
fi
+AC_ARG_WITH(xrandr, AS_HELP_STRING([--without-xrandr],[Disable xrandr 1.2 support.]),
+ [USE_XRANDR="$withval"], [USE_XRANDR="yes"])
+if test "x$USE_XRANDR" != "xno" ; then
+ PKG_CHECK_MODULES(DPY_XRANDR, xrandr >= 1.2,
+ [SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $DPY_XRANDR_CFLAGS $DPY_X11_CFLAGS"
+ AC_CHECK_HEADERS([X11/extensions/Xrandr.h],,,[#include <X11/Xlib.h>])
+ CPPFLAGS="$SAVE_CPPFLAGS"],[echo "not found"])
+else
+ echo "without xrandr 1.2"
+fi
+
PKG_CHECK_MODULES(DPY_XTST, xtst,
[SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $DPY_XTST_CFLAGS $DPY_X11_CFLAGS"
diff --git a/xdpyinfo.c b/xdpyinfo.c
index 152e32c..409968c 100644
--- a/xdpyinfo.c
+++ b/xdpyinfo.c
@@ -76,6 +76,10 @@ in this Software without prior written authorization from The Open Group.
# define DMX
# endif
+# if HAVE_X11_EXTENSIONS_XRANDR_H
+# define XRANDR
+# endif
+
#endif
#ifdef WIN32
@@ -137,6 +141,9 @@ in this Software without prior written authorization from The Open Group.
#ifdef DMX
#include <X11/extensions/dmxext.h>
#endif
+#ifdef XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
#include <X11/Xos.h>
#include <stdio.h>
#include <stdlib.h>
@@ -455,27 +462,75 @@ print_screen_info(Display *dpy, int scr)
double xres, yres;
int ndepths = 0, *depths = NULL;
unsigned int width, height;
-
- /*
- * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
- *
- * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
- * = N pixels / (M inch / 25.4)
- * = N * 25.4 pixels / M inch
- */
-
- xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) /
- ((double) DisplayWidthMM(dpy,scr)));
- yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) /
- ((double) DisplayHeightMM(dpy,scr)));
+#ifdef XRANDR
+ int event_base, error_base;
+ int major, minor;
+ XRRScreenResources *res = NULL;
+ XRROutputInfo *output;
+ XRRCrtcInfo *crtc;
+#endif
printf ("\n");
printf ("screen #%d:\n", scr);
- printf (" dimensions: %dx%d pixels (%dx%d millimeters)\n",
- XDisplayWidth (dpy, scr), XDisplayHeight (dpy, scr),
- XDisplayWidthMM(dpy, scr), XDisplayHeightMM (dpy, scr));
- printf (" resolution: %dx%d dots per inch\n",
- (int) (xres + 0.5), (int) (yres + 0.5));
+
+#ifdef XRANDR
+ if (XRRQueryExtension (dpy, &event_base, &error_base) &&
+ XRRQueryVersion (dpy, &major, &minor) &&
+ (major > 1 || (major == 1 && minor >= 2)) &&
+ (res = XRRGetScreenResources (dpy, RootWindow (dpy, scr))))
+ {
+ for (i = 0; i < res->noutput; ++i) {
+ output = XRRGetOutputInfo (dpy, res, res->outputs[i]);
+ if (!output || !output->crtc || output->connection != RR_Connected)
+ continue;
+
+ crtc = XRRGetCrtcInfo (dpy, res, output->crtc);
+ if (!crtc) {
+ XRRFreeOutputInfo (output);
+ continue;
+ }
+
+ printf (" output: %s\n", output->name);
+ printf (" dimensions: %ux%u pixels (%lux%lu millimeters)\n",
+ crtc->width, crtc->height, output->mm_width, output->mm_height);
+
+ if (output->mm_width && output->mm_height) {
+ xres = ((((double) crtc->width) * 25.4) / ((double) output->mm_width));
+ yres = ((((double) crtc->height) * 25.4) / ((double) output->mm_height));
+ } else {
+ xres = 0;
+ yres = 0;
+ }
+ printf (" resolution: %dx%d dots per inch\n",
+ (int) (xres + 0.5), (int) (yres + 0.5));
+
+ XRRFreeCrtcInfo (crtc);
+ XRRFreeOutputInfo (output);
+ }
+ XRRFreeScreenResources (res);
+ }
+ else
+#endif
+ {
+ printf (" dimensions: %dx%d pixels (%dx%d millimeters)\n",
+ DisplayWidth (dpy, scr), DisplayHeight (dpy, scr),
+ DisplayWidthMM(dpy, scr), DisplayHeightMM (dpy, scr));
+
+ /*
+ * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
+ *
+ * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
+ * = N pixels / (M inch / 25.4)
+ * = N * 25.4 pixels / M inch
+ */
+ xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) /
+ ((double) DisplayWidthMM(dpy,scr)));
+ yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) /
+ ((double) DisplayHeightMM(dpy,scr)));
+ printf (" resolution: %dx%d dots per inch\n",
+ (int) (xres + 0.5), (int) (yres + 0.5));
+ }
+
depths = XListDepths (dpy, scr, &ndepths);
if (!depths) ndepths = 0;
printf (" depths (%d): ", ndepths);
--
1.7.9.5
_______________________________________________
xorg-***@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.
1.7.9.5
_______________________________________________
xorg-***@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.