[Xfce4-commits] <xfce4-power-manager:master> Fallback to HaL in case of failure on mapping X button. Use gint instead of guint for the brightness level.

Ali Abdallah noreply at xfce.org
Sat Jan 30 02:18:07 CET 2010


Updating branch refs/heads/master
         to cdc132a83cd7785319170eef508338bedf52fc21 (commit)
       from df7818730f752678a89baf9625f798943401b95f (commit)

commit cdc132a83cd7785319170eef508338bedf52fc21
Author: Ali Abdallah <ali at ali-xfce.org>
Date:   Fri Nov 6 12:45:24 2009 +0100

    Fallback to HaL in case of failure on mapping X button.
    Use gint instead of guint for the brightness level.

 common/xfpm-brightness.c                     |   90 ++++++++++-----
 common/xfpm-brightness.h                     |   10 +-
 libhal/Makefile.am                           |    3 +
 libhal/hal-manager.c                         |   96 ++++++++++-----
 libhal/hal-manager.h                         |    5 +
 panel-plugins/brightness/brightness-button.c |   20 ++--
 src/xfpm-backlight.c                         |   12 +-
 src/xfpm-button.c                            |  167 +++++++++++++++++++++++++-
 src/xfpm-enum.h                              |    9 +-
 9 files changed, 323 insertions(+), 89 deletions(-)

diff --git a/common/xfpm-brightness.c b/common/xfpm-brightness.c
index fdee10d..ab2e024 100644
--- a/common/xfpm-brightness.c
+++ b/common/xfpm-brightness.c
@@ -57,22 +57,25 @@ struct XfpmBrightnessPrivate
     gint 		output;
     gboolean		xrandr_has_hw;
     
-    guint		max_level;
-    guint		current_level;
-    guint		min_level;
-    guint		step;
+    gint		max_level;
+    gint		current_level;
+    gint		min_level;
+    gint		step;
     
 #ifdef WITH_HAL
+    HalManager	       *manager;
+    DBusGConnection    *bus;
     DBusGProxy         *hal_proxy;
     gboolean		hal_brightness_in_hw;
     gboolean		hal_hw_found;
+    gboolean		connected;
 #endif
 };
 
 G_DEFINE_TYPE (XfpmBrightness, xfpm_brightness, G_TYPE_OBJECT)
 
 static gboolean
-xfpm_brightness_xrand_get_limit (XfpmBrightness *brightness, RROutput output, guint *min, guint *max)
+xfpm_brightness_xrand_get_limit (XfpmBrightness *brightness, RROutput output, gint *min, gint *max)
 {
     XRRPropertyInfo *info;
     gboolean ret = TRUE;
@@ -101,11 +104,11 @@ out:
 }
 
 static gboolean
