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