[gnome-power-manager] Revert "HAL is no longer a dependency of gnome-power-manager"



commit 852ab8676a78e9a7edbad60e35adef92e24f9132
Author: Richard Hughes <richard hughsie com>
Date:   Sun Jul 5 09:39:14 2009 +0100

    Revert "HAL is no longer a dependency of gnome-power-manager"
    
    This reverts commit f884a1ae954d14928a6a7055d4d4b182fbb2a3bc.

 Makefile.am                    |    1 +
 README                         |   38 ++--
 TODO                           |    9 +-
 applets/brightness/Makefile.am |    1 +
 applets/inhibit/Makefile.am    |    1 +
 configure.ac                   |    7 +
 libhal-glib/.gitignore         |    9 +
 libhal-glib/Makefile.am        |   52 ++++
 libhal-glib/egg-dbus-monitor.c |    1 +
 libhal-glib/egg-dbus-monitor.h |    1 +
 libhal-glib/egg-dbus-proxy.c   |    1 +
 libhal-glib/egg-dbus-proxy.h   |    1 +
 libhal-glib/egg-debug.c        |    1 +
 libhal-glib/egg-debug.h        |    1 +
 libhal-glib/hal-device.c       |  262 ++++++++++++++++++++
 libhal-glib/hal-device.h       |   71 ++++++
 libhal-glib/hal-manager.c      |  358 +++++++++++++++++++++++++++
 libhal-glib/hal-manager.h      |   86 +++++++
 libhal-glib/hal-marshal.list   |    9 +
 src/Makefile.am                |   12 +
 src/gpm-brightness-hal.c       |  528 ++++++++++++++++++++++++++++++++++++++++
 src/gpm-brightness-hal.h       |   67 +++++
 src/gpm-brightness.c           |   62 ++++-
 23 files changed, 1551 insertions(+), 28 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 36f06a1..6c225e6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,7 @@
 ACLOCAL_AMFLAGS = -I m4
 
 SUBDIRS = 						\
+	libhal-glib					\
 	src						\
 	po						\
 	docs						\
diff --git a/README b/README
index 28b6078..ddd9542 100644
--- a/README
+++ b/README
@@ -1,11 +1,17 @@
 			      GNOME Power Manager
 			   A Power Manager for GNOME
 
-GNOME Power Manager is a GNOME session daemon that acts as a policy agent on top of
-the DeviceKit stack, which requires fairly new versions of the kernel and udev.
-GNOME Power Manager listens for system events and responds with user-configurable actions.
+GNOME Power Manager is a GNOME session daemon that acts as a policy agent on top of 
+the Project Utopia stack, which includes the kernel, hotplug, udev, and HAL. GNOME 
+Power Manager listens for HAL events and responds with user-configurable reactions.
+Currently it supports UPS's, laptop batteries and AC adapters. Its goal is to be 
+architecture neutral and free of polling and other hacks.
 
-GNOME Power Manager comes in three main parts:
+Most of the code is actually in HAL for abstracting various power aware devices 
+(UPS's) and frameworks (ACPI, PMU, APM etc.) - so the desktop parts are fairly 
+lightweight and straightforward to write.
+
+GNOME Power Manager comes in three parts:
 
 	- gnome-power-manager:	    the manager daemon itself
 	- gnome-power-preferences:  the control panel program, for configuration
@@ -13,21 +19,13 @@ GNOME Power Manager comes in three main parts:
 
 To build, GNOME Power Manager requires
 
-	- Glib (2.13.0 or later)
-	- Gtk2+ (2.11.0 or later)
-	- GNOME Keyring (0.6.0 or later)
-	- DBus (0.70 or later)
-	- libnotify (0.4.3 or later)
-	- libwnck (2.10.0 or later)
-	- Cairo (1.0.0 or later)
-	- Unique (0.9.4 or later)
-	- libpanel (2.0.0 or later)
-	- xrandr (1.2.0 or later)
-	- Canberra (0.10 or later)
-	- DeviceKit (001 or later)
-	- DeviceKit-power (008 or later)
-
-To work properly, gnome-power-manager requires udevd, DeviceKit-power and
-DeviceKit-disks to be running.
+	- libgnomeui-2.0
+	- libglade-2.0
+	- libhal-0 (from HAL 0.5.7 , 0.5.8 recommended)
+	- libdbus-1 (from D-BUS 0.70 or later)
+	- libdbus-glib-1 (from D-BUS 0.70 or later)
+	- libnotify (from 0.3.0 or later, 0.4.3 recommended)
+
+To work properly, gnome-power-manager requires hald to be running.
 
 For more information, please see http://www.gnome.org/projects/gnome-power-manager/
diff --git a/TODO b/TODO
index 8cf2294..cb390c5 100644
--- a/TODO
+++ b/TODO
@@ -1 +1,8 @@
-Ask on the mailing list!
+TODO:
+
+ * Implement the low power changed signal
+ * Throw dbus errors when we fail dbus methods: org.gnome.PowerManager.NotInhibited.
+ * Make strings more translatable
+ * Integrate g-p-m with more modules, e.g. nautilus.
+ * Give the user the ability to force an Inhibit()'d action
+ * use the updated hal can_suspend_to_disk keys
diff --git a/applets/brightness/Makefile.am b/applets/brightness/Makefile.am
index 4ba35a9..14b18b3 100644
--- a/applets/brightness/Makefile.am
+++ b/applets/brightness/Makefile.am
@@ -1,6 +1,7 @@
 INCLUDES =							\
 	-I. -I$(srcdir) 					\
 	$(GLIB_CFLAGS)						\
+	$(HAL_CFLAGS)						\
 	$(DBUS_CFLAGS)						\
 	$(GNOME_CFLAGS)						\
 	$(LIBNOTIFY_CFLAGS)					\
diff --git a/applets/inhibit/Makefile.am b/applets/inhibit/Makefile.am
index 788a7e8..6cd275f 100644
--- a/applets/inhibit/Makefile.am
+++ b/applets/inhibit/Makefile.am
@@ -1,6 +1,7 @@
 INCLUDES =							\
 	-I. -I$(srcdir) 					\
 	$(GLIB_CFLAGS)						\
+	$(HAL_CFLAGS)						\
 	$(DBUS_CFLAGS)						\
 	$(GNOME_CFLAGS)						\
 	$(LIBNOTIFY_CFLAGS)					\
diff --git a/configure.ac b/configure.ac
index 8490fb1..601f30a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,6 +94,7 @@ GLIB_REQUIRED=2.13.0
 GTK_REQUIRED=2.11.0
 GDK_REQUIRED=2.11.0
 GNOME_KEYRING_REQUIRED=0.6.0
+HAL_REQUIRED=0.5.8
 DBUS_REQUIRED=0.70
 LIBNOTIFY_REQUIRED=0.4.3
 LIBWNCK_REQUIRED=2.10.0
@@ -112,6 +113,7 @@ dnl ---------------------------------------------------------------------------
 AC_SUBST(GLIB_REQUIRED)
 AC_SUBST(GTK_REQUIRED)
 AC_SUBST(GDK_REQUIRED)
+AC_SUBST(HAL_REQUIRED)
 AC_SUBST(DBUS_REQUIRED)
 AC_SUBST(LIBNOTIFY_REQUIRED)
 AC_SUBST(LIBWNCK_REQUIRED)
@@ -128,6 +130,10 @@ PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED gobject-2.0)
 AC_SUBST(GLIB_CFLAGS)
 AC_SUBST(GLIB_LIBS)
 
+PKG_CHECK_MODULES(HAL, hal >= $HAL_REQUIRED)
+AC_SUBST(HAL_CFLAGS)
+AC_SUBST(HAL_LIBS)
+
 PKG_CHECK_MODULES(CANBERRA, libcanberra-gtk >= $CANBERRA_REQUIRED)
 AC_SUBST(CANBERRA_CFLAGS)
 AC_SUBST(CANBERRA_LIBS)
@@ -602,6 +608,7 @@ src/Makefile
 applets/Makefile
 applets/brightness/Makefile
 applets/inhibit/Makefile
+libhal-glib/Makefile
 docs/Makefile
 man/Makefile
 help/Makefile
