cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_dbus.c (7361B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 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"
     27static const char *dbus_library = "libdbus-1.so.3";
     28static void *dbus_handle = NULL;
     29static unsigned int screensaver_cookie = 0;
     30static SDL_DBusContext dbus = {0};
     31
     32static int
     33load_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
     78static void
     79UnloadDBUSLibrary(void)
     80{
     81    if (dbus_handle != NULL) {
     82        SDL_UnloadObject(dbus_handle);
     83        dbus_handle = NULL;
     84    }
     85}
     86
     87static int
     88LoadDBUSLibrary(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
    107void
    108SDL_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
    126void
    127SDL_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
    138SDL_DBusContext *
    139SDL_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
    152void
    153SDL_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
    170SDL_bool
    171SDL_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