On Wed, Sep 7, 2011 at 9:11 PM, Peter Hutterer <[email protected]> wrote:
> 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.
>
I don't believe there have been any changes. I could always diff the
diffs to be sure, but there weren't any comments on the patch last
time, and it doesn't conflict with any MapToOutput work, so it should
be identical to the v3 version.
>> * 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
>
>
Jason
---
Day xee-nee-svsh duu-'ushtlh-ts'it;
nuu-wee-ya' duu-xan' 'vm-nvshtlh-ts'it.
Huu-chan xuu naa~-gha.
------------------------------------------------------------------------------
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