[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