aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/tray/dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/tray/dbus.c')
-rw-r--r--swaybar/tray/dbus.c102
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 */ 139struct async_prop_data {
140 char const *sig;
141 void(*callback)(DBusMessageIter *, void *, enum property_status);
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 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
186bail:
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
195bool 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
202bool 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
140void dispatch_dbus() { 240void dispatch_dbus() {
141 if (!should_dispatch || !conn) { 241 if (!should_dispatch || !conn) {