1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 Copyright (C) 2004-2006 Bastien Nocera <hadess@hadess.net>
4 Copyright © 2010 Christian Persch
5 Copyright © 2010 Carlos Garcia Campos
7 The Gnome Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 The Gnome Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with the Gnome Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301 USA.
22 Authors: Bastien Nocera <hadess@hadess.net>
29 #include <glib/gi18n.h>
33 #ifdef GDK_WINDOWING_X11
35 #include <X11/keysym.h>
38 #include <X11/extensions/XTest.h>
39 #endif /* HAVE_XTEST */
40 #endif /* GDK_WINDOWING_X11 */
42 #include "totem-scrsaver.h"
44 #define GS_SERVICE "org.gnome.SessionManager"
45 #define GS_PATH "/org/gnome/SessionManager"
46 #define GS_INTERFACE "org.gnome.SessionManager"
47 /* From org.gnome.SessionManager.xml */
48 #define GS_NO_IDLE_FLAG 8
50 #define XSCREENSAVER_MIN_TIMEOUT 60
58 static void totem_scrsaver_finalize (GObject *object);
60 struct TotemScrsaverPrivate {
61 /* Whether the screensaver is disabled */
63 /* The reason for the inhibition */
67 gboolean have_session_dbus;
71 /* To save the screensaver info */
77 /* For use with XTest */
78 int keycode1, keycode2;
83 G_DEFINE_TYPE(TotemScrsaver, totem_scrsaver, G_TYPE_OBJECT)
86 screensaver_is_running_dbus (TotemScrsaver *scr)
88 return scr->priv->have_session_dbus;
92 on_inhibit_cb (GObject *source_object,
96 GDBusProxy *proxy = G_DBUS_PROXY (source_object);
97 TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
101 value = g_dbus_proxy_call_finish (proxy, res, &error);
103 g_warning ("Problem inhibiting the screensaver: %s", error->message);
104 g_object_unref (scr);
105 g_error_free (error);
110 /* save the cookie */
111 if (g_variant_is_of_type (value, G_VARIANT_TYPE ("(u)")))
112 g_variant_get (value, "(u)", &scr->priv->cookie);
114 scr->priv->cookie = 0;
115 g_variant_unref (value);
117 g_object_unref (scr);
121 on_uninhibit_cb (GObject *source_object,
125 GDBusProxy *proxy = G_DBUS_PROXY (source_object);
126 TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
128 GError *error = NULL;
130 value = g_dbus_proxy_call_finish (proxy, res, &error);
132 g_warning ("Problem uninhibiting the screensaver: %s", error->message);
133 g_object_unref (scr);
134 g_error_free (error);
139 /* clear the cookie */
140 scr->priv->cookie = 0;
141 g_variant_unref (value);
143 g_object_unref (scr);
147 screensaver_inhibit_dbus (TotemScrsaver *scr,
150 TotemScrsaverPrivate *priv = scr->priv;
153 if (!priv->have_session_dbus)
161 g_return_if_fail (scr->priv->reason != NULL);
164 if (scr->priv->window != NULL) {
165 window = gtk_widget_get_window (GTK_WIDGET (scr->priv->window));
167 xid = gdk_x11_window_get_xid (window);
171 g_dbus_proxy_call (priv->gs_proxy,
173 g_variant_new ("(susu)",
174 g_get_application_name (),
178 G_DBUS_CALL_FLAGS_NO_AUTO_START,
184 if (priv->cookie > 0) {
185 g_dbus_proxy_call (priv->gs_proxy,
187 g_variant_new ("(u)", priv->cookie),
188 G_DBUS_CALL_FLAGS_NO_AUTO_START,
198 screensaver_enable_dbus (TotemScrsaver *scr)
200 screensaver_inhibit_dbus (scr, FALSE);
204 screensaver_disable_dbus (TotemScrsaver *scr)
206 screensaver_inhibit_dbus (scr, TRUE);
210 screensaver_dbus_proxy_new_cb (GObject *source,
211 GAsyncResult *result,
214 TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
215 TotemScrsaverPrivate *priv = scr->priv;
217 priv->gs_proxy = g_dbus_proxy_new_for_bus_finish (result, NULL);
221 priv->have_session_dbus = TRUE;
222 if (priv->reason != NULL && scr->priv->disabled)
223 screensaver_disable_dbus (scr);
227 screensaver_init_dbus (TotemScrsaver *scr)
229 g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
230 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
236 screensaver_dbus_proxy_new_cb,
241 screensaver_finalize_dbus (TotemScrsaver *scr)
243 if (scr->priv->gs_proxy) {
244 g_object_unref (scr->priv->gs_proxy);
248 #ifdef GDK_WINDOWING_X11
250 screensaver_enable_x11 (TotemScrsaver *scr)
254 if (scr->priv->have_xtest != FALSE)
256 g_source_remove_by_user_data (scr);
259 #endif /* HAVE_XTEST */
261 XLockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
262 XSetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
265 scr->priv->prefer_blanking,
266 scr->priv->allow_exposures);
267 XUnlockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
272 fake_event (TotemScrsaver *scr)
274 if (scr->priv->disabled)
276 XLockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
277 XTestFakeKeyEvent (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), *scr->priv->keycode,
279 XTestFakeKeyEvent (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), *scr->priv->keycode,
281 XUnlockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
282 /* Swap the keycode */
283 if (scr->priv->keycode == &scr->priv->keycode1)
284 scr->priv->keycode = &scr->priv->keycode2;
286 scr->priv->keycode = &scr->priv->keycode1;
291 #endif /* HAVE_XTEST */
294 screensaver_disable_x11 (TotemScrsaver *scr)
298 if (scr->priv->have_xtest != FALSE)
300 XLockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
301 XGetScreenSaver(GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &scr->priv->timeout,
302 &scr->priv->interval,
303 &scr->priv->prefer_blanking,
304 &scr->priv->allow_exposures);
305 XUnlockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
307 if (scr->priv->timeout != 0) {
308 g_timeout_add_seconds (scr->priv->timeout / 2,
309 (GSourceFunc) fake_event, scr);
311 g_timeout_add_seconds (XSCREENSAVER_MIN_TIMEOUT / 2,
312 (GSourceFunc) fake_event, scr);
317 #endif /* HAVE_XTEST */
319 XLockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
320 XGetScreenSaver(GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &scr->priv->timeout,
321 &scr->priv->interval,
322 &scr->priv->prefer_blanking,
323 &scr->priv->allow_exposures);
324 XSetScreenSaver(GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, 0,
325 DontPreferBlanking, DontAllowExposures);
326 XUnlockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
330 screensaver_init_x11 (TotemScrsaver *scr)
335 XLockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
336 scr->priv->have_xtest = (XTestQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &a, &b, &c, &d) == True);
337 if (scr->priv->have_xtest != FALSE)
339 scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XK_Alt_L);
340 if (scr->priv->keycode1 == 0) {
341 g_warning ("scr->priv->keycode1 not existant");
343 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XK_Alt_R);
344 if (scr->priv->keycode2 == 0) {
345 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XK_Alt_L);
346 if (scr->priv->keycode2 == 0) {
347 g_warning ("scr->priv->keycode2 not existant");
350 scr->priv->keycode = &scr->priv->keycode1;
352 XUnlockDisplay (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
353 #endif /* HAVE_XTEST */
357 screensaver_finalize_x11 (TotemScrsaver *scr)
359 g_source_remove_by_user_data (scr);
364 totem_scrsaver_get_property (GObject *object,
371 scr = TOTEM_SCRSAVER (object);
376 g_value_set_string (value, scr->priv->reason);
379 g_value_set_object (value, scr->priv->window);
382 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
387 totem_scrsaver_set_property (GObject *object,
394 scr = TOTEM_SCRSAVER (object);
399 g_free (scr->priv->reason);
400 scr->priv->reason = g_value_dup_string (value);
403 if (scr->priv->window)
404 g_object_unref (scr->priv->window);
405 scr->priv->window = g_value_dup_object (value);
408 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
413 totem_scrsaver_class_init (TotemScrsaverClass *klass)
415 GObjectClass *object_class = G_OBJECT_CLASS (klass);
417 g_type_class_add_private (klass, sizeof (TotemScrsaverPrivate));
419 object_class->set_property = totem_scrsaver_set_property;
420 object_class->get_property = totem_scrsaver_get_property;
421 object_class->finalize = totem_scrsaver_finalize;
423 g_object_class_install_property (object_class, PROP_REASON,
424 g_param_spec_string ("reason", NULL, NULL,
425 NULL, G_PARAM_READWRITE));
426 g_object_class_install_property (object_class, PROP_WINDOW,
427 g_param_spec_object ("window", NULL, NULL,
428 GTK_TYPE_WINDOW, G_PARAM_READWRITE));
432 * totem_scrsaver_new:
434 * Creates a #TotemScrsaver object.
435 * If the GNOME screen saver is running, it uses its DBUS interface to
436 * inhibit the screensaver; otherwise it falls back to using the X
437 * screensaver functionality for this.
439 * Returns: a newly created #TotemScrsaver
442 totem_scrsaver_new (void)
444 return TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
448 totem_scrsaver_init (TotemScrsaver *scr)
450 scr->priv = G_TYPE_INSTANCE_GET_PRIVATE (scr,
452 TotemScrsaverPrivate);
454 screensaver_init_dbus (scr);
455 #ifdef GDK_WINDOWING_X11
456 screensaver_init_x11 (scr);
458 #warning Unimplemented
463 totem_scrsaver_disable (TotemScrsaver *scr)
465 g_return_if_fail (TOTEM_IS_SCRSAVER (scr));
467 if (scr->priv->disabled != FALSE)
470 scr->priv->disabled = TRUE;
472 if (screensaver_is_running_dbus (scr) != FALSE)
473 screensaver_disable_dbus (scr);
475 #ifdef GDK_WINDOWING_X11
476 screensaver_disable_x11 (scr);
478 #warning Unimplemented
484 totem_scrsaver_enable (TotemScrsaver *scr)
486 g_return_if_fail (TOTEM_IS_SCRSAVER (scr));
488 if (scr->priv->disabled == FALSE)
491 scr->priv->disabled = FALSE;
493 if (screensaver_is_running_dbus (scr) != FALSE)
494 screensaver_enable_dbus (scr);
496 #ifdef GDK_WINDOWING_X11
497 screensaver_enable_x11 (scr);
499 #warning Unimplemented
505 totem_scrsaver_set_state (TotemScrsaver *scr, gboolean enable)
507 g_return_if_fail (TOTEM_IS_SCRSAVER (scr));
509 if (scr->priv->disabled == !enable)
513 totem_scrsaver_disable (scr);
515 totem_scrsaver_enable (scr);
519 totem_scrsaver_finalize (GObject *object)
521 TotemScrsaver *scr = TOTEM_SCRSAVER (object);
523 g_free (scr->priv->reason);
524 if (scr->priv->window != NULL)
525 g_object_unref (scr->priv->window);
527 screensaver_finalize_dbus (scr);
528 #ifdef GDK_WINDOWING_X11
529 screensaver_finalize_x11 (scr);
531 #warning Unimplemented
535 G_OBJECT_CLASS (totem_scrsaver_parent_class)->finalize (object);