-xfpm_brightness_xrandr_get_level (XfpmBrightness *brightness, RROutput output, guint *current)
+xfpm_brightness_xrandr_get_level (XfpmBrightness *brightness, RROutput output, gint *current)
 {
     unsigned long nitems;
     unsigned long bytes_after;
-    guint *prop;
+    gint *prop;
     Atom actual_type;
     int actual_format;
     gboolean ret = FALSE;
@@ -121,7 +124,7 @@ xfpm_brightness_xrandr_get_level (XfpmBrightness *brightness, RROutput output, g
     
     if (actual_type == XA_INTEGER && nitems == 1 && actual_format == 32) 
     {
-	memcpy (current, prop, sizeof (guint));
+	memcpy (current, prop, sizeof (gint));
 	ret = TRUE;
     }
     
@@ -131,7 +134,7 @@ xfpm_brightness_xrandr_get_level (XfpmBrightness *brightness, RROutput output, g
 }
 
 static gboolean
-xfpm_brightness_xrandr_set_level (XfpmBrightness *brightness, RROutput output, guint level)
+xfpm_brightness_xrandr_set_level (XfpmBrightness *brightness, RROutput output, gint level)
 {
     gboolean ret = TRUE;
 
@@ -158,7 +161,7 @@ xfpm_brightness_setup_xrandr (XfpmBrightness *brightness)
     XRROutputInfo *info;
     Window window;
     gint major, minor, screen_num;
-    guint min, max;
+    gint min, max;
     gboolean ret = FALSE;
     gint i;
     
@@ -199,6 +202,7 @@ xfpm_brightness_setup_xrandr (XfpmBrightness *brightness)
 	    {
 		ret = TRUE;
 		brightness->priv->output = brightness->priv->resource->outputs[i];
+		brightness->priv->step = max / 20;
 	    }
 	    
 	}
@@ -208,9 +212,9 @@ xfpm_brightness_setup_xrandr (XfpmBrightness *brightness)
 }
 
 static gboolean
-xfpm_brightness_xrand_up (XfpmBrightness *brightness, guint *new_level)
+xfpm_brightness_xrand_up (XfpmBrightness *brightness, gint *new_level)
 {
-    guint hw_level;
+    gint hw_level;
     gboolean ret;
     
     ret = xfpm_brightness_xrandr_get_level (brightness, brightness->priv->output, &hw_level);
@@ -236,16 +240,16 @@ xfpm_brightness_xrand_up (XfpmBrightness *brightness, guint *new_level)
 }
 
 static gboolean
-xfpm_brightness_xrand_down (XfpmBrightness *brightness, guint *new_level)
+xfpm_brightness_xrand_down (XfpmBrightness *brightness, gint *new_level)
 {
-    guint hw_level;
+    gint hw_level;
     gboolean ret;
     
     ret = xfpm_brightness_xrandr_get_level (brightness, brightness->priv->output, &hw_level);
     
     if ( !ret )
 	return FALSE;
-	
+    
     if ( hw_level - brightness->priv->step >= brightness->priv->min_level)
 	ret = xfpm_brightness_xrandr_set_level (brightness, brightness->priv->output, hw_level - brightness->priv->step);
     else
@@ -271,11 +275,14 @@ xfpm_brightness_xrand_down (XfpmBrightness *brightness, guint *new_level)
 
 #ifdef WITH_HAL
 static gboolean
-xfpm_brightness_hal_get_level (XfpmBrightness *brg, guint *level)
+xfpm_brightness_hal_get_level (XfpmBrightness *brg, gint *level)
 {
     GError *error = NULL;
     gboolean ret = FALSE;
     
+    if (!brg->priv->connected)
+	return FALSE;
+    
     ret = dbus_g_proxy_call (brg->priv->hal_proxy, "GetBrightness", &error,
 	 		     G_TYPE_INVALID,
 			     G_TYPE_INT, level,
@@ -297,6 +304,9 @@ xfpm_brightness_hal_set_level (XfpmBrightness *brg, gint level)
     gboolean ret = FALSE;
     gint dummy;
     
+    if (!brg->priv->connected)
+	return FALSE;
+    
     TRACE ("Setting level %d", level);
     
     ret = dbus_g_proxy_call (brg->priv->hal_proxy, "SetBrightness", &error,
@@ -324,7 +334,7 @@ xfpm_brightness_hal_set_level (XfpmBrightness *brg, gint level)
 static gboolean
 xfpm_brightness_hal_up (XfpmBrightness *brightness)
 {
-    guint hw_level;
+    gint hw_level;
     gboolean ret = TRUE;
     
     ret = xfpm_brightness_hal_get_level (brightness, &hw_level);
@@ -347,7 +357,7 @@ xfpm_brightness_hal_up (XfpmBrightness *brightness)
 static gboolean
 xfpm_brightness_hal_down (XfpmBrightness *brightness)
 {
-    guint hw_level;
+    gint hw_level;
     gboolean ret = TRUE;
     
     ret = xfpm_brightness_hal_get_level (brightness, &hw_level);
@@ -367,19 +377,28 @@ xfpm_brightness_hal_down (XfpmBrightness *brightness)
     return ret;
 }
 
+static void
+xfpm_brightness_hal_connection_changed_cb (HalManager *manager, gboolean connected, XfpmBrightness *brightness)
+{
+    brightness->priv->connected = connected;
+}
+
 static gboolean
 xfpm_brightness_setup_hal (XfpmBrightness *brightness)
 {
     DBusGConnection *bus;
     HalDevice *device;
     gchar **udi = NULL;
-    HalManager *manager;
     
-    manager = hal_manager_new ();
+    brightness->priv->manager = hal_manager_new ();
     
-    udi = hal_manager_find_device_by_capability (manager, "laptop_panel");
-    g_object_unref ( manager);
+    brightness->priv->connected = hal_manager_get_is_connected (brightness->priv->manager);
     
+    g_signal_connect (brightness->priv->manager, "connection-changed",
+		      G_CALLBACK (xfpm_brightness_hal_connection_changed_cb), brightness);
+		      
+    udi = hal_manager_find_device_by_capability (brightness->priv->manager, "laptop_panel");
+
     if ( !udi || !udi[0])
     {
     	return FALSE;
@@ -400,7 +419,6 @@ xfpm_brightness_setup_hal (XfpmBrightness *brightness)
     
     g_object_unref (device);
 
-    /*FIXME, check for errors*/
     bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
     
     brightness->priv->hal_proxy = dbus_g_proxy_new_for_name (bus,
@@ -415,6 +433,7 @@ xfpm_brightness_setup_hal (XfpmBrightness *brightness)
     }
     
     hal_manager_free_string_array (udi);
+    brightness->priv->bus = bus;
     
     return brightness->priv->hal_hw_found;
 }
@@ -444,9 +463,11 @@ xfpm_brightness_init (XfpmBrightness *brightness)
     brightness->priv->step = 0;
     
 #ifdef WITH_HAL
+    brightness->priv->bus = NULL;
     brightness->priv->hal_proxy = NULL;
     brightness->priv->hal_brightness_in_hw = FALSE;
     brightness->priv->hal_hw_found = FALSE;
+    brightness->priv->manager = NULL;
 #endif
 }
 
@@ -460,6 +481,17 @@ xfpm_brightness_finalize (GObject *object)
     if ( brightness->priv->resource )
 	XRRFreeScreenResources (brightness->priv->resource);
 
+#ifdef WITH_HAL
+    if ( brightness->priv->bus )
+	dbus_g_connection_unref (brightness->priv->bus);
+	
+    if ( brightness->priv->hal_proxy )
+	g_object_unref (brightness->priv->hal_proxy);
+
+    if ( brightness->priv->manager )
+	g_object_unref (brightness->priv->manager);
+#endif
+
     G_OBJECT_CLASS (xfpm_brightness_parent_class)->finalize (object);
 }
 
@@ -482,7 +514,7 @@ xfpm_brightness_setup (XfpmBrightness *brightness)
 					 brightness->priv->output, 
 					 &brightness->priv->min_level, 
 					 &brightness->priv->max_level);
-	g_debug ("Brightness controlled by xrandr, min_level=%u max_level=%u", 
+	g_debug ("Brightness controlled by xrandr, min_level=%d max_level=%d", 
 		 brightness->priv->min_level, 
 		 brightness->priv->max_level);
 		 
@@ -499,7 +531,7 @@ xfpm_brightness_setup (XfpmBrightness *brightness)
     return brightness->priv->xrandr_has_hw;
 }
 
-gboolean xfpm_brightness_up (XfpmBrightness *brightness, guint *new_level)
+gboolean xfpm_brightness_up (XfpmBrightness *brightness, gint *new_level)
 {
     gboolean ret = FALSE;
     
@@ -518,7 +550,7 @@ gboolean xfpm_brightness_up (XfpmBrightness *brightness, guint *new_level)
     return ret;
 }
 
-gboolean xfpm_brightness_down (XfpmBrightness *brightness, guint *new_level)
+gboolean xfpm_brightness_down (XfpmBrightness *brightness, gint *new_level)
 {
     gboolean ret = FALSE;
     
@@ -549,12 +581,12 @@ gboolean xfpm_brightness_has_hw (XfpmBrightness *brightness)
     return brightness->priv->xrandr_has_hw;
 }
 
-guint xfpm_brightness_get_max_level (XfpmBrightness *brightness)
+gint xfpm_brightness_get_max_level (XfpmBrightness *brightness)
 {
     return brightness->priv->max_level;
 }
 
-gboolean xfpm_brightness_get_level	(XfpmBrightness *brightness, guint *level)
+gboolean xfpm_brightness_get_level	(XfpmBrightness *brightness, gint *level)
 {
     gboolean ret = FALSE;
     
@@ -568,7 +600,7 @@ gboolean xfpm_brightness_get_level	(XfpmBrightness *brightness, guint *level)
     return ret;
 }
 
-gboolean xfpm_brightness_set_level (XfpmBrightness *brightness, guint level)
+gboolean xfpm_brightness_set_level (XfpmBrightness *brightness, gint level)
 {
     gboolean ret = FALSE;
     
diff --git a/common/xfpm-brightness.h b/common/xfpm-brightness.h
index ba799e3..4fa37d7 100644
--- a/common/xfpm-brightness.h
+++ b/common/xfpm-brightness.h
@@ -59,20 +59,20 @@ XfpmBrightness       	       *xfpm_brightness_new             (void);
 gboolean			xfpm_brightness_setup 		(XfpmBrightness *brightness);
 
 gboolean			xfpm_brightness_up		(XfpmBrightness *brightness,
-								 guint *new_level);
+								 gint *new_level);
 
 gboolean			xfpm_brightness_down		(XfpmBrightness *brightness,
-								 guint *new_level);
+								 gint *new_level);
 
 gboolean			xfpm_brightness_has_hw 		(XfpmBrightness *brightness);
 
-guint 				xfpm_brightness_get_max_level   (XfpmBrightness *brightness);
+gint 				xfpm_brightness_get_max_level   (XfpmBrightness *brightness);
 
 gboolean			xfpm_brightness_get_level	(XfpmBrightness *brightness,
-								 guint *level);
+								 gint *level);
 
 gboolean			xfpm_brightness_set_level	(XfpmBrightness *brightness,
-								 guint level);
+								 gint level);
 
 gboolean			xfpm_brightness_dim_down	(XfpmBrightness *brightness);
 
diff --git a/libhal/Makefile.am b/libhal/Makefile.am
index d8e76b3..ed5af2a 100644
--- a/libhal/Makefile.am
+++ b/libhal/Makefile.am
@@ -13,6 +13,9 @@ libxfpmhal_la_CFLAGS =			\
 	$(GLIB_CFLAGS)			\
 	$(DBUS_GLIB_CFLAGS)
 
+libxfpmhal_la_LIBADD =			\
+	$(top_builddir)/libdbus/libxfpmdbus.la
+
 if MAINTAINER_MODE
 
 BUILT_SOURCES =				\
diff --git a/libhal/hal-manager.c b/libhal/hal-manager.c
index 97ea4f4..7ec8a61 100644
--- a/libhal/hal-manager.c
+++ b/libhal/hal-manager.c
@@ -27,11 +27,15 @@
 #include <string.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include <glib.h>
 
 #include "hal-manager.h"
 #include "hal-device.h"
 
+#include "libdbus/xfpm-dbus-monitor.h"
+#include "libdbus/xfpm-dbus.h"
+
 static void hal_manager_finalize   (GObject *object);
 
 #define HAL_MANAGER_GET_PRIVATE(o) \
@@ -39,21 +43,23 @@ static void hal_manager_finalize   (GObject *object);
 
 struct HalManagerPrivate
 {
+    XfpmDBusMonitor *monitor;
     DBusGConnection *bus;
     DBusGProxy      *proxy;
     gboolean 	     connected;
     gboolean         is_laptop;
+    
+    gulong	     sig_hal;
 };
 
 enum
 {
     DEVICE_ADDED,
     DEVICE_REMOVED,
+    CONNECTION_CHANGED,
     LAST_SIGNAL
 };
 
-static gpointer hal_manager_object = NULL;
-
 static guint signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (HalManager, hal_manager, G_TYPE_OBJECT)
@@ -83,7 +89,12 @@ hal_manager_connect (HalManager *manager)
 	g_error_free (error);
 	goto out;
     }
