[PATCH app/xdpyinfo v2] Use XRANDR 1.2 extension for reporting dimensions and resolution per output

Pali Rohár pali.rohar at gmail.com
Sat Mar 10 02:20:28 UTC 2018


Hi! I would like to remind this patch which fixes dimensions values in
xdpyinfo output which are broken for many years...

On Tuesday 16 May 2017 22:04:57 Pali Rohár wrote:
> 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 <pali.rohar at 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);

-- 
Pali Rohár
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://lists.x.org/archives/xorg-devel/attachments/20180310/e93d24f4/attachment.sig>


More information about the xorg-devel mailing list