From: Phillip Susi <psusi@cfl.rr.com>
Last-Update: 2011-03-18
Description: g-p-m used to handle requests to sleep and had config options
 to lock the screen when suspending and/or hibernating.  The functionality
 of actually performing the suspend or hibernate has since been moved to
 upower.  Because of this, g-p-m no longer had the chance to lock the
 screen when the system was manually suspended ( as opposed to g-p-m
 deciding to suspend the system due to idle time or lid switch ).  This
 patch moves this code from the gpm control object suspend and hibernate
 methods to its SLEEPING and RESUMING signals instead, and ties those
 signals to upower via dbus.
Index: b/src/gpm-control.c
===================================================================
--- a/src/gpm-control.c
+++ b/src/gpm-control.c
@@ -57,6 +57,9 @@
 {
 	GConfClient		*conf;
 	UpClient		*client;
+	guint32 throttle_cookie;
+	GpmScreensaver *screensaver;
+	DBusGProxy *proxy;
 };
 
 enum {
@@ -130,71 +133,90 @@
 	return do_lock;
 }
 
-/**
- * gpm_control_suspend:
- **/
-gboolean
-gpm_control_suspend (GpmControl *control, GError **error)
+static void gpm_control_sleep(GpmControl *control,
+			      GpmControlAction action)
 {
-	gboolean allowed;
-	gboolean ret = FALSE;
+	gboolean lock_gnome_keyring;
 	gboolean do_lock;
 	gboolean nm_sleep;
-	gboolean lock_gnome_keyring;
 	GnomeKeyringResult keyres;
-	GpmScreensaver *screensaver;
-	guint32 throttle_cookie = 0;
-
-	screensaver = gpm_screensaver_new ();
 
-	g_object_get (control->priv->client,
-		      "can-suspend", &allowed,
-		      NULL);
-	if (!allowed) {
-		egg_debug ("cannot suspend as not allowed from policy");
-		g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot suspend");
-		goto out;
+	control->priv->screensaver = gpm_screensaver_new ();
+	if (action == GPM_CONTROL_ACTION_HIBERNATE) {
+		do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_HIBERNATE);
+		lock_gnome_keyring = gconf_client_get_bool (control->priv->conf, GPM_CONF_LOCK_GNOME_KEYRING_HIBERNATE, NULL);
+	}
+	else { // GPM_CONTROL_ACTION_SUSPEND
+		do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_SUSPEND);
+		lock_gnome_keyring = gconf_client_get_bool (control->priv->conf, GPM_CONF_LOCK_GNOME_KEYRING_SUSPEND, NULL);
 	}
 
 	/* we should perhaps lock keyrings when sleeping #375681 */
-	lock_gnome_keyring = gconf_client_get_bool (control->priv->conf, GPM_CONF_LOCK_GNOME_KEYRING_SUSPEND, NULL);
 	if (lock_gnome_keyring) {
 		keyres = gnome_keyring_lock_all_sync ();
 		if (keyres != GNOME_KEYRING_RESULT_OK)
 			egg_warning ("could not lock keyring");
 	}
 
-	do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_SUSPEND);
 	if (do_lock) {
-		throttle_cookie = gpm_screensaver_add_throttle (screensaver, "suspend");
-		gpm_screensaver_lock (screensaver);
+		if (action == GPM_CONTROL_ACTION_HIBERNATE)
+			control->priv->throttle_cookie = gpm_screensaver_add_throttle (control->priv->screensaver, "hibernate");
+		else control->priv->throttle_cookie = gpm_screensaver_add_throttle (control->priv->screensaver, "suspend");
+		gpm_screensaver_lock (control->priv->screensaver);
 	}
 
 	nm_sleep = gconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
 	if (nm_sleep)
 		gpm_networkmanager_sleep ();
+}
 
-	/* Do the suspend */
-	egg_debug ("emitting sleep");
-	g_signal_emit (control, signals [SLEEP], 0, GPM_CONTROL_ACTION_SUSPEND);
-
-	ret = up_client_suspend_sync (control->priv->client, NULL, error);
-
-	egg_debug ("emitting resume");
-	g_signal_emit (control, signals [RESUME], 0, GPM_CONTROL_ACTION_SUSPEND);
+static void gpm_control_resume(GpmControl *control,
+			       GpmControlAction action)
+{
+	gboolean do_lock;
+	gboolean nm_sleep;
 
-	if (do_lock) {
-		gpm_screensaver_poke (screensaver);
-		if (throttle_cookie)
-			gpm_screensaver_remove_throttle (screensaver, throttle_cookie);
+	if (action == GPM_CONTROL_ACTION_HIBERNATE) {
+		do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_HIBERNATE);
+	}
+	else {
+		do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_SUSPEND);
+	}
+	if (control->priv->throttle_cookie) {
+		gpm_screensaver_poke (control->priv->screensaver);
+		gpm_screensaver_remove_throttle (control->priv->screensaver, control->priv->throttle_cookie);
 	}
-
 	nm_sleep = gconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
 	if (nm_sleep)
 		gpm_networkmanager_wake ();
 