-    manager->priv->connected = TRUE;
+    
+    manager->priv->connected = xfpm_dbus_name_has_owner (dbus_g_connection_get_connection (manager->priv->bus),
+							 "org.freedesktop.Hal");
+    
+    if ( !manager->priv->connected )
+	goto out;
     
     manager->priv->proxy = dbus_g_proxy_new_for_name (manager->priv->bus,
 		  				      "org.freedesktop.Hal",
@@ -112,30 +123,27 @@ out:
 }
 
 static void
-hal_manager_get_is_laptop_internal (HalManager *manager)
+hal_manager_service_connection_changed_cb (XfpmDBusMonitor *monitor, 
+					   gchar *service_name, 
+					   gboolean is_connected,
+					   gboolean on_session, 
+					   HalManager *manager)
 {
-    HalDevice *device;
-    gchar *form_factor;
-    
-    device = hal_device_new ();
-    
-    hal_device_set_udi (device, "/org/freedesktop/Hal/devices/computer");
-
-    form_factor = hal_device_get_property_string (device, "system.formfactor");
-
-    if ( g_strcmp0 (form_factor, "laptop") == 0)
-	manager->priv->is_laptop = TRUE;
-    else
-	manager->priv->is_laptop = FALSE;
-    
-    if (form_factor)
-	g_free (form_factor);
-
-    g_object_unref (device);
+    if ( !on_session)
+    {
+	if (!g_strcmp0 (service_name, "org.freedesktop.Hal") )
+	{
+	    if ( manager->priv->connected != is_connected )
+	    {
+		manager->priv->connected = is_connected;
+		g_signal_emit (G_OBJECT (manager), signals [CONNECTION_CHANGED], 0, is_connected);
+	    }
+	}
+    }
 }
 
 static void
