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., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301 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 #define GS_SERVICE "org.gnome.ScreenSaver"
41 #define GS_PATH "/org/gnome/ScreenSaver"
42 #define GS_INTERFACE "org.gnome.ScreenSaver"
43 #endif /* ENABLE_DBUS */
45 #include "totem-scrsaver.h"
47 #define XSCREENSAVER_MIN_TIMEOUT 60
49 static GObjectClass *parent_class = NULL;
50 static void totem_scrsaver_finalize (GObject *object);
52 struct TotemScrsaverPrivate {
53 /* Whether the screensaver is disabled */
57 GDBusConnection *connection;
58 gboolean have_screensaver_dbus;
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 return scr->priv->connection != NULL;
84 #endif /* ENABLE_DBUS */
88 screensaver_inhibit_dbus (TotemScrsaver *scr,
92 TotemScrsaverPrivate *priv = scr->priv;
96 if (!priv->have_screensaver_dbus)
100 value = g_dbus_connection_call_sync (priv->connection,
105 g_variant_new ("(ss)",
107 _("Running in presentation mode")),
108 G_DBUS_CALL_FLAGS_NO_AUTO_START,
112 if (error && g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) {
113 /* try the old API */
114 g_clear_error (&error);
115 value = g_dbus_connection_call_sync (priv->connection,
120 g_variant_new ("(s)",
121 _("Running in presentation mode")),
122 G_DBUS_CALL_FLAGS_NO_AUTO_START,
128 /* save the cookie */
129 if (g_variant_is_of_type (value, G_VARIANT_TYPE ("(u)")))
130 g_variant_get (value, "(u)", &priv->cookie);
133 g_variant_unref (value);
135 g_warning ("Problem inhibiting the screensaver: %s", error->message);
136 g_error_free (error);
140 value = g_dbus_connection_call_sync (priv->connection,
145 g_variant_new ("(u)", priv->cookie),
146 G_DBUS_CALL_FLAGS_NO_AUTO_START,
150 if (error && g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) {
151 /* try the old API */
152 g_clear_error (&error);
153 value = g_dbus_connection_call_sync (priv->connection,
158 g_variant_new ("()"),
159 G_DBUS_CALL_FLAGS_NO_AUTO_START,
165 /* clear the cookie */
167 g_variant_unref (value);
169 g_warning ("Problem uninhibiting the screensaver: %s", error->message);
170 g_error_free (error);
173 #endif /* ENABLE_DBUS */
177 screensaver_enable_dbus (TotemScrsaver *scr)
179 screensaver_inhibit_dbus (scr, FALSE);
183 screensaver_disable_dbus (TotemScrsaver *scr)
185 screensaver_inhibit_dbus (scr, TRUE);
190 screensaver_dbus_appeared_cb (GDBusConnection *connection,
192 const char *name_owner,
195 TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
196 TotemScrsaverPrivate *priv = scr->priv;
198 g_assert (connection == priv->connection);
200 priv->have_screensaver_dbus = TRUE;
204 screensaver_dbus_disappeared_cb (GDBusConnection *connection,
208 TotemScrsaver *scr = TOTEM_SCRSAVER (user_data);
209 TotemScrsaverPrivate *priv = scr->priv;
211 g_assert (connection == priv->connection);
213 priv->have_screensaver_dbus = FALSE;
218 screensaver_init_dbus (TotemScrsaver *scr)
221 TotemScrsaverPrivate *priv = scr->priv;
223 priv->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
225 G_BUS_NAME_WATCHER_FLAGS_NONE,
226 screensaver_dbus_appeared_cb,
227 screensaver_dbus_disappeared_cb,
229 #endif /* ENABLE_DBUS */
233 screensaver_finalize_dbus (TotemScrsaver *scr)
236 g_bus_unwatch_name (scr->priv->watch_id);
238 if (scr->priv->connection != NULL)
239 g_object_unref (scr->priv->connection);
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) {
303 g_timeout_add_seconds (scr->priv->timeout / 2,
304 (GSourceFunc) fake_event, scr);
306 g_timeout_add_seconds (XSCREENSAVER_MIN_TIMEOUT / 2,
307 (GSourceFunc) fake_event, scr);
312 #endif /* HAVE_XTEST */
314 XLockDisplay (GDK_DISPLAY());
315 XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
316 &scr->priv->interval,
317 &scr->priv->prefer_blanking,
318 &scr->priv->allow_exposures);
319 XSetScreenSaver(GDK_DISPLAY(), 0, 0,
320 DontPreferBlanking, DontAllowExposures);
321 XUnlockDisplay (GDK_DISPLAY());
325 screensaver_init_x11 (TotemScrsaver *scr)
330 XLockDisplay (GDK_DISPLAY());
331 scr->priv->have_xtest = (XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d) == True);
332 if (scr->priv->have_xtest != FALSE)
334 scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
335 if (scr->priv->keycode1 == 0) {
336 g_warning ("scr->priv->keycode1 not existant");
338 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_R);
339 if (scr->priv->keycode2 == 0) {
340 scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
341 if (scr->priv->keycode2 == 0) {
342 g_warning ("scr->priv->keycode2 not existant");
345 scr->priv->keycode = &scr->priv->keycode1;
347 XUnlockDisplay (GDK_DISPLAY());
348 #endif /* HAVE_XTEST */
352 screensaver_finalize_x11 (TotemScrsaver *scr)
354 g_source_remove_by_user_data (scr);
366 totem_scrsaver_constructed (GObject *object)
368 TotemScrsaver *scr = TOTEM_SCRSAVER (object);
369 TotemScrsaverPrivate *priv = scr->priv;
371 priv->watch_id = g_bus_watch_name_on_connection (priv->connection,
373 G_BUS_NAME_WATCHER_FLAGS_NONE,
374 screensaver_dbus_appeared_cb,
375 screensaver_dbus_disappeared_cb,
380 totem_scrsaver_set_property (GObject *object,
385 TotemScrsaver *scr = TOTEM_SCRSAVER (object);
386 TotemScrsaverPrivate *priv = scr->priv;
389 case PROP_CONNECTION:
390 priv->connection = g_value_dup_object (value);
393 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
398 #endif /* ENABLE_DBUS */
401 totem_scrsaver_class_init (TotemScrsaverClass *klass)
403 GObjectClass *object_class = G_OBJECT_CLASS (klass);
406 g_object_class_install_property (object_class,
408 g_param_spec_object ("connection", NULL, NULL,
409 G_TYPE_DBUS_CONNECTION,
411 G_PARAM_CONSTRUCT_ONLY |
412 G_PARAM_STATIC_STRINGS));
413 object_class->set_property = totem_scrsaver_set_property;
414 object_class->constructed = totem_scrsaver_constructed;
417 object_class->finalize = totem_scrsaver_finalize;
422 totem_scrsaver_new (GDBusConnection *connection)
424 totem_scrsaver_new (void)
427 return g_object_new (TOTEM_TYPE_SCRSAVER,
429 "connection", connection,
435 totem_scrsaver_init (TotemScrsaver *scr)
437 scr->priv = G_TYPE_INSTANCE_GET_PRIVATE (scr, TOTEM_TYPE_SCRSAVER, TotemScrsaverPrivate);
439 screensaver_init_dbus (scr);
440 #ifdef GDK_WINDOWING_X11
441 screensaver_init_x11 (scr);
443 #warning Unimplemented
448 totem_scrsaver_disable (TotemScrsaver *scr)
450 g_return_if_fail (TOTEM_SCRSAVER (scr));
452 if (scr->priv->disabled != FALSE)
455 scr->priv->disabled = TRUE;
457 if (screensaver_is_running_dbus (scr) != FALSE)
458 screensaver_disable_dbus (scr);
460 #ifdef GDK_WINDOWING_X11
461 screensaver_disable_x11 (scr);
463 #warning Unimplemented
469 totem_scrsaver_enable (TotemScrsaver *scr)
471 g_return_if_fail (TOTEM_SCRSAVER (scr));
473 if (scr->priv->disabled == FALSE)
476 scr->priv->disabled = FALSE;
478 if (screensaver_is_running_dbus (scr) != FALSE)
479 screensaver_enable_dbus (scr);
481 #ifdef GDK_WINDOWING_X11
482 screensaver_enable_x11 (scr);
484 #warning Unimplemented
490 totem_scrsaver_set_state (TotemScrsaver *scr, gboolean enable)
492 g_return_if_fail (TOTEM_SCRSAVER (scr));
494 if (scr->priv->disabled == !enable)
498 totem_scrsaver_disable (scr);
500 totem_scrsaver_enable (scr);
504 totem_scrsaver_finalize (GObject *object)
506 TotemScrsaver *scr = TOTEM_SCRSAVER (object);
508 screensaver_finalize_dbus (scr);
509 #ifdef GDK_WINDOWING_X11
510 screensaver_finalize_x11 (scr);
512 #warning Unimplemented
516 G_OBJECT_CLASS (parent_class)->finalize (object);