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.h>
36 #include <dbus/dbus-glib.h>
38 #define GS_SERVICE "org.gnome.ScreenSaver"
39 #define GS_PATH "/org/gnome/ScreenSaver"
40 #define GS_INTERFACE "org.gnome.ScreenSaver"
41 #endif /* ENABLE_DBUS */
43 #include "totem-scrsaver.h"
45 #define XSCREENSAVER_MIN_TIMEOUT 60
47 static GObjectClass *parent_class = NULL;
48 static void totem_scrsaver_class_init (TotemScrsaverClass *class);
49 static void totem_scrsaver_init (TotemScrsaver *parser);
50 static void totem_scrsaver_finalize (GObject *object);
53 struct TotemScrsaverPrivate {
54 /* Whether the screensaver is disabled */
58 DBusGConnection *connection;
61 #endif /* ENABLE_DBUS */
63 /* To save the screensaver info */
69 /* For use with XTest */
70 int keycode1, keycode2;
75 G_DEFINE_TYPE(TotemScrsaver, totem_scrsaver, G_TYPE_OBJECT)
78 screensaver_is_running_dbus (TotemScrsaver *scr)
81 if (! scr->priv->connection)
84 if (! scr->priv->gs_proxy)
90 #endif /* ENABLE_DBUS */
94 screensaver_inhibit_dbus (TotemScrsaver *scr,
101 g_return_if_fail (scr != NULL);
102 g_return_if_fail (scr->priv->connection != NULL);
103 g_return_if_fail (scr->priv->gs_proxy != NULL);
111 application = g_strdup ("Evince");
112 reason = g_strdup (_("Running in presentation mode"));
114 res = dbus_g_proxy_call (scr->priv->gs_proxy,
117 G_TYPE_STRING, application,
118 G_TYPE_STRING, reason,
120 G_TYPE_UINT, &cookie,
124 /* save the cookie */
125 scr->priv->cookie = cookie;
127 /* try the old API */
128 res = dbus_g_proxy_call (scr->priv->gs_proxy,
131 G_TYPE_STRING, reason,
137 g_free (application);
140 res = dbus_g_proxy_call (scr->priv->gs_proxy,
143 G_TYPE_UINT, scr->priv->cookie,
147 /* clear the cookie */
148 scr->priv->cookie = 0;
150 /* try the old API */
151 res = dbus_g_proxy_call (scr->priv->gs_proxy,
161 g_warning ("Problem inhibiting the screensaver: %s", error->message);
162 g_error_free (error);
165 #endif /* ENABLE_DBUS */
169 screensaver_enable_dbus (TotemScrsaver *scr)
171 screensaver_inhibit_dbus (scr, FALSE);
175 screensaver_disable_dbus (TotemScrsaver *scr)
177 screensaver_inhibit_dbus (scr, TRUE);
182 gs_proxy_destroy_cb (GObject *proxy,
185 g_warning ("Detected that GNOME screensaver has left the bus");
187 /* just invalidate for now */
188 scr->priv->gs_proxy = NULL;
193 screensaver_init_dbus (TotemScrsaver *scr)
196 GError *error = NULL;
198 scr->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
200 if (! scr->priv->connection) {
202 g_warning ("Failed to connect to the session bus: %s", error->message);
203 g_error_free (error);
208 scr->priv->gs_proxy = dbus_g_proxy_new_for_name_owner (scr->priv->connection,
213 if (scr->priv->gs_proxy != NULL) {
214 g_signal_connect_object (scr->priv->gs_proxy,
216 G_CALLBACK (gs_proxy_destroy_cb),
222 #endif /* ENABLE_DBUS */
226 screensaver_finalize_dbus (TotemScrsaver *scr)
229 if (scr->priv->gs_proxy) {
230 g_object_unref (scr->priv->gs_proxy);
232 #endif /* ENABLE_DBUS */
236 screensaver_enable_x11 (TotemScrsaver *scr)
240 if (scr->priv->have_xtest == True)
242 g_source_remove_by_user_data (scr);
245 #endif /* HAVE_XTEST */
247 XLockDisplay (GDK_DISPLAY());
248 XSetScreenSaver (GDK_DISPLAY(),
251 scr->priv->prefer_blanking,
252 scr->priv->allow_exposures);
253 XUnlockDisplay (GDK_DISPLAY());
258 fake_event (TotemScrsaver *scr)
260 if (scr->priv->disabled)
262 XLockDisplay (GDK_DISPLAY());
263 XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
265 XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
267 XUnlockDisplay (GDK_DISPLAY());
268 /* Swap the keycode */
269 if (scr->priv->keycode == &scr->priv->keycode1)
270 scr->priv->keycode = &scr->priv->keycode2;
272 scr->priv->keycode = &scr->priv->keycode1;
277 #endif /* HAVE_XTEST */
280 screensaver_disable_x11 (TotemScrsaver *scr)
284 if (scr->priv->have_xtest == True)
286 XLockDisplay (GDK_DISPLAY());
287 XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
288 &scr->priv->interval,
289 &scr->priv->prefer_blanking,
290 &scr->priv->allow_exposures);
291 XUnlockDisplay (GDK_DISPLAY());
293 if (scr->priv->timeout != 0)
295 g_timeout_add (scr->priv->timeout / 2 * 1000,
296 (GSourceFunc) fake_event, scr);
298 g_timeout_add (XSCREENSAVER_MIN_TIMEOUT / 2 * 1000,
299 (GSourceFunc) fake_event, scr);
304 #endif /* HAVE_XTEST */
306 XLockDisplay (GDK_DISPLAY());
307 XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
308 &scr->priv->interval,
309 &scr->priv->prefer_blanking,
310 &scr->priv->allow_exposures);
311 XSetScreenSaver(GDK_DISPLAY(), 0, 0,
312 DontPreferBlanking, DontAllowExposures);
313 XUnlockDisplay (GDK_DISPLAY());
317 screensaver_init_x11 (TotemScrsaver *scr)
322 XLockDisplay (GDK_DISPLAY());
323 scr->priv->have_xtest = XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d);
324 if(scr->priv->have_xtest == True)
326 scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
327 if (scr->priv->keycode1 == 0) {
328 g_warning ("scr->priv->keycode1 not existant");
330 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_R);
331 if (scr->priv->keycode2 == 0) {
332 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
333 if (scr->priv->keycode2 == 0) {
334 g_warning ("scr->priv->keycode2 not existant");
337 scr->priv->keycode = &scr->priv->keycode1;
339 XUnlockDisplay (GDK_DISPLAY());
340 #endif /* HAVE_XTEST */
344 screensaver_finalize_x11 (TotemScrsaver *scr)
346 g_source_remove_by_user_data (scr);
350 totem_scrsaver_class_init (TotemScrsaverClass *klass)
352 GObjectClass *object_class = G_OBJECT_CLASS (klass);
354 parent_class = g_type_class_peek_parent (klass);
356 object_class->finalize = totem_scrsaver_finalize;
360 totem_scrsaver_new (void)
362 return TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
366 totem_scrsaver_init (TotemScrsaver *scr)
368 scr->priv = g_new0 (TotemScrsaverPrivate, 1);
370 screensaver_init_dbus (scr);
371 screensaver_init_x11 (scr);
375 totem_scrsaver_disable (TotemScrsaver *scr)
377 if (scr->priv->disabled != FALSE)
380 scr->priv->disabled = TRUE;
382 if (screensaver_is_running_dbus (scr) != FALSE)
383 screensaver_disable_dbus (scr);
385 screensaver_disable_x11 (scr);
389 totem_scrsaver_enable (TotemScrsaver *scr)
391 if (scr->priv->disabled == FALSE)
394 scr->priv->disabled = FALSE;
396 if (screensaver_is_running_dbus (scr) != FALSE)
397 screensaver_enable_dbus (scr);
399 screensaver_enable_x11 (scr);
403 totem_scrsaver_finalize (GObject *object)
405 TotemScrsaver *scr = TOTEM_SCRSAVER (object);
407 screensaver_finalize_dbus (scr);
408 screensaver_finalize_x11 (scr);
412 if (G_OBJECT_CLASS (parent_class)->finalize != NULL) {
413 (* G_OBJECT_CLASS (parent_class)->finalize) (object);