diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index a53c1abebe..3b7aa3682f 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -73,6 +73,7 @@ static bool LoadDBUSSyms(void) SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, int), connection_read_write); SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, int), connection_read_write_dispatch); SDL_DBUS_SYM(DBusDispatchStatus (*)(DBusConnection *), connection_dispatch); + SDL_DBUS_SYM(dbus_bool_t (*)(int), type_is_fixed); SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, const char *, const char *), message_is_signal); SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, const char *), message_has_path); SDL_DBUS_SYM(DBusMessage *(*)(const char *, const char *, const char *, const char *), message_new_method_call); @@ -229,7 +230,7 @@ SDL_DBusContext *SDL_DBus_GetContext(void) return (dbus_handle && dbus.session_conn) ? &dbus : NULL; } -static bool SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap) +static bool SDL_DBus_CallMethodInternal(DBusConnection *conn, DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *method, va_list ap) { bool result = false; @@ -261,7 +262,11 @@ static bool SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap_reply)) { result = true; } - dbus.message_unref(reply); + if (save_reply) { + *save_reply = reply; + } else { + dbus.message_unref(reply); + } } } va_end(ap_reply); @@ -272,22 +277,22 @@ static bool SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, return result; } -bool SDL_DBus_CallMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) +bool SDL_DBus_CallMethodOnConnection(DBusConnection *conn, DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *method, ...) { bool result; va_list ap; va_start(ap, method); - result = SDL_DBus_CallMethodInternal(conn, node, path, interface, method, ap); + result = SDL_DBus_CallMethodInternal(conn, save_reply, node, path, interface, method, ap); va_end(ap); return result; } -bool SDL_DBus_CallMethod(const char *node, const char *path, const char *interface, const char *method, ...) +bool SDL_DBus_CallMethod(DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *method, ...) { bool result; va_list ap; va_start(ap, method); - result = SDL_DBus_CallMethodInternal(dbus.session_conn, node, path, interface, method, ap); + result = SDL_DBus_CallMethodInternal(dbus.session_conn, save_reply, node, path, interface, method, ap); va_end(ap); return result; } @@ -314,31 +319,6 @@ static bool SDL_DBus_CallVoidMethodInternal(DBusConnection *conn, const char *no return result; } -static bool SDL_DBus_CallWithBasicReply(DBusConnection *conn, DBusMessage *msg, const int expectedtype, void *result) -{ - bool retval = false; - - DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL); - if (reply) { - DBusMessageIter iter, actual_iter; - dbus.message_iter_init(reply, &iter); - if (dbus.message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) { - dbus.message_iter_recurse(&iter, &actual_iter); - } else { - actual_iter = iter; - } - - if (dbus.message_iter_get_arg_type(&actual_iter) == expectedtype) { - dbus.message_iter_get_basic(&actual_iter, result); - retval = true; - } - - dbus.message_unref(reply); - } - - return retval; -} - bool SDL_DBus_CallVoidMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) { bool result; @@ -359,7 +339,40 @@ bool SDL_DBus_CallVoidMethod(const char *node, const char *path, const char *int return result; } -bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result) +static bool SDL_DBus_CallWithBasicReply(DBusConnection *conn, DBusMessage **save_reply, DBusMessage *msg, const int expectedtype, void *result) +{ + bool retval = false; + + // Make sure we're not looking up strings here, otherwise we'd have to save and return the reply + SDL_assert(save_reply == NULL || *save_reply == NULL); + SDL_assert(save_reply != NULL || dbus.type_is_fixed(expectedtype)); + + DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL); + if (reply) { + DBusMessageIter iter, actual_iter; + dbus.message_iter_init(reply, &iter); + if (dbus.message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) { + dbus.message_iter_recurse(&iter, &actual_iter); + } else { + actual_iter = iter; + } + + if (dbus.message_iter_get_arg_type(&actual_iter) == expectedtype) { + dbus.message_iter_get_basic(&actual_iter, result); + retval = true; + } + + if (save_reply) { + *save_reply = reply; + } else { + dbus.message_unref(reply); + } + } + + return retval; +} + +bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result) { bool retval = false; @@ -367,7 +380,7 @@ bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, DBusMessage *msg = dbus.message_new_method_call(node, path, "org.freedesktop.DBus.Properties", "Get"); if (msg) { if (dbus.message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) { - retval = SDL_DBus_CallWithBasicReply(conn, msg, expectedtype, result); + retval = SDL_DBus_CallWithBasicReply(conn, save_reply, msg, expectedtype, result); } dbus.message_unref(msg); } @@ -376,9 +389,18 @@ bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, return retval; } -bool SDL_DBus_QueryProperty(const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result) +bool SDL_DBus_QueryProperty(DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result) { - return SDL_DBus_QueryPropertyOnConnection(dbus.session_conn, node, path, interface, property, expectedtype, result); + return SDL_DBus_QueryPropertyOnConnection(dbus.session_conn, save_reply, node, path, interface, property, expectedtype, result); +} + +void SDL_DBus_FreeReply(DBusMessage **saved_reply) +{ + DBusMessage *reply = *saved_reply; + if (reply) { + dbus.message_unref(reply); + *saved_reply = NULL; + } } void SDL_DBus_ScreensaverTickle(void) @@ -473,7 +495,7 @@ bool SDL_DBus_ScreensaverInhibit(bool inhibit) DBusMessage *msg; bool result = false; const char *key = "reason"; - const char *reply = NULL; + const char *reply_path = NULL; const char *reason = SDL_GetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME); if (!reason || !reason[0]) { reason = default_inhibit_reason; @@ -497,11 +519,12 @@ bool SDL_DBus_ScreensaverInhibit(bool inhibit) return false; } - if (SDL_DBus_CallWithBasicReply(dbus.session_conn, msg, DBUS_TYPE_OBJECT_PATH, &reply)) { - inhibit_handle = SDL_strdup(reply); + DBusMessage *reply = NULL; + if (SDL_DBus_CallWithBasicReply(dbus.session_conn, &reply, msg, DBUS_TYPE_OBJECT_PATH, &reply_path)) { + inhibit_handle = SDL_strdup(reply_path); result = true; } - + SDL_DBus_FreeReply(&reply); dbus.message_unref(msg); return result; } else { @@ -523,7 +546,7 @@ bool SDL_DBus_ScreensaverInhibit(bool inhibit) reason = default_inhibit_reason; } - if (!SDL_DBus_CallMethod(bus_name, path, interface, "Inhibit", + if (!SDL_DBus_CallMethod(NULL, bus_name, path, interface, "Inhibit", DBUS_TYPE_STRING, &app, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID, DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) { return false; diff --git a/src/core/linux/SDL_dbus.h b/src/core/linux/SDL_dbus.h index ca2c96abf0..83b11367c0 100644 --- a/src/core/linux/SDL_dbus.h +++ b/src/core/linux/SDL_dbus.h @@ -64,6 +64,7 @@ typedef struct SDL_DBusContext dbus_bool_t (*connection_read_write)(DBusConnection *, int); dbus_bool_t (*connection_read_write_dispatch)(DBusConnection *, int); DBusDispatchStatus (*connection_dispatch)(DBusConnection *); + dbus_bool_t (*type_is_fixed)(int); dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); dbus_bool_t (*message_has_path)(DBusMessage *, const char *); DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *); @@ -100,14 +101,19 @@ extern void SDL_DBus_Quit(void); extern SDL_DBusContext *SDL_DBus_GetContext(void); // These use the built-in Session connection. -extern bool SDL_DBus_CallMethod(const char *node, const char *path, const char *interface, const char *method, ...); +extern bool SDL_DBus_CallMethod(DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *method, ...); extern bool SDL_DBus_CallVoidMethod(const char *node, const char *path, const char *interface, const char *method, ...); -extern bool SDL_DBus_QueryProperty(const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result); +// save_reply must be non-NULL if it's a string property +extern bool SDL_DBus_QueryProperty(DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result); // These use whatever connection you like. -extern bool SDL_DBus_CallMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...); +extern bool SDL_DBus_CallMethodOnConnection(DBusConnection *conn, DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *method, ...); extern bool SDL_DBus_CallVoidMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...); -extern bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result); +// save_reply must be non-NULL if it's a string property +extern bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, DBusMessage **save_reply, const char *node, const char *path, const char *interface, const char *property, int expectedtype, void *result); + +// Used to free any reply returned from SDL_DBus_CallMethod() and SDL_DBus_QueryProperty() +extern void SDL_DBus_FreeReply(DBusMessage **saved_reply); extern void SDL_DBus_ScreensaverTickle(void); extern bool SDL_DBus_ScreensaverInhibit(bool inhibit); diff --git a/src/core/linux/SDL_fcitx.c b/src/core/linux/SDL_fcitx.c index d1222f76bd..d47b44e86f 100644 --- a/src/core/linux/SDL_fcitx.c +++ b/src/core/linux/SDL_fcitx.c @@ -370,7 +370,7 @@ bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, bool down) return false; } - if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent", + if (SDL_DBus_CallMethod(NULL, FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent", DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID, DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) { if (handled) { diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index 0b9873445f..e018d10427 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -426,6 +426,7 @@ static void SDLCALL IBus_SetCapabilities(void *data, const char *name, const cha static bool IBus_SetupConnection(SDL_DBusContext *dbus, const char *addr) { const char *client_name = "SDL3_Application"; + DBusMessage *reply = NULL; const char *path = NULL; bool result = false; DBusObjectPathVTable ibus_vtable; @@ -442,7 +443,7 @@ static bool IBus_SetupConnection(SDL_DBusContext *dbus, const char *addr) ibus_input_interface = IBUS_PORTAL_INPUT_INTERFACE; ibus_conn = dbus->session_conn; - result = SDL_DBus_CallMethodOnConnection(ibus_conn, ibus_service, IBUS_PATH, ibus_interface, "CreateInputContext", + result = SDL_DBus_CallMethodOnConnection(ibus_conn, &reply, ibus_service, IBUS_PATH, ibus_interface, "CreateInputContext", DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); if (!result) { @@ -465,7 +466,7 @@ static bool IBus_SetupConnection(SDL_DBusContext *dbus, const char *addr) dbus->connection_flush(ibus_conn); - result = SDL_DBus_CallMethodOnConnection(ibus_conn, ibus_service, IBUS_PATH, ibus_interface, "CreateInputContext", + result = SDL_DBus_CallMethodOnConnection(ibus_conn, &reply, ibus_service, IBUS_PATH, ibus_interface, "CreateInputContext", DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); } else { @@ -483,6 +484,7 @@ static bool IBus_SetupConnection(SDL_DBusContext *dbus, const char *addr) dbus->connection_try_register_object_path(ibus_conn, input_ctx_path, &ibus_vtable, dbus, NULL); dbus->connection_flush(ibus_conn); } + SDL_DBus_FreeReply(&reply); SDL_Window *window = SDL_GetKeyboardFocus(); if (SDL_TextInputActive(window)) { @@ -669,7 +671,7 @@ bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, bool down) if (!down) { mods |= (1 << 30); // IBUS_RELEASE_MASK } - if (!SDL_DBus_CallMethodOnConnection(ibus_conn, ibus_service, input_ctx_path, ibus_input_interface, "ProcessKeyEvent", + if (!SDL_DBus_CallMethodOnConnection(ibus_conn, NULL, ibus_service, input_ctx_path, ibus_input_interface, "ProcessKeyEvent", DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID, DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) { result = 0; diff --git a/src/core/linux/SDL_threadprio.c b/src/core/linux/SDL_threadprio.c index 2085378671..68b11911a1 100644 --- a/src/core/linux/SDL_threadprio.c +++ b/src/core/linux/SDL_threadprio.c @@ -70,7 +70,7 @@ static Sint64 rtkit_max_rttime_usec = 200000; static bool realtime_portal_supported(DBusConnection *conn) { Sint64 res; - return SDL_DBus_QueryPropertyOnConnection(conn, XDG_PORTAL_DBUS_NODE, XDG_PORTAL_DBUS_PATH, XDG_PORTAL_DBUS_INTERFACE, + return SDL_DBus_QueryPropertyOnConnection(conn, NULL, XDG_PORTAL_DBUS_NODE, XDG_PORTAL_DBUS_PATH, XDG_PORTAL_DBUS_INTERFACE, "RTTimeUSecMax", DBUS_TYPE_INT64, &res); } @@ -111,19 +111,19 @@ static void rtkit_initialize(void) dbus_conn = get_rtkit_dbus_connection(); // Try getting minimum nice level: this is often greater than PRIO_MIN (-20). - if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MinNiceLevel", + if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, NULL, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MinNiceLevel", DBUS_TYPE_INT32, &rtkit_min_nice_level)) { rtkit_min_nice_level = -20; } // Try getting maximum realtime priority: this can be less than the POSIX default (99). - if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MaxRealtimePriority", + if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, NULL, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MaxRealtimePriority", DBUS_TYPE_INT32, &rtkit_max_realtime_priority)) { rtkit_max_realtime_priority = 99; } // Try getting maximum rttime allowed by rtkit: exceeding this value will result in SIGKILL - if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "RTTimeUSecMax", + if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, NULL, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "RTTimeUSecMax", DBUS_TYPE_INT64, &rtkit_max_rttime_usec)) { rtkit_max_rttime_usec = 200000; } @@ -202,10 +202,10 @@ static bool rtkit_setpriority_nice(pid_t thread, int nice_level) nice = rtkit_min_nice_level; } - if (!dbus_conn || !SDL_DBus_CallMethodOnConnection(dbus_conn, - rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MakeThreadHighPriorityWithPID", - DBUS_TYPE_UINT64, &pid, DBUS_TYPE_UINT64, &tid, DBUS_TYPE_INT32, &nice, DBUS_TYPE_INVALID, - DBUS_TYPE_INVALID)) { + if (!dbus_conn || !SDL_DBus_CallMethodOnConnection(dbus_conn, NULL, + rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MakeThreadHighPriorityWithPID", + DBUS_TYPE_UINT64, &pid, DBUS_TYPE_UINT64, &tid, DBUS_TYPE_INT32, &nice, DBUS_TYPE_INVALID, + DBUS_TYPE_INVALID)) { return false; } return true; @@ -233,10 +233,10 @@ static bool rtkit_setpriority_realtime(pid_t thread, int rt_priority) // go through to determine whether it really needs to fail or not. rtkit_initialize_realtime_thread(); - if (!dbus_conn || !SDL_DBus_CallMethodOnConnection(dbus_conn, - rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MakeThreadRealtimeWithPID", - DBUS_TYPE_UINT64, &pid, DBUS_TYPE_UINT64, &tid, DBUS_TYPE_UINT32, &priority, DBUS_TYPE_INVALID, - DBUS_TYPE_INVALID)) { + if (!dbus_conn || !SDL_DBus_CallMethodOnConnection(dbus_conn, NULL, + rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MakeThreadRealtimeWithPID", + DBUS_TYPE_UINT64, &pid, DBUS_TYPE_UINT64, &tid, DBUS_TYPE_UINT32, &priority, DBUS_TYPE_INVALID, + DBUS_TYPE_INVALID)) { return false; } return true; diff --git a/src/power/linux/SDL_syspower.c b/src/power/linux/SDL_syspower.c index dc87f88a90..88e7b481ec 100644 --- a/src/power/linux/SDL_syspower.c +++ b/src/power/linux/SDL_syspower.c @@ -536,17 +536,17 @@ static void check_upower_device(DBusConnection *conn, const char *path, SDL_Powe Sint64 si64 = 0; double d = 0.0; - if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Type", DBUS_TYPE_UINT32, &ui32)) { + if (!SDL_DBus_QueryPropertyOnConnection(conn, NULL, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Type", DBUS_TYPE_UINT32, &ui32)) { return; // Don't know _what_ we're looking at. Give up on it. } else if (ui32 != 2) { // 2==Battery return; // we don't care about UPS and such. - } else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "PowerSupply", DBUS_TYPE_BOOLEAN, &ui32)) { + } else if (!SDL_DBus_QueryPropertyOnConnection(conn, NULL, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "PowerSupply", DBUS_TYPE_BOOLEAN, &ui32)) { return; } else if (!ui32) { return; // we don't care about random devices with batteries, like wireless controllers, etc } - if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) { + if (!SDL_DBus_QueryPropertyOnConnection(conn, NULL, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) { return; } if (!ui32) { @@ -555,9 +555,11 @@ static void check_upower_device(DBusConnection *conn, const char *path, SDL_Powe /* Get updated information on the battery status * This can occasionally fail, and we'll just return slightly stale data in that case */ - SDL_DBus_CallMethodOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Refresh", DBUS_TYPE_INVALID, DBUS_TYPE_INVALID); + SDL_DBus_CallMethodOnConnection(conn, NULL, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Refresh", + DBUS_TYPE_INVALID, + DBUS_TYPE_INVALID); - if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) { + if (!SDL_DBus_QueryPropertyOnConnection(conn, NULL, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) { st = SDL_POWERSTATE_UNKNOWN; // uh oh } else if (ui32 == 1) { // 1 == charging st = SDL_POWERSTATE_CHARGING; @@ -578,14 +580,14 @@ static void check_upower_device(DBusConnection *conn, const char *path, SDL_Powe } } - if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Percentage", DBUS_TYPE_DOUBLE, &d)) { + if (!SDL_DBus_QueryPropertyOnConnection(conn, NULL, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Percentage", DBUS_TYPE_DOUBLE, &d)) { pct = -1; // some old/cheap batteries don't set this property. } else { pct = (int)d; pct = (pct > 100) ? 100 : pct; // clamp between 0%, 100% } - if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "TimeToEmpty", DBUS_TYPE_INT64, &si64)) { + if (!SDL_DBus_QueryPropertyOnConnection(conn, NULL, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "TimeToEmpty", DBUS_TYPE_INT64, &si64)) { secs = -1; } else { secs = (int)si64; @@ -620,6 +622,7 @@ bool SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *state, int *s #ifdef SDL_USE_LIBDBUS SDL_DBusContext *dbus = SDL_DBus_GetContext(); + DBusMessage *reply = NULL; char **paths = NULL; char *path = NULL; int i, numpaths = 0; @@ -628,22 +631,20 @@ bool SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *state, int *s return false; // try a different approach than UPower. } - if (SDL_DBus_CallMethodOnConnection(dbus->system_conn, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE, "GetDisplayDevice", DBUS_TYPE_INVALID, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { + if (SDL_DBus_CallMethodOnConnection(dbus->system_conn, &reply, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE, "GetDisplayDevice", + DBUS_TYPE_INVALID, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { result = true; // Clearly we can use this interface. *state = SDL_POWERSTATE_NO_BATTERY; // assume we're just plugged in. *seconds = -1; *percent = -1; - // Make a copy of the path before making more dbus calls - path = SDL_strdup(path); - if (!path) { - // Out of memory, try to do something else - return false; - } check_upower_device(dbus->system_conn, path, state, seconds, percent); - SDL_free(path); + SDL_DBus_FreeReply(&reply); - } else if (SDL_DBus_CallMethodOnConnection(dbus->system_conn, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE, "EnumerateDevices", DBUS_TYPE_INVALID, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &numpaths, DBUS_TYPE_INVALID)) { + } else if (SDL_DBus_CallMethodOnConnection(dbus->system_conn, NULL, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE, "EnumerateDevices", + DBUS_TYPE_INVALID, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &numpaths, DBUS_TYPE_INVALID)) { result = true; // Clearly we can use this interface. *state = SDL_POWERSTATE_NO_BATTERY; // assume we're just plugged in. *seconds = -1;