diff --git a/libhal-glib/.gitignore b/libhal-glib/.gitignore
new file mode 100644
index 0000000..36e653a
--- /dev/null
+++ b/libhal-glib/.gitignore
@@ -0,0 +1,9 @@
+*.la
+*.lo
+*.o
+.deps/
+.libs/
+Makefile.in
+hal-marshal.c
+hal-marshal.h
+
diff --git a/libhal-glib/Makefile.am b/libhal-glib/Makefile.am
new file mode 100644
index 0000000..22be87c
--- /dev/null
+++ b/libhal-glib/Makefile.am
@@ -0,0 +1,52 @@
+INCLUDES = \
+	$(GLIB_CFLAGS)						\
+	$(DBUS_CFLAGS)						\
+	-DEGG_LOG_FILE=\""~/gnome-power-manager.log"\"		\
+	-DEGG_VERBOSE="\"GPM_VERBOSE\""				\
+	-DEGG_LOGGING="\"GPM_LOGGING\""				\
+	-DEGG_CONSOLE="\"GPM_CONSOLE\""				\
+	-DPACKAGE_DATA_DIR=\""$(datadir)"\"			\
+	-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\"
+
+noinst_LTLIBRARIES =						\
+	libhal.la
+
+libhal_la_SOURCES =						\
+	egg-dbus-proxy.h					\
+	egg-dbus-proxy.c					\
+	egg-dbus-monitor.h					\
+	egg-dbus-monitor.c					\
+	egg-debug.h						\
+	egg-debug.c						\
+	hal-marshal.h						\
+	hal-marshal.c						\
+	hal-device.c						\
+	hal-device.h						\
+	hal-manager.c						\
+	hal-manager.h
+
+libhal_la_LIBADD =						\
+	$(DBUS_LIBS)						\
+	$(INTLLIBS)						\
+	$(GLIB_LIBS)
+
+EXTRA_DIST =							\
+	hal-marshal.list
+
+BUILT_SOURCES = 						\
+	hal-marshal.c						\
+	hal-marshal.h
+
+hal-marshal.c: hal-marshal.list
+	echo "#include \"hal-marshal.h\"" > $@ && \
+	@GLIB_GENMARSHAL@ $< --prefix=hal_marshal --body >> $@
+
+hal-marshal.h: hal-marshal.list
+	@GLIB_GENMARSHAL@ $< --prefix=hal_marshal --header > $@
+
+clean-local:
+	rm -f *~
+	rm -f hal-marshal.c hal-marshal.h
+
+CLEANFILES = $(BUILT_SOURCES)
+
diff --git a/libhal-glib/egg-dbus-monitor.c b/libhal-glib/egg-dbus-monitor.c
new file mode 120000
index 0000000..219defb
--- /dev/null
+++ b/libhal-glib/egg-dbus-monitor.c
@@ -0,0 +1 @@
+../src/egg-dbus-monitor.c
\ No newline at end of file
diff --git a/libhal-glib/egg-dbus-monitor.h b/libhal-glib/egg-dbus-monitor.h
new file mode 120000
index 0000000..29083a2
--- /dev/null
+++ b/libhal-glib/egg-dbus-monitor.h
@@ -0,0 +1 @@
+../src/egg-dbus-monitor.h
\ No newline at end of file
diff --git a/libhal-glib/egg-dbus-proxy.c b/libhal-glib/egg-dbus-proxy.c
new file mode 120000
index 0000000..41bdb44
--- /dev/null
+++ b/libhal-glib/egg-dbus-proxy.c
@@ -0,0 +1 @@
+../src/egg-dbus-proxy.c
\ No newline at end of file
diff --git a/libhal-glib/egg-dbus-proxy.h b/libhal-glib/egg-dbus-proxy.h
new file mode 120000
index 0000000..cd380ec
--- /dev/null
+++ b/libhal-glib/egg-dbus-proxy.h
@@ -0,0 +1 @@
+../src/egg-dbus-proxy.h
\ No newline at end of file
diff --git a/libhal-glib/egg-debug.c b/libhal-glib/egg-debug.c
new file mode 120000
index 0000000..0a3eb62
--- /dev/null
+++ b/libhal-glib/egg-debug.c
@@ -0,0 +1 @@
+../src/egg-debug.c
\ No newline at end of file
diff --git a/libhal-glib/egg-debug.h b/libhal-glib/egg-debug.h
new file mode 120000
index 0000000..db811d2
--- /dev/null
+++ b/libhal-glib/egg-debug.h
@@ -0,0 +1 @@
+../src/egg-debug.h
\ No newline at end of file
diff --git a/libhal-glib/hal-device.c b/libhal-glib/hal-device.c
new file mode 100644
index 0000000..3b471aa
--- /dev/null
+++ b/libhal-glib/hal-device.c
@@ -0,0 +1,262 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include "egg-debug.h"
+#include "egg-dbus-proxy.h"
+
+#include "hal-marshal.h"
+#include "hal-device.h"
+#include "hal-manager.h"
+
+static void     hal_device_class_init (HalDeviceClass *klass);
+static void     hal_device_init       (HalDevice      *device);
+static void     hal_device_finalize   (GObject	     *object);
+
+#define HAL_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HAL_TYPE_DEVICE, HalDevicePrivate))
+
+struct HalDevicePrivate
+{
+	DBusGConnection		*connection;
+	EggDbusProxy		*gproxy;
+	gchar			*udi;
+};
+
+/* Signals emitted from HalDevice are:
+ *
+ * device-added
+ * device-removed
+ * device-property-modified
+ * device-condition
+ * new-capability
+ * lost-capability
+ * daemon-start
+ * daemon-stop
+ */
+enum {
+	DEVICE_PROPERTY_MODIFIED,
+	DEVICE_CONDITION,
+	LAST_SIGNAL
+};
+
+static guint	     signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (HalDevice, hal_device, G_TYPE_OBJECT)
+
+/**
+ * hal_device_set_udi:
+ *
+ * Return value: TRUE for success, FALSE for failure
+ **/
+gboolean
+hal_device_set_udi (HalDevice  *device, const gchar *udi)
+{
+	DBusGProxy *proxy;
+	DBusGConnection *connection;
+
+	g_return_val_if_fail (HAL_IS_DEVICE (device), FALSE);
+	g_return_val_if_fail (udi != NULL, FALSE);
+
+	if (device->priv->udi != NULL) {
+		/* aready set UDI */
+		return FALSE;
+	}
+
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+	proxy = egg_dbus_proxy_assign (device->priv->gproxy, connection,
+				       HAL_DBUS_SERVICE, udi, HAL_DBUS_INTERFACE_DEVICE);
+	if (DBUS_IS_G_PROXY (proxy) == FALSE) {
+		g_warning ("proxy failed");
+		return FALSE;
+	}
+	device->priv->udi = g_strdup (udi);
+
+	return TRUE;
+}
+
+/**
+ * hal_device_get_bool:
+ *
+ * @hal_device: This class instance
+ * @key: The key to query
+ * @value: return value, passed by ref
+ * Return value: TRUE for success, FALSE for failure
+ **/
+gboolean
+hal_device_get_bool (HalDevice  *device,
+		      const gchar *key,
+		      gboolean    *value,
+		      GError     **error)
+{
+	gboolean ret;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (HAL_IS_DEVICE (device), FALSE);
+	g_return_val_if_fail (key != NULL, FALSE);
+	g_return_val_if_fail (value != NULL, FALSE);
+	g_return_val_if_fail (device->priv->udi != NULL, FALSE);
+
+	proxy = egg_dbus_proxy_get_proxy (device->priv->gproxy);
+	if (DBUS_IS_G_PROXY (proxy) == FALSE) {
+		g_warning ("proxy NULL!!");
+		return FALSE;
+	}
+	ret = dbus_g_proxy_call (proxy, "GetPropertyBoolean", error,
+				 G_TYPE_STRING, key,
+				 G_TYPE_INVALID,
+				 G_TYPE_BOOLEAN, value,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		*value = FALSE;
+	}
+	return ret;
+}
+
+/**
+ * hal_device_get_int:
+ *
+ * @hal_device: This class instance
+ * @key: The key to query
+ * @value: return value, passed by ref
+ * Return value: TRUE for success, FALSE for failure
+ **/
+static gboolean
+hal_device_get_int (HalDevice   *device,
+		     const gchar  *key,
+		     gint         *value,
+		     GError      **error)
+{
+	gboolean ret;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (HAL_IS_DEVICE (device), FALSE);
+	g_return_val_if_fail (key != NULL, FALSE);
+	g_return_val_if_fail (value != NULL, FALSE);
+	g_return_val_if_fail (device->priv->udi != NULL, FALSE);
+
+	proxy = egg_dbus_proxy_get_proxy (device->priv->gproxy);
+	if (DBUS_IS_G_PROXY (proxy) == FALSE) {
+		g_warning ("proxy NULL!!");
+		return FALSE;
+	}
+	ret = dbus_g_proxy_call (proxy, "GetPropertyInteger", error,
+				 G_TYPE_STRING, key,
+				 G_TYPE_INVALID,
+				 G_TYPE_INT, value,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		*value = 0;
+	}
+	return ret;
+}
+
+/**
+ * hal_device_get_uint:
+ *
+ * HAL has no concept of a UINT, only INT
+ **/
+gboolean
+hal_device_get_uint (HalDevice   *device,
+		      const gchar  *key,
+		      guint        *value,
+		      GError      **error)
+{
+	gint tvalue;
+	gboolean ret;
+
+	/* bodge */
+	ret = hal_device_get_int (device, key, &tvalue, error);
+	*value = (guint) tvalue;
+	return ret;
+}
+
+/**
+ * hal_device_class_init:
+ * @klass: This class instance
+ **/
+static void
+hal_device_class_init (HalDeviceClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = hal_device_finalize;
+	g_type_class_add_private (klass, sizeof (HalDevicePrivate));
+}
+
+/**
+ * hal_device_init:
+ *
+ * @hal_device: This class instance
+ **/
+static void
+hal_device_init (HalDevice *device)
+{
+	GError *error = NULL;
+
+	device->priv = HAL_DEVICE_GET_PRIVATE (device);
+
+	device->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (error != NULL) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+	/* get the manager connection */
+	device->priv->gproxy = egg_dbus_proxy_new ();
+}
+
+/**
+ * hal_device_finalize:
+ * @object: This class instance
+ **/
+static void
+hal_device_finalize (GObject *object)
+{
+	HalDevice *device;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (HAL_IS_DEVICE (object));
+
+	device = HAL_DEVICE (object);
+	device->priv = HAL_DEVICE_GET_PRIVATE (device);
+
+	g_object_unref (device->priv->gproxy);
+	g_free (device->priv->udi);
+
+	G_OBJECT_CLASS (hal_device_parent_class)->finalize (object);
+}
+
+/**
+ * hal_device_new:
+ * Return value: new HalDevice instance.
+ **/
+HalDevice *
+hal_device_new (void)
+{
+	HalDevice *device = g_object_new (HAL_TYPE_DEVICE, NULL);
+	return HAL_DEVICE (device);
+}
diff --git a/libhal-glib/hal-device.h b/libhal-glib/hal-device.h
new file mode 100644
index 0000000..def3a47
--- /dev/null
+++ b/libhal-glib/hal-device.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __HAL_DEVICE_H
+#define __HAL_DEVICE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define HAL_TYPE_DEVICE		(hal_device_get_type ())
+#define HAL_DEVICE(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), HAL_TYPE_DEVICE, HalDevice))
+#define HAL_DEVICE_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), HAL_TYPE_DEVICE, HalDeviceClass))
+#define HAL_IS_DEVICE(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), HAL_TYPE_DEVICE))
+#define HAL_IS_DEVICE_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), HAL_TYPE_DEVICE))
+#define HAL_DEVICE_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), HAL_TYPE_DEVICE, HalDeviceClass))
+
+typedef struct HalDevicePrivate HalDevicePrivate;
+
+typedef struct
+{
+	GObject		     parent;
+	HalDevicePrivate *priv;
+} HalDevice;
+
+/* Signals emitted from HalDevice are:
+ *
+ * device-property-modified
+ * device-condition
+ */
+
+typedef struct
+{
+	GObjectClass	parent_class;
+} HalDeviceClass;
+
+GType		 hal_device_get_type			(void);
+HalDevice	*hal_device_new				(void);
+
+gboolean	 hal_device_set_udi			(HalDevice	*device,
+							 const gchar	*udi);
+gboolean	 hal_device_get_bool			(HalDevice	*device,
+							 const gchar	*key,
+							 gboolean	*value,
+							 GError		**error);
+gboolean	 hal_device_get_uint			(HalDevice	*device,
+							 const gchar	*key,
+							 guint		*value,
+							 GError		**error);
+
+G_END_DECLS
+
+#endif	/* __HAL_DEVICE_H */
diff --git a/libhal-glib/hal-manager.c b/libhal-glib/hal-manager.c
new file mode 100644
index 0000000..ed50c91
--- /dev/null
+++ b/libhal-glib/hal-manager.c
@@ -0,0 +1,358 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include "egg-debug.h"
+#include "egg-dbus-proxy.h"
+
+#include "hal-marshal.h"
+#include "hal-device.h"
+#include "hal-manager.h"
+
+static void     hal_manager_class_init (HalManagerClass *klass);
+static void     hal_manager_init       (HalManager      *hal_manager);
+static void     hal_manager_finalize   (GObject	  *object);
+
+#define HAL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HAL_TYPE_MANAGER, HalManagerPrivate))
+
+struct HalManagerPrivate
+{
+	DBusGConnection		*connection;
+	HalDevice		*computer;
+	EggDbusProxy		*gproxy;
+};
+
+/* Signals emitted from HalManager are:
+ *
+ * device-added
+ * device-removed
+ * daemon-start
+ * daemon-stop
+ */
+enum {
+	DEVICE_ADDED,
+	DEVICE_REMOVED,
+	DAEMON_START,
+	DAEMON_STOP,
+	LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer hal_manager_object = NULL;
+
+G_DEFINE_TYPE (HalManager, hal_manager, G_TYPE_OBJECT)
+
+/**
+ * hal_manager_find_capability:
+ *
+ * @hal_manager: This class instance
+ * @capability: The capability, e.g. "battery"
+ * @value: return value, passed by ref
+ * Return value: TRUE for success, FALSE for failure
+ **/
+gboolean
+hal_manager_find_capability (HalManager *manager,
+			      const gchar *capability,
+			      gchar     ***value,
+			      GError     **error)
+{
+	DBusGProxy *proxy = NULL;
+	gboolean ret;
+
+	g_return_val_if_fail (HAL_IS_MANAGER (manager), FALSE);
+	g_return_val_if_fail (capability != NULL, FALSE);
+	g_return_val_if_fail (value != NULL, FALSE);
+
+	proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+					   HAL_DBUS_SERVICE,
+					   HAL_DBUS_PATH_MANAGER,
+					   HAL_DBUS_INTERFACE_MANAGER);
+	ret = dbus_g_proxy_call (proxy, "FindDeviceByCapability", error,
+				 G_TYPE_STRING, capability,
+				 G_TYPE_INVALID,
+				 G_TYPE_STRV, value,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		*value = NULL;
+	}
+	return ret;
+}
+
+/**
+ * hal_manager_class_init:
+ * @klass: This class instance
+ **/
+static void
+hal_manager_class_init (HalManagerClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = hal_manager_finalize;
+	g_type_class_add_private (klass, sizeof (HalManagerPrivate));
+
+	signals [DEVICE_ADDED] =
+		g_signal_new ("device-added",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (HalManagerClass, device_added),
+			      NULL,
+			      NULL,
+			      hal_marshal_VOID__STRING,
+			      G_TYPE_NONE,
+			      1, G_TYPE_STRING);
+
+	signals [DEVICE_REMOVED] =
+		g_signal_new ("device-removed",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (HalManagerClass, device_removed),
+			      NULL,
+			      NULL,
+			      hal_marshal_VOID__STRING,
+			      G_TYPE_NONE,
+			      1, G_TYPE_STRING);
+
+	signals [DAEMON_START] =
+		g_signal_new ("daemon-start",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (HalManagerClass, daemon_start),
+			      NULL,
+			      NULL,
+			      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+	signals [DAEMON_STOP] =
+		g_signal_new ("daemon-stop",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (HalManagerClass, daemon_stop),
+			      NULL,
+			      NULL,
+			      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+/**
+ * hal_manager_device_added_cb:
+ *
+ * @proxy: The org.freedesktop.Hal.Manager proxy
+ * @udi: Univerisal Device Id
+ * @manager: This class instance
+ *
+ * Invoked when a device is added.
+ */
+static void
+hal_manager_device_added_cb (DBusGProxy  *proxy,
+		              const gchar *udi,
+		              HalManager *manager)
+{
+	g_signal_emit (manager, signals [DEVICE_ADDED], 0, udi);
+}
+
+/**
+ * hal_manager_device_removed_cb:
+ *
+ * @proxy: The org.freedesktop.Hal.Manager proxy
+ * @udi: Univerisal Device Id
+ * @manager: This class instance
+ *
+ * Invoked when a device is removed.
+ */
+static void
+hal_manager_device_removed_cb (DBusGProxy  *proxy,
+		                const gchar *udi,
+		                HalManager *manager)
+{
+	g_signal_emit (manager, signals [DEVICE_REMOVED], 0, udi);
+}
+
+/**
+ * hal_manager_proxy_connect_more:
+ *
+ * @manager: This class instance
+ * Return value: Success
+ *
+ * Connect the manager proxy to HAL and register some basic callbacks
+ */
+static gboolean
+hal_manager_proxy_connect_more (HalManager *manager)
+{
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (HAL_IS_MANAGER (manager), FALSE);
+
+	proxy = egg_dbus_proxy_get_proxy (manager->priv->gproxy);
+	if (DBUS_IS_G_PROXY (proxy) == FALSE) {
+		g_warning ("proxy NULL!!");
+		return FALSE;
+	}
+
+	/* connect the org.freedesktop.Hal.Manager signals */
+	dbus_g_proxy_add_signal (proxy, "DeviceAdded",
+				 G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (proxy, "DeviceAdded",
+				     G_CALLBACK (hal_manager_device_added_cb), manager, NULL);
+
+	dbus_g_proxy_add_signal (proxy, "DeviceRemoved",
+				 G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (proxy, "DeviceRemoved",
+				     G_CALLBACK (hal_manager_device_removed_cb), manager, NULL);
+
+	return TRUE;
+}
+
+/**
+ * hal_manager_proxy_disconnect_more:
+ *
+ * @manager: This class instance
+ * Return value: Success
+ *
+ * Disconnect the manager proxy to HAL_MANAGER and disconnect some basic callbacks
+ */
+static gboolean
+hal_manager_proxy_disconnect_more (HalManager *manager)
+{
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (HAL_IS_MANAGER (manager), FALSE);
+
+	proxy = egg_dbus_proxy_get_proxy (manager->priv->gproxy);
+	if (DBUS_IS_G_PROXY (proxy) == FALSE) {
+		g_warning ("proxy NULL!!");
+		return FALSE;
+	}
+
+	dbus_g_proxy_disconnect_signal (proxy, "DeviceRemoved",
+					G_CALLBACK (hal_manager_device_removed_cb), manager);
+
+	return TRUE;
+}
+
+/**
+ * proxy_status_cb:
+ * @proxy: The dbus raw proxy
+ * @status: The status of the service, where TRUE is connected
+ * @manager: This class instance
+ **/
+static void
+proxy_status_cb (DBusGProxy    *proxy,
+		 gboolean       status,
+		 HalManager *manager)
+{
+	g_return_if_fail (HAL_IS_MANAGER (manager));
+	if (status) {
+		g_signal_emit (manager, signals [DAEMON_START], 0);
+		hal_manager_proxy_connect_more (manager);
+	} else {
+		g_signal_emit (manager, signals [DAEMON_STOP], 0);
+		hal_manager_proxy_disconnect_more (manager);
+	}
+}
+
+/**
+ * hal_manager_init:
+ *
+ * @manager: This class instance
+ **/
+static void
+hal_manager_init (HalManager *manager)
+{
+	GError *error = NULL;
+	DBusGProxy *proxy;
+	DBusGConnection *connection;
+	gboolean ret;
+
+	manager->priv = HAL_MANAGER_GET_PRIVATE (manager);
+
+	manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (error) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+	/* get the manager connection */
+	manager->priv->gproxy = egg_dbus_proxy_new ();
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+	proxy = egg_dbus_proxy_assign (manager->priv->gproxy, connection,
+				       HAL_DBUS_SERVICE, HAL_DBUS_PATH_MANAGER,
+				       HAL_DBUS_INTERFACE_MANAGER);
+	if (DBUS_IS_G_PROXY (proxy) == FALSE) {
+		g_warning ("Either HAL or DBUS are not working!");
+		exit (0);
+	}
+
+	g_signal_connect (manager->priv->gproxy, "proxy-status",
+			  G_CALLBACK (proxy_status_cb), manager);
+
+	/* use the computer object */
+	manager->priv->computer = hal_device_new();
+	ret = hal_device_set_udi (manager->priv->computer, HAL_ROOT_COMPUTER);
+	if (!ret) {
+		g_warning ("failed to get Computer root object");
+	}
+
+	/* blindly try to connect, assuming HAL is alive */
+	hal_manager_proxy_connect_more (manager);
+}
+
+/**
+ * hal_manager_finalize:
+ * @object: This class instance
+ **/
+static void
+hal_manager_finalize (GObject *object)
+{
+	HalManager *manager;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (HAL_IS_MANAGER (object));
+
+	manager = HAL_MANAGER (object);
+	manager->priv = HAL_MANAGER_GET_PRIVATE (manager);
+
+	g_object_unref (manager->priv->gproxy);
+	g_object_unref (manager->priv->computer);
+
+	G_OBJECT_CLASS (hal_manager_parent_class)->finalize (object);
+}
+
+/**
+ * hal_manager_new:
+ * Return value: new HalManager instance.
+ **/
+HalManager *
+hal_manager_new (void)
+{
+	if (hal_manager_object != NULL) {
+		g_object_ref (hal_manager_object);
+	} else {
+		hal_manager_object = g_object_new (HAL_TYPE_MANAGER, NULL);
+		g_object_add_weak_pointer (hal_manager_object, &hal_manager_object);
+	}
+	return HAL_MANAGER (hal_manager_object);
+}
+
diff --git a/libhal-glib/hal-manager.h b/libhal-glib/hal-manager.h
new file mode 100644
index 0000000..cc331fc
--- /dev/null
+++ b/libhal-glib/hal-manager.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2006 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __HAL_MANAGER_H
+#define __HAL_MANAGER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define	HAL_DBUS_SERVICE		 	"org.freedesktop.Hal"
+#define	HAL_DBUS_PATH_MANAGER		 	"/org/freedesktop/Hal/Manager"
+#define	HAL_DBUS_INTERFACE_MANAGER	 	"org.freedesktop.Hal.Manager"
+#define	HAL_DBUS_INTERFACE_DEVICE	 	"org.freedesktop.Hal.Device"
+#define	HAL_DBUS_INTERFACE_LAPTOP_PANEL	 	"org.freedesktop.Hal.Device.LaptopPanel"
+#define	HAL_DBUS_INTERFACE_POWER	 	"org.freedesktop.Hal.Device.SystemPowerManagement"
+#define	HAL_DBUS_INTERFACE_CPUFREQ	 	"org.freedesktop.Hal.Device.CPUFreq"
+#define	HAL_DBUS_INTERFACE_KBD_BACKLIGHT 	"org.freedesktop.Hal.Device.KeyboardBacklight"
+#define	HAL_DBUS_INTERFACE_LIGHT_SENSOR	 	"org.freedesktop.Hal.Device.LightSensor"
+#define HAL_ROOT_COMPUTER		 	"/org/freedesktop/Hal/devices/computer"
+
+#define HAL_TYPE_MANAGER		(hal_manager_get_type ())
+#define HAL_MANAGER(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), HAL_TYPE_MANAGER, HalManager))
+#define HAL_MANAGER_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), HAL_TYPE_MANAGER, HalManagerClass))
+#define HAL_IS_MANAGER(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), HAL_TYPE_MANAGER))
+#define HAL_IS_MANAGER_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), HAL_TYPE_MANAGER))
+#define HAL_MANAGER_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), HAL_TYPE_MANAGER, HalManagerClass))
+
+typedef struct HalManagerPrivate HalManagerPrivate;
+
+typedef struct
+{
+	GObject			 parent;
+	HalManagerPrivate	*priv;
+} HalManager;
+
+/* Signals emitted from HalManager are:
+ *
+ * device-added
+ * device-removed
+ * new-capability
+ * lost-capability
+ * daemon-start
+ * daemon-stop
+ */
+
+typedef struct
+{
+	GObjectClass	parent_class;
+	void		(* device_added)		(HalManager	*manager,
+							 const gchar	*udi);
+	void		(* device_removed)		(HalManager	*manager,
+							 const gchar	*udi);
+	void		(* daemon_start)		(HalManager	*manager);
+	void		(* daemon_stop)			(HalManager	*manager);
+} HalManagerClass;
+
+GType		 hal_manager_get_type			(void);
+HalManager	*hal_manager_new			(void);
+
+gboolean	 hal_manager_find_capability		(HalManager	*manager,
+							 const gchar	*capability,
+							 gchar     	***value,
+							 GError		**error);
+
+G_END_DECLS
+
+#endif	/* __HAL_MANAGER_H */
diff --git a/libhal-glib/hal-marshal.list b/libhal-glib/hal-marshal.list
new file mode 100644
index 0000000..e5eb3da
--- /dev/null
+++ b/libhal-glib/hal-marshal.list
@@ -0,0 +1,9 @@
+NONE:INT,BOXED
+NONE:STRING,STRING
+NONE:STRING,STRING,STRING
+NONE:STRING,BOOLEAN
+NONE:STRING,STRING,BOOLEAN
+NONE:STRING,BOOLEAN,BOOLEAN,BOOLEAN
+NONE:INT
+NONE:STRING
+NONE:INT,LONG,BOOLEAN,BOOLEAN
diff --git a/src/Makefile.am b/src/Makefile.am
index 8295f32..f0af417 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,7 @@ EXTRA_DIST =						\
 
 INCLUDES =						\
 	$(GLIB_CFLAGS)					\
+	$(HAL_CFLAGS)					\
 	$(DBUS_CFLAGS)					\
 	$(GNOME_CFLAGS)					\
 	$(UNIQUE_CFLAGS)				\
@@ -36,8 +37,12 @@ INCLUDES =						\
 	-DEGG_LOGGING="\"GPM_LOGGING\""			\
 	-DEGG_CONSOLE="\"GPM_CONSOLE\""			\
 	-I$(top_srcdir)					\
+	-I$(top_srcdir)/libhal-glib			\
 	$(NULL)
 
+LOCAL_LIBHAL_LIBS =					\
+	$(top_builddir)/libhal-glib/libhal.la
+
 bin_PROGRAMS =						\
 	gnome-power-manager				\
 	gnome-power-preferences				\
@@ -117,10 +122,12 @@ gnome_power_preferences_SOURCES =			\
 gnome_power_preferences_LDADD =				\
 	$(GLIB_LIBS)					\
 	$(GNOME_LIBS)					\
+	$(HAL_LIBS)					\
 	$(DBUS_LIBS)					\
 	$(UNIQUE_LIBS)					\
 	$(POLKIT_GNOME_LIBS)				\
 	$(GPM_EXTRA_LIBS)				\
+	$(LOCAL_LIBHAL_LIBS)				\
 	$(DEVKIT_LIBS)					\
 	$(NULL)
 
@@ -165,6 +172,8 @@ gnome_power_manager_SOURCES =				\
 	gpm-button.c					\
 	gpm-brightness.h				\
 	gpm-brightness.c				\
+	gpm-brightness-hal.h				\
+	gpm-brightness-hal.c				\
 	gpm-brightness-xrandr.h				\
 	gpm-brightness-xrandr.c				\
 	gpm-brightness-dkp.h				\
@@ -200,12 +209,14 @@ gnome_power_manager_LDADD =				\
 	$(GLIB_LIBS)					\
 	$(GSTREAMER_LIBS)				\
 	$(GNOME_LIBS)					\
+	$(HAL_LIBS)					\
 	$(POLKIT_LIBS)					\
 	$(DBUS_LIBS)					\
 	$(XRANDR_LIBS)					\
 	$(CANBERRA_LIBS)				\
 	$(LIBNOTIFY_LIBS)				\
 	$(GPM_EXTRA_LIBS)				\
+	$(LOCAL_LIBHAL_LIBS)				\
 	$(DEVKIT_LIBS)					\
 	$(NULL)
 
@@ -275,6 +286,7 @@ gnome_power_self_test_LDADD =				\
 	$(DEVKIT_LIBS)					\
 	$(DBUS_LIBS)					\
 	$(LIBNOTIFY_LIBS)				\
+	$(LOCAL_LIBHAL_LIBS)				\
 	$(GPM_EXTRA_LIBS)				\
 	$(NULL)
 
diff --git a/src/gpm-brightness-hal.c b/src/gpm-brightness-hal.c
new file mode 100644
index 0000000..546f47f
--- /dev/null
+++ b/src/gpm-brightness-hal.c
@@ -0,0 +1,528 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include <hal-device.h>
+#include <hal-manager.h>
+#include "egg-dbus-proxy.h"
+
+#include "egg-debug.h"
+#include "egg-discrete.h"
+
+#include "gpm-brightness.h"
+#include "gpm-brightness-hal.h"
+#include "gpm-common.h"
+#include "gpm-marshal.h"
+
+#define GPM_BRIGHTNESS_HAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_BRIGHTNESS_HAL, GpmBrightnessHalPrivate))
+
+struct GpmBrightnessHalPrivate
+{
+	guint			 last_set_hw;
+	guint			 level_std_hw;
+	guint			 levels;
+	gchar			*udi;
+	gboolean		 hw_changed;
+	EggDbusProxy		*gproxy;
+
+ 	/* true if hardware automatically sets brightness in response to
+ 	 * key press events */
+ 	gboolean		 does_own_updates;
+};
+
+enum {
+	BRIGHTNESS_CHANGED,
+	LAST_SIGNAL
+};
+
+G_DEFINE_TYPE (GpmBrightnessHal, gpm_brightness_hal, G_TYPE_OBJECT)
+static guint signals [LAST_SIGNAL] = { 0 };
+
+/**
+ * gpm_brightness_hal_get_hw:
+ * @brightness: This brightness class instance
+ *
+ * Updates the private local value of value_hw as it may have
+ * changed on some h/w
+ * Return value: Success.
+ **/
+static gboolean
+gpm_brightness_hal_get_hw (GpmBrightnessHal *brightness, guint *value_hw)
+{
+	GError *error = NULL;
+	gboolean ret;
+	DBusGProxy *proxy;
+	gint level = 0;
+
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+
+	proxy = egg_dbus_proxy_get_proxy (brightness->priv->gproxy);
+	if (proxy == NULL) {
+		egg_warning ("not connected to HAL");
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "GetBrightness", &error,
+				 G_TYPE_INVALID,
+				 G_TYPE_INT, &level,
+				 G_TYPE_INVALID);
+
+	if (value_hw != NULL) {
+		*value_hw = (guint)level;
+	}
+
+	if (error) {
+		egg_debug ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (!ret) {
+		/* abort as the DBUS method failed */
+		egg_warning ("GetBrightness failed!");
+		return FALSE;
+	}
+	egg_debug ("GetBrightness returned level: %i", level);
+
+	return TRUE;
+}
+
+/**
+ * gpm_brightness_hal_set_hw:
+ * @brightness: This brightness class instance
+ * @value_hw: The hardware level in raw units
+ *
+ * Sets the hardware value to a new number.
+ *
+ * Return value: Success.
+ **/
+static gboolean
+gpm_brightness_hal_set_hw (GpmBrightnessHal *brightness, guint value_hw)
+{
+	GError *error = NULL;
+	gboolean ret;
+	DBusGProxy *proxy;
+	gint retval;
+
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+
+	proxy = egg_dbus_proxy_get_proxy (brightness->priv->gproxy);
+	if (proxy == NULL) {
+		egg_warning ("not connected to HAL");
+		return FALSE;
+	}
+
+	if (value_hw > brightness->priv->levels - 1) {
+		egg_warning ("set outside range (%i of %i)",
+			     value_hw, brightness->priv->levels - 1);
+		return FALSE;
+	}
+
+	egg_debug ("Setting %i of %i", value_hw, brightness->priv->levels - 1);
+
+	ret = dbus_g_proxy_call (proxy, "SetBrightness", &error,
+				 G_TYPE_INT, (gint)value_hw,
+				 G_TYPE_INVALID,
+				 G_TYPE_INT, &retval,
+				 G_TYPE_INVALID);
+	/* retval is ignored, the HAL API is broken... */
+
+	if (error) {
+		egg_debug ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (!ret) {
+		/* abort as the DBUS method failed */
+		egg_warning ("SetBrightness failed!");
+		return FALSE;
+	}
+
+	/* we changed the hardware */
+	if (ret) {
+		brightness->priv->hw_changed = TRUE;
+	}
+
+	brightness->priv->last_set_hw = value_hw;
+	return TRUE;
+}
+
+/**
+ * gpm_brightness_hal_dim_hw_step:
+ * @brightness: This brightness class instance
+ * @new_level_hw: The new hardware level
+ *
+ * Just do the step up and down, after knowing the step interval
+ **/
+static gboolean
+gpm_brightness_hal_dim_hw_step (GpmBrightnessHal *brightness, guint new_level_hw, guint step_interval)
+{
+	guint last_set_hw;
+	gint a;
+	gboolean ret = FALSE;
+
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+
+	last_set_hw = brightness->priv->last_set_hw;
+	egg_debug ("new_level_hw=%i, last_set_hw=%i", new_level_hw, last_set_hw);
+
+	/* we do the step interval as we can have insane levels of brightness */
+	if (new_level_hw == last_set_hw) {
+		return FALSE;
+	}
+
+	if (new_level_hw > last_set_hw) {
+		/* going up */
+		for (a=last_set_hw; a <= (gint) new_level_hw; a+=step_interval) {
+			ret = gpm_brightness_hal_set_hw (brightness, a);
+			/* we failed the last brightness set command, don't keep trying */
+			if (!ret) {
+				break;
+			}
+			g_usleep (1000 * GPM_BRIGHTNESS_DIM_INTERVAL);
+		}
+	} else {
+		/* going down */
+		for (a=last_set_hw; (gint) (a + 1) > (gint) new_level_hw; a-=step_interval) {
+			ret = gpm_brightness_hal_set_hw (brightness, a);
+			/* we failed the last brightness set command, don't keep trying */
+			if (!ret) {
+				break;
+			}
+			g_usleep (1000 * GPM_BRIGHTNESS_DIM_INTERVAL);
+		}
+	}
+	return ret;
+}
+
+/**
+ * gpm_brightness_hal_dim_hw:
+ * @brightness: This brightness class instance
+ * @new_level_hw: The new hardware level
+ **/
+static gboolean
+gpm_brightness_hal_dim_hw (GpmBrightnessHal *brightness, guint new_level_hw)
+{
+	guint step;
+
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+
+	egg_debug ("new_level_hw=%i", new_level_hw);
+
+	/* macbook pro has a bazzillion brightness levels, be a bit clever */
+	step = gpm_brightness_get_step (brightness->priv->levels);
+	return gpm_brightness_hal_dim_hw_step (brightness, new_level_hw, step);
+}
+
+/**
+ * gpm_brightness_hal_set:
+ * @brightness: This brightness class instance
+ * @percentage: The percentage brightness
+ * @hw_changed: If the hardware was changed, i.e. the brightness changed
+ * Return value: %TRUE if success, %FALSE if there was an error
+ **/
+gboolean
+gpm_brightness_hal_set (GpmBrightnessHal *brightness, guint percentage, gboolean *hw_changed)
+{
+	guint level_hw;
+	gboolean ret;
+
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+	g_return_val_if_fail (hw_changed != NULL, FALSE);
+
+	/* reset to not-changed */
+	brightness->priv->hw_changed = FALSE;
+
+	level_hw = egg_discrete_from_percent (percentage, brightness->priv->levels);
+	brightness->priv->level_std_hw = level_hw;
+
+	/* update */
+	ret = gpm_brightness_hal_dim_hw (brightness, level_hw);
+
+	/* did the hardware have to be modified? */
+	*hw_changed = brightness->priv->hw_changed;
+	return ret;
+}
+
+/**
+ * gpm_brightness_hal_get:
+ * @brightness: This brightness class instance
+ * Return value: The percentage brightness, or -1 for no hardware or error
+ *
+ * Gets the current (or at least what this class thinks is current) percentage
+ * brightness. This is quick as no HAL inquiry is done.
+ **/
+gboolean
+gpm_brightness_hal_get (GpmBrightnessHal *brightness, guint *percentage)
+{
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+
+	*percentage = egg_discrete_to_percent (brightness->priv->last_set_hw,
+					       brightness->priv->levels);
+	return TRUE;
+}
+
+/**
+ * gpm_brightness_hal_up:
+ * @brightness: This brightness class instance
+ * @hw_changed: If the hardware was changed, i.e. the brightness changed
+ * Return value: %TRUE if success, %FALSE if there was an error
+ *
+ * If possible, put the brightness of the LCD up one unit.
+ **/
+gboolean
+gpm_brightness_hal_up (GpmBrightnessHal *brightness, gboolean *hw_changed)
+{
+	gboolean ret = FALSE;
+	gint step;
+	guint current_hw;
+
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+	g_return_val_if_fail (hw_changed != NULL, FALSE);
+
+	/* reset to not-changed */
+	brightness->priv->hw_changed = FALSE;
+
+	/* check to see if the panel has changed */
+	gpm_brightness_hal_get_hw (brightness, &current_hw);
+
+	/* the panel has been updated in firmware */
+	if (current_hw != brightness->priv->last_set_hw || 
+            brightness->priv->does_own_updates) {
+		brightness->priv->last_set_hw = current_hw;
+		ret = TRUE;
+	} else {
+		/* macbook pro has a bazzillion brightness levels, be a bit clever */
+		step = gpm_brightness_get_step (brightness->priv->levels);
+		/* don't overflow */
+		if (brightness->priv->last_set_hw + step > brightness->priv->levels - 1) {
+			step = (brightness->priv->levels - 1) - brightness->priv->last_set_hw;
+		}
+		ret = gpm_brightness_hal_set_hw (brightness, brightness->priv->last_set_hw + step);
+	}
+
+	/* did the hardware have to be modified? */
+	*hw_changed = brightness->priv->hw_changed;
+	return ret;
+}
+
+/**
+ * gpm_brightness_hal_down:
+ * @brightness: This brightness class instance
+ * @hw_changed: If the hardware was changed, i.e. the brightness changed
+ * Return value: %TRUE if success, %FALSE if there was an error
+ *
+ * If possible, put the brightness of the LCD down one unit.
+ **/
+gboolean
+gpm_brightness_hal_down (GpmBrightnessHal *brightness, gboolean *hw_changed)
+{
+	gboolean ret = FALSE;
+	gint step;
+	guint current_hw;
+
+	g_return_val_if_fail (GPM_IS_BRIGHTNESS_HAL (brightness), FALSE);
+	g_return_val_if_fail (hw_changed != NULL, FALSE);
+
+	/* reset to not-changed */
+	brightness->priv->hw_changed = FALSE;
+
+	/* check to see if the panel has changed */
+	gpm_brightness_hal_get_hw (brightness, &current_hw);
+
+	/* the panel has been updated in firmware */
+ 	if (current_hw != brightness->priv->last_set_hw ||
+              brightness->priv->does_own_updates) {
+		brightness->priv->last_set_hw = current_hw;
+		ret = TRUE;
+	} else {
+		/* macbook pro has a bazzillion brightness levels, be a bit clever */
+		step = gpm_brightness_get_step (brightness->priv->levels);
+		/* don't underflow */
+		if ((gint) brightness->priv->last_set_hw < step) {
+			step = brightness->priv->last_set_hw;
+		}
+		ret = gpm_brightness_hal_set_hw (brightness, brightness->priv->last_set_hw - step);
+	}
+
+
+	/* did the hardware have to be modified? */
+	*hw_changed = brightness->priv->hw_changed;
+	return ret;
+}
+
+/**
+ * gpm_brightness_hal_has_hw:
+ **/
+gboolean
+gpm_brightness_hal_has_hw (GpmBrightnessHal *brightness)
+{
+	return (brightness->priv->gproxy != NULL);
+}
+
+/**
+ * gpm_brightness_hal_finalize:
+ **/
+static void
+gpm_brightness_hal_finalize (GObject *object)
+{
+	GpmBrightnessHal *brightness;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GPM_IS_BRIGHTNESS_HAL (object));
+	brightness = GPM_BRIGHTNESS_HAL (object);
+
+	if (brightness->priv->udi != NULL) {
+		g_free (brightness->priv->udi);
+	}
+	if (brightness->priv->gproxy != NULL) {
+		g_object_unref (brightness->priv->gproxy);
+	}
+
+	G_OBJECT_CLASS (gpm_brightness_hal_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_brightness_hal_class_init:
+ **/
+static void
+gpm_brightness_hal_class_init (GpmBrightnessHalClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = gpm_brightness_hal_finalize;
+
+	signals [BRIGHTNESS_CHANGED] =
+		g_signal_new ("brightness-changed",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GpmBrightnessHalClass, brightness_changed),
+			      NULL, NULL, g_cclosure_marshal_VOID__UINT,
+			      G_TYPE_NONE, 1, G_TYPE_UINT);
+
+	g_type_class_add_private (klass, sizeof (GpmBrightnessHalPrivate));
+}
+
+/**
+ * gpm_brightness_hal_init:
+ * @brightness: This brightness class instance
+ *
+ * initialises the brightness class. NOTE: We expect laptop_panel objects
+ * to *NOT* be removed or added during the session.
+ * We only control the first laptop_panel object if there are more than one.
+ **/
+static void
+gpm_brightness_hal_init (GpmBrightnessHal *brightness)
+{
+	gchar **names;
+	HalManager *manager;
+	HalDevice *device;
+	gboolean res;
+	DBusGConnection *connection;
+
+	brightness->priv = GPM_BRIGHTNESS_HAL_GET_PRIVATE (brightness);
+	brightness->priv->gproxy = NULL;
+	brightness->priv->hw_changed = FALSE;
+
+	/* save udi of lcd adapter */
+	manager = hal_manager_new ();
+	hal_manager_find_capability (manager, "laptop_panel", &names, NULL);
+	g_object_unref (manager);
+	if (names == NULL || names[0] == NULL) {
+		egg_warning ("No devices of capability laptop_panel");
+		return;
+	}
+
+	/* We only want first laptop_panel object (should only be one) */
+	brightness->priv->udi = g_strdup (names[0]);
+	g_strfreev (names);
+
+	device = hal_device_new ();
+	hal_device_set_udi (device, brightness->priv->udi);
+
+	/* get levels that the adapter supports -- this does not change ever */
+	hal_device_get_uint (device, "laptop_panel.num_levels",
+			      &brightness->priv->levels, NULL);
+	egg_debug ("Laptop panel levels: %i", brightness->priv->levels);
+	if (brightness->priv->levels == 0 || brightness->priv->levels > 256) {
+		egg_warning ("Laptop panel levels are invalid!");
+	}
+
+	/* Check if hardware handles brightness changes automatically */
+	res = hal_device_get_bool (device, 
+				    "laptop_panel.brightness_in_hardware",
+			            &brightness->priv->does_own_updates, NULL);
+
+	if (!res) {
+		brightness->priv->does_own_updates = FALSE;
+		egg_debug ("laptop_panel.brightness_in_hardware not found. "
+			   "Assuming false");
+	} else {
+		if (brightness->priv->does_own_updates) {
+			egg_debug ("laptop_panel.brightness_in_hardware: True");
+		} else {
+			egg_debug ("laptop_panel.brightness_in_hardware: False");
+		}
+	}
+
+	g_object_unref (device);
+
+	/* get a managed proxy */
+	brightness->priv->gproxy = egg_dbus_proxy_new ();
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+	egg_dbus_proxy_assign (brightness->priv->gproxy, connection, HAL_DBUS_SERVICE,
+			       brightness->priv->udi, HAL_DBUS_INTERFACE_LAPTOP_PANEL);
+
+	/* this changes under our feet */
+	gpm_brightness_hal_get_hw (brightness, &brightness->priv->last_set_hw);
+
+	/* set to known value */
+	brightness->priv->level_std_hw = 0;
+
+	egg_debug ("Starting: (%i of %i)", brightness->priv->last_set_hw,
+		   brightness->priv->levels - 1);
+}
+
+/**
+ * gpm_brightness_hal_new:
+ * Return value: A new brightness class instance.
+ * Can return NULL if no suitable hardware is found.
+ **/
+GpmBrightnessHal *
+gpm_brightness_hal_new (void)
+{
+	GpmBrightnessHal *brightness;
+	brightness = g_object_new (GPM_TYPE_BRIGHTNESS_HAL, NULL);
+	return GPM_BRIGHTNESS_HAL (brightness);
+}
+
diff --git a/src/gpm-brightness-hal.h b/src/gpm-brightness-hal.h
new file mode 100644
index 0000000..131fba8
--- /dev/null
+++ b/src/gpm-brightness-hal.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GPM_BRIGHTNESS_HAL_H
+#define __GPM_BRIGHTNESS_HAL_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_BRIGHTNESS_HAL		(gpm_brightness_hal_get_type ())
+#define GPM_BRIGHTNESS_HAL(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_BRIGHTNESS_HAL, GpmBrightnessHal))
+#define GPM_BRIGHTNESS_HAL_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_BRIGHTNESS_HAL, GpmBrightnessHalClass))
+#define GPM_IS_BRIGHTNESS_HAL(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_BRIGHTNESS_HAL))
+#define GPM_IS_BRIGHTNESS_HAL_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_BRIGHTNESS_HAL))
+#define GPM_BRIGHTNESS_HAL_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_BRIGHTNESS_HAL, GpmBrightnessHalClass))
+
+typedef struct GpmBrightnessHalPrivate GpmBrightnessHalPrivate;
+
+typedef struct
+{
+	GObject			 	 parent;
+	GpmBrightnessHalPrivate		*priv;
+} GpmBrightnessHal;
+
+typedef struct
+{
+	GObjectClass	parent_class;
+	void		(* brightness_changed)	(GpmBrightnessHal	*brightness,
+						 guint			 percentage);
+} GpmBrightnessHalClass;
+
+GType		 gpm_brightness_hal_get_type	(void);
+GpmBrightnessHal *gpm_brightness_hal_new	(void);
+
+gboolean	 gpm_brightness_hal_has_hw	(GpmBrightnessHal	*brightness);
+gboolean	 gpm_brightness_hal_up		(GpmBrightnessHal	*brightness,
+						 gboolean		*hw_changed);
+gboolean	 gpm_brightness_hal_down	(GpmBrightnessHal	*brightness,
+						 gboolean		*hw_changed);
+gboolean	 gpm_brightness_hal_get		(GpmBrightnessHal	*brightness,
+						 guint			*percentage);
+gboolean	 gpm_brightness_hal_set		(GpmBrightnessHal	*brightness,
+						 guint			 percentage,
+						 gboolean		*hw_changed);
+
+G_END_DECLS
+
+#endif /* __GPM_BRIGHTNESS_HAL_H */
diff --git a/src/gpm-brightness.c b/src/gpm-brightness.c
index 2c576ca..5a574da 100644
--- a/src/gpm-brightness.c
+++ b/src/gpm-brightness.c
@@ -36,6 +36,7 @@
 #endif /* HAVE_UNISTD_H */
 
 #include "gpm-brightness.h"
+#include "gpm-brightness-hal.h"
 #include "gpm-brightness-dkp.h"
 #include "gpm-brightness-xrandr.h"
 #include "gpm-common.h"
@@ -48,10 +49,12 @@
 struct GpmBrightnessPrivate
 {
 	gboolean		 use_xrandr;
+	gboolean		 use_hal;
 	gboolean		 use_dkp;
 	gboolean		 has_changed_events;
 	gboolean		 cache_trusted;
 	guint			 cache_percentage;
+	GpmBrightnessHal	*hal;
 	GpmBrightnessDkp	*dkp;
 	GpmBrightnessXRandR	*xrandr;
 };
@@ -132,7 +135,7 @@ gpm_brightness_set (GpmBrightness *brightness, guint percentage, gboolean *hw_ch
 		ret = gpm_brightness_xrandr_set (brightness->priv->xrandr, percentage, &hw_changed_local);
 		if (ret)
 			goto out;
-		egg_warning ("failed to set using xrandr, falling back to DeviceKit-power");
+		egg_warning ("failed to set using xrandr, falling back to HAL");
 		brightness->priv->use_xrandr = FALSE;
 	}
 	if (brightness->priv->use_dkp) {
@@ -141,6 +144,12 @@ gpm_brightness_set (GpmBrightness *brightness, guint percentage, gboolean *hw_ch
 			goto out;
 		egg_warning ("failed to set using DeviceKit-power");
 	}
+	if (brightness->priv->use_hal) {
+		ret = gpm_brightness_hal_set (brightness->priv->hal, percentage, &hw_changed_local);
+		if (ret)
+			goto out;
+		egg_warning ("failed to set using HAL");
+	}
 	egg_debug ("no hardware support");
 	return FALSE;
 out:
@@ -185,7 +194,7 @@ gpm_brightness_get (GpmBrightness *brightness, guint *percentage)
 		ret = gpm_brightness_xrandr_get (brightness->priv->xrandr, &percentage_local);
 		if (ret)
 			goto out;
-		egg_warning ("failed to set using xrandr, falling back to DeviceKit-power");
+		egg_warning ("failed to set using xrandr, falling back to HAL");
 		brightness->priv->use_xrandr = FALSE;
 	}
 	if (brightness->priv->use_dkp) {
@@ -194,6 +203,12 @@ gpm_brightness_get (GpmBrightness *brightness, guint *percentage)
 			goto out;
 		egg_warning ("failed to set using DeviceKit-power");
 	}
+	if (brightness->priv->use_hal) {
+		ret = gpm_brightness_hal_get (brightness->priv->hal, &percentage_local);
+		if (ret)
+			goto out;
+		egg_warning ("failed to set using HAL");
+	}
 	egg_debug ("no hardware support");
 	return FALSE;
 out:
@@ -233,7 +248,7 @@ gpm_brightness_up (GpmBrightness *brightness, gboolean *hw_changed)
 		ret = gpm_brightness_xrandr_up (brightness->priv->xrandr, &hw_changed_local);
 		if (ret)
 			goto out;
-		egg_warning ("failed to set using xrandr, falling back to DeviceKit-power");
+		egg_warning ("failed to set using xrandr, falling back to HAL");
 		brightness->priv->use_xrandr = FALSE;
 	}
 	if (brightness->priv->use_dkp) {
@@ -242,6 +257,12 @@ gpm_brightness_up (GpmBrightness *brightness, gboolean *hw_changed)
 			goto out;
 		egg_warning ("failed to set using DeviceKit-power");
 	}
+	if (brightness->priv->use_hal) {
+		ret = gpm_brightness_hal_up (brightness->priv->hal, &hw_changed_local);
+		if (ret)
+			goto out;
+		egg_warning ("failed to set using HAL");
+	}
 	egg_debug ("no hardware support");
 	return FALSE;
 out:
@@ -275,7 +296,7 @@ gpm_brightness_down (GpmBrightness *brightness, gboolean *hw_changed)
 		ret = gpm_brightness_xrandr_down (brightness->priv->xrandr, &hw_changed_local);
 		if (ret)
 			goto out;
-		egg_warning ("failed to set using xrandr, falling back to DeviceKit-power");
+		egg_warning ("failed to set using xrandr, falling back to HAL");
 		brightness->priv->use_xrandr = FALSE;
 	}
 	if (brightness->priv->use_dkp) {
@@ -284,6 +305,12 @@ gpm_brightness_down (GpmBrightness *brightness, gboolean *hw_changed)
 			goto out;
 		egg_warning ("failed to set using DeviceKit-power");
 	}
+	if (brightness->priv->use_hal) {
+		ret = gpm_brightness_hal_down (brightness->priv->hal, &hw_changed_local);
+		if (ret)
+			goto out;
+		egg_warning ("failed to set using HAL");
+	}
 	egg_debug ("no hardware support");
 	return FALSE;
 out:
@@ -304,7 +331,7 @@ gboolean
 gpm_brightness_has_hw (GpmBrightness *brightness)
 {
 	g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
-	return (brightness->priv->use_xrandr || brightness->priv->use_dkp);
+	return (brightness->priv->use_xrandr || brightness->priv->use_dkp || brightness->priv->use_hal);
 }
 
 /**
@@ -318,6 +345,7 @@ gpm_brightness_finalize (GObject *object)
 	g_return_if_fail (GPM_IS_BRIGHTNESS (object));
 	brightness = GPM_BRIGHTNESS (object);
 	g_object_unref (brightness->priv->dkp);
+	g_object_unref (brightness->priv->hal);
 	g_object_unref (brightness->priv->xrandr);
 	G_OBJECT_CLASS (gpm_brightness_parent_class)->finalize (object);
 }
@@ -393,6 +421,18 @@ gpm_brightness_dkp_changed_cb (GpmBrightnessDkp *dkp, guint percentage, GpmBrigh
 }
 
 /**
+ * gpm_brightness_hal_changed_cb:
+ * This callback is called when the brightness value changes.
+ **/
+static void
+gpm_brightness_hal_changed_cb (GpmBrightnessHal *hal, guint percentage, GpmBrightness *brightness)
+{
+	g_return_if_fail (GPM_IS_BRIGHTNESS (brightness));
+	if (brightness->priv->use_hal)
+		gpm_brightness_changed (brightness, percentage);
+}
+
+/**
  * gpm_brightness_init:
  * @brightness: This brightness class instance
  **/
@@ -403,6 +443,7 @@ gpm_brightness_init (GpmBrightness *brightness)
 
 	brightness->priv->use_xrandr = FALSE;
 	brightness->priv->use_dkp = FALSE;
+	brightness->priv->use_hal = FALSE;
 	brightness->priv->cache_trusted = FALSE;
 	brightness->priv->has_changed_events = FALSE;
 	brightness->priv->cache_percentage = 0;
@@ -417,10 +458,17 @@ gpm_brightness_init (GpmBrightness *brightness)
 		egg_debug ("detected DeviceKit-power hardware");
 		brightness->priv->use_dkp = TRUE;
 	}
-	g_signal_connect (brightness->priv->xrandr, "brightness-changed",
-			  G_CALLBACK (gpm_brightness_xrandr_changed_cb), brightness);
+	brightness->priv->hal = gpm_brightness_hal_new ();
+	if (gpm_brightness_hal_has_hw (brightness->priv->hal)) {
+		egg_debug ("detected HAL hardware");
+		brightness->priv->use_hal = TRUE;
+	}
 	g_signal_connect (brightness->priv->dkp, "brightness-changed",
 			  G_CALLBACK (gpm_brightness_dkp_changed_cb), brightness);
+	g_signal_connect (brightness->priv->hal, "brightness-changed",
+			  G_CALLBACK (gpm_brightness_hal_changed_cb), brightness);
+	g_signal_connect (brightness->priv->xrandr, "brightness-changed",
+			  G_CALLBACK (gpm_brightness_xrandr_changed_cb), brightness);
 }
 
 /**



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