]> www.fi.muni.cz Git - evince.git/blobdiff - cut-n-paste/totem-screensaver/totem-scrsaver.c
[totem-screensaver] Use g_bus_watch_proxy instead of g_bus_watch_name
[evince.git] / cut-n-paste / totem-screensaver / totem-scrsaver.c
index 392443043443c69b23d63ac3226ea26c24631529..64a7844267a07842d5204657a7caa60a0d0b78da 100644 (file)
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 
    Copyright (C) 2004-2006 Bastien Nocera <hadess@hadess.net>
+   Copyright © 2010 Christian Persch
 
    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,8 +15,8 @@
 
    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 <hadess@hadess.net>
  */
 #include "config.h"
 
 #include <glib/gi18n.h>
+
+#include <gdk/gdk.h>
+
+#ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
+#include <X11/keysym.h>
 
 #ifdef HAVE_XTEST
 #include <X11/extensions/XTest.h>
 #endif /* HAVE_XTEST */
-#include <X11/keysym.h>
+#endif /* GDK_WINDOWING_X11 */
 
-#ifdef ENABLE_DBUS
-#include <dbus/dbus-glib.h>
+#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);
 
-
 struct TotemScrsaverPrivate {
        /* Whether the screensaver is disabled */
        gboolean disabled;
 
-#ifdef ENABLE_DBUS
-       DBusGConnection *connection;
-       DBusGProxy *gs_proxy;
+       GDBusProxy *gs_proxy;
+        gboolean have_screensaver_dbus;
+        guint watch_id;
        guint32 cookie;
-#endif /* ENABLE_DBUS */
 
        /* To save the screensaver info */
        int timeout;
@@ -68,7 +66,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 +74,82 @@ 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)
 {
-#ifdef ENABLE_DBUS
-       GError *error;
-       gboolean res;
+        TotemScrsaverPrivate *priv = scr->priv;
+       GError *error = NULL;
+        GVariant *value;
 
-       g_return_if_fail (scr != NULL);
-       g_return_if_fail (scr->priv->connection != NULL);
-       g_return_if_fail (scr->priv->gs_proxy != NULL);
+        if (!priv->have_screensaver_dbus)
+                return;
 
-       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) {
+                value = g_dbus_proxy_call_sync (priv->gs_proxy,
+                                               "Inhibit",
+                                               g_variant_new ("(ss)",
+                                                              "Evince",
+                                                              _("Running in presentation mode")),
+                                               G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                               -1,
+                                               NULL,
+                                               &error);
+               if (error && g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) {
+                       /* try the old API */
+                        g_clear_error (&error);
+                        value = g_dbus_proxy_call_sync (priv->gs_proxy,
+                                                       "InhibitActivation",
+                                                       g_variant_new ("(s)",
+                                                                      _("Running in presentation mode")),
+                                                       G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                                       -1,
+                                                       NULL,
+                                                       &error);
+                }
+                if (value != NULL) {
                        /* save the cookie */
-                       scr->priv->cookie = cookie;
+                        if (g_variant_is_of_type (value, G_VARIANT_TYPE ("(u)")))
+                              g_variant_get (value, "(u)", &priv->cookie);
+                        else
+                                priv->cookie = 0;
+                        g_variant_unref (value);
                } else {
-                       /* 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);
+                       g_warning ("Problem inhibiting the screensaver: %s", error->message);
+                        g_error_free (error);
                }
 
-               g_free (reason);
-               g_free (application);
-
        } 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) {
+                value = g_dbus_proxy_call_sync (priv->gs_proxy,
+                                               "UnInhibit",
+                                               g_variant_new ("(u)", priv->cookie),
+                                               G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                               -1,
+                                               NULL,
+                                               &error);
+               if (error && g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) {
+                       /* try the old API */
+                        g_clear_error (&error);
+                        value = g_dbus_proxy_call_sync (priv->gs_proxy,
+                                                       "AllowActivation",
+                                                       g_variant_new ("()"),
+                                                       G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                                       -1,
+                                                       NULL,
+                                                       &error);
+                }
+                if (value != NULL) {
                        /* clear the cookie */
-                       scr->priv->cookie = 0;
+                       priv->cookie = 0;
+                        g_variant_unref (value);
                } else {
-                       /* try the old API */
-                       res = dbus_g_proxy_call (scr->priv->gs_proxy,
-                                                "AllowActivation",
-                                                &error,
-                                                G_TYPE_INVALID,
-                                                G_TYPE_INVALID);
-               }
-       }
-
-       if (! res) {
-               if (error) {
-                       g_warning ("Problem inhibiting the screensaver: %s", error->message);
+                       g_warning ("Problem uninhibiting the screensaver: %s", error->message);
                        g_error_free (error);
                }
        }
-#endif /* ENABLE_DBUS */
 }
 
 static void
@@ -176,70 +164,75 @@ screensaver_disable_dbus (TotemScrsaver *scr)
        screensaver_inhibit_dbus (scr, TRUE);
 }
 
