On Sun, Jun 19, 2011 at 9:01 PM, Peter Hutterer
<peter.hutte...@who-t.net> wrote:
> The NVIDIA binary driver doesn't support RandR 1.2. Test for the NV-CONTROL
> extension and assume the binary driver is running when this extension is
> detected. Then use Xinerama to query the screen offset and set the
> transformation matrix accordingly.
>
> 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>
> ---
>  configure.ac      |    2 +-
>  man/xsetwacom.man |    3 +-
>  tools/xsetwacom.c |   64 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 66 insertions(+), 3 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.

See comment below on expanding syntax to "HEAD-N" (where N can be any
digit from 0 to 9). If you remove the NV-CONTROL restriction, you may
also want to mention the syntax works for any driver exposing info
through Xinerama.

>  .TP
>  \fBMode\fR Absolute|Relative
> diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
> index 1a313df..94c9db2 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(...) \
> @@ -2058,8 +2059,64 @@ static void set_output_xrandr(Display *dpy, XDevice 
> *dev, param_t *param, int ar
>        XRRFreeScreenResources(res);
>  }
>
> +/**
> + * Adjust the transformation matrix based on the twinview settings. 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_twinview(Display *dpy, XDevice *dev, param_t *param, 
> int argc, char **argv)

I'd prefer if this were named e.g. 'set_output_xinerama' since there
is nothing inherently TwinView-related in it.

> +{
> +       char *output_name;
> +       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;
> +       }
> +
> +       output_name = argv[0];
> +       if (strncmp(output_name, "HEAD-", 5) != 0)
> +       {
> +               fprintf(stderr, "Please specify the output name as HEAD-0 or 
> HEAD-1\n");
> +               return;
> +       }
> +
> +       head = output_name[5] - '0';
> +       if (head != 0 && head != 1)
> +       {
> +               fprintf(stderr, "Please specify the output name as HEAD-0 or 
> HEAD-1\n");
> +               return;
> +       }
> +
> +       screens = XineramaQueryScreens(dpy, &nscreens);
> +
> +       if (nscreens == 0)
> +       {
> +               fprintf(stderr, "Xinerama failed to query screens.\n");
> +               goto out;
> +       } else if (nscreens != 2)
> +       {
> +               fprintf(stderr, "Found %d screens, but this command requires 
> exactly 2.\n", nscreens);
> +               goto out;
> +       }

My code uses convert_value_from_user to allow an arbitrary (positive)
integer as a head number. That's definitely overkill, but supporting
up to 10 heads (still probably overkill) would require only a trivial
change to this code and work with the rarer tri- and quad-head setups.

> +
> +       _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;
> +
>        if (argc != param->arg_count)
>        {
>                fprintf(stderr, "'%s' requires exactly %d value(s).\n", 
> param->name,
> @@ -2067,7 +2124,12 @@ static void set_output(Display *dpy, XDevice *dev, 
> param_t *param, int argc, cha
>                return;
>        }
>
> -       set_output_xrandr(dpy, dev, param, argc, argv);
> +       if (XQueryExtension(dpy, "NV-CONTROL", &opcode, &event, &error))
> +       {
> +               TRACE("Nvidia binary driver detected.\n");
> +               set_output_twinview(dpy, dev, param, argc, argv);
> +       } else
> +               set_output_xrandr(dpy, dev, param, argc, argv);
>  }

Why make the Xinerama codepath dependent on the NV-CONTROL extension?
Its a reasonable fallback in a number of circumstances beyond the user
being stuck with the binary nVidia driver. Why not try RandR first,
and if it fails (version too old, output not found, etc) give Xinerama
a shot?

>
>
> --
> 1.7.5.4
>

Jason

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

------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to