~ubuntu-branches/ubuntu/trusty/evince/trusty-proposed

« back to all changes in this revision

Viewing changes to cut-n-paste/totem-screensaver/totem-scrsaver.c

Tags: upstream-0.7.0
ImportĀ upstreamĀ versionĀ 0.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 
2
 
 
3
   Copyright (C) 2004-2006 Bastien Nocera <hadess@hadess.net>
 
4
 
 
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.
 
9
 
 
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.
 
14
 
 
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.
 
19
 
 
20
   Author: Bastien Nocera <hadess@hadess.net>
 
21
 */
 
22
 
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include <glib/gi18n.h>
 
27
#include <gdk/gdkx.h>
 
28
 
 
29
#ifdef HAVE_XTEST
 
30
#include <X11/extensions/XTest.h>
 
31
#endif /* HAVE_XTEST */
 
32
#include <X11/keysym.h>
 
33
 
 
34
#ifdef ENABLE_DBUS
 
35
#include <dbus/dbus-glib.h>
 
36
 
 
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 */
 
41
 
 
42
#include "totem-scrsaver.h"
 
43
 
 
44
#define XSCREENSAVER_MIN_TIMEOUT 60
 
45
 
 
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);
 
50
 
 
51
 
 
52
struct TotemScrsaverPrivate {
 
53
        /* Whether the screensaver is disabled */
 
54
        gboolean disabled;
 
55
 
 
56
#ifdef ENABLE_DBUS
 
57
        DBusGConnection *connection;
 
58
        DBusGProxy *gs_proxy;
 
59
        guint32 cookie;
 
60
#endif /* ENABLE_DBUS */
 
61
 
 
62
        /* To save the screensaver info */
 
63
        int timeout;
 
64
        int interval;
 
65
        int prefer_blanking;
 
66
        int allow_exposures;
 
67
 
 
68
        /* For use with XTest */
 
69
        int keycode1, keycode2;
 
70
        int *keycode;
 
71
        Bool have_xtest;
 
72
};
 
73
 
 
74
G_DEFINE_TYPE(TotemScrsaver, totem_scrsaver, G_TYPE_OBJECT)
 
75
 
 
76
static gboolean
 
77
screensaver_is_running_dbus (TotemScrsaver *scr)
 
78
{
 
79
#ifdef ENABLE_DBUS
 
80
        if (! scr->priv->connection)
 
81
                return FALSE;
 
82
 
 
83
        if (! scr->priv->gs_proxy)
 
84
                return FALSE;
 
85
 
 
86
        return TRUE;
 
87
#else
 
88
        return FALSE;
 
89
#endif /* ENABLE_DBUS */
 
90
}
 
91
 
 
92
static void
 
93
screensaver_inhibit_dbus (TotemScrsaver *scr,
 
94
                          gboolean       inhibit)
 
95
{
 
96
#ifdef ENABLE_DBUS
 
97
        GError *error;
 
98
        gboolean res;
 
99
 
 
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);
 
103
 
 
104
        error = NULL;
 
105
        if (inhibit) {
 
106
                char   *application;
 
107
                char   *reason;
 
108
                guint32 cookie;
 
109
 
 
110
                application = g_strdup ("Evince");
 
111
                reason = g_strdup (_("Running in presentation mode"));
 
112
 
 
113
                res = dbus_g_proxy_call (scr->priv->gs_proxy,
 
114
                                         "Inhibit",
 
115
                                         &error,
 
116
                                         G_TYPE_STRING, application,
 
117
                                         G_TYPE_STRING, reason,
 
118
                                         G_TYPE_INVALID,
 
119
                                         G_TYPE_UINT, &cookie,
 
120
                                         G_TYPE_INVALID);
 
121
 
 
122
                if (res) {
 
123
                        /* save the cookie */
 
124
                        scr->priv->cookie = cookie;
 
125
                } else {
 
126
                        /* try the old API */
 
127
                        res = dbus_g_proxy_call (scr->priv->gs_proxy,
 
128
                                                 "InhibitActivation",
 
129
                                                 &error,
 
130
                                                 G_TYPE_STRING, reason,
 
131
                                                 G_TYPE_INVALID,
 
132
                                                 G_TYPE_INVALID);
 
133
                }
 
134
 
 
135
                g_free (reason);
 
136
                g_free (application);
 
137
 
 
138
        } else {
 
139
                res = dbus_g_proxy_call (scr->priv->gs_proxy,
 
140
                                         "UnInhibit",
 
141
                                         &error,
 
142
                                         G_TYPE_UINT, scr->priv->cookie,
 
143
                                         G_TYPE_INVALID,
 
144
                                         G_TYPE_INVALID);
 
145
                if (res) {
 
146
                        /* clear the cookie */
 
147
                        scr->priv->cookie = 0;
 
148
                } else {
 
149
                        /* try the old API */
 
150
                        res = dbus_g_proxy_call (scr->priv->gs_proxy,
 
151
                                                 "AllowActivation",
 
152
                                                 &error,
 
153
                                                 G_TYPE_INVALID,
 
154
                                                 G_TYPE_INVALID);
 
155
                }
 
156
        }
 