-hal_manager_class_init(HalManagerClass *klass)
+hal_manager_class_init (HalManagerClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS(klass);
     
@@ -157,6 +165,15 @@ hal_manager_class_init(HalManagerClass *klass)
 		     g_cclosure_marshal_VOID__STRING,
 		     G_TYPE_NONE, 1, G_TYPE_STRING);
     
+    signals[CONNECTION_CHANGED] =
+    	g_signal_new("connection-changed",
+		     HAL_TYPE_MANAGER,
+		     G_SIGNAL_RUN_LAST,
+		     G_STRUCT_OFFSET(HalManagerClass, connection_changed),
+		     NULL, NULL,
+		     g_cclosure_marshal_VOID__VOID,
+		     G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+    
     object_class->finalize = hal_manager_finalize;
 
     g_type_class_add_private (klass,sizeof(HalManagerPrivate));
@@ -170,17 +187,26 @@ hal_manager_init (HalManager *manager)
     manager->priv->bus 	     = NULL;
     manager->priv->proxy     = NULL;
     manager->priv->connected = FALSE;
+    manager->priv->monitor   = xfpm_dbus_monitor_new ();
     
     hal_manager_connect (manager);
-    hal_manager_get_is_laptop_internal (manager);
+    
+    xfpm_dbus_monitor_add_service (manager->priv->monitor, DBUS_BUS_SYSTEM, "org.freedesktop.Hal");
+    
+    manager->priv->sig_hal = 
+    g_signal_connect (manager->priv->monitor, "service-connection-changed",
+		      G_CALLBACK (hal_manager_service_connection_changed_cb), manager);
 }
 
 static void
