Re: [gpm] [Pm-utils] Re: Dealing with suspend/resume failures



On Thu, 2006-11-09 at 16:27 -0500, David Zeuthen wrote:
> On Thu, 2006-11-09 at 21:11 +0000, Richard Hughes wrote:
> > Yes, it needs some cleanup but I can do this for you on HEAD. 
> 
> Yea, it was a quick one hour job, was working against the clock, sorry.

How does the attached look (against HEAD)?

I've applied this - we can hack it about as much as you like, and if we
change the mechanism a little I can always update it. I really wanted to
get the translations committed asap, and have a play with this myself.

I guess this makes most sense (grammar advice gratefully received):

Your computer did not appear to resume correctly from suspend.
This may be a driver or hardware problem.
Check the GNOME Power Manager manual for common problems.

I appreciate it's probably too late for RHEL, but I though you might be
interested in how I adapted it. Feel free to shout "BUT YOU CAN'T DO IT
THAT WAY!" :-)

Richard
Index: src/gpm-hal.c
===================================================================
RCS file: /cvs/gnome/gnome-power-manager/src/gpm-hal.c,v
retrieving revision 1.44
diff -u -r1.44 gpm-hal.c
--- src/gpm-hal.c	2 Nov 2006 19:53:29 -0000	1.44
+++ src/gpm-hal.c	10 Nov 2006 00:06:05 -0000
@@ -1487,11 +1487,125 @@
 	return TRUE;
 }
 
+/**
+ * gpm_hal_has_suspend_error:
+ *
+ * @hal: This class instance
+ * @enable: Return true if there was a suspend error
+ * Return value: Success
+ *
+ * TODO: should call a method on HAL and also return the ouput of the file
+ **/
+gboolean
+gpm_hal_has_suspend_error (GpmHal *hal, gboolean *state)
+{
+	g_return_val_if_fail (hal != NULL, FALSE);
+	g_return_val_if_fail (state != NULL, FALSE);
+	g_return_val_if_fail (GPM_IS_HAL (hal), FALSE);
+	*state = g_file_test ("/var/lib/hal/system-power-suspend-output", G_FILE_TEST_EXISTS);
+	return TRUE;
+}
 
