diff options
author | Calvin Lee <cyrus296@gmail.com> | 2017-11-09 12:58:32 -0700 |
---|---|---|
committer | Calvin Lee <cyrus296@gmail.com> | 2017-12-29 12:11:51 -0700 |
commit | 87035380e33c7da10b53c6da713c56f3d89a1577 (patch) | |
tree | 4b31ad282fe07227f5720928b1ba07715bc7ea48 /swaybar/tray/dbus.c | |
parent | Plug memory `dbus_message_iter_get_signature` leak (diff) | |
download | sway-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.c | 90 |
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 */ | 139 | struct async_prop_data { |
140 | char const *sig; | ||
141 | void(*callback)(DBusMessageIter *, void *); | ||
142 | void *usr_data; | ||
143 | }; | ||
144 | |||
145 | static 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 | |||
183 | bail: | ||
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 | ||
141 | bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) { | 192 | bool 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 | ||
199 | bool 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 | |||
148 | void dispatch_dbus() { | 236 | void dispatch_dbus() { |
149 | if (!should_dispatch || !conn) { | 237 | if (!should_dispatch || !conn) { |
150 | return; | 238 | return; |