/* -*- 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
+ 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
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301 USA.
- Author: Bastien Nocera <hadess@hadess.net>
+ Authors: Bastien Nocera <hadess@hadess.net>
+ Christian Persch
+ Carlos Garcia Campos
*/
-
#include "config.h"
-#include <glib/gi18n.h>
-
#include <gdk/gdk.h>
#ifdef GDK_WINDOWING_X11
#endif /* HAVE_XTEST */
#endif /* GDK_WINDOWING_X11 */
-#ifdef ENABLE_DBUS
+#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;
+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
- GDBusConnection *connection;
+ GDBusProxy *gs_proxy;
gboolean have_screensaver_dbus;
- guint watch_id;
guint32 cookie;
-#endif /* ENABLE_DBUS */
+ gboolean old_dbus_api;
/* To save the screensaver info */
int timeout;
static gboolean
screensaver_is_running_dbus (TotemScrsaver *scr)
{
-#ifdef ENABLE_DBUS
- return scr->priv->connection != NULL;
-#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
- TotemScrsaverPrivate *priv = scr->priv;
- GError *error = NULL;
- GVariant *value;
-
- if (!priv->have_screensaver_dbus)
- return;
-
- if (inhibit) {
- value = g_dbus_connection_call_sync (priv->connection,
- GS_SERVICE,
- GS_PATH,
- GS_INTERFACE,
- "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)) {
+ 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 */
- g_clear_error (&error);
- value = g_dbus_connection_call_sync (priv->connection,
- GS_SERVICE,
- GS_PATH,
- GS_INTERFACE,
- "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 */
- 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);
+ 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_error_free (error);
- } else {
- value = g_dbus_connection_call_sync (priv->connection,
- GS_SERVICE,
- GS_PATH,
- GS_INTERFACE,
- "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)) {
+ return;
+ }
+
+ /* 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 */
- g_clear_error (&error);
- value = g_dbus_connection_call_sync (priv->connection,
- GS_SERVICE,
- GS_PATH,
- GS_INTERFACE,
- "AllowActivation",
- g_variant_new ("()"),
- G_DBUS_CALL_FLAGS_NO_AUTO_START,
- -1,
- NULL,
- &error);
- }
- if (value != NULL) {
- /* clear the cookie */
- priv->cookie = 0;
- g_variant_unref (value);
+ 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);
}
+ g_error_free (error);
+
+ return;
+ }
+
+ /* 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
screensaver_inhibit_dbus (scr, TRUE);
}
-#ifdef ENABLE_DBUS
static void
-screensaver_dbus_appeared_cb (GDBusConnection *connection,
- const char *name,
- const char *name_owner,
- gpointer user_data)
+screensaver_update_dbus_presence (TotemScrsaver *scr)
{
- TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
TotemScrsaverPrivate *priv = scr->priv;
+ gchar *name_owner;
- g_assert (connection == priv->connection);
-
- priv->have_screensaver_dbus = TRUE;
+ 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;
+ }
}
static void
-screensaver_dbus_disappeared_cb (GDBusConnection *connection,
- const char *name,
- gpointer user_data)
+screensaver_dbus_owner_changed_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
{
TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
- TotemScrsaverPrivate *priv = scr->priv;
- g_assert (connection == priv->connection);
+ screensaver_update_dbus_presence (scr);
+}
+
+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;
+
+ screensaver_update_dbus_presence (scr);
- priv->have_screensaver_dbus = FALSE;
+ g_signal_connect (priv->gs_proxy, "notify::g-name-owner",
+ G_CALLBACK (screensaver_dbus_owner_changed_cb),
+ scr);
}
-#endif
static void
screensaver_init_dbus (TotemScrsaver *scr)
{
-#ifdef ENABLE_DBUS
- TotemScrsaverPrivate *priv = scr->priv;
-
- priv->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
- GS_SERVICE,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- screensaver_dbus_appeared_cb,
- screensaver_dbus_disappeared_cb,
- scr, NULL);
-#endif /* ENABLE_DBUS */
+ 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);
}
static void
screensaver_finalize_dbus (TotemScrsaver *scr)
{
-#ifdef ENABLE_DBUS
- g_bus_unwatch_name (scr->priv->watch_id);
-
- if (scr->priv->connection != NULL)
- g_object_unref (scr->priv->connection);
-#endif /* ENABLE_DBUS */
+ if (scr->priv->gs_proxy) {
+ g_object_unref (scr->priv->gs_proxy);
+ }
}
#ifdef GDK_WINDOWING_X11
}
#endif
-#ifdef ENABLE_DBUS
-
-enum {
- PROP_0,
- PROP_CONNECTION
-};
-
static void
-totem_scrsaver_constructed (GObject *object)
+totem_scrsaver_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- TotemScrsaver *scr = TOTEM_SCRSAVER (object);
- TotemScrsaverPrivate *priv = scr->priv;
+ TotemScrsaver *scr;
+
+ scr = TOTEM_SCRSAVER (object);
- priv->watch_id = g_bus_watch_name_on_connection (priv->connection,
- GS_SERVICE,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- screensaver_dbus_appeared_cb,
- screensaver_dbus_disappeared_cb,
- scr, NULL);
+ 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 prop_id,
- const GValue *value,
- GParamSpec *pspec)
+totem_scrsaver_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- TotemScrsaver *scr = TOTEM_SCRSAVER (object);
- TotemScrsaverPrivate *priv = scr->priv;
+ TotemScrsaver *scr;
+
+ scr = TOTEM_SCRSAVER (object);
- switch (prop_id) {
- case PROP_CONNECTION:
- priv->connection = g_value_dup_object (value);
+ 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, prop_id, pspec);
- break;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
-#endif /* ENABLE_DBUS */
-
static void
totem_scrsaver_class_init (TotemScrsaverClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
-#ifdef ENABLE_DBUS
- g_object_class_install_property (object_class,
- PROP_CONNECTION,
- g_param_spec_object ("connection", NULL, NULL,
- G_TYPE_DBUS_CONNECTION,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- object_class->set_property = totem_scrsaver_set_property;
- object_class->constructed = totem_scrsaver_constructed;
-#endif
+ 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;
+
+ g_object_class_install_property (object_class, PROP_REASON,
+ g_param_spec_string ("reason", NULL, NULL,
+ NULL, G_PARAM_READWRITE));
+
}
+/**
+ * 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 *
-#ifdef ENABLE_DBUS
-totem_scrsaver_new (GDBusConnection *connection)
-#else
totem_scrsaver_new (void)
-#endif
{
- return g_object_new (TOTEM_TYPE_SCRSAVER,
-#ifdef ENABLE_DBUS
- "connection", connection,
-#endif
- NULL);
+ return TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
}
static void
totem_scrsaver_init (TotemScrsaver *scr)
{
- scr->priv = G_TYPE_INSTANCE_GET_PRIVATE (scr, TOTEM_TYPE_SCRSAVER, TotemScrsaverPrivate);
+ scr->priv = G_TYPE_INSTANCE_GET_PRIVATE (scr,
+ TOTEM_TYPE_SCRSAVER,
+ TotemScrsaverPrivate);
screensaver_init_dbus (scr);
#ifdef GDK_WINDOWING_X11
if (screensaver_is_running_dbus (scr) != FALSE)
screensaver_enable_dbus (scr);
- else
+ else
#ifdef GDK_WINDOWING_X11
screensaver_enable_x11 (scr);
#else
{
TotemScrsaver *scr = TOTEM_SCRSAVER (object);
+ g_free (scr->priv->reason);
+
screensaver_finalize_dbus (scr);
#ifdef GDK_WINDOWING_X11
screensaver_finalize_x11 (scr);
{}
#endif
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ G_OBJECT_CLASS (totem_scrsaver_parent_class)->finalize (object);
}