+/**
+ * gpm_hal_has_hibernate_error:
+ *
+ * @hal: This class instance
+ * @enable: Return true if there was a hibernate error
+ * Return value: Success
+ *
+ * TODO: should call a method on HAL and also return the ouput of the file
+ **/
+gboolean
+gpm_hal_has_hibernate_error (GpmHal *hal, gboolean *state)
+{
+	g_return_val_if_fail (hal != NULL, FALSE);
+	g_return_val_if_fail (state != NULL, FALSE);
+	g_return_val_if_fail (GPM_IS_HAL (hal), FALSE);
+	*state = g_file_test ("/var/lib/hal/system-power-hibernate-output", G_FILE_TEST_EXISTS);
+	return TRUE;
+}
+
+/**
+ * gpm_hal_clear_suspend_error:
+ *
+ * @hal: This class instance
+ * Return value: Success
+ *
+ * Tells HAL to try and clear the suspend error as we appear to be okay
+ **/
+gboolean
+gpm_hal_clear_suspend_error (GpmHal *hal)
+{
+	GError *error = NULL;
+	gboolean ret;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (hal != NULL, FALSE);
+	g_return_val_if_fail (GPM_IS_HAL (hal), FALSE);
+
+	proxy = gpm_proxy_get_proxy (hal->priv->gproxy_power);
+	if (proxy == NULL) {
+		gpm_warning ("not connected");
+		return FALSE;
+	}
+
+	gpm_debug ("Doing SuspendClearError");
+	ret = dbus_g_proxy_call (proxy, "SuspendClearError", &error,
+				 G_TYPE_INVALID, G_TYPE_INVALID);
+	if (error) {
+		gpm_debug ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		gpm_warning ("SuspendClearError failed!");
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * gpm_hal_clear_hibernate_error:
+ *
+ * @hal: This class instance
+ * Return value: Success
+ *
+ * Tells HAL to try and clear the hibernate error as we appear to be okay
+ **/
+gboolean
+gpm_hal_clear_hibernate_error (GpmHal *hal)
+{
+	GError *error = NULL;
+	gboolean ret;
+	DBusGProxy *proxy;
+
+	g_return_val_if_fail (hal != NULL, FALSE);
+	g_return_val_if_fail (GPM_IS_HAL (hal), FALSE);
+
+	proxy = gpm_proxy_get_proxy (hal->priv->gproxy_power);
+	if (proxy == NULL) {
+		gpm_warning ("not connected");
+		return FALSE;
+	}
+
+	gpm_debug ("Doing HibernateClearError");
+	ret = dbus_g_proxy_call (proxy, "HibernateClearError", &error,
+				 G_TYPE_INVALID, G_TYPE_INVALID);
+	if (error) {
+		gpm_debug ("ERROR: %s", error->message);
+		g_error_free (error);
+	}
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		gpm_warning ("HibernateClearError failed!");
+		return FALSE;
+	}
+	return TRUE;
+}
 
 /**
  * gpm_hal_finalize:
- * @object: This hal class instance
+ * @object: This class instance
  **/
 static void
 gpm_hal_finalize (GObject *object)
Index: src/gpm-hal.h
===================================================================
RCS file: /cvs/gnome/gnome-power-manager/src/gpm-hal.h,v
retrieving revision 1.21
diff -u -r1.21 gpm-hal.h
--- src/gpm-hal.h	2 Nov 2006 19:53:30 -0000	1.21
+++ src/gpm-hal.h	10 Nov 2006 00:06:05 -0000
@@ -151,6 +151,12 @@
 gboolean	 gpm_hal_enable_power_save		(GpmHal		*hal,
 							 gboolean	 enable);
 gboolean	 gpm_hal_is_laptop			(GpmHal		*hal);
+gboolean	 gpm_hal_has_suspend_error		(GpmHal		*hal,
+							 gboolean	*state);
+gboolean	 gpm_hal_has_hibernate_error		(GpmHal		*hal,
+							 gboolean	*state);
+gboolean	 gpm_hal_clear_suspend_error		(GpmHal		*hal);
+gboolean	 gpm_hal_clear_hibernate_error		(GpmHal		*hal);
 
 G_END_DECLS
 
Index: src/gpm-manager.c
===================================================================
RCS file: /cvs/gnome/gnome-power-manager/src/gpm-manager.c,v
retrieving revision 1.224
diff -u -r1.224 gpm-manager.c
--- src/gpm-manager.c	9 Nov 2006 00:21:04 -0000	1.224
+++ src/gpm-manager.c	10 Nov 2006 00:06:08 -0000
@@ -114,6 +114,7 @@
 };
 
 static guint	     signals [LAST_SIGNAL] = { 0, };
+static gpointer      manager_object = NULL; /* needed for g_atexit */
 
 G_DEFINE_TYPE (GpmManager, gpm_manager, G_TYPE_OBJECT)
 