-hal_manager_finalize(GObject *object)
+hal_manager_finalize (GObject *object)
 {
     HalManager *manager;
 
     manager = HAL_MANAGER(object);
+
+    if ( g_signal_handler_is_connected (manager->priv->monitor, manager->priv->sig_hal) )
+	g_signal_handler_disconnect (manager->priv->monitor, manager->priv->sig_hal);
     
     if ( manager->priv->proxy )
 	g_object_unref (manager->priv->proxy);
@@ -188,12 +214,18 @@ hal_manager_finalize(GObject *object)
     if ( manager->priv->bus )
 	dbus_g_connection_unref (manager->priv->bus);
 
+    xfpm_dbus_monitor_remove_service (manager->priv->monitor, DBUS_BUS_SYSTEM, "org.freedesktop.Hal");
+
+    g_object_unref (manager->priv->monitor);
+
     G_OBJECT_CLASS(hal_manager_parent_class)->finalize(object);
 }
 
 HalManager *
 hal_manager_new (void)
 {
+    static gpointer hal_manager_object = NULL;
+    
     if ( hal_manager_object != NULL )
     {
 	g_object_ref (hal_manager_object);
@@ -229,13 +261,6 @@ gchar **hal_manager_find_device_by_capability (HalManager *manager, const gchar
     return udi;
 }
 
-gboolean hal_manager_get_is_laptop (HalManager *manager)
-{
-    g_return_val_if_fail (HAL_IS_MANAGER (manager), FALSE);
-    
-    return manager->priv->is_laptop;
-}
-
 void hal_manager_free_string_array (gchar **array)
 {
     gint i;
@@ -248,3 +273,10 @@ void hal_manager_free_string_array (gchar **array)
     
     g_free (array);
 }
+
+gboolean hal_manager_get_is_connected (HalManager *manager)
+{
+    g_return_val_if_fail (HAL_IS_MANAGER (manager), FALSE);
+    
+    return manager->priv->connected;
+}
diff --git a/libhal/hal-manager.h b/libhal/hal-manager.h
index 982c90c..76e94be 100644
--- a/libhal/hal-manager.h
+++ b/libhal/hal-manager.h
@@ -47,6 +47,9 @@ typedef struct
     void                        (*device_removed)			(HalManager *manager,
 									 const gchar *udi);
     
+    void			(*connection_changed)			(HalManager *manager,
+									 gboolean connected);
+    
 } HalManagerClass;
 
 GType        	  		hal_manager_get_type        		(void) G_GNUC_CONST;
@@ -59,6 +62,8 @@ gboolean                        hal_manager_get_is_laptop               (HalMana
 						 
 void                            hal_manager_free_string_array           (gchar **array);
 
+gboolean			hal_manager_get_is_connected		(HalManager *manager);
+
 G_END_DECLS
 
 #endif /* __HAL_MANAGER_H */
diff --git a/panel-plugins/brightness/brightness-button.c b/panel-plugins/brightness/brightness-button.c
index 839e697..0318c95 100644
--- a/panel-plugins/brightness/brightness-button.c
+++ b/panel-plugins/brightness/brightness-button.c
@@ -186,7 +186,7 @@ static gboolean
 brightness_button_popup_win (GtkWidget *widget, GdkEvent *ev, guint32 ev_time)
 {
     gint x, y, orientation;
-    guint current_level = 0;
+    gint current_level = 0;
     GdkDisplay *display;
     GdkScreen *screen;
     BrightnessButton *button;
@@ -320,10 +320,10 @@ brightness_button_press_event (GtkWidget *widget, GdkEventButton *ev)
 static void
 minus_clicked (GtkWidget *widget, BrightnessButton *button)
 {
-    guint level, max_level;
+    gint level, max_level;
     
     max_level = xfpm_brightness_get_max_level (button->priv->brightness);
-    level = (guint ) gtk_range_get_value (GTK_RANGE (button->priv->range));
+    level = (gint ) gtk_range_get_value (GTK_RANGE (button->priv->range));
     
     if ( level != 0 )
 	gtk_range_set_value (GTK_RANGE (button->priv->range), level - 1);
@@ -332,10 +332,10 @@ minus_clicked (GtkWidget *widget, BrightnessButton *button)
 static void
 plus_clicked (GtkWidget *widget, BrightnessButton *button)
 {
-    guint level, max_level;
+    gint level, max_level;
     
     max_level = xfpm_brightness_get_max_level (button->priv->brightness);
-    level = (guint ) gtk_range_get_value (GTK_RANGE (button->priv->range));
+    level = (gint ) gtk_range_get_value (GTK_RANGE (button->priv->range));
     
     if ( level != max_level )
 	gtk_range_set_value (GTK_RANGE (button->priv->range), level + 1);
@@ -344,9 +344,9 @@ plus_clicked (GtkWidget *widget, BrightnessButton *button)
 static void
 range_value_changed (GtkWidget *widget, BrightnessButton *button)
 {
-    guint range_level, hw_level;
+    gint range_level, hw_level;
     
-    range_level = (guint) gtk_range_get_value (GTK_RANGE (button->priv->range));
+    range_level = (gint) gtk_range_get_value (GTK_RANGE (button->priv->range));
     
     xfpm_brightness_get_level (button->priv->brightness, &hw_level);
     
@@ -361,7 +361,7 @@ brightness_button_create_popup (BrightnessButton *button)
 {
     GtkWidget *box;
     GtkOrientation orientation;
-    guint max_level;
+    gint max_level;
     gboolean has_hw;
     
     has_hw = xfpm_brightness_has_hw (button->priv->brightness);
@@ -430,8 +430,8 @@ brightness_button_create_popup (BrightnessButton *button)
 static void
 brightness_button_up (BrightnessButton *button)
 {
-    guint level;
-    guint max_level;
+    gint level;
+    gint max_level;
     
     xfpm_brightness_get_level (button->priv->brightness, &level);
     max_level = xfpm_brightness_get_max_level (button->priv->brightness);
diff --git a/src/xfpm-backlight.c b/src/xfpm-backlight.c
index b804fec..194eda8 100644
--- a/src/xfpm-backlight.c
+++ b/src/xfpm-backlight.c
@@ -64,8 +64,8 @@ struct XfpmBacklightPrivate
     gulong	    destroy_id;
     gboolean	    has_hw;
     gboolean	    on_battery;
-    guint           last_level;
-    guint 	    max_level;
+    gint           last_level;
+    gint 	    max_level;
 #ifdef WITH_HAL
     gboolean	    brightness_in_hw;
 #endif
@@ -113,9 +113,9 @@ xfpm_backlight_destroy_popup (gpointer data)
 }
 
 static void
-xfpm_backlight_show_notification (XfpmBacklight *backlight, guint level, guint max_level)
+xfpm_backlight_show_notification (XfpmBacklight *backlight, gint level, gint max_level)
 {
-    guint i;
+    gint i;
     gfloat value = 0;
     NotifyNotification *n;
     
@@ -217,7 +217,7 @@ xfpm_backlight_create_popup (XfpmBacklight *backlight)
 }
 
 static void
-xfpm_backlight_show (XfpmBacklight *backlight, guint level)
+xfpm_backlight_show (XfpmBacklight *backlight, gint level)
 {
     gboolean sync;
     gboolean show_popup;
@@ -291,7 +291,7 @@ xfpm_backlight_reset_cb (XfpmIdle *idle, XfpmBacklight *backlight)
 static void
 xfpm_backlight_button_pressed_cb (XfpmButton *button, XfpmButtonKey type, XfpmBacklight *backlight)
 {
-    guint level;
+    gint level;
     gboolean ret = TRUE;
     
     gboolean enable_brightness;
diff --git a/src/xfpm-button.c b/src/xfpm-button.c
index ed6cf52..40bbb76 100644
--- a/src/xfpm-button.c
+++ b/src/xfpm-button.c
@@ -48,6 +48,11 @@
 #include "xfpm-enum-types.h"
 #include "xfpm-debug.h"
 
+#ifdef WITH_HAL
+#include "libhal/hal-manager.h"
+#include "libhal/hal-device.h"
+#endif
+
 static void xfpm_button_finalize   (GObject *object);
 
 #define XFPM_BUTTON_GET_PRIVATE(o) \
@@ -65,6 +70,9 @@ struct XfpmButtonPrivate
     GdkWindow   *window;
     
     guint8       mapped_buttons;
+#ifdef WITH_HAL
+    GPtrArray  *array;
+#endif
 };
 
 enum
@@ -206,14 +214,135 @@ xfpm_button_setup (XfpmButton *button)
     if ( xfpm_button_xevent_key (button, XF86XK_Sleep, BUTTON_SLEEP) )
 	button->priv->mapped_buttons |= SLEEP_KEY;
 	
-    if ( xfpm_button_xevent_key (button, XF86XK_MonBrightnessUp, BUTTON_MON_BRIGHTNESS_UP) &&
-	 xfpm_button_xevent_key (button, XF86XK_MonBrightnessDown, BUTTON_MON_BRIGHTNESS_DOWN) )
-	button->priv->mapped_buttons |= BRIGHTNESS_KEY;
+    if ( xfpm_button_xevent_key (button, XF86XK_MonBrightnessUp, BUTTON_MON_BRIGHTNESS_UP) )
+	button->priv->mapped_buttons |= BRIGHTNESS_KEY_UP;
+	
+    if (xfpm_button_xevent_key (button, XF86XK_MonBrightnessDown, BUTTON_MON_BRIGHTNESS_DOWN) )
+	button->priv->mapped_buttons |= BRIGHTNESS_KEY_DOWN;
 
     gdk_window_add_filter (button->priv->window, 
 			   xfpm_button_filter_x_events, button);
 }
 
+#ifdef WITH_HAL
+static void
+xfpm_button_hal_emit_signals (XfpmButton *button, const gchar *condition, const gchar *detail)
+{
+    if ( g_strcmp0 (condition, "ButtonPressed") )
+	return;
+
+    TRACE ("Button press condition %s detail %s", condition, detail);
+
+    if ( !g_strcmp0 (detail, "power") )
+	g_signal_emit (G_OBJECT (button), signals [BUTTON_PRESSED], 0, BUTTON_POWER_OFF);
+    else if ( !g_strcmp0 (detail, "sleep")  || !g_strcmp0 (detail, "suspend") )
+	g_signal_emit (G_OBJECT (button), signals [BUTTON_PRESSED], 0, BUTTON_SLEEP);
+    else if ( !g_strcmp0 (detail, "hibernate"))
+	g_signal_emit (G_OBJECT (button), signals [BUTTON_PRESSED], 0, BUTTON_HIBERNATE);
+    else if ( !g_strcmp0 (detail, "brightness-up") )
+	g_signal_emit (G_OBJECT (button), signals [BUTTON_PRESSED], 0, BUTTON_MON_BRIGHTNESS_UP);
+    else if ( !g_strcmp0 (detail, "brightness-down") )
+	g_signal_emit (G_OBJECT (button), signals [BUTTON_PRESSED], 0, BUTTON_MON_BRIGHTNESS_DOWN);
+}
+
+static void
+xfpm_button_hal_condition_cb (HalDevice *device, const gchar *condition, 
+			      const gchar *detail, XfpmButton *button)
+{
+    xfpm_button_hal_emit_signals (button, condition, detail);
+}
+
+static void
+xfpm_button_add_button_hal (XfpmButton *button, const gchar *udi)
+{
+    HalDevice *device;
+    gchar *button_type = NULL;
+    
+    device = hal_device_new ();
+    
+    hal_device_set_udi (device, udi);
+   
+    if ( hal_device_has_key (device, "button.type") )
+    {
+	button_type = hal_device_get_property_string (device, "button.type");
+	
+	if ( button_type == NULL ) 
+	{
+	    g_object_unref (device);
+	    return;
+	}
+	
+	if ( !g_strcmp0 (button_type, "sleep") && !(button->priv->mapped_buttons & SLEEP_KEY))
+	    button->priv->mapped_buttons |= SLEEP_KEY;
+	else if ( !g_strcmp0 (button_type, "suspend") && !(button->priv->mapped_buttons & SLEEP_KEY))
+	    button->priv->mapped_buttons |= SLEEP_KEY;
+	else if ( !g_strcmp0 (button_type, "hibernate") && !(button->priv->mapped_buttons & HIBERNATE_KEY))
+	    button->priv->mapped_buttons |= HIBERNATE_KEY;
+	else if ( !g_strcmp0 (button_type, "power") && !(button->priv->mapped_buttons & POWER_KEY))
+	    button->priv->mapped_buttons |= POWER_KEY;
+	else if ( !g_strcmp0 (button_type, "brightness-up") && !(button->priv->mapped_buttons & BRIGHTNESS_KEY_UP))
+	    button->priv->mapped_buttons |= BRIGHTNESS_KEY_UP;
+	else if ( !g_strcmp0 (button_type, "brightness-down") && !(button->priv->mapped_buttons & BRIGHTNESS_KEY_DOWN))
+	    button->priv->mapped_buttons |= BRIGHTNESS_KEY_DOWN;
+	else
+	{
+	    g_object_unref (device);
+	    if ( button_type )
+		g_free (button_type);
+	    return;
+	}
+	
+	if ( button_type )
+		g_free (button_type);
+    }
+    else
+    {
+	g_object_unref (device);
+	return;
+    }
+    
+    g_signal_connect (device, "device-condition",
+		      G_CALLBACK (xfpm_button_hal_condition_cb), button);
+		      
+    hal_device_watch_condition (device);
+   
+    if ( button->priv->array == NULL )
+    {
+	button->priv->array = g_ptr_array_new ();
+    }
+    g_ptr_array_add (button->priv->array, device);
+
+}
+
+static void
+xfpm_button_setup_failed_hal (XfpmButton *button)
+{
+    HalManager *manager;
+    gchar     **udi;
+    int 	i;
+    
+    g_debug ("Getting missing buttons from HAL");
+    
+    manager = hal_manager_new ();
+    
+    udi = hal_manager_find_device_by_capability (manager, "button");
+    
+    g_object_unref (manager);
+    
+    if ( udi == NULL || udi[0] == NULL )
+	return;
+	
+    for ( i = 0; udi[i]; i++)
+    {
+	xfpm_button_add_button_hal (button, udi[i]);
+    }
+    
+    hal_manager_free_string_array (udi);
+    if ( button->priv->array )
+	g_debug ("Mapped HAL buttons : %u", button->priv->array->len);
+}
+#endif /* WITH_HAL*/
+
 static void
 xfpm_button_class_init(XfpmButtonClass *klass)
 {
@@ -243,7 +372,31 @@ xfpm_button_init (XfpmButton *button)
     button->priv->window = NULL;
     
     xfpm_button_setup (button);
+#ifdef WITH_HAL
+    if ( !(button->priv->mapped_buttons & BRIGHTNESS_KEY_DOWN ) ||
+         !(button->priv->mapped_buttons & BRIGHTNESS_KEY_UP )   ||
+	 !(button->priv->mapped_buttons & SLEEP_KEY )   ||
+	 !(button->priv->mapped_buttons & HIBERNATE_KEY)   ||
+	 !(button->priv->mapped_buttons & POWER_KEY )  )
+	xfpm_button_setup_failed_hal (button);
+#endif
+    
+}
+
+#ifdef WITH_HAL
+static void
+xfpm_button_free_device_array (XfpmButton *button)
+{
+    HalDevice *device;
+    guint i;
+    
+    for ( i = 0 ; i<button->priv->array->len; i++)
+    {
+	device = g_ptr_array_index (button->priv->array, i);
+	g_object_unref (device);
+    }
 }
+#endif
 
 static void
 xfpm_button_finalize (GObject *object)
@@ -252,6 +405,14 @@ xfpm_button_finalize (GObject *object)
 
     button = XFPM_BUTTON (object);
     
+#ifdef WITH_HAL
+    if ( button->priv->array )
+    {
+	xfpm_button_free_device_array (button);
+	g_ptr_array_free (button->priv->array, TRUE);
+    }
+#endif
+    
     G_OBJECT_CLASS(xfpm_button_parent_class)->finalize(object);
 }
 
diff --git a/src/xfpm-enum.h b/src/xfpm-enum.h
index 283c980..7eccb49 100644
--- a/src/xfpm-enum.h
+++ b/src/xfpm-enum.h
@@ -41,10 +41,11 @@ typedef enum
 typedef enum
 {
     LID_KEY   		= (1 << 0),
-    BRIGHTNESS_KEY	= (1 << 1),
-    SLEEP_KEY 		= (1 << 2),
-    HIBERNATE_KEY	= (1 << 3),
-    POWER_KEY 		= (1 << 4)
+    BRIGHTNESS_KEY_UP	= (1 << 1),
+    BRIGHTNESS_KEY_DOWN	= (1 << 2),
+    SLEEP_KEY 		= (1 << 3),
+    HIBERNATE_KEY	= (1 << 4),
+    POWER_KEY 		= (1 << 5)
     
 } XfpmKeys;
 



More information about the Xfce4-commits mailing list