From 87035380e33c7da10b53c6da713c56f3d89a1577 Mon Sep 17 00:00:00 2001 From: Calvin Lee Date: Thu, 9 Nov 2017 12:58:32 -0700 Subject: Add `dbus_get_prop_async` utility This drastically reduces the amount of boilerplate needed to get a property from a bus object. --- swaybar/tray/dbus.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) (limited to 'swaybar/tray/dbus.c') diff --git a/swaybar/tray/dbus.c b/swaybar/tray/dbus.c index 46a1c807..4439fb83 100644 --- a/swaybar/tray/dbus.c +++ b/swaybar/tray/dbus.c @@ -136,7 +136,58 @@ static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_s } } -/* Public functions below */ +struct async_prop_data { + char const *sig; + void(*callback)(DBusMessageIter *, void *); + void *usr_data; +}; + +static void get_prop_callback(DBusPendingCall *pending, void *_data) { + struct async_prop_data *data = _data; + + DBusMessage *reply = dbus_pending_call_steal_reply(pending); + + if (!reply) { + sway_log(L_INFO, "Got no icon name reply from item"); + goto bail; + } + + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + char *msg; + + dbus_message_get_args(reply, NULL, + DBUS_TYPE_STRING, &msg, + DBUS_TYPE_INVALID); + + sway_log(L_INFO, "Failure to get property: %s", msg); + goto bail; + } + + DBusMessageIter iter; + DBusMessageIter variant; + + dbus_message_iter_init(reply, &iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + sway_log(L_ERROR, "Property relpy type incorrect"); + goto bail; + } + dbus_message_iter_recurse(&iter, &variant); + + if (!dbus_message_iter_check_signature(&variant, data->sig)) { + sway_log(L_INFO, "Property returned has incorrect signatue."); + goto bail; + } + + data->callback(&variant, data->usr_data); + +bail: + if (reply) { + dbus_message_unref(reply); + } + dbus_pending_call_unref(pending); +} + +/* Public functions below -- see header for docs*/ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) { char *msg_sig = dbus_message_iter_get_signature(iter); @@ -145,6 +196,43 @@ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) { return (result == 0); } +bool dbus_get_prop_async(const char *destination, + const char *path, const char *iface, + const char *prop, const char *expected_signature, + void(*callback)(DBusMessageIter *, void *), void *usr_data) { + struct async_prop_data *data = malloc(sizeof(struct async_prop_data)); + if (!data) { + return false; + } + DBusPendingCall *pending; + DBusMessage *message = dbus_message_new_method_call( + destination, path, + "org.freedesktop.DBus.Properties", + "Get"); + + dbus_message_append_args(message, + DBUS_TYPE_STRING, &iface, + DBUS_TYPE_STRING, &prop, + DBUS_TYPE_INVALID); + + bool status = + dbus_connection_send_with_reply(conn, message, &pending, -1); + + dbus_message_unref(message); + + if (!(pending || status)) { + sway_log(L_ERROR, "Could not get property"); + return false; + } + + data->sig = expected_signature; + data->callback = callback; + data->usr_data = usr_data; + dbus_pending_call_set_notify(pending, get_prop_callback, data, free); + + return true; +} + void dispatch_dbus() { if (!should_dispatch || !conn) { return; -- cgit v1.2.3-54-g00ecf