summaryrefslogtreecommitdiffstats
path: root/swaybar/ipc.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-28 23:04:20 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-29 22:11:08 -0400
commitcab1352801b62d1b8a12ca1c995cb24445ce4bc9 (patch)
treebc67373916c06d48700c4f69b8c2470a2f86887f /swaybar/ipc.c
parentAllow sway IPC clients to fall back to i3 socket (diff)
downloadsway-cab1352801b62d1b8a12ca1c995cb24445ce4bc9.tar.gz
sway-cab1352801b62d1b8a12ca1c995cb24445ce4bc9.tar.zst
sway-cab1352801b62d1b8a12ca1c995cb24445ce4bc9.zip
Start port of swaybar to layer shell
This starts up the event loop and wayland display and shims out the basic top level rendering concepts. Also includes some changes to incorporate pango into the 1.x codebase properly.
Diffstat (limited to 'swaybar/ipc.c')
-rw-r--r--swaybar/ipc.c410
1 files changed, 0 insertions, 410 deletions
diff --git a/swaybar/ipc.c b/swaybar/ipc.c
deleted file mode 100644
index 93d1219c..00000000
--- a/swaybar/ipc.c
+++ /dev/null
@@ -1,410 +0,0 @@
1#define _XOPEN_SOURCE 500
2#include <string.h>
3#include <strings.h>
4#include <json-c/json.h>
5#include "swaybar/config.h"
6#include "swaybar/ipc.h"
7#include "ipc-client.h"
8#include "list.h"
9#include "log.h"
10
11void ipc_send_workspace_command(const char *workspace_name) {
12 uint32_t size = strlen("workspace \"\"") + strlen(workspace_name) + 1;
13
14 char command[size];
15 sprintf(command, "workspace \"%s\"", workspace_name);
16
17 ipc_single_command(swaybar.ipc_socketfd, IPC_COMMAND, command, &size);
18}
19
20static void ipc_parse_config(struct config *config, const char *payload) {
21 json_object *bar_config = json_tokener_parse(payload);
22 json_object *markup, *mode, *hidden_bar, *position, *status_command;
23 json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers;
24 json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs;
25#ifdef ENABLE_TRAY
26 json_object *tray_output, *icon_theme, *tray_padding, *activate_button, *context_button;
27 json_object *secondary_button;
28 json_object_object_get_ex(bar_config, "tray_output", &tray_output);
29 json_object_object_get_ex(bar_config, "icon_theme", &icon_theme);
30 json_object_object_get_ex(bar_config, "tray_padding", &tray_padding);
31 json_object_object_get_ex(bar_config, "activate_button", &activate_button);
32 json_object_object_get_ex(bar_config, "context_button", &context_button);
33 json_object_object_get_ex(bar_config, "secondary_button", &secondary_button);
34#endif
35 json_object_object_get_ex(bar_config, "mode", &mode);
36 json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar);
37 json_object_object_get_ex(bar_config, "position", &position);
38 json_object_object_get_ex(bar_config, "status_command", &status_command);
39 json_object_object_get_ex(bar_config, "font", &font);
40 json_object_object_get_ex(bar_config, "bar_height", &bar_height);
41 json_object_object_get_ex(bar_config, "wrap_scroll", &wrap_scroll);
42 json_object_object_get_ex(bar_config, "workspace_buttons", &workspace_buttons);
43 json_object_object_get_ex(bar_config, "strip_workspace_numbers", &strip_workspace_numbers);
44 json_object_object_get_ex(bar_config, "binding_mode_indicator", &binding_mode_indicator);
45 json_object_object_get_ex(bar_config, "verbose", &verbose);
46 json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol);
47 json_object_object_get_ex(bar_config, "colors", &colors);
48 json_object_object_get_ex(bar_config, "outputs", &outputs);
49 json_object_object_get_ex(bar_config, "pango_markup", &markup);
50
51 if (status_command) {
52 free(config->status_command);
53 config->status_command = strdup(json_object_get_string(status_command));
54 }
55
56 if (position) {
57 config->position = parse_position(json_object_get_string(position));
58 }
59
60 if (font) {
61 free(config->font);
62 config->font = parse_font(json_object_get_string(font));
63 }
64
65 if (sep_symbol) {
66 free(config->sep_symbol);
67 config->sep_symbol = strdup(json_object_get_string(sep_symbol));
68 }
69
70 if (strip_workspace_numbers) {
71 config->strip_workspace_numbers = json_object_get_boolean(strip_workspace_numbers);
72 }
73
74 if (binding_mode_indicator) {
75 config->binding_mode_indicator = json_object_get_boolean(binding_mode_indicator);
76 }
77
78 if (wrap_scroll) {
79 config->wrap_scroll = json_object_get_boolean(wrap_scroll);
80 }
81
82 if (workspace_buttons) {
83 config->workspace_buttons = json_object_get_boolean(workspace_buttons);
84 }
85
86 if (bar_height) {
87 config->height = json_object_get_int(bar_height);
88 }
89
90 if (markup) {
91 config->pango_markup = json_object_get_boolean(markup);
92 }
93
94#ifdef ENABLE_TRAY
95 if (tray_output) {
96 free(config->tray_output);
97 config->tray_output = strdup(json_object_get_string(tray_output));
98 }
99
100 if (icon_theme) {
101 free(config->icon_theme);
102 config->icon_theme = strdup(json_object_get_string(icon_theme));
103 }
104
105 if (tray_padding) {
106 config->tray_padding = json_object_get_int(tray_padding);
107 }
108
109 if (activate_button) {
110 config->activate_button = json_object_get_int(activate_button);
111 }
112
113 if (context_button) {
114 config->context_button = json_object_get_int(context_button);
115 }
116
117 if (secondary_button) {
118 config->secondary_button = json_object_get_int(secondary_button);
119 }
120#endif
121
122 // free previous outputs list
123 int i;
124 for (i = 0; i < config->outputs->length; ++i) {
125 free(config->outputs->items[i]);
126 }
127 list_free(config->outputs);
128 config->outputs = create_list();
129
130 if (outputs) {
131 int length = json_object_array_length(outputs);
132 json_object *output;
133 const char *output_str;
134 for (i = 0; i < length; ++i) {
135 output = json_object_array_get_idx(outputs, i);
136 output_str = json_object_get_string(output);
137 if (strcmp("*", output_str) == 0) {
138 config->all_outputs = true;
139 break;
140 }
141 list_add(config->outputs, strdup(output_str));
142 }
143 } else {
144 config->all_outputs = true;
145 }
146
147 if (colors) {
148 json_object *background, *statusline, *separator;
149 json_object *focused_background, *focused_statusline, *focused_separator;
150 json_object *focused_workspace_border, *focused_workspace_bg, *focused_workspace_text;
151 json_object *inactive_workspace_border, *inactive_workspace_bg, *inactive_workspace_text;
152 json_object *active_workspace_border, *active_workspace_bg, *active_workspace_text;
153 json_object *urgent_workspace_border, *urgent_workspace_bg, *urgent_workspace_text;
154 json_object *binding_mode_border, *binding_mode_bg, *binding_mode_text;
155 json_object_object_get_ex(colors, "background", &background);
156 json_object_object_get_ex(colors, "statusline", &statusline);
157 json_object_object_get_ex(colors, "separator", &separator);
158 json_object_object_get_ex(colors, "focused_background", &focused_background);
159 json_object_object_get_ex(colors, "focused_statusline", &focused_statusline);
160 json_object_object_get_ex(colors, "focused_separator", &focused_separator);
161 json_object_object_get_ex(colors, "focused_workspace_border", &focused_workspace_border);
162 json_object_object_get_ex(colors, "focused_workspace_bg", &focused_workspace_bg);
163 json_object_object_get_ex(colors, "focused_workspace_text", &focused_workspace_text);
164 json_object_object_get_ex(colors, "active_workspace_border", &active_workspace_border);
165 json_object_object_get_ex(colors, "active_workspace_bg", &active_workspace_bg);
166 json_object_object_get_ex(colors, "active_workspace_text", &active_workspace_text);
167 json_object_object_get_ex(colors, "inactive_workspace_border", &inactive_workspace_border);
168 json_object_object_get_ex(colors, "inactive_workspace_bg", &inactive_workspace_bg);
169 json_object_object_get_ex(colors, "inactive_workspace_text", &inactive_workspace_text);
170 json_object_object_get_ex(colors, "urgent_workspace_border", &urgent_workspace_border);
171 json_object_object_get_ex(colors, "urgent_workspace_bg", &urgent_workspace_bg);
172 json_object_object_get_ex(colors, "urgent_workspace_text", &urgent_workspace_text);
173 json_object_object_get_ex(colors, "binding_mode_border", &binding_mode_border);
174 json_object_object_get_ex(colors, "binding_mode_bg", &binding_mode_bg);
175 json_object_object_get_ex(colors, "binding_mode_text", &binding_mode_text);
176 if (background) {
177 config->colors.background = parse_color(json_object_get_string(background));
178 }
179
180 if (statusline) {
181 config->colors.statusline = parse_color(json_object_get_string(statusline));
182 }
183
184 if (separator) {
185 config->colors.separator = parse_color(json_object_get_string(separator));
186 }
187
188 if (focused_background) {
189 config->colors.focused_background = parse_color(json_object_get_string(focused_background));
190 }
191
192 if (focused_statusline) {
193 config->colors.focused_statusline = parse_color(json_object_get_string(focused_statusline));
194 }
195
196 if (focused_separator) {
197 config->colors.focused_separator = parse_color(json_object_get_string(focused_separator));
198 }
199
200 if (focused_workspace_border) {
201 config->colors.focused_workspace.border = parse_color(json_object_get_string(focused_workspace_border));
202 }
203
204 if (focused_workspace_bg) {
205 config->colors.focused_workspace.background = parse_color(json_object_get_string(focused_workspace_bg));
206 }
207
208 if (focused_workspace_text) {
209 config->colors.focused_workspace.text = parse_color(json_object_get_string(focused_workspace_text));
210 }
211
212 if (active_workspace_border) {
213 config->colors.active_workspace.border = parse_color(json_object_get_string(active_workspace_border));
214 }
215
216 if (active_workspace_bg) {
217 config->colors.active_workspace.background = parse_color(json_object_get_string(active_workspace_bg));
218 }
219
220 if (active_workspace_text) {
221 config->colors.active_workspace.text = parse_color(json_object_get_string(active_workspace_text));
222 }
223
224 if (inactive_workspace_border) {
225 config->colors.inactive_workspace.border = parse_color(json_object_get_string(inactive_workspace_border));
226 }
227
228 if (inactive_workspace_bg) {
229 config->colors.inactive_workspace.background = parse_color(json_object_get_string(inactive_workspace_bg));
230 }
231
232 if (inactive_workspace_text) {
233 config->colors.inactive_workspace.text = parse_color(json_object_get_string(inactive_workspace_text));
234 }
235
236 if (binding_mode_border) {
237 config->colors.binding_mode.border = parse_color(json_object_get_string(binding_mode_border));
238 }
239
240 if (binding_mode_bg) {
241 config->colors.binding_mode.background = parse_color(json_object_get_string(binding_mode_bg));
242 }
243
244 if (binding_mode_text) {
245 config->colors.binding_mode.text = parse_color(json_object_get_string(binding_mode_text));
246 }
247 }
248
249 json_object_put(bar_config);
250}
251
252static void ipc_update_workspaces(struct bar *bar) {
253 int i;
254 for (i = 0; i < bar->outputs->length; ++i) {
255 struct output *output = bar->outputs->items[i];
256 if (output->workspaces) {
257 free_workspaces(output->workspaces);
258 }
259 output->workspaces = create_list();
260 }
261
262 uint32_t len = 0;
263 char *res = ipc_single_command(bar->ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len);
264 json_object *results = json_tokener_parse(res);
265 if (!results) {
266 free(res);
267 return;
268 }
269
270 int length = json_object_array_length(results);
271 json_object *ws_json;
272 json_object *num, *name, *visible, *focused, *out, *urgent;
273 for (i = 0; i < length; ++i) {
274 ws_json = json_object_array_get_idx(results, i);
275
276 json_object_object_get_ex(ws_json, "num", &num);
277 json_object_object_get_ex(ws_json, "name", &name);
278 json_object_object_get_ex(ws_json, "visible", &visible);
279 json_object_object_get_ex(ws_json, "focused", &focused);
280 json_object_object_get_ex(ws_json, "output", &out);
281 json_object_object_get_ex(ws_json, "urgent", &urgent);
282
283 int j;
284 for (j = 0; j < bar->outputs->length; ++j) {
285 struct output *output = bar->outputs->items[j];
286 if (strcmp(json_object_get_string(out), output->name) == 0) {
287 struct workspace *ws = malloc(sizeof(struct workspace));
288 ws->num = json_object_get_int(num);
289 ws->name = strdup(json_object_get_string(name));
290 ws->visible = json_object_get_boolean(visible);
291 ws->focused = json_object_get_boolean(focused);
292 if (ws->focused) {
293 if (bar->focused_output) {
294 bar->focused_output->focused = false;
295 }
296 bar->focused_output = output;
297 output->focused = true;
298 }
299 ws->urgent = json_object_get_boolean(urgent);
300 list_add(output->workspaces, ws);
301 }
302 }
303 }
304
305 json_object_put(results);
306 free(res);
307}
308
309void ipc_bar_init(struct bar *bar, const char *bar_id) {
310 // Get bar config
311 uint32_t len = strlen(bar_id);
312 char *res = ipc_single_command(bar->ipc_socketfd, IPC_GET_BAR_CONFIG, bar_id, &len);
313
314 ipc_parse_config(bar->config, res);
315 free(res);
316
317 // Get outputs
318 len = 0;
319 res = ipc_single_command(bar->ipc_socketfd, IPC_GET_OUTPUTS, NULL, &len);
320 json_object *outputs = json_tokener_parse(res);
321 int i;
322 int length = json_object_array_length(outputs);
323 json_object *output, *output_name, *output_active;
324 const char *name;
325 bool active;
326 for (i = 0; i < length; ++i) {
327 output = json_object_array_get_idx(outputs, i);
328 json_object_object_get_ex(output, "name", &output_name);
329 json_object_object_get_ex(output, "active", &output_active);
330 name = json_object_get_string(output_name);
331 active = json_object_get_boolean(output_active);
332 if (!active) {
333 continue;
334 }
335
336 bool use_output = false;
337 if (bar->config->all_outputs) {
338 use_output = true;
339 } else {
340 int j = 0;
341 for (j = 0; j < bar->config->outputs->length; ++j) {
342 const char *conf_name = bar->config->outputs->items[j];
343 if (strcasecmp(name, conf_name) == 0) {
344 use_output = true;
345 break;
346 }
347 }
348 }
349
350 if (!use_output) {
351 continue;
352 }
353
354 // add bar to the output
355 struct output *bar_output = new_output(name);
356 bar_output->idx = i;
357 list_add(bar->outputs, bar_output);
358 }
359 free(res);
360 json_object_put(outputs);
361
362 const char *subscribe_json = "[ \"workspace\", \"mode\" ]";
363 len = strlen(subscribe_json);
364 res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len);
365 free(res);
366
367 ipc_update_workspaces(bar);
368}
369
370bool handle_ipc_event(struct bar *bar) {
371 struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd);
372 if (!resp) {
373 return false;
374 }
375 switch (resp->type) {
376 case IPC_EVENT_WORKSPACE:
377 ipc_update_workspaces(bar);
378 break;
379 case IPC_EVENT_MODE: {
380 json_object *result = json_tokener_parse(resp->payload);
381 if (!result) {
382 free_ipc_response(resp);
383 sway_log(L_ERROR, "failed to parse payload as json");
384 return false;
385 }
386 json_object *json_change;
387 if (json_object_object_get_ex(result, "change", &json_change)) {
388 const char *change = json_object_get_string(json_change);
389
390 free(bar->config->mode);
391 if (strcmp(change, "default") == 0) {
392 bar->config->mode = NULL;
393 } else {
394 bar->config->mode = strdup(change);
395 }
396 } else {
397 sway_log(L_ERROR, "failed to parse response");
398 }
399
400 json_object_put(result);
401 break;
402 }
403 default:
404 free_ipc_response(resp);
405 return false;
406 }
407
408 free_ipc_response(resp);
409 return true;
410}