Between the parsing code seperating the two halves of set/unset and the code being confusing in general, I've rewritten this to hopefully make its operation a little clearer for the next person.
Signed-off-by: Jason Gerecke <killert...@gmail.com> --- Changes: * Broke parsing code out into its own function. Might as well go whole-hog for readability. tools/xsetwacom.c | 159 ++++++++++++++++++++++++++++++++++------------------ 1 files changed, 104 insertions(+), 55 deletions(-) diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c index 70331b5..9860e57 100644 --- a/tools/xsetwacom.c +++ b/tools/xsetwacom.c @@ -1115,59 +1115,30 @@ static int convert_wheel_prop(Display *dpy, XDevice *dev, Atom btnact_prop) return 0; } - -static void special_map_property(Display *dpy, XDevice *dev, Atom btnact_prop, int offset, int argc, char **argv) +/** + * This function parses the given strings to produce a list of actions that + * the driver can carry out. We first combine the strings and then split + * on spaces to produce a wordlist. Begining with the first word, we let each + * registered keyword parser try to parse the string; if one succeeds in + * parsing a portion, we jump ahead to the first word it could not parse + * and repeat the process. Each parser builds up the list of actions with + * those commands it can interpret. + * + * @param dpy X11 display to query + * @param argc Length of argv + * @param argv String data to be parsed + * @param data Parsed action data + * @return 'true' if the whole string was parsed sucessfully, else 'false' + */ +static Bool parse_actions(Display *dpy, int argc, char **argv, unsigned long* data, unsigned long *nitems) { - unsigned long *data, *btnact_data; - Atom type, prop = 0; - int format; - unsigned long btnact_nitems, nitems, bytes_after; - int i; - int nwords = 0; + int i; + int nwords = 0; char **words = NULL; - XGetDeviceProperty(dpy, dev, btnact_prop, 0, 100, False, - AnyPropertyType, &type, &format, &btnact_nitems, - &bytes_after, (unsigned char**)&btnact_data); - - if (offset > btnact_nitems) - return; - - /* Prop is currently 8 bit integer, i.e. plain button - * mappings. Convert to 32 bit Atom actions first. - */ - if (format == 8 && type == XA_INTEGER) - { - if (convert_wheel_prop(dpy, dev, btnact_prop)) - return; - - XGetDeviceProperty(dpy, dev, btnact_prop, 0, 100, False, - AnyPropertyType, &type, &format, - &btnact_nitems, &bytes_after, - (unsigned char**)&btnact_data); - } - - if (argc == 0) /* unset property */ - { - prop = btnact_data[offset]; - btnact_data[offset] = 0; - } else if (btnact_data[offset]) - /* some atom already assigned, modify that */ - prop = btnact_data[offset]; - else - { - char buff[64]; - sprintf(buff, "Wacom button action %d", (offset + 1)); - prop = XInternAtom(dpy, buff, False); - - btnact_data[offset] = prop; - } - - data = calloc(sizeof(long), 256); - nitems = 0; - /* translate cmdline commands */ words = strjoinsplit(argc, argv, &nwords); + for (i = 0; i < nwords; i++) { int j = 0; @@ -1180,7 +1151,7 @@ static void special_map_property(Display *dpy, XDevice *dev, Atom btnact_prop, i { parsed = keywords[j].func(dpy, nwords - i - 1, &words[i + 1], - &nitems, data); + nitems, data); i += parsed; keyword_found = 1; } @@ -1193,22 +1164,100 @@ static void special_map_property(Display *dpy, XDevice *dev, Atom btnact_prop, i if (!keyword_found) { fprintf(stderr, "Cannot parse keyword '%s' at position %d\n", words[i], i+1); - return; + return False; } } + free(words); + + return True; +} + +/** + * Maps sub-properties (e.g. the 3rd button in WACOM_PROP_BUTTON_ACTIONS) + * to actions. This function leverages the several available parsing + * functions to convert plain-text descriptions into a list of actions + * the driver can understand. + * + * Once we have a list of actions, we can store it in the appropriate + * child property. If none exists, we must first create one and update + * the parent list. If we want no action to occur, we can delete the + * child property and have the parent point to '0' instead. + * + * @param dpy X display we want to query + * @param dev X device we want to modify + * @param btnact_prop Parent property + * @param offset Offset into the parent's list of child properties + * @param argc Number of command line arguments we've been passed + * @param argv Command line arguments we need to parse + */ +static void special_map_property(Display *dpy, XDevice *dev, Atom btnact_prop, int offset, int argc, char **argv) +{ + unsigned long *data, *btnact_data; + Atom type, prop = 0; + int format; + unsigned long btnact_nitems, bytes_after; + unsigned long nitems = 0; + + data = calloc(sizeof(long), 256); + if (!parse_actions(dpy, argc, argv, data, &nitems)) + return; + + /* obtain the button actions Atom */ + XGetDeviceProperty(dpy, dev, btnact_prop, 0, 100, False, + AnyPropertyType, &type, &format, &btnact_nitems, + &bytes_after, (unsigned char**)&btnact_data); + + if (offset > btnact_nitems) + return; + + if (format == 8 && type == XA_INTEGER) + { + /* Prop is currently 8 bit integer, i.e. plain button + * mappings. Convert to 32 bit Atom actions first. + */ + if (convert_wheel_prop(dpy, dev, btnact_prop)) + return; + + XGetDeviceProperty(dpy, dev, btnact_prop, 0, 100, False, + AnyPropertyType, &type, &format, + &btnact_nitems, &bytes_after, + (unsigned char**)&btnact_data); + } + + /* set or unset the property */ + prop = btnact_data[offset]; if (nitems > 0) + { //Setting a new or existing property + if (!prop) + { + char buff[64]; + sprintf(buff, "Wacom button action %d", (offset + 1)); + prop = XInternAtom(dpy, buff, False); + btnact_data[offset] = prop; + + XChangeDeviceProperty(dpy, dev, btnact_prop, XA_ATOM, 32, + PropModeReplace, + (unsigned char*)btnact_data, + btnact_nitems); + } + + XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, 32, PropModeReplace, (unsigned char*)data, nitems); + } + else if (prop) + { //Unsetting a property that exists + btnact_data[offset] = 0; - XChangeDeviceProperty(dpy, dev, btnact_prop, XA_ATOM, 32, - PropModeReplace, - (unsigned char*)btnact_data, - btnact_nitems); + XChangeDeviceProperty(dpy, dev, btnact_prop, XA_ATOM, 32, + PropModeReplace, + (unsigned char*)btnact_data, + btnact_nitems); - if (argc == 0 && prop) XDeleteDeviceProperty(dpy, dev, prop); + } XFlush(dpy); } -- 1.7.4.1 ------------------------------------------------------------------------------ Enable your software for Intel(R) Active Management Technology to meet the growing manageability and security demands of your customers. Businesses are taking advantage of Intel(R) vPro (TM) technology - will your software be a part of the solution? Download the Intel(R) Manageability Checker today! http://p.sf.net/sfu/intel-dev2devmar _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel