summaryrefslogtreecommitdiffstats
path: root/swaybar/tray/dbus.c
diff options
context:
space:
mode:
authorLibravatar Calvin Lee <cyrus296@gmail.com>2017-11-09 12:58:32 -0700
committerLibravatar Calvin Lee <cyrus296@gmail.com>2017-12-29 12:11:51 -0700
commit87035380e33c7da10b53c6da713c56f3d89a1577 (patch)
tree4b31ad282fe07227f5720928b1ba07715bc7ea48 /swaybar/tray/dbus.c
parentPlug memory `dbus_message_iter_get_signature` leak (diff)
downloadsway-87035380e33c7da10b53c6da713c56f3d89a1577.tar.gz
sway-87035380e33c7da10b53c6da713c56f3d89a1577.tar.zst
sway-87035380e33c7da10b53c6da713c56f3d89a1577.zip
Add `dbus_get_prop_async` utility
This drastically reduces the amount of boilerplate needed to get a property from a bus object.
Diffstat (limited to 'swaybar/tray/dbus.c')
-rw-r--r--swaybar/tray/dbus.c90
1 files changed, 89 insertions, 1 deletions
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
136 } 136 }
137} 137}
138 138
139/* Public functions below */ 139struct async_prop_data {
140 char const *sig;
141 void(*callback)(DBusMessageIter *, void *);
142 void *usr_data;
143};
144
145static void get_prop_callback(DBusPendingCall *pending, void *_data) {
146 struct async_prop_data *data = _data;
147
148 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
149
150 if (!reply) {
151 sway_log(L_INFO, "Got no icon name reply from item");
152 goto bail;
153 }
154
155 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
156 char *msg;
157
158 dbus_message_get_args(reply, NULL,
159 DBUS_TYPE_STRING, &msg,
160 DBUS_TYPE_INVALID);
161
162 sway_log(L_INFO, "Failure to get property: %s", msg);
163 goto bail;
164 }
165
166 DBusMessageIter iter;
167 DBusMessageIter variant;
168
169 dbus_message_iter_init(reply, &iter);
170 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
171 sway_log(L_ERROR, "Property relpy type incorrect");
172 goto bail;
173 }
174 dbus_message_iter_recurse(&iter, &variant);
175
176 if (!dbus_message_iter_check_signature(&variant, data->sig)) {
177 sway_log(L_INFO, "Property returned has incorrect signatue.");
178 goto bail;
179 }
180
181 data->callback(&variant, data->usr_data);
182
183bail:
184 if (reply) {
185 dbus_message_unref(reply);
186 }
187 dbus_pending_call_unref(pending);
188}
189
190/* Public functions below -- see header for docs*/
140 191
141bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) { 192bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) {
142 char *msg_sig = dbus_message_iter_get_signature(iter); 193 char *msg_sig = dbus_message_iter_get_signature(iter);
@@ -145,6 +196,43 @@ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) {
145 return (result == 0); 196 return (result == 0);
146} 197}
147 198
199bool dbus_get_prop_async(const char *destination,
200 const char *path, const char *iface,
201 const char *prop, const char *expected_signature,
202 void(*callback)(DBusMessageIter *, void *), void *usr_data) {
203 struct async_prop_data *data = malloc(sizeof(struct async_prop_data));
204 if (!data) {
205 return false;
206 }
207 DBusPendingCall *pending;
208 DBusMessage *message = dbus_message_new_method_call(
209 destination, path,
210 "org.freedesktop.DBus.Properties",
211 "Get");
212
213 dbus_message_append_args(message,
214 DBUS_TYPE_STRING, &iface,
215 DBUS_TYPE_STRING, &prop,
216 DBUS_TYPE_INVALID);
217
218 bool status =
219 dbus_connection_send_with_reply(conn, message, &pending, -1);
220
221 dbus_message_unref(message);
222
223 if (!(pending || status)) {
224 sway_log(L_ERROR, "Could not get property");
225 return false;
226 }
227
228 data->sig = expected_signature;
229 data->callback = callback;
230 data->usr_data = usr_data;
231 dbus_pending_call_set_notify(pending, get_prop_callback, data, free);
232
233 return true;
234}
235
148void dispatch_dbus() { 236void dispatch_dbus() {
149 if (!should_dispatch || !conn) { 237 if (!should_dispatch || !conn) {
150 return; 238 return;