On Thu, Jun 23, 2011 at 3:55 PM, Peter Hutterer
<peter.hutte...@who-t.net> wrote:
> The NVIDIA binary driver doesn't support RandR 1.2 but it does support
> Xinerama. Due to a server bug, we still get the current server's RandR
> version back when we query, so we need to check to the binary
> driver-specific NV-CONTROL extension first. If that or a RandR < 1.2
> version is present fall back to Xinerama if we need to.
>
> User commands:
>    xsetwacom set "device name" MapToOutput HEAD-0
>    xsetwacom set "device name" MapToOutput HEAD-1
>
> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
> ---
> Changes to v2:
> - test for NV-CONTROL before testing for randr
> - move TRACE statements inside set_output_*
>
>  configure.ac      |    2 +-
>  man/xsetwacom.man |    3 +-
>  tools/xsetwacom.c |   93 ++++++++++++++++++++++++++++++++++++++++++----------
>  3 files changed, 78 insertions(+), 20 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 408e75f..c151e54 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -53,7 +53,7 @@ AC_CHECK_LIB([m], [rint])
>  PKG_CHECK_MODULES(XORG, [xorg-server >= 1.7.0] xproto xext kbproto 
> inputproto randrproto)
>
>  # Obtain compiler/linker options for the xsetwacom tool
> -PKG_CHECK_MODULES(X11, x11 xi xrandr)
> +PKG_CHECK_MODULES(X11, x11 xi xrandr xinerama)
>
>  # Obtain compiler/linker options for libudev used by ISDV4 code
>  PKG_CHECK_MODULES(UDEV, libudev)
> diff --git a/man/xsetwacom.man b/man/xsetwacom.man
> index 3a5fa40..564e1d0 100644
> --- a/man/xsetwacom.man
> +++ b/man/xsetwacom.man
> @@ -126,7 +126,8 @@ outputs may be obtained with the xrandr tool. The output 
> mapping
>  configuration is a onetime setting and does not track output
>  reconfigurations; the command needs to be re-run whenever the output
>  configuration changes. When used with tablet rotation, the tablet must be
> -rotated before it is mapped to the new screen.
> +rotated before it is mapped to the new screen. When running the NVIDIA
> +binary driver, the output names are "HEAD-0" and "HEAD-1".
>  This parameter is write-only and cannot be queried.
>  .TP
>  \fBMode\fR Absolute|Relative
> diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
> index c0cf707..9a73078 100644
> --- a/tools/xsetwacom.c
> +++ b/tools/xsetwacom.c
> @@ -37,6 +37,7 @@
>  #include <X11/Xatom.h>
>  #include <X11/extensions/XInput.h>
>  #include <X11/extensions/Xrandr.h>
> +#include <X11/extensions/Xinerama.h>
>  #include <X11/XKBlib.h>
>
>  #define TRACE(...) \
> @@ -57,6 +58,7 @@ enum prop_flags {
>        PROP_FLAG_READONLY = 2,
>        PROP_FLAG_WRITEONLY = 4,
>        PROP_FLAG_INVERTED = 8, /* only valid with PROP_FLAG_BOOLEAN */
> +       PROP_FLAG_OUTPUT = 16,
>  };
>
>
> @@ -416,7 +418,7 @@ static param_t parameters[] =
>                .desc = "Map the device to the given output. ",
>                .set_func = set_output,
>                .arg_count = 1,
> -               .prop_flags = PROP_FLAG_WRITEONLY
> +               .prop_flags = PROP_FLAG_WRITEONLY | PROP_FLAG_OUTPUT,
>        },
>        {
>                .name = "all",
> @@ -1483,7 +1485,16 @@ static Bool convert_value_from_user(const param_t 
> *param, const char *value, int
>                if (param->prop_flags & PROP_FLAG_INVERTED)
>                        *return_value = !(*return_value);
>        }
> -       else
> +       else if (param->prop_flags & PROP_FLAG_OUTPUT)
> +       {
> +               const char *prefix = "HEAD-";
> +               /* We currently support HEAD-X, where X is 0-9 */
> +               if (strlen(value) != strlen(prefix) + 1 ||
> +                   strncasecmp(value, prefix, strlen(prefix)) != 0)
> +                       return False;
> +
> +               *return_value = value[strlen(prefix)] - '0';
> +       } else
>        {
>                char *end;
>                long conversion = strtol(value, &end, 10);
> @@ -2000,7 +2011,6 @@ static void _set_matrix(Display *dpy, XDevice *dev,
>
>  static void set_output_xrandr(Display *dpy, XDevice *dev, param_t *param, 
> int argc, char **argv)
>  {
> -       int min, maj;
>        int i, found = 0;
>        char *output_name;
>        XRRScreenResources *res;
> @@ -2009,20 +2019,6 @@ static void set_output_xrandr(Display *dpy, XDevice 
> *dev, param_t *param, int ar
>
>        output_name = argv[0];
>
> -       if (!XRRQueryExtension(dpy, &maj, &min)) /* using min/maj as dummy */
> -       {
> -               fprintf(stderr, "Server does not support RandR");
> -               return;
> -       }
> -
> -       if (!XRRQueryVersion(dpy, &maj, &min) ||
> -           (maj * 1000 + min) < 1002)
> -       {
> -               fprintf(stderr, "Server does not support RandR 1.2");
> -               return;
> -       }
> -
> -
>        res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy));
>
>        for (i = 0; i < res->noutput && !found; i++)
> @@ -2049,6 +2045,7 @@ static void set_output_xrandr(Display *dpy, XDevice 
> *dev, param_t *param, int ar
>        /* crtc holds our screen info, need to compare to actual screen size */
>        if (found)
>        {
> +               TRACE("Setting CRTC %s\n", output_name);
>                _set_matrix(dpy, dev, crtc_info->x, crtc_info->y,
>                            crtc_info->width, crtc_info->height);
>        } else
> @@ -2058,8 +2055,60 @@ static void set_output_xrandr(Display *dpy, XDevice 
> *dev, param_t *param, int ar
>        XRRFreeScreenResources(res);
>  }
>
> +/**
> + * Adjust the transformation matrix based on the Xinerama settings. For
> + * TwinView This would better be done with libXNVCtrl but until they learn
> + * to package it properly, rely on Xinerama. Besides, libXNVCtrl isn't
> + * available on RHEL, so we'd have to do it through Xinerama there anyway.
> + */
> +static void set_output_xinerama(Display *dpy, XDevice *dev, param_t *param, 
> int argc, char **argv)
> +{
> +       int event, error;
> +       XineramaScreenInfo *screens;
> +       int nscreens;
> +       int head;
> +
> +       if (!XineramaQueryExtension(dpy, &event, &error))
> +       {
> +               fprintf(stderr, "Unable to set screen mapping. Xinerama 
> extension not found\n");
> +               return;
> +       }
> +
> +       if (!convert_value_from_user(param, argv[0], &head))
> +       {
> +               fprintf(stderr, "Please specify the output name as HEAD-X,"
> +                               "where X is the screen number\n");
> +               return;
> +       }
> +
> +       screens = XineramaQueryScreens(dpy, &nscreens);
> +
> +       if (nscreens == 0)
> +       {
> +               fprintf(stderr, "Xinerama failed to query screens.\n");
> +               goto out;
> +       } else if (nscreens <= head)
> +       {
> +               fprintf(stderr, "Found %d screens, but you requested %s.\n",
> +                               nscreens, argv[0]);
> +               goto out;
> +       }
> +
> +       TRACE("Setting xinerama head %d\n", head);
> +
> +       _set_matrix(dpy, dev,
> +                   screens[head].x_org, screens[head].y_org,
> +                   screens[head].width, screens[head].height);
> +
> +out:
> +       XFree(screens);
> +}
> +
>  static void set_output(Display *dpy, XDevice *dev, param_t *param, int argc, 
> char **argv)
>  {
> +       int opcode, event, error;
> +       int maj, min;
> +
>        if (argc != param->arg_count)
>        {
>                fprintf(stderr, "'%s' requires exactly %d value(s).\n", 
> param->name,
> @@ -2067,7 +2116,15 @@ static void set_output(Display *dpy, XDevice *dev, 
> param_t *param, int argc, cha
>                return;
>        }
>
> -       set_output_xrandr(dpy, dev, param, argc, argv);
> +       /* Check for RandR 1.2. Server bug causes the NVIDIA driver to
> +        * report with RandR 1.3 support but it doesn't expose RandR CRTCs.
> +        * Force Xinerama if NV-CONTROL is present */
> +       if (XQueryExtension(dpy, "NV-CONTROL", &opcode, &event, &error) ||
> +           !XQueryExtension(dpy, "RANDR", &opcode, &event, &error) ||
> +           !XRRQueryVersion(dpy, &maj, &min) || (maj * 1000 + min) < 1002)
> +               set_output_xinerama(dpy, dev, param, argc, argv);
> +       else
> +               set_output_xrandr(dpy, dev, param, argc, argv);
>  }
>
>
> --
> 1.7.5.4
>
>

Tested-by: Jason Gerecke <killert...@gmail.com>

Jason

---
Day xee-nee-svsh duu-'ushtlh-ts'it;
nuu-wee-ya' duu-xan' 'vm-nvshtlh-ts'it.
Huu-chan xuu naa~-gha.

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to