157
 
 
158
        if (! res) {
 
159
                if (error) {
 
160
                        g_warning ("Problem inhibiting the screensaver: %s", error->message);
 
161
                        g_error_free (error);
 
162
                }
 
163
        }
 
164
#endif /* ENABLE_DBUS */
 
165
}
 
166
 
 
167
static void
 
168
screensaver_enable_dbus (TotemScrsaver *scr)
 
169
{
 
170
        screensaver_inhibit_dbus (scr, FALSE);
 
171
}
 
172
 
 
173
static void
 
174
screensaver_disable_dbus (TotemScrsaver *scr)
 
175
{
 
176
        screensaver_inhibit_dbus (scr, TRUE);
 
177
}
 
178
 
 
179
#ifdef ENABLE_DBUS
 
180
static void
 
181
gs_proxy_destroy_cb (GObject *proxy,
 
182
                     TotemScrsaver *scr)
 
183
{
 
184
        g_warning ("Detected that GNOME screensaver has left the bus");
 
185
 
 
186
        /* just invalidate for now */
 
187
        scr->priv->gs_proxy = NULL;
 
188
}
 
189
#endif
 
190
 
 
191
#ifdef ENABLE_DBUS
 
192
static void
 
193
screensaver_init_dbus (TotemScrsaver *scr, DBusGConnection *connection)
 
194
{
 
195
        GError *error = NULL;
 
196
 
 
197
        if (!connection)
 
198
                scr->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
 
199
        else
 
200
                scr->priv->connection = connection;
 
201
 
 
202
        if (! scr->priv->connection) {
 
203
                if (error) {
 
204
                        g_warning ("Failed to connect to the session bus: %s", error->message);
 
205
                        g_error_free (error);
 
206
                }
 
207
                return;
 
208
        }
 
209
 
 
210
        scr->priv->gs_proxy = dbus_g_proxy_new_for_name_owner (scr->priv->connection,
 
211
                                                               GS_SERVICE,
 
212
                                                               GS_PATH,
 
213
                                                               GS_INTERFACE,
 
214
                                                               NULL);
 
215
        if (scr->priv->gs_proxy != NULL) {
 
216
                g_signal_connect_object (scr->priv->gs_proxy,
 
217
                                         "destroy",
 
218
                                         G_CALLBACK (gs_proxy_destroy_cb),
 
219
                                         scr,
 
220
                                         0);
 
221
 
 
222
        }
 
223
 
 
224
}
 
225
#endif /* ENABLE_DBUS */
 
226
 
 
227
static void
 
228
screensaver_finalize_dbus (TotemScrsaver *scr)
 
229
{
 
230
#ifdef ENABLE_DBUS
 
231
        if (scr->priv->gs_proxy) {
 
232
                g_object_unref (scr->priv->gs_proxy);
 
233
        }
 
234
#endif /* ENABLE_DBUS */
 
235
}
 
236
 
 
237
static void
 
238
screensaver_enable_x11 (TotemScrsaver *scr)
 
239
{
 
240
 
 
241
#ifdef HAVE_XTEST
 
242
        if (scr->priv->have_xtest == True)
 
243
        {
 
244
                g_source_remove_by_user_data (scr);
 
245
                return;
 
246
        }
 
247
#endif /* HAVE_XTEST */
 
248
 
 
249
        XLockDisplay (GDK_DISPLAY());
 
250
        XSetScreenSaver (GDK_DISPLAY(),
 
251
                        scr->priv->timeout,
 
252
                        scr->priv->interval,
 
253
                        scr->priv->prefer_blanking,
 
254
                        scr->priv->allow_exposures);
 
255
        XUnlockDisplay (GDK_DISPLAY());
 
256
}
 
257
 
 
258
#ifdef HAVE_XTEST
 
259
static gboolean
 
260
fake_event (TotemScrsaver *scr)
 
261
{
 
262
        if (scr->priv->disabled)
 
263
        {
 
264
                XLockDisplay (GDK_DISPLAY());
 
265
                XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
 
266
                                True, CurrentTime);
 
267
                XTestFakeKeyEvent (GDK_DISPLAY(), *scr->priv->keycode,
 
268
                                False, CurrentTime);
 
269
                XUnlockDisplay (GDK_DISPLAY());
 
270
                /* Swap the keycode */
 
271
                if (scr->priv->keycode == &scr->priv->keycode1)
 
272
                        scr->priv->keycode = &scr->priv->keycode2;
 
273
                else
 
274
                        scr->priv->keycode = &scr->priv->keycode1;
 
275
        }
 
276
 
 
277
        return TRUE;
 
278
}
 
279
#endif /* HAVE_XTEST */
 
280
 
 
281
static void
 
282
screensaver_disable_x11 (TotemScrsaver *scr)
 
