X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=inline;f=cut-n-paste%2Ftotem-screensaver%2Ftotem-scrsaver.c;h=36d314ef20b615ab29ef2afc4bd44300fa7669e7;hb=38c1b9aab8bfb41de6dc07df26fd6743a63ea015;hp=392443043443c69b23d63ac3226ea26c24631529;hpb=0de4e4076b4198674b6fa77c8281cd62a293f2fe;p=evince.git diff --git a/cut-n-paste/totem-screensaver/totem-scrsaver.c b/cut-n-paste/totem-screensaver/totem-scrsaver.c index 39244304..36d314ef 100644 --- a/cut-n-paste/totem-screensaver/totem-scrsaver.c +++ b/cut-n-paste/totem-screensaver/totem-scrsaver.c @@ -1,6 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- Copyright (C) 2004-2006 Bastien Nocera + Copyright © 2010 Christian Persch + Copyright © 2010 Carlos Garcia Campos The Gnome Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -14,50 +16,52 @@ You should have received a copy of the GNU Library General Public License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. - Author: Bastien Nocera + Authors: Bastien Nocera + Christian Persch + Carlos Garcia Campos */ - #include "config.h" -#include +#include + +#ifdef GDK_WINDOWING_X11 #include +#include #ifdef HAVE_XTEST #include #endif /* HAVE_XTEST */ -#include +#endif /* GDK_WINDOWING_X11 */ -#ifdef ENABLE_DBUS -#include +#include "totem-scrsaver.h" #define GS_SERVICE "org.gnome.ScreenSaver" #define GS_PATH "/org/gnome/ScreenSaver" #define GS_INTERFACE "org.gnome.ScreenSaver" -#endif /* ENABLE_DBUS */ - -#include "totem-scrsaver.h" #define XSCREENSAVER_MIN_TIMEOUT 60 -static GObjectClass *parent_class = NULL; -static void totem_scrsaver_class_init (TotemScrsaverClass *class); -static void totem_scrsaver_init (TotemScrsaver *parser); -static void totem_scrsaver_finalize (GObject *object); +enum { + PROP_0, + PROP_REASON +}; +static void totem_scrsaver_finalize (GObject *object); struct TotemScrsaverPrivate { /* Whether the screensaver is disabled */ gboolean disabled; + /* The reason for the inhibition */ + char *reason; -#ifdef ENABLE_DBUS - DBusGConnection *connection; - DBusGProxy *gs_proxy; + GDBusProxy *gs_proxy; + gboolean have_screensaver_dbus; guint32 cookie; -#endif /* ENABLE_DBUS */ + gboolean old_dbus_api; /* To save the screensaver info */ int timeout; @@ -68,7 +72,7 @@ struct TotemScrsaverPrivate { /* For use with XTest */ int keycode1, keycode2; int *keycode; - Bool have_xtest; + gboolean have_xtest; }; G_DEFINE_TYPE(TotemScrsaver, totem_scrsaver, G_TYPE_OBJECT) @@ -76,92 +80,121 @@ G_DEFINE_TYPE(TotemScrsaver, totem_scrsaver, G_TYPE_OBJECT) static gboolean screensaver_is_running_dbus (TotemScrsaver *scr) { -#ifdef ENABLE_DBUS - if (! scr->priv->connection) - return FALSE; - - if (! scr->priv->gs_proxy) - return FALSE; - - return TRUE; -#else - return FALSE; -#endif /* ENABLE_DBUS */ + return scr->priv->have_screensaver_dbus; } static void -screensaver_inhibit_dbus (TotemScrsaver *scr, - gboolean inhibit) +on_inhibit_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { -#ifdef ENABLE_DBUS - GError *error; - gboolean res; - - g_return_if_fail (scr != NULL); - g_return_if_fail (scr->priv->connection != NULL); - g_return_if_fail (scr->priv->gs_proxy != NULL); - - error = NULL; - if (inhibit) { - char *application; - char *reason; - guint32 cookie; - - application = g_strdup ("Evince"); - reason = g_strdup (_("Running in presentation mode")); - - res = dbus_g_proxy_call (scr->priv->gs_proxy, - "Inhibit", - &error, - G_TYPE_STRING, application, - G_TYPE_STRING, reason, - G_TYPE_INVALID, - G_TYPE_UINT, &cookie, - G_TYPE_INVALID); - - if (res) { - /* save the cookie */ - scr->priv->cookie = cookie; - } else { + GDBusProxy *proxy = G_DBUS_PROXY (source_object); + TotemScrsaver *scr = TOTEM_SCRSAVER (user_data); + GVariant *value; + GError *error = NULL; + + value = g_dbus_proxy_call_finish (proxy, res, &error); + if (!value) { + if (!scr->priv->old_dbus_api && + g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) { + g_return_if_fail (scr->priv->reason != NULL); /* try the old API */ - res = dbus_g_proxy_call (scr->priv->gs_proxy, - "InhibitActivation", - &error, - G_TYPE_STRING, reason, - G_TYPE_INVALID, - G_TYPE_INVALID); + scr->priv->old_dbus_api = TRUE; + g_dbus_proxy_call (proxy, + "InhibitActivation", + g_variant_new ("(s)", + scr->priv->reason), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + on_inhibit_cb, + scr); + } else { + g_warning ("Problem inhibiting the screensaver: %s", error->message); } + g_error_free (error); - g_free (reason); - g_free (application); + return; + } - } else { - res = dbus_g_proxy_call (scr->priv->gs_proxy, - "UnInhibit", - &error, - G_TYPE_UINT, scr->priv->cookie, - G_TYPE_INVALID, - G_TYPE_INVALID); - if (res) { - /* clear the cookie */ - scr->priv->cookie = 0; - } else { + /* save the cookie */ + if (g_variant_is_of_type (value, G_VARIANT_TYPE ("(u)"))) + g_variant_get (value, "(u)", &scr->priv->cookie); + else + scr->priv->cookie = 0; + g_variant_unref (value); +} + +static void +on_uninhibit_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (source_object); + TotemScrsaver *scr = TOTEM_SCRSAVER (user_data); + GVariant *value; + GError *error = NULL; + + value = g_dbus_proxy_call_finish (proxy, res, &error); + if (!value) { + if (!scr->priv->old_dbus_api && + g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) { /* try the old API */ - res = dbus_g_proxy_call (scr->priv->gs_proxy, - "AllowActivation", - &error, - G_TYPE_INVALID, - G_TYPE_INVALID); + scr->priv->old_dbus_api = TRUE; + g_dbus_proxy_call (proxy, + "AllowActivation", + g_variant_new ("()"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + on_uninhibit_cb, + scr); + } else { + g_warning ("Problem uninhibiting the screensaver: %s", error->message); } + g_error_free (error); + + return; } - if (! res) { - if (error) { - g_warning ("Problem inhibiting the screensaver: %s", error->message); - g_error_free (error); - } + /* clear the cookie */ + scr->priv->cookie = 0; + g_variant_unref (value); +} + +static void +screensaver_inhibit_dbus (TotemScrsaver *scr, + gboolean inhibit) +{ + TotemScrsaverPrivate *priv = scr->priv; + + if (!priv->have_screensaver_dbus) + return; + + scr->priv->old_dbus_api = FALSE; + + if (inhibit) { + g_return_if_fail (scr->priv->reason != NULL); + g_dbus_proxy_call (priv->gs_proxy, + "Inhibit", + g_variant_new ("(ss)", + g_get_application_name (), + scr->priv->reason), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + on_inhibit_cb, + scr); + } else { + g_dbus_proxy_call (priv->gs_proxy, + "UnInhibit", + g_variant_new ("(u)", priv->cookie), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + on_uninhibit_cb, + scr); } -#endif /* ENABLE_DBUS */ } static void @@ -176,83 +209,94 @@ screensaver_disable_dbus (TotemScrsaver *scr) screensaver_inhibit_dbus (scr, TRUE); } -#ifdef ENABLE_DBUS static void -gs_proxy_destroy_cb (GObject *proxy, - TotemScrsaver *scr) +screensaver_update_dbus_presence (TotemScrsaver *scr) { - g_warning ("Detected that GNOME screensaver has left the bus"); + TotemScrsaverPrivate *priv = scr->priv; + gchar *name_owner; - /* just invalidate for now */ - scr->priv->gs_proxy = NULL; + name_owner = g_dbus_proxy_get_name_owner (priv->gs_proxy); + if (name_owner) { + priv->have_screensaver_dbus = TRUE; + g_free (name_owner); + } else { + priv->have_screensaver_dbus = FALSE; + } } -#endif -#ifdef ENABLE_DBUS static void -screensaver_init_dbus (TotemScrsaver *scr, DBusGConnection *connection) +screensaver_dbus_owner_changed_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data) { - GError *error = NULL; + TotemScrsaver *scr = TOTEM_SCRSAVER (user_data); - if (!connection) - scr->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - else - scr->priv->connection = connection; + screensaver_update_dbus_presence (scr); +} - if (! scr->priv->connection) { - if (error) { - g_warning ("Failed to connect to the session bus: %s", error->message); - g_error_free (error); - } +static void +screensaver_dbus_proxy_new_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + TotemScrsaver *scr = TOTEM_SCRSAVER (user_data); + TotemScrsaverPrivate *priv = scr->priv; + + priv->gs_proxy = g_dbus_proxy_new_for_bus_finish (result, NULL); + if (!priv->gs_proxy) return; - } - scr->priv->gs_proxy = dbus_g_proxy_new_for_name_owner (scr->priv->connection, - GS_SERVICE, - GS_PATH, - GS_INTERFACE, - NULL); - if (scr->priv->gs_proxy != NULL) { - g_signal_connect_object (scr->priv->gs_proxy, - "destroy", - G_CALLBACK (gs_proxy_destroy_cb), - scr, - 0); + screensaver_update_dbus_presence (scr); - } + g_signal_connect (priv->gs_proxy, "notify::g-name-owner", + G_CALLBACK (screensaver_dbus_owner_changed_cb), + scr); +} +static void +screensaver_init_dbus (TotemScrsaver *scr) +{ + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + GS_SERVICE, + GS_PATH, + GS_INTERFACE, + NULL, + screensaver_dbus_proxy_new_cb, + scr); } -#endif /* ENABLE_DBUS */ static void screensaver_finalize_dbus (TotemScrsaver *scr) { -#ifdef ENABLE_DBUS if (scr->priv->gs_proxy) { g_object_unref (scr->priv->gs_proxy); } -#endif /* ENABLE_DBUS */ } +#ifdef GDK_WINDOWING_X11 static void screensaver_enable_x11 (TotemScrsaver *scr) { + Display *xdisplay; #ifdef HAVE_XTEST - if (scr->priv->have_xtest == True) + if (scr->priv->have_xtest != FALSE) { g_source_remove_by_user_data (scr); return; } #endif /* HAVE_XTEST */ - XLockDisplay (GDK_DISPLAY()); - XSetScreenSaver (GDK_DISPLAY(), + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + XLockDisplay (xdisplay); + XSetScreenSaver (xdisplay, scr->priv->timeout, scr->priv->interval, scr->priv->prefer_blanking, scr->priv->allow_exposures); - XUnlockDisplay (GDK_DISPLAY()); + XUnlockDisplay (xdisplay); } #ifdef HAVE_XTEST @@ -261,12 +305,15 @@ fake_event (TotemScrsaver *scr) { if (scr->priv->disabled) { - XLockDisplay (GDK_DISPLAY()); - XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode, + Display *display; + + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + XLockDisplay (xdisplay); + XTestFakeKeyEvent (xdisplay, *scr->priv->keycode, True, CurrentTime); - XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode, + XTestFakeKeyEvent (xdisplay, *scr->priv->keycode, False, CurrentTime); - XUnlockDisplay (GDK_DISPLAY()); + XUnlockDisplay (xdisplay); /* Swap the keycode */ if (scr->priv->keycode == &scr->priv->keycode1) scr->priv->keycode = &scr->priv->keycode2; @@ -281,48 +328,40 @@ fake_event (TotemScrsaver *scr) static void screensaver_disable_x11 (TotemScrsaver *scr) { + Display *xdisplay; + + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); #ifdef HAVE_XTEST - if (scr->priv->have_xtest == True) + if (scr->priv->have_xtest != FALSE) { - XLockDisplay (GDK_DISPLAY()); - XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout, + XLockDisplay (xdisplay); + XGetScreenSaver(xdisplay, &scr->priv->timeout, &scr->priv->interval, &scr->priv->prefer_blanking, &scr->priv->allow_exposures); - XUnlockDisplay (GDK_DISPLAY()); + XUnlockDisplay (xdisplay); - if (scr->priv->timeout != 0) - { -#if GLIB_CHECK_VERSION (2, 13, 0) + if (scr->priv->timeout != 0) { g_timeout_add_seconds (scr->priv->timeout / 2, (GSourceFunc) fake_event, scr); -#else - g_timeout_add (scr->priv->timeout / 2 * 1000, - (GSourceFunc) fake_event, scr); -#endif } else { -#if GLIB_CHECK_VERSION (2, 13, 0) g_timeout_add_seconds (XSCREENSAVER_MIN_TIMEOUT / 2, - (GSourceFunc) fake_event, scr); -#else - g_timeout_add (XSCREENSAVER_MIN_TIMEOUT / 2 * 1000, - (GSourceFunc) fake_event, scr); -#endif + (GSourceFunc) fake_event, scr); } return; } #endif /* HAVE_XTEST */ - XLockDisplay (GDK_DISPLAY()); - XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout, + XLockDisplay (xdisplay); + XGetScreenSaver(xdisplay, &scr->priv->timeout, &scr->priv->interval, &scr->priv->prefer_blanking, &scr->priv->allow_exposures); - XSetScreenSaver(GDK_DISPLAY(), 0, 0, + XSetScreenSaver(xdisplay, 0, 0, DontPreferBlanking, DontAllowExposures); - XUnlockDisplay (GDK_DISPLAY()); + XUnlockDisplay (xdisplay); } static void @@ -330,25 +369,28 @@ screensaver_init_x11 (TotemScrsaver *scr) { #ifdef HAVE_XTEST int a, b, c, d; + Display *display; + + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - XLockDisplay (GDK_DISPLAY()); - scr->priv->have_xtest = XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d); - if(scr->priv->have_xtest == True) + XLockDisplay (xdisplay); + scr->priv->have_xtest = (XTestQueryExtension (xdisplay, &a, &b, &c, &d) == True); + if (scr->priv->have_xtest != FALSE) { - scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L); + scr->priv->keycode1 = XKeysymToKeycode (xdisplay, XK_Alt_L); if (scr->priv->keycode1 == 0) { g_warning ("scr->priv->keycode1 not existant"); } - scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_R); + scr->priv->keycode2 = XKeysymToKeycode (xdisplay, XK_Alt_R); if (scr->priv->keycode2 == 0) { - scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L); + scr->priv->keycode2 = XKeysymToKeycode (xdisplay, XK_Alt_L); if (scr->priv->keycode2 == 0) { g_warning ("scr->priv->keycode2 not existant"); } } scr->priv->keycode = &scr->priv->keycode1; } - XUnlockDisplay (GDK_DISPLAY()); + XUnlockDisplay (xdisplay); #endif /* HAVE_XTEST */ } @@ -357,51 +399,102 @@ screensaver_finalize_x11 (TotemScrsaver *scr) { g_source_remove_by_user_data (scr); } +#endif + +static void +totem_scrsaver_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + TotemScrsaver *scr; + + scr = TOTEM_SCRSAVER (object); + + switch (property_id) + { + case PROP_REASON: + g_value_set_string (value, scr->priv->reason); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +totem_scrsaver_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + TotemScrsaver *scr; + + scr = TOTEM_SCRSAVER (object); + + switch (property_id) + { + case PROP_REASON: + g_free (scr->priv->reason); + scr->priv->reason = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} static void totem_scrsaver_class_init (TotemScrsaverClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); + g_type_class_add_private (klass, sizeof (TotemScrsaverPrivate)); + object_class->set_property = totem_scrsaver_set_property; + object_class->get_property = totem_scrsaver_get_property; object_class->finalize = totem_scrsaver_finalize; -} -#ifdef ENABLE_DBUS -TotemScrsaver * -totem_scrsaver_new (DBusGConnection *connection) -{ - TotemScrsaver * scr; - scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL)); + g_object_class_install_property (object_class, PROP_REASON, + g_param_spec_string ("reason", NULL, NULL, + NULL, G_PARAM_READWRITE)); - screensaver_init_dbus (scr, connection); - screensaver_init_x11 (scr); - - return scr; } -#else + +/** + * totem_scrsaver_new: + * + * Creates a #TotemScrsaver object. + * If the GNOME screen saver is running, it uses its DBUS interface to + * inhibit the screensaver; otherwise it falls back to using the X + * screensaver functionality for this. + * + * Returns: a newly created #TotemScrsaver + */ TotemScrsaver * -totem_scrsaver_new() +totem_scrsaver_new (void) { - TotemScrsaver * scr; - scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL)); - - screensaver_init_x11 (scr); - - return scr; + return TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL)); } -#endif static void totem_scrsaver_init (TotemScrsaver *scr) { - scr->priv = g_new0 (TotemScrsaverPrivate, 1); + scr->priv = G_TYPE_INSTANCE_GET_PRIVATE (scr, + TOTEM_TYPE_SCRSAVER, + TotemScrsaverPrivate); + + screensaver_init_dbus (scr); +#ifdef GDK_WINDOWING_X11 + screensaver_init_x11 (scr); +#else +#warning Unimplemented +#endif } void totem_scrsaver_disable (TotemScrsaver *scr) { + g_return_if_fail (TOTEM_SCRSAVER (scr)); + if (scr->priv->disabled != FALSE) return; @@ -410,12 +503,19 @@ totem_scrsaver_disable (TotemScrsaver *scr) if (screensaver_is_running_dbus (scr) != FALSE) screensaver_disable_dbus (scr); else +#ifdef GDK_WINDOWING_X11 screensaver_disable_x11 (scr); +#else +#warning Unimplemented + {} +#endif } void totem_scrsaver_enable (TotemScrsaver *scr) { + g_return_if_fail (TOTEM_SCRSAVER (scr)); + if (scr->priv->disabled == FALSE) return; @@ -423,8 +523,27 @@ totem_scrsaver_enable (TotemScrsaver *scr) if (screensaver_is_running_dbus (scr) != FALSE) screensaver_enable_dbus (scr); - else + else +#ifdef GDK_WINDOWING_X11 screensaver_enable_x11 (scr); +#else +#warning Unimplemented + {} +#endif +} + +void +totem_scrsaver_set_state (TotemScrsaver *scr, gboolean enable) +{ + g_return_if_fail (TOTEM_SCRSAVER (scr)); + + if (scr->priv->disabled == !enable) + return; + + if (enable == FALSE) + totem_scrsaver_disable (scr); + else + totem_scrsaver_enable (scr); } static void @@ -432,13 +551,15 @@ totem_scrsaver_finalize (GObject *object) { TotemScrsaver *scr = TOTEM_SCRSAVER (object); + g_free (scr->priv->reason); + screensaver_finalize_dbus (scr); +#ifdef GDK_WINDOWING_X11 screensaver_finalize_x11 (scr); +#else +#warning Unimplemented + {} +#endif - g_free (scr->priv); - - if (G_OBJECT_CLASS (parent_class)->finalize != NULL) { - (* G_OBJECT_CLASS (parent_class)->finalize) (object); - } + G_OBJECT_CLASS (totem_scrsaver_parent_class)->finalize (object); } -