+	g_object_unref (control->priv->screensaver);
+	control->priv->screensaver = NULL;
+	control->priv->throttle_cookie = 0;
+}
+
+/**
+ * gpm_control_suspend:
+ **/
+gboolean
+gpm_control_suspend (GpmControl *control, GError **error)
+{
+	gboolean allowed;
+	gboolean ret = FALSE;
+
+	g_object_get (control->priv->client,
+		      "can-suspend", &allowed,
+		      NULL);
+	if (!allowed) {
+		egg_debug ("cannot suspend as not allowed from policy");
+		g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot suspend");
+		goto out;
+	}
+
+	/* Do the suspend */
+
+	ret = up_client_suspend_sync (control->priv->client, NULL, error);
 out:
-	g_object_unref (screensaver);
 	return ret;
 }
 
@@ -206,14 +228,6 @@
 {
 	gboolean allowed;
 	gboolean ret = FALSE;
-	gboolean do_lock;
-	gboolean nm_sleep;
-	gboolean lock_gnome_keyring;
-	GnomeKeyringResult keyres;
-	GpmScreensaver *screensaver;
-	guint32 throttle_cookie = 0;
-
-	screensaver = gpm_screensaver_new ();
 
 	g_object_get (control->priv->client,
 		      "can-hibernate", &allowed,
@@ -224,45 +238,8 @@
 		goto out;
 	}
 
-	/* we should perhaps lock keyrings when sleeping #375681 */
-	lock_gnome_keyring = gconf_client_get_bool (control->priv->conf, GPM_CONF_LOCK_GNOME_KEYRING_HIBERNATE, NULL);
-	if (lock_gnome_keyring) {
-		keyres = gnome_keyring_lock_all_sync ();
-		if (keyres != GNOME_KEYRING_RESULT_OK) {
-			egg_warning ("could not lock keyring");
-		}
-	}
-
-	do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_HIBERNATE);
-	if (do_lock) {
-		throttle_cookie = gpm_screensaver_add_throttle (screensaver, "hibernate");
-		gpm_screensaver_lock (screensaver);
-	}
-
-	nm_sleep = gconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
-	if (nm_sleep)
-		gpm_networkmanager_sleep ();
-
-	egg_debug ("emitting sleep");
-	g_signal_emit (control, signals [SLEEP], 0, GPM_CONTROL_ACTION_HIBERNATE);
-
 	ret = up_client_hibernate_sync (control->priv->client, NULL, error);
-
-	egg_debug ("emitting resume");
-	g_signal_emit (control, signals [RESUME], 0, GPM_CONTROL_ACTION_HIBERNATE);
-
-	if (do_lock) {
-		gpm_screensaver_poke (screensaver);
-		if (throttle_cookie)
-			gpm_screensaver_remove_throttle (screensaver, throttle_cookie);
-	}
-
-	nm_sleep = gconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
-	if (nm_sleep)
-		gpm_networkmanager_wake ();
-
 out:
-	g_object_unref (screensaver);
 	return ret;
 }
 
@@ -280,6 +257,7 @@
 
 	g_object_unref (control->priv->conf);
 	g_object_unref (control->priv->client);
+	g_object_unref (control->priv->proxy);
 
 	g_return_if_fail (control->priv != NULL);
 	G_OBJECT_CLASS (gpm_control_parent_class)->finalize (object);
@@ -293,6 +271,8 @@
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	object_class->finalize = gpm_control_finalize;
+	klass->sleep = gpm_control_sleep;
+	klass->resume = gpm_control_resume;
 
 	signals [RESUME] =
 		g_signal_new ("resume",
@@ -316,6 +296,16 @@
 	g_type_class_add_private (klass, sizeof (GpmControlPrivate));
 }
 
+static void proxy_sleeping_cb (DBusGProxy *proxy, guint type, GpmControl *control)
+{
+	g_signal_emit (control, signals [SLEEP], 0, type);
+}
+
+static void proxy_resuming_cb (DBusGProxy *proxy, guint type, GpmControl *control)
+{
+	g_signal_emit (control, signals [RESUME], 0, type);
+}
+
 /**
  * gpm_control_init:
  * @control: This control class instance
@@ -323,10 +313,42 @@
 static void
 gpm_control_init (GpmControl *control)
 {
+	DBusGConnection *connection;
+	GError *error = NULL;
+
+	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	g_assert_no_error (error);
 	control->priv = GPM_CONTROL_GET_PRIVATE (control);
 
 	control->priv->client = up_client_new ();
 	control->priv->conf = gconf_client_get_default ();
+	control->priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
+								"org.freedesktop.UPower",
+								"/org/freedesktop/UPower",
+								"org.freedesktop.UPower",
+								&error);
+	control->priv->throttle_cookie = 0;
+	control->priv->screensaver = 0;
+	g_assert_no_error (error);
+	dbus_g_proxy_add_signal (control->priv->proxy,
+				 "Sleeping",
+				 G_TYPE_UINT,
+				 G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (control->priv->proxy,
+				     "Sleeping",
+				     G_CALLBACK (proxy_sleeping_cb),
+				     control,
+				     NULL);
+	dbus_g_proxy_add_signal (control->priv->proxy,
+				 "Resuming",
+				 G_TYPE_UINT,
+				 G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (control->priv->proxy,
+				     "Resuming",
+				     G_CALLBACK (proxy_resuming_cb),
+				     control,
+				     NULL);
+	g_object_unref (connection);
 }
 
 /**
