1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 Copyright (C) 2004-2006 Bastien Nocera <hadess@hadess.net>
5 The Gnome Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The Gnome Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the Gnome Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
20 Author: Bastien Nocera <hadess@hadess.net>
26 #include <glib/gi18n.h>
30 #include <X11/extensions/XTest.h>
31 #endif /* HAVE_XTEST */
32 #include <X11/keysym.h>
35 #include <dbus/dbus-glib.h>
37 #define GS_SERVICE "org.gnome.ScreenSaver"
38 #define GS_PATH "/org/gnome/ScreenSaver"
39 #define GS_INTERFACE "org.gnome.ScreenSaver"
40 #endif /* ENABLE_DBUS */
42 #include "totem-scrsaver.h"
44 #define XSCREENSAVER_MIN_TIMEOUT 60
46 static GObjectClass *parent_class = NULL;
47 static void totem_scrsaver_class_init (TotemScrsaverClass *class);
48 static void totem_scrsaver_init (TotemScrsaver *parser);
49 static void totem_scrsaver_finalize (GObject *object);
52 struct TotemScrsaverPrivate {
53 /* Whether the screensaver is disabled */
57 DBusGConnection *connection;
60 #endif /* ENABLE_DBUS */
62 /* To save the screensaver info */
68 /* For use with XTest */
69 int keycode1, keycode2;
74 G_DEFINE_TYPE(TotemScrsaver, totem_scrsaver, G_TYPE_OBJECT)
77 screensaver_is_running_dbus (TotemScrsaver *scr)
80 if (! scr->priv->connection)
83 if (! scr->priv->gs_proxy)
89 #endif /* ENABLE_DBUS */
93 screensaver_inhibit_dbus (TotemScrsaver *scr,
100 g_return_if_fail (scr != NULL);
101 g_return_if_fail (scr->priv->connection != NULL);
102 g_return_if_fail (scr->priv->gs_proxy != NULL);
110 application = g_strdup ("Evince");
111 reason = g_strdup (_("Running in presentation mode"));
113 res = dbus_g_proxy_call (scr->priv->gs_proxy,
116 G_TYPE_STRING, application,
117 G_TYPE_STRING, reason,
119 G_TYPE_UINT, &cookie,
123 /* save the cookie */
124 scr->priv->cookie = cookie;
126 /* try the old API */
127 res = dbus_g_proxy_call (scr->priv->gs_proxy,
130 G_TYPE_STRING, reason,
136 g_free (application);
139 res = dbus_g_proxy_call (scr->priv->gs_proxy,
142 G_TYPE_UINT, scr->priv->cookie,
146 /* clear the cookie */
147 scr->priv->cookie = 0;
149 /* try the old API */
150 res = dbus_g_proxy_call (scr->priv->gs_proxy,
160 g_warning ("Problem inhibiting the screensaver: %s", error->message);
161 g_error_free (error);
164 #endif /* ENABLE_DBUS */
168 screensaver_enable_dbus (TotemScrsaver *scr)
170 screensaver_inhibit_dbus (scr, FALSE);
174 screensaver_disable_dbus (TotemScrsaver *scr)
176 screensaver_inhibit_dbus (scr, TRUE);
181 gs_proxy_destroy_cb (GObject *proxy,
184 g_warning ("Detected that GNOME screensaver has left the bus");
186 /* just invalidate for now */
187 scr->priv->gs_proxy = NULL;
193 screensaver_init_dbus (TotemScrsaver *scr, DBusGConnection *connection)
195 GError *error = NULL;
198 scr->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
200 scr->priv->connection = connection;
202 if (! scr->priv->connection) {
204 g_warning ("Failed to connect to the session bus: %s", error->message);
205 g_error_free (error);
210 scr->priv->gs_proxy = dbus_g_proxy_new_for_name_owner (scr->priv->connection,
215 if (scr->priv->gs_proxy != NULL) {
216 g_signal_connect_object (scr->priv->gs_proxy,
218 G_CALLBACK (gs_proxy_destroy_cb),
225 #endif /* ENABLE_DBUS */
228 screensaver_finalize_dbus (TotemScrsaver *scr)
231 if (scr->priv->gs_proxy) {
232 g_object_unref (scr->priv->gs_proxy);
234 #endif /* ENABLE_DBUS */
238 screensaver_enable_x11 (TotemScrsaver *scr)
242 if (scr->priv->have_xtest == True)
244 g_source_remove_by_user_data (scr);
247 #endif /* HAVE_XTEST */
249 XLockDisplay (GDK_DISPLAY());
250 XSetScreenSaver (GDK_DISPLAY(),
253 scr->priv->prefer_blanking,
254 scr->priv->allow_exposures);
255 XUnlockDisplay (GDK_DISPLAY());
260 fake_event (TotemScrsaver *scr)
262 if (scr->priv->disabled)
264 XLockDisplay (GDK_DISPLAY());
265 XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
267 XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
269 XUnlockDisplay (GDK_DISPLAY());
270 /* Swap the keycode */
271 if (scr->priv->keycode == &scr->priv->keycode1)
272 scr->priv->keycode = &scr->priv->keycode2;
274 scr->priv->keycode = &scr->priv->keycode1;
279 #endif /* HAVE_XTEST */
282 screensaver_disable_x11 (TotemScrsaver *scr)
286 if (scr->priv->have_xtest == True)
288 XLockDisplay (GDK_DISPLAY());
289 XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
290 &scr->priv->interval,
291 &scr->priv->prefer_blanking,
292 &scr->priv->allow_exposures);
293 XUnlockDisplay (GDK_DISPLAY());
295 if (scr->priv->timeout != 0)
297 #if GLIB_CHECK_VERSION (2, 13, 0)
298 g_timeout_add_seconds (scr->priv->timeout / 2,
299 (GSourceFunc) fake_event, scr);
301 g_timeout_add (scr->priv->timeout / 2 * 1000,
302 (GSourceFunc) fake_event, scr);
305 #if GLIB_CHECK_VERSION (2, 13, 0)
306 g_timeout_add_seconds (XSCREENSAVER_MIN_TIMEOUT / 2,
307 (GSourceFunc) fake_event, scr);
309 g_timeout_add (XSCREENSAVER_MIN_TIMEOUT / 2 * 1000,
310 (GSourceFunc) fake_event, scr);
316 #endif /* HAVE_XTEST */
318 XLockDisplay (GDK_DISPLAY());
319 XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
320 &scr->priv->interval,
321 &scr->priv->prefer_blanking,
322 &scr->priv->allow_exposures);
323 XSetScreenSaver(GDK_DISPLAY(), 0, 0,
324 DontPreferBlanking, DontAllowExposures);
325 XUnlockDisplay (GDK_DISPLAY());
329 screensaver_init_x11 (TotemScrsaver *scr)
334 XLockDisplay (GDK_DISPLAY());
335 scr->priv->have_xtest = XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d);
336 if(scr->priv->have_xtest == True)
338 scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
339 if (scr->priv->keycode1 == 0) {
340 g_warning ("scr->priv->keycode1 not existant");
342 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_R);
343 if (scr->priv->keycode2 == 0) {
344 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
345 if (scr->priv->keycode2 == 0) {
346 g_warning ("scr->priv->keycode2 not existant");
349 scr->priv->keycode = &scr->priv->keycode1;
351 XUnlockDisplay (GDK_DISPLAY());
352 #endif /* HAVE_XTEST */
356 screensaver_finalize_x11 (TotemScrsaver *scr)
358 g_source_remove_by_user_data (scr);
362 totem_scrsaver_class_init (TotemScrsaverClass *klass)
364 GObjectClass *object_class = G_OBJECT_CLASS (klass);
366 parent_class = g_type_class_peek_parent (klass);
368 object_class->finalize = totem_scrsaver_finalize;
373 totem_scrsaver_new (DBusGConnection *connection)
376 scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
378 screensaver_init_dbus (scr, connection);
379 screensaver_init_x11 (scr);
388 scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
390 screensaver_init_x11 (scr);
397 totem_scrsaver_init (TotemScrsaver *scr)
399 scr->priv = g_new0 (TotemScrsaverPrivate, 1);
403 totem_scrsaver_disable (TotemScrsaver *scr)
405 if (scr->priv->disabled != FALSE)
408 scr->priv->disabled = TRUE;
410 if (screensaver_is_running_dbus (scr) != FALSE)
411 screensaver_disable_dbus (scr);
413 screensaver_disable_x11 (scr);
417 totem_scrsaver_enable (TotemScrsaver *scr)
419 if (scr->priv->disabled == FALSE)
422 scr->priv->disabled = FALSE;
424 if (screensaver_is_running_dbus (scr) != FALSE)
425 screensaver_enable_dbus (scr);
427 screensaver_enable_x11 (scr);
431 totem_scrsaver_finalize (GObject *object)
433 TotemScrsaver *scr = TOTEM_SCRSAVER (object);
435 screensaver_finalize_dbus (scr);
436 screensaver_finalize_x11 (scr);
440 if (G_OBJECT_CLASS (parent_class)->finalize != NULL) {
441 (* G_OBJECT_CLASS (parent_class)->finalize) (object);