'get_map' is the new getter entrypoint and attempts to determine
the mapping present on buttons, wheels, and strips. It calls on
'get_actions' (essentially get_special_button_map) and 'get_button'
(an 8-bit XA_INTEGER version of the same) to determine this. If
both fail to find a mapping, it falls back to the method originally
used for non-actions: punt and ask XGetDeviceButtonMapping for
something.

When raw buttons are removed from the driver, it should be possible
to replace 'get_map' with 'get_actions' (since everything will be
an action at that point).

Signed-off-by: Jason Gerecke <killert...@gmail.com>
---
 Changes since v1:
  * Use strcmp instead of ==
  * Change comment style

 tools/xsetwacom.c |  188 +++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 140 insertions(+), 48 deletions(-)

diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
index 18155aa..41e4ced 100644
--- a/tools/xsetwacom.c
+++ b/tools/xsetwacom.c
@@ -101,7 +101,7 @@ typedef struct _param
 static void map_actions(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
 static void set_mode(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
 static void get_mode(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
-static void get_button(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
+static void get_map(Display *dpy, XDevice *dev, param_t *param, int argc, char 
**argv);
 static void set_rotate(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
 static void get_rotate(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
 static void set_xydefault(Display *dpy, XDevice *dev, param_t *param, int 
argc, char **argv);
@@ -127,7 +127,7 @@ static param_t parameters[] =
                .desc = "X11 event to which the given button should be mapped. 
",
                .prop_name = WACOM_PROP_BUTTON_ACTIONS,
                .set_func = map_actions,
-               .get_func = get_button,
+               .get_func = get_map,
        },
        {
                .name = "ToolDebugLevel",
@@ -259,6 +259,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 0,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "RelWheelDown",
@@ -267,6 +268,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 1,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "AbsWheelUp",
@@ -275,6 +277,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 2,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "AbsWheelDown",
@@ -283,6 +286,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 3,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "StripLeftUp",
@@ -291,6 +295,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 0,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "StripLeftDown",
@@ -299,6 +304,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 1,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "StripRightUp",
@@ -307,6 +313,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 2,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "StripRightDown",
@@ -315,6 +322,7 @@ static param_t parameters[] =
                .prop_format = 8,
                .prop_offset = 3,
                .set_func = map_actions,
+               .get_func = get_map,
        },
        {
                .name = "Threshold",
@@ -1691,50 +1699,57 @@ static void get_rotate(Display *dpy, XDevice *dev, 
param_t* param, int argc, cha
        return;
 }
 
-static int get_special_button_map(Display *dpy, XDevice *dev,
-                                 param_t *param, int btn_no)
+/**
+ * Try to print the value of the action mapped to the given parameter's
+ * property. If the property contains data in the wrong format/type then
+ * nothing will be printed.
+ *
+ * @param dpy    X11 display to connect to
+ * @param dev    Device to query
+ * @param param  Info about parameter to query
+ * @param offset Offset into property specified in param
+ * @return       0 on failure, 1 otherwise
+ */
+static int get_actions(Display *dpy, XDevice *dev,
+                                 param_t *param, int offset)
 {
-       Atom btnact_prop, action_prop;
-       unsigned long *btnact_data;
-       Atom type;
+       Atom prop, type;
        int format;
-       unsigned long btnact_nitems, bytes_after;
+       unsigned long nitems, bytes_after, *data;
        int i;
        char buff[1024] = {0};
 
-       btnact_prop = XInternAtom(dpy, WACOM_PROP_BUTTON_ACTIONS, True);
+       prop = XInternAtom(dpy, param->prop_name, True);
 
-       if (!btnact_prop)
+       if (!prop)
                return 0;
 
-       XGetDeviceProperty(dpy, dev, btnact_prop, 0, 100, False,
-                          AnyPropertyType, &type, &format, &btnact_nitems,
-                          &bytes_after, (unsigned char**)&btnact_data);
+       XGetDeviceProperty(dpy, dev, prop, 0, 100, False,
+                          AnyPropertyType, &type, &format, &nitems,
+                          &bytes_after, (unsigned char**)&data);
 
-       /* button numbers start at 1, property is zero-indexed */
-       if (btn_no >= btnact_nitems)
+       if (offset >= nitems)
+       {
+               XFree(data);
                return 0;
+       }
 
-       /* FIXME: doesn't cover wheels/strips at the moment, they can be 8
-        * bits (plain buttons) or 32 bits (complex actions) */
+       prop = data[offset];
+       XFree(data);
 
-       action_prop = btnact_data[btn_no - 1];
-       if (!action_prop)
+       if (format != 32 || type != XA_ATOM || !prop)
+       {
                return 0;
+       }
 
-       XFree(btnact_data);
+       XGetDeviceProperty(dpy, dev, prop, 0, 100, False,
+                  AnyPropertyType, &type, &format, &nitems,
+                  &bytes_after, (unsigned char**)&data);
 
-       XGetDeviceProperty(dpy, dev, action_prop, 0, 100, False,
-                          AnyPropertyType, &type, &format, &btnact_nitems,
-                          &bytes_after, (unsigned char**)&btnact_data);
-
-       if (format != 32 && type != XA_ATOM)
-               return 0;
-
-       for (i = 0; i < btnact_nitems; i++)
+       for (i = 0; i < nitems; i++)
        {
                static int last_type, last_press;
-               unsigned long action = btnact_data[i];
+               unsigned long action = data[i];
                int current_type;
                int detail;
                int is_press = -1;
@@ -1782,41 +1797,118 @@ static int get_special_button_map(Display *dpy, 
XDevice *dev,
 
        TRACE("%s\n", buff);
 
-       XFree(btnact_data);
+       XFree(data);
 
        print_value(param, "%s", buff);
 
        return 1;
 }
 
-static void get_button(Display *dpy, XDevice *dev, param_t *param, int argc,
-                       char **argv)
+/**
+ * Try to print the value of the raw button mapped to the given parameter's
+ * property. If the property contains data in the wrong format/type then
+ * nothing will be printed.
+ *
+ * @param dpy    X11 display to connect to
+ * @param dev    Device to query
+ * @param param  Info about parameter to query
+ * @param offset Offset into the property specified in param
+ * @return       0 on failure, 1 otherwise
+ */
+static int get_button(Display *dpy, XDevice *dev, param_t *param, int offset)
 {
-       int nmap = 256;
-       unsigned char map[nmap];
-       int button = 0;
+       Atom prop, type;
+       int format;
+       unsigned long nitems, bytes_after;
+       unsigned char *data;
 
-       if (argc < 1 || (sscanf(argv[0], "%d", &button) != 1))
-               return;
+       prop = XInternAtom(dpy, param->prop_name, True);
+
+       if (!prop)
+               return 0;
+
+       XGetDeviceProperty(dpy, dev, prop, 0, 100, False,
+                          AnyPropertyType, &type, &format, &nitems,
+                          &bytes_after, (unsigned char**)&data);
+
+       if (offset >= nitems)
+       {
+               XFree(data);
+               return 0;
+       }
+
+       prop = data[offset];
+       XFree(data);
+
+       if (format != 8 || type != XA_INTEGER || !prop)
+       {
+               return 0;
+       }
+
+       print_value(param, "%d", prop);
+
+       return 1;
+}
+
+/**
+ * Print the current button/wheel/strip mapping, be it a raw button or
+ * an action. Button map requests require the button number as the first
+ * argument in argv.
+ *
+ * @param dpy   X11 display to connect to
+ * @param dev   Device to query
+ * @param param Info about parameter to query
+ * @param argc  Length of argv
+ * @param argv  Command-line arguments
+ */
+static void get_map(Display *dpy, XDevice *dev, param_t *param, int argc, 
char** argv)
+{
+       int offset = param->prop_offset;
 
        TRACE("Getting button map for device %ld.\n", dev->device_id);
 
-       /* if there's a special map, print it and return */
-       if (get_special_button_map(dpy, dev, param, button))
-               return;
+       if (strcmp(param->prop_name, WACOM_PROP_BUTTON_ACTIONS) == 0)
+       {
+               if (argc == 0)
+               {
+                       fprintf(stderr, "Too few arguments provided.\n");
+                       return;
+               }
 
-       nmap = XGetDeviceButtonMapping(dpy, dev, map, nmap);
+               if (sscanf(argv[0], "%d", &offset) != 1)
+               {
+                       fprintf(stderr, "'%s' is not a valid button number.\n", 
argv[0]);
+                       return;
+               }
 
-       if (button > nmap)
-       {
-               fprintf(stderr, "Button number does not exist on device.\n");
-               return;
+               offset--;        /* Property is 0-indexed, X buttons are 
1-indexed */
+               argc--;          /* Trim off the target button argument */
+               argv = &argv[1]; /*... ditto ...                        */
        }
 
-       print_value(param, "%d", map[button - 1]);
 
-       XSetDeviceButtonMapping(dpy, dev, map, nmap);
-       XFlush(dpy);
+       if (get_actions(dpy, dev, param, offset))
+               return;
+       else if (get_button(dpy, dev, param, offset))
+               return;
+       else
+       {
+               int nmap = 256;
+               unsigned char map[nmap];
+
+               nmap = XGetDeviceButtonMapping(dpy, dev, map, nmap);
+
+               if (offset >= nmap)
+               {
+                       fprintf(stderr, "Button number does not exist on 
device.\n");
+                       return;
+               }
+
+               print_value(param, "%d", map[offset]);
+
+               XSetDeviceButtonMapping(dpy, dev, map, nmap);
+               XFlush(dpy);
+       }
 }
 
 static void _set_matrix_prop(Display *dpy, XDevice *dev, const float 
fmatrix[9])
-- 
1.7.4.1


------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to