src/core/linux/SDL_dbus.c
changeset 8889 26a6243b27c2
child 8977 84ae33058c67
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/core/linux/SDL_dbus.c	Wed Jun 18 20:11:39 2014 +0100
     1.3 @@ -0,0 +1,236 @@
     1.4 +/*
     1.5 +  Simple DirectMedia Layer
     1.6 +  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     1.7 +
     1.8 +  This software is provided 'as-is', without any express or implied
     1.9 +  warranty.  In no event will the authors be held liable for any damages
    1.10 +  arising from the use of this software.
    1.11 +
    1.12 +  Permission is granted to anyone to use this software for any purpose,
    1.13 +  including commercial applications, and to alter it and redistribute it
    1.14 +  freely, subject to the following restrictions:
    1.15 +
    1.16 +  1. The origin of this software must not be misrepresented; you must not
    1.17 +     claim that you wrote the original software. If you use this software
    1.18 +     in a product, an acknowledgment in the product documentation would be
    1.19 +     appreciated but is not required.
    1.20 +  2. Altered source versions must be plainly marked as such, and must not be
    1.21 +     misrepresented as being the original software.
    1.22 +  3. This notice may not be removed or altered from any source distribution.
    1.23 +*/
    1.24 +#include "../../SDL_internal.h"
    1.25 +#include "SDL_dbus.h"
    1.26 +
    1.27 +#if SDL_USE_LIBDBUS
    1.28 +/* we never link directly to libdbus. */
    1.29 +#include "SDL_loadso.h"
    1.30 +static const char *dbus_library = "libdbus-1.so.3";
    1.31 +static void *dbus_handle = NULL;
    1.32 +static unsigned int screensaver_cookie = 0;
    1.33 +static SDL_DBusContext dbus = {0};
    1.34 +
    1.35 +static int
    1.36 +load_dbus_syms(void)
    1.37 +{
    1.38 +    #define SDL_DBUS_SYM2(x, y) \
    1.39 +        if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) return -1
    1.40 +        
    1.41 +    #define SDL_DBUS_SYM(x) \
    1.42 +        SDL_DBUS_SYM2(x, dbus_##x)
    1.43 +
    1.44 +    SDL_DBUS_SYM(bus_get_private);
    1.45 +    SDL_DBUS_SYM(bus_register);
    1.46 +    SDL_DBUS_SYM(bus_add_match);
    1.47 +    SDL_DBUS_SYM(connection_open_private);
    1.48 +    SDL_DBUS_SYM(connection_set_exit_on_disconnect);
    1.49 +    SDL_DBUS_SYM(connection_get_is_connected);
    1.50 +    SDL_DBUS_SYM(connection_add_filter);
    1.51 +    SDL_DBUS_SYM(connection_send);
    1.52 +    SDL_DBUS_SYM(connection_send_with_reply_and_block);
    1.53 +    SDL_DBUS_SYM(connection_close);
    1.54 +    SDL_DBUS_SYM(connection_unref);
    1.55 +    SDL_DBUS_SYM(connection_flush);
    1.56 +    SDL_DBUS_SYM(connection_read_write);
    1.57 +    SDL_DBUS_SYM(connection_dispatch);
    1.58 +    SDL_DBUS_SYM(message_is_signal);
    1.59 +    SDL_DBUS_SYM(message_new_method_call);
    1.60 +    SDL_DBUS_SYM(message_append_args);
    1.61 +    SDL_DBUS_SYM(message_get_args);
    1.62 +    SDL_DBUS_SYM(message_iter_init);
    1.63 +    SDL_DBUS_SYM(message_iter_next);
    1.64 +    SDL_DBUS_SYM(message_iter_get_basic);
    1.65 +    SDL_DBUS_SYM(message_iter_get_arg_type);
    1.66 +    SDL_DBUS_SYM(message_iter_recurse);
    1.67 +    SDL_DBUS_SYM(message_unref);
    1.68 +    SDL_DBUS_SYM(error_init);
    1.69 +    SDL_DBUS_SYM(error_is_set);
    1.70 +    SDL_DBUS_SYM(error_free);
    1.71 +    SDL_DBUS_SYM(get_local_machine_id);
    1.72 +    SDL_DBUS_SYM(free);
    1.73 +
    1.74 +    #undef SDL_DBUS_SYM
    1.75 +    #undef SDL_DBUS_SYM2
    1.76 +
    1.77 +    return 0;
    1.78 +}
    1.79 +
    1.80 +static void
    1.81 +UnloadDBUSLibrary(void)
    1.82 +{
    1.83 +    if (dbus_handle != NULL) {
    1.84 +        SDL_UnloadObject(dbus_handle);
    1.85 +        dbus_handle = NULL;
    1.86 +    }
    1.87 +}
    1.88 +
    1.89 +static int
    1.90 +LoadDBUSLibrary(void)
    1.91 +{
    1.92 +    int retval = 0;
    1.93 +    if (dbus_handle == NULL) {
    1.94 +        dbus_handle = SDL_LoadObject(dbus_library);
    1.95 +        if (dbus_handle == NULL) {
    1.96 +            retval = -1;
    1.97 +            /* Don't call SDL_SetError(): SDL_LoadObject already did. */
    1.98 +        } else {
    1.99 +            retval = load_dbus_syms();
   1.100 +            if (retval < 0) {
   1.101 +                UnloadDBUSLibrary();
   1.102 +            }
   1.103 +        }
   1.104 +    }
   1.105 +
   1.106 +    return retval;
   1.107 +}
   1.108 +
   1.109 +void
   1.110 +SDL_DBus_Init(void)
   1.111 +{
   1.112 +    if (LoadDBUSLibrary() != -1) {
   1.113 +        DBusError err;
   1.114 +        dbus.error_init(&err);
   1.115 +        dbus.session_conn = dbus.bus_get_private(DBUS_BUS_SESSION, &err);
   1.116 +        if (dbus.error_is_set(&err)) {
   1.117 +            dbus.error_free(&err);
   1.118 +            if (dbus.session_conn) {
   1.119 +                dbus.connection_unref(dbus.session_conn);
   1.120 +                dbus.session_conn = NULL;
   1.121 +            }
   1.122 +            return;  /* oh well */
   1.123 +        }
   1.124 +        dbus.connection_set_exit_on_disconnect(dbus.session_conn, 0);
   1.125 +    }
   1.126 +}
   1.127 +
   1.128 +void
   1.129 +SDL_DBus_Quit(void)
   1.130 +{
   1.131 +    if (dbus.session_conn) {
   1.132 +        dbus.connection_close(dbus.session_conn);
   1.133 +        dbus.connection_unref(dbus.session_conn);
   1.134 +        SDL_memset(&dbus, 0, sizeof(dbus));
   1.135 +    }
   1.136 +    UnloadDBUSLibrary();
   1.137 +}
   1.138 +
   1.139 +SDL_DBusContext *
   1.140 +SDL_DBus_GetContext(void)
   1.141 +{
   1.142 +    if(!dbus_handle || !dbus.session_conn){
   1.143 +        SDL_DBus_Init();
   1.144 +    }
   1.145 +    
   1.146 +    if(dbus_handle && dbus.session_conn){
   1.147 +        return &dbus;
   1.148 +    } else {
   1.149 +        return NULL;
   1.150 +    }
   1.151 +}
   1.152 +
   1.153 +void
   1.154 +SDL_DBus_ScreensaverTickle(void)
   1.155 +{
   1.156 +    DBusConnection *conn = dbus.session_conn;
   1.157 +    if (conn != NULL) {
   1.158 +        DBusMessage *msg = dbus.message_new_method_call("org.gnome.ScreenSaver",
   1.159 +                                                        "/org/gnome/ScreenSaver",
   1.160 +                                                        "org.gnome.ScreenSaver",
   1.161 +                                                        "SimulateUserActivity");
   1.162 +        if (msg != NULL) {
   1.163 +            if (dbus.connection_send(conn, msg, NULL)) {
   1.164 +                dbus.connection_flush(conn);
   1.165 +            }
   1.166 +            dbus.message_unref(msg);
   1.167 +        }
   1.168 +    }
   1.169 +}
   1.170 +
   1.171 +SDL_bool
   1.172 +SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
   1.173 +{
   1.174 +    DBusConnection *conn = dbus.session_conn;
   1.175 +
   1.176 +    if (conn == NULL)
   1.177 +        return SDL_FALSE;
   1.178 +
   1.179 +    if (inhibit &&
   1.180 +        screensaver_cookie != 0)
   1.181 +        return SDL_TRUE;
   1.182 +    if (!inhibit &&
   1.183 +        screensaver_cookie == 0)
   1.184 +        return SDL_TRUE;
   1.185 +
   1.186 +    if (inhibit) {
   1.187 +        const char *app = "My SDL application";
   1.188 +        const char *reason = "Playing a game";
   1.189 +
   1.190 +        DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   1.191 +                                                         "/org/freedesktop/ScreenSaver",
   1.192 +                                                         "org.freedesktop.ScreenSaver",
   1.193 +                                                         "Inhibit");
   1.194 +        if (msg != NULL) {
   1.195 +            dbus.message_append_args (msg,
   1.196 +                                      DBUS_TYPE_STRING, &app,
   1.197 +                                      DBUS_TYPE_STRING, &reason,
   1.198 +                                      DBUS_TYPE_INVALID);
   1.199 +        }
   1.200 +
   1.201 +        if (msg != NULL) {
   1.202 +            DBusMessage *reply;
   1.203 +
   1.204 +            reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
   1.205 +            if (reply) {
   1.206 +                if (!dbus.message_get_args(reply, NULL,
   1.207 +                                           DBUS_TYPE_UINT32, &screensaver_cookie,
   1.208 +                                           DBUS_TYPE_INVALID))
   1.209 +                    screensaver_cookie = 0;
   1.210 +                dbus.message_unref(reply);
   1.211 +            }
   1.212 +
   1.213 +            dbus.message_unref(msg);
   1.214 +        }
   1.215 +
   1.216 +        if (screensaver_cookie == 0) {
   1.217 +            return SDL_FALSE;
   1.218 +        }
   1.219 +        return SDL_TRUE;
   1.220 +    } else {
   1.221 +        DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   1.222 +                                                        "/org/freedesktop/ScreenSaver",
   1.223 +                                                        "org.freedesktop.ScreenSaver",
   1.224 +                                                        "UnInhibit");
   1.225 +        dbus.message_append_args (msg,
   1.226 +                                  DBUS_TYPE_UINT32, &screensaver_cookie,
   1.227 +                                  DBUS_TYPE_INVALID);
   1.228 +        if (msg != NULL) {
   1.229 +            if (dbus.connection_send(conn, msg, NULL)) {
   1.230 +                dbus.connection_flush(conn);
   1.231 +            }
   1.232 +            dbus.message_unref(msg);
   1.233 +        }
   1.234 +
   1.235 +        screensaver_cookie = 0;
   1.236 +        return SDL_TRUE;
   1.237 +    }
   1.238 +}
   1.239 +#endif