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