[gimp] Bug 592364 - Use GUdev rather than deprecated HAL for GIMP



commit f1bb40166b1061f630fab615f658310c25abf423
Author: Michael Natterer <mitch gimp org>
Date:   Thu Jun 23 16:30:58 2011 +0200

    Bug 592364 - Use GUdev rather than deprecated HAL for GIMP
    
    GIMP was probably the only user of libhal on most systems, this had
    to stop. Ported the linux-input module to GUdev.

 configure.ac                                       |   30 ++--
 modules/Makefile.am                                |    6 +-
 modules/controller-linux-input.c                   |    8 +-
 ...icestore-hal.c => gimpinputdevicestore-gudev.c} |  266 +++++++++-----------
 4 files changed, 142 insertions(+), 168 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1297e0c..f4c1457 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,7 +58,7 @@ m4_define([pygtk_required_version], [2.10.4])
 m4_define([poppler_required_version], [0.12.4])
 m4_define([libcurl_required_version], [7.15.1])
 m4_define([dbus_glib_required_version], [0.70])
-m4_define([libhal_required_version], [0.5.7])
+m4_define([libgudev_required_version], [167])
 m4_define([exif_required_version], [0.6.15])
 m4_define([lcms_required_version], [1.16])
 m4_define([libpng_required_version], [1.2.37])
@@ -1623,27 +1623,27 @@ if test "x$have_dbus_glib" = xyes; then
 fi
 
 
-###############################################
-# Check for libhal (Hardware Abstraction Layer)
-###############################################
+####################
+# Check for libgudev
+####################
 
-AC_ARG_WITH(hal,   [  --without-hal           build without HAL support])
+AC_ARG_WITH(gudev, [  --without-gudev        build without GUdev support])
 
-have_libhal=no
+have_libgudev=no
 
-if test "x$with_hal" = xno; then
-  have_libhal="no (disabled)"
+if test "x$with_gudev" = xno; then
+  have_libgudev="no (disabled)"
 fi
 
 if test "x$have_linux_input" = xyes && test "x$have_dbus_glib" = xyes &&
-   test "x$with_hal" != xno; then
-  PKG_CHECK_MODULES(HAL, hal >= libhal_required_version,
-    have_libhal=yes,
-    have_libhal="no (libhal not found)")
+   test "x$with_gudev" != xno; then
+  PKG_CHECK_MODULES(GUDEV, gudev-1.0 >= libgudev_required_version,
+    have_libgudev=yes,
+    have_libgudev="no (libgudev not found)")
 fi
 
-if test "x$have_libhal" = xyes; then
-  AC_DEFINE(HAVE_LIBHAL, 1, [Define to 1 if libhal is available])
+if test "x$have_libgudev" = xyes; then
+  AC_DEFINE(HAVE_LIBGUDEV, 1, [Define to 1 if libgudev is available])
 fi
 
 
@@ -2304,7 +2304,7 @@ Plug-In Features:
 
 Optional Modules:
   ALSA (MIDI Input):   $have_alsa
-  Linux Input:         $have_linux_input (HAL support: $have_libhal)
+  Linux Input:         $have_linux_input (GUdev support: $have_libgudev)
   DirectInput (Win32): $have_dx_dinput
   Color Correction:    $have_lcms
   Soft Proof:          $have_lcms
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 4dfced7..ab476a3 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -104,13 +104,13 @@ libdisplay_filter_proof_la_LDFLAGS = -avoid-version -module $(no_undefined)
 libdisplay_filter_proof_la_LIBADD = $(display_filter_libadd) $(LCMS_LIBS)
 
 libcontroller_linux_input_la_SOURCES = \
-	gimpinputdevicestore-hal.c	\
+	gimpinputdevicestore-gudev.c	\
 	gimpinputdevicestore.h		\
 	controller-linux-input.c
-libcontroller_linux_input_la_CFLAGS = $(DBUS_GLIB_CFLAGS) $(HAL_CFLAGS)
+libcontroller_linux_input_la_CFLAGS = $(GUDEV_CFLAGS)
 libcontroller_linux_input_la_LDFLAGS = -avoid-version -module $(no_undefined)
 libcontroller_linux_input_la_LIBADD = \
