Instead of having 'set_output' be responsible for choosing an
appropriate helper function, we let the helper functions be
autonomous. If they cannot find an appropriate output (or
encounter an error), they simply return False to let the
caller know that it failed.
---
Changes from v1:
 * Don't allow Xinerama to work if RandR looks like it would
 * Add documentation to the functions I touched

 tools/xsetwacom.c |   77 ++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 58 insertions(+), 19 deletions(-)

diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
index dd0a3e5..ffb2875 100644
--- a/tools/xsetwacom.c
+++ b/tools/xsetwacom.c
@@ -2003,8 +2003,15 @@ static void _set_matrix(Display *dpy, XDevice *dev,
        _set_matrix_prop(dpy, dev, matrix);
 }
 
-static void set_output_xrandr(Display *dpy, XDevice *dev, param_t *param, int 
argc, char **argv)
+/**
+ * Adjust the transformation matrix based on RandR settings. This function
+ * will attempt to map the given device to the output named in the first
+ * command-line argument. If the function succeeds, it returns 'true'.
+ */
+static Bool set_output_xrandr(Display *dpy, XDevice *dev, param_t *param, int 
argc, char **argv)
 {
+       int opcode, event, error;
+       int maj, min;
        int i, found = 0;
        int x, y, width, height;
        char *output_name;
@@ -2012,6 +2019,21 @@ static void set_output_xrandr(Display *dpy, XDevice 
*dev, param_t *param, int ar
        XRROutputInfo *output_info;
        XRRCrtcInfo *crtc_info;
 
+       if (!XQueryExtension(dpy, "RANDR", &opcode, &event, &error) ||
+           !XRRQueryVersion(dpy, &maj, &min) || (maj * 1000 + min) < 1002 ||
+           XQueryExtension(dpy, "NV-CONTROL", &opcode, &event, &error))
+       {
+               /* RandR not present or earlier than version 1.2
+                *
+                * Server bug causes the NVIDIA driver to report RandR 1.3
+                * support but it doesn't expose RandR CRTCs; ignore if
+                * this is the case.
+                */
+               TRACE("RandR extension not found, too old, or NV-CONTROL "
+                       "extension is also present.\n");
+               return False;
+       }
+
        output_name = argv[0];
 
        res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy));
@@ -2048,36 +2070,60 @@ static void set_output_xrandr(Display *dpy, XDevice 
*dev, param_t *param, int ar
                TRACE("Setting CRTC %s\n", output_name);
                _set_matrix(dpy, dev, crtc_info->x, crtc_info->y,
                            crtc_info->width, crtc_info->height);
+
+               return True;
        } else
+       {
                printf("Unable to find output '%s'. "
                        "Output may not be connected.\n", output_name);
 
+               return False;
+       }
 }
 
 /**
- * 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
+ * Adjust the transformation matrix based on the Xinerama settings. This
+ * function will attempt to map the given pointer to the Xinerama head
+ * (which should be formatted as 'HEAD-N') specified in the first command-
+ * line argument. If this function succeeds in modifying the transformation
+ * matrix, it returns 'true'.
+ *
+ * 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)
+static Bool set_output_xinerama(Display *dpy, XDevice *dev, param_t *param, 
int argc, char **argv)
 {
-       int event, error;
+       int opcode, event, error;
+       int maj, min;
        XineramaScreenInfo *screens;
        int nscreens;
        int head;
+       Bool success = False;
+
+       if (XQueryExtension(dpy, "RANDR", &opcode, &event, &error) &&
+           XRRQueryVersion(dpy, &maj, &min) && (maj * 1000 + min) >= 1002 &&
+           !XQueryExtension(dpy, "NV-CONTROL", &opcode, &event, &error))
+       {
+               /* You have a new enough version of RandR, and aren't
+                * subject to the NVIDIA driver bug mentioned in
+                * set_output_randr.
+                */
+               TRACE("Working version of RandR present. Xinerama disabled.\n");
+               return False;
+       }
 
        if (!XineramaQueryExtension(dpy, &event, &error))
        {
                fprintf(stderr, "Unable to set screen mapping. Xinerama 
extension not found\n");
-               return;
+               return False;
        }
 
        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;
+               return False;
        }
 
        screens = XineramaQueryScreens(dpy, &nscreens);
@@ -2099,15 +2145,15 @@ static void set_output_xinerama(Display *dpy, XDevice 
*dev, param_t *param, int
                    screens[head].x_org, screens[head].y_org,
                    screens[head].width, screens[head].height);
 
+       success = True;
+
 out:
        XFree(screens);
+       return success;
 }
 
 static void set_output(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv)
 {
-       int opcode, event, error;
-       int maj, min;
-
        if (argc == 0)
        {
                float matrix[9] = { 1, 0, 0,
@@ -2123,14 +2169,7 @@ static void set_output(Display *dpy, XDevice *dev, 
param_t *param, int argc, cha
                return;
        }
 
-       /* 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
+       if (!set_output_xinerama(dpy, dev, param, argc, argv))
                set_output_xrandr(dpy, dev, param, argc, argv);
 }
 
-- 
1.7.6


------------------------------------------------------------------------------
Get a FREE DOWNLOAD! and learn more about uberSVN rich system, 
user administration capabilities and model configuration. Take 
the hassle out of deploying and managing Subversion and the 
tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to