HAL input support with 2.6.23 kernel series

Ben Gamari ben at mw0.ath.cx
Sun Sep 30 17:23:06 PDT 2007


Hey All,

It seems that kernel input team has broken input support in hal by
changing the structure of sysfs. As of
2.6.23-rc8, /sys/class/input/event%d/device/capabilities no longer
existed, meaning that hal can no longer identify input devices. While I
did hack up a patch to use the /sys/class/input/event%
d/device/input:input%d/capabilities file instead, it is far from an
elegant solution, but it nevertheless works.

One issue I could foresee is the possibility of multiple
device/input:input%d links (which apparently the input team is
anticipating considering they numbered the entry). Should someone talk
to the input team about this? Anyways, I hope this has somewhat helped.
Thanks,

- Ben

The Patch for reference (I doubt it's merge-worthy, whitespace cleanup
needed at very least):


diff --git a/hald/linux/device.c b/hald/linux/device.c
index 5b44108..02defa4 100644
--- a/hald/linux/device.c
+++ b/hald/linux/device.c
@@ -282,11 +282,12 @@ input_add (const gchar *sysfs_path, const gchar
*device_file, HalDevice *parent_
 {
        int eventdev_num;
        HalDevice *d;
-        char *attr_sysfs_path;
+  char *attr_sysfs_path;
         
-        d = NULL;
-        attr_sysfs_path = NULL;
-
+  d = NULL;
+  attr_sysfs_path = NULL;
+       HAL_INFO (("input_add: sysfs_path: %s, dvice_file: %s\n",
sysfs_path,
device_file));
+       
        if (device_file == NULL || device_file[0] == '\0')
                goto out;
 
@@ -294,24 +295,49 @@ input_add (const gchar *sysfs_path, const gchar
*device_file, HalDevice *parent_
        if (sscanf (hal_util_get_last_element (sysfs_path), "event%d",
&eventdev_num) != 1)
                goto out;
         
-        /* Prior to 2.6.23pre event%d was a child of input%d - after
that event%d
-         * moved to the same level with a device/ symlink... Handle
both cases
-         */
-        attr_sysfs_path = g_strdup_printf ("%s/../capabilities",
sysfs_path);
-        if (g_file_test (attr_sysfs_path, G_FILE_TEST_EXISTS |
G_FILE_TEST_IS_DIR)) {
-                g_free (attr_sysfs_path);
-                attr_sysfs_path = g_strdup_printf ("%s/../",
sysfs_path);
-        } else {
-                g_free (attr_sysfs_path);
-                attr_sysfs_path = g_strdup_printf ("%
s/device/capabilities", sysfs_path);
-                if (g_file_test (attr_sysfs_path, G_FILE_TEST_EXISTS |
G_FILE_TEST_IS_DIR)) {
-                        g_free (attr_sysfs_path);
-                        attr_sysfs_path = g_strdup_printf ("%
s/device/", sysfs_path);
-                } else {
-                        goto out;
-                }
+  /* Prior to 2.6.23pre event%d was a child of input%d - after that
event%d
+   * moved to the same level with a device/ symlink... Handle both
cases
+   */
+  attr_sysfs_path = g_strdup_printf ("%s/../capabilities", sysfs_path);
+  if (g_file_test (attr_sysfs_path, G_FILE_TEST_EXISTS |
G_FILE_TEST_IS_DIR)) {
+    g_free (attr_sysfs_path);
+    attr_sysfs_path = g_strdup_printf ("%s/../", sysfs_path);
+  } else {
+    g_free (attr_sysfs_path);
+    attr_sysfs_path = g_strdup_printf ("%s/device/capabilities",
sysfs_path);
+    if (g_file_test (attr_sysfs_path, G_FILE_TEST_EXISTS |
G_FILE_TEST_IS_DIR)) {
+      g_free (attr_sysfs_path);
+      attr_sysfs_path = g_strdup_printf ("%s/device/", sysfs_path);
+    } else {
+      GDir* dir;
+      gchar* input_dir = NULL;
+      
+      g_free (attr_sysfs_path);
+      attr_sysfs_path = g_strdup_printf ("%s/device/", sysfs_path);
+      dir = g_dir_open(attr_sysfs_path, 0, NULL);
+      g_free (attr_sysfs_path);
+      if (dir) {
+        for (input_dir = g_dir_read_name(dir); input_dir != NULL;
input_dir = g_dir_read_name(dir)) {
+          #define INPUT_PREFIX "input:input"
+          HAL_INFO (("dir: %s, %d", input_dir, strncmp(INPUT_PREFIX,
input_dir, strlen(INPUT_PREFIX)) ));
+
+          if (strncmp(INPUT_PREFIX, input_dir, strlen(INPUT_PREFIX)) ==
0)
+            break;
         }
-
+      }
+      attr_sysfs_path = g_strdup_printf("%s/device/%s/capabilities",
sysfs_path, input_dir);
+      if (g_file_test (attr_sysfs_path, G_FILE_TEST_EXISTS |
G_FILE_TEST_IS_DIR)) {
+        HAL_INFO (("input_add: found"));
+        g_free (attr_sysfs_path);
+        attr_sysfs_path = g_strdup_printf("%s/device/%s/", sysfs_path,
input_dir);
+      } else {
+                         HAL_INFO (("Couldn't find input device
capabilities for %s",
device_file));
+        goto out;
+      }
+    }
+  }
+       
+       HAL_INFO (("input_add: creating device"));
        d = hal_device_new ();
        hal_device_property_set_string (d, "linux.sysfs_path",
sysfs_path);
        if (parent_dev != NULL) {





More information about the hal mailing list