-#ifdef ENABLE_DBUS
 static void
-gs_proxy_destroy_cb (GObject *proxy,
-                    TotemScrsaver *scr)
+screensaver_dbus_appeared_cb (GDBusConnection *connection,
+                             const gchar     *name,
+                             const gchar     *name_owner,
+                             GDBusProxy      *proxy,
+                             gpointer         user_data)
 {
-       g_warning ("Detected that GNOME screensaver has left the bus");
+        TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
+        TotemScrsaverPrivate *priv = scr->priv;
 
-       /* just invalidate for now */
-       scr->priv->gs_proxy = NULL;
+       priv->gs_proxy = g_object_ref (proxy);
+
+        priv->have_screensaver_dbus = TRUE;
 }
-#endif
 
-#ifdef ENABLE_DBUS
 static void
-screensaver_init_dbus (TotemScrsaver *scr, DBusGConnection *connection)
+screensaver_dbus_disappeared_cb (GDBusConnection *connection,
+                                const gchar     *name,
+                                gpointer         user_data)
 {
-       GError *error = NULL;
-
-       if (!connection)
-               scr->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-       else
-               scr->priv->connection = connection;
+        TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
+        TotemScrsaverPrivate *priv = scr->priv;
 
-       if (! scr->priv->connection) {
-               if (error) {
-                       g_warning ("Failed to connect to the session bus: %s", error->message);
-                       g_error_free (error);
-               }
-               return;
+       if (priv->gs_proxy) {
+               g_object_unref (priv->gs_proxy);
+               priv->gs_proxy = NULL;
        }
 
-       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);
-
-       }
+        priv->have_screensaver_dbus = FALSE;
+}
 
+static void
+screensaver_init_dbus (TotemScrsaver *scr)
+{
+       TotemScrsaverPrivate *priv = scr->priv;
+
+        priv->watch_id = g_bus_watch_proxy (G_BUS_TYPE_SESSION,
+                                           GS_SERVICE,
+                                           G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                           GS_PATH,
+                                           GS_INTERFACE,
+                                           G_TYPE_DBUS_PROXY,
+                                           G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+                                           G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+                                           screensaver_dbus_appeared_cb,
+                                           screensaver_dbus_disappeared_cb,
+                                           scr, NULL);
 }
-#endif /* ENABLE_DBUS */
 
 static void
 screensaver_finalize_dbus (TotemScrsaver *scr)
 {
-#ifdef ENABLE_DBUS
+        TotemScrsaverPrivate *priv = scr->priv;
+
        if (scr->priv->gs_proxy) {
                g_object_unref (scr->priv->gs_proxy);
        }
-#endif /* ENABLE_DBUS */
+
+       if (priv->watch_id > 0)
+               g_bus_unwatch_proxy (priv->watch_id);
 }
 
+#ifdef GDK_WINDOWING_X11
 static void
 screensaver_enable_x11 (TotemScrsaver *scr)
 {
 
 #ifdef HAVE_XTEST
-       if (scr->priv->have_xtest == True)
+       if (scr->priv->have_xtest != FALSE)
        {
                g_source_remove_by_user_data (scr);
                return;
@@ -283,7 +276,7 @@ screensaver_disable_x11 (TotemScrsaver *scr)
 {
 
 #ifdef HAVE_XTEST
-       if (scr->priv->have_xtest == True)
+       if (scr->priv->have_xtest != FALSE)
        {
                XLockDisplay (GDK_DISPLAY());
                XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
@@ -292,23 +285,12 @@ screensaver_disable_x11 (TotemScrsaver *scr)
                                &scr->priv->allow_exposures);
                XUnlockDisplay (GDK_DISPLAY());
 
-               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;
@@ -332,8 +314,8 @@ screensaver_init_x11 (TotemScrsaver *scr)
        int a, b, c, d;
 
        XLockDisplay (GDK_DISPLAY());
-       scr->priv->have_xtest = XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d);
-       if(scr->priv->have_xtest == True)
+       scr->priv->have_xtest = (XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d) == True);
+       if (scr->priv->have_xtest != FALSE)
        {
                scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
                if (scr->priv->keycode1 == 0) {
@@ -357,6 +339,7 @@ screensaver_finalize_x11 (TotemScrsaver *scr)
 {
        g_source_remove_by_user_data (scr);
 }
+#endif
 
 static void
 totem_scrsaver_class_init (TotemScrsaverClass *klass)
@@ -368,40 +351,40 @@ totem_scrsaver_class_init (TotemScrsaverClass *klass)
        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));
-
-       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);
+
+       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 +393,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;
 
@@ -424,7 +414,26 @@ totem_scrsaver_enable (TotemScrsaver *scr)
        if (screensaver_is_running_dbus (scr) != FALSE)
                screensaver_enable_dbus (scr);
        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
@@ -433,12 +442,12 @@ totem_scrsaver_finalize (GObject *object)
        TotemScrsaver *scr = TOTEM_SCRSAVER (object);
 
        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 (parent_class)->finalize (object);
 }
-