diff options
Diffstat (limited to 'swaybar/tray/dbus.c')
-rw-r--r-- | swaybar/tray/dbus.c | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/swaybar/tray/dbus.c b/swaybar/tray/dbus.c index 8e719fd9..08abf65c 100644 --- a/swaybar/tray/dbus.c +++ b/swaybar/tray/dbus.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #define _XOPEN_SOURCE 700 | 1 | #define _XOPEN_SOURCE 700 |
2 | #include <stdio.h> | 2 | #include <stdio.h> |
3 | #include <string.h> | ||
3 | #include <stdlib.h> | 4 | #include <stdlib.h> |
4 | #include <stdint.h> | 5 | #include <stdint.h> |
5 | #include <stdbool.h> | 6 | #include <stdbool.h> |
@@ -135,7 +136,106 @@ static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_s | |||
135 | } | 136 | } |
136 | } | 137 | } |
137 | 138 | ||
138 | /* Public functions below */ | 139 | struct async_prop_data { |
140 | char const *sig; | ||
141 | void(*callback)(DBusMessageIter *, void *, enum property_status); | ||
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 | data->callback(NULL, data->usr_data, PROP_ERROR); | ||
164 | goto bail; | ||
165 | } | ||
166 | |||
167 | DBusMessageIter iter; | ||
168 | DBusMessageIter variant; | ||
169 | |||
170 | dbus_message_iter_init(reply, &iter); | ||
171 | if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { | ||
172 | sway_log(L_ERROR, "Property relpy type incorrect"); | ||
173 | data->callback(NULL, data->usr_data, PROP_BAD_DATA); | ||
174 | goto bail; | ||
175 | } | ||
176 | dbus_message_iter_recurse(&iter, &variant); | ||
177 | |||
178 | if (!dbus_message_iter_check_signature(&variant, data->sig)) { | ||
179 | sway_log(L_INFO, "Property returned has incorrect signatue."); | ||
180 | data->callback(&variant, data->usr_data, PROP_WRONG_SIG); | ||
181 | goto bail; | ||
182 | } | ||
183 | |||
184 | data->callback(&variant, data->usr_data, PROP_EXISTS); | ||
185 | |||
186 | bail: | ||
187 | if (reply) { | ||
188 | dbus_message_unref(reply); | ||
189 | } | ||
190 | dbus_pending_call_unref(pending); | ||
191 | } | ||
192 | |||
193 | /* Public functions below -- see header for docs*/ | ||
194 | |||
195 | bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) { | ||
196 | char *msg_sig = dbus_message_iter_get_signature(iter); | ||
197 | int result = strcmp(msg_sig, sig); | ||
198 | dbus_free(msg_sig); | ||
199 | return (result == 0); | ||
200 | } | ||
201 | |||
202 | bool dbus_get_prop_async(const char *destination, | ||
203 | const char *path, const char *iface, | ||
204 | const char *prop, const char *expected_signature, | ||
205 | void(*callback)(DBusMessageIter *, void *, enum property_status), | ||
206 | void *usr_data) { | ||
207 | struct async_prop_data *data = malloc(sizeof(struct async_prop_data)); | ||
208 | if (!data) { | ||
209 | return false; | ||
210 | } | ||
211 | DBusPendingCall *pending; | ||
212 | DBusMessage *message = dbus_message_new_method_call( | ||
213 | destination, path, | ||
214 | "org.freedesktop.DBus.Properties", | ||
215 | "Get"); | ||
216 | |||
217 | dbus_message_append_args(message, | ||
218 | DBUS_TYPE_STRING, &iface, | ||
219 | DBUS_TYPE_STRING, &prop, | ||
220 | DBUS_TYPE_INVALID); | ||
221 | |||
222 | bool status = | ||
223 | dbus_connection_send_with_reply(conn, message, &pending, -1); | ||
224 | |||
225 | dbus_message_unref(message); | ||
226 | |||
227 | if (!(pending || status)) { | ||
228 | sway_log(L_ERROR, "Could not get property"); | ||
229 | return false; | ||
230 | } | ||
231 | |||
232 | data->sig = expected_signature; | ||
233 | data->callback = callback; | ||
234 | data->usr_data = usr_data; | ||
235 | dbus_pending_call_set_notify(pending, get_prop_callback, data, free); | ||
236 | |||
237 | return true; | ||
238 | } | ||
139 | 239 | ||
140 | void dispatch_dbus() { | 240 | void dispatch_dbus() { |
141 | if (!should_dispatch || !conn) { | 241 | if (!should_dispatch || !conn) { |