283
{
 
284
 
 
285
#ifdef HAVE_XTEST
 
286
        if (scr->priv->have_xtest == True)
 
287
        {
 
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());
 
294
 
 
295
                if (scr->priv->timeout != 0)
 
296
                {
 
297
                        g_timeout_add (scr->priv->timeout / 2 * 1000,
 
298
                                        (GSourceFunc) fake_event, scr);
 
299
                } else {
 
300
                        g_timeout_add (XSCREENSAVER_MIN_TIMEOUT / 2 * 1000,
 
301
                                        (GSourceFunc) fake_event, scr);
 
302
                }
 
303
 
 
304
                return;
 
305
        }
 
306
#endif /* HAVE_XTEST */
 
307
 
 
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());
 
316
}
 
317
 
 
318
static void
 
319
screensaver_init_x11 (TotemScrsaver *scr)
 
320
{
 
321
#ifdef HAVE_XTEST
 
322
        int a, b, c, d;
 
323
 
 
324
        XLockDisplay (GDK_DISPLAY());
 
325
        scr->priv->have_xtest = XTestQueryExtension (GDK_DISPLAY(), &a, &b, &c, &d);
 
326
        if(scr->priv->have_xtest == True)
 
327
        {
 
328
                scr->priv->keycode1 = XKeysymToKeycode (GDK_DISPLAY(), XK_Alt_L);
 
329
                if (scr->priv->keycode1 == 0) {
 
330
                        g_warning ("scr->priv->keycode1 not existant");
 
331
                }
 
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");
 
337
                        }
 
338
                }
 
339
                scr->priv->keycode = &scr->priv->keycode1;
 
340
        }
 
341
        XUnlockDisplay (GDK_DISPLAY());
 
342
#endif /* HAVE_XTEST */
 
343
}
 
344
 
 
345
static void
 
346
screensaver_finalize_x11 (TotemScrsaver *scr)
 
347
{
 
348
        g_source_remove_by_user_data (scr);
 
349
}
 
350
 
 
351
static void
 
352
totem_scrsaver_class_init (TotemScrsaverClass *klass)
 
353
{
 
354
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
355
 
 
356
        parent_class = g_type_class_peek_parent (klass);
 
357
 
 
358
        object_class->finalize = totem_scrsaver_finalize;
 
359
}
 
360
 
 
361
#ifdef ENABLE_DBUS
 
362
TotemScrsaver *
 
363
totem_scrsaver_new      (DBusGConnection *connection)
 
364
{
 
365
        TotemScrsaver * scr;
 
366
        scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
 
367
 
 
368
        screensaver_init_dbus (scr, connection);
 
369
        screensaver_init_x11 (scr);
 
370
        
 
371
        return scr;
 
372
}
 
373
#else
 
374
TotemScrsaver *
 
375
totem_scrsaver_new()
 
376
{
 
377
        TotemScrsaver * scr;
 
378
        scr = TOTEM_SCRSAVER (g_object_new (TOTEM_TYPE_SCRSAVER, NULL));
 
379
 
 
380
        screensaver_init_x11 (scr);
 
381
        
 
382
        return scr;
 
383
}
 
384
#endif
 
385
 
 
386
static void
 
387
totem_scrsaver_init (TotemScrsaver *scr)
 
388
{
 
389
        scr->priv = g_new0 (TotemScrsaverPrivate, 1);
 
390
}
 
391
 
 
392
void
 
393
totem_scrsaver_disable (TotemScrsaver *scr)
 
394
{
 
395
        if (scr->priv->disabled != FALSE)
 
396
                return;
 
397
 
 
398
        scr->priv->disabled = TRUE;
 
399
 
 
400
        if (screensaver_is_running_dbus (scr) != FALSE)
 
401
                screensaver_disable_dbus (scr);
 
402
        else 
 
403
                screensaver_disable_x11 (scr);
 
404
}
 
405
 
 
406
void
 
407
totem_scrsaver_enable (TotemScrsaver *scr)
 
408
{
 
409
        if (scr->priv->disabled == FALSE)
 
410
                return;
 
411
 
 
412
        scr->priv->disabled = FALSE;
 
413
 
 
414
        if (screensaver_is_running_dbus (scr) != FALSE)
 
415
                screensaver_enable_dbus (scr);
 
416
        else 
 
417
                screensaver_enable_x11 (scr);
 
418
}
 
419
 
 
420
static void
 
421
totem_scrsaver_finalize (GObject *object)
 
422
{
 
423
        TotemScrsaver *scr = TOTEM_SCRSAVER (object);
 
424
 
 
425
        screensaver_finalize_dbus (scr);
 
426
        screensaver_finalize_x11 (scr);
 
427
 
 
428
        g_free (scr->priv);
 
429
 
 
430
        if (G_OBJECT_CLASS (parent_class)->finalize != NULL) {
 
431
                (* G_OBJECT_CLASS (parent_class)->finalize) (object);
 
432
        }
 
433
}
 
434