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 #ifdef GDK_WINDOWING_X11
32 #include <X11/keysym.h>
35 #include <X11/extensions/XTest.h>
36 #endif /* HAVE_XTEST */
37 #endif /* GDK_WINDOWING_X11 */
40 #include <dbus/dbus.h>
41 #include <dbus/dbus-glib.h>
43 #define GS_SERVICE "org.gnome.ScreenSaver"
44 #define GS_PATH "/org/gnome/ScreenSaver"
45 #define GS_INTERFACE "org.gnome.ScreenSaver"
46 #endif /* ENABLE_DBUS */
48 #include "totem-scrsaver.h"
50 #define XSCREENSAVER_MIN_TIMEOUT 60
52 static GObjectClass *parent_class = NULL;
53 static void totem_scrsaver_class_init (TotemScrsaverClass *class);
54 static void totem_scrsaver_init (TotemScrsaver *parser);
55 static void totem_scrsaver_finalize (GObject *object);
58 struct TotemScrsaverPrivate {
59 /* Whether the screensaver is disabled */
63 DBusGConnection *connection;
66 #endif /* ENABLE_DBUS */
68 /* To save the screensaver info */
74 /* For use with XTest */
75 int keycode1, keycode2;
80 G_DEFINE_TYPE(TotemScrsaver, totem_scrsaver, G_TYPE_OBJECT)
83 screensaver_is_running_dbus (TotemScrsaver *scr)
86 if (! scr->priv->connection)
89 if (! scr->priv->gs_proxy)
95 #endif /* ENABLE_DBUS */
99 screensaver_inhibit_dbus (TotemScrsaver *scr,
106 g_return_if_fail (scr != NULL);
107 g_return_if_fail (scr->priv->connection != NULL);
108 g_return_if_fail (scr->priv->gs_proxy != NULL);
116 application = g_strdup ("Evince");
117 reason = g_strdup (_("Running in presentation mode"));
119 res = dbus_g_proxy_call (scr->priv->gs_proxy,
122 G_TYPE_STRING, application,
123 G_TYPE_STRING, reason,
125 G_TYPE_UINT, &cookie,
129 /* save the cookie */
130 scr->priv->cookie = cookie;
132 /* try the old API */
133 res = dbus_g_proxy_call (scr->priv->gs_proxy,
136 G_TYPE_STRING, reason,
142 g_free (application);
145 res = dbus_g_proxy_call (scr->priv->gs_proxy,
148 G_TYPE_UINT, scr->priv->cookie,
152 /* clear the cookie */
153 scr->priv->cookie = 0;
155 /* try the old API */
156 res = dbus_g_proxy_call (scr->priv->gs_proxy,
166 g_warning ("Problem inhibiting the screensaver: %s", error->message);
167 g_error_free (error);
170 #endif /* ENABLE_DBUS */
174 screensaver_enable_dbus (TotemScrsaver *scr)
176 screensaver_inhibit_dbus (scr, FALSE);
180 screensaver_disable_dbus (TotemScrsaver *scr)
182 screensaver_inhibit_dbus (scr, TRUE);
187 gs_proxy_destroy_cb (GObject *proxy,
190 g_warning ("Detected that GNOME screensaver has left the bus");
192 /* just invalidate for now */
193 scr->priv->gs_proxy = NULL;
199 screensaver_init_dbus (TotemScrsaver *scr, DBusGConnection *connection)
201 GError *error = NULL;
204 scr->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
206 scr->priv->connection = connection;
208 if (! scr->priv->connection) {
210 g_warning ("Failed to connect to the session bus: %s", error->message);
211 g_error_free (error);
216 scr->priv->gs_proxy = dbus_g_proxy_new_for_name_owner (scr->priv->connection,
221 if (scr->priv->gs_proxy != NULL) {
222 g_signal_connect_object (scr->priv->gs_proxy,
224 G_CALLBACK (gs_proxy_destroy_cb),
231 #endif /* ENABLE_DBUS */
234 screensaver_finalize_dbus (TotemScrsaver *scr)
237 if (scr->priv->gs_proxy) {
238 g_object_unref (scr->priv->gs_proxy);
240 #endif /* ENABLE_DBUS */
243 #ifdef GDK_WINDOWING_X11
245 screensaver_enable_x11 (TotemScrsaver *scr)
249 if (scr->priv->have_xtest != FALSE)
251 g_source_remove_by_user_data (scr);
254 #endif /* HAVE_XTEST */
256 XLockDisplay (GDK_DISPLAY());
257 XSetScreenSaver (GDK_DISPLAY(),
260 scr->priv->prefer_blanking,
261 scr->priv->allow_exposures);
262 XUnlockDisplay (GDK_DISPLAY());
267 fake_event (TotemScrsaver *scr)
269 if (scr->priv->disabled)
271 XLockDisplay (GDK_DISPLAY());
272 XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
274 XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
276 XUnlockDisplay (GDK_DISPLAY());
277 /* Swap the keycode */
278 if (scr->priv->keycode == &scr->priv->keycode1)
279 scr->priv->keycode = &scr->priv->keycode2;
281 scr->priv->keycode = &scr->priv->keycode1;
286 #endif /* HAVE_XTEST */
289 screensaver_disable_x11 (TotemScrsaver *scr)
293 if (scr->priv->have_xtest != FALSE)
295 XLockDisplay (GDK_DISPLAY());
296 XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
297 &scr->priv->interval,
298 &scr->priv->prefer_blanking,
299 &scr->priv->allow_exposures);
300 XUnlockDisplay (GDK_DISPLAY());
302 if (scr->priv->timeout != 0)
304 g_timeout_add_seconds (scr->priv->timeout / 2,
305 (GSourceFunc) fake_event, scr);
307 g_timeout_add_seconds (XSCREENSAVER_MIN_TIMEOUT / 2,
308 (GSourceFunc) fake_event, scr);
313 #endif /* HAVE_XTEST */
315 XLockDisplay (GDK_DISPLAY());
316 XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
317 &scr->priv->interval,
318 &scr->priv->prefer_blanking,
319 &scr->priv->allow_exposures);
320 XSetScreenSaver(GDK_DISPLAY(), 0, 0,
321 DontPreferBlanking, DontAllowExposures);
322 XUnlockDisplay (GDK_DISPLAY());
326 screensaver_init_x11 (TotemScrsaver *scr)
331 XLockDisplay (GDK_DISPLAY());
332 scr->priv->have_xtest = (XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d) == True);
333 if (scr->priv->have_xtest != FALSE)
335 scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
336 if (scr->priv->keycode1 == 0) {
337 g_warning ("scr->priv->keycode1 not existant");
339 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_R);
340 if (scr->priv->keycode2 == 0) {
341 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
342 if (scr->priv->keycode2 == 0) {
343 g_warning ("scr->priv->keycode2 not existant");
346 scr->priv->keycode = &scr->priv->keycode1;
348 XUnlockDisplay (GDK_DISPLAY());
349 #endif /* HAVE_XTEST */
353 screensaver_finalize_x11 (TotemScrsaver *scr)
355 g_source_remove_by_user_data (scr);
360 totem_scrsaver_class_init (TotemScrsaverClass *klass)
362 GObjectClass *object_class = G_OBJECT_CLASS (klass);
364 parent_class = g_type_class_peek_parent (klass);
366 object_class->finalize = totem_scrsaver_finalize;
371 totem_scrsaver_new (DBusGConnection *connection)
374 scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
376 screensaver_init_dbus (scr, connection);
377 #ifdef GDK_WINDOWING_X11
378 screensaver_init_x11 (scr);
380 #warning Unimplemented
390 scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
392 #ifdef GDK_WINDOWING_X11
393 screensaver_init_x11 (scr);
395 #warning Unimplemented
403 totem_scrsaver_init (TotemScrsaver *scr)
405 scr->priv = g_new0 (TotemScrsaverPrivate, 1);
411 totem_scrsaver_disable (TotemScrsaver *scr)
413 g_return_if_fail (TOTEM_SCRSAVER (scr));
415 if (scr->priv->disabled != FALSE)
418 scr->priv->disabled = TRUE;
420 if (screensaver_is_running_dbus (scr) != FALSE)
421 screensaver_disable_dbus (scr);
423 #ifdef GDK_WINDOWING_X11
424 screensaver_disable_x11 (scr);
426 #warning Unimplemented
432 totem_scrsaver_enable (TotemScrsaver *scr)
434 g_return_if_fail (TOTEM_SCRSAVER (scr));
436 if (scr->priv->disabled == FALSE)
439 scr->priv->disabled = FALSE;
441 if (screensaver_is_running_dbus (scr) != FALSE)
442 screensaver_enable_dbus (scr);
444 #ifdef GDK_WINDOWING_X11
445 screensaver_enable_x11 (scr);
447 #warning Unimplemented
453 totem_scrsaver_finalize (GObject *object)
455 TotemScrsaver *scr = TOTEM_SCRSAVER (object);
457 screensaver_finalize_dbus (scr);
458 #ifdef GDK_WINDOWING_X11
459 screensaver_finalize_x11 (scr);
461 #warning Unimplemented
467 if (G_OBJECT_CLASS (parent_class)->finalize != NULL) {
468 (* G_OBJECT_CLASS (parent_class)->finalize) (object);