[gnome-power-manager/gnome-2-26] Backport DPMS and IDLETIME fixes from master to fix multiple bugs



commit 3be6649478cf3c9d1f1b02122f891295ad6f5172
Author: Richard Hughes <richard hughsie com>
Date:   Sat Apr 18 18:15:40 2009 +0100

    Backport DPMS and IDLETIME fixes from master to fix multiple bugs
---
 src/egg-idletime.c  |  760 ++++++++++++++++++++++-----------------------------
 src/egg-idletime.h  |   43 ++--
 src/gpm-backlight.c |  247 +++++------------
 src/gpm-dpms.c      |  754 +++++++++++++++------------------------------------
 src/gpm-dpms.h      |   41 +---
 src/gpm-idle.c      |  117 ++++++--
 src/gpm-manager.c   |   27 +-
 src/gpm-self-test.c |    2 +
 8 files changed, 747 insertions(+), 1244 deletions(-)

diff --git a/src/egg-idletime.c b/src/egg-idletime.c
index 6f509aa..e09ed5e 100644
--- a/src/egg-idletime.c
+++ b/src/egg-idletime.c
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2007 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2009 William Jon McCann <mccann jhu edu>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -19,42 +20,39 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
+#include "config.h"
+
+#include <time.h>
+#include <string.h>
 
-#include <glib.h>
 #include <X11/Xlib.h>
 #include <X11/extensions/sync.h>
+
+#include <glib.h>
 #include <gdk/gdkx.h>
 #include <gdk/gdk.h>
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "egg-idletime.h"
+#include "egg-debug.h"
 
-static void     egg_idletime_finalize   (GObject       *object);
+static void egg_idletime_finalize	(GObject		*object);
 
