[PATCH app/xdpyinfo] Use XRANDR 1.2 extension for reporting dimensions and resolution per output
Pali Rohár
pali.rohar at gmail.com
Wed Apr 12 16:29:19 UTC 2017
Current usage of DisplayWidthMM() and DisplayHeightMM() does not make sense
for multi-monitor configuration. In most cases DPI is set to 96 as there is
no sane value.
Instead when XRANDR 1.2 extension is supported, report dimensions and
resolution information per XRANDR monitor output. It should provide
correct DPI value.
Lot of users complains about incorrect DPI reported by xdpyinfo, see bug:
https://bugs.freedesktop.org/show_bug.cgi?id=23705
Signed-off-by: Pali Rohár <pali.rohar at gmail.com>
---
Without this patch `xdpyinfo | grep -A 4 ^screen` reports:
screen #0:
dimensions: 1600x900 pixels (423x238 millimeters)
resolution: 96x96 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
root window id: 0xf8
Where DPI and also monitor dimensions in millimeters is incorrect.
After applying this patch `xdpyinfo | grep -A 4 ^screen` reports:
screen #0:
output: eDP1
dimensions: 1600x900 pixels (310x170 millimeters)
resolution: 131x134 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
And both DPI and monitor dimensions (for eDP1) are correct.
---
Makefile.am | 2 ++
configure.ac | 12 ++++++++
xdpyinfo.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 82 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..7a75fdc 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,70 @@ 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);
+
+ xres = ((((double) crtc->width) * 25.4) / ((double) output->mm_width));
+ yres = ((((double) crtc->height) * 25.4) / ((double) output->mm_height));
+ 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
More information about the xorg-devel
mailing list