mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
293 lines
8.3 KiB
C
293 lines
8.3 KiB
C
#include "common/dbus.h"
|
|
|
|
#ifdef FF_HAVE_DBUS
|
|
|
|
#include "common/thread.h"
|
|
#include "common/stringUtils.h"
|
|
|
|
static bool loadLibSymbols(FFDBusLibrary* lib)
|
|
{
|
|
FF_LIBRARY_LOAD(dbus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
|
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)
|
|
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)
|
|
dbus = NULL; // don't auto dlclose
|
|
return true;
|
|
}
|
|
|
|
static const FFDBusLibrary* loadLib(void)
|
|
{
|
|
static FFDBusLibrary lib;
|
|
static bool loaded = false;
|
|
static bool loadSuccess = false;
|
|
|
|
if(!loaded)
|
|
{
|
|
loaded = true;
|
|
loadSuccess = loadLibSymbols(&lib);
|
|
}
|
|
|
|
return loadSuccess ? &lib : NULL;
|
|
}
|
|
|
|
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data)
|
|
{
|
|
data->lib = loadLib();
|
|
if(data->lib == NULL)
|
|
return "Failed to load DBus library";
|
|
|
|
data->connection = data->lib->ffdbus_bus_get(busType, NULL);
|
|
if(data->connection == NULL)
|
|
return "Failed to connect to DBus";
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result)
|
|
{
|
|
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
|
|
|
if(argType == DBUS_TYPE_STRING || argType == DBUS_TYPE_OBJECT_PATH)
|
|
{
|
|
const char* value = NULL;
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
|
|
|
if(!ffStrSet(value))
|
|
return false;
|
|
|
|
ffStrbufAppendS(result, value);
|
|
return true;
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
if(argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY)
|
|
return false;
|
|
|
|
DBusMessageIter subIter;
|
|
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
|
|
|
if(argType == DBUS_TYPE_VARIANT)
|
|
return ffDBusGetString(dbus, &subIter, result);
|
|
|
|
//At this point we have an array
|
|
|
|
bool foundAValue = false;
|
|
|
|
while(true)
|
|
{
|
|
if(ffDBusGetString(dbus, &subIter, result))
|
|
{
|
|
foundAValue = true;
|
|
ffStrbufAppendS(result, ", ");
|
|
}
|
|
|
|
if(!dbus->lib->ffdbus_message_iter_next(&subIter))
|
|
break;
|
|
else
|
|
continue;
|
|
}
|
|
|
|
if(foundAValue)
|
|
ffStrbufSubstrBefore(result, result->length - 2);
|
|
|
|
return foundAValue;
|
|
}
|
|
|
|
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result)
|
|
{
|
|
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
|
|
|
if(argType == DBUS_TYPE_BOOLEAN)
|
|
{
|
|
dbus_bool_t value = 0;
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
|
*result = value != 0;
|
|
return true;
|
|
}
|
|
|
|
if(argType != DBUS_TYPE_VARIANT)
|
|
return false;
|
|
|
|
DBusMessageIter subIter;
|
|
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
|
return ffDBusGetBool(dbus, &subIter, result);
|
|
}
|
|
|
|
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result)
|
|
{
|
|
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
|
|
|
if(argType == DBUS_TYPE_BYTE)
|
|
{
|
|
uint8_t value = 0;
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
|
*result = value;
|
|
return true;
|
|
}
|
|
|
|
if(argType == DBUS_TYPE_UINT16)
|
|
{
|
|
uint16_t value = 0;
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
|
*result = value;
|
|
return true;
|
|
}
|
|
|
|
if(argType == DBUS_TYPE_UINT32)
|
|
{
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
|
|
return true;
|
|
}
|
|
|
|
if(argType != DBUS_TYPE_VARIANT)
|
|
return false;
|
|
|
|
DBusMessageIter subIter;
|
|
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
|
return ffDBusGetUint(dbus, &subIter, result);
|
|
}
|
|
|
|
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result)
|
|
{
|
|
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
|
|
|
if(argType == DBUS_TYPE_INT16)
|
|
{
|
|
int16_t value = 0;
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
|
*result = value;
|
|
return true;
|
|
}
|
|
|
|
if(argType == DBUS_TYPE_INT32)
|
|
{
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
|
|
return true;
|
|
}
|
|
|
|
if(argType == DBUS_TYPE_BYTE)
|
|
{
|
|
uint8_t value = 0;
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
|
*result = value;
|
|
return true;
|
|
}
|
|
|
|
if(argType == DBUS_TYPE_UINT16)
|
|
{
|
|
uint16_t value = 0;
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
|
*result = (int16_t) value;
|
|
return true;
|
|
}
|
|
|
|
if(argType == DBUS_TYPE_UINT32)
|
|
{
|
|
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
|
|
return true;
|
|
}
|
|
|
|
if(argType != DBUS_TYPE_VARIANT)
|
|
return false;
|
|
|
|
DBusMessageIter subIter;
|
|
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
|
return ffDBusGetInt(dbus, &subIter, result);
|
|
}
|
|
|
|
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2)
|
|
{
|
|
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, interface, method);
|
|
if(message == NULL)
|
|
return NULL;
|
|
|
|
if (arg1)
|
|
{
|
|
if (arg2)
|
|
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_STRING, &arg2, DBUS_TYPE_INVALID);
|
|
else
|
|
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_INVALID);
|
|
}
|
|
|
|
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
|
|
|
|
dbus->lib->ffdbus_message_unref(message);
|
|
|
|
return reply;
|
|
}
|
|
|
|
DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property)
|
|
{
|
|
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, "org.freedesktop.DBus.Properties", "Get");
|
|
if(message == NULL)
|
|
return NULL;
|
|
|
|
dbus->lib->ffdbus_message_append_args(message,
|
|
DBUS_TYPE_STRING, &interface,
|
|
DBUS_TYPE_STRING, &property,
|
|
DBUS_TYPE_INVALID);
|
|
|
|
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
|
|
|
|
dbus->lib->ffdbus_message_unref(message);
|
|
|
|
return reply;
|
|
}
|
|
|
|
bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result)
|
|
{
|
|
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
|
|
if(reply == NULL)
|
|
return false;
|
|
|
|
DBusMessageIter rootIterator;
|
|
if(!dbus->lib->ffdbus_message_iter_init(reply, &rootIterator))
|
|
{
|
|
dbus->lib->ffdbus_message_unref(reply);
|
|
return false;
|
|
}
|
|
|
|
bool ret = ffDBusGetString(dbus, &rootIterator, result);
|
|
|
|
dbus->lib->ffdbus_message_unref(reply);
|
|
|
|
return ret;
|
|
}
|
|
|
|
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);
|
|
if(reply == NULL)
|
|
return false;
|
|
|
|
DBusMessageIter rootIterator;
|
|
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;
|
|
}
|
|
|
|
#endif //FF_HAVE_DBUS
|