src/core/linux/SDL_dbus.c
changeset 11042 303c875e47f0
parent 11041 5aebcca5ff18
child 11043 5be3faa49e54
     1.1 --- a/src/core/linux/SDL_dbus.c	Sun May 28 07:08:10 2017 -0400
     1.2 +++ b/src/core/linux/SDL_dbus.c	Sun May 28 07:11:52 2017 -0400
     1.3 @@ -56,7 +56,9 @@
     1.4      SDL_DBUS_SYM(message_is_signal);
     1.5      SDL_DBUS_SYM(message_new_method_call);
     1.6      SDL_DBUS_SYM(message_append_args);
     1.7 +    SDL_DBUS_SYM(message_append_args_valist);
     1.8      SDL_DBUS_SYM(message_get_args);
     1.9 +    SDL_DBUS_SYM(message_get_args_valist);
    1.10      SDL_DBUS_SYM(message_iter_init);
    1.11      SDL_DBUS_SYM(message_iter_next);
    1.12      SDL_DBUS_SYM(message_iter_get_basic);
    1.13 @@ -157,91 +159,170 @@
    1.14      }
    1.15  }
    1.16  
    1.17 -void
    1.18 -SDL_DBus_ScreensaverTickle(void)
    1.19 +static SDL_bool
    1.20 +SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap)
    1.21  {
    1.22 -    DBusConnection *conn = dbus.session_conn;
    1.23 -    if (conn != NULL) {
    1.24 -        DBusMessage *msg = dbus.message_new_method_call("org.gnome.ScreenSaver",
    1.25 -                                                        "/org/gnome/ScreenSaver",
    1.26 -                                                        "org.gnome.ScreenSaver",
    1.27 -                                                        "SimulateUserActivity");
    1.28 -        if (msg != NULL) {
    1.29 -            if (dbus.connection_send(conn, msg, NULL)) {
    1.30 -                dbus.connection_flush(conn);
    1.31 +    SDL_bool retval = SDL_FALSE;
    1.32 +
    1.33 +    if (conn) {
    1.34 +        DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method);
    1.35 +        if (msg) {
    1.36 +            int firstarg = va_arg(ap, int);
    1.37 +            if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) {
    1.38 +                DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
    1.39 +                if (reply) {
    1.40 +                    firstarg = va_arg(ap, int);
    1.41 +                    if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap)) {
    1.42 +                        retval = SDL_TRUE;
    1.43 +                    }
    1.44 +                    dbus.message_unref(reply);
    1.45 +                }
    1.46              }
    1.47              dbus.message_unref(msg);
    1.48          }
    1.49      }
    1.50 +
    1.51 +    return retval;
    1.52 +}
    1.53 +
    1.54 +SDL_bool
    1.55 +SDL_DBus_CallMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...)
    1.56 +{
    1.57 +    SDL_bool retval;
    1.58 +    va_list ap;
    1.59 +    va_start(ap, method);
    1.60 +    retval = SDL_DBus_CallMethodInternal(conn, node, path, interface, method, ap);
    1.61 +    va_end(ap);
    1.62 +    return retval;
    1.63 +}
    1.64 +
    1.65 +SDL_bool
    1.66 +SDL_DBus_CallMethod(const char *node, const char *path, const char *interface, const char *method, ...)
    1.67 +{
    1.68 +    SDL_bool retval;
    1.69 +    va_list ap;
    1.70 +    va_start(ap, method);
    1.71 +    retval = SDL_DBus_CallMethodInternal(dbus.session_conn, node, path, interface, method, ap);
    1.72 +    va_end(ap);
    1.73 +    return retval;
    1.74 +}
    1.75 +
    1.76 +static SDL_bool
    1.77 +SDL_DBus_CallVoidMethodInternal(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap)
    1.78 +{
    1.79 +    SDL_bool retval = SDL_FALSE;
    1.80 +
    1.81 +    if (conn) {
    1.82 +        DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method);
    1.83 +        if (msg) {
    1.84 +            int firstarg = va_arg(ap, int);
    1.85 +            if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) {
    1.86 +                if (dbus.connection_send(conn, msg, NULL)) {
    1.87 +                    dbus.connection_flush(conn);
    1.88 +                    retval = SDL_TRUE;
    1.89 +                }
    1.90 +            }
    1.91 +
    1.92 +            dbus.message_unref(msg);
    1.93 +        }
    1.94 +    }
    1.95 +
    1.96 +    return retval;
    1.97 +}
    1.98 +
    1.99 +SDL_bool
   1.100 +SDL_DBus_CallVoidMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...)
   1.101 +{
   1.102 +    SDL_bool retval;
   1.103 +    va_list ap;
   1.104 +    va_start(ap, method);
   1.105 +    retval = SDL_DBus_CallVoidMethodInternal(conn, node, path, interface, method, ap);
   1.106 +    va_end(ap);
   1.107 +    return retval;
   1.108 +}
   1.109 +
   1.110 +SDL_bool
   1.111 +SDL_DBus_CallVoidMethod(const char *node, const char *path, const char *interface, const char *method, ...)
   1.112 +{
   1.113 +    SDL_bool retval;
   1.114 +    va_list ap;
   1.115 +    va_start(ap, method);
   1.116 +    retval = SDL_DBus_CallVoidMethodInternal(dbus.session_conn, node, path, interface, method, ap);
   1.117 +    va_end(ap);
   1.118 +    return retval;
   1.119 +}
   1.120 +
   1.121 +SDL_bool
   1.122 +SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result)
   1.123 +{
   1.124 +    SDL_bool retval = SDL_FALSE;
   1.125 +
   1.126 +    if (conn) {
   1.127 +        DBusMessage *msg = dbus.message_new_method_call(node, path, "org.freedesktop.DBus.Properties", "Get");
   1.128 +        if (msg) {
   1.129 +            if (dbus.message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) {
   1.130 +                DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
   1.131 +                if (reply) {
   1.132 +                    DBusMessageIter iter, sub;
   1.133 +                    dbus.message_iter_init(reply, &iter);
   1.134 +                    if (dbus.message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) {
   1.135 +                        dbus.message_iter_recurse(&iter, &sub);
   1.136 +                        if (dbus.message_iter_get_arg_type(&sub) == expectedtype) {
   1.137 +                            dbus.message_iter_get_basic(&sub, result);
   1.138 +                            retval = SDL_TRUE;
   1.139 +                        }
   1.140 +                    }
   1.141 +                    dbus.message_unref(reply);
   1.142 +                }
   1.143 +            }
   1.144 +            dbus.message_unref(msg);
   1.145 +        }
   1.146 +    }
   1.147 +
   1.148 +    return retval;
   1.149 +}
   1.150 +
   1.151 +SDL_bool
   1.152 +SDL_DBus_QueryProperty(const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result)
   1.153 +{
   1.154 +    return SDL_DBus_QueryPropertyOnConnection(dbus.session_conn, node, path, interface, property, expectedtype, result);
   1.155 +}
   1.156 +
   1.157 +
   1.158 +void
   1.159 +SDL_DBus_ScreensaverTickle(void)
   1.160 +{
   1.161 +    SDL_DBus_CallVoidMethod("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver", "SimulateUserActivity", DBUS_TYPE_INVALID);
   1.162  }
   1.163  
   1.164  SDL_bool
   1.165  SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
   1.166  {
   1.167 -    DBusConnection *conn = dbus.session_conn;
   1.168 -
   1.169 -    if (conn == NULL)
   1.170 -        return SDL_FALSE;
   1.171 -
   1.172 -    if (inhibit &&
   1.173 -        screensaver_cookie != 0)
   1.174 -        return SDL_TRUE;
   1.175 -    if (!inhibit &&
   1.176 -        screensaver_cookie == 0)
   1.177 -        return SDL_TRUE;
   1.178 -
   1.179 -    if (inhibit) {
   1.180 -        const char *app = "My SDL application";
   1.181 -        const char *reason = "Playing a game";
   1.182 -
   1.183 -        DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   1.184 -                                                         "/org/freedesktop/ScreenSaver",
   1.185 -                                                         "org.freedesktop.ScreenSaver",
   1.186 -                                                         "Inhibit");
   1.187 -        if (msg != NULL) {
   1.188 -            dbus.message_append_args (msg,
   1.189 -                                      DBUS_TYPE_STRING, &app,
   1.190 -                                      DBUS_TYPE_STRING, &reason,
   1.191 -                                      DBUS_TYPE_INVALID);
   1.192 -        }
   1.193 -
   1.194 -        if (msg != NULL) {
   1.195 -            DBusMessage *reply;
   1.196 -
   1.197 -            reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL);
   1.198 -            if (reply) {
   1.199 -                if (!dbus.message_get_args(reply, NULL,
   1.200 -                                           DBUS_TYPE_UINT32, &screensaver_cookie,
   1.201 -                                           DBUS_TYPE_INVALID))
   1.202 -                    screensaver_cookie = 0;
   1.203 -                dbus.message_unref(reply);
   1.204 -            }
   1.205 -
   1.206 -            dbus.message_unref(msg);
   1.207 -        }
   1.208 -
   1.209 -        if (screensaver_cookie == 0) {
   1.210 -            return SDL_FALSE;
   1.211 -        }
   1.212 +    if ( (inhibit && (screensaver_cookie != 0)) || (!inhibit && (screensaver_cookie == 0)) ) {
   1.213          return SDL_TRUE;
   1.214      } else {
   1.215 -        DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.ScreenSaver",
   1.216 -                                                        "/org/freedesktop/ScreenSaver",
   1.217 -                                                        "org.freedesktop.ScreenSaver",
   1.218 -                                                        "UnInhibit");
   1.219 -        dbus.message_append_args (msg,
   1.220 -                                  DBUS_TYPE_UINT32, &screensaver_cookie,
   1.221 -                                  DBUS_TYPE_INVALID);
   1.222 -        if (msg != NULL) {
   1.223 -            if (dbus.connection_send(conn, msg, NULL)) {
   1.224 -                dbus.connection_flush(conn);
   1.225 +        const char *node = "org.freedesktop.ScreenSaver";
   1.226 +        const char *path = "/org/freedesktop/ScreenSaver";
   1.227 +        const char *interface = "org.freedesktop.ScreenSaver";
   1.228 +
   1.229 +        if (inhibit) {
   1.230 +            const char *app = "My SDL application";
   1.231 +            const char *reason = "Playing a game";
   1.232 +            if (!SDL_DBus_CallMethod(node, path, interface, "Inhibit",
   1.233 +                    DBUS_TYPE_STRING, &app, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID,
   1.234 +                    DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) {
   1.235 +                return SDL_FALSE;
   1.236              }
   1.237 -            dbus.message_unref(msg);
   1.238 +            return (screensaver_cookie != 0) ? SDL_TRUE : SDL_FALSE;
   1.239 +        } else {
   1.240 +            if (!SDL_DBus_CallVoidMethod(node, path, interface, "UnInhibit", DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) {
   1.241 +                return SDL_FALSE;
   1.242 +            }
   1.243 +            screensaver_cookie = 0;
   1.244          }
   1.245 +    }
   1.246  
   1.247 -        screensaver_cookie = 0;
   1.248 -        return SDL_TRUE;
   1.249 -    }
   1.250 +    return SDL_TRUE;
   1.251  }
   1.252  #endif
   1.253