summaryrefslogtreecommitdiff
path: root/src/gpm-screensaver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpm-screensaver.c')
-rw-r--r--src/gpm-screensaver.c453
1 files changed, 453 insertions, 0 deletions
diff --git a/src/gpm-screensaver.c b/src/gpm-screensaver.c
new file mode 100644
index 0000000..b4f9ad7
--- /dev/null
+++ b/src/gpm-screensaver.c
@@ -0,0 +1,453 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+#include <mateconf/mateconf-client.h>
+
+#include "gpm-screensaver.h"
+#include "gpm-common.h"
+#include "egg-debug.h"
+
+static void gpm_screensaver_finalize (GObject *object);
+
+#define GPM_SCREENSAVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_SCREENSAVER, GpmScreensaverPrivate))
+
+#define GS_LISTENER_SERVICE "org.mate.ScreenSaver"
+#define GS_LISTENER_PATH "/"
+#define GS_LISTENER_INTERFACE "org.mate.ScreenSaver"
+
+struct GpmScreensaverPrivate
+{
+ DBusGProxy *proxy;
+ MateConfClient *conf;
+};
+
+enum {
+ AUTH_REQUEST,
+ LAST_SIGNAL
+};
+
+#if 0
+static guint signals [LAST_SIGNAL] = { 0 };
+#endif
+static gpointer gpm_screensaver_object = NULL;
+
+G_DEFINE_TYPE (GpmScreensaver, gpm_screensaver, G_TYPE_OBJECT)
+
+#if 0
+
+/** Invoked when we get the AuthenticationRequestBegin from g-s when the user
+ * has moved their mouse and we are showing the authentication box.
+ */
+static void
+gpm_screensaver_auth_begin (DBusGProxy *proxy,
+ GpmScreensaver *screensaver)
+{
+ egg_debug ("emitting auth-request : (%i)", TRUE);
+ g_signal_emit (screensaver, signals [AUTH_REQUEST], 0, TRUE);
+}
+
+/** Invoked when we get the AuthenticationRequestEnd from g-s when the user
+ * has entered a valid password or re-authenticated.
+ */
+static void
+gpm_screensaver_auth_end (DBusGProxy *proxy,
+ GpmScreensaver *screensaver)
+{
+ egg_debug ("emitting auth-request : (%i)", FALSE);
+ g_signal_emit (screensaver, signals [AUTH_REQUEST], 0, FALSE);
+}
+
+/**
+ * gpm_screensaver_proxy_connect_more:
+ * @screensaver: This class instance
+ **/
+static gboolean
+gpm_screensaver_proxy_connect_more (GpmScreensaver *screensaver)
+{
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ /* get AuthenticationRequestBegin */
+ dbus_g_proxy_add_signal (screensaver->priv->proxy,
+ "AuthenticationRequestBegin", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (screensaver->priv->proxy,
+ "AuthenticationRequestBegin",
+ G_CALLBACK (gpm_screensaver_auth_begin),
+ screensaver, NULL);
+
+ /* get AuthenticationRequestEnd */
+ dbus_g_proxy_add_signal (screensaver->priv->proxy,
+ "AuthenticationRequestEnd", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (screensaver->priv->proxy,
+ "AuthenticationRequestEnd",
+ G_CALLBACK (gpm_screensaver_auth_end),
+ screensaver, NULL);
+
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_proxy_disconnect_more:
+ * @screensaver: This class instance
+ **/
+static gboolean
+gpm_screensaver_proxy_disconnect_more (GpmScreensaver *screensaver)
+{
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+ egg_debug ("mate-screensaver disconnected from the session DBUS");
+ return TRUE;
+}
+#endif
+
+/**
+ * gpm_screensaver_lock_enabled:
+ * @screensaver: This class instance
+ * Return value: If mate-screensaver is set to lock the screen on screensave
+ **/
+gboolean
+gpm_screensaver_lock_enabled (GpmScreensaver *screensaver)
+{
+ gboolean enabled;
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+ enabled = mateconf_client_get_bool (screensaver->priv->conf, GS_PREF_LOCK_ENABLED, NULL);
+ return enabled;
+}
+
+/**
+ * gpm_screensaver_lock
+ * @screensaver: This class instance
+ * Return value: Success value
+ **/
+gboolean
+gpm_screensaver_lock (GpmScreensaver *screensaver)
+{
+ guint sleepcount = 0;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ egg_debug ("doing mate-screensaver lock");
+ dbus_g_proxy_call_no_reply (screensaver->priv->proxy,
+ "Lock", G_TYPE_INVALID);
+
+ /* When we send the Lock signal to g-ss it takes maybe a second
+ or so to fade the screen and lock. If we suspend mid fade then on
+ resume the X display is still present for a split second
+ (since fade is gamma) and as such it can leak information.
+ Instead we wait until g-ss reports running and thus blanked
+ solidly before we continue from the screensaver_lock action.
+ The interior of g-ss is async, so we cannot get the dbus method
+ to block until lock is complete. */
+ while (! gpm_screensaver_check_running (screensaver)) {
+ /* Sleep for 1/10s */
+ g_usleep (1000 * 100);
+ if (sleepcount++ > 50) {
+ egg_debug ("timeout waiting for mate-screensaver");
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_add_throttle:
+ * @screensaver: This class instance
+ * @reason: The reason for throttling
+ * Return value: Success value, or zero for failure
+ **/
+guint
+gpm_screensaver_add_throttle (GpmScreensaver *screensaver,
+ const char *reason)
+{
+ GError *error = NULL;
+ gboolean ret;
+ guint32 cookie;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), 0);
+ g_return_val_if_fail (reason != NULL, 0);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return 0;
+ }
+
+ ret = dbus_g_proxy_call (screensaver->priv->proxy,
+ "Throttle", &error,
+ G_TYPE_STRING, "Power screensaver",
+ G_TYPE_STRING, reason,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &cookie,
+ G_TYPE_INVALID);
+ if (error) {
+ egg_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
+ if (!ret) {
+ /* abort as the DBUS method failed */
+ egg_warning ("Throttle failed!");
+ return 0;
+ }
+
+ egg_debug ("adding throttle reason: '%s': id %u", reason, cookie);
+ return cookie;
+}
+
+/**
+ * gpm_screensaver_remove_throttle:
+ **/
+gboolean
+gpm_screensaver_remove_throttle (GpmScreensaver *screensaver, guint cookie)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ egg_debug ("removing throttle: id %u", cookie);
+ ret = dbus_g_proxy_call (screensaver->priv->proxy,
+ "UnThrottle", &error,
+ G_TYPE_UINT, cookie,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (error) {
+ egg_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
+ if (!ret) {
+ /* abort as the DBUS method failed */
+ egg_warning ("UnThrottle failed!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_check_running:
+ * @screensaver: This class instance
+ * Return value: TRUE if mate-screensaver is running
+ **/
+gboolean
+gpm_screensaver_check_running (GpmScreensaver *screensaver)
+{
+ gboolean ret;
+ gboolean temp = TRUE;
+ GError *error = NULL;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ ret = dbus_g_proxy_call (screensaver->priv->proxy,
+ "GetActive", &error,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &temp,
+ G_TYPE_INVALID);
+ if (error) {
+ egg_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
+
+ return ret;
+}
+
+/**
+ * gpm_screensaver_poke:
+ * @screensaver: This class instance
+ *
+ * Pokes MATE Screensaver simulating hardware events. This displays the unlock
+ * dialogue when we resume, so the user doesn't have to move the mouse or press
+ * any key before the window comes up.
+ **/
+gboolean
+gpm_screensaver_poke (GpmScreensaver *screensaver)
+{
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ egg_debug ("poke");
+ dbus_g_proxy_call_no_reply (screensaver->priv->proxy,
+ "SimulateUserActivity",
+ G_TYPE_INVALID);
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_screensaver_class_init (GpmScreensaverClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_screensaver_finalize;
+ g_type_class_add_private (klass, sizeof (GpmScreensaverPrivate));
+
+#if 0
+ signals [AUTH_REQUEST] =
+ g_signal_new ("auth-request",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmScreensaverClass, auth_request),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+#endif
+}
+
+/**
+ * gpm_screensaver_init:
+ * @screensaver: This class instance
+ **/
+static void
+gpm_screensaver_init (GpmScreensaver *screensaver)
+{
+ DBusGConnection *connection;
+
+ screensaver->priv = GPM_SCREENSAVER_GET_PRIVATE (screensaver);
+
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+ screensaver->priv->proxy = dbus_g_proxy_new_for_name (connection,
+ GS_LISTENER_SERVICE,
+ GS_LISTENER_PATH,
+ GS_LISTENER_INTERFACE);
+ screensaver->priv->conf = mateconf_client_get_default ();
+}
+
+/**
+ * gpm_screensaver_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_screensaver_finalize (GObject *object)
+{
+ GpmScreensaver *screensaver;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_SCREENSAVER (object));
+
+ screensaver = GPM_SCREENSAVER (object);
+ screensaver->priv = GPM_SCREENSAVER_GET_PRIVATE (screensaver);
+
+ g_object_unref (screensaver->priv->conf);
+ g_object_unref (screensaver->priv->proxy);
+
+ G_OBJECT_CLASS (gpm_screensaver_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_screensaver_new:
+ * Return value: new GpmScreensaver instance.
+ **/
+GpmScreensaver *
+gpm_screensaver_new (void)
+{
+ if (gpm_screensaver_object != NULL) {
+ g_object_ref (gpm_screensaver_object);
+ } else {
+ gpm_screensaver_object = g_object_new (GPM_TYPE_SCREENSAVER, NULL);
+ g_object_add_weak_pointer (gpm_screensaver_object, &gpm_screensaver_object);
+ }
+ return GPM_SCREENSAVER (gpm_screensaver_object);
+}
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+#if 0
+static gboolean test_got_request = FALSE;
+static void
+gpm_screensaver_test_auth_request_cb (GpmScreensaver *screensaver, gboolean auth, EggTest *test)
+{
+ egg_debug ("auth request = %i", auth);
+ test_got_request = auth;
+
+ egg_test_loop_quit (test);
+}
+#endif
+
+void
+gpm_screensaver_test (gpointer data)
+{
+ GpmScreensaver *screensaver;
+// guint value;
+ gboolean ret;
+ EggTest *test = (EggTest *) data;
+
+ if (egg_test_start (test, "GpmScreensaver") == FALSE)
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get a non null screensaver");
+ screensaver = gpm_screensaver_new ();
+ egg_test_assert (test, (screensaver != NULL));
+
+#if 0
+ /* connect signals */
+ g_signal_connect (screensaver, "auth-request",
+ G_CALLBACK (gpm_screensaver_test_auth_request_cb), test);
+#endif
+ /************************************************************/
+ egg_test_title (test, "lock screensaver");
+ ret = gpm_screensaver_lock (screensaver);
+ egg_test_assert (test, ret);
+
+ /************************************************************/
+ egg_test_title (test, "poke screensaver");
+ ret = gpm_screensaver_poke (screensaver);
+ egg_test_assert (test, ret);
+
+ g_object_unref (screensaver);
+
+ egg_test_end (test);
+}
+
+#endif
+