@@ -1936,6 +1937,81 @@
 }
 
 /**
+ * gpm_manager_check_sleep_errors:
+ * @manager: This class instance
+ *
+ * Checks HAL for resume failures
+ **/
+static void
+gpm_manager_check_sleep_errors (GpmManager *manager)
+{
+	gboolean suspend_error;
+	gboolean hibernate_error;
+	const gchar *error_title = NULL;
+	const gchar *error_body = NULL;
+	gchar *error_msg;
+
+	gpm_hal_has_suspend_error (manager->priv->hal, &suspend_error);
+	gpm_hal_has_hibernate_error (manager->priv->hal, &hibernate_error);
+
+	if (suspend_error == TRUE) {
+		error_title = _("Suspend failure");
+		error_body = _("Your computer did not appear to resume correctly from suspend.");
+	}
+	if (hibernate_error == TRUE) {
+		error_title = _("Hibernate failure");
+		error_body = _("Your computer did not appear to resume correctly from hibernate.");
+	}
+
+	if (suspend_error == TRUE || hibernate_error == TRUE) {
+		error_msg = g_strdup_printf ("%s\n%s\n%s", error_body,
+					     _("This may be a driver or hardware problem."),
+					     _("Check the GNOME Power Manager manual for common problems."));
+		gpm_tray_icon_notify (manager->priv->tray_icon,
+				      error_title,
+				      error_msg,
+				      GPM_NOTIFY_TIMEOUT_LONG,
+				      GTK_STOCK_DIALOG_WARNING,
+				      GPM_NOTIFY_URGENCY_NORMAL);
+		g_free (error_msg);
+	}
+}
+
+/**
+ * screensaver_auth_request_cb:
+ * @manager: This manager class instance
+ * @auth: If we are trying to authenticate
+ *
+ * Called when the user has authenticated
+ **/
+static void
+screensaver_auth_request_cb (GpmScreensaver *screensaver,
+			     gboolean        auth,
+			     GpmManager     *manager)
+{
+	/* only clear errors if we have finished the authentication */
+	if (auth == FALSE) {
+		gpm_hal_clear_suspend_error (manager->priv->hal);
+		gpm_hal_clear_hibernate_error (manager->priv->hal);
+	}
+}
+
+/**
+ * gpm_manager_at_exit:
+ *
+ * Called when we are exiting. We should remove the errors if any
+ * exist so we don't get them again on next boot.
+ **/
+static void 
+gpm_manager_at_exit (void)
+{
+	/* we can't use manager as g_atexit has no userdata */
+	GpmManager *manager = GPM_MANAGER (manager_object);
+	gpm_hal_clear_suspend_error (manager->priv->hal);
+	gpm_hal_clear_hibernate_error (manager->priv->hal);
+}
+
+/**
  * gpm_manager_init:
  * @manager: This class instance
  **/
@@ -1951,6 +2027,9 @@
 
 	manager->priv = GPM_MANAGER_GET_PRIVATE (manager);
 
+	/* do some actions even when killed */
+	g_atexit (gpm_manager_at_exit);
+
 	manager->priv->conf = gpm_conf_new ();
 	g_signal_connect (manager->priv->conf, "value-changed",
 			  G_CALLBACK (conf_key_changed_cb), manager);
@@ -1982,6 +2061,8 @@
 	manager->priv->screensaver = gpm_screensaver_new ();
 	if (manager->priv->screensaver != NULL) {
 		gpm_screensaver_service_init (manager->priv->screensaver);
+	 	g_signal_connect (manager->priv->screensaver, "auth-request",
+	 			  G_CALLBACK (screensaver_auth_request_cb), manager);
 	}
 
 	/* try an start an interactive service */
@@ -2078,15 +2159,11 @@
 	/* Pretend we just resumed when we start to let actions settle */
 	gpm_manager_reset_event_time (manager);
 
-	/* needed in the future */
-	if (FALSE) {
-		char *temp;
-		temp = _("Your system did not resume correctly.");
-		temp = _("This might be a hardware or software problem.");
-	}
-
-	/* Do we beep? */
+	/* do we beep? */
 	gpm_conf_get_bool (manager->priv->conf, GPM_CONF_ENABLE_BEEPING, &manager->priv->enable_beeping);
+
+	/* on startup, check if there are suspend errors left */
+	gpm_manager_check_sleep_errors (manager);
 }
 
 /**
@@ -2150,6 +2227,7 @@
 	GpmManager *manager;
 
 	manager = g_object_new (GPM_TYPE_MANAGER, NULL);
+	manager_object = manager;
 
 	return GPM_MANAGER (manager);
 }


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