diff options
Diffstat (limited to 'src/gpm-screensaver.c')
-rw-r--r-- | src/gpm-screensaver.c | 453 |
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 + |