summaryrefslogtreecommitdiff
path: root/tools/gnome_screensaver.c
blob: a23d42368f9bf572ec622e8d4ce8077c85274df0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * gnome_screensaver.c v0.0.7
 *
 * Enable/Disable the GNOME screensaver
 * Supports GNOME screensaver API 2.14 and 2.15
 *
 * Call gnome_screensaver_control(1) to enable and
 * gnome_screensaver_control(0) to disable
 *
 */
/*
 * Orginally written for mplayer by Piotr Kaczuba
 *   (http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-April/042661.html)
 *
 * Modified for xineliboutput by Alex Stansfield
 *   (http://www.linuxtv.org/pipermail/vdr/2007-July/013458.html)
 */

#include <stdlib.h>
#include <unistd.h>
#include <dbus/dbus-glib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#define LOG_MODULENAME "[vdr-fe]    "
#include "../logdefs.h"

#include "gnome_screensaver.h"

#define GS_SERVICE   "org.gnome.ScreenSaver"
#define GS_PATH      "/org/gnome/ScreenSaver"
#define GS_INTERFACE "org.gnome.ScreenSaver"

#define GS_APPLICATION_NAME     "vdr-sxfe"
#define GS_REASON_FOR_INHIBIT   "Watching TV"

/* Log Messages */
#define MSG_OpenBusConnectionError "Failed to open connection to bus: %s"
#define MSG_RemoteMethodException "Caught remote method exception %s: %s"
#define MSG_GnomeAPI215Failed "GNOME screensaver 2.15 API failed, trying 2.14 API"
#define MSG_GError "Error: %s"
#define MSG_GNOMEScreensaverEnabled "GNOME screensaver enabled"
#define MSG_GNOMEScreensaverDisabled "GNOME screensaver disabled"

static guint32 cookie;

void gnome_screensaver_control(int enable)
{
  DBusGConnection *connection;
  GError *error;
  DBusGProxy *proxy;
  gboolean ret;

  g_type_init();

  /* Get a connection to the session bus */
  error = NULL;
  connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
  if (!connection) {
    LOGERR(MSG_OpenBusConnectionError, error ? error->message : "<null>");
    g_error_free(error);
    return;
  }

  /* Create a proxy object */
  proxy = dbus_g_proxy_new_for_name(connection,
                                    GS_SERVICE, GS_PATH, GS_INTERFACE);
  if (!proxy) {
    LOGDBG("Failed to get a proxy for gnome-screensaver");
    return;
  }

  /* Enable the screensaver */
  if (enable) {
    /* First call the GNOME screensaver 2.15 API method */
    error = NULL;
    ret =
        dbus_g_proxy_call(proxy, "UnInhibit", &error,
                          G_TYPE_UINT, cookie,
                          G_TYPE_INVALID, G_TYPE_INVALID);

    /* If this fails, try the GNOME screensaver 2.14 API */
    if (!ret && error->domain == DBUS_GERROR
        && error->code == DBUS_GERROR_UNKNOWN_METHOD) {
      LOGERR(MSG_GnomeAPI215Failed);
      g_error_free(error);
      error = NULL;
      ret =
          dbus_g_proxy_call(proxy, "AllowActivation", &error,
                            G_TYPE_INVALID, G_TYPE_INVALID);
    }
  }
  /* Disable the screensaver */
  else {
    /* First call the GNOME screensaver 2.15 API method */
    error = NULL;
    ret =
        dbus_g_proxy_call(proxy, "Inhibit", &error,
                          G_TYPE_STRING, GS_APPLICATION_NAME,
                          G_TYPE_STRING, GS_REASON_FOR_INHIBIT,
                          G_TYPE_INVALID,
                          G_TYPE_UINT, &cookie,
                          G_TYPE_INVALID);

    /* If this fails, try the GNOME screensaver 2.14 API */
    if (!ret && error->domain == DBUS_GERROR
        && error->code == DBUS_GERROR_UNKNOWN_METHOD) {
      LOGERR(MSG_GnomeAPI215Failed);
      g_error_free(error);
      error = NULL;
      ret =
          dbus_g_proxy_call(proxy, "InhibitActivation", &error,
                            G_TYPE_STRING, GS_REASON_FOR_INHIBIT,
                            G_TYPE_INVALID, G_TYPE_INVALID);
    }
  }

  if (!ret) {
    /* Check if it's a remote exception or a regular GError */
    if (error->domain == DBUS_GERROR
        && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
      LOGERR(MSG_RemoteMethodException, dbus_g_error_get_name(error), error->message);
    }
    else {
      LOGERR(MSG_GError, error->message);
    }
    g_error_free(error);
  }
  else {
    LOGMSG(enable ? MSG_GNOMEScreensaverEnabled : MSG_GNOMEScreensaverDisabled);
  }

  g_object_unref(proxy);
}