--- ./libhal-glib/Makefile.am.orig	2008-09-16 10:41:55.539506000 +0800
+++ ./libhal-glib/Makefile.am	2008-09-16 10:45:00.053008000 +0800
@@ -11,11 +11,27 @@
 	$(top_builddir)/libdbus-glib/libdbus-proxy.la
 
 noinst_LTLIBRARIES =						\
+	libhal-gcpufreq.la					\
 	libhal-gmanager.la					\
 	libhal-gdevice.la					\
 	libhal-gdevicestore.la					\
 	libhal-gpower.la
 
+libhal_gcpufreq_la_SOURCES =					\
+	libhal-marshal.h					\
+	libhal-marshal.c					\
+	libhal-gdevice.c					\
+	libhal-gdevice.h					\
+	libhal-gcpufreq.c					\
+	libhal-gcpufreq.h					\
+	libhal-gmanager.c					\
+	libhal-gmanager.h
+libhal_gcpufreq_la_LIBADD =					\
+	$(LOCAL_LIBDBUS_LIBS)					\
+	$(DBUS_LIBS)						\
+	$(INTLLIBS)						\
+	$(GLIB_LIBS)
+
 libhal_gmanager_la_SOURCES =					\
 	libhal-marshal.h					\
 	libhal-marshal.c					\