-#define EGG_IDLETIME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_IDLETIME_TYPE, EggIdletimePrivate))
+#define EGG_IDLETIME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_IDLETIME, EggIdletimePrivate))
 
 struct EggIdletimePrivate
 {
-	int			 sync_event;
-	guint			 last_event;
-	gboolean		 reset_set;
-	XSyncCounter		 idle_counter;
-	GPtrArray		*array;
-	Display			*dpy;
+	GHashTable	*watches;
+	int		 sync_event_base;
+	XSyncCounter	 counter;
 };
 
 typedef struct
 {
-	guint			 id;
-	XSyncValue		 timeout;
-	XSyncAlarm		 xalarm;
-} EggIdletimeAlarm;
+	guint		 id;
+	XSyncValue	 interval;
+	XSyncAlarm	 xalarm_positive;
+	XSyncAlarm	 xalarm_negative;
+} EggIdletimeWatch;
 
 enum {
 	SIGNAL_ALARM_EXPIRED,
@@ -62,271 +60,346 @@ enum {
 	LAST_SIGNAL
 };
 
+static guint32 watch_serial = 1;
 static guint signals [LAST_SIGNAL] = { 0 };
-static gpointer egg_idletime_object = NULL;
 
 G_DEFINE_TYPE (EggIdletime, egg_idletime, G_TYPE_OBJECT)
 
 /**
- * egg_idletime_xsync_alarm_set:
- *
- * Gets the time remaining for the current percentage
- *
+ * egg_idletime_xsyncvalue_to_int64:
  */
-static void
-egg_idletime_xsync_alarm_set (EggIdletime *idletime, EggIdletimeAlarm *alarm, gboolean positive)
+static gint64
+egg_idletime_xsyncvalue_to_int64 (XSyncValue value)
 {
-	XSyncAlarmAttributes attr;
-	XSyncValue delta;
-	unsigned int flags;
-	XSyncTestType test;
-
-	/* which way do we do the test? */
-	if (positive)
-		test = XSyncPositiveTransition;
-	else
-		test = XSyncNegativeTransition;
-
-	XSyncIntToValue (&delta, 0);
-
-	attr.trigger.counter = idletime->priv->idle_counter;
-	attr.trigger.value_type = XSyncAbsolute;
-	attr.trigger.test_type = test;
-	attr.trigger.wait_value = alarm->timeout;
-	attr.delta = delta;
-
-	flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | XSyncCAValue | XSyncCADelta;
-
-	if (alarm->xalarm)
-		XSyncChangeAlarm (idletime->priv->dpy, alarm->xalarm, flags, &attr);
-	else
-		alarm->xalarm = XSyncCreateAlarm (idletime->priv->dpy, flags, &attr);
+	return ((guint64) XSyncValueHigh32 (value)) << 32
+		| (guint64) XSyncValueLow32 (value);
 }
 
 /**
- * egg_idletime_alarm_reset_all:
+ * egg_idletime_int64_to_xsyncvalue:
  */
-void
-egg_idletime_alarm_reset_all (EggIdletime *idletime)
+static XSyncValue
+egg_idletime_int64_to_xsyncvalue (gint64 value)
 {
-	guint i;
-	EggIdletimeAlarm *alarm;
+	XSyncValue ret;
+	XSyncIntsToValue (&ret, value, ((guint64)value) >> 32);
+	return ret;
+}
 
-	/* reset all the alarms (except the reset alarm) to their timeouts */
-	for (i=1; i<idletime->priv->array->len; i++) {
-		alarm = g_ptr_array_index (idletime->priv->array, i);
-		egg_idletime_xsync_alarm_set (idletime, alarm, TRUE);
+/**
+ * egg_idletime_find_alarm:
+ */
+static gboolean
+egg_idletime_find_alarm (gpointer key, EggIdletimeWatch *watch, XSyncAlarm *alarm)
+{
+	egg_debug ("Searching for %d in %d,%d", (int)*alarm, (int)watch->xalarm_positive, (int)watch->xalarm_negative);
+	if (watch->xalarm_positive == *alarm ||
+	    watch->xalarm_negative == *alarm) {
+		return TRUE;
 	}
-
-	/* emit signal */
-	g_signal_emit (idletime, signals [SIGNAL_RESET], 0);
-
-	/* we need to be reset again on the next event */
-	idletime->priv->reset_set = FALSE;
+	return FALSE;
 }
 
 /**
- * egg_idletime_timeout:
+ * egg_idletime_find_watch_for_alarm:
  */
-static void
-egg_idletime_timeout (EggIdletime *idletime, EggIdletimeAlarm *alarm)
+static EggIdletimeWatch *
+egg_idletime_find_watch_for_alarm (EggIdletime *idletime, XSyncAlarm alarm)
 {
-	/* emit signal */
-	g_signal_emit (idletime, signals [SIGNAL_ALARM_EXPIRED], 0, alarm->id);
+	EggIdletimeWatch *watch;
+	watch = g_hash_table_find (idletime->priv->watches,
+				   (GHRFunc)egg_idletime_find_alarm, &alarm);
+	return watch;
 }
 
 /**
- * egg_idletime_xsync_value_add_one:
- *
- * Just adds one to a XSyncValue. I love X.
+ * egg_idletime_handle_alarm_notify_event:
  */
 static void
-egg_idletime_xsync_value_add_one (XSyncValue *from, XSyncValue *to)
+egg_idletime_handle_alarm_notify_event (EggIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event)
 {
-	int overflow;
-	XSyncValue add;
-	XSyncIntToValue (&add, -1);
-	XSyncValueAdd (to, *from, add, &overflow);
+	EggIdletimeWatch *watch;
+
+	if (alarm_event->state == XSyncAlarmDestroyed)
+		return;
+
+	watch = egg_idletime_find_watch_for_alarm (idletime, alarm_event->alarm);
+
+	if (watch == NULL) {
+		egg_warning ("Unable to find watch for alarm %d", (int)alarm_event->alarm);
+		return;
+	}
+
+	egg_debug ("Watch %d fired, idle time = %lld",
+		   watch->id, egg_idletime_xsyncvalue_to_int64 (alarm_event->counter_value));
+
+	if (alarm_event->alarm == watch->xalarm_positive) {
+		g_signal_emit (idletime, signals [SIGNAL_ALARM_EXPIRED], 0, watch->id);
+	} else {
+		g_signal_emit (idletime, signals [SIGNAL_RESET], 0);
+	}
 }
 
 /**
- * egg_idletime_alarm_find_id:
+ * egg_idletime_xevent_filter:
  */
-static EggIdletimeAlarm *
-egg_idletime_alarm_find_id (EggIdletime *idletime, guint id)
+static GdkFilterReturn
+egg_idletime_xevent_filter (GdkXEvent *xevent, GdkEvent *event, EggIdletime *idletime)
 {
-	guint i;
-	EggIdletimeAlarm *alarm;
-	for (i=0; i<idletime->priv->array->len; i++) {
-		alarm = g_ptr_array_index (idletime->priv->array, i);
-		if (alarm->id == id)
-			return alarm;
-	}
-	return NULL;
+	XEvent *ev;
+	XSyncAlarmNotifyEvent *alarm_event;
+
+	ev = xevent;
+	if (ev->xany.type != idletime->priv->sync_event_base + XSyncAlarmNotify)
+		return GDK_FILTER_CONTINUE;
+
+	alarm_event = xevent;
+	egg_idletime_handle_alarm_notify_event (idletime, alarm_event);
+
+	return GDK_FILTER_CONTINUE;
 }
 
 /**
- * egg_idletime_x_set_reset:
+ * egg_idletime_init_xsync:
  */
-static void
-egg_idletime_x_set_reset (EggIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event)
+static gboolean
+egg_idletime_init_xsync (EggIdletime *idletime)
 {
-	EggIdletimeAlarm *alarm;
+	int sync_error_base;
+	int res;
+	int major;
+	int minor;
+	int i;
+	int ncounters;
+	XSyncSystemCounter *counters;
 
-	alarm = egg_idletime_alarm_find_id (idletime, 0);
+	res = XSyncQueryExtension (GDK_DISPLAY (),
+				   &idletime->priv->sync_event_base,
+				   &sync_error_base);
+	if (res == 0) {
+		egg_warning ("EggIdletime: Sync extension not present");
+		return FALSE;
+	}
 
-	if (idletime->priv->reset_set == FALSE) {
-		/* don't match on the current value because
-		 * XSyncNegativeComparison means less or equal. */
-		egg_idletime_xsync_value_add_one (&alarm_event->counter_value, &alarm->timeout);
+	res = XSyncInitialize (GDK_DISPLAY (), &major, &minor);
+	if (res == 0) {
+		egg_warning ("EggIdletime: Unable to initialize Sync extension");
+		return FALSE;
+	}
 
-		/* set the reset alarm to fire the next time
-		 * idletime->priv->idle_counter < the current counter value */
-		egg_idletime_xsync_alarm_set (idletime, alarm, FALSE);
+	counters = XSyncListSystemCounters (GDK_DISPLAY (), &ncounters);
+	for (i = 0; i < ncounters; i++) {
+		if (counters[i].name != NULL &&
+		    g_strcmp0 (counters[i].name, "IDLETIME") == 0) {
+			idletime->priv->counter = counters[i].counter;
+			break;
+		}
+	}
+	XSyncFreeSystemCounterList (counters);
 
-		/* don't try to set this again */
-		idletime->priv->reset_set = TRUE;
+	if (idletime->priv->counter == None) {
+		egg_warning ("EggIdletime: IDLETIME counter not found");
+		return FALSE;
 	}
+
+	gdk_window_add_filter (NULL, (GdkFilterFunc) egg_idletime_xevent_filter, idletime);
+
+	return TRUE;
 }
 
 /**
- * egg_idletime_alarm_find_event:
+ * egg_idletime_get_next_watch_serial:
  */
-static EggIdletimeAlarm *
-egg_idletime_alarm_find_event (EggIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event)
+static guint32
+egg_idletime_get_next_watch_serial (void)
 {
-	guint i;
-	EggIdletimeAlarm *alarm;
-	for (i=0; i<idletime->priv->array->len; i++) {
-		alarm = g_ptr_array_index (idletime->priv->array, i);
-		if (alarm_event->alarm == alarm->xalarm)
-			return alarm;
-	}
-	return NULL;
+	guint32 serial;
+
+	serial = watch_serial++;
+	/* cope with overflow */
+	if ((gint32)watch_serial < 0)
+		watch_serial = 1;
+	return serial;
 }
 
 /**
- * egg_idletime_x_event_filter:
+ * egg_idletime_watch_new:
  */
-static GdkFilterReturn
-egg_idletime_x_event_filter (GdkXEvent *gdkxevent, GdkEvent *event, gpointer data)
+static EggIdletimeWatch *
+egg_idletime_watch_new (guint interval)
 {
-	EggIdletimeAlarm *alarm;
-	XEvent *xevent = (XEvent *) gdkxevent;
-	EggIdletime *idletime = (EggIdletime *) data;
-	XSyncAlarmNotifyEvent *alarm_event;
+	EggIdletimeWatch *watch;
 
-	/* no point continuing */
-	if (xevent->type != idletime->priv->sync_event + XSyncAlarmNotify)
-		return GDK_FILTER_CONTINUE;
+	watch = g_slice_new0 (EggIdletimeWatch);
+	watch->interval = egg_idletime_int64_to_xsyncvalue ((gint64)interval);
+	watch->id = egg_idletime_get_next_watch_serial ();
+	watch->xalarm_positive = None;
+	watch->xalarm_negative = None;
 
-	alarm_event = (XSyncAlarmNotifyEvent *) xevent;
+	return watch;
+}
 
-	alarm = egg_idletime_alarm_find_event (idletime, alarm_event);
+/**
+ * egg_idletime_watch_free:
+ */
+static void
+egg_idletime_watch_free (EggIdletimeWatch *watch)
+{
+	if (watch == NULL)
+		return;
+	if (watch->xalarm_positive != None)
+		XSyncDestroyAlarm (GDK_DISPLAY (), watch->xalarm_positive);
+	if (watch->xalarm_negative != None)
+		XSyncDestroyAlarm (GDK_DISPLAY (), watch->xalarm_negative);
+	g_slice_free (EggIdletimeWatch, watch);
+}
 
-	/* did we match one of our alarms? */
-	if (alarm != NULL) {
-		/* save the last state we triggered */
-		idletime->priv->last_event = alarm->id;
+/**
+ * egg_idletime_xsync_alarm_set:
+ */
+static gboolean
+egg_idletime_xsync_alarm_set (EggIdletime *idletime, EggIdletimeWatch *watch)
+{
+	XSyncAlarmAttributes attr;
+	XSyncValue delta;
+	guint flags;
 
-		/* do the signal */
-		if (alarm->id != 0) {
-			egg_idletime_timeout (idletime, alarm);
+	flags = XSyncCACounter
+		| XSyncCAValueType
+		| XSyncCATestType
+		| XSyncCAValue
+		| XSyncCADelta
+		| XSyncCAEvents;
 
-			/* we need the first alarm to go off to set the reset alarm */
-			egg_idletime_x_set_reset (idletime, alarm_event);
-			return GDK_FILTER_CONTINUE;
-		}
+	XSyncIntToValue (&delta, 0);
+	attr.trigger.counter = idletime->priv->counter;
+	attr.trigger.value_type = XSyncAbsolute;
+	attr.trigger.wait_value = watch->interval;
+	attr.delta = delta;
+	attr.events = TRUE;
 
-		/* do the reset callback */
-		egg_idletime_alarm_reset_all (idletime);
+	attr.trigger.test_type = XSyncPositiveTransition;
+	if (watch->xalarm_positive != None) {
+		egg_debug ("EggIdletime: updating alarm for positive transition wait=%lld",
+			   egg_idletime_xsyncvalue_to_int64 (attr.trigger.wait_value));
+		XSyncChangeAlarm (GDK_DISPLAY (), watch->xalarm_positive, flags, &attr);
+	} else {
+		egg_debug ("EggIdletime: creating new alarm for positive transition wait=%lld",
+			   egg_idletime_xsyncvalue_to_int64 (attr.trigger.wait_value));
+		watch->xalarm_positive = XSyncCreateAlarm (GDK_DISPLAY (), flags, &attr);
 	}
 
-	return GDK_FILTER_CONTINUE;
+	attr.trigger.test_type = XSyncNegativeTransition;
+	if (watch->xalarm_negative != None) {
+		egg_debug ("EggIdletime: updating alarm for negative transition wait=%lld",
+			   egg_idletime_xsyncvalue_to_int64 (attr.trigger.wait_value));
+		XSyncChangeAlarm (GDK_DISPLAY (), watch->xalarm_negative, flags, &attr);
+	} else {
+		egg_debug ("EggIdletime: creating new alarm for negative transition wait=%lld",
+			   egg_idletime_xsyncvalue_to_int64 (attr.trigger.wait_value));
+		watch->xalarm_negative = XSyncCreateAlarm (GDK_DISPLAY (), flags, &attr);
+	}
+
+	return TRUE;
 }
 
 /**
- * egg_idletime_get_idletime->priv->last_event:
+ * egg_idletime_add_watch:
  */
 guint
-egg_idletime_alarm_get (EggIdletime *idletime)
+egg_idletime_add_watch (EggIdletime *idletime, guint interval)
 {
-	return idletime->priv->last_event;
+	EggIdletimeWatch *watch;
+
+	g_return_val_if_fail (EGG_IS_IDLETIME (idletime), 0);
+
+	watch = egg_idletime_watch_new (interval);
+
+	egg_idletime_xsync_alarm_set (idletime, watch);
+
+	g_hash_table_insert (idletime->priv->watches,
+			     GUINT_TO_POINTER (watch->id), watch);
+	return watch->id;
 }
 
 /**
- * egg_idletime_alarm_set:
+ * egg_idletime_remove_watch:
  */
-gboolean
-egg_idletime_alarm_set (EggIdletime *idletime, guint id, guint timeout)
+void
+egg_idletime_remove_watch (EggIdletime *idletime, guint id)
 {
-	EggIdletimeAlarm *alarm;
-
-	/* id cannot be zero */
-	if (id == 0)
-		return FALSE;
+	g_return_if_fail (EGG_IS_IDLETIME (idletime));
 
-	/* timeout cannot be zero */
-	if (timeout == 0)
-		return FALSE;
+	g_hash_table_remove (idletime->priv->watches, GUINT_TO_POINTER (id));
+}
 
-	/* see if we already created an alarm with this ID */
-	alarm = egg_idletime_alarm_find_id (idletime, id);
-	if (alarm == NULL) {
-		/* create a new alarm */
-		alarm = g_new0 (EggIdletimeAlarm, 1);
+/**
+ * egg_idletime_finalize:
+ */
+static void
+egg_idletime_finalize (GObject *object)
+{
+	EggIdletime *idletime;
 
-		/* set the id - this is just something like userdata */
-		alarm->id = id;
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (EGG_IS_IDLETIME (object));
 
-		/* add to array */
-		g_ptr_array_add (idletime->priv->array, alarm);
-	}
+	idletime = EGG_IDLETIME (object);
 
-	/* set the timeout */
-	XSyncIntToValue (&alarm->timeout, (gint)timeout);
+	g_return_if_fail (idletime->priv != NULL);
 
-	/* set, and start the timer */
-	egg_idletime_xsync_alarm_set (idletime, alarm, TRUE);
-	return TRUE;
+	G_OBJECT_CLASS (egg_idletime_parent_class)->finalize (object);
 }
 
 /**
- * egg_idletime_alarm_free:
+ * egg_idletime_constructor:
  */
-static gboolean
-egg_idletime_alarm_free (EggIdletime *idletime, EggIdletimeAlarm *alarm)
+static GObject *
+egg_idletime_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)
 {
-	XSyncDestroyAlarm (idletime->priv->dpy, alarm->xalarm);
-	g_free (alarm);
-	g_ptr_array_remove (idletime->priv->array, alarm);
-	return TRUE;
+	EggIdletime *idletime;
+
+	idletime = EGG_IDLETIME (G_OBJECT_CLASS (egg_idletime_parent_class)->constructor (type, n_construct_properties, construct_properties));
+
+	if (!egg_idletime_init_xsync (idletime)) {
+		g_object_unref (idletime);
+		return NULL;
+	}
+
+	return G_OBJECT (idletime);
 }
 
 /**
- * egg_idletime_alarm_free:
+ * egg_idletime_dispose:
  */
-gboolean
-egg_idletime_alarm_remove (EggIdletime *idletime, guint id)
+static void
+egg_idletime_dispose (GObject *object)
 {
-	EggIdletimeAlarm *alarm;
-	alarm = egg_idletime_alarm_find_id (idletime, id);
-	if (alarm == NULL)
-		return FALSE;
-	egg_idletime_alarm_free (idletime, alarm);
-	return TRUE;
+	EggIdletime *idletime;
+
+	g_return_if_fail (EGG_IS_IDLETIME (object));
+
+	idletime = EGG_IDLETIME (object);
+
+	if (idletime->priv->watches != NULL) {
+		g_hash_table_destroy (idletime->priv->watches);
+		idletime->priv->watches = NULL;
+	}
+
+	G_OBJECT_CLASS (egg_idletime_parent_class)->dispose (object);
 }
 
 /**
  * egg_idletime_class_init:
- * @klass: This class instance
- **/
+ */
 static void
 egg_idletime_class_init (EggIdletimeClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
 	object_class->finalize = egg_idletime_finalize;
-	g_type_class_add_private (klass, sizeof (EggIdletimePrivate));
+	object_class->dispose = egg_idletime_dispose;
+	object_class->constructor = egg_idletime_constructor;
 
 	signals [SIGNAL_ALARM_EXPIRED] =
 		g_signal_new ("alarm-expired",
@@ -342,102 +415,31 @@ egg_idletime_class_init (EggIdletimeClass *klass)
 			      G_STRUCT_OFFSET (EggIdletimeClass, reset),
 			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE, 0);
+
+	g_type_class_add_private (klass, sizeof (EggIdletimePrivate));
 }
 
 /**
  * egg_idletime_init:
- *
- * @egg_idletime: This class instance
- **/
+ */
 static void
 egg_idletime_init (EggIdletime *idletime)
 {
-	int sync_error;
-	int ncounters;
-	XSyncSystemCounter *counters;
-	EggIdletimeAlarm *alarm;
-	int i;
-
 	idletime->priv = EGG_IDLETIME_GET_PRIVATE (idletime);
-
-	idletime->priv->array = g_ptr_array_new ();
-
-	idletime->priv->idle_counter = None;
-	idletime->priv->last_event = 0;
-	idletime->priv->sync_event = 0;
-	idletime->priv->dpy = GDK_DISPLAY ();
-
-	/* get the sync event */
-	if (!XSyncQueryExtension (idletime->priv->dpy, &idletime->priv->sync_event, &sync_error)) {
-		g_warning ("No Sync extension.");
-		return;
-	}
-
-	/* gtk_init should do XSyncInitialize for us */
-	counters = XSyncListSystemCounters (idletime->priv->dpy, &ncounters);
-	for (i = 0; i < ncounters && !idletime->priv->idle_counter; i++) {
-		if (!strcmp(counters[i].name, "IDLETIME"))
-			idletime->priv->idle_counter = counters[i].counter;
-	}
-//	XSyncFreeSystemCounterList (counters);
-
-	/* arh. we don't have IDLETIME support */
-	if (!idletime->priv->idle_counter) {
-		g_warning ("No idle counter.");
-		return;
-	}
-
-	idletime->priv->reset_set = FALSE;
-
-	/* catch the timer alarm */
-	gdk_window_add_filter (NULL, egg_idletime_x_event_filter, idletime);
-
-	/* create a reset alarm */
-	alarm = g_new0 (EggIdletimeAlarm, 1);
-	alarm->id = 0;
-	g_ptr_array_add (idletime->priv->array, alarm);
-}
-
-/**
- * egg_idletime_finalize:
- * @object: This class instance
- **/
-static void
-egg_idletime_finalize (GObject *object)
-{
-	guint i;
-	EggIdletime *idletime;
-	EggIdletimeAlarm *alarm;
-
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (EGG_IS_IDLETIME (object));
-
-	idletime = EGG_IDLETIME (object);
-	idletime->priv = EGG_IDLETIME_GET_PRIVATE (idletime);
-
-	for (i=0; i<idletime->priv->array->len; i++) {
-		alarm = g_ptr_array_index (idletime->priv->array, i);
-		egg_idletime_alarm_free (idletime, alarm);
-	}
-	g_ptr_array_free (idletime->priv->array, TRUE);
-
-	G_OBJECT_CLASS (egg_idletime_parent_class)->finalize (object);
+	idletime->priv->counter = None;
+	idletime->priv->watches = g_hash_table_new_full (NULL, NULL, NULL,
+							(GDestroyNotify) egg_idletime_watch_free);
 }
 
 /**
  * egg_idletime_new:
- * Return value: new EggIdletime instance.
- **/
+ */
 EggIdletime *
 egg_idletime_new (void)
 {
-	if (egg_idletime_object != NULL) {
-		g_object_ref (egg_idletime_object);
-	} else {
-		egg_idletime_object = g_object_new (EGG_IDLETIME_TYPE, NULL);
-		g_object_add_weak_pointer (egg_idletime_object, &egg_idletime_object);
-	}
-	return EGG_IDLETIME (egg_idletime_object);
+	GObject *idletime;
+	idletime = g_object_new (EGG_TYPE_IDLETIME, NULL);
+	return EGG_IDLETIME (idletime);
 }
 
 /***************************************************************************
@@ -446,216 +448,94 @@ egg_idletime_new (void)
 #ifdef EGG_TEST
 #include "egg-test.h"
 
-static void
-egg_test_egg_idletime_wait (guint time_ms)
-{
-	GTimer *ltimer = g_timer_new ();
-	gfloat goal = time_ms / (gfloat) 1000.0f;
-	do {
-		g_main_context_iteration (NULL, FALSE);
-	} while (g_timer_elapsed (ltimer, NULL) < goal);
-	g_timer_destroy (ltimer);
-}
-
-static guint last_alarm = 0;
-static guint event_time;
-GTimer *timer;
+static guint _last_alarm = 0;
 
 static void
-gpm_alarm_expired_cb (EggIdletime *idletime, guint alarm, gpointer data)
+egg_idletime_test_alarm_expired_cb (EggIdletime *idletime, guint alarm, EggTest *test)
 {
-	last_alarm = alarm;
-	event_time = g_timer_elapsed (timer, NULL) * (gfloat) 1000.0f;
-//	g_print ("[evt %i in %ims]\n", alarm, event_time);
+	_last_alarm = alarm;
+	egg_debug ("alarm %i", alarm);
+	egg_test_loop_quit (test);
 }
 
 static void
-wait_until_alarm (void)
+egg_idletime_test_reset_cb (EggIdletime *idletime, EggTest *test)
 {
-	g_print ("*****************************\n");
-	g_print ("*** DO NOT MOVE THE MOUSE ***\n");
-	g_print ("*****************************\n");
-	while (last_alarm == 0)
-		g_main_context_iteration (NULL, FALSE);
-}
-
-static void
-wait_until_reset (void)
-{
-	if (last_alarm == 0)
-		return;
-	g_print ("*****************************\n");
-	g_print ("***     MOVE THE MOUSE    ***\n");
-	g_print ("*****************************\n");
-	while (last_alarm != 0)
-		g_main_context_iteration (NULL, FALSE);
-	egg_test_egg_idletime_wait (1000);
+	_last_alarm = 0;
+	egg_debug ("reset");
+	egg_test_loop_quit (test);
 }
 
 void
 egg_idletime_test (gpointer data)
 {
 	EggIdletime *idletime;
-	gboolean ret;
-	guint alarm;
-	guint i;
 	EggTest *test = (EggTest *) data;
+	guint id;
 
 	if (egg_test_start (test, "EggIdletime") == FALSE)
 		return;
 
-	timer = g_timer_new ();
 	gdk_init (NULL, NULL);
 
-	/* warn */
-
-	g_timer_start (timer);
 	/************************************************************/
-	egg_test_title (test, "check to see if delay works as expected");
-	egg_test_egg_idletime_wait (2000);
-	event_time = g_timer_elapsed (timer, NULL) * (gfloat) 1000.0f;
-	if (event_time > 1800 && event_time < 2200) {
-		egg_test_success (test, "time %i~=%i", 2000, event_time);
-	} else {
-		egg_test_failed (test, "time not the same! %i != %i", event_time, 2000);
-	}
-
-	/************************************************************/
-	egg_test_title (test, "make sure we get a non null device");
+	egg_test_title (test, "make sure we get an object");
 	idletime = egg_idletime_new ();
-	if (idletime != NULL) {
-		egg_test_success (test, "got EggIdletime");
-	} else {
-		egg_test_failed (test, "could not get EggIdletime");
-	}
+	egg_test_assert (test, (idletime != NULL));
 	g_signal_connect (idletime, "alarm-expired",
-			  G_CALLBACK (gpm_alarm_expired_cb), NULL);
+			  G_CALLBACK (egg_idletime_test_alarm_expired_cb), test);
+	g_signal_connect (idletime, "reset",
+			  G_CALLBACK (egg_idletime_test_reset_cb), test);
 
 	/************************************************************/
-	egg_test_title (test, "check if we are alarm zero with no alarms");
-	alarm = egg_idletime_alarm_get (idletime);
-	if (alarm == 0) {
-		egg_test_success (test, NULL);
-	} else {
-		egg_test_failed (test, "alarm %i set!", alarm);
-	}
+	egg_test_title (test, "add a watch");
+	id = egg_idletime_add_watch (idletime, 3000);
+	egg_test_assert (test, (id != 0));
 
 	/************************************************************/
-	egg_test_title (test, "check if we can set an reset alarm");
-	ret = egg_idletime_alarm_set (idletime, 0, 100);
-	if (!ret) {
-		egg_test_success (test, "ignored reset alarm");
-	} else {
-		egg_test_failed (test, "did not ignore reset alarm");
-	}
+	g_print ("*****************************\n");
+	g_print ("*** DO NOT MOVE THE MOUSE ***\n");
+	g_print ("*****************************\n");
+	egg_test_loop_wait (test, 4500);
+	egg_test_loop_check (test);
 
 	/************************************************************/
-	egg_test_title (test, "check if we can set an alarm timeout of zero");
-	ret = egg_idletime_alarm_set (idletime, 999, 0);
-	if (!ret) {
-		egg_test_success (test, "ignored invalid alarm");
-	} else {
-		egg_test_failed (test, "did not ignore invalid alarm");
-	}
+	egg_test_title (test, "check condition");
+	egg_test_assert (test, (_last_alarm == 1));
 
 	/************************************************************/
-	g_timer_start (timer);
-	egg_test_title (test, "check if we can set an alarm");
-	ret = egg_idletime_alarm_set (idletime, 101, 5000);
-	if (ret) {
-		egg_test_success (test, "set alarm okay");
-	} else {
-		egg_test_failed (test, "could not set alarm");
-	}
-
-	egg_idletime_alarm_set (idletime, 101, 5000);
-	wait_until_alarm ();
-
-	/* loop this two times */
-	for (i=0; i<2; i++) {
-		/* just let it time out, and wait for human input */
-		wait_until_reset ();
-		g_timer_start (timer);
-
-		/************************************************************/
-		g_timer_start (timer);
-		egg_test_title (test, "check if we can set an alarm");
-		ret = egg_idletime_alarm_set (idletime, 101, 5000);
-		if (ret) {
-			egg_test_success (test, "set alarm 5000ms okay");
-		} else {
-			egg_test_failed (test, "could not set alarm 5000ms");
-		}
-
-		/* wait for alarm to go off */
-		wait_until_alarm ();
-		g_timer_start (timer);
-
-		/************************************************************/
-		egg_test_title (test, "check if correct alarm has gone off");
-		alarm = egg_idletime_alarm_get (idletime);
-		if (alarm == 101) {
-			egg_test_success (test, "correct alarm");
-		} else {
-			egg_test_failed (test, "alarm %i set!", alarm);
-		}
-
-		/************************************************************/
-		egg_test_title (test, "check if alarm has gone off in correct time");
-		alarm = egg_idletime_alarm_get (idletime);
-		if (event_time > 3000 && event_time < 6000) {
-			egg_test_success (test, "correct, timeout ideally %ims (we did after %ims)", 5000, event_time);
-		} else {
-			egg_test_failed (test, "alarm %i did not timeout correctly !", alarm);
-		}
-	}
-
-	/* just let it time out, and wait for human input */
-	wait_until_reset ();
-	g_timer_start (timer);
+	g_print ("*****************************\n");
+	g_print ("***    MOVE THE MOUSE     ***\n");
+	g_print ("*****************************\n");
+	egg_test_loop_wait (test, 10000);
+	egg_test_loop_check (test);
 
 	/************************************************************/
-	g_timer_start (timer);
-	egg_test_title (test, "check if we can set an existing alarm");
-	ret = egg_idletime_alarm_set (idletime, 101, 10000);
-	if (ret) {
-		egg_test_success (test, "set alarm 10000ms okay");
-	} else {
-		egg_test_failed (test, "could not set alarm 10000ms");
-	}
+	egg_test_title (test, "check condition");
+	egg_test_assert (test, (_last_alarm == 0));
 
-	/* wait for alarm to go off */
-	wait_until_alarm ();
-	g_timer_start (timer);
+	/************************************************************/
+	g_print ("*****************************\n");
+	g_print ("*** DO NOT MOVE THE MOUSE ***\n");
+	g_print ("*****************************\n");
+	egg_test_loop_wait (test, 4500);
+	egg_test_loop_check (test);
 
 	/************************************************************/
-	egg_test_title (test, "check if alarm has gone off in the old time");
-	alarm = egg_idletime_alarm_get (idletime);
-	if (event_time > 5000) {
-		egg_test_success (test, "last timeout value used");
-	} else {
-		egg_test_failed (test, "incorrect timeout used %ims", event_time);
-	}
+	egg_test_title (test, "check condition");
+	egg_test_assert (test, (_last_alarm == 1));
 
 	/************************************************************/
-	egg_test_title (test, "check if we can remove an invalid alarm");
-	ret = egg_idletime_alarm_remove (idletime, 202);
-	if (!ret) {
-		egg_test_success (test, "ignored invalid alarm");
-	} else {
-		egg_test_failed (test, "removed invalid alarm");
-	}
+	g_print ("*****************************\n");
+	g_print ("***    MOVE THE MOUSE     ***\n");
+	g_print ("*****************************\n");
+	egg_test_loop_wait (test, 10000);
+	egg_test_loop_check (test);
 
 	/************************************************************/
-	egg_test_title (test, "check if we can remove an valid alarm");
-	ret = egg_idletime_alarm_remove (idletime, 101);
-	if (ret) {
-		egg_test_success (test, "removed valid alarm");
-	} else {
-		egg_test_failed (test, "failed to remove valid alarm");
-	}
+	egg_test_title (test, "check condition");
+	egg_test_assert (test, (_last_alarm == 0));
 
-	g_timer_destroy (timer);
 	g_object_unref (idletime);
 
 	egg_test_end (test);
diff --git a/src/egg-idletime.h b/src/egg-idletime.h
index d67e5ec..9616710 100644
--- a/src/egg-idletime.h
+++ b/src/egg-idletime.h
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
- * Copyright (C) 2007 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2009 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2007-2009 William Jon McCann <mccann jhu edu>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -26,12 +27,12 @@
 
 G_BEGIN_DECLS
 
-#define EGG_IDLETIME_TYPE		(egg_idletime_get_type ())
-#define EGG_IDLETIME(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_IDLETIME_TYPE, EggIdletime))
-#define EGG_IDLETIME_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), EGG_IDLETIME_TYPE, EggIdletimeClass))
-#define EGG_IS_IDLETIME(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_IDLETIME_TYPE))
-#define EGG_IS_IDLETIME_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), EGG_IDLETIME_TYPE))
-#define EGG_IDLETIME_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), EGG_IDLETIME_TYPE, EggIdletimeClass))
+#define EGG_TYPE_IDLETIME		(egg_idletime_get_type ())
+#define EGG_IDLETIME(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_IDLETIME, EggIdletime))
+#define EGG_IDLETIME_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_IDLETIME, EggIdletimeClass))
+#define EGG_IS_IDLETIME(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_IDLETIME))
+#define EGG_IS_IDLETIME_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_IDLETIME))
+#define EGG_IDLETIME_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_IDLETIME, EggIdletimeClass))
 
 typedef struct EggIdletimePrivate EggIdletimePrivate;
 
@@ -43,26 +44,22 @@ typedef struct
 
 typedef struct
 {
-	GObjectClass	parent_class;
-	void		(* alarm_expired)		(EggIdletime	*idletime,
-							 guint		 timer_id);
-	void		(* reset)			(EggIdletime	*idletime);
+	GObjectClass	 parent_class;
+	void		(* alarm_expired)	(EggIdletime	*idletime,
+						 guint		 timer_id);
+	void		(* reset)		(EggIdletime	*idletime);
 } EggIdletimeClass;
 
-GType		 egg_idletime_get_type			(void);
-EggIdletime	*egg_idletime_new			(void);
-
-void		 egg_idletime_alarm_reset_all		(EggIdletime	*idletime);
-guint		 egg_idletime_alarm_get			(EggIdletime	*idletime);
-gboolean	 egg_idletime_alarm_set			(EggIdletime	*idletime,
-							 guint		 alarm_id,
-							 guint		 timeout);
-gboolean	 egg_idletime_alarm_remove		(EggIdletime	*idletime,
-							 guint		 alarm_id);
+GType		 egg_idletime_get_type		(void);
+EggIdletime	*egg_idletime_new		(void);
+guint		 egg_idletime_add_watch		(EggIdletime	*idletime,
+						 guint		 interval);
+void		 egg_idletime_remove_watch	(EggIdletime	*idletime,
+						 guint		 id);
 #ifdef EGG_TEST
-void		 egg_idletime_test			(gpointer	 data);
+void		 egg_idletime_test		(gpointer	 data);
 #endif
 
 G_END_DECLS
 
-#endif	/* __EGG_IDLETIME_H */
+#endif /* __EGG_IDLETIME_H */
diff --git a/src/gpm-backlight.c b/src/gpm-backlight.c
index 8139b40..0b0e353 100644
--- a/src/gpm-backlight.c
+++ b/src/gpm-backlight.c
@@ -73,7 +73,6 @@ struct GpmBacklightPrivate
 	GpmLightSensor		*light_sensor;
 	gboolean		 can_dim;
 	gboolean		 can_sense;
-	gboolean		 can_dpms;
 	gboolean		 is_laptop;
 	gboolean		 system_is_idle;
 	GTimer			*idle_timer;
@@ -105,107 +104,6 @@ gpm_backlight_error_quark (void)
 	return quark;
 }
 
-/**
- * gpm_backlight_sync_policy:
- * @backlight: This class instance
- *
- * Sync the BACKLIGHT policy with what we have set in gconf.
- **/
-static void
-gpm_backlight_sync_policy (GpmBacklight *backlight)
-{
-	GError *error;
-	gboolean res;
-	guint timeout = 0;
-	guint standby = 0;
-	guint suspend = 0;
-	guint off = 0;
-	gchar *dpms_method;
-	GpmDpmsMethod method;
-	gboolean on_ac;
-
-	/* no point processing if we can't do the dpms action */
-	if (!backlight->priv->can_dpms)
-		return;
-
-	/* get the ac state */
-	on_ac = gpm_ac_adapter_is_present (backlight->priv->ac_adapter);
-
-	error = NULL;
-
-	if (on_ac) {
-		timeout = gconf_client_get_int (backlight->priv->conf, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC, NULL);
-		dpms_method = gconf_client_get_string (backlight->priv->conf, GPM_CONF_BACKLIGHT_DPMS_METHOD_AC, NULL);
-	} else {
-		timeout = gconf_client_get_int (backlight->priv->conf, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT, NULL);
-		dpms_method = gconf_client_get_string (backlight->priv->conf, GPM_CONF_BACKLIGHT_DPMS_METHOD_BATT, NULL);
-	}
-
-	/* convert the string types to standard types */
-	method = gpm_dpms_method_from_string (dpms_method);
-	g_free (dpms_method);
-
-	/* check if method is valid */
-	if (method == GPM_DPMS_METHOD_UNKNOWN) {
-		egg_warning ("BACKLIGHT method unknown. Possible schema problem!");
-		return;
-	}
-
-	/* choose a sensible default */
-	if (method == GPM_DPMS_METHOD_DEFAULT) {
-		egg_debug ("choosing sensible default");
-		if (backlight->priv->is_laptop) {
-			egg_debug ("laptop, so use GPM_DPMS_METHOD_OFF");
-			method = GPM_DPMS_METHOD_OFF;
-		} else {
-			egg_debug ("not laptop, so use GPM_BACKLIGHT_METHOD_STAGGER");
-			method = GPM_DPMS_METHOD_STAGGER;
-		}
-	}
-
-	/* Some monitors do not support certain suspend states, so we have to
-	 * provide a way to only use the one that works. */
-	if (method == GPM_DPMS_METHOD_STAGGER) {
-		/* suspend after one timeout, turn off after another */
-		standby = timeout;
-		suspend = timeout;
-		off = timeout * 2;
-	} else if (method == GPM_DPMS_METHOD_STANDBY) {
-		standby = timeout;
-		suspend = 0;
-		off = 0;
-	} else if (method == GPM_DPMS_METHOD_SUSPEND) {
-		standby = 0;
-		suspend = timeout;
-		off = 0;
-	} else if (method == GPM_DPMS_METHOD_OFF) {
-		standby = 0;
-		suspend = 0;
-		off = timeout;
-	} else {
-		/* wtf? */
-		egg_warning ("unknown backlight mode!");
-	}
-
-	egg_debug ("BACKLIGHT parameters %d %d %d, method '%i'", standby, suspend, off, method);
-
-	error = NULL;
-	res = gpm_dpms_set_enabled (backlight->priv->dpms, TRUE, &error);
-	if (error) {
-		egg_warning ("Unable to enable BACKLIGHT: %s", error->message);
-		g_error_free (error);
-		return;
-	}
-
-	error = NULL;
-	res = gpm_dpms_set_timeouts (backlight->priv->dpms, standby, suspend, off, &error);
-	if (error) {
-		egg_warning ("Unable to get BACKLIGHT timeouts: %s", error->message);
-		g_error_free (error);
-		return;
-	}
-}
-
 /* dbus methods shouldn't use enumerated types, but should use textual descriptors */
 gboolean
 gpm_backlight_set_mode (GpmBacklight *backlight, const gchar *mode_str, GError **error)
@@ -215,18 +113,9 @@ gpm_backlight_set_mode (GpmBacklight *backlight, const gchar *mode_str, GError *
 
 	g_return_val_if_fail (GPM_IS_BACKLIGHT (backlight), FALSE);
 
-	/* check if we have the hw */
-	if (backlight->priv->can_dpms == FALSE) {
-		*error = g_error_new (gpm_backlight_error_quark (),
-				      GPM_BACKLIGHT_ERROR_HARDWARE_NOT_PRESENT,
-				      "DPMS capable hardware not present");
-		return FALSE;
-	}
-
 	/* convert mode to an enumerated type */
 	mode = gpm_dpms_mode_from_string (mode_str);
-
-	ret = gpm_dpms_set_mode_enum (backlight->priv->dpms, mode, error);
+	ret = gpm_dpms_set_mode (backlight->priv->dpms, mode, error);
 	return ret;
 }
 
@@ -242,15 +131,7 @@ gpm_backlight_get_mode (GpmBacklight *backlight,
 	g_return_val_if_fail (GPM_IS_BACKLIGHT (backlight), FALSE);
 	g_return_val_if_fail (mode_str != NULL, FALSE);
 
-	/* check if we have the hw */
-	if (backlight->priv->can_dpms == FALSE) {
-		*error = g_error_new (gpm_backlight_error_quark (),
-				      GPM_BACKLIGHT_ERROR_HARDWARE_NOT_PRESENT,
-				      "DPMS capable hardware not present");
-		return FALSE;
-	}
-
-	ret = gpm_dpms_get_mode_enum (backlight->priv->dpms, &mode, error);
+	ret = gpm_dpms_get_mode (backlight->priv->dpms, &mode, error);
 	if (ret)
 		*mode_str = g_strdup (gpm_dpms_mode_to_string (mode));
 	return ret;
@@ -484,11 +365,6 @@ gpm_conf_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *e
 	         strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_BRIGHTNESS) == 0) {
 		gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
 
-	} else if (strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT) == 0 ||
-	           strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC) == 0 ||
-	           strcmp (entry->key, GPM_CONF_BACKLIGHT_DPMS_METHOD_AC) == 0 ||
-	           strcmp (entry->key, GPM_CONF_BACKLIGHT_DPMS_METHOD_BATT) == 0) {
-		gpm_backlight_sync_policy (backlight);
 	} else if (strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_DIM_TIME) == 0) {
 		backlight->priv->idle_dim_timeout = gconf_value_get_int (value);
 		gpm_idle_set_timeout_dim (backlight->priv->idle, backlight->priv->idle_dim_timeout);
@@ -521,8 +397,9 @@ ac_adapter_changed_cb (GpmAcAdapter *ac_adapter, gboolean on_ac, GpmBacklight *b
 static void
 gpm_backlight_button_pressed_cb (GpmButton *button, const gchar *type, GpmBacklight *backlight)
 {
-	guint percentage;
 	gboolean ret;
+	GError *error = NULL;
+	guint percentage;
 	gboolean hw_changed;
 	egg_debug ("Button press event type=%s", type);
 
@@ -561,7 +438,13 @@ gpm_backlight_button_pressed_cb (GpmButton *button, const gchar *type, GpmBackli
 	} else if (strcmp (type, GPM_BUTTON_LID_OPEN) == 0) {
 		/* make sure we undim when we lift the lid */
 		gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
-		gpm_backlight_sync_policy (backlight);
+
+		/* ensure backlight is on */
+		ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+		if (!ret) {
+			egg_warning ("failed to turn on DPMS: %s", error->message);
+			g_error_free (error);
+		}
 	}
 }
 
@@ -628,53 +511,71 @@ gpm_backlight_notify_system_idle_changed (GpmBacklight *backlight, gboolean is_i
 static void
 idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmBacklight *backlight)
 {
-	GError *error;
+	gboolean ret;
+	GError *error = NULL;
+	gboolean on_ac;
+	gchar *dpms_method;
+	GpmDpmsMode dpms_mode;
 
 	/* don't dim or undim the screen when the lid is closed */
 	if (gpm_button_is_lid_closed (backlight->priv->button))
 		return;
 
 	if (mode == GPM_IDLE_MODE_NORMAL) {
-		/* deactivate display power management */
-		if (backlight->priv->can_dpms) {
-			error = NULL;
-			gpm_dpms_set_active (backlight->priv->dpms, FALSE, &error);
-			if (error) {
-				egg_debug ("Unable to set DPMS not active: %s", error->message);
-				g_error_free (error);
-			}
-		}
-
 		/* sync lcd brightness */
 		gpm_backlight_notify_system_idle_changed (backlight, FALSE);
 		gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
 
-		/* sync timeouts */
-		gpm_backlight_sync_policy (backlight);
-
-	} else if (mode == GPM_IDLE_MODE_BLANK) {
-		/* activate display power management */
-		if (backlight->priv->can_dpms) {
-			error = NULL;
-			gpm_dpms_set_active (backlight->priv->dpms, TRUE, &error);
-			if (error) {
-				egg_debug ("Unable to set DPMS active: %s", error->message);
-				g_error_free (error);
-			}
+		/* ensure backlight is on */
+		ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+		if (!ret) {
+			egg_warning ("failed to turn on DPMS: %s", error->message);
+			g_error_free (error);
 		}
 
+	} else if (mode == GPM_IDLE_MODE_DIM) {
+
 		/* sync lcd brightness */
-		gpm_backlight_notify_system_idle_changed (backlight, FALSE);
+		gpm_backlight_notify_system_idle_changed (backlight, TRUE);
 		gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
 
-		/* sync timeouts */
-		gpm_backlight_sync_policy (backlight);
+		/* ensure backlight is on */
+		ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+		if (!ret) {
+			egg_warning ("failed to turn on DPMS: %s", error->message);
+			g_error_free (error);
+		}
 
-	} else if (mode == GPM_IDLE_MODE_DIM) {
+	} else if (mode == GPM_IDLE_MODE_BLANK) {
 
 		/* sync lcd brightness */
 		gpm_backlight_notify_system_idle_changed (backlight, TRUE);
 		gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+		/* get the DPMS state we're supposed to use on the power state */
+		on_ac = gpm_ac_adapter_is_present (backlight->priv->ac_adapter);
+		if (on_ac)
+			dpms_method = gconf_client_get_string (backlight->priv->conf, GPM_CONF_BACKLIGHT_DPMS_METHOD_AC, NULL);
+		else
+			dpms_method = gconf_client_get_string (backlight->priv->conf, GPM_CONF_BACKLIGHT_DPMS_METHOD_BATT, NULL);
+
+		/* convert the string types to standard types */
+		dpms_mode = gpm_dpms_mode_from_string (dpms_method);
+
+		/* check if method is valid */
+		if (dpms_mode == GPM_DPMS_MODE_UNKNOWN || dpms_mode == GPM_DPMS_MODE_ON) {
+			egg_warning ("BACKLIGHT method %s unknown. Using OFF.", dpms_method);
+			dpms_mode = GPM_DPMS_MODE_OFF;
+		}
+
+		/* turn backlight off */
+		ret = gpm_dpms_set_mode (backlight->priv->dpms, dpms_mode, &error);
+		if (!ret) {
+			egg_warning ("failed to change DPMS: %s", error->message);
+			g_error_free (error);
+		}
+
+		g_free (dpms_method);
 	}
 }
 
@@ -741,7 +642,15 @@ sensor_changed_cb (GpmLightSensor *sensor, guint percentage, GpmBacklight *backl
 static void
 control_resume_cb (GpmControl *control, GpmControlAction action, GpmBacklight *backlight)
 {
-	gpm_backlight_sync_policy (backlight);
+	gboolean ret;
+	GError *error = NULL;
+
+	/* ensure backlight is on */
+	ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+	if (!ret) {
+		egg_warning ("failed to turn on DPMS: %s", error->message);
+		g_error_free (error);
+	}
 }
 
 /**
@@ -757,10 +666,8 @@ gpm_backlight_finalize (GObject *object)
 
 	g_timer_destroy (backlight->priv->idle_timer);
 
-	if (backlight->priv->dpms != NULL)
-		g_object_unref (backlight->priv->dpms);
-	if (backlight->priv->control != NULL)
-		g_object_unref (backlight->priv->control);
+	g_object_unref (backlight->priv->dpms);
+	g_object_unref (backlight->priv->control);
 	g_object_unref (backlight->priv->light_sensor);
 	g_object_unref (backlight->priv->feedback);
 	g_object_unref (backlight->priv->conf);
@@ -834,7 +741,6 @@ gpm_backlight_init (GpmBacklight *backlight)
 
 	/* gets caps */
 	backlight->priv->can_dim = gpm_brightness_has_hw (backlight->priv->brightness);
-	backlight->priv->can_dpms = gpm_dpms_has_hw ();
 	backlight->priv->can_sense = gpm_light_sensor_has_hw (backlight->priv->light_sensor);
 
 	/* we use hal to see if we are a laptop */
@@ -890,23 +796,20 @@ gpm_backlight_init (GpmBacklight *backlight)
 	gpm_feedback_set_icon_name (backlight->priv->feedback,
 				    GPM_STOCK_BRIGHTNESS_LCD);
 
-	if (backlight->priv->can_dpms) {
-		/* DPMS mode poll class */
-		backlight->priv->dpms = gpm_dpms_new ();
-		g_signal_connect (backlight->priv->dpms, "mode-changed",
-				  G_CALLBACK (mode_changed_cb), backlight);
+	/* DPMS mode poll class */
+	backlight->priv->dpms = gpm_dpms_new ();
+	g_signal_connect (backlight->priv->dpms, "mode-changed",
+			  G_CALLBACK (mode_changed_cb), backlight);
 
-		/* we refresh DPMS on resume */
-		backlight->priv->control = gpm_control_new ();
-		g_signal_connect (backlight->priv->control, "resume",
-				  G_CALLBACK (control_resume_cb), backlight);
-	}
+	/* we refresh DPMS on resume */
+	backlight->priv->control = gpm_control_new ();
+	g_signal_connect (backlight->priv->control, "resume",
+			  G_CALLBACK (control_resume_cb), backlight);
 
 	/* sync at startup */
 	gpm_light_sensor_get_absolute (backlight->priv->light_sensor, &value);
 	backlight->priv->ambient_sensor_value = value / 100.0f;
 	gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
-	gpm_backlight_sync_policy (backlight);
 }
 
 /**
diff --git a/src/gpm-dpms.c b/src/gpm-dpms.c
index 61a906d..a58ed7d 100644
--- a/src/gpm-dpms.c
+++ b/src/gpm-dpms.c
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2005 William Jon McCann <mccann jhu edu>
+ * Copyright (C) 2006-2009 Richard Hughes <richard hughsie com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -42,11 +43,10 @@
 #include <X11/extensions/dpmsstr.h>
 #endif
 
-#include <gconf/gconf-client.h>
 #include "egg-debug.h"
 #include "gpm-dpms.h"
 
-static void     gpm_dpms_finalize   (GObject      *object);
+static void   gpm_dpms_finalize  (GObject   *object);
 
 #define GPM_DPMS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_DPMS, GpmDpmsPrivate))
 
@@ -55,17 +55,8 @@ static void     gpm_dpms_finalize   (GObject      *object);
 
 struct GpmDpmsPrivate
 {
-	gboolean		 enabled;
-	gboolean		 active;
 	gboolean		 dpms_capable;
-
-	guint			 standby_timeout;
-	guint			 suspend_timeout;
-	guint			 off_timeout;
-
-	GConfClient			*conf;
 	GpmDpmsMode		 mode;
-
 	guint			 timer_id;
 };
 
@@ -74,132 +65,30 @@ enum {
 	LAST_SIGNAL
 };
 
-enum {
-	PROP_0,
-	PROP_STANDBY_TIMEOUT,
-	PROP_SUSPEND_TIMEOUT,
-	PROP_OFF_TIMEOUT
-};
-
 static guint signals [LAST_SIGNAL] = { 0 };
 static gpointer gpm_dpms_object = NULL;
 
 G_DEFINE_TYPE (GpmDpms, gpm_dpms, G_TYPE_OBJECT)
 
+/**
+ * gpm_dpms_error_quark:
+ **/
 GQuark
 gpm_dpms_error_quark (void)
 {
 	static GQuark quark = 0;
 	if (!quark)
 		quark = g_quark_from_static_string ("gpm_dpms_error");
-
 	return quark;
 }
 
-gboolean
-gpm_dpms_has_hw (void)
-{
-#ifdef HAVE_DPMS_EXTENSION
-	return TRUE;
-#else
-	return FALSE;
-#endif
-}
-
-/* the following function is derived from
-   xscreensaver Copyright (C) Jamie Zawinski
-*/
-static gboolean
-x11_sync_server_dpms_settings (Display *dpy,
-			       gboolean enabled,
-			       guint	standby_secs,
-			       guint	suspend_secs,
-			       guint	off_secs,
-			       GError **error)
-{
-#ifdef HAVE_DPMS_EXTENSION
-	BOOL o_enabled = FALSE;
-	CARD16 o_power = 0;
-	CARD16 o_standby = 0;
-	CARD16 o_suspend = 0;
-	CARD16 o_off = 0;
-
-	egg_debug ("Syncing DPMS settings enabled=%d timeouts=%d %d %d",
-		   enabled, standby_secs, suspend_secs, off_secs);
-
-	if (! DPMSInfo (dpy, &o_power, &o_enabled)) {
-		egg_debug ("unable to get DPMS state.");
-		g_set_error (error,
-			     GPM_DPMS_ERROR,
-			     GPM_DPMS_ERROR_GENERAL,
-			     "Unable to get DPMS state");
-
-		return FALSE;
-	}
-
-	if (o_enabled != enabled) {
-		int res;
-
-		if (enabled) {
-			res = DPMSEnable (dpy);
-		} else {
-			res = DPMSDisable (dpy);
-		}
-
-		if (! res) {
-			egg_debug ("unable to set DPMS state.");
-			g_set_error (error,
-				     GPM_DPMS_ERROR,
-				     GPM_DPMS_ERROR_GENERAL,
-				     "Unable to set DPMS state");
-
-			return FALSE;
-		} else {
-			egg_debug ("turned DPMS %s", enabled ? "ON" : "OFF");
-		}
-	}
-
-	if (! DPMSGetTimeouts (dpy, &o_standby, &o_suspend, &o_off)) {
-		egg_debug ("unable to get DPMS timeouts.");
-		g_set_error (error,
-			     GPM_DPMS_ERROR,
-			     GPM_DPMS_ERROR_GENERAL,
-			     "Unable to get DPMS timeouts");
-
-		return FALSE;
-	}
-
-	if (o_standby != standby_secs ||
-	    o_suspend != suspend_secs ||
-	    o_off != off_secs) {
-		if (! DPMSSetTimeouts (dpy, standby_secs, suspend_secs, off_secs)) {
-			egg_debug ("unable to set DPMS timeouts.");
-			g_set_error (error,
-				     GPM_DPMS_ERROR,
-				     GPM_DPMS_ERROR_GENERAL,
-				     "Unable to set DPMS timeouts");
-
-			return FALSE;
-		} else {
-			egg_debug ("set DPMS timeouts: %d %d %d.",
-				  standby_secs, suspend_secs, off_secs);
-		}
-	}
-
-	return TRUE;
-# else	/* !HAVE_DPMS_EXTENSION */
-
-	egg_debug ("DPMS support not compiled in.");
-	return FALSE;
-# endif /* HAVE_DPMS_EXTENSION */
-}
-
 #ifdef HAVE_DPMS_EXTENSION
 
+/**
+ * gpm_dpms_x11_get_mode:
+ **/
 static gboolean
-x11_get_mode (GpmDpms     *dpms,
-	      GpmDpmsMode *mode,
-	      GError     **error)
+gpm_dpms_x11_get_mode (GpmDpms *dpms, GpmDpmsMode *mode, GError **error)
 {
 	GpmDpmsMode result;
 	BOOL enabled = FALSE;
@@ -208,72 +97,67 @@ x11_get_mode (GpmDpms     *dpms,
 	if (dpms->priv->dpms_capable == FALSE) {
 		/* Server or monitor can't DPMS -- assume the monitor is on. */
 		result = GPM_DPMS_MODE_ON;
-	} else {
-		DPMSInfo (GDK_DISPLAY (), &state, &enabled);
-		if (! enabled) {
-			/* Server says DPMS is disabled -- so the monitor is on. */
-			result = GPM_DPMS_MODE_ON;
-		} else {
-			switch (state) {
-			case DPMSModeOn:
-				result = GPM_DPMS_MODE_ON;
-				break;
-			case DPMSModeStandby:
-				result = GPM_DPMS_MODE_STANDBY;
-				break;
-			case DPMSModeSuspend:
-				result = GPM_DPMS_MODE_SUSPEND;
-				break;
-			case DPMSModeOff:
-				result = GPM_DPMS_MODE_OFF;
-				break;
-			default:
-				result = GPM_DPMS_MODE_ON;
-				break;
-			}
-		}
+		goto out;
 	}
 
-	if (mode) {
-		*mode = result;
+	DPMSInfo (GDK_DISPLAY (), &state, &enabled);
+	if (!enabled) {
+		/* Server says DPMS is disabled -- so the monitor is on. */
+		result = GPM_DPMS_MODE_ON;
+		goto out;
 	}
 
+	switch (state) {
+	case DPMSModeOn:
+		result = GPM_DPMS_MODE_ON;
+		break;
+	case DPMSModeStandby:
+		result = GPM_DPMS_MODE_STANDBY;
+		break;
+	case DPMSModeSuspend:
+		result = GPM_DPMS_MODE_SUSPEND;
+		break;
+	case DPMSModeOff:
+		result = GPM_DPMS_MODE_OFF;
+		break;
+	default:
+		result = GPM_DPMS_MODE_ON;
+		break;
+	}
+out:
+	if (mode)
+		*mode = result;
 	return TRUE;
 }
 
+/**
+ * gpm_dpms_x11_set_mode:
+ **/
 static gboolean
-x11_set_mode (GpmDpms	 *dpms,
-	      GpmDpmsMode mode,
-	      GError    **error)
+gpm_dpms_x11_set_mode (GpmDpms *dpms, GpmDpmsMode mode, GError **error)
 {
 	GpmDpmsMode current_mode;
 	CARD16 state;
 	CARD16 current_state;
 	BOOL current_enabled;
 
-	if (dpms->priv->dpms_capable == FALSE) {
+	if (!dpms->priv->dpms_capable) {
 		egg_debug ("not DPMS capable");
-		g_set_error (error,
-			     GPM_DPMS_ERROR,
-			     GPM_DPMS_ERROR_GENERAL,
+		g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
 			     "Display is not DPMS capable");
 		return FALSE;
 	}
 
-	if (! DPMSInfo (GDK_DISPLAY (), &current_state, &current_enabled)) {
+	if (!DPMSInfo (GDK_DISPLAY (), &current_state, &current_enabled)) {
 		egg_debug ("couldn't get DPMS info");
-		g_set_error (error,
-			     GPM_DPMS_ERROR,
-			     GPM_DPMS_ERROR_GENERAL,
+		g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
 			     "Unable to get DPMS state");
 		return FALSE;
 	}
 
-	if (! current_enabled) {
+	if (!current_enabled) {
 		egg_debug ("DPMS not enabled");
-		g_set_error (error,
-			     GPM_DPMS_ERROR,
-			     GPM_DPMS_ERROR_GENERAL,
+		g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
 			     "DPMS is not enabled");
 		return FALSE;
 	}
@@ -296,17 +180,13 @@ x11_set_mode (GpmDpms	 *dpms,
 		break;
 	}
 
-	x11_get_mode (dpms, &current_mode, NULL);
-
+	gpm_dpms_x11_get_mode (dpms, &current_mode, NULL);
 	if (current_mode != mode) {
 		if (! DPMSForceLevel (GDK_DISPLAY (), state)) {
-			g_set_error (error,
-				     GPM_DPMS_ERROR,
-				     GPM_DPMS_ERROR_GENERAL,
+			g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
 				     "Could not change DPMS mode");
 			return FALSE;
 		}
-
 		XSync (GDK_DISPLAY (), FALSE);
 	}
 
@@ -315,215 +195,50 @@ x11_set_mode (GpmDpms	 *dpms,
 
 #else  /* HAVE_DPMS_EXTENSION */
 
+/**
+ * gpm_dpms_x11_get_mode:
+ **/
 static gboolean
-x11_get_mode (GpmDpms     *dpms,
-	      GpmDpmsMode *mode,
-	      GError     **error)
+gpm_dpms_x11_get_mode (GpmDpms *dpms, GpmDpmsMode *mode, GError **error)
 {
-	if (mode) {
+	if (mode)
 		*mode = GPM_DPMS_MODE_ON;
-	}
-
 	return TRUE;
 }
 
+/**
+ * gpm_dpms_x11_set_mode:
+ **/
 static gboolean
-x11_set_mode (GpmDpms	 *dpms,
-	      GpmDpmsMode mode,
-	      GError    **error)
+gpm_dpms_x11_set_mode (GpmDpms *dpms, GpmDpmsMode mode, GError **error)
 {
 	return FALSE;
 }
 
 #endif /* !HAVE_DPMS_EXTENSION */
 
-static gboolean
-sync_settings (GpmDpms *dpms,
-	       GError **error)
-{
-	guint    standby;
-	guint    suspend;
-	guint    off;
-
-	if (dpms->priv->active) {
-		standby = dpms->priv->standby_timeout;
-		suspend = dpms->priv->suspend_timeout;
-		off     = dpms->priv->off_timeout;
-	} else {
-		standby = 0;
-		suspend = 0;
-		off     = 0;
-	}
-
-	if (dpms->priv->dpms_capable == FALSE) {
-		egg_debug ("Display is not DPMS capable");
-		g_set_error (error,
-			     GPM_DPMS_ERROR,
-			     GPM_DPMS_ERROR_GENERAL,
-			     "Display is not DPMS capable");
-
-		return FALSE;
-	}
-
-	/* We always try to keep the DPMS enabled so that
-	   we can use set the mode manually.  We will
-	   use zero values for the timeouts when the
-	   we aren't active in order to prevent it
-	   from activating.  */
-	return x11_sync_server_dpms_settings (GDK_DISPLAY (),
-					      dpms->priv->enabled,
-					      standby,
-					      suspend,
-					      off,
-					      error);
-}
-
-gboolean
-gpm_dpms_get_enabled (GpmDpms  *dpms,
-		      gboolean *enabled,
-		      GError  **error)
-{
-	g_return_val_if_fail (GPM_IS_DPMS (dpms), FALSE);
-
-	if (enabled) {
-		*enabled = dpms->priv->enabled;
-	}
-
-	return TRUE;
-}
-
-gboolean
-gpm_dpms_set_enabled (GpmDpms *dpms,
-		      gboolean enabled,
-		      GError **error)
-{
-	gboolean ret;
-
-	g_return_val_if_fail (GPM_IS_DPMS (dpms), FALSE);
-
-	ret = FALSE;
-	if (dpms->priv->enabled != enabled) {
-		egg_debug ("setting DPMS enabled: %d", enabled);
-
-		dpms->priv->enabled = enabled;
-
-		ret = sync_settings (dpms, error);
-	}
-
-	return ret;
-}
-
-gboolean
-gpm_dpms_get_active (GpmDpms  *dpms,
-		     gboolean *active,
-		     GError  **error)
-{
-	g_return_val_if_fail (GPM_IS_DPMS (dpms), FALSE);
-
-	if (active) {
-		*active = dpms->priv->active;
-	}
-
-	return TRUE;
-}
-
-gboolean
-gpm_dpms_set_active (GpmDpms *dpms,
-		     gboolean active,
-		     GError **error)
-{
-	gboolean ret;
-
-	g_return_val_if_fail (GPM_IS_DPMS (dpms), FALSE);
-
-	ret = FALSE;
-	if (dpms->priv->active != active) {
-		egg_debug ("setting DPMS active: %d", active);
-
-		dpms->priv->active = active;
-
-		ret = sync_settings (dpms, error);
-	}
-
-	return ret;
-}
-
-/* time specified in seconds */
-gboolean
-gpm_dpms_set_timeouts (GpmDpms	 *dpms,
-		       guint	  standby,
-		       guint	  suspend,
-		       guint	  off,
-		       GError   **error)
-{
-	gboolean ret;
-
-	g_return_val_if_fail (GPM_IS_DPMS (dpms), FALSE);
-
-	dpms->priv->standby_timeout = standby;
-	dpms->priv->suspend_timeout = suspend;
-	dpms->priv->off_timeout     = off;
-
-	ret = sync_settings (dpms, error);
-
-	return ret;
-}
-
 /**
- * gpm_dpms_method_from_string:
- * @dpms_method: Method type, e.g. "off" or "staggered"
- *
- * Convert descriptive types to enumerated values.
+ * gpm_dpms_mode_from_string:
  **/
-GpmDpmsMethod
-gpm_dpms_method_from_string (const gchar *dpms_method)
-{
-	GpmDpmsMethod method;
-
-	/* default to unknown */
-	method = GPM_DPMS_METHOD_UNKNOWN;
-	if (dpms_method == NULL) {
-		return method;
-	}
-
-	/* convert descriptive types to enumerated values */
-	if (strcmp (dpms_method, "default") == 0) {
-		method = GPM_DPMS_METHOD_DEFAULT;
-	} else if (strcmp (dpms_method, "stagger") == 0) {
-		method = GPM_DPMS_METHOD_STAGGER;
-	} else if (strcmp (dpms_method, "standby") == 0) {
-		method = GPM_DPMS_METHOD_STANDBY;
-	} else if (strcmp (dpms_method, "suspend") == 0) {
-		method = GPM_DPMS_METHOD_SUSPEND;
-	} else if (strcmp (dpms_method, "off") == 0) {
-		method = GPM_DPMS_METHOD_OFF;
-	} else {
-		egg_warning ("dpms_method '%s' not recognised", dpms_method);
-	}
-
-	return method;
-}
-
 GpmDpmsMode
 gpm_dpms_mode_from_string (const gchar *str)
 {
-	if (str == NULL) {
+	if (str == NULL)
 		return GPM_DPMS_MODE_UNKNOWN;
-	}
-
-	if (strcmp (str, "on") == 0) {
+	if (strcmp (str, "on") == 0)
 		return GPM_DPMS_MODE_ON;
-	} else if (strcmp (str, "standby") == 0) {
+	if (strcmp (str, "standby") == 0)
 		return GPM_DPMS_MODE_STANDBY;
-	} else if (strcmp (str, "suspend") == 0) {
+	if (strcmp (str, "suspend") == 0)
 		return GPM_DPMS_MODE_SUSPEND;
-	} else if (strcmp (str, "off") == 0) {
+	if (strcmp (str, "off") == 0)
 		return GPM_DPMS_MODE_OFF;
-	} else {
-		return GPM_DPMS_MODE_UNKNOWN;
-	}
+	return GPM_DPMS_MODE_UNKNOWN;
 }
 
+/**
+ * gpm_dpms_mode_to_string:
+ **/
 const gchar *
 gpm_dpms_mode_to_string (GpmDpmsMode mode)
 {
@@ -546,14 +261,14 @@ gpm_dpms_mode_to_string (GpmDpmsMode mode)
 		str = NULL;
 		break;
 	}
-
 	return str;
 }
 
+/**
+ * gpm_dpms_set_mode:
+ **/
 gboolean
-gpm_dpms_set_mode_enum (GpmDpms    *dpms,
-		        GpmDpmsMode mode,
-		        GError    **error)
+gpm_dpms_set_mode (GpmDpms *dpms, GpmDpmsMode mode, GError **error)
 {
 	gboolean ret;
 
@@ -561,224 +276,104 @@ gpm_dpms_set_mode_enum (GpmDpms    *dpms,
 
 	if (mode == GPM_DPMS_MODE_UNKNOWN) {
 		egg_debug ("mode unknown");
-		g_set_error (error,
-			     GPM_DPMS_ERROR,
-			     GPM_DPMS_ERROR_GENERAL,
+		g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
 			     "Unknown DPMS mode");
 		return FALSE;
 	}
 
-	ret = x11_set_mode (dpms, mode, error);
-
+	ret = gpm_dpms_x11_set_mode (dpms, mode, error);
 	return ret;
 }
 
+/**
+ * gpm_dpms_get_mode:
+ **/
 gboolean
-gpm_dpms_get_mode_enum (GpmDpms     *dpms,
-		        GpmDpmsMode *mode,
-		        GError     **error)
+gpm_dpms_get_mode (GpmDpms *dpms, GpmDpmsMode *mode, GError **error)
 {
 	gboolean ret;
-
-	if (mode) {
+	if (mode)
 		*mode = GPM_DPMS_MODE_UNKNOWN;
-	}
-
-	ret = x11_get_mode (dpms, mode, error);
-
+	ret = gpm_dpms_x11_get_mode (dpms, mode, error);
 	return ret;
 }
 
-static void
-gpm_dpms_set_standby_timeout (GpmDpms *dpms,
-			      guint    timeout)
-{
-	g_return_if_fail (GPM_IS_DPMS (dpms));
-
-	if (dpms->priv->standby_timeout != timeout) {
-		dpms->priv->standby_timeout = timeout;
-		sync_settings (dpms, NULL);
-	}
-}
-
-static void
-gpm_dpms_set_suspend_timeout (GpmDpms *dpms,
-			      guint    timeout)
-{
-	g_return_if_fail (GPM_IS_DPMS (dpms));
-
-	if (dpms->priv->suspend_timeout != timeout) {
-		dpms->priv->suspend_timeout = timeout;
-		sync_settings (dpms, NULL);
-	}
-}
-
-static void
-gpm_dpms_set_off_timeout (GpmDpms *dpms,
-			  guint	   timeout)
-{
-	g_return_if_fail (GPM_IS_DPMS (dpms));
-
-	if (dpms->priv->off_timeout != timeout) {
-		dpms->priv->off_timeout = timeout;
-		sync_settings (dpms, NULL);
-	}
-}
-
-static void
-gpm_dpms_set_property (GObject		  *object,
-		       guint		   prop_id,
-		       const GValue	  *value,
-		       GParamSpec	  *pspec)
-{
-	GpmDpms *self;
-
-	self = GPM_DPMS (object);
-
-	switch (prop_id) {
-	case PROP_STANDBY_TIMEOUT:
-		gpm_dpms_set_standby_timeout (self, g_value_get_uint (value));
-		break;
-	case PROP_SUSPEND_TIMEOUT:
-		gpm_dpms_set_suspend_timeout (self, g_value_get_uint (value));
-		break;
-	case PROP_OFF_TIMEOUT:
-		gpm_dpms_set_off_timeout (self, g_value_get_uint (value));
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-gpm_dpms_get_property (GObject		  *object,
-		       guint		   prop_id,
-		       GValue		  *value,
-		       GParamSpec	  *pspec)
-{
-	GpmDpms *self;
-
-	self = GPM_DPMS (object);
-
-	switch (prop_id) {
-	case PROP_STANDBY_TIMEOUT:
-		g_value_set_uint (value, self->priv->standby_timeout);
-		break;
-	case PROP_SUSPEND_TIMEOUT:
-		g_value_set_uint (value, self->priv->suspend_timeout);
-		break;
-	case PROP_OFF_TIMEOUT:
-		g_value_set_uint (value, self->priv->off_timeout);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-gpm_dpms_class_init (GpmDpmsClass *klass)
-{
-	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
-
-	object_class->finalize	   = gpm_dpms_finalize;
-	object_class->get_property = gpm_dpms_get_property;
-	object_class->set_property = gpm_dpms_set_property;
-
-	signals [MODE_CHANGED] =
-		g_signal_new ("mode-changed",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (GpmDpmsClass, mode_changed),
-			      NULL,
-			      NULL,
-			      g_cclosure_marshal_VOID__INT,
-			      G_TYPE_NONE,
-			      1, G_TYPE_INT);
-
-	g_object_class_install_property (object_class,
-					 PROP_STANDBY_TIMEOUT,
-					 g_param_spec_uint ("standby-timeout",
-							    NULL,
-							    NULL,
-							    0,
-							    G_MAXUINT,
-							    0,
-							    G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_SUSPEND_TIMEOUT,
-					 g_param_spec_uint ("suspend-timeout",
-							    NULL,
-							    NULL,
-							    0,
-							    G_MAXUINT,
-							    0,
-							    G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-					 PROP_OFF_TIMEOUT,
-					 g_param_spec_uint ("off-timeout",
-							    NULL,
-							    NULL,
-							    0,
-							    G_MAXUINT,
-							    0,
-							    G_PARAM_READWRITE));
-
-	g_type_class_add_private (klass, sizeof (GpmDpmsPrivate));
-}
-
+/**
+ * gpm_dpms_poll_mode_cb:
+ **/
 static gboolean
-poll_dpms_mode (GpmDpms *dpms)
+gpm_dpms_poll_mode_cb (GpmDpms *dpms)
 {
-	gboolean    res;
+	gboolean ret;
 	GpmDpmsMode mode;
-	GError     *error;
+	GError *error = NULL;
 
 #ifndef HAVE_DPMS_EXTENSION
 	return FALSE;
 #endif
 
-	error = NULL;
-	res = x11_get_mode (dpms, &mode, &error);
-
 	/* Try again */
-	if (! res) {
+	ret = gpm_dpms_x11_get_mode (dpms, &mode, &error);
+	if (!ret) {
 		g_clear_error (&error);
-
 		return TRUE;
 	}
 
 	if (mode != dpms->priv->mode) {
 		dpms->priv->mode = mode;
-
-		g_signal_emit (dpms,
-			       signals [MODE_CHANGED],
-			       0,
-			       mode);
+		g_signal_emit (dpms, signals [MODE_CHANGED], 0, mode);
 	}
 
-	/* FIXME: check that we are on console? */
-
 	return TRUE;
 }
 
-static void
-remove_poll_timer (GpmDpms *dpms)
+/**
+ * gpm_dpms_clear_timeouts:
+ **/
+static gboolean
+gpm_dpms_clear_timeouts (GpmDpms *dpms)
 {
-	if (dpms->priv->timer_id != 0) {
-		g_source_remove (dpms->priv->timer_id);
-		dpms->priv->timer_id = 0;
+	gboolean ret = FALSE;
+
+	/* never going to work */
+	if (!dpms->priv->dpms_capable) {
+		egg_debug ("not DPMS capable");
+		goto out;
 	}
+
+#ifdef HAVE_DPMS_EXTENSION
+	egg_debug ("set timeouts to zero");
+	ret = DPMSSetTimeouts (GDK_DISPLAY (), 0, 0, 0);
+#else
+	egg_warning ("no DPMS extension");
+#endif
+out:
+	return ret;
 }
 
+/**
+ * gpm_dpms_class_init:
+ **/
 static void
-add_poll_timer (GpmDpms *dpms,
-		glong	 timeout)
+gpm_dpms_class_init (GpmDpmsClass *klass)
 {
-	dpms->priv->timer_id = g_timeout_add_seconds (timeout, (GSourceFunc)poll_dpms_mode, dpms);
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = gpm_dpms_finalize;
+
+	signals [MODE_CHANGED] =
+		g_signal_new ("mode-changed",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GpmDpmsClass, mode_changed),
+			      NULL, NULL, g_cclosure_marshal_VOID__UINT,
+			      G_TYPE_NONE, 1, G_TYPE_UINT);
+
+	g_type_class_add_private (klass, sizeof (GpmDpmsPrivate));
 }
 
+/**
+ * gpm_dpms_init:
+ **/
 static void
 gpm_dpms_init (GpmDpms *dpms)
 {
@@ -786,10 +381,15 @@ gpm_dpms_init (GpmDpms *dpms)
 
 	/* DPMSCapable() can never change for a given display */
 	dpms->priv->dpms_capable = DPMSCapable (GDK_DISPLAY ());
+	dpms->priv->timer_id = g_timeout_add_seconds (GPM_DPMS_POLL_TIME, (GSourceFunc)gpm_dpms_poll_mode_cb, dpms);
 
-	add_poll_timer (dpms, GPM_DPMS_POLL_TIME);
+	/* ensure we clear the default timeouts (Standby: 1200s, Suspend: 1800s, Off: 2400s) */
+	gpm_dpms_clear_timeouts (dpms);
 }
 
+/**
+ * gpm_dpms_finalize:
+ **/
 static void
 gpm_dpms_finalize (GObject *object)
 {
@@ -802,11 +402,15 @@ gpm_dpms_finalize (GObject *object)
 
 	g_return_if_fail (dpms->priv != NULL);
 
-	remove_poll_timer (dpms);
+	if (dpms->priv->timer_id != 0)
+		g_source_remove (dpms->priv->timer_id);
 
 	G_OBJECT_CLASS (gpm_dpms_parent_class)->finalize (object);
 }
 
+/**
+ * gpm_dpms_new:
+ **/
 GpmDpms *
 gpm_dpms_new (void)
 {
@@ -818,3 +422,87 @@ gpm_dpms_new (void)
 	}
 	return GPM_DPMS (gpm_dpms_object);
 }
+
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+gpm_dpms_test (gpointer data)
+{
+	GpmDpms *dpms;
+	gboolean ret;
+	GError *error = NULL;
+	EggTest *test = (EggTest *) data;
+
+	if (!egg_test_start (test, "GpmDpms"))
+		return;
+
+	/************************************************************/
+	egg_test_title (test, "get object");
+	dpms = gpm_dpms_new ();
+	if (dpms != NULL)
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "got no object");
+
+	/************************************************************/
+	egg_test_title (test, "set on");
+	ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_ON, &error);
+	if (ret)
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "failed: %s", error->message);
+
+	g_usleep (2*1000*1000);
+
+	/************************************************************/
+	egg_test_title (test, "set STANDBY");
+	ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_STANDBY, &error);
+	if (ret)
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "failed: %s", error->message);
+
+	g_usleep (2*1000*1000);
+
+	/************************************************************/
+	egg_test_title (test, "set SUSPEND");
+	ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_SUSPEND, &error);
+	if (ret)
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "failed: %s", error->message);
+
+	g_usleep (2*1000*1000);
+
+	/************************************************************/
+	egg_test_title (test, "set OFF");
+	ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_OFF, &error);
+	if (ret)
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "failed: %s", error->message);
+
+	g_usleep (2*1000*1000);
+
+	/************************************************************/
+	egg_test_title (test, "set on");
+	ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_ON, &error);
+	if (ret)
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "failed: %s", error->message);
+
+	g_usleep (2*1000*1000);
+
+	g_object_unref (dpms);
+
+	egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/gpm-dpms.h b/src/gpm-dpms.h
index 0971cab..40a7cf2 100644
--- a/src/gpm-dpms.h
+++ b/src/gpm-dpms.h
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2004-2005 William Jon McCann <mccann jhu edu>
+ * Copyright (C) 2006-2009 Richard Hughes <richard hughsie com>
  *
  * Licensed under the GNU General Public License Version 2
  *
@@ -39,15 +40,6 @@ typedef enum {
 	GPM_DPMS_MODE_UNKNOWN
 } GpmDpmsMode;
 
-typedef enum {
-	GPM_DPMS_METHOD_DEFAULT,
-	GPM_DPMS_METHOD_STAGGER,
-	GPM_DPMS_METHOD_STANDBY,
-	GPM_DPMS_METHOD_SUSPEND,
-	GPM_DPMS_METHOD_OFF,
-	GPM_DPMS_METHOD_UNKNOWN
-} GpmDpmsMethod;
-
 typedef struct GpmDpmsPrivate GpmDpmsPrivate;
 
 typedef struct
@@ -73,40 +65,15 @@ typedef enum
 GQuark		 gpm_dpms_error_quark		(void);
 GType		 gpm_dpms_get_type		(void);
 GpmDpms		*gpm_dpms_new			(void);
-gboolean	 gpm_dpms_has_hw		(void);
-
-gboolean	 gpm_dpms_get_active		(GpmDpms 	*dpms,
-						 gboolean	*active,
-						 GError 	**error);
-gboolean	 gpm_dpms_set_active		(GpmDpms 	*dpms,
-						 gboolean	 active,
-						 GError 	**error);
-
-gboolean	 gpm_dpms_get_enabled		(GpmDpms 	*dpms,
-						 gboolean	*enabled,
-						 GError 	**error);
-gboolean	 gpm_dpms_set_enabled		(GpmDpms 	*dpms,
-						 gboolean	 enabled,
-						 GError 	**error);
-
-gboolean	 gpm_dpms_set_timeouts		(GpmDpms 	*dpms,
-						 guint		 standby,
-						 guint		 suspend,
-						 guint		 off,
-						 GError 	**error);
-
-/* Direct manipulation */
-gboolean	 gpm_dpms_get_mode_enum	 	(GpmDpms	*dpms,
+gboolean	 gpm_dpms_get_mode	 	(GpmDpms	*dpms,
 						 GpmDpmsMode	*mode,
 						 GError		**error);
-gboolean	 gpm_dpms_set_mode_enum	 	(GpmDpms	*dpms,
+gboolean	 gpm_dpms_set_mode	 	(GpmDpms	*dpms,
 						 GpmDpmsMode	 mode,
 						 GError		**error);
-
 const gchar	*gpm_dpms_mode_to_string	(GpmDpmsMode	 mode);
 GpmDpmsMode	 gpm_dpms_mode_from_string	(const gchar	*mode);
-
-GpmDpmsMethod	 gpm_dpms_method_from_string	(const gchar	*dpms_method);
+void		 gpm_dpms_test			(gpointer	 data);
 
 G_END_DECLS
 
diff --git a/src/gpm-idle.c b/src/gpm-idle.c
index ba7c867..3e515e6 100644
--- a/src/gpm-idle.c
+++ b/src/gpm-idle.c
@@ -47,9 +47,8 @@
 
 /* Sets the idle percent limit, i.e. how hard the computer can work
    while considered "at idle" */
-#define GPM_IDLE_CPU_LIMIT		5
-
-#define GPM_IDLE_IDLETIME_ALARM_ID	1
+#define GPM_IDLE_CPU_LIMIT			5
+#define GPM_IDLE_TIMEOUT_IGNORE_DPMS_CHANGE	1.0f /* seconds */
 
 struct GpmIdlePrivate
 {
@@ -62,8 +61,11 @@ struct GpmIdlePrivate
 	guint		 timeout_sleep;		/* in seconds */
 	guint		 timeout_blank_id;
 	guint		 timeout_sleep_id;
+	guint		 idletime_id;
+	guint		 idletime_ignore_id;
 	gboolean	 x_idle;
 	gboolean	 check_type_cpu;
+	GTimer		*timer;
 };
 
 enum {
@@ -105,6 +107,11 @@ gpm_idle_set_mode (GpmIdle *idle, GpmIdleMode mode)
 
 	if (mode != idle->priv->mode) {
 		idle->priv->mode = mode;
+
+		/* we save the time of the last state, so we can ignore the X11
+		 * timer reset when we change brightness or do DPMS actions */
+		g_timer_reset (idle->priv->timer);
+
 		egg_debug ("Doing a state transition: %s", gpm_idle_mode_to_text (mode));
 		g_signal_emit (idle, signals [IDLE_CHANGED], 0, mode);
 	}
@@ -187,17 +194,25 @@ gpm_idle_evaluate (GpmIdle *idle)
 	is_inhibited = gpm_session_get_inhibited (idle->priv->session);
 	egg_debug ("is_idle=%i, is_inhibited=%i", is_idle, is_inhibited);
 
-	if (idle->priv->x_idle) {
-		if (is_inhibited)
-			gpm_idle_set_mode (idle, GPM_IDLE_MODE_NORMAL);
-		else
-			gpm_idle_set_mode (idle, GPM_IDLE_MODE_DIM);
-	} else {
+	/* check we are really idle */
+	if (!idle->priv->x_idle) {
 		gpm_idle_set_mode (idle, GPM_IDLE_MODE_NORMAL);
+		egg_debug ("X not idle");
+		if (idle->priv->timeout_blank_id != 0) {
+			g_source_remove (idle->priv->timeout_blank_id);
+			idle->priv->timeout_blank_id = 0;
+		}
+		if (idle->priv->timeout_sleep_id != 0) {
+			g_source_remove (idle->priv->timeout_sleep_id);
+			idle->priv->timeout_sleep_id = 0;
+		}
+		goto out;
 	}
 
-	/* normal */
-	if (!is_idle) {
+	/* are we inhibited */
+	if (is_inhibited) {
+		egg_debug ("inhibited, so using normal state");
+		gpm_idle_set_mode (idle, GPM_IDLE_MODE_NORMAL);
 		if (idle->priv->timeout_blank_id != 0) {
 			g_source_remove (idle->priv->timeout_blank_id);
 			idle->priv->timeout_blank_id = 0;
@@ -206,22 +221,30 @@ gpm_idle_evaluate (GpmIdle *idle)
 			g_source_remove (idle->priv->timeout_sleep_id);
 			idle->priv->timeout_sleep_id = 0;
 		}
-		/* don't reset DIM state */
-		if (idle->priv->mode == GPM_IDLE_MODE_BLANK ||
-		    idle->priv->mode == GPM_IDLE_MODE_SLEEP)
-			gpm_idle_set_mode (idle, GPM_IDLE_MODE_NORMAL);
+		goto out;
+	}
+
+	/* normal to dim */
+	if (idle->priv->mode == GPM_IDLE_MODE_NORMAL) {
+		egg_debug ("normal to dim");
+		gpm_idle_set_mode (idle, GPM_IDLE_MODE_DIM);
 	}
 
-	/* if there are any inhibits, clear the dim timeout */
+	/* set up blank callback even when session is not idle */
+	if (idle->priv->timeout_blank_id == 0) {
+		egg_debug ("setting up blank callback");
+		idle->priv->timeout_blank_id = g_timeout_add_seconds (idle->priv->timeout_blank, (GSourceFunc) gpm_idle_blank_cb, idle);
+	}
+
+	/* only do the sleep timeout when the session is idle */
 	if (is_idle) {
-		/* normal to dim */
-		if (idle->priv->mode == GPM_IDLE_MODE_NORMAL)
-			gpm_idle_set_mode (idle, GPM_IDLE_MODE_DIM);
-		if (idle->priv->timeout_blank_id != 0)
-			idle->priv->timeout_blank_id = g_timeout_add_seconds (idle->priv->timeout_blank, (GSourceFunc) gpm_idle_blank_cb, idle);
-		if (idle->priv->timeout_sleep_id != 0)
+		if (idle->priv->timeout_sleep_id == 0) {
+			egg_debug ("setting up sleep callback = %i", idle->priv->timeout_blank);
 			idle->priv->timeout_sleep_id = g_timeout_add_seconds (idle->priv->timeout_sleep, (GSourceFunc) gpm_idle_sleep_cb, idle);
+		}
 	}
+out:
+	return;
 }
 
 /**
@@ -237,8 +260,12 @@ gpm_idle_set_timeout_dim (GpmIdle *idle, guint timeout)
 	egg_debug ("Setting dim idle timeout: %ds", timeout);
 	if (idle->priv->timeout_dim != timeout) {
 		idle->priv->timeout_dim = timeout;
-		egg_idletime_alarm_set (idle->priv->idletime, GPM_IDLE_IDLETIME_ALARM_ID, idle->priv->timeout_dim * 1000);
-		gpm_idle_evaluate (idle);
+
+		/* remove old id */
+		if (idle->priv->idletime_id != 0)
+			egg_idletime_remove_watch (idle->priv->idletime, idle->priv->idletime_id);
+		idle->priv->idletime_id =
+			egg_idletime_add_watch (idle->priv->idletime, timeout * 1000);
 	}
 	return TRUE;
 }
@@ -305,23 +332,52 @@ gpm_idle_session_inhibited_changed_cb (GpmSession *session, gboolean is_inhibite
 
 /**
  * gpm_idle_idletime_alarm_expired_cb:
+ *
+ * We're idle, something timed out
  **/
 static void
 gpm_idle_idletime_alarm_expired_cb (EggIdletime *idletime, guint alarm_id, GpmIdle *idle)
 {
+	egg_debug ("idletime alarm: %i", alarm_id);
+
+	if (alarm_id == idle->priv->idletime_ignore_id)
+		egg_debug ("expired 1ms timeout");
+
 	/* set again */
-	egg_debug ("idletime alarm");
 	idle->priv->x_idle = TRUE;
 	gpm_idle_evaluate (idle);
 }
 
 /**
  * gpm_idle_idletime_reset_cb:
+ *
+ * We're no longer idle, the user moved
  **/
 static void
 gpm_idle_idletime_reset_cb (EggIdletime *idletime, GpmIdle *idle)
 {
-	egg_debug ("idletime reset");
+	gdouble elapsed;
+	elapsed = g_timer_elapsed (idle->priv->timer, NULL);
+
+	/* have we just chaged state? */
+	if (idle->priv->mode == GPM_IDLE_MODE_BLANK &&
+	    elapsed < GPM_IDLE_TIMEOUT_IGNORE_DPMS_CHANGE) {
+		egg_debug ("ignoring reset, as we've just done a state change");
+		/* make sure we trigger a short 1ms timeout so we can get the expired signal */
+		if (idle->priv->idletime_ignore_id != 0)
+			egg_idletime_remove_watch (idle->priv->idletime, idle->priv->idletime_ignore_id);
+		idle->priv->idletime_ignore_id =
+			egg_idletime_add_watch (idle->priv->idletime, 1);
+		return;
+	}
+
+	/* remove 1ms timeout */
+	if (idle->priv->idletime_ignore_id != 0) {
+		egg_debug ("removing 1ms timeout");
+		egg_idletime_remove_watch (idle->priv->idletime, idle->priv->idletime_ignore_id);
+		idle->priv->idletime_ignore_id = 0;
+	}
+
 	idle->priv->x_idle = FALSE;
 	gpm_idle_evaluate (idle);
 }
@@ -347,8 +403,14 @@ gpm_idle_finalize (GObject *object)
 	if (idle->priv->timeout_sleep_id != 0)
 		g_source_remove (idle->priv->timeout_sleep_id);
 
+	g_timer_destroy (idle->priv->timer);
 	g_object_unref (idle->priv->load);
 	g_object_unref (idle->priv->session);
+
+	if (idle->priv->idletime_id != 0)
+		egg_idletime_remove_watch (idle->priv->idletime, idle->priv->idletime_id);
+	if (idle->priv->idletime_ignore_id != 0)
+		egg_idletime_remove_watch (idle->priv->idletime, idle->priv->idletime_ignore_id);
 	g_object_unref (idle->priv->idletime);
 
 	G_OBJECT_CLASS (gpm_idle_parent_class)->finalize (object);
@@ -394,7 +456,10 @@ gpm_idle_init (GpmIdle *idle)
 	idle->priv->timeout_sleep = G_MAXUINT;
 	idle->priv->timeout_blank_id = 0;
 	idle->priv->timeout_sleep_id = 0;
+	idle->priv->idletime_id = 0;
+	idle->priv->idletime_ignore_id = 0;
 	idle->priv->x_idle = FALSE;
+	idle->priv->timer = g_timer_new ();
 	idle->priv->load = gpm_load_new ();
 	idle->priv->session = gpm_session_new ();
 	g_signal_connect (idle->priv->session, "idle-changed", G_CALLBACK (gpm_idle_session_idle_changed_cb), idle);
diff --git a/src/gpm-manager.c b/src/gpm-manager.c
index a05d95f..3b223f6 100644
--- a/src/gpm-manager.c
+++ b/src/gpm-manager.c
@@ -329,7 +329,7 @@ gpm_manager_blank_screen (GpmManager *manager, GError **noerror)
 {
 	gboolean do_lock;
 	gboolean ret = TRUE;
-	GError  *error = NULL;
+	GError *error = NULL;
 
 	do_lock = gpm_control_get_lock_policy (manager->priv->control,
 					       GPM_CONF_LOCK_ON_BLANK_SCREEN);
@@ -337,7 +337,7 @@ gpm_manager_blank_screen (GpmManager *manager, GError **noerror)
 		if (!gpm_screensaver_lock (manager->priv->screensaver))
 			egg_debug ("Could not lock screen via gnome-screensaver");
 	}
-	gpm_dpms_set_mode_enum (manager->priv->dpms, GPM_DPMS_MODE_OFF, &error);
+	gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_OFF, &error);
 	if (error) {
 		egg_debug ("Unable to set DPMS mode: %s", error->message);
 		g_error_free (error);
@@ -357,12 +357,11 @@ gpm_manager_blank_screen (GpmManager *manager, GError **noerror)
 static gboolean
 gpm_manager_unblank_screen (GpmManager *manager, GError **noerror)
 {
-	gboolean  do_lock;
-	gboolean  ret = TRUE;
-	GError   *error;
+	gboolean do_lock;
+	gboolean ret = TRUE;
+	GError *error = NULL;
 
-	error = NULL;
-	gpm_dpms_set_mode_enum (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
+	gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
 	if (error) {
 		egg_debug ("Unable to set DPMS mode: %s", error->message);
 		g_error_free (error);
@@ -704,7 +703,7 @@ idle_do_sleep (GpmManager *manager)
  * @mode: The idle mode, e.g. GPM_IDLE_MODE_BLANK
  * @manager: This class instance
  *
- * This callback is called when gnome-screensaver detects that the idle state
+ * This callback is called when the idle class detects that the idle state
  * has changed. GPM_IDLE_MODE_BLANK is when the session has become inactive,
  * and GPM_IDLE_MODE_SLEEP is where the session has become inactive, AND the
  * session timeout has elapsed for the idle action.
@@ -732,10 +731,10 @@ idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmManager *manager)
 		egg_debug ("Idle state changed: NORMAL");
 		gpm_brightness_kbd_undim (manager->priv->brightness_kbd);
 	} else if (mode == GPM_IDLE_MODE_BLANK) {
-		egg_debug ("Idle state changed: SESSION");
+		egg_debug ("Idle state changed: BLANK");
 		gpm_brightness_kbd_dim (manager->priv->brightness_kbd);
 	} else if (mode == GPM_IDLE_MODE_SLEEP) {
-		egg_debug ("Idle state changed: SYSTEM");
+		egg_debug ("Idle state changed: SLEEP");
 		if (gpm_manager_is_inhibit_valid (manager, FALSE, "timeout action") == FALSE)
 			return;
 		idle_do_sleep (manager);
@@ -810,7 +809,7 @@ static void
 update_dpms_throttle (GpmManager *manager)
 {
 	GpmDpmsMode mode;
-	gpm_dpms_get_mode_enum (manager->priv->dpms, &mode, NULL);
+	gpm_dpms_get_mode (manager->priv->dpms, &mode, NULL);
 
 	/* Throttle the manager when DPMS is active since we can't see it anyway */
 	if (mode == GPM_DPMS_MODE_ON) {
@@ -1057,7 +1056,9 @@ gpm_conf_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *e
 		return;
 
 	if (strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT) == 0 ||
-	    strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC) == 0)
+	    strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC) == 0 ||
+	    strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT) == 0 ||
+	    strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC) == 0)
 		gpm_manager_sync_policy_sleep (manager);
 
 	/* set keyboard brightness */
@@ -1125,7 +1126,7 @@ screensaver_auth_request_cb (GpmScreensaver *screensaver, gboolean auth_begin, G
 		/* We turn on the monitor unconditionally, as we may be using
 		 * a smartcard to authenticate and DPMS might still be on.
 		 * See #350291 for more details */
-		gpm_dpms_set_mode_enum (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
+		gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
 		if (error != NULL) {
 			egg_warning ("Failed to turn on DPMS: %s", error->message);
 			g_error_free (error);
diff --git a/src/gpm-self-test.c b/src/gpm-self-test.c
index 51b09fa..be612ce 100644
--- a/src/gpm-self-test.c
+++ b/src/gpm-self-test.c
@@ -40,6 +40,7 @@ void gpm_cell_test (EggTest *test);
 void gpm_cell_test_array (EggTest *test);
 void gpm_inhibit_test (EggTest *test);
 void gpm_phone_test (EggTest *test);
+void gpm_dpms_test (EggTest *test);
 void gpm_graph_widget_test (EggTest *test);
 void gpm_proxy_test (EggTest *test);
 void gpm_hal_device_power_test (EggTest *test);
@@ -69,6 +70,7 @@ main (int argc, char **argv)
 	gpm_common_test (test);
 	gpm_inhibit_test (test);
 	gpm_phone_test (test);
+//	gpm_dpms_test (test);
 //	gpm_graph_widget_test (test);
 
 #if 0



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