On Wed, Sep 07, 2011 at 04:36:56PM -0700, Jason Gerecke wrote:
> Adds an optional "KeepShape" paramater to the MapToOutput command.
> If provided, the AspectRatio property is updated to match the aspect
> ratio of the new output. If not provided, the AspectRatio property is
> reset to allow full use of the tablet's area.
> 
> Signed-off-by: Jason Gerecke <[email protected]>
> ---
>  Changes from v2:
>   * Corresponds to patch v2 9/9

I take the original AspectRatio patch is still the most current one then?
Sorry, haven't been able to review this earlier.

>   * Boolean "match" argument replaced with the "KeepShape" keyword for
>     more semantic meaning.
> 
>   * Helper functions (finally) modified to return booleans

there's a bit of noise in this patch because of this change. Why not split
this out so that the actual aspect ratio patch is limited to aspect
ratio fetures?

> 
>   * '_set_aspect' renamed to '_update_aspect'
> 
>   * Helper functions no longer take an additional boolean argument;
>     '_update_aspect' should be called manually.
> 
>  man/xsetwacom.man |   19 ++++---
>  tools/xsetwacom.c |  146 +++++++++++++++++++++++++++++++++++++++++-----------
>  2 files changed, 126 insertions(+), 39 deletions(-)
> 
> diff --git a/man/xsetwacom.man b/man/xsetwacom.man
> index edc97c4..d87f24d 100644
> --- a/man/xsetwacom.man
> +++ b/man/xsetwacom.man
> @@ -119,15 +119,18 @@ the device will ignore events from other tools. A 
> serial of 0 means the
>  device is unbound and will react to any tool of the matching type.
>  Default: 0
>  .TP
> -\fBMapToOutput\fR [output]
> +\fBMapToOutput\fR [output] [match_aspect]
>  Map the tablet's input area to the given output (e.g. "VGA1"), or the entire
> -desktop if no output is provided. Output names may either be the name of
> -a head available through the XRandR extension, or an X11 geometry string of
> -the form WIDTHxHEIGHT+X+Y. To switch to the next available output, the "next"
> -keyword is also supported. This will cycle between the individual monitors
> -connected to the system, and then the entire desktop. Users of the NVIDIA
> -binary driver should use the output names "HEAD-0" and "HEAD-1" until proper
> -XRandR support is included.
> +desktop if no output is provided. If the match_aspect option is 'true', the
> +the active area of the tablet will be restricted to match the aspect ratio of
> +the output; if 'false' or unspecified, the entire tablet area will be usable.
> +
> +Output names may either be the name of a head available through the XRandR
> +extension, or an X11 geometry string of the form WIDTHxHEIGHT+X+Y. The
> +relative output "next" will cycle the mapping through all available outputs,
> +including the desktop as a whole. Users of the NVIDIA binary driver should
> +use the output names "HEAD-0" and "HEAD-1" until proper XRandR support is
> +included.
>  
>  The output mapping configuration is a onetime setting and does not track 
> output
>  reconfigurations; the command needs to be re-run whenever the output
> diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
> index 5377c97..d3a237f 100644
> --- a/tools/xsetwacom.c
> +++ b/tools/xsetwacom.c
> @@ -410,7 +410,7 @@ static param_t parameters[] =
>               .name = "MapToOutput",
>               .desc = "Map the device to the given output. ",
>               .set_func = set_output,
> -             .arg_count = 1,
> +             .arg_count = 2,
>               .prop_flags = PROP_FLAG_WRITEONLY | PROP_FLAG_OUTPUT,
>       },
>       {
> @@ -2036,7 +2036,61 @@ Bool get_mapped_area(Display *dpy, XDevice *dev, int 
> *width, int *height, int *x
>       return matrix_is_valid;
>  }
>  
> -static void _set_matrix_prop(Display *dpy, XDevice *dev, const float 
> fmatrix[9])
> +/**
> + * Updates device's aspect ratio property so that it matches that of
> + * the currently defied output area (if 'do_match' is true), or to
> + * allow use of the entire area (if 'do_match' is false). If this
> + * function succeeds in modifying the aspect ratio, it returns 'true'.
> + */
> +static Bool _update_aspect(Display *dpy, XDevice *dev, Bool do_match)
> +{
> +     Atom aspect_prop = XInternAtom(dpy, "Wacom Aspect Ratio", True);
> +     Atom type;
> +     int format;
> +     unsigned long nitems, bytes_after;
> +     char *data = NULL;
> +     int w, h, x_org, y_org;
> +     Bool success = False;
> +
> +     XGetDeviceProperty(dpy, dev, aspect_prop, 0, 2, False,
> +                        AnyPropertyType, &type, &format, &nitems,
> +                        &bytes_after, (unsigned char**)&data);
> +
> +     if (format != 32 || nitems != 2)
> +     {
> +             fprintf(stderr, "Property for '%s' has unexpected type - this 
> is a bug.\n",
> +                     "Wacom Aspect Ratio");

xsetwacom is always built from the tree anyway, we can use the #define for
the property name here.

> +             return success;
> +     }
> +
> +     if (!get_mapped_area(dpy, dev, &w, &h, &x_org, &y_org))
> +             return False;
> +
> +     if (!do_match) {
> +             w = 0;
> +             h = 0;
> +     }
> +
> +     TRACE("Setting aspect ratio of device to %d:%d.\n", w, h);
> +
> +     ((int*)data)[0] = w;
> +     ((int*)data)[1] = h;
> +     XChangeDeviceProperty(dpy, dev, aspect_prop, type, format,
> +                           PropModeReplace, (unsigned char*)data, nitems);
> +
> +     XFlush(dpy);
> +     free(data);
> +
> +     return True;
> +}
> +
> +/**
> + * Modifies the server's transformation matrix property for the given
> + * device. It takes as input a 9-element array of floats interpreted
> + * as the row-major 3x3 matrix to be set. If this function succeeds
> + * in modifying the transformation matrix, it returns 'true'.
> + */
> +static Bool _set_matrix_prop(Display *dpy, XDevice *dev, const float 
> fmatrix[9])
>  {
>       Atom matrix_prop = XInternAtom(dpy, "Coordinate Transformation Matrix", 
> True);
>       Atom type;
> @@ -2049,7 +2103,7 @@ static void _set_matrix_prop(Display *dpy, XDevice 
> *dev, const float fmatrix[9])
>       if (!matrix_prop)
>       {
>               fprintf(stderr, "Server does not support transformation\n");
> -             return;
> +             return False;
>       }
>  
>       /* XI1 expects 32 bit properties (including float) as long,
> @@ -2065,21 +2119,24 @@ static void _set_matrix_prop(Display *dpy, XDevice 
> *dev, const float fmatrix[9])
>       {
>               fprintf(stderr, "Property for '%s' has unexpected type - this 
> is a bug.\n",
>                       "Coordinate Transformation Matrix");
> -             return;
> +             return False;
>       }
>  
>       XChangeDeviceProperty(dpy, dev, matrix_prop, type, format,
>                             PropModeReplace, (unsigned char*)matrix, 9);
>       XFree(data);
>       XFlush(dpy);
> +
> +     return True;
>  }
>  
>  /**
>   * Adjust the transformation matrix based on a user-defined area.
>   * This function will attempt to map the given pointer to an arbitrary
> - * rectangular portion of the desktop.
> + * rectangular portion of the desktop. If this function succeeds in
> + * modifying the transformation matrix, it returns 'true'.
>   */
> -static void set_output_area(Display *dpy, XDevice *dev,
> +static Bool set_output_area(Display *dpy, XDevice *dev,
>                       int offset_x, int offset_y,
>                       int output_width, int output_height)
>  {
> @@ -2110,15 +2167,17 @@ static void set_output_area(Display *dpy, XDevice 
> *dev,
>       TRACE(" [ %f %f %f ]\n", matrix[3], matrix[4], matrix[5]);
>       TRACE(" [ %f %f %f ]\n", matrix[6], matrix[7], matrix[8]);
>  
> -     _set_matrix_prop(dpy, dev, matrix);
> +     return _set_matrix_prop(dpy, dev, matrix);
>  }
>  
> +
>  /**
>   * Adjust the transformation matrix based on RandR settings. This function
>   * will attempt to map the given device to the output with the given RandR
> - * output name.
> + * output name. If this function succeeds in modifying the transformation
> + * matrix, it returns 'true'.
>   */
> -static void set_output_xrandr(Display *dpy, XDevice *dev, char *output_name)
> +static Bool set_output_xrandr(Display *dpy, XDevice *dev, char *output_name)
>  {
>       int i, found = 0;
>       int x, y, width, height;
> @@ -2158,33 +2217,38 @@ static void set_output_xrandr(Display *dpy, XDevice 
> *dev, char *output_name)
>       if (found)
>       {
>               TRACE("Setting CRTC %s\n", output_name);
> -             set_output_area(dpy, dev, x, y, width, height);
> +             return set_output_area(dpy, dev, x, y, width, height);
>       } 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. This
>   * function will attempt to map the given device to the specified Xinerama
> - * head number.
> + * head number. 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, we need to 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, int head)
> +static Bool set_output_xinerama(Display *dpy, XDevice *dev, int head)
>  {
>       int event, error;
>       XineramaScreenInfo *screens;
>       int nscreens;
> +     Bool success = False;
>  
>       if (!XineramaQueryExtension(dpy, &event, &error))
>       {
>               fprintf(stderr, "Unable to set screen mapping. Xinerama 
> extension not found\n");
> -             return;
> +             return success;
>       }
>  
>       screens = XineramaQueryScreens(dpy, &nscreens);
> @@ -2202,12 +2266,13 @@ static void set_output_xinerama(Display *dpy, XDevice 
> *dev, int head)
>  
>       TRACE("Setting xinerama head %d\n", head);
>  
> -     set_output_area(dpy, dev,
> +     success = set_output_area(dpy, dev,
>                   screens[head].x_org, screens[head].y_org,
>                   screens[head].width, screens[head].height);
>  
>  out:
>       XFree(screens);
> +     return success;
>  }
>  
>  /**
> @@ -2215,12 +2280,12 @@ out:
>   * This function will attempt to map the given device to the entire
>   * desktop.
>   */
> -static void set_output_desktop(Display *dpy, XDevice *dev)
> +static Bool set_output_desktop(Display *dpy, XDevice *dev)
>  {
>       int display_width = DisplayWidth(dpy, DefaultScreen(dpy));
>       int display_height = DisplayHeight(dpy, DefaultScreen(dpy));
>  
> -     set_output_area(dpy, dev, 0, 0, display_width, display_height);
> +     return set_output_area(dpy, dev, 0, 0, display_width, display_height);
>  }
>  
>  /**
> @@ -2230,7 +2295,7 @@ static void set_output_desktop(Display *dpy, XDevice 
> *dev)
>   * head, it maps to the first head. If mapped to the last Xinerama
>   * head, it maps to the entire desktop.
>   */
> -static void set_output_next(Display *dpy, XDevice *dev)
> +static Bool set_output_next(Display *dpy, XDevice *dev)
>  {
>       XineramaScreenInfo *screens;
>       int event, error, nscreens, head;
> @@ -2238,12 +2303,12 @@ static void set_output_next(Display *dpy, XDevice 
> *dev)
>       Bool success = False;
>  
>       if (!get_mapped_area(dpy, dev, &width, &height, &x_org, &y_org))
> -             return;
> +             return success;
>  
>       if (!XineramaQueryExtension(dpy, &event, &error))
>       {
>               fprintf(stderr, "Unable to get screen mapping. Xinerama 
> extension not found\n");
> -             return;
> +             return success;
>       }
>  
>       screens = XineramaQueryScreens(dpy, &nscreens);
> @@ -2260,30 +2325,43 @@ static void set_output_next(Display *dpy, XDevice 
> *dev)
>               if (screens[head].width == width && screens[head].height == 
> height &&
>                   screens[head].x_org == x_org && screens[head].y_org  == 
> y_org)
>               {
> -                     success = True;
> -
>                       if (head + 1 < nscreens)
> -                             set_output_xinerama(dpy, dev, head+1);
> +                             success = set_output_xinerama(dpy, dev, head+1);
>                       else
> -                             set_output_desktop(dpy, dev);
> +                             success = set_output_desktop(dpy, dev);
> +
> +                     if (!success)
> +                             goto out;
>               }
>       }
>  
>       if (!success)
> -             set_output_xinerama(dpy, dev, 0);
> +             success = set_output_xinerama(dpy, dev, 0);
>  
>  out:
>       XFree(screens);
> +     return success;
>  }
>  
>  static void set_output(Display *dpy, XDevice *dev, param_t *param, int argc, 
> char **argv)
>  {
>       int tmp_int[2];
>       unsigned int tmp_uint[2];
> +     Bool success = False;
>  
> -     if (argc != param->arg_count)
> +     if (argc == 0)
>       {
> -             fprintf(stderr, "'%s' requires exactly %d value(s).\n", 
> param->name,
> +             fprintf(stderr, "'%s' requires at least one argument.\n", 
> param->name);
> +             return;
> +     }
> +     else if (argc == param->arg_count && strcasecmp(argv[1], "KeepShape") 
> != 0)
> +     {
> +             fprintf(stderr, "'%s' could not understand the provided 
> argument '%s'.\n",
> +                     param->name, argv[1]);
> +     }
> +     else if (argc > param->arg_count)
> +     {
> +             fprintf(stderr, "'%s' accepts no more than %d value(s).\n", 
> param->name,
>                       param->arg_count);
>               return;
>       }
> @@ -2291,28 +2369,34 @@ static void set_output(Display *dpy, XDevice *dev, 
> param_t *param, int argc, cha
>       if (MaskIsSet(XParseGeometry(argv[0], &tmp_int[0], &tmp_int[1], 
> &tmp_uint[0], &tmp_uint[1]),
>           XValue|YValue|WidthValue|HeightValue))
>       {
> -             set_output_area(dpy, dev, tmp_int[0], tmp_int[1], tmp_uint[0], 
> tmp_uint[1]);
> +             success = set_output_area(dpy, dev, tmp_int[0], tmp_int[1], 
> tmp_uint[0], tmp_uint[1]);
>       }
>       else if (strcasecmp(argv[0], "next") == 0)
>       {
> -             set_output_next(dpy, dev);
> +             success = set_output_next(dpy, dev);
>       }
>       else if (strcasecmp(argv[0], "desktop") == 0)
>       {
> -             set_output_desktop(dpy, dev);
> +             success = set_output_desktop(dpy, dev);
>       }
>       else if (!need_xinerama(dpy))
>       {
> -             set_output_xrandr(dpy, dev, argv[0]);
> +             success = set_output_xrandr(dpy, dev, argv[0]);
>       }
>       else if  (convert_value_from_user(param, argv[0], &tmp_int[0]))
>       {
> -             set_output_xinerama(dpy, dev, tmp_int[0]);
> +             success = set_output_xinerama(dpy, dev, tmp_int[0]);
>       }
>       else
>       {
>               fprintf(stderr, "Unable to find an output '%s'.\n", argv[0]);
>       }
> +
> +     if (!success)
> +             return;
> +
> +     Bool do_match = argc > 1 && strcasecmp(argv[1], "KeepShape") == 0;

declarations at the top please.
this seems at odds with the man page, which requires it to be "true".

Cheers,
  Peter

> +     _update_aspect(dpy, dev, do_match);
>  }
>  
>  
> -- 
> 1.7.6
 

------------------------------------------------------------------------------
Doing More with Less: The Next Generation Virtual Desktop 
What are the key obstacles that have prevented many mid-market businesses
from deploying virtual desktops?   How do next-generation virtual desktops
provide companies an easier-to-deploy, easier-to-manage and more affordable
virtual desktop model.http://www.accelacomm.com/jaw/sfnl/114/51426474/
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to