Repository: libsdl-org/SDL
File: src/core/linux/SDL_dbus.c (C)

Code before:
    }
}

static bool SDL_DBus_AppendDictWithKeysAndValues(DBusMessageIter *iterInit, const char **keys, const char **values, int count)
{
    DBusMessageIter iterDict;

    if (!dbus.message_iter_open_container(iterInit, DBUS_TYPE_ARRAY, "{sv}", &iterDict)) {
        goto failed;
    }

    for (int i = 0; i < count; i++) {
        DBusMessageIter iterEntry, iterValue;
        const char *key = keys[i];
        const char *value = values[i];

        if (!dbus.message_iter_open_container(&iterDict, DBUS_TYPE_DICT_ENTRY, NULL, &iterEntry)) {
            goto failed;
        }

        if (!dbus.message_iter_append_basic(&iterEntry, DBUS_TYPE_STRING, &key)) {
            goto failed;
        }

        if (!dbus.message_iter_open_container(&iterEntry, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &iterValue)) {
            goto failed;
        }

        if (!dbus.message_iter_append_basic(&iterValue, DBUS_TYPE_STRING, &value)) {
            goto failed;
        }

        if (!dbus.message_iter_close_container(&iterEntry, &iterValue) || !dbus.message_iter_close_container(&iterDict, &iterEntry)) {
            goto failed;
        }
    }

    if (!dbus.message_iter_close_container(iterInit, &iterDict)) {
        goto failed;
    }

    return true;

failed:
    /* message_iter_abandon_container_if_open() and message_iter_abandon_container() might be
     * missing if libdbus is too old. Instead, we just return without cleaning up any eventual
     * open container */
    return false;
}

static bool SDL_DBus_AppendDictWithKeyValue(DBusMessageIter *iterInit, const char *key, const char *value)

Review comment (suggestion):
This naming seems odd to me: there's nothing special about replies or this function that mean that it can/should be used on replies, specifically. It could be used to clear/empty/reset any variable (or even struct member) that is known to be either null or an "owned" pointer to a `DBusMessage`, in an idempotent way, without either leaking the pointed-to message or leaving a dangling pointer behind.

The naming convention in libdbus (which was borrowed from GLib) is that functions like this have "clear" in the name, because conceptually the function is clearing a variable.

Prior art elsewhere is that this is basically the `reset()` method found on C++ smart pointers: it's behaving a bit like a `shared_ptr<DBusMessage>`.

Code after:
    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;

    if (conn) {
        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, save_reply, msg, expectedtype, result);
            }
            dbus.message_unref(msg);
        }
    }

    return retval;
}

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, 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)
{
    if (screensaver_cookie == 0 && !inhibit_handle) { // no need to tickle if we're inhibiting.
        // org.gnome.ScreenSaver is the legacy interface, but it'll either do nothing or just be a second harmless tickle on newer systems, so we leave it for now.
        SDL_DBus_CallVoidMethod("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver", "SimulateUserActivity", DBUS_TYPE_INVALID);
        SDL_DBus_CallVoidMethod("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver", "SimulateUserActivity", DBUS_TYPE_INVALID);
    }
}

static bool SDL_DBus_AppendDictWithKeysAndValues(DBusMessageIter *iterInit, const char **keys, const char **values, int count)
{
    DBusMessageIter iterDict;

    if (!dbus.message_iter_open_container(iterInit, DBUS_TYPE_ARRAY, "{sv}", &iterDict)) {
        goto failed;
    }