SDL  2.0
SDL_dbus.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 #include "SDL_dbus.h"
23 
24 #if SDL_USE_LIBDBUS
25 /* we never link directly to libdbus. */
26 #include "SDL_loadso.h"
27 static const char *dbus_library = "libdbus-1.so.3";
28 static void *dbus_handle = NULL;
29 static unsigned int screensaver_cookie = 0;
30 static SDL_DBusContext dbus;
31 
32 static int
33 LoadDBUSSyms(void)
34 {
35  #define SDL_DBUS_SYM2(x, y) \
36  if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) return -1
37 
38  #define SDL_DBUS_SYM(x) \
39  SDL_DBUS_SYM2(x, dbus_##x)
40 
41  SDL_DBUS_SYM(bus_get_private);
42  SDL_DBUS_SYM(bus_register);
43  SDL_DBUS_SYM(bus_add_match);
44  SDL_DBUS_SYM(connection_open_private);
45  SDL_DBUS_SYM(connection_set_exit_on_disconnect);
46  SDL_DBUS_SYM(connection_get_is_connected);
47  SDL_DBUS_SYM(connection_add_filter);
48  SDL_DBUS_SYM(connection_try_register_object_path);
49  SDL_DBUS_SYM(connection_send);
50  SDL_DBUS_SYM(connection_send_with_reply_and_block);
51  SDL_DBUS_SYM(connection_close);
52  SDL_DBUS_SYM(connection_unref);
53  SDL_DBUS_SYM(connection_flush);
54  SDL_DBUS_SYM(connection_read_write);
55  SDL_DBUS_SYM(connection_dispatch);
56  SDL_DBUS_SYM(message_is_signal);
57  SDL_DBUS_SYM(message_new_method_call);
58  SDL_DBUS_SYM(message_append_args);
59  SDL_DBUS_SYM(message_get_args);
60  SDL_DBUS_SYM(message_iter_init);
61  SDL_DBUS_SYM(message_iter_next);
62  SDL_DBUS_SYM(message_iter_get_basic);
63  SDL_DBUS_SYM(message_iter_get_arg_type);
64  SDL_DBUS_SYM(message_iter_recurse);
65  SDL_DBUS_SYM(message_unref);
66  SDL_DBUS_SYM(error_init);
67  SDL_DBUS_SYM(error_is_set);
68  SDL_DBUS_SYM(error_free);
69  SDL_DBUS_SYM(get_local_machine_id);
70  SDL_DBUS_SYM(free);
71  SDL_DBUS_SYM(shutdown);
72 
73  #undef SDL_DBUS_SYM
74  #undef SDL_DBUS_SYM2
75 
76  return 0;
77 }
78 
79 static void
80 UnloadDBUSLibrary(void)
81 {
82  if (dbus_handle != NULL) {
83  SDL_UnloadObject(dbus_handle);
84  dbus_handle = NULL;
85  }
86 }
87 
88 static int
89 LoadDBUSLibrary(void)
90 {
91  int retval = 0;
92  if (dbus_handle == NULL) {
93  dbus_handle = SDL_LoadObject(dbus_library);
94  if (dbus_handle == NULL) {
95  retval = -1;
96  /* Don't call SDL_SetError(): SDL_LoadObject already did. */
97  } else {
98  retval = LoadDBUSSyms();
99  if (retval < 0) {
100  UnloadDBUSLibrary();
101  }
102  }
103  }
104 
105  return retval;
106 }
107 
108 void
109 SDL_DBus_Init(void)
110 {
111  if (!dbus.session_conn && LoadDBUSLibrary() != -1) {
112  DBusError err;
113  dbus.error_init(&err);
114  dbus.session_conn = dbus.bus_get_private(DBUS_BUS_SESSION, &err);
115  if (dbus.error_is_set(&err)) {
116  dbus.error_free(&err);
117  if (dbus.session_conn) {
118  dbus.connection_unref(dbus.session_conn);
119  dbus.session_conn = NULL;
120  }
121  return; /* oh well */
122  }
123  dbus.connection_set_exit_on_disconnect(dbus.session_conn, 0);
124  }
125 }
126 
127 void
128 SDL_DBus_Quit(void)
129 {
130  if (dbus.session_conn) {
131  dbus.connection_close(dbus.session_conn);
132  dbus.connection_unref(dbus.session_conn);
133  dbus.shutdown();
134  SDL_memset(&dbus, 0, sizeof(dbus));
135  }
136  UnloadDBUSLibrary();
137 }
138 
139 SDL_DBusContext *
140 SDL_DBus_GetContext(void)
141 {
142  if(!dbus_handle || !dbus.session_conn){
143  SDL_DBus_Init();
144  }
145 
146  if(dbus_handle && dbus.session_conn){
147  return &dbus;
148  } else {
149  return NULL;
150  }
151 }
152 
153 void
154 SDL_DBus_ScreensaverTickle(void)
155 {
156  DBusConnection *conn = dbus.session_conn;
157  if (conn != NULL) {
158  DBusMessage *msg = dbus.message_new_method_call("org.gnome.ScreenSaver",
159  "/org/gnome/ScreenSaver",
160  "org.gnome.ScreenSaver",
161  "SimulateUserActivity");
162  if (msg != NULL) {
163  if (dbus.connection_send(conn, msg, NULL)) {
164  dbus.connection_flush(conn);
165  }
166  dbus.message_unref(msg);
167  }
168  }
169 }
170 
171 SDL_bool
172 SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
173 {
174  DBusConnection *conn = dbus.session_conn;
175 
176  if (conn == NULL)
177  return SDL_FALSE;
178 
179  if (inhibit &&
180  screensaver_cookie != 0)
181  return SDL_TRUE;
182  if (!inhibit &&
183  screensaver_cookie == 0)
184  return SDL_TRUE;
185 
186  if (inhibit) {
187  const char *app = "My SDL application";
188  const char *reason = "Playing a game";
189 
190  DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
191  "/org/freedesktop/ScreenSaver",
192  "org.freedesktop.ScreenSaver",
193  "Inhibit");
194  if (msg != NULL) {
195  dbus.message_append_args (msg,
196  DBUS_TYPE_STRING, &app,
197  DBUS_TYPE_STRING, &reason,
198  DBUS_TYPE_INVALID);
199  }
200 
201  if (msg != NULL) {
202  DBusMessage *reply;
203 
204  reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
205  if (reply) {
206  if (!dbus.message_get_args(reply, NULL,
207  DBUS_TYPE_UINT32, &screensaver_cookie,
208  DBUS_TYPE_INVALID))
209  screensaver_cookie = 0;
210  dbus.message_unref(reply);
211  }
212 
213  dbus.message_unref(msg);
214  }
215 
216  if (screensaver_cookie == 0) {
217  return SDL_FALSE;
218  }
219  return SDL_TRUE;
220  } else {
221  DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
222  "/org/freedesktop/ScreenSaver",
223  "org.freedesktop.ScreenSaver",
224  "UnInhibit");
225  dbus.message_append_args (msg,
226  DBUS_TYPE_UINT32, &screensaver_cookie,
227  DBUS_TYPE_INVALID);
228  if (msg != NULL) {
229  if (dbus.connection_send(conn, msg, NULL)) {
230  dbus.connection_flush(conn);
231  }
232  dbus.message_unref(msg);
233  }
234 
235  screensaver_cookie = 0;
236  return SDL_TRUE;
237  }
238 }
239 #endif
SDL_EventEntry * free
Definition: SDL_events.c:81
#define SDL_LoadObject
#define SDL_UnloadObject
SDL_bool retval
#define NULL
Definition: begin_code.h:143
SDL_bool
Definition: SDL_stdinc.h:130
#define SDL_memset