-	$(controller_libadd) $(DBUS_GLIB_LIBS) $(HAL_LIBS)
+	$(controller_libadd) $(GUDEV_LIBS)
 
 libcontroller_dx_dinput_la_SOURCES = \
 	gimpinputdevicestore-dx.c	\
diff --git a/modules/controller-linux-input.c b/modules/controller-linux-input.c
index b7f69e0..fe3f5e8 100644
--- a/modules/controller-linux-input.c
+++ b/modules/controller-linux-input.c
@@ -218,7 +218,7 @@ controller_linux_input_class_init (ControllerLinuxInputClass *klass)
                                                         _("The name of the device to read Linux Input events from."),
                                                         NULL,
                                                         GIMP_CONFIG_PARAM_FLAGS));
-#ifdef HAVE_LIBHAL
+#ifdef HAVE_LIBGUDEV
   g_object_class_install_property (object_class, PROP_DEVICE_STORE,
                                    g_param_spec_object ("device-values",
                                                         NULL, NULL,
@@ -480,11 +480,11 @@ linux_input_get_device_info (ControllerLinuxInput *controller,
 
 static void
 linux_input_device_changed (ControllerLinuxInput *controller,
-                            const gchar          *udi)
+                            const gchar          *identifier)
 {
-  if (controller->device && strcmp (udi, controller->device) == 0)
+  if (controller->device && strcmp (identifier, controller->device) == 0)
     {
-      linux_input_set_device (controller, udi);
+      linux_input_set_device (controller, identifier);
       g_object_notify (G_OBJECT (controller), "device");
     }
 }
diff --git a/modules/gimpinputdevicestore-hal.c b/modules/gimpinputdevicestore-gudev.c
similarity index 53%
rename from modules/gimpinputdevicestore-hal.c
rename to modules/gimpinputdevicestore-gudev.c
index 06770dd..4c703bc 100644
--- a/modules/gimpinputdevicestore-hal.c
+++ b/modules/gimpinputdevicestore-gudev.c
@@ -1,9 +1,10 @@
 /* GIMP - The GNU Image Manipulation Program
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
- * gimpinputdevicestore-hal.c
- * Input device store based on HAL, the hardware abstraction layer.
+ * gimpinputdevicestore-gudev.c
+ * Input device store based on GUdev, the hardware abstraction layer.
  * Copyright (C) 2007  Sven Neumann <sven gimp org>
+ *               2011  Michael Natterer <mitch gimp org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,16 +31,15 @@
 #include "libgimpmodule/gimpmodule.h"
 
 
-#ifdef HAVE_LIBHAL
+#ifdef HAVE_LIBGUDEV
 
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <hal/libhal.h>
+#include <gudev/gudev.h>
 
 enum
 {
-  COLUMN_UDI,
+  COLUMN_IDENTIFIER,
   COLUMN_LABEL,
+  COLUMN_DEVICE_FILE,
   NUM_COLUMNS
 };
 
@@ -60,10 +60,10 @@ typedef struct _GimpInputDeviceStoreClass GimpInputDeviceStoreClass;
 
 struct _GimpInputDeviceStore
 {
-  GtkListStore    parent_instance;
+  GtkListStore  parent_instance;
 
-  LibHalContext  *context;
-  GError         *error;
+  GUdevClient  *client;
+  GError       *error;
 };
 
 
@@ -72,23 +72,23 @@ struct _GimpInputDeviceStoreClass
   GtkListStoreClass   parent_class;
 
   void  (* device_added)   (GimpInputDeviceStore *store,
-                            const gchar          *udi);
+                            const gchar          *identifier);
   void  (* device_removed) (GimpInputDeviceStore *store,
-                            const gchar          *udi);
+                            const gchar          *identifier);
 };
 
 
 static void      gimp_input_device_store_finalize   (GObject              *object);
 
 static gboolean  gimp_input_device_store_add        (GimpInputDeviceStore *store,
-                                                     const gchar          *udi);
+                                                     GUdevDevice          *device);
 static gboolean  gimp_input_device_store_remove     (GimpInputDeviceStore *store,
-                                                     const gchar          *udi);
+                                                     GUdevDevice          *device);
 
-static void      gimp_input_device_store_device_added   (LibHalContext *ctx,
-                                                         const char    *udi);
-static void      gimp_input_device_store_device_removed (LibHalContext *ctx,
-                                                         const char    *udi);
+static void      gimp_input_device_store_uevent     (GUdevClient          *client,
+                                                     const gchar          *action,
+                                                     GUdevDevice          *device,
+                                                     GimpInputDeviceStore *store);
 
 
 G_DEFINE_DYNAMIC_TYPE (GimpInputDeviceStore, gimp_input_device_store,
@@ -140,63 +140,31 @@ gimp_input_device_store_class_finalize (GimpInputDeviceStoreClass *klass)
 static void
 gimp_input_device_store_init (GimpInputDeviceStore *store)
 {
-  GType            types[] = { G_TYPE_STRING, G_TYPE_STRING };
-  DBusGConnection *connection;
-  DBusError        dbus_error;
+  GType        types[]      = { G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING };
+  const gchar *subsystems[] = { "input", NULL };
+  GList       *devices;
+  GList       *list;
 
   gtk_list_store_set_column_types (GTK_LIST_STORE (store),
                                    G_N_ELEMENTS (types), types);
 
-  connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &store->error);
+  store->client = g_udev_client_new (subsystems);
 
-  if (! connection)
-    return;
+  devices = g_udev_client_query_by_subsystem (store->client, "input");
 
-  store->context = libhal_ctx_new ();
-
-  libhal_ctx_set_dbus_connection (store->context,
-                                  dbus_g_connection_get_connection (connection));
-  dbus_g_connection_unref (connection);
-
-  dbus_error_init (&dbus_error);
-
-  if (libhal_ctx_init (store->context, &dbus_error))
+  for (list = devices; list; list = g_list_next (list))
     {
-      char **devices;
-      int    i, num_devices;
-
-      devices = libhal_find_device_by_capability (store->context, "input",
-                                                  &num_devices, NULL);
-
-      for (i = 0; i < num_devices; i++)
-        gimp_input_device_store_add (store, devices[i]);
+      GUdevDevice *device = list->data;
 
-      libhal_free_string_array (devices);
-
-      libhal_ctx_set_user_data (store->context, store);
-
-      libhal_ctx_set_device_added (store->context,
-                                   gimp_input_device_store_device_added);
-      libhal_ctx_set_device_removed (store->context,
-                                     gimp_input_device_store_device_removed);
+      gimp_input_device_store_add (store, device);
+      g_object_unref (device);
     }
-  else
-    {
-      if (dbus_error_is_set (&dbus_error))
-        {
-          dbus_set_g_error (&store->error, &dbus_error);
-          dbus_error_free (&dbus_error);
-        }
-      else
-        {
-          g_set_error_literal (&store->error,
-			       GIMP_MODULE_ERROR, GIMP_MODULE_FAILED,
-			       "Unable to connect to hald");
-        }
 
-      libhal_ctx_free (store->context);
-      store->context = NULL;
-    }
+  g_list_free (devices);
+
+  g_signal_connect (store->client, "uevent",
+                    G_CALLBACK (gimp_input_device_store_uevent),
+                    store);
 }
 
 static void
@@ -204,11 +172,10 @@ gimp_input_device_store_finalize (GObject *object)
 {
   GimpInputDeviceStore *store = GIMP_INPUT_DEVICE_STORE (object);
 
-  if (store->context)
+  if (store->client)
     {
-      libhal_ctx_shutdown (store->context, NULL);
-      libhal_ctx_free (store->context);
-      store->context = NULL;
+      g_object_unref (store->client);
+      store->client = NULL;
     }
 
   if (store->error)
@@ -222,7 +189,7 @@ gimp_input_device_store_finalize (GObject *object)
 
 static gboolean
 gimp_input_device_store_lookup (GimpInputDeviceStore *store,
-                                const gchar          *udi,
+                                const gchar          *identifier,
                                 GtkTreeIter          *iter)
 {
   GtkTreeModel *model = GTK_TREE_MODEL (store);
@@ -235,11 +202,11 @@ gimp_input_device_store_lookup (GimpInputDeviceStore *store,
     {
       const gchar *str;
 
-      gtk_tree_model_get_value (model, iter, COLUMN_UDI, &value);
+      gtk_tree_model_get_value (model, iter, COLUMN_IDENTIFIER, &value);
 
       str = g_value_get_string (&value);
 
-      if (strcmp (str, udi) == 0)
+      if (strcmp (str, identifier) == 0)
         {
           g_value_unset (&value);
           break;
@@ -254,8 +221,9 @@ gimp_input_device_store_lookup (GimpInputDeviceStore *store,
 /*  insert in alphabetic order  */
 static void
 gimp_input_device_store_insert (GimpInputDeviceStore *store,
-                                const gchar          *udi,
-                                const gchar          *label)
+                                const gchar          *identifier,
+                                const gchar          *label,
+                                const gchar          *device_file)
 {
   GtkTreeModel *model = GTK_TREE_MODEL (store);
   GtkTreeIter   iter;
@@ -283,72 +251,90 @@ gimp_input_device_store_insert (GimpInputDeviceStore *store,
     }
 
   gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, pos,
-                                     COLUMN_UDI,   udi,
-                                     COLUMN_LABEL, label,
+                                     COLUMN_IDENTIFIER,  identifier,
+                                     COLUMN_LABEL,       label,
+                                     COLUMN_DEVICE_FILE, device_file,
                                      -1);
 }
 
 static gboolean
 gimp_input_device_store_add (GimpInputDeviceStore *store,
-                             const gchar          *udi)
+                             GUdevDevice          *device)
 {
-  gboolean   added = FALSE;
-  char     **caps;
-  gint       i;
-
-  caps = libhal_device_get_property_strlist (store->context,
-                                             udi, "info.capabilities",
-                                             NULL);
-
-  for (i = 0; caps && caps[i] && !added; i++)
+  const gchar *device_file = g_udev_device_get_device_file (device);
+#if 0
+  const gchar *path        = g_udev_device_get_sysfs_path (device);
+#endif
+  const gchar *name        = g_udev_device_get_sysfs_attr (device, "name");
+
+#if 0
+  g_printerr ("\ndevice added: %s, %s, %s\n",
+              name ? name : "NULL",
+              device_file ? device_file : "NULL",
+              path);
+#endif
+
+  if (device_file)
     {
-      char *str;
+      if (name)
+        {
+          GtkTreeIter unused;
+
+          if (! gimp_input_device_store_lookup (store, name, &unused))
+            {
+              gimp_input_device_store_insert (store, name, name, device_file);
 
-      if (strcmp (caps[i], "input") != 0)
-        continue;
+              g_signal_emit (store, store_signals[DEVICE_ADDED], 0,
+                             name);
 
-      /*  skip "PC Speaker" (why is this an input device at all?)  */
-      str = libhal_device_get_property_string (store->context,
-                                               udi, "input.physical_device",
-                                               NULL);
-      if (str)
+              return TRUE;
+            }
+        }
+      else
         {
-          gboolean speaker =
-            strcmp (str, "/org/freedesktop/Hal/devices/platform_pcspkr") == 0;
+          GUdevDevice *parent = g_udev_device_get_parent (device);
+          const gchar *parent_name;
 
-          libhal_free_string (str);
+          parent_name = g_udev_device_get_sysfs_attr (parent, "name");
 
-          if (speaker)
-            continue;
-        }
+          if (parent_name)
+            {
+              GtkTreeIter unused;
 
-      str = libhal_device_get_property_string (store->context,
-                                               udi, "input.product",
-                                               NULL);
-      if (str)
-        {
-          gimp_input_device_store_insert (store, udi, str);
+              if (! gimp_input_device_store_lookup (store, parent_name, &unused))
+                {
+                  gimp_input_device_store_insert (store, parent_name, parent_name,
+                                                  device_file);
+
+                  g_signal_emit (store, store_signals[DEVICE_ADDED], 0,
+                                 parent_name);
 
-          libhal_free_string (str);
+                  g_object_unref (parent);
+                  return TRUE;
+                }
+            }
 
-          added = TRUE;
+          g_object_unref (parent);
+          return FALSE;
         }
     }
 
-  libhal_free_string_array (caps);
-
-  return added;
+  return FALSE;
 }
 
 static gboolean
 gimp_input_device_store_remove (GimpInputDeviceStore *store,
-                                const gchar          *udi)
+                                GUdevDevice          *device)
 {
+  const gchar *name = g_udev_device_get_sysfs_attr (device, "name");
   GtkTreeIter  iter;
 
-  if (gimp_input_device_store_lookup (store, udi, &iter))
+  if (gimp_input_device_store_lookup (store, name, &iter))
     {
       gtk_list_store_remove (GTK_LIST_STORE (store), &iter);
+
+      g_signal_emit (store, store_signals[DEVICE_REMOVED], 0, name);
+
       return TRUE;
     }
 
@@ -356,26 +342,18 @@ gimp_input_device_store_remove (GimpInputDeviceStore *store,
 }
 
 static void
-gimp_input_device_store_device_added (LibHalContext *ctx,
-                                      const char    *udi)
+gimp_input_device_store_uevent (GUdevClient          *client,
+                                const gchar          *action,
+                                GUdevDevice          *device,
+                                GimpInputDeviceStore *store)
 {
-  GimpInputDeviceStore *store = libhal_ctx_get_user_data (ctx);
-
-  if (gimp_input_device_store_add (store, udi))
+  if (! strcmp (action, "add"))
     {
-      g_signal_emit (store, store_signals[DEVICE_ADDED], 0, udi);
+      gimp_input_device_store_add (store, device);
     }
-}
-
-static void
-gimp_input_device_store_device_removed (LibHalContext *ctx,
-                                        const char    *udi)
-{
-  GimpInputDeviceStore *store = libhal_ctx_get_user_data (ctx);
-
-  if (gimp_input_device_store_remove (store, udi))
+  else if (! strcmp (action, "remove"))
     {
-      g_signal_emit (store, store_signals[DEVICE_REMOVED], 0, udi);
+      gimp_input_device_store_remove (store, device);
     }
 }
 
@@ -387,30 +365,26 @@ gimp_input_device_store_new (void)
 
 gchar *
 gimp_input_device_store_get_device_file (GimpInputDeviceStore *store,
-                                         const gchar          *udi)
+                                         const gchar          *identifier)
 {
   GtkTreeIter iter;
 
   g_return_val_if_fail (GIMP_IS_INPUT_DEVICE_STORE (store), NULL);
-  g_return_val_if_fail (udi != NULL, NULL);
+  g_return_val_if_fail (identifier != NULL, NULL);
 
-  if (! store->context)
+  if (! store->client)
     return NULL;
 
-  if (gimp_input_device_store_lookup (store, udi, &iter))
+  if (gimp_input_device_store_lookup (store, identifier, &iter))
     {
-      char *str = libhal_device_get_property_string (store->context,
-                                                     udi, "input.device",
-                                                     NULL);
-
-      if (str)
-        {
-          gchar *retval = g_strdup (str);
+      GtkTreeModel *model = GTK_TREE_MODEL (store);
+      gchar        *device_file;
 
-          libhal_free_string (str);
+      gtk_tree_model_get (model, &iter,
+                          COLUMN_DEVICE_FILE, &device_file,
+                          -1);
 
-          return retval;
-        }
+      return device_file;
     }
 
   return NULL;
@@ -424,7 +398,7 @@ gimp_input_device_store_get_error (GimpInputDeviceStore  *store)
   return store->error ? g_error_copy (store->error) : NULL;
 }
 
-#else /* HAVE_LIBHAL */
+#else /* HAVE_LIBGUDEV */
 
 void
 gimp_input_device_store_register_types (GTypeModule *module)
@@ -445,7 +419,7 @@ gimp_input_device_store_new (void)
 
 gchar *
 gimp_input_device_store_get_device_file (GimpInputDeviceStore *store,
-                                         const gchar          *udi)
+                                         const gchar          *identifier)
 {
   return NULL;
 }
@@ -456,4 +430,4 @@ gimp_input_device_store_get_error (GimpInputDeviceStore  *store)
   return NULL;
 }
 
-#endif /* HAVE_LIBHAL */
+#endif /* HAVE_LIBGUDEV */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]