--- ./libhal-glib/libhal-gcpufreq.h.orig	1970-01-01 08:00:00.000000000 +0800
+++ ./libhal-glib/libhal-gcpufreq.h	2008-09-16 10:34:25.096229000 +0800
@@ -0,0 +1,93 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-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 __LIBHAL_GCPUFREQ_H
+#define __LIBHAL_GCPUFREQ_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define LIBHAL_TYPE_CPUFREQ		(hal_gcpufreq_get_type ())
+#define LIBHAL_CPUFREQ(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), LIBHAL_TYPE_CPUFREQ, HalGCpufreq))
+#define LIBHAL_CPUFREQ_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), LIBHAL_TYPE_CPUFREQ, HalGCpufreqClass))
+#define LIBHAL_IS_CPUFREQ(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), LIBHAL_TYPE_CPUFREQ))
+#define LIBHAL_IS_CPUFREQ_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), LIBHAL_TYPE_CPUFREQ))
+#define LIBHAL_CPUFREQ_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), LIBHAL_TYPE_CPUFREQ, HalGCpufreqClass))
+
+typedef struct HalGCpufreqPrivate HalGCpufreqPrivate;
+
+typedef struct
+{
+	GObject			 parent;
+	HalGCpufreqPrivate	*priv;
+} HalGCpufreq;
+
+
+typedef struct
+{
+	GObjectClass	parent_class;
+} HalGCpufreqClass;
+
+/* types of governor */
+typedef enum {
+	LIBHAL_CPUFREQ_UNKNOWN = 0,
+	LIBHAL_CPUFREQ_ONDEMAND = 1,
+	LIBHAL_CPUFREQ_CONSERVATIVE = 2,
+	LIBHAL_CPUFREQ_POWERSAVE = 4,
+	LIBHAL_CPUFREQ_USERSPACE = 8,
+	LIBHAL_CPUFREQ_PERFORMANCE = 16,
+	LIBHAL_CPUFREQ_NOTHING = 32,
+} HalGCpufreqType;
+
+#define CODE_CPUFREQ_ONDEMAND		"ondemand"
+#define CODE_CPUFREQ_CONSERVATIVE	"conservative"
+#define CODE_CPUFREQ_POWERSAVE		"powersave"
+#define CODE_CPUFREQ_USERSPACE		"userspace"
+#define CODE_CPUFREQ_PERFORMANCE	"performance"
+#define CODE_CPUFREQ_NOTHING		"nothing"
+
+GType		 hal_gcpufreq_get_type			(void);
+HalGCpufreq	*hal_gcpufreq_new			(void);
+gboolean	 hal_gcpufreq_has_hw			(void);
+
+const gchar	*hal_gcpufreq_enum_to_string		(HalGCpufreqType  cpufreq_type);
+HalGCpufreqType	 hal_gcpufreq_string_to_enum		(const gchar	*governor);
+gboolean	 hal_gcpufreq_get_governors		(HalGCpufreq	*cpufreq,
+							 HalGCpufreqType *cpufreq_type);
+gboolean	 hal_gcpufreq_get_governor		(HalGCpufreq	*cpufreq,
+							 HalGCpufreqType *cpufreq_type);
+gboolean	 hal_gcpufreq_set_governor		(HalGCpufreq	*cpufreq,
+							 HalGCpufreqType  governor_enum);
+gboolean	 hal_gcpufreq_get_consider_nice		(HalGCpufreq	*cpufreq,
+							 gboolean	*consider_nice);
+gboolean	 hal_gcpufreq_set_consider_nice		(HalGCpufreq	*cpufreq,
+							 gboolean	 consider_nice);
+gboolean	 hal_gcpufreq_get_performance		(HalGCpufreq	*cpufreq,
+							 guint		*performance);
+gboolean	 hal_gcpufreq_set_performance		(HalGCpufreq	*cpufreq,
+							 guint		 performance);
+guint		 hal_gcpufreq_get_number_governors	(HalGCpufreq	*cpufreq,
+							 gboolean	 use_cache);
+
+G_END_DECLS
+
+#endif	/* __LIBHAL_GCPUFREQ_H */
--- ./libhal-glib/libhal-gcpufreq.c.orig	1970-01-01 08:00:00.000000000 +0800
+++ ./libhal-glib/libhal-gcpufreq.c	2008-09-16 10:34:25.096051000 +0800
@@ -0,0 +1,608 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-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 <dbus/dbus-glib.h>
+#include <glib/gi18n.h>
+#include <libdbus-proxy.h>
+
+#include "libhal-marshal.h"
+#include "libhal-gpower.h"
+#include "libhal-gdevice.h"
+#include "libhal-gcpufreq.h"
+#include "libhal-gmanager.h"
+
+static void     hal_gcpufreq_class_init (HalGCpufreqClass *klass);
+static void     hal_gcpufreq_init       (HalGCpufreq      *hal);
+static void     hal_gcpufreq_finalize   (GObject	  *object);
+
+#define LIBHAL_CPUFREQ_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LIBHAL_TYPE_CPUFREQ, HalGCpufreqPrivate))
+
+struct HalGCpufreqPrivate
+{
+	DbusProxy		*gproxy;
+	guint			 available_governors;
+	HalGCpufreqType		 current_governor;
+};
+
+G_DEFINE_TYPE (HalGCpufreq, hal_gcpufreq, G_TYPE_OBJECT)
+
+static gpointer hal_gcpufreq_object = NULL;
+
+/**
+ * hal_gcpufreq_string_to_enum:
+ * @governor: The cpufreq kernel governor, e.g. "powersave"
+ * Return value: The HalGCpufreqType value, e.g. LIBHAL_CPUFREQ_POWERSAVE
+ **/
+HalGCpufreqType
+hal_gcpufreq_string_to_enum (const gchar *governor)
+{
+	HalGCpufreqType cpufreq_type = LIBHAL_CPUFREQ_UNKNOWN;
+	if (governor == NULL) {
+		cpufreq_type = LIBHAL_CPUFREQ_NOTHING;
+	} else if (strcmp (governor, CODE_CPUFREQ_ONDEMAND) == 0) {
+		cpufreq_type = LIBHAL_CPUFREQ_ONDEMAND;
+	} else if (strcmp (governor, CODE_CPUFREQ_CONSERVATIVE) == 0) {
+		cpufreq_type = LIBHAL_CPUFREQ_CONSERVATIVE;
+	} else if (strcmp (governor, CODE_CPUFREQ_POWERSAVE) == 0) {
+		cpufreq_type = LIBHAL_CPUFREQ_POWERSAVE;
+	} else if (strcmp (governor, CODE_CPUFREQ_USERSPACE) == 0) {
+		cpufreq_type = LIBHAL_CPUFREQ_USERSPACE;
+	} else if (strcmp (governor, CODE_CPUFREQ_PERFORMANCE) == 0) {
+		cpufreq_type = LIBHAL_CPUFREQ_PERFORMANCE;
+	} else if (strcmp (governor, CODE_CPUFREQ_NOTHING) == 0) {
+		cpufreq_type = LIBHAL_CPUFREQ_NOTHING;
+	}
+	return cpufreq_type;
+}
+
+/**
+ * hal_gcpufreq_string_to_enum:
+ * @cpufreq_type: The HalGCpufreqType value, e.g. LIBHAL_CPUFREQ_POWERSAVE
+ * Return value: The cpufreq kernel governor, e.g. "powersave"
+ **/
+const gchar *
+hal_gcpufreq_enum_to_string (HalGCpufreqType cpufreq_type)
+{
+	const char *governor;
+	if (cpufreq_type == LIBHAL_CPUFREQ_ONDEMAND) {
+		governor = CODE_CPUFREQ_ONDEMAND;
+	} else if (cpufreq_type == LIBHAL_CPUFREQ_CONSERVATIVE) {
+		governor = CODE_CPUFREQ_CONSERVATIVE;
+	} else if (cpufreq_type == LIBHAL_CPUFREQ_POWERSAVE) {
+		governor = CODE_CPUFREQ_POWERSAVE;
+	} else if (cpufreq_type == LIBHAL_CPUFREQ_USERSPACE) {
+		governor = CODE_CPUFREQ_USERSPACE;
+	} else if (cpufreq_type == LIBHAL_CPUFREQ_PERFORMANCE) {
+		governor = CODE_CPUFREQ_PERFORMANCE;
+	} else if (cpufreq_type == LIBHAL_CPUFREQ_NOTHING) {
+		governor = CODE_CPUFREQ_NOTHING;
+	} else {
+		governor = "unknown";
+	}
+	return governor;
+}
+
+/**
+ * hal_gcpufreq_set_performance:
+ *
+ * @cpufreq: This class instance
+ * @performance: The percentage perfomance figure
+ * Return value: If the method succeeded
+ **/
+gboolean
+hal_gcpufreq_set_performance (HalGCpufreq *cpufreq, guint performance)
+{
+	GError *error = NULL;
+	gboolean ret;
+	HalGCpufreqType cpufreq_type;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+	g_return_val_if_fail (performance >= 0, FALSE);
+	g_return_val_if_fail (performance <= 100, FALSE);
+
+	/* we need to find the current governor to see if it's sane */
+	if (cpufreq->priv->current_governor == LIBHAL_CPUFREQ_UNKNOWN) {
+		hal_gcpufreq_get_governor (cpufreq, &cpufreq_type);
+	}
+
+	/* only applies to some governors */
+	if (cpufreq->priv->current_governor == LIBHAL_CPUFREQ_PERFORMANCE ||
+	    cpufreq->priv->current_governor == LIBHAL_CPUFREQ_POWERSAVE) {
+		return FALSE;
+	}
+
+	proxy = dbus_proxy_get_proxy (cpufreq->priv->gproxy);
+	if (proxy == NULL) {
+		g_warning ("not connected");
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "SetCPUFreqPerformance", &error,
+				 G_TYPE_INT, performance,
+				 G_TYPE_INVALID,
+				 G_TYPE_INVALID);
+	if (error) {
+		g_warning ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * hal_gcpufreq_set_governor:
+ *
+ * @cpufreq: This class instance
+ * @cpufreq_type: The CPU governor type, e.g. LIBHAL_CPUFREQ_CONSERVATIVE
+ * Return value: If the method succeeded
+ **/
+gboolean
+hal_gcpufreq_set_governor (HalGCpufreq    *cpufreq,
+			   HalGCpufreqType cpufreq_type)
+{
+	GError *error = NULL;
+	gboolean ret;
+	const gchar *governor;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+	g_return_val_if_fail (cpufreq_type != LIBHAL_CPUFREQ_UNKNOWN, FALSE);
+
+	governor = hal_gcpufreq_enum_to_string (cpufreq_type);
+	g_return_val_if_fail (governor != NULL, FALSE);
+
+	proxy = dbus_proxy_get_proxy (cpufreq->priv->gproxy);
+	if (proxy == NULL) {
+		g_warning ("not connected");
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "SetCPUFreqGovernor", &error,
+				 G_TYPE_STRING, governor,
+				 G_TYPE_INVALID,
+				 G_TYPE_INVALID);
+	if (error) {
+		g_warning ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		return FALSE;
+	}
+
+	/* save the cache */
+	cpufreq->priv->current_governor = cpufreq_type;
+	return TRUE;
+}
+
+/**
+ * hal_gcpufreq_get_governors:
+ *
+ * @cpufreq: This class instance
+ * @cpufreq_type: Return variable, The CPU governor type as an combined bitwise type
+ * Return value: If the method succeeded
+ **/
+gboolean
+hal_gcpufreq_get_governors (HalGCpufreq     *cpufreq,
+			    HalGCpufreqType *cpufreq_type)
+{
+	GError *error = NULL;
+	gboolean ret;
+	char **strlist;
+	int i = 0;
+	DBusGProxy *proxy;
+	HalGCpufreqType types = LIBHAL_CPUFREQ_UNKNOWN;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+	g_return_val_if_fail (cpufreq_type != NULL, FALSE);
+
+	proxy = dbus_proxy_get_proxy (cpufreq->priv->gproxy);
+	if (proxy == NULL) {
+		g_warning ("not connected");
+		*cpufreq_type = LIBHAL_CPUFREQ_UNKNOWN;
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "GetCPUFreqAvailableGovernors", &error,
+				 G_TYPE_INVALID,
+				 G_TYPE_STRV, &strlist,
+				 G_TYPE_INVALID);
+	if (error) {
+		g_warning ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		*cpufreq_type = LIBHAL_CPUFREQ_UNKNOWN;
+		return FALSE;
+	}
+
+	/* treat as binary flags */
+	while (strlist && strlist[i]) {
+		types += hal_gcpufreq_string_to_enum (strlist[i]);
+		++i;
+	}
+
+	/* when we have conservative and ondemand available, only expose
+	   ondemand in the UI. They are too similar and ondemand is better. */
+	if (types & LIBHAL_CPUFREQ_ONDEMAND && types & LIBHAL_CPUFREQ_CONSERVATIVE) {
+		types -= LIBHAL_CPUFREQ_CONSERVATIVE;
+	}
+
+	/* We never allow the user to use userspace. */
+	if (types & LIBHAL_CPUFREQ_USERSPACE) {
+		types -= LIBHAL_CPUFREQ_USERSPACE;
+	}
+
+	*cpufreq_type = types;
+	cpufreq->priv->available_governors = i;
+	return TRUE;
+}
+
+/**
+ * hal_gcpufreq_get_number_governors:
+ *
+ * @cpufreq: This class instance
+ * @use_cache: if we should force a cache update
+ * Return value: the number of available governors
+ **/
+guint
+hal_gcpufreq_get_number_governors (HalGCpufreq *cpufreq,
+				   gboolean    use_cache)
+{
+	HalGCpufreqType cpufreq_type;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+
+	if (use_cache == FALSE || cpufreq->priv->available_governors == -1) {
+		hal_gcpufreq_get_governors (cpufreq, &cpufreq_type);
+	}
+	return cpufreq->priv->available_governors;
+}
+
+/**
+ * hal_gcpufreq_get_consider_nice:
+ *
+ * @cpufreq: This class instance
+ * @consider_nice: Return variable, if consider niced processes
+ * Return value: If the method succeeded
+ **/
+gboolean
+hal_gcpufreq_get_consider_nice (HalGCpufreq *cpufreq,
+			        gboolean      *consider_nice)
+{
+	GError *error = NULL;
+	gboolean ret;
+	HalGCpufreqType cpufreq_type;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+	g_return_val_if_fail (consider_nice != NULL, FALSE);
+
+	/* we need to find the current governor to see if it's sane */
+	if (cpufreq->priv->current_governor == LIBHAL_CPUFREQ_UNKNOWN) {
+		hal_gcpufreq_get_governor (cpufreq, &cpufreq_type);
+	}
+
+	/* only applies to some governors */
+	if (cpufreq->priv->current_governor != LIBHAL_CPUFREQ_ONDEMAND &&
+	    cpufreq->priv->current_governor != LIBHAL_CPUFREQ_CONSERVATIVE) {
+		*consider_nice = FALSE;
+		return FALSE;
+	}
+
+	proxy = dbus_proxy_get_proxy (cpufreq->priv->gproxy);
+	if (proxy == NULL) {
+		g_warning ("not connected");
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "GetCPUFreqConsiderNice", &error,
+				 G_TYPE_INVALID,
+				 G_TYPE_BOOLEAN, consider_nice,
+				 G_TYPE_INVALID);
+	if (error) {
+		g_warning ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * hal_gcpufreq_get_performance:
+ *
+ * @cpufreq: This class instance
+ * @performance: Return variable, the percentage performance
+ * Return value: If the method succeeded
+ **/
+gboolean
+hal_gcpufreq_get_performance (HalGCpufreq *cpufreq,
+		              guint         *performance)
+{
+	GError *error = NULL;
+	gboolean ret;
+	HalGCpufreqType cpufreq_type;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+	g_return_val_if_fail (performance != NULL, FALSE);
+
+	/* we need to find the current governor to see if it's sane */
+	if (cpufreq->priv->current_governor == LIBHAL_CPUFREQ_UNKNOWN) {
+		hal_gcpufreq_get_governor (cpufreq, &cpufreq_type);
+	}
+
+	/* only applies to some governors */
+	if (cpufreq->priv->current_governor != LIBHAL_CPUFREQ_USERSPACE) {
+		*performance = -1;
+		return FALSE;
+	}
+
+	proxy = dbus_proxy_get_proxy (cpufreq->priv->gproxy);
+	if (proxy == NULL) {
+		g_warning ("not connected");
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "GetCPUFreqPerformance", &error,
+				 G_TYPE_INVALID,
+				 G_TYPE_INT, performance,
+				 G_TYPE_INVALID);
+	if (error) {
+		g_warning ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * hal_gcpufreq_get_governor:
+ *
+ * @cpufreq: This class instance
+ * @cpufreq_type: Return variable, the governor type, e.g. LIBHAL_CPUFREQ_POWERSAVE
+ * Return value: If the method succeeded
+ **/
+gboolean
+hal_gcpufreq_get_governor (HalGCpufreq     *cpufreq,
+			   HalGCpufreqType *cpufreq_type)
+{
+	GError *error = NULL;
+	gboolean ret;
+	gchar *governor;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+	g_return_val_if_fail (cpufreq_type, FALSE);
+
+	*cpufreq_type = LIBHAL_CPUFREQ_UNKNOWN;
+
+	/* use the cache */
+	if (cpufreq->priv->current_governor != LIBHAL_CPUFREQ_UNKNOWN) {
+		return cpufreq->priv->current_governor;
+	}
+
+	proxy = dbus_proxy_get_proxy (cpufreq->priv->gproxy);
+	if (proxy == NULL) {
+		g_warning ("not connected");
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "GetCPUFreqGovernor", &error,
+				 G_TYPE_INVALID,
+				 G_TYPE_STRING, &governor,
+				 G_TYPE_INVALID);
+	if (error) {
+		g_warning ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		return FALSE;
+	}
+
+	/* convert to enumerated type */
+	if (governor != NULL) {
+		*cpufreq_type = hal_gcpufreq_string_to_enum (governor);
+		cpufreq->priv->current_governor = *cpufreq_type;
+		g_free (governor);
+	}
+
+	return TRUE;
+}
+
+/**
+ * hal_gcpufreq_set_consider_nice:
+ *
+ * @cpufreq: This class instance
+ * @enable: True to consider nice processes
+ * Return value: If the method succeeded
+ **/
+gboolean
+hal_gcpufreq_set_consider_nice (HalGCpufreq *cpufreq,
+			        gboolean    consider_nice)
+{
+	GError *error = NULL;
+	gboolean ret;
+	HalGCpufreqType cpufreq_type;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (cpufreq != NULL, FALSE);
+	g_return_val_if_fail (LIBHAL_IS_CPUFREQ (cpufreq), FALSE);
+
+	/* we need to find the current governor to see if it's sane */
+	if (cpufreq->priv->current_governor == LIBHAL_CPUFREQ_UNKNOWN) {
+		hal_gcpufreq_get_governor (cpufreq, &cpufreq_type);
+	}
+
+	/* only applies to some governors */
+	if (cpufreq->priv->current_governor != LIBHAL_CPUFREQ_ONDEMAND &&
+	    cpufreq->priv->current_governor != LIBHAL_CPUFREQ_CONSERVATIVE) {
+		return FALSE;
+	}
+
+	proxy = dbus_proxy_get_proxy (cpufreq->priv->gproxy);
+	if (proxy == NULL) {
+		g_warning ("not connected");
+		return FALSE;
+	}
+
+	ret = dbus_g_proxy_call (proxy, "SetCPUFreqConsiderNice", &error,
+				 G_TYPE_BOOLEAN, consider_nice,
+				 G_TYPE_INVALID,
+				 G_TYPE_INVALID);
+	if (error) {
+		g_warning ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * hal_gcpufreq_class_init:
+ * @klass: This class instance
+ **/
+static void
+hal_gcpufreq_class_init (HalGCpufreqClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = hal_gcpufreq_finalize;
+	g_type_class_add_private (klass, sizeof (HalGCpufreqPrivate));
+}
+
+/**
+ * hal_gcpufreq_init:
+ *
+ * @cpufreq: This class instance
+ **/
+static void
+hal_gcpufreq_init (HalGCpufreq *cpufreq)
+{
+	cpufreq->priv = LIBHAL_CPUFREQ_GET_PRIVATE (cpufreq);
+
+	cpufreq->priv->gproxy = dbus_proxy_new ();
+	dbus_proxy_assign (cpufreq->priv->gproxy,
+			  DBUS_PROXY_SYSTEM,
+			  HAL_DBUS_SERVICE,
+			  HAL_ROOT_COMPUTER,
+			  HAL_DBUS_INTERFACE_CPUFREQ);
+
+	/* set defaults */
+	cpufreq->priv->available_governors = -1;
+	cpufreq->priv->current_governor = LIBHAL_CPUFREQ_UNKNOWN;
+}
+
+/**
+ * hal_gcpufreq_finalize:
+ * @object: This class instance
+ **/
+static void
+hal_gcpufreq_finalize (GObject *object)
+{
+	HalGCpufreq *cpufreq;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (LIBHAL_IS_CPUFREQ (object));
+
+	cpufreq = LIBHAL_CPUFREQ (object);
+	cpufreq->priv = LIBHAL_CPUFREQ_GET_PRIVATE (cpufreq);
+
+	if (cpufreq->priv->gproxy != NULL) {
+		g_object_unref (cpufreq->priv->gproxy);
+	}
+
+	G_OBJECT_CLASS (hal_gcpufreq_parent_class)->finalize (object);
+}
+
+/**
+ * hal_gcpufreq_has_hw:
+ *
+ * Self contained function that works out if we have the hardware.
+ * If not, we return FALSE and the module is unloaded.
+ **/
+gboolean
+hal_gcpufreq_has_hw (void)
+{
+	HalGManager *hal_manager;
+	gchar **names;
+	gboolean ret = TRUE;
+
+	/* okay, as singleton */
+	hal_manager = hal_gmanager_new ();
+	ret = hal_gmanager_find_capability (hal_manager, "cpufreq_control", &names, NULL);
+
+	/* nothing found */
+	if (names == NULL || names[0] == NULL) {
+		ret = FALSE;
+	}
+	hal_gmanager_free_capability (names);
+	g_object_unref (hal_manager);
+
+	return ret;
+}
+
+/**
+ * hal_gcpufreq_new:
+ * Return value: new HalGCpufreq instance.
+ **/
+HalGCpufreq *
+hal_gcpufreq_new (void)
+{
+	if (hal_gcpufreq_object != NULL) {
+		g_object_ref (hal_gcpufreq_object);
+	} else {
+		/* only load an instance of this module if we have the hardware */
+		if (hal_gcpufreq_has_hw () == FALSE) {
+			return NULL;
+		}
+		hal_gcpufreq_object = g_object_new (LIBHAL_TYPE_CPUFREQ, NULL);
+		g_object_add_weak_pointer (hal_gcpufreq_object, &hal_gcpufreq_object);
+	}
+	return LIBHAL_CPUFREQ (hal_gcpufreq_object);
+}
+
--- data/gnome-power-manager.schemas.in.orig	2008-09-16 13:26:20.971533000 +0800
+++ data/gnome-power-manager.schemas.in	2008-09-16 13:27:40.434145000 +0800
@@ -300,6 +300,66 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/gnome-power-manager/cpufreq/consider_nice</key>
+	<applyto>/apps/gnome-power-manager/cpufreq/consider_nice</applyto>
+	<owner>gnome-power-manager</owner>
+	<type>bool</type>
+	<default>false</default>
+	<locale name="C">
+	<short>Whether or not niced processes should be considered on processor load calculation</short>
+	<long>If niced processes are considered, they can cause a frequency increment even though their absolute load percentage wouldn't trigger the scaling mechanism to switch up the frequency.</long>
+	</locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-power-manager/cpufreq/policy_ac</key>
+	<applyto>/apps/gnome-power-manager/cpufreq/policy_ac</applyto>
+	<owner>gnome-power-manager</owner>
+	<type>string</type>
+	<default>nothing</default>
+	<locale name="C">
+	<short>The cpufreq policy to use when on AC power</short>
+	<long>The cpufreq policy used to scale the processor when on AC power. Possible values are ondemand, conservative, powersave, userspace, performance, nothing.</long>
+	</locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-power-manager/cpufreq/performance_ac</key>
+	<applyto>/apps/gnome-power-manager/cpufreq/performance_ac</applyto>
+	<owner>gnome-power-manager</owner>
+	<type>int</type>
+	<default>85</default>
+	<locale name="C">
+	<short>The cpufreq performance value to use when on AC power</short>
+	<long>The cpufreq performance value used to scale the processor when on AC power.</long>
+	</locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-power-manager/cpufreq/policy_battery</key>
+	<applyto>/apps/gnome-power-manager/cpufreq/policy_battery</applyto>
+	<owner>gnome-power-manager</owner>
+	<type>string</type>
+	<default>nothing</default>
+	<locale name="C">
+	<short>The cpufreq policy to use when on battery power</short>
+	<long>The cpufreq policy used to scale the processor when on battery power. Possible values are ondemand, conservative, powersave, userspace, performance, nothing.</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-power-manager/cpufreq/performance_battery</key>
+      <applyto>/apps/gnome-power-manager/cpufreq/performance_battery</applyto>
+      <owner>gnome-power-manager</owner>
+      <type>int</type>
+      <default>25</default>
+      <locale name="C">
+	<short>The cpufreq performance value to use when on battery power</short>
+	<long>The cpufreq performance value used to scale the processor when on battery power.</long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/gnome-power-manager/general/installed_schema</key>
       <applyto>/apps/gnome-power-manager/general/installed_schema</applyto>
       <owner>gnome-power-manager</owner>
--- data/gpm-prefs.glade.orig	2008-09-16 12:10:25.562141000 +0800
+++ data/gpm-prefs.glade	2008-09-16 12:20:00.554400000 +0800
@@ -111,6 +111,58 @@
                                 <property name="position">1</property>
                               </packing>
                             </child>
+
+			  <child>
+			    <widget class="GtkHBox" id="hbox_ac_cpu">
+			      <property name="visible">True</property>
+			      <property name="homogeneous">True</property>
+			      <property name="spacing">12</property>
+
+			      <child>
+				<widget class="GtkLabel" id="label_ac_cpu">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes" comments="SUN_BRANDING">Computer sp_eed policy:</property>
+				  <property name="use_underline">True</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_LEFT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">0</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				  <property name="width_chars">-1</property>
+				  <property name="single_line_mode">False</property>
+				  <property name="angle">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkComboBox" id="combobox_ac_cpu">
+				  <property name="visible">True</property>
+				  <property name="items" translatable="yes"></property>
+				  <property name="add_tearoffs">False</property>
+				  <property name="focus_on_click">True</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
                           </widget>
                         </child>
                       </widget>
@@ -378,6 +430,58 @@
                                 <property name="position">2</property>
                               </packing>
                             </child>
+
+			  <child>
+			    <widget class="GtkHBox" id="hbox_battery_cpu">
+			      <property name="visible">True</property>
+			      <property name="homogeneous">True</property>
+			      <property name="spacing">12</property>
+
+			      <child>
+				<widget class="GtkLabel" id="label_battery_cpu">
+				  <property name="visible">True</property>
+				  <property name="label" translatable="yes" comments="SUN_BRANDING">Computer sp_eed policy:</property>
+				  <property name="use_underline">True</property>
+				  <property name="use_markup">False</property>
+				  <property name="justify">GTK_JUSTIFY_LEFT</property>
+				  <property name="wrap">False</property>
+				  <property name="selectable">False</property>
+				  <property name="xalign">0</property>
+				  <property name="yalign">0.5</property>
+				  <property name="xpad">0</property>
+				  <property name="ypad">0</property>
+				  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				  <property name="width_chars">-1</property>
+				  <property name="single_line_mode">False</property>
+				  <property name="angle">0</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkComboBox" id="combobox_battery_cpu">
+				  <property name="visible">True</property>
+				  <property name="items" translatable="yes"></property>
+				  <property name="add_tearoffs">False</property>
+				  <property name="focus_on_click">True</property>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
                           </widget>
                         </child>
                       </widget>
--- src/Makefile.am.orig	2008-09-16 10:37:34.789458000 +0800
+++ src/Makefile.am	2008-09-16 10:41:39.623511000 +0800
@@ -38,6 +38,7 @@
 	$(top_builddir)/libhal-glib/libhal-gdevice.la	\
 	$(top_builddir)/libhal-glib/libhal-gdevicestore.la	\
 	$(top_builddir)/libhal-glib/libhal-gmanager.la	\
+	$(top_builddir)/libhal-glib/libhal-gcpufreq.la	\
 	$(top_builddir)/libhal-glib/libhal-gpower.la
 
 LOCAL_LIBDBUS_LIBS =						\
@@ -164,6 +165,8 @@
 	gpm-srv-brightness-kbd.c			\
 	gpm-srv-screensaver.h				\
 	gpm-srv-screensaver.c				\
+	gpm-cpufreq.c					\
+	gpm-cpufreq.h					\
 	gpm-conf.h					\
 	gpm-conf.c					\
 	gpm-idle.h					\
--- src/gpm-cpufreq.h.orig	1970-01-01 08:00:00.000000000 +0800
+++ src/gpm-cpufreq.h	2008-09-16 10:54:00.762524000 +0800
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-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 __GPMCPUFREQ_H
+#define __GPMCPUFREQ_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_CPUFREQ		(gpm_cpufreq_get_type ())
+#define GPM_CPUFREQ(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_CPUFREQ, GpmCpufreq))
+#define GPM_CPUFREQ_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_CPUFREQ, GpmCpufreqClass))
+#define GPM_IS_CPUFREQ(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_CPUFREQ))
+#define GPM_IS_CPUFREQ_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_CPUFREQ))
+#define GPM_CPUFREQ_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_CPUFREQ, GpmCpufreqClass))
+
+typedef struct GpmCpufreqPrivate GpmCpufreqPrivate;
+
+typedef struct
+{
+	GObject			 parent;
+	GpmCpufreqPrivate	*priv;
+} GpmCpufreq;
+
+typedef struct
+{
+	GObjectClass	parent_class;
+} GpmCpufreqClass;
+
+GType		 gpm_cpufreq_get_type				(void);
+GpmCpufreq	*gpm_cpufreq_new				(void);
+
+G_END_DECLS
+
+#endif	/* __GPMCPUFREQ_H */
+
--- src/gpm-cpufreq.c.orig	1970-01-01 08:00:00.000000000 +0800
+++ src/gpm-cpufreq.c	2008-09-16 13:18:02.206211000 +0800
@@ -0,0 +1,250 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-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 <dbus/dbus-glib.h>
+#include <glib/gi18n.h>
+
+#include <libhal-gcpufreq.h>
+
+#include "gpm-ac-adapter.h"
+#include "gpm-conf.h"
+#include "egg-debug.h"
+#include "gpm-cpufreq.h"
+
+static void     gpm_cpufreq_class_init (GpmCpufreqClass *klass);
+static void     gpm_cpufreq_init       (GpmCpufreq      *hal);
+static void     gpm_cpufreq_finalize   (GObject	*object);
+
+#define GPM_CPUFREQ_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_CPUFREQ, GpmCpufreqPrivate))
+
+struct GpmCpufreqPrivate
+{
+	HalGCpufreq		*hal_cpufreq;
+	GpmConf			*conf;
+	GpmAcAdapter		*ac_adapter;
+};
+
+G_DEFINE_TYPE (GpmCpufreq, gpm_cpufreq, G_TYPE_OBJECT)
+
+#if defined(sun) && defined(__SVR4)
+/**
+ * gpm_cpufreq_sync_policy_from_system_to_gconf:
+ * @cpufreq: This class instance
+ *
+ * Changes the cpufreq policy if AC gconf isn't identical to current system setting.
+ * Note: Because Solaris considers server user apart from laptop user, AC gconf key
+ *       isn't per user preference any more. In other words, AC gconf key always 
+ *       identical to current kernel/system configuration. Therefore, we need to 
+ *       read setting from kernel/system and store in AC gconf key. 
+ **/
+static gboolean
+gpm_cpufreq_sync_policy_from_system_to_gconf (GpmCpufreq *cpufreq)
+{
+	gboolean on_ac;
+	guint cpufreq_performance;
+	gchar *cpufreq_policy;
+	HalGCpufreqType cpufreq_type;
+
+	on_ac = gpm_ac_adapter_is_present (cpufreq->priv->ac_adapter);
+	if (on_ac == TRUE) {
+		/* Store current system governor and performance setting into AC gconf key.
+		 * Solaris CPUfreq don't support nice, do nothing for that. 
+                 */
+		hal_gcpufreq_get_governor (cpufreq->priv->hal_cpufreq, &cpufreq_type);
+		cpufreq_policy = hal_gcpufreq_enum_to_string (cpufreq_type);
+		gpm_conf_set_string (cpufreq->priv->conf, GPM_CONF_CPUFREQ_POLICY_AC, cpufreq_policy);
+		if (hal_gcpufreq_get_performance (cpufreq->priv->hal_cpufreq, &cpufreq_performance)) {
+			gpm_conf_set_uint (cpufreq->priv->conf, GPM_CONF_CPUFREQ_PERFORMANCE_AC, cpufreq_performance);
+		}
+	}
+
+	return TRUE;
+}
+#endif
+
+/**
+ * gpm_cpufreq_sync_policy:
+ * @cpufreq: This class instance
+ * @on_ac: If we are on AC power
+ *
+ * Changes the cpufreq policy if required
+ **/
+static gboolean
+gpm_cpufreq_sync_policy (GpmCpufreq *cpufreq)
+{
+	gboolean cpufreq_consider_nice;
+	gboolean on_ac;
+	guint cpufreq_performance;
+	gchar *cpufreq_policy;
+	HalGCpufreqType cpufreq_type;
+
+	on_ac = gpm_ac_adapter_is_present (cpufreq->priv->ac_adapter);
+
+	if (on_ac == TRUE) {
+		gpm_conf_get_bool (cpufreq->priv->conf, GPM_CONF_CPUFREQ_USE_NICE, &cpufreq_consider_nice);
+		gpm_conf_get_string (cpufreq->priv->conf, GPM_CONF_CPUFREQ_POLICY_AC, &cpufreq_policy);
+		gpm_conf_get_uint (cpufreq->priv->conf, GPM_CONF_CPUFREQ_PERFORMANCE_AC, &cpufreq_performance);
+	} else {
+		gpm_conf_get_bool (cpufreq->priv->conf, GPM_CONF_CPUFREQ_USE_NICE, &cpufreq_consider_nice);
+		gpm_conf_get_string (cpufreq->priv->conf, GPM_CONF_CPUFREQ_POLICY_BATT, &cpufreq_policy);
+		gpm_conf_get_uint (cpufreq->priv->conf, GPM_CONF_CPUFREQ_PERFORMANCE_BATT, &cpufreq_performance);
+	}
+
+	/* use enumerated value */
+	cpufreq_type = hal_gcpufreq_string_to_enum (cpufreq_policy);
+	g_free (cpufreq_policy);
+
+	/* change to the right governer and settings */
+	hal_gcpufreq_set_governor (cpufreq->priv->hal_cpufreq, cpufreq_type);
+	hal_gcpufreq_set_consider_nice (cpufreq->priv->hal_cpufreq, cpufreq_consider_nice);
+	// Fix for bugster #6727770. hal_gcpufreq_set_performance (cpufreq->priv->hal_cpufreq, cpufreq_performance);
+	return TRUE;
+}
+
+/**
+ * conf_key_changed_cb:
+ *
+ * We might have to do things when the gconf keys change; do them here.
+ **/
+static void
+conf_key_changed_cb (GpmConf     *conf,
+		     const gchar *key,
+		     GpmCpufreq  *cpufreq)
+{
+	/* if any change, just resync the whole lot */
+	if (strcmp (key, GPM_CONF_CPUFREQ_POLICY_AC) == 0 ||
+	    strcmp (key, GPM_CONF_CPUFREQ_PERFORMANCE_AC) == 0 ||
+	    strcmp (key, GPM_CONF_CPUFREQ_POLICY_BATT) == 0 ||
+	    strcmp (key, GPM_CONF_CPUFREQ_PERFORMANCE_BATT) == 0 ||
+	    strcmp (key, GPM_CONF_CPUFREQ_USE_NICE) == 0) {
+
+		gpm_cpufreq_sync_policy (cpufreq);
+	}
+}
+
+/**
+ * ac_adapter_changed_cb:
+ * @ac_adapter: The ac_adapter class instance
+ * @on_ac: if we are on AC power
+ * @cpufreq: This class instance
+ *
+ * Does the actions when the ac power source is inserted/removed.
+ **/
+static void
+ac_adapter_changed_cb (GpmAcAdapter *ac_adapter,
+		       gboolean      on_ac,
+		       GpmCpufreq  *cpufreq)
+{
+	gpm_cpufreq_sync_policy (cpufreq);
+}
+
+/**
+ * gpm_cpufreq_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_cpufreq_class_init (GpmCpufreqClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = gpm_cpufreq_finalize;
+	g_type_class_add_private (klass, sizeof (GpmCpufreqPrivate));
+}
+
+/**
+ * gpm_cpufreq_init:
+ *
+ * @cpufreq: This class instance
+ **/
+static void
+gpm_cpufreq_init (GpmCpufreq *cpufreq)
+{
+	cpufreq->priv = GPM_CPUFREQ_GET_PRIVATE (cpufreq);
+
+	/* we use cpufreq as the master class */
+	cpufreq->priv->hal_cpufreq = hal_gcpufreq_new ();
+
+	/* get changes from gconf */
+	cpufreq->priv->conf = gpm_conf_new ();
+	g_signal_connect (cpufreq->priv->conf, "value-changed",
+			  G_CALLBACK (conf_key_changed_cb), cpufreq);
+
+	/* we use ac_adapter for the ac-adapter-changed signal */
+	cpufreq->priv->ac_adapter = gpm_ac_adapter_new ();
+	g_signal_connect (cpufreq->priv->ac_adapter, "ac-adapter-changed",
+			  G_CALLBACK (ac_adapter_changed_cb), cpufreq);
+
+	/* sync policy */
+#if defined(sun) && defined(__SVR4)
+	gpm_cpufreq_sync_policy_from_system_to_gconf (cpufreq);
+#else
+	gpm_cpufreq_sync_policy (cpufreq);
+#endif
+}
+
+/**
+ * gpm_cpufreq_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_cpufreq_finalize (GObject *object)
+{
+	GpmCpufreq *cpufreq;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GPM_IS_CPUFREQ (object));
+
+	cpufreq = GPM_CPUFREQ (object);
+	cpufreq->priv = GPM_CPUFREQ_GET_PRIVATE (cpufreq);
+
+	if (cpufreq->priv->hal_cpufreq != NULL) {
+		g_object_unref (cpufreq->priv->hal_cpufreq);
+	}
+	if (cpufreq->priv->conf != NULL) {
+		g_object_unref (cpufreq->priv->conf);
+	}
+	if (cpufreq->priv->ac_adapter != NULL) {
+		g_object_unref (cpufreq->priv->ac_adapter);
+	}
+	G_OBJECT_CLASS (gpm_cpufreq_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_cpufreq_new:
+ * Return value: new GpmCpufreq instance.
+ **/
+GpmCpufreq *
+gpm_cpufreq_new (void)
+{
+	GpmCpufreq *cpufreq = NULL;
+
+	/* only load if we have the hardware */
+	if (hal_gcpufreq_has_hw() == TRUE) {
+		cpufreq = g_object_new (GPM_TYPE_CPUFREQ, NULL);
+	}
+
+	return cpufreq;
+}
+
--- src/gpm-conf.h.orig	2008-09-16 10:56:10.738304000 +0800
+++ src/gpm-conf.h	2008-09-16 10:56:30.989120000 +0800
@@ -72,6 +72,13 @@
 #define GPM_CONF_BUTTON_HIBERNATE		GPM_CONF_DIR "/buttons/hibernate"
 #define GPM_CONF_BUTTON_POWER			GPM_CONF_DIR "/buttons/power"
 
+/* cpufreq */
+#define GPM_CONF_CPUFREQ_POLICY_AC		GPM_CONF_DIR "/cpufreq/policy_ac"
+#define GPM_CONF_CPUFREQ_POLICY_BATT		GPM_CONF_DIR "/cpufreq/policy_battery"
+#define GPM_CONF_CPUFREQ_PERFORMANCE_AC		GPM_CONF_DIR "/cpufreq/performance_ac"
+#define GPM_CONF_CPUFREQ_PERFORMANCE_BATT	GPM_CONF_DIR "/cpufreq/performance_battery"
+#define GPM_CONF_CPUFREQ_USE_NICE		GPM_CONF_DIR "/cpufreq/consider_nice"
+
 /* general */
 #define GPM_CONF_DEBUG				GPM_CONF_DIR "/general/debug"
 #define GPM_CONF_SCHEMA_VERSION			GPM_CONF_DIR "/general/installed_schema"
--- src/gpm-prefs-core.c.orig	2008-09-16 11:14:29.546125000 +0800
+++ src/gpm-prefs-core.c	2008-09-16 13:08:23.567034000 +0800
@@ -34,6 +34,7 @@
 #include <gconf/gconf-client.h>
 
 #include <libhal-gmanager.h>
+#include <libhal-gcpufreq.h>
 
 #include "gpm-tray-icon.h"
 #include "gpm-common.h"
@@ -79,6 +80,8 @@
 #ifdef HAVE_GCONF_DEFAULTS
 	PolKitGnomeAction	*default_action;
 #endif
+	HalGCpufreq		*hal_cpufreq;
+	HalGCpufreqType	 cpufreq_types;
 };
 
 enum {
@@ -99,6 +102,17 @@
 #define ACTION_BLANK_TEXT		_("Blank screen")
 #define ACTION_NOTHING_TEXT		_("Do nothing")
 
+/* The text that should appear in the processor combo box */
+#define CPUFREQ_NOTHING_TEXT		_("Do nothing")
+/* SUN_BRANDING */
+#define CPUFREQ_ONDEMAND_TEXT		_("Based on processor load")
+/* SUN_BRANDING */
+#define CPUFREQ_CONSERVATIVE_TEXT	_("Automatic power saving")
+/* SUN_BRANDING */
+#define CPUFREQ_POWERSAVE_TEXT		_("Maximum power saving")
+/* SUN_BRANDING */
+#define CPUFREQ_PERFORMANCE_TEXT	_("Always maximum speed")
+
 /* If sleep time in a slider is set to 61 it is considered as never */
 const int NEVER_TIME_ON_SLIDER = 61;
 
@@ -704,6 +718,134 @@
 	}
 }
 
+/**
+ * gpm_prefs_processor_combo_changed_cb:
+ * @widget: The GtkWidget object
+ * @gpm_pref_key: The GConf key for this preference setting.
+ **/
+static void
+gpm_prefs_processor_combo_changed_cb (GtkWidget *widget,
+				      GpmPrefs  *prefs)
+{
+	gchar *value;
+	const gchar *policy;
+	gchar *gpm_pref_key;
+
+	value = gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget));
+	if (value == NULL) {
+		egg_warning ("active text failed");
+		return;
+	}
+	if (strcmp (value, CPUFREQ_ONDEMAND_TEXT) == 0) {
+		policy = CODE_CPUFREQ_ONDEMAND;
+	} else if (strcmp (value, CPUFREQ_CONSERVATIVE_TEXT) == 0) {
+		policy = CODE_CPUFREQ_CONSERVATIVE;
+	} else if (strcmp (value, CPUFREQ_POWERSAVE_TEXT) == 0) {
+		policy = CODE_CPUFREQ_POWERSAVE;
+	} else if (strcmp (value, CPUFREQ_PERFORMANCE_TEXT) == 0) {
+		policy = CODE_CPUFREQ_PERFORMANCE;
+	} else if (strcmp (value, CPUFREQ_NOTHING_TEXT) == 0) {
+		policy = CODE_CPUFREQ_NOTHING;
+	} else {
+		g_assert (FALSE);
+	}
+
+	g_free (value);
+	gpm_pref_key = (char *) g_object_get_data (G_OBJECT (widget), "conf_key");
+	egg_debug ("Changing %s to %s", gpm_pref_key, policy);
+	gpm_conf_set_string (prefs->priv->conf, gpm_pref_key, policy);
+}
+
+/**
+ * gpm_prefs_setup_action_combo:
+ * @prefs: This prefs class instance
+ * @widget_name: The GtkWidget name
+ * @gpm_pref_key: The GConf key for this preference setting.
+ * @actions: The actions to associate in an array.
+ **/
+static void
+gpm_prefs_setup_processor_combo (GpmPrefs         *prefs,
+				 const gchar      *widget_name,
+				 const gchar      *gpm_pref_key,
+				 HalGCpufreqType cpufreq_types)
+{
+	gchar *value;
+	guint n_added = 0;
+	gboolean has_option = FALSE;
+	gboolean is_writable;
+	GtkWidget *widget;
+	HalGCpufreqType cpufreq_type;
+
+	widget = glade_xml_get_widget (prefs->priv->glade_xml, widget_name);
+	gpm_conf_get_string (prefs->priv->conf, gpm_pref_key, &value);
+	gpm_conf_is_writable (prefs->priv->conf, gpm_pref_key, &is_writable);
+
+	gtk_widget_set_sensitive (widget, is_writable);
+
+	if (value == NULL) {
+		egg_warning ("invalid schema, please re-install");
+		value = g_strdup ("nothing");
+	}
+
+	g_object_set_data (G_OBJECT (widget), "conf_key", (gpointer) gpm_pref_key);
+	g_signal_connect (G_OBJECT (widget), "changed",
+			  G_CALLBACK (gpm_prefs_processor_combo_changed_cb),
+			  prefs);
+
+	cpufreq_type = hal_gcpufreq_string_to_enum (value);
+
+	if (cpufreq_types & LIBHAL_CPUFREQ_ONDEMAND) {
+		gtk_combo_box_append_text (GTK_COMBO_BOX (widget),
+					   CPUFREQ_ONDEMAND_TEXT);
+		if (cpufreq_type == LIBHAL_CPUFREQ_ONDEMAND) {
+			gtk_combo_box_set_active (GTK_COMBO_BOX (widget), n_added);
+			has_option = TRUE;
+		}
+		n_added++;
+	}
+	if (cpufreq_types & LIBHAL_CPUFREQ_NOTHING) {
+		gtk_combo_box_append_text (GTK_COMBO_BOX (widget),
+					   CPUFREQ_NOTHING_TEXT);
+		if (cpufreq_type == LIBHAL_CPUFREQ_ONDEMAND) {
+			gtk_combo_box_set_active (GTK_COMBO_BOX (widget), n_added);
+			has_option = TRUE;
+		}
+		n_added++;
+	}
+	if (cpufreq_types & LIBHAL_CPUFREQ_CONSERVATIVE) {
+		gtk_combo_box_append_text (GTK_COMBO_BOX (widget),
+					   CPUFREQ_CONSERVATIVE_TEXT);
+		if (cpufreq_type == LIBHAL_CPUFREQ_CONSERVATIVE) {
+			gtk_combo_box_set_active (GTK_COMBO_BOX (widget), n_added);
+			has_option = TRUE;
+		}
+		n_added++;
+	}
+	if (cpufreq_types & LIBHAL_CPUFREQ_POWERSAVE) {
+		gtk_combo_box_append_text (GTK_COMBO_BOX (widget),
+					   CPUFREQ_POWERSAVE_TEXT);
+		if (cpufreq_type == LIBHAL_CPUFREQ_POWERSAVE) {
+			gtk_combo_box_set_active (GTK_COMBO_BOX (widget), n_added);
+			has_option = TRUE;
+		}
+		n_added++;
+	}
+	if (cpufreq_types & LIBHAL_CPUFREQ_PERFORMANCE) {
+		gtk_combo_box_append_text (GTK_COMBO_BOX (widget),
+					   CPUFREQ_PERFORMANCE_TEXT);
+		if (cpufreq_type == LIBHAL_CPUFREQ_PERFORMANCE) {
+			gtk_combo_box_set_active (GTK_COMBO_BOX (widget), n_added);
+			has_option = TRUE;
+		}
+		n_added++;
+	}
+
+	if (has_option == FALSE || cpufreq_type == LIBHAL_CPUFREQ_NOTHING) {
+		gtk_combo_box_set_active (GTK_COMBO_BOX (widget), n_added);
+	}
+	g_free (value);
+}
+
 /** setup the notification page */
 static void
 prefs_setup_notification (GpmPrefs *prefs)
@@ -815,6 +957,7 @@
         gint page;
 
         if ((prefs->priv->has_button_lid == FALSE)
+	    && (prefs->priv->hal_cpufreq == FALSE)
 	    && (prefs->priv->has_lcd == FALSE)) {
                 notebook = glade_xml_get_widget (prefs->priv->glade_xml, "notebook_preferences");
                 widget = glade_xml_get_widget (prefs->priv->glade_xml, "vbox_ac");
@@ -827,6 +970,8 @@
 	gpm_prefs_setup_action_combo (prefs, "combobox_ac_lid",
 				      GPM_CONF_BUTTON_LID_AC,
 				      button_lid_actions);
+	gpm_prefs_setup_processor_combo (prefs, "combobox_ac_cpu",
+					 GPM_CONF_CPUFREQ_POLICY_AC, prefs->priv->cpufreq_types);
 	gpm_prefs_setup_sleep_slider (prefs, "hscale_ac_computer",
 				      GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC);
 	gpm_prefs_setup_sleep_slider (prefs, "hscale_ac_display",
@@ -845,6 +990,16 @@
 		widget = glade_xml_get_widget (prefs->priv->glade_xml, "hbox_ac_lid");
 		gtk_widget_hide_all (widget);
 	}
+
+#if defined(sun) && defined(__SVR4)
+        if (prefs->priv->hal_cpufreq == NULL || prefs->priv->can_cpufreq == FALSE ) {
+#else
+	if (prefs->priv->hal_cpufreq == NULL) {
+#endif
+		widget = glade_xml_get_widget (prefs->priv->glade_xml, "hbox_ac_cpu");
+		gtk_widget_hide_all (widget);
+	}
+
 #if defined(sun) && defined(__SVR4)
 	if (prefs->priv->has_lcd == FALSE || prefs->priv->can_brightness == FALSE) {
 #else
@@ -1060,6 +1064,8 @@
 	gpm_prefs_setup_action_combo (prefs, "combobox_battery_critical",
 				      GPM_CONF_ACTIONS_CRITICAL_BATT,
 				      battery_critical_actions);
+	gpm_prefs_setup_processor_combo (prefs, "combobox_battery_cpu",
+                                         GPM_CONF_CPUFREQ_POLICY_BATT, prefs->priv->cpufreq_types);
 	gpm_prefs_setup_sleep_slider (prefs, "hscale_battery_computer",
 				      GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT);
 	gpm_prefs_setup_sleep_slider (prefs, "hscale_battery_display",
@@ -1133,6 +1288,8 @@
 
 	prefs->priv = GPM_PREFS_GET_PRIVATE (prefs);
 
+	prefs->priv->hal_cpufreq = hal_gcpufreq_new ();
+
 	prefs->priv->screensaver = gpm_screensaver_new ();
 	g_signal_connect (prefs->priv->screensaver, "gs-delay-changed",
 			  G_CALLBACK (gs_delay_changed_cb), prefs);
@@ -1161,6 +1318,7 @@
 	GpmControl *control = gpm_control_new ();
 	if (control) {
 		prefs->priv->can_cpufreq = gpm_control_is_user_privileged (control, "hal-power-cpu");
+		prefs->priv->can_cpufreq = 1;
 		prefs->priv->can_brightness = gpm_control_is_user_privileged (control, "hal-power-brightness");
 		g_object_unref (control);
 	} else {
@@ -1178,6 +1336,14 @@
 	gpk_prefs_setup_policykit (prefs);
 #endif
 
+	/* only enable cpufreq stuff if we have the hardware */
+	if (prefs->priv->hal_cpufreq) {
+		hal_gcpufreq_get_governors (prefs->priv->hal_cpufreq,
+					    &prefs->priv->cpufreq_types);
+	} else {
+		prefs->priv->cpufreq_types = LIBHAL_CPUFREQ_NOTHING;
+	}
+
 	prefs->priv->glade_xml = glade_xml_new (GPM_DATA "/gpm-prefs.glade", NULL, NULL);
 	if (prefs->priv->glade_xml == NULL) {
 		g_error ("Cannot find 'gpm-prefs.glade'");
@@ -1235,6 +1401,10 @@
 		g_object_unref (prefs->priv->screensaver);
 	}
 
+	if (prefs->priv->hal_cpufreq) {
+		g_object_unref (prefs->priv->hal_cpufreq);
+	}
+
 	G_OBJECT_CLASS (gpm_prefs_parent_class)->finalize (object);
 }
 
--- src/gpm-manager.c.orig	2008-09-16 14:48:55.069459000 +0800
+++ src/gpm-manager.c	2008-09-16 14:58:21.514052000 +0800
@@ -48,6 +48,7 @@
 #include "gpm-conf.h"
 #include "gpm-control.h"
 #include "gpm-common.h"
+#include "gpm-cpufreq.h"
 #include "egg-debug.h"
 #include "gpm-dpms.h"
 #include "gpm-idle.h"
@@ -99,6 +100,7 @@
 	GpmBacklight		*backlight;
 	EggConsoleKit		*console;
 	GpmSrvBrightnessKbd	*srv_brightness_kbd;
+	GpmCpufreq		*cpufreq;
 	GpmSrvScreensaver 	*srv_screensaver;
 };
 
@@ -1742,6 +1744,8 @@
 	manager->priv->sound = gpm_sound_new ();
 
 	/* try and start an interactive service */
+	manager->priv->cpufreq = gpm_cpufreq_new ();
+
 	manager->priv->screensaver = gpm_screensaver_new ();
 	g_signal_connect (manager->priv->screensaver, "auth-request",
  			  G_CALLBACK (screensaver_auth_request_cb), manager);
