[PATCH] config: allow device labelling through hal keys.

Peter Hutterer peter.hutterer at who-t.net
Wed Mar 25 21:23:47 PDT 2009


Supports hal keys in the following format:
<append key="input.x11_property.abc" type="strlist">123</append>
<append key="input.x11_property.abc" type="strlist">456</append>
<append key="input.x11_property.foo" type="strlist">bar</append>

The above results in two properties being added to the input device:
  "abc" -> "123", "456"
  "foo" -> "bar"

Where both "abc" and "foo" are properties that contain lists of Atoms (and
123, 456 and bar are Atoms created on-the-fly).

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 config/hal.c |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/config/hal.c b/config/hal.c
index 782fbb5..8156d8b 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -32,15 +32,18 @@
 #include <hal/libhal.h>
 #include <string.h>
 #include <sys/select.h>
+#include <X11/Xatom.h>
 
 #include "input.h"
 #include "inputstr.h"
 #include "hotplug.h"
 #include "config-backends.h"
 #include "os.h"
+#include "exevents.h"
 
 
 #define LIBHAL_OPTIONS_KEY "input.x11_options."
+#define LIBHAL_PROPERTIES_KEY "input.x11_property."
 #define LIBHAL_XKB_OPTIONS_KEY "input.xkb."
 
 
@@ -58,6 +61,12 @@ struct xkb_options {
     char* options;
 };
 
+struct dev_property {
+    struct dev_property *next; /* null-terminated */
+    char *propname;
+    int nitems;
+    char **values;
+};
 
 static void
 remove_device(DeviceIntPtr dev)
@@ -132,6 +141,9 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name)
     return ret;
 }
 
+/**
+ * Get the strlist from HAL and collate into a comma-separated list.
+ */
 static char *
 get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
 {
@@ -166,6 +178,39 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
     return ret;
 }
 
+/**
+ * Duplicate the strlist from hal and return it in strlist_return. Returns the
+ * number of items.
+ * Caller must free the list.
+ */
+static int
+get_prop_strlist(LibHalContext *hal_ctx, const char *udi,
+                 const char *prop, char ***strlist_return)
+{
+    char **props;
+    int i, nitems = 0;
+
+    props = libhal_device_get_property_strlist(hal_ctx, udi, prop, NULL);
+    if (props) {
+        for (i = 0; props[i]; i++)
+            nitems++;
+
+        *strlist_return = xcalloc(nitems, sizeof(char**));
+        if (!*strlist_return) {
+            libhal_free_string_array(props);
+            return 0;
+        }
+
+        for (i = 0; props[i]; i++) {
+            (*strlist_return)[i] = strdup(props[i]);
+        }
+
+    }
+
+    libhal_free_string_array(props);
+    return nitems;
+}
+
 static BOOL
 device_is_duplicate(char *config_info)
 {
@@ -194,6 +239,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
     DeviceIntPtr dev = NULL;
     DBusError error;
     struct xkb_options xkb_opts = {0};
+    struct dev_property *dev_props = NULL;
     int rc;
 
     LibHalPropertySet *set = NULL;
@@ -378,6 +424,26 @@ device_added(LibHalContext *hal_ctx, const char *udi)
                             xkb_opts.options = strdup(tmp_val);
                     }
                 }
+            } else if (!strncasecmp(psi_key, LIBHAL_PROPERTIES_KEY, sizeof(LIBHAL_PROPERTIES_KEY)-1)){
+                char **strlist;
+                int nitems;
+                if ((strlen(psi_key) >= sizeof(LIBHAL_PROPERTIES_KEY)) &&
+                    (nitems = get_prop_strlist(hal_ctx, udi, psi_key, &strlist)))
+                {
+                    struct dev_property *dp;
+
+                    dp = xcalloc (1, sizeof(struct dev_property));
+                    if (dp)
+                    {
+                        dp->propname =
+                            strdup(&psi_key[sizeof(LIBHAL_PROPERTIES_KEY) - 1]);
+
+                        dp->nitems = nitems;
+                        dp->values = strlist;
+                        dp->next = dev_props;
+                        dev_props = dp;
+                    }
+                }
             }
         }
 
@@ -406,6 +472,30 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         goto unwind;
     }
 
+    while(dev_props) {
+        struct dev_property *next  = dev_props->next;
+        int i;
+        Atom *atoms;
+        Atom prop = MakeAtom(dev_props->propname, strlen(dev_props->propname),
+                TRUE);
+
+        atoms = xcalloc(dev_props->nitems, sizeof(Atom));
+
+        for (i = 0; i < dev_props->nitems; i++)
+        {
+            atoms[i] = MakeAtom(dev_props->values[i],
+                                  strlen(dev_props->values[i]), TRUE);
+            xfree(dev_props->values[i]);
+        }
+
+        XIChangeDeviceProperty(dev, prop, XA_ATOM, 32, PropModeReplace,
+                               dev_props->nitems, atoms, FALSE);
+
+        xfree(dev_props->values);
+        xfree(atoms);
+        dev_props = next;
+    }
+
     for (; dev; dev = dev->next){
         if (dev->config_info)
             xfree(dev->config_info);
-- 
1.6.0.6



More information about the xorg mailing list