diff options
Diffstat (limited to 'swaymsg/main.c')
-rw-r--r-- | swaymsg/main.c | 155 |
1 files changed, 124 insertions, 31 deletions
diff --git a/swaymsg/main.c b/swaymsg/main.c index 574d3b75..573a7b16 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | |
2 | #include <limits.h> | ||
2 | #include <stdio.h> | 3 | #include <stdio.h> |
3 | #include <stdlib.h> | 4 | #include <stdlib.h> |
4 | #include <string.h> | 5 | #include <string.h> |
@@ -58,7 +59,7 @@ static void pretty_print_cmd(json_object *r) { | |||
58 | if (!success_object(r)) { | 59 | if (!success_object(r)) { |
59 | json_object *error; | 60 | json_object *error; |
60 | if (!json_object_object_get_ex(r, "error", &error)) { | 61 | if (!json_object_object_get_ex(r, "error", &error)) { |
61 | printf("An unknkown error occurred"); | 62 | printf("An unknown error occurred"); |
62 | } else { | 63 | } else { |
63 | printf("Error: %s\n", json_object_get_string(error)); | 64 | printf("Error: %s\n", json_object_get_string(error)); |
64 | } | 65 | } |
@@ -183,12 +184,14 @@ static void pretty_print_seat(json_object *i) { | |||
183 | } | 184 | } |
184 | 185 | ||
185 | static void pretty_print_output(json_object *o) { | 186 | static void pretty_print_output(json_object *o) { |
186 | json_object *name, *rect, *focused, *active, *ws, *current_mode; | 187 | json_object *name, *rect, *focused, *active, *power, *ws, *current_mode, *non_desktop; |
187 | json_object_object_get_ex(o, "name", &name); | 188 | json_object_object_get_ex(o, "name", &name); |
188 | json_object_object_get_ex(o, "rect", &rect); | 189 | json_object_object_get_ex(o, "rect", &rect); |
189 | json_object_object_get_ex(o, "focused", &focused); | 190 | json_object_object_get_ex(o, "focused", &focused); |
190 | json_object_object_get_ex(o, "active", &active); | 191 | json_object_object_get_ex(o, "active", &active); |
192 | json_object_object_get_ex(o, "power", &power); | ||
191 | json_object_object_get_ex(o, "current_workspace", &ws); | 193 | json_object_object_get_ex(o, "current_workspace", &ws); |
194 | json_object_object_get_ex(o, "non_desktop", &non_desktop); | ||
192 | json_object *make, *model, *serial, *scale, *scale_filter, *subpixel, | 195 | json_object *make, *model, *serial, *scale, *scale_filter, *subpixel, |
193 | *transform, *max_render_time, *adaptive_sync_status; | 196 | *transform, *max_render_time, *adaptive_sync_status; |
194 | json_object_object_get_ex(o, "make", &make); | 197 | json_object_object_get_ex(o, "make", &make); |
@@ -211,10 +214,19 @@ static void pretty_print_output(json_object *o) { | |||
211 | json_object_object_get_ex(current_mode, "height", &height); | 214 | json_object_object_get_ex(current_mode, "height", &height); |
212 | json_object_object_get_ex(current_mode, "refresh", &refresh); | 215 | json_object_object_get_ex(current_mode, "refresh", &refresh); |
213 | 216 | ||
214 | if (json_object_get_boolean(active)) { | 217 | if (json_object_get_boolean(non_desktop)) { |
218 | printf( | ||
219 | "Output %s '%s %s %s' (non-desktop)\n", | ||
220 | json_object_get_string(name), | ||
221 | json_object_get_string(make), | ||
222 | json_object_get_string(model), | ||
223 | json_object_get_string(serial) | ||
224 | ); | ||
225 | } else if (json_object_get_boolean(active)) { | ||
215 | printf( | 226 | printf( |
216 | "Output %s '%s %s %s'%s\n" | 227 | "Output %s '%s %s %s'%s\n" |
217 | " Current mode: %dx%d @ %.3f Hz\n" | 228 | " Current mode: %dx%d @ %.3f Hz\n" |
229 | " Power: %s\n" | ||
218 | " Position: %d,%d\n" | 230 | " Position: %d,%d\n" |
219 | " Scale factor: %f\n" | 231 | " Scale factor: %f\n" |
220 | " Scale filter: %s\n" | 232 | " Scale filter: %s\n" |
@@ -229,6 +241,7 @@ static void pretty_print_output(json_object *o) { | |||
229 | json_object_get_int(width), | 241 | json_object_get_int(width), |
230 | json_object_get_int(height), | 242 | json_object_get_int(height), |
231 | (double)json_object_get_int(refresh) / 1000, | 243 | (double)json_object_get_int(refresh) / 1000, |
244 | json_object_get_boolean(power) ? "on" : "off", | ||
232 | json_object_get_int(x), json_object_get_int(y), | 245 | json_object_get_int(x), json_object_get_int(y), |
233 | json_object_get_double(scale), | 246 | json_object_get_double(scale), |
234 | json_object_get_string(scale_filter), | 247 | json_object_get_string(scale_filter), |
@@ -245,7 +258,7 @@ static void pretty_print_output(json_object *o) { | |||
245 | json_object_get_string(adaptive_sync_status)); | 258 | json_object_get_string(adaptive_sync_status)); |
246 | } else { | 259 | } else { |
247 | printf( | 260 | printf( |
248 | "Output %s '%s %s %s' (inactive)\n", | 261 | "Output %s '%s %s %s' (disabled)\n", |
249 | json_object_get_string(name), | 262 | json_object_get_string(name), |
250 | json_object_get_string(make), | 263 | json_object_get_string(make), |
251 | json_object_get_string(model), | 264 | json_object_get_string(model), |
@@ -260,14 +273,22 @@ static void pretty_print_output(json_object *o) { | |||
260 | for (size_t i = 0; i < modes_len; ++i) { | 273 | for (size_t i = 0; i < modes_len; ++i) { |
261 | json_object *mode = json_object_array_get_idx(modes, i); | 274 | json_object *mode = json_object_array_get_idx(modes, i); |
262 | 275 | ||
263 | json_object *mode_width, *mode_height, *mode_refresh; | 276 | json_object *mode_width, *mode_height, *mode_refresh, |
277 | *mode_picture_aspect_ratio; | ||
264 | json_object_object_get_ex(mode, "width", &mode_width); | 278 | json_object_object_get_ex(mode, "width", &mode_width); |
265 | json_object_object_get_ex(mode, "height", &mode_height); | 279 | json_object_object_get_ex(mode, "height", &mode_height); |
266 | json_object_object_get_ex(mode, "refresh", &mode_refresh); | 280 | json_object_object_get_ex(mode, "refresh", &mode_refresh); |
281 | json_object_object_get_ex(mode, "picture_aspect_ratio", | ||
282 | &mode_picture_aspect_ratio); | ||
267 | 283 | ||
268 | printf(" %dx%d @ %.3f Hz\n", json_object_get_int(mode_width), | 284 | printf(" %dx%d @ %.3f Hz", json_object_get_int(mode_width), |
269 | json_object_get_int(mode_height), | 285 | json_object_get_int(mode_height), |
270 | (double)json_object_get_int(mode_refresh) / 1000); | 286 | (double)json_object_get_int(mode_refresh) / 1000); |
287 | if (mode_picture_aspect_ratio && | ||
288 | strcmp("none", json_object_get_string(mode_picture_aspect_ratio)) != 0) { | ||
289 | printf(" (%s)", json_object_get_string(mode_picture_aspect_ratio)); | ||
290 | } | ||
291 | printf("\n"); | ||
271 | } | 292 | } |
272 | } | 293 | } |
273 | 294 | ||
@@ -286,28 +307,83 @@ static void pretty_print_config(json_object *c) { | |||
286 | printf("%s\n", json_object_get_string(config)); | 307 | printf("%s\n", json_object_get_string(config)); |
287 | } | 308 | } |
288 | 309 | ||
289 | static void pretty_print(int type, json_object *resp) { | 310 | static void pretty_print_tree(json_object *obj, int indent) { |
290 | if (type != IPC_COMMAND && type != IPC_GET_WORKSPACES && | 311 | for (int i = 0; i < indent; i++) { |
291 | type != IPC_GET_INPUTS && type != IPC_GET_OUTPUTS && | 312 | printf(" "); |
292 | type != IPC_GET_VERSION && type != IPC_GET_SEATS && | ||
293 | type != IPC_GET_CONFIG && type != IPC_SEND_TICK) { | ||
294 | printf("%s\n", json_object_to_json_string_ext(resp, | ||
295 | JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | ||
296 | return; | ||
297 | } | 313 | } |
298 | 314 | ||
299 | if (type == IPC_SEND_TICK) { | 315 | int id = json_object_get_int(json_object_object_get(obj, "id")); |
300 | return; | 316 | const char *name = json_object_get_string(json_object_object_get(obj, "name")); |
317 | const char *type = json_object_get_string(json_object_object_get(obj, "type")); | ||
318 | const char *shell = json_object_get_string(json_object_object_get(obj, "shell")); | ||
319 | |||
320 | printf("#%d: %s \"%s\"", id, type, name); | ||
321 | |||
322 | if (shell != NULL) { | ||
323 | int pid = json_object_get_int(json_object_object_get(obj, "pid")); | ||
324 | const char *app_id = json_object_get_string(json_object_object_get(obj, "app_id")); | ||
325 | json_object *window_props_obj = json_object_object_get(obj, "window_properties"); | ||
326 | const char *instance = json_object_get_string(json_object_object_get(window_props_obj, "instance")); | ||
327 | const char *class = json_object_get_string(json_object_object_get(window_props_obj, "class")); | ||
328 | int x11_id = json_object_get_int(json_object_object_get(obj, "window")); | ||
329 | |||
330 | printf(" (%s, pid: %d", shell, pid); | ||
331 | if (app_id != NULL) { | ||
332 | printf(", app_id: \"%s\"", app_id); | ||
333 | } | ||
334 | if (instance != NULL) { | ||
335 | printf(", instance: \"%s\"", instance); | ||
336 | } | ||
337 | if (class != NULL) { | ||
338 | printf(", class: \"%s\"", class); | ||
339 | } | ||
340 | if (x11_id != 0) { | ||
341 | printf(", X11 window: 0x%X", x11_id); | ||
342 | } | ||
343 | printf(")"); | ||
301 | } | 344 | } |
302 | 345 | ||
303 | if (type == IPC_GET_VERSION) { | 346 | printf("\n"); |
304 | pretty_print_version(resp); | 347 | |
305 | return; | 348 | json_object *nodes_obj = json_object_object_get(obj, "nodes"); |
349 | size_t len = json_object_array_length(nodes_obj); | ||
350 | for (size_t i = 0; i < len; i++) { | ||
351 | pretty_print_tree(json_object_array_get_idx(nodes_obj, i), indent + 1); | ||
306 | } | 352 | } |
307 | 353 | ||
308 | if (type == IPC_GET_CONFIG) { | 354 | json_object *floating_nodes_obj; |
355 | json_bool floating_nodes = json_object_object_get_ex(obj, "floating_nodes", &floating_nodes_obj); | ||
356 | if (floating_nodes) { | ||
357 | size_t len = json_object_array_length(floating_nodes_obj); | ||
358 | for (size_t i = 0; i < len; i++) { | ||
359 | pretty_print_tree(json_object_array_get_idx(floating_nodes_obj, i), indent + 1); | ||
360 | } | ||
361 | } | ||
362 | } | ||
363 | |||
364 | static void pretty_print(int type, json_object *resp) { | ||
365 | switch (type) { | ||
366 | case IPC_SEND_TICK: | ||
367 | return; | ||
368 | case IPC_GET_VERSION: | ||
369 | pretty_print_version(resp); | ||
370 | return; | ||
371 | case IPC_GET_CONFIG: | ||
309 | pretty_print_config(resp); | 372 | pretty_print_config(resp); |
310 | return; | 373 | return; |
374 | case IPC_GET_TREE: | ||
375 | pretty_print_tree(resp, 0); | ||
376 | return; | ||
377 | case IPC_COMMAND: | ||
378 | case IPC_GET_WORKSPACES: | ||
379 | case IPC_GET_INPUTS: | ||
380 | case IPC_GET_OUTPUTS: | ||
381 | case IPC_GET_SEATS: | ||
382 | break; | ||
383 | default: | ||
384 | printf("%s\n", json_object_to_json_string_ext(resp, | ||
385 | JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | ||
386 | return; | ||
311 | } | 387 | } |
312 | 388 | ||
313 | json_object *obj; | 389 | json_object *obj; |
@@ -480,12 +556,20 @@ int main(int argc, char **argv) { | |||
480 | char *resp = ipc_single_command(socketfd, type, command, &len); | 556 | char *resp = ipc_single_command(socketfd, type, command, &len); |
481 | 557 | ||
482 | // pretty print the json | 558 | // pretty print the json |
483 | json_object *obj = json_tokener_parse(resp); | 559 | json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH); |
484 | if (obj == NULL) { | 560 | if (tok == NULL) { |
561 | if (quiet) { | ||
562 | exit(EXIT_FAILURE); | ||
563 | } | ||
564 | sway_abort("failed allocating json_tokener"); | ||
565 | } | ||
566 | json_object *obj = json_tokener_parse_ex(tok, resp, -1); | ||
567 | enum json_tokener_error err = json_tokener_get_error(tok); | ||
568 | json_tokener_free(tok); | ||
569 | if (obj == NULL || err != json_tokener_success) { | ||
485 | if (!quiet) { | 570 | if (!quiet) { |
486 | fprintf(stderr, "ERROR: Could not parse json response from ipc. " | 571 | sway_log(SWAY_ERROR, "failed to parse payload as json: %s", |
487 | "This is a bug in sway."); | 572 | json_tokener_error_desc(err)); |
488 | printf("%s\n", resp); | ||
489 | } | 573 | } |
490 | ret = 1; | 574 | ret = 1; |
491 | } else { | 575 | } else { |
@@ -517,13 +601,22 @@ int main(int argc, char **argv) { | |||
517 | break; | 601 | break; |
518 | } | 602 | } |
519 | 603 | ||
520 | json_object *obj = json_tokener_parse(reply->payload); | 604 | json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH); |
521 | if (obj == NULL) { | 605 | if (tok == NULL) { |
606 | if (quiet) { | ||
607 | exit(EXIT_FAILURE); | ||
608 | } | ||
609 | sway_abort("failed allocating json_tokener"); | ||
610 | } | ||
611 | json_object *obj = json_tokener_parse_ex(tok, reply->payload, -1); | ||
612 | enum json_tokener_error err = json_tokener_get_error(tok); | ||
613 | json_tokener_free(tok); | ||
614 | if (obj == NULL || err != json_tokener_success) { | ||
522 | if (!quiet) { | 615 | if (!quiet) { |
523 | fprintf(stderr, "ERROR: Could not parse json response from" | 616 | sway_log(SWAY_ERROR, "failed to parse payload as json: %s", |
524 | " ipc. This is a bug in sway."); | 617 | json_tokener_error_desc(err)); |
525 | ret = 1; | ||
526 | } | 618 | } |
619 | ret = 1; | ||
527 | break; | 620 | break; |
528 | } else if (quiet) { | 621 | } else if (quiet) { |
529 | json_object_put(obj); | 622 | json_object_put(obj); |