Files
fastfetch/src/common/impl/dbus.c
T

290 lines
8.7 KiB
C
Raw Normal View History

2026-01-06 09:48:38 +08:00
#include "common/dbus.h"
2023-01-24 10:39:33 +01:00
2023-01-26 22:08:55 +01:00
#ifdef FF_HAVE_DBUS
#include "common/thread.h"
#include "common/stringUtils.h"
2023-01-24 10:39:33 +01:00
2026-03-29 09:28:49 +08:00
static bool loadLibSymbols(FFDBusLibrary* lib) {
2024-09-04 15:28:35 +08:00
FF_LIBRARY_LOAD(dbus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
2023-01-24 10:39:33 +01:00
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_append_args, false)
2023-01-24 10:39:33 +01:00
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_init, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_get_arg_type, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_get_basic, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_recurse, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_has_next, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_next, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_unref, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_send_with_reply_and_block, false)
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_connection_unref, false)
dbus = NULL; // don't auto dlclose
2023-01-24 10:39:33 +01:00
return true;
}
2026-03-29 09:28:49 +08:00
static const FFDBusLibrary* loadLib(void) {
2023-01-24 10:39:33 +01:00
static FFDBusLibrary lib;
static bool loaded = false;
static bool loadSuccess = false;
2026-03-29 09:28:49 +08:00
if (!loaded) {
2023-01-24 10:39:33 +01:00
loaded = true;
loadSuccess = loadLibSymbols(&lib);
2023-01-24 10:39:33 +01:00
}
return loadSuccess ? &lib : NULL;
}
2026-03-29 09:28:49 +08:00
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data) {
data->lib = loadLib();
2026-03-29 09:28:49 +08:00
if (data->lib == NULL) {
2023-01-24 10:39:33 +01:00
return "Failed to load DBus library";
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
data->connection = data->lib->ffdbus_bus_get(busType, NULL);
2026-03-29 09:28:49 +08:00
if (data->connection == NULL) {
2023-01-24 10:39:33 +01:00
return "Failed to connect to DBus";
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
return NULL;
}
2026-03-29 09:28:49 +08:00
void ffDBusDestroyData(FFDBusData* data) {
if (data->connection != NULL) {
data->lib->ffdbus_connection_unref(data->connection);
data->connection = NULL;
}
}
2026-03-29 09:28:49 +08:00
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result) {
2023-01-24 10:39:33 +01:00
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_STRING || argType == DBUS_TYPE_OBJECT_PATH) {
2023-01-24 10:39:33 +01:00
const char* value = NULL;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
2026-03-29 09:28:49 +08:00
if (!ffStrSet(value)) {
2023-01-24 10:39:33 +01:00
return false;
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
ffStrbufAppendS(result, value);
return true;
}
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_BYTE) {
uint8_t value;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
ffStrbufAppendC(result, (char) value);
return false; // Don't append a comma
}
2026-03-29 09:28:49 +08:00
if (argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY) {
2023-01-24 10:39:33 +01:00
return false;
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_VARIANT) {
return ffDBusGetString(dbus, &subIter, result);
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
2026-03-29 09:28:49 +08:00
// At this point we have an array
2023-01-24 10:39:33 +01:00
bool foundAValue = false;
2026-03-29 09:28:49 +08:00
while (true) {
if (ffDBusGetString(dbus, &subIter, result)) {
2023-01-24 10:39:33 +01:00
foundAValue = true;
ffStrbufAppendS(result, ", ");
}
2026-03-29 09:28:49 +08:00
if (!dbus->lib->ffdbus_message_iter_next(&subIter)) {
break;
2026-03-29 09:28:49 +08:00
} else {
continue;
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
}
2026-03-29 09:28:49 +08:00
if (foundAValue) {
2023-01-24 10:39:33 +01:00
ffStrbufSubstrBefore(result, result->length - 2);
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
return foundAValue;
}
2026-03-29 09:28:49 +08:00
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result) {
2023-01-24 10:39:33 +01:00
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_BOOLEAN) {
2023-01-24 10:39:33 +01:00
dbus_bool_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value != 0;
return true;
}
2026-03-29 09:28:49 +08:00
if (argType != DBUS_TYPE_VARIANT) {
2023-01-24 10:39:33 +01:00
return false;
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
return ffDBusGetBool(dbus, &subIter, result);
}
2026-03-29 09:28:49 +08:00
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result) {
2023-01-24 10:39:33 +01:00
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_BYTE) {
uint8_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
2023-01-24 10:39:33 +01:00
return true;
}
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_UINT16) {
uint16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_UINT32) {
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
2026-03-29 09:28:49 +08:00
if (argType != DBUS_TYPE_VARIANT) {
return false;
2026-03-29 09:28:49 +08:00
}
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
return ffDBusGetUint(dbus, &subIter, result);
}
2026-03-29 09:28:49 +08:00
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result) {
2025-09-04 09:35:52 +08:00
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_INT16) {
2025-09-04 09:35:52 +08:00
int16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_INT32) {
2025-09-04 09:35:52 +08:00
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_BYTE) {
2025-09-04 09:35:52 +08:00
uint8_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_UINT16) {
2025-09-04 09:35:52 +08:00
uint16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = (int16_t) value;
return true;
}
2026-03-29 09:28:49 +08:00
if (argType == DBUS_TYPE_UINT32) {
2025-09-04 09:35:52 +08:00
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
2026-03-29 09:28:49 +08:00
if (argType != DBUS_TYPE_VARIANT) {
2025-09-04 09:35:52 +08:00
return false;
2026-03-29 09:28:49 +08:00
}
2025-09-04 09:35:52 +08:00
DBusMessageIter subIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
return ffDBusGetInt(dbus, &subIter, result);
}
2026-03-29 09:28:49 +08:00
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2) {
2023-01-24 10:39:33 +01:00
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, interface, method);
2026-03-29 09:28:49 +08:00
if (message == NULL) {
2023-01-24 10:39:33 +01:00
return NULL;
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
2026-03-29 09:28:49 +08:00
if (arg1) {
if (arg2) {
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_STRING, &arg2, DBUS_TYPE_INVALID);
2026-03-29 09:28:49 +08:00
} else {
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_INVALID);
2026-03-29 09:28:49 +08:00
}
}
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
2023-01-24 10:39:33 +01:00
dbus->lib->ffdbus_message_unref(message);
return reply;
}
2026-03-29 09:28:49 +08:00
DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property) {
2023-01-24 10:39:33 +01:00
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, "org.freedesktop.DBus.Properties", "Get");
2026-03-29 09:28:49 +08:00
if (message == NULL) {
2023-01-24 10:39:33 +01:00
return NULL;
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
dbus->lib->ffdbus_message_append_args(message,
2026-03-29 09:28:49 +08:00
DBUS_TYPE_STRING,
&interface,
DBUS_TYPE_STRING,
&property,
DBUS_TYPE_INVALID);
2023-01-24 10:39:33 +01:00
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
2023-01-24 10:39:33 +01:00
dbus->lib->ffdbus_message_unref(message);
return reply;
}
2026-03-29 09:28:49 +08:00
bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result) {
2023-01-24 10:39:33 +01:00
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
2026-03-29 09:28:49 +08:00
if (reply == NULL) {
2024-04-17 19:00:45 +08:00
return false;
2026-03-29 09:28:49 +08:00
}
2023-01-24 10:39:33 +01:00
DBusMessageIter rootIterator;
2026-03-29 09:28:49 +08:00
if (!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator)) {
2023-01-24 10:39:33 +01:00
dbus->lib->ffdbus_message_unref(reply);
2024-04-17 19:00:45 +08:00
return false;
2023-01-24 10:39:33 +01:00
}
bool ret = ffDBusGetString(dbus, &rootIterator, result);
2023-01-24 10:39:33 +01:00
dbus->lib->ffdbus_message_unref(reply);
2024-04-17 19:00:45 +08:00
return ret;
2023-01-24 10:39:33 +01:00
}
2023-01-26 22:08:55 +01:00
2026-03-29 09:28:49 +08:00
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result) {
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
2026-03-29 09:28:49 +08:00
if (reply == NULL) {
return false;
2026-03-29 09:28:49 +08:00
}
DBusMessageIter rootIterator;
2026-03-29 09:28:49 +08:00
if (!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator)) {
dbus->lib->ffdbus_message_unref(reply);
return false;
}
bool ret = ffDBusGetUint(dbus, &rootIterator, result);
dbus->lib->ffdbus_message_unref(reply);
return ret;
}
2026-03-29 09:28:49 +08:00
#endif // FF_HAVE_DBUS