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
g_timeout_add (scr->priv->timeout / 2 * 1000,
298
(GSourceFunc) fake_event, scr);
300
g_timeout_add (XSCREENSAVER_MIN_TIMEOUT / 2 * 1000,
301
(GSourceFunc) fake_event, scr);
306
#endif /* HAVE_XTEST */
308
XLockDisplay (GDK_DISPLAY());
309
XGetScreenSaver(GDK_DISPLAY(), &scr->priv->timeout,
310
&scr->priv->interval,
311
&scr->priv->prefer_blanking,
312
&scr->priv->allow_exposures);
313
XSetScreenSaver(GDK_DISPLAY(), 0, 0,
314
DontPreferBlanking, DontAllowExposures);
315
XUnlockDisplay (GDK_DISPLAY());
319
screensaver_init_x11 (TotemScrsaver *scr)
324
XLockDisplay (GDK_DISPLAY());
325
scr->priv->have_xtest = XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d);
326
if(scr->priv->have_xtest == True)
328
scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
329
if (scr->priv->keycode1 == 0) {
330
g_warning ("scr->priv->keycode1 not existant");
332
scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_R);
333
if (scr->priv->keycode2 == 0) {
334
scr->priv->keycode2 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
335
if (scr->priv->keycode2 == 0) {
336
g_warning ("scr->priv->keycode2 not existant");
339
scr->priv->keycode = &scr->priv->keycode1;
341
XUnlockDisplay (GDK_DISPLAY());
342
#endif /* HAVE_XTEST */
346
screensaver_finalize_x11 (TotemScrsaver *scr)
348
g_source_remove_by_user_data (scr);
352
totem_scrsaver_class_init (TotemScrsaverClass *klass)
354
GObjectClass *object_class = G_OBJECT_CLASS (klass);
356
parent_class = g_type_class_peek_parent (klass);
358
object_class->finalize = totem_scrsaver_finalize;
363
totem_scrsaver_new (DBusGConnection *connection)
366
scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
368
screensaver_init_dbus (scr, connection);
369
screensaver_init_x11 (scr);
378
scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
380
screensaver_init_x11 (scr);
387
totem_scrsaver_init (TotemScrsaver *scr)
389
scr->priv = g_new0 (TotemScrsaverPrivate, 1);
393
totem_scrsaver_disable (TotemScrsaver *scr)
395
if (scr->priv->disabled != FALSE)
398
scr->priv->disabled = TRUE;
400
if (screensaver_is_running_dbus (scr) != FALSE)
401
screensaver_disable_dbus (scr);
403
screensaver_disable_x11 (scr);
407
totem_scrsaver_enable (TotemScrsaver *scr)
409
if (scr->priv->disabled == FALSE)
412
scr->priv->disabled = FALSE;
414
if (screensaver_is_running_dbus (scr) != FALSE)
415
screensaver_enable_dbus (scr);
417
screensaver_enable_x11 (scr);
421
totem_scrsaver_finalize (GObject *object)
423
TotemScrsaver *scr = TOTEM_SCRSAVER (object);
425
screensaver_finalize_dbus (scr);
426
screensaver_finalize_x11 (scr);
430
if (G_OBJECT_CLASS (parent_class)->finalize != NULL) {
431
(* G_OBJECT_CLASS (parent_class)->finalize) (object);