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