On Tue, Sep 20, 2011 at 3:54 PM, Jason Gerecke <killert...@gmail.com> wrote:
> Adds an optional "KeepShape" paramater to the MapToOutput command.
> If provided, the Area property is updated to match the aspect ratio
> of the new output. If not provided, the Area property is reset to
> the full tablet dimensions.
>
> This commit causes the MapToOutput command to break existing scripts
> that rely on the Area property for device calibration. It is not
> expected that this will result in actual problems since calibration
> utilities do not currently handle multi-head setups properly anyway.
>
> Signed-off-by: Jason Gerecke <killert...@gmail.com>
> ---
> Changes from v3:
>
>  * Broken out from patch v3 7/7
>  * Handles only the introduction of KeepShape
>  * AspectRatio property does not exist anymore, so we modify the
>   Area property directly.
>
>  man/xsetwacom.man |   21 ++++++-----
>  tools/xsetwacom.c |  104 
> +++++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 113 insertions(+), 12 deletions(-)
>
> diff --git a/man/xsetwacom.man b/man/xsetwacom.man
> index dc0995f..43da602 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]
> -Map the tablet's input area to a given output (e.g. "VGA1"). 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. The mapping may be reset to the entire desktop at any time with the
> -output name "desktop". Users of the NVIDIA binary driver should use the 
> output
> -names "HEAD-0" and "HEAD-1" until the driver supports XRandR 1.2 or later.
> +\fBMapToOutput\fR [output] [KeepShape]
> +Map the tablet's input area to a given output (e.g. "VGA1"). If the 
> "KeepShape"
> +argument is passed in, the the active area of the tablet will be restricted
> +to match the aspect ratio of the output; if unspecified, the entire tablet
> +area will be usable.
> +
> +Outputs may be specified by their XRandR name (users of the NVIDIA binary
> +should use the names "HEAD-0" and "HEAD-1" until the driver supports XRandR
> +1.2 or later). To map the tablet to an arbitrary portion of the desktop, you
> +may provide an X11 geometry string of the form WIDTHxHEIGHT+X+Y. To map to
> +the entire desktop, use "desktop". To cycle through all attached displays and
> +the desktop, use "next".
>
>  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 a3998d2..08fe6b2 100644
> --- a/tools/xsetwacom.c
> +++ b/tools/xsetwacom.c
> @@ -407,7 +407,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,
>        },
>        {
> @@ -2025,6 +2025,90 @@ Bool get_mapped_area(Display *dpy, XDevice *dev, int 
> *width, int *height, int *x
>  }
>
>  /**
> + * Updates device's area property so that it's aspect ratio 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)
> +{
> +       param_t* param = find_parameter("Area");
> +       Atom prop, type;
> +       int format;
> +       unsigned char* data = NULL;
> +       unsigned long nitems, bytes_after;
> +       long *ldata;
> +       int w, h, x_org, y_org;
> +       float width, height, aspect;
> +       Bool success = False;
> +
> +       if (!get_mapped_area(dpy, dev, &w, &h, &x_org, &y_org))
> +       {
> +               fprintf(stderr, "Unable to get the output area.\n");
> +               return success;
> +       }
> +       aspect = (float)w/(float)h;
> +
> +       prop = XInternAtom(dpy, param->prop_name, True);
> +       if (!prop)
> +       {
> +               fprintf(stderr, "Property for '%s' not available.\n",
> +                       param->name);
> +               return success;
> +       }
> +
> +       XGetDeviceProperty(dpy, dev, prop, 0, 1000, False, AnyPropertyType,
> +                               &type, &format, &nitems, &bytes_after, &data);
> +
> +       if (nitems <= param->prop_offset)
> +       {
> +               fprintf(stderr, "Property offset doesn't exist, this is a 
> bug.\n");
> +               goto out;
> +       }
> +
> +       ldata = (long*)data;
> +       ldata[0] = -1;
> +       ldata[1] = -1;
> +       ldata[2] = -1;
> +       ldata[3] = -1;
> +
> +       XChangeDeviceProperty(dpy, dev, prop, type, format,
> +                               PropModeReplace, data, nitems);
> +       XFlush(dpy);
> +
> +       if (do_match)
> +       {
> +               XGetDeviceProperty(dpy, dev, prop, 0, 1000, False, 
> AnyPropertyType,
> +                                       &type, &format, &nitems, 
> &bytes_after, &data);
> +
> +               ldata = (long*)data;
> +               width  = ldata[2] - ldata[0];
> +               height = ldata[3] - ldata[1];
> +
> +               if (width / height > aspect)
> +                       width = height * aspect;
> +               else
> +                       height = width / aspect;
> +
> +               ldata[2] = ldata[0] + width;
> +               ldata[3] = ldata[1] + height;
> +
> +               XChangeDeviceProperty(dpy, dev, prop, type, format,
> +                                       PropModeReplace, data, nitems);
> +               XFlush(dpy);
> +       }
> +
> +       success = True;
> +
> +out:
> +       free(data);
> +
> +       return success;
> +}
> +
> +/**
>  * 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
> @@ -2290,10 +2374,21 @@ static void set_output(Display *dpy, XDevice *dev, 
> param_t *param, int argc, cha
>        unsigned int width, height;
>        int flags = XParseGeometry(argv[0], &x, &y, &width, &height);
>        Bool success = False;
> +       Bool do_match;
>
> -       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;
>        }
> @@ -2313,6 +2408,9 @@ static void set_output(Display *dpy, XDevice *dev, 
> param_t *param, int argc, cha
>
>        if (!success)
>                return;
> +
> +       do_match = argc > 1 && strcasecmp(argv[1], "KeepShape") == 0;
> +       _update_aspect(dpy, dev, do_match);
>  }
>
>
> --
> 1.7.6
>
>

Argh. I'm going to to have to pre-emptively NAK my own patch -- I just
realized I forgot to copy over the bit of code which detects and
handles tablet rotation. I also realized that handling aspect ratio
this way requires that MapToOutput be run after any change to the
tablet rotation... Not sure how I feel about that.

Jason

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

------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2dcopy1
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to