src/core/linux/SDL_dbus.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 26 May 2015 06:27:46 -0700
changeset 9619 b94b6d0bff0f
parent 8977 84ae33058c67
child 9646 9d4917e2d909
permissions -rw-r--r--
Updated the copyright year to 2015
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2015 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 = {0};
    31 
    32 static int
    33 load_dbus_syms(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_send);
    49     SDL_DBUS_SYM(connection_send_with_reply_and_block);
    50     SDL_DBUS_SYM(connection_close);
    51     SDL_DBUS_SYM(connection_unref);
    52     SDL_DBUS_SYM(connection_flush);
    53     SDL_DBUS_SYM(connection_read_write);
    54     SDL_DBUS_SYM(connection_dispatch);
    55     SDL_DBUS_SYM(message_is_signal);
    56     SDL_DBUS_SYM(message_new_method_call);
    57     SDL_DBUS_SYM(message_append_args);
    58     SDL_DBUS_SYM(message_get_args);
    59     SDL_DBUS_SYM(message_iter_init);
    60     SDL_DBUS_SYM(message_iter_next);
    61     SDL_DBUS_SYM(message_iter_get_basic);
    62     SDL_DBUS_SYM(message_iter_get_arg_type);
    63     SDL_DBUS_SYM(message_iter_recurse);
    64     SDL_DBUS_SYM(message_unref);
    65     SDL_DBUS_SYM(error_init);
    66     SDL_DBUS_SYM(error_is_set);
    67     SDL_DBUS_SYM(error_free);
    68     SDL_DBUS_SYM(get_local_machine_id);
    69     SDL_DBUS_SYM(free);
    70     SDL_DBUS_SYM(shutdown);
    71 
    72     #undef SDL_DBUS_SYM
    73     #undef SDL_DBUS_SYM2
    74 
    75     return 0;
    76 }
    77 
    78 static void
    79 UnloadDBUSLibrary(void)
    80 {
    81     if (dbus_handle != NULL) {
    82         SDL_UnloadObject(dbus_handle);
    83         dbus_handle = NULL;
    84     }
    85 }
    86 
    87 static int
    88 LoadDBUSLibrary(void)
    89 {
    90     int retval = 0;
    91     if (dbus_handle == NULL) {
    92         dbus_handle = SDL_LoadObject(dbus_library);
    93         if (dbus_handle == NULL) {
    94             retval = -1;
    95             /* Don't call SDL_SetError(): SDL_LoadObject already did. */
    96         } else {
    97             retval = load_dbus_syms();
    98             if (retval < 0) {
    99                 UnloadDBUSLibrary();
   100             }
   101         }
   102     }
   103 
   104     return retval;
   105 }
   106 
   107 void
   108 SDL_DBus_Init(void)
   109 {
   110     if (!dbus.session_conn && LoadDBUSLibrary() != -1) {
   111         DBusError err;
   112         dbus.error_init(&err);
   113         dbus.session_conn = dbus.bus_get_private(DBUS_BUS_SESSION, &err);
   114         if (dbus.error_is_set(&err)) {
   115             dbus.error_free(&err);
   116             if (dbus.session_conn) {
   117                 dbus.connection_unref(dbus.session_conn);
   118                 dbus.session_conn = NULL;
   119             }
   120             return;  /* oh well */
   121         }
   122         dbus.connection_set_exit_on_disconnect(dbus.session_conn, 0);
   123     }
   124 }
   125 
   126 void
   127 SDL_DBus_Quit(void)
   128 {
   129     if (dbus.session_conn) {
   130         dbus.connection_close(dbus.session_conn);
   131         dbus.connection_unref(dbus.session_conn);
   132         dbus.shutdown();
   133         SDL_memset(&dbus, 0, sizeof(dbus));
   134     }
   135     UnloadDBUSLibrary();
   136 }
   137 
   138 SDL_DBusContext *
   139 SDL_DBus_GetContext(void)
   140 {
   141     if(!dbus_handle || !dbus.session_conn){
   142         SDL_DBus_Init();
   143     }
   144     
   145     if(dbus_handle && dbus.session_conn){
   146         return &dbus;
   147     } else {
   148         return NULL;
   149     }
   150 }
   151 
   152 void
   153 SDL_DBus_ScreensaverTickle(void)
   154 {
   155     DBusConnection *conn = dbus.session_conn;
   156     if (conn != NULL) {
   157         DBusMessage *msg = dbus.message_new_method_call("org.gnome.ScreenSaver",
   158                                                         "/org/gnome/ScreenSaver",
   159                                                         "org.gnome.ScreenSaver",
   160                                                         "SimulateUserActivity");
   161         if (msg != NULL) {
   162             if (dbus.connection_send(conn, msg, NULL)) {
   163                 dbus.connection_flush(conn);
   164             }
   165             dbus.message_unref(msg);
   166         }
   167     }
   168 }
   169 
   170 SDL_bool
   171 SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
   172 {
   173     DBusConnection *conn = dbus.session_conn;
   174 
   175     if (conn == NULL)
   176         return SDL_FALSE;
   177 
   178     if (inhibit &&
   179         screensaver_cookie != 0)
   180         return SDL_TRUE;
   181     if (!inhibit &&
   182         screensaver_cookie == 0)
   183         return SDL_TRUE;
   184 
   185     if (inhibit) {
   186         const char *app = "My SDL application";
   187         const char *reason = "Playing a game";
   188 
   189         DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   190                                                          "/org/freedesktop/ScreenSaver",
   191                                                          "org.freedesktop.ScreenSaver",
   192                                                          "Inhibit");
   193         if (msg != NULL) {
   194             dbus.message_append_args (msg,
   195                                       DBUS_TYPE_STRING, &app,
   196                                       DBUS_TYPE_STRING, &reason,
   197                                       DBUS_TYPE_INVALID);
   198         }
   199 
   200         if (msg != NULL) {
   201             DBusMessage *reply;
   202 
   203             reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
   204             if (reply) {
   205                 if (!dbus.message_get_args(reply, NULL,
   206                                            DBUS_TYPE_UINT32, &screensaver_cookie,
   207                                            DBUS_TYPE_INVALID))
   208                     screensaver_cookie = 0;
   209                 dbus.message_unref(reply);
   210             }
   211 
   212             dbus.message_unref(msg);
   213         }
   214 
   215         if (screensaver_cookie == 0) {
   216             return SDL_FALSE;
   217         }
   218         return SDL_TRUE;
   219     } else {
   220         DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   221                                                         "/org/freedesktop/ScreenSaver",
   222                                                         "org.freedesktop.ScreenSaver",
   223                                                         "UnInhibit");
   224         dbus.message_append_args (msg,
   225                                   DBUS_TYPE_UINT32, &screensaver_cookie,
   226                                   DBUS_TYPE_INVALID);
   227         if (msg != NULL) {
   228             if (dbus.connection_send(conn, msg, NULL)) {
   229                 dbus.connection_flush(conn);
   230             }
   231             dbus.message_unref(msg);
   232         }
   233 
   234         screensaver_cookie = 0;
   235         return SDL_TRUE;
   236     }
   237 }
   238 #endif