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;
+ GDBusConnection *connection;
+ gboolean have_screensaver_dbus;
+ guint watch_id;
guint32 cookie;
-#endif /* ENABLE_DBUS */
/* To save the screensaver info */
int timeout;
/* For use with XTest */
int keycode1, keycode2;
int *keycode;
- Bool have_xtest;
+ gboolean have_xtest;
+};
+
+enum {
+ PROP_0,
+ PROP_CONNECTION
};
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_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)) {
+ /* 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 */
- 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_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)) {
+ /* 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 */
- 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
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 char *name,
+ const char *name_owner,
+ 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;
+ g_assert (connection == priv->connection);
+
+ 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 char *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;
-
- if (! scr->priv->connection) {
- if (error) {
- g_warning ("Failed to connect to the session bus: %s", error->message);
- g_error_free (error);
- }
- 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);
+ TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
+ TotemScrsaverPrivate *priv = scr->priv;
- }
+ g_assert (connection == priv->connection);
+ priv->have_screensaver_dbus = FALSE;
}
-#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 */
+ TotemScrsaverPrivate *priv = scr->priv;
+
+ if (priv->connection == NULL)
+ return;
+
+ g_bus_unwatch_name (priv->watch_id);
+
+ g_object_unref (priv->connection);
}
+#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;
{
#ifdef HAVE_XTEST
- if (scr->priv->have_xtest == True)
+ if (scr->priv->have_xtest != FALSE)
{
XLockDisplay (GDK_DISPLAY());
XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
&scr->priv->allow_exposures);
XUnlockDisplay (GDK_DISPLAY());
- if (scr->priv->timeout != 0)
- {
+ if (scr->priv->timeout != 0) {
g_timeout_add_seconds (scr->priv->timeout / 2,
(GSourceFunc) fake_event, scr);
} else {
g_timeout_add_seconds (XSCREENSAVER_MIN_TIMEOUT / 2,
- (GSourceFunc) fake_event, scr);
+ (GSourceFunc) fake_event, scr);
}
return;
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) {
{
g_source_remove_by_user_data (scr);
}
+#endif
static void
-totem_scrsaver_class_init (TotemScrsaverClass *klass)
+totem_scrsaver_constructed (GObject *object)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
+ TotemScrsaver *scr = TOTEM_SCRSAVER (object);
+ TotemScrsaverPrivate *priv = scr->priv;
+
+ if (priv->connection == NULL)
+ return;
+
+ 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);
+}
- object_class->finalize = totem_scrsaver_finalize;
+static void
+totem_scrsaver_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TotemScrsaver *scr = TOTEM_SCRSAVER (object);
+ TotemScrsaverPrivate *priv = scr->priv;
+
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ priv->connection = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
-#ifdef ENABLE_DBUS
-TotemScrsaver *
-totem_scrsaver_new (DBusGConnection *connection)
+static void
+totem_scrsaver_class_init (TotemScrsaverClass *klass)
{
- TotemScrsaver * scr;
- scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- screensaver_init_dbus (scr, connection);
- screensaver_init_x11 (scr);
-
- return scr;
+ object_class->set_property = totem_scrsaver_set_property;
+ object_class->constructed = totem_scrsaver_constructed;
+ object_class->finalize = totem_scrsaver_finalize;
+
+ 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));
}
-#else
+
+/**
+ * totem_scrsaver_new:
+ * @connection: (allow-none): a #GDBusConnection, or %NULL
+ *
+ * Creates a #TotemScrsaver object. If @connection is non-%NULL,
+ * and 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 (GDBusConnection *connection)
{
- TotemScrsaver * scr;
- scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
-
- screensaver_init_x11 (scr);
-
- return scr;
+ return g_object_new (TOTEM_TYPE_SCRSAVER,
+ "connection", connection,
+ 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);
+
+#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;
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;
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
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);
}
-