| 
									
										
										
										
											2018-11-25 12:12:48 +01:00
										 |  |  | #define _POSIX_C_SOURCE 200809L
 | 
					
						
							| 
									
										
										
										
											2015-11-26 12:41:24 -05:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2017-03-10 23:41:24 -05:00
										 |  |  | #include <strings.h>
 | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | #include <getopt.h>
 | 
					
						
							|  |  |  | #include <stdint.h>
 | 
					
						
							| 
									
										
										
										
											2015-11-26 15:06:41 -05:00
										 |  |  | #include <sys/un.h>
 | 
					
						
							|  |  |  | #include <sys/socket.h>
 | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | #include <ctype.h>
 | 
					
						
							| 
									
										
										
										
											2015-11-26 15:06:41 -05:00
										 |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2016-07-31 14:45:53 -04:00
										 |  |  | #include <json-c/json.h>
 | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | #include "stringop.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-27 09:50:04 -05:00
										 |  |  | #include "ipc-client.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | #include "log.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-26 12:41:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-26 09:08:05 +01:00
										 |  |  | void sway_terminate(int exit_code) { | 
					
						
							|  |  |  | 	exit(exit_code); | 
					
						
							| 
									
										
										
										
											2015-11-26 12:41:24 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | static bool success_object(json_object *result) { | 
					
						
							|  |  |  | 	json_object *success; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!json_object_object_get_ex(result, "success", &success)) { | 
					
						
							| 
									
										
										
										
											2018-10-29 11:25:54 +01:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 10:38:16 +02:00
										 |  |  | 	return json_object_get_boolean(success); | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 13:33:02 +10:00
										 |  |  | // Iterate results array and return false if any of them failed
 | 
					
						
							| 
									
										
										
										
											2017-07-07 21:51:34 +02:00
										 |  |  | static bool success(json_object *r, bool fallback) { | 
					
						
							| 
									
										
										
										
											2018-05-28 13:33:02 +10:00
										 |  |  | 	if (!json_object_is_type(r, json_type_array)) { | 
					
						
							| 
									
										
										
										
											2018-11-28 21:41:58 -05:00
										 |  |  | 		if (json_object_is_type(r, json_type_object)) { | 
					
						
							|  |  |  | 			return success_object(r); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-07 21:51:34 +02:00
										 |  |  | 		return fallback; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 13:33:02 +10:00
										 |  |  | 	size_t results_len = json_object_array_length(r); | 
					
						
							|  |  |  | 	if (!results_len) { | 
					
						
							|  |  |  | 		return fallback; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 13:33:02 +10:00
										 |  |  | 	for (size_t i = 0; i < results_len; ++i) { | 
					
						
							|  |  |  | 		json_object *result = json_object_array_get_idx(r, i); | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (!success_object(result)) { | 
					
						
							| 
									
										
										
										
											2018-05-28 13:33:02 +10:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-28 13:33:02 +10:00
										 |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2017-07-07 21:51:34 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pretty_print_cmd(json_object *r) { | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | 	if (!success_object(r)) { | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		json_object *error; | 
					
						
							|  |  |  | 		if (!json_object_object_get_ex(r, "error", &error)) { | 
					
						
							| 
									
										
										
										
											2018-05-05 20:40:34 +02:00
										 |  |  | 			printf("An unknkown error occurred"); | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			printf("Error: %s\n", json_object_get_string(error)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pretty_print_workspace(json_object *w) { | 
					
						
							| 
									
										
										
										
											2018-05-29 17:42:11 +10:00
										 |  |  | 	json_object *name, *rect, *visible, *output, *urgent, *layout, | 
					
						
							|  |  |  | 				*representation, *focused; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	json_object_object_get_ex(w, "name", &name); | 
					
						
							|  |  |  | 	json_object_object_get_ex(w, "rect", &rect); | 
					
						
							|  |  |  | 	json_object_object_get_ex(w, "visible", &visible); | 
					
						
							|  |  |  | 	json_object_object_get_ex(w, "output", &output); | 
					
						
							|  |  |  | 	json_object_object_get_ex(w, "urgent", &urgent); | 
					
						
							|  |  |  | 	json_object_object_get_ex(w, "layout", &layout); | 
					
						
							| 
									
										
										
										
											2018-05-29 17:42:11 +10:00
										 |  |  | 	json_object_object_get_ex(w, "representation", &representation); | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	json_object_object_get_ex(w, "focused", &focused); | 
					
						
							|  |  |  | 	printf( | 
					
						
							|  |  |  | 		"Workspace %s%s%s%s\n" | 
					
						
							|  |  |  | 		"  Output: %s\n" | 
					
						
							| 
									
										
										
										
											2018-05-29 17:42:11 +10:00
										 |  |  | 		"  Layout: %s\n" | 
					
						
							|  |  |  | 		"  Representation: %s\n\n", | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		json_object_get_string(name), | 
					
						
							|  |  |  | 		json_object_get_boolean(focused) ? " (focused)" : "", | 
					
						
							|  |  |  | 		!json_object_get_boolean(visible) ? " (off-screen)" : "", | 
					
						
							|  |  |  | 		json_object_get_boolean(urgent) ? " (urgent)" : "", | 
					
						
							|  |  |  | 		json_object_get_string(output), | 
					
						
							| 
									
										
										
										
											2018-05-29 17:42:11 +10:00
										 |  |  | 		json_object_get_string(layout), | 
					
						
							|  |  |  | 		json_object_get_string(representation) | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-18 14:27:38 -05:00
										 |  |  | static const char *pretty_type_name(const char *name) { | 
					
						
							|  |  |  | 	// TODO these constants probably belong in the common lib
 | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	struct { | 
					
						
							|  |  |  | 		const char *a; | 
					
						
							|  |  |  | 		const char *b; | 
					
						
							| 
									
										
										
										
											2017-12-18 14:27:38 -05:00
										 |  |  | 	} type_names[] = { | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		{ "keyboard", "Keyboard" }, | 
					
						
							|  |  |  | 		{ "pointer", "Mouse" }, | 
					
						
							|  |  |  | 		{ "tablet_pad", "Tablet pad" }, | 
					
						
							| 
									
										
										
										
											2017-12-18 14:27:38 -05:00
										 |  |  | 		{ "tablet_tool", "Tablet tool" }, | 
					
						
							|  |  |  | 		{ "touch", "Touch" }, | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-18 14:27:38 -05:00
										 |  |  | 	for (size_t i = 0; i < sizeof(type_names) / sizeof(type_names[0]); ++i) { | 
					
						
							|  |  |  | 		if (strcmp(type_names[i].a, name) == 0) { | 
					
						
							|  |  |  | 			return type_names[i].b; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-18 14:27:38 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return name; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pretty_print_input(json_object *i) { | 
					
						
							| 
									
										
										
										
											2018-11-12 14:33:16 +05:30
										 |  |  | 	json_object *id, *name, *type, *product, *vendor, *kbdlayout; | 
					
						
							| 
									
										
										
										
											2017-12-18 14:27:38 -05:00
										 |  |  | 	json_object_object_get_ex(i, "identifier", &id); | 
					
						
							|  |  |  | 	json_object_object_get_ex(i, "name", &name); | 
					
						
							|  |  |  | 	json_object_object_get_ex(i, "type", &type); | 
					
						
							|  |  |  | 	json_object_object_get_ex(i, "product", &product); | 
					
						
							|  |  |  | 	json_object_object_get_ex(i, "vendor", &vendor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const char *fmt = | 
					
						
							|  |  |  | 		"Input device: %s\n" | 
					
						
							|  |  |  | 		"  Type: %s\n" | 
					
						
							|  |  |  | 		"  Identifier: %s\n" | 
					
						
							|  |  |  | 		"  Product ID: %d\n" | 
					
						
							| 
									
										
										
										
											2018-11-12 14:33:16 +05:30
										 |  |  | 		"  Vendor ID: %d\n"; | 
					
						
							| 
									
										
										
										
											2017-12-18 14:27:38 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printf(fmt, json_object_get_string(name), | 
					
						
							|  |  |  | 		pretty_type_name(json_object_get_string(type)), | 
					
						
							|  |  |  | 		json_object_get_string(id), | 
					
						
							|  |  |  | 		json_object_get_int(product), | 
					
						
							|  |  |  | 		json_object_get_int(vendor)); | 
					
						
							| 
									
										
										
										
											2018-11-12 14:33:16 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (json_object_object_get_ex(i, "xkb_active_layout_name", &kbdlayout)) { | 
					
						
							|  |  |  | 		printf("  Active Keyboard Layout: %s\n", | 
					
						
							|  |  |  | 			json_object_get_string(kbdlayout)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printf("\n"); | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 23:51:47 +10:00
										 |  |  | static void pretty_print_seat(json_object *i) { | 
					
						
							|  |  |  | 	json_object *name, *capabilities, *devices; | 
					
						
							|  |  |  | 	json_object_object_get_ex(i, "name", &name); | 
					
						
							|  |  |  | 	json_object_object_get_ex(i, "capabilities", &capabilities); | 
					
						
							|  |  |  | 	json_object_object_get_ex(i, "devices", &devices); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const char *fmt = | 
					
						
							|  |  |  | 		"Seat: %s\n" | 
					
						
							|  |  |  | 		"  Capabilities: %d\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printf(fmt, json_object_get_string(name), | 
					
						
							|  |  |  | 		json_object_get_int(capabilities)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size_t devices_len = json_object_array_length(devices); | 
					
						
							|  |  |  | 	if (devices_len > 0) { | 
					
						
							|  |  |  | 		printf("  Devices:\n"); | 
					
						
							|  |  |  | 		for (size_t i = 0; i < devices_len; ++i) { | 
					
						
							|  |  |  | 			json_object *device = json_object_array_get_idx(devices, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			json_object *device_name; | 
					
						
							|  |  |  | 			json_object_object_get_ex(device, "name", &device_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			printf("    %s\n", json_object_get_string(device_name)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printf("\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | static void pretty_print_output(json_object *o) { | 
					
						
							| 
									
										
										
										
											2018-11-03 15:07:51 -07:00
										 |  |  | 	json_object *name, *rect, *focused, *active, *ws, *current_mode; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	json_object_object_get_ex(o, "name", &name); | 
					
						
							|  |  |  | 	json_object_object_get_ex(o, "rect", &rect); | 
					
						
							|  |  |  | 	json_object_object_get_ex(o, "focused", &focused); | 
					
						
							|  |  |  | 	json_object_object_get_ex(o, "active", &active); | 
					
						
							|  |  |  | 	json_object_object_get_ex(o, "current_workspace", &ws); | 
					
						
							| 
									
										
										
										
											2018-11-03 15:07:51 -07:00
										 |  |  | 	json_object *make, *model, *serial, *scale, *transform; | 
					
						
							| 
									
										
										
										
											2017-12-29 11:16:57 +01:00
										 |  |  | 	json_object_object_get_ex(o, "make", &make); | 
					
						
							|  |  |  | 	json_object_object_get_ex(o, "model", &model); | 
					
						
							|  |  |  | 	json_object_object_get_ex(o, "serial", &serial); | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	json_object_object_get_ex(o, "scale", &scale); | 
					
						
							| 
									
										
										
										
											2017-12-29 11:16:57 +01:00
										 |  |  | 	json_object_object_get_ex(o, "transform", &transform); | 
					
						
							| 
									
										
										
										
											2018-11-03 15:07:51 -07:00
										 |  |  | 	json_object *x, *y; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	json_object_object_get_ex(rect, "x", &x); | 
					
						
							|  |  |  | 	json_object_object_get_ex(rect, "y", &y); | 
					
						
							| 
									
										
										
										
											2018-03-12 13:48:42 +01:00
										 |  |  | 	json_object *modes; | 
					
						
							|  |  |  | 	json_object_object_get_ex(o, "modes", &modes); | 
					
						
							| 
									
										
										
										
											2018-11-03 15:07:51 -07:00
										 |  |  | 	json_object *width, *height, *refresh; | 
					
						
							| 
									
										
										
										
											2018-11-02 01:34:33 -07:00
										 |  |  | 	json_object_object_get_ex(o, "current_mode", ¤t_mode); | 
					
						
							| 
									
										
										
										
											2018-11-03 15:07:51 -07:00
										 |  |  | 	json_object_object_get_ex(current_mode, "width", &width); | 
					
						
							|  |  |  | 	json_object_object_get_ex(current_mode, "height", &height); | 
					
						
							|  |  |  | 	json_object_object_get_ex(current_mode, "refresh", &refresh); | 
					
						
							| 
									
										
										
										
											2018-03-12 13:48:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-05 17:56:32 -04:00
										 |  |  | 	if (json_object_get_boolean(active)) { | 
					
						
							|  |  |  | 		printf( | 
					
						
							|  |  |  | 			"Output %s '%s %s %s'%s\n" | 
					
						
							|  |  |  | 			"  Current mode: %dx%d @ %f Hz\n" | 
					
						
							|  |  |  | 			"  Position: %d,%d\n" | 
					
						
							| 
									
										
										
										
											2018-11-02 01:34:33 -07:00
										 |  |  | 			"  Scale factor: %f\n" | 
					
						
							| 
									
										
										
										
											2018-06-05 17:56:32 -04:00
										 |  |  | 			"  Transform: %s\n" | 
					
						
							|  |  |  | 			"  Workspace: %s\n", | 
					
						
							|  |  |  | 			json_object_get_string(name), | 
					
						
							|  |  |  | 			json_object_get_string(make), | 
					
						
							|  |  |  | 			json_object_get_string(model), | 
					
						
							|  |  |  | 			json_object_get_string(serial), | 
					
						
							|  |  |  | 			json_object_get_boolean(focused) ? " (focused)" : "", | 
					
						
							| 
									
										
										
										
											2018-11-03 15:07:51 -07:00
										 |  |  | 			json_object_get_int(width), | 
					
						
							|  |  |  | 			json_object_get_int(height), | 
					
						
							| 
									
										
										
										
											2018-06-05 17:56:32 -04:00
										 |  |  | 			(float)json_object_get_int(refresh) / 1000, | 
					
						
							|  |  |  | 			json_object_get_int(x), json_object_get_int(y), | 
					
						
							| 
									
										
										
										
											2018-11-02 01:34:33 -07:00
										 |  |  | 			json_object_get_double(scale), | 
					
						
							| 
									
										
										
										
											2018-06-05 17:56:32 -04:00
										 |  |  | 			json_object_get_string(transform), | 
					
						
							|  |  |  | 			json_object_get_string(ws) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		printf( | 
					
						
							|  |  |  | 			"Output %s '%s %s %s' (inactive)", | 
					
						
							|  |  |  | 			json_object_get_string(name), | 
					
						
							|  |  |  | 			json_object_get_string(make), | 
					
						
							|  |  |  | 			json_object_get_string(model), | 
					
						
							|  |  |  | 			json_object_get_string(serial) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-12 13:48:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	size_t modes_len = json_object_array_length(modes); | 
					
						
							|  |  |  | 	if (modes_len > 0) { | 
					
						
							|  |  |  | 		printf("  Available modes:\n"); | 
					
						
							|  |  |  | 		for (size_t i = 0; i < modes_len; ++i) { | 
					
						
							|  |  |  | 			json_object *mode = json_object_array_get_idx(modes, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			json_object *mode_width, *mode_height, *mode_refresh; | 
					
						
							|  |  |  | 			json_object_object_get_ex(mode, "width", &mode_width); | 
					
						
							|  |  |  | 			json_object_object_get_ex(mode, "height", &mode_height); | 
					
						
							|  |  |  | 			json_object_object_get_ex(mode, "refresh", &mode_refresh); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			printf("    %dx%d @ %f Hz\n", json_object_get_int(mode_width), | 
					
						
							|  |  |  | 				json_object_get_int(mode_height), | 
					
						
							|  |  |  | 				(float)json_object_get_int(mode_refresh) / 1000); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printf("\n"); | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void pretty_print_version(json_object *v) { | 
					
						
							|  |  |  | 	json_object *ver; | 
					
						
							|  |  |  | 	json_object_object_get_ex(v, "human_readable", &ver); | 
					
						
							|  |  |  | 	printf("sway version %s\n", json_object_get_string(ver)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-08 20:34:47 +01:00
										 |  |  | static void pretty_print_config(json_object *c) { | 
					
						
							|  |  |  | 	json_object *config; | 
					
						
							|  |  |  | 	json_object_object_get_ex(c, "config", &config); | 
					
						
							|  |  |  | 	printf("%s\n", json_object_get_string(config)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | static void pretty_print(int type, json_object *resp) { | 
					
						
							|  |  |  | 	if (type != IPC_COMMAND && type != IPC_GET_WORKSPACES && | 
					
						
							|  |  |  | 			type != IPC_GET_INPUTS && type != IPC_GET_OUTPUTS && | 
					
						
							| 
									
										
										
										
											2018-07-09 22:39:47 +01:00
										 |  |  | 			type != IPC_GET_VERSION && type != IPC_GET_SEATS && | 
					
						
							| 
									
										
										
										
											2018-07-18 12:30:39 +01:00
										 |  |  | 			type != IPC_GET_CONFIG && type != IPC_SEND_TICK) { | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		printf("%s\n", json_object_to_json_string_ext(resp, | 
					
						
							|  |  |  | 			JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 12:30:39 +01:00
										 |  |  | 	if (type == IPC_SEND_TICK) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	if (type == IPC_GET_VERSION) { | 
					
						
							|  |  |  | 		pretty_print_version(resp); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-08 20:34:47 +01:00
										 |  |  | 	if (type == IPC_GET_CONFIG) { | 
					
						
							|  |  |  | 		pretty_print_config(resp); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 	json_object *obj; | 
					
						
							|  |  |  | 	size_t len = json_object_array_length(resp); | 
					
						
							|  |  |  | 	for (size_t i = 0; i < len; ++i) { | 
					
						
							|  |  |  | 		obj = json_object_array_get_idx(resp, i); | 
					
						
							|  |  |  | 		switch (type) { | 
					
						
							|  |  |  | 		case IPC_COMMAND: | 
					
						
							|  |  |  | 			pretty_print_cmd(obj); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case IPC_GET_WORKSPACES: | 
					
						
							|  |  |  | 			pretty_print_workspace(obj); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case IPC_GET_INPUTS: | 
					
						
							|  |  |  | 			pretty_print_input(obj); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case IPC_GET_OUTPUTS: | 
					
						
							|  |  |  | 			pretty_print_output(obj); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2018-05-11 23:51:47 +10:00
										 |  |  | 		case IPC_GET_SEATS: | 
					
						
							|  |  |  | 			pretty_print_seat(obj); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | int main(int argc, char **argv) { | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 	static bool quiet = false; | 
					
						
							|  |  |  | 	static bool raw = false; | 
					
						
							|  |  |  | 	static bool monitor = false; | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	char *socket_path = NULL; | 
					
						
							|  |  |  | 	char *cmdtype = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-09 22:54:30 +01:00
										 |  |  | 	wlr_log_init(WLR_INFO, NULL); | 
					
						
							| 
									
										
										
										
											2015-11-26 15:06:41 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	static struct option long_options[] = { | 
					
						
							| 
									
										
										
										
											2015-11-28 16:18:46 +02:00
										 |  |  | 		{"help", no_argument, NULL, 'h'}, | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 		{"monitor", no_argument, NULL, 'm'}, | 
					
						
							| 
									
										
										
										
											2015-11-28 16:35:44 +02:00
										 |  |  | 		{"quiet", no_argument, NULL, 'q'}, | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		{"raw", no_argument, NULL, 'r'}, | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 		{"socket", required_argument, NULL, 's'}, | 
					
						
							|  |  |  | 		{"type", required_argument, NULL, 't'}, | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		{"version", no_argument, NULL, 'v'}, | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 		{0, 0, 0, 0} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-28 16:09:19 +02:00
										 |  |  | 	const char *usage = | 
					
						
							|  |  |  | 		"Usage: swaymsg [options] [message]\n" | 
					
						
							|  |  |  | 		"\n" | 
					
						
							| 
									
										
										
										
											2015-11-28 16:18:46 +02:00
										 |  |  | 		"  -h, --help             Show help message and quit.\n" | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 		"  -m, --monitor          Monitor until killed (-t SUBSCRIBE only)\n" | 
					
						
							| 
									
										
										
										
											2015-11-28 16:09:19 +02:00
										 |  |  | 		"  -q, --quiet            Be quiet.\n" | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		"  -r, --raw              Use raw output even if using a tty\n" | 
					
						
							| 
									
										
										
										
											2015-11-28 16:09:19 +02:00
										 |  |  | 		"  -s, --socket <socket>  Use the specified socket.\n" | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		"  -t, --type <type>      Specify the message type.\n" | 
					
						
							|  |  |  | 		"  -v, --version          Show the version number and quit.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	raw = !isatty(STDOUT_FILENO); | 
					
						
							| 
									
										
										
										
											2015-11-28 16:09:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	int c; | 
					
						
							|  |  |  | 	while (1) { | 
					
						
							|  |  |  | 		int option_index = 0; | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 		c = getopt_long(argc, argv, "hmqrs:t:v", long_options, &option_index); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 		if (c == -1) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		switch (c) { | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 		case 'm': // Monitor
 | 
					
						
							|  |  |  | 			monitor = true; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2015-11-28 16:35:44 +02:00
										 |  |  | 		case 'q': // Quiet
 | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 			quiet = true; | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 		case 'r': // Raw
 | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 			raw = true; | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 		case 's': // Socket
 | 
					
						
							|  |  |  | 			socket_path = strdup(optarg); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case 't': // Type
 | 
					
						
							|  |  |  | 			cmdtype = strdup(optarg); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case 'v': | 
					
						
							| 
									
										
										
										
											2018-10-10 18:34:50 +10:00
										 |  |  | 			fprintf(stdout, "swaymsg version " SWAY_VERSION "\n"); | 
					
						
							| 
									
										
										
										
											2015-11-28 15:47:44 +02:00
										 |  |  | 			exit(EXIT_SUCCESS); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2015-11-28 16:09:19 +02:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			fprintf(stderr, "%s", usage); | 
					
						
							|  |  |  | 			exit(EXIT_FAILURE); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!cmdtype) { | 
					
						
							| 
									
										
										
										
											2015-11-26 15:06:41 -05:00
										 |  |  | 		cmdtype = strdup("command"); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (!socket_path) { | 
					
						
							|  |  |  | 		socket_path = get_socketpath(); | 
					
						
							|  |  |  | 		if (!socket_path) { | 
					
						
							|  |  |  | 			sway_abort("Unable to retrieve socket path"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-27 09:42:24 -05:00
										 |  |  | 	uint32_t type = IPC_COMMAND; | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (strcasecmp(cmdtype, "command") == 0) { | 
					
						
							|  |  |  | 		type = IPC_COMMAND; | 
					
						
							|  |  |  | 	} else if (strcasecmp(cmdtype, "get_workspaces") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_WORKSPACES; | 
					
						
							| 
									
										
										
										
											2018-05-11 23:51:47 +10:00
										 |  |  | 	} else if (strcasecmp(cmdtype, "get_seats") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_SEATS; | 
					
						
							| 
									
										
										
										
											2016-01-17 02:53:37 -08:00
										 |  |  | 	} else if (strcasecmp(cmdtype, "get_inputs") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_INPUTS; | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	} else if (strcasecmp(cmdtype, "get_outputs") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_OUTPUTS; | 
					
						
							|  |  |  | 	} else if (strcasecmp(cmdtype, "get_tree") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_TREE; | 
					
						
							|  |  |  | 	} else if (strcasecmp(cmdtype, "get_marks") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_MARKS; | 
					
						
							|  |  |  | 	} else if (strcasecmp(cmdtype, "get_bar_config") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_BAR_CONFIG; | 
					
						
							|  |  |  | 	} else if (strcasecmp(cmdtype, "get_version") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_VERSION; | 
					
						
							| 
									
										
										
										
											2018-07-08 20:32:42 +01:00
										 |  |  | 	} else if (strcasecmp(cmdtype, "get_binding_modes") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_BINDING_MODES; | 
					
						
							| 
									
										
										
										
											2018-07-08 20:34:47 +01:00
										 |  |  | 	} else if (strcasecmp(cmdtype, "get_config") == 0) { | 
					
						
							|  |  |  | 		type = IPC_GET_CONFIG; | 
					
						
							| 
									
										
										
										
											2018-07-18 12:30:39 +01:00
										 |  |  | 	} else if (strcasecmp(cmdtype, "send_tick") == 0) { | 
					
						
							|  |  |  | 		type = IPC_SEND_TICK; | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 	} else if (strcasecmp(cmdtype, "subscribe") == 0) { | 
					
						
							|  |  |  | 		type = IPC_SUBSCRIBE; | 
					
						
							| 
									
										
										
										
											2015-11-27 09:42:24 -05:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		sway_abort("Unknown message type %s", cmdtype); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-30 10:29:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-26 15:06:41 -05:00
										 |  |  | 	free(cmdtype); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 	if (monitor && type != IPC_SUBSCRIBE) { | 
					
						
							|  |  |  | 		wlr_log(WLR_ERROR, "Monitor can only be used with -t SUBSCRIBE"); | 
					
						
							|  |  |  | 		free(socket_path); | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 05:38:41 -05:00
										 |  |  | 	char *command = NULL; | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	if (optind < argc) { | 
					
						
							|  |  |  | 		command = join_args(argv + optind, argc - optind); | 
					
						
							| 
									
										
										
										
											2017-12-19 05:38:41 -05:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		command = strdup(""); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-31 14:45:53 -04:00
										 |  |  | 	int ret = 0; | 
					
						
							| 
									
										
										
										
											2015-11-27 10:10:29 -05:00
										 |  |  | 	int socketfd = ipc_open_socket(socket_path); | 
					
						
							|  |  |  | 	uint32_t len = strlen(command); | 
					
						
							|  |  |  | 	char *resp = ipc_single_command(socketfd, type, command, &len); | 
					
						
							| 
									
										
										
										
											2015-11-26 15:06:41 -05:00
										 |  |  | 	if (!quiet) { | 
					
						
							| 
									
										
										
										
											2016-07-31 14:45:53 -04:00
										 |  |  | 		// pretty print the json
 | 
					
						
							|  |  |  | 		json_object *obj = json_tokener_parse(resp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (obj == NULL) { | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 			fprintf(stderr, "ERROR: Could not parse json response from ipc. " | 
					
						
							|  |  |  | 					"This is a bug in sway."); | 
					
						
							| 
									
										
										
										
											2016-07-31 14:45:53 -04:00
										 |  |  | 			printf("%s\n", resp); | 
					
						
							|  |  |  | 			ret = 1; | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-07-07 21:51:34 +02:00
										 |  |  | 			if (!success(obj, true)) { | 
					
						
							|  |  |  | 				ret = 1; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 			if (type != IPC_SUBSCRIBE  || ret != 0) { | 
					
						
							|  |  |  | 				if (raw) { | 
					
						
							|  |  |  | 					printf("%s\n", json_object_to_json_string_ext(obj, | 
					
						
							|  |  |  | 						JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					pretty_print(type, obj); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-04-03 07:27:25 -04:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-12-18 17:52:50 -05:00
										 |  |  | 			json_object_put(obj); | 
					
						
							| 
									
										
										
										
											2016-07-31 14:45:53 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-11-26 15:06:41 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	free(command); | 
					
						
							|  |  |  | 	free(resp); | 
					
						
							| 
									
										
										
										
											2018-11-28 11:19:18 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (type == IPC_SUBSCRIBE && ret == 0) { | 
					
						
							|  |  |  | 		do { | 
					
						
							|  |  |  | 			struct ipc_response *reply = ipc_recv_response(socketfd); | 
					
						
							|  |  |  | 			if (!reply) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			json_object *obj = json_tokener_parse(reply->payload); | 
					
						
							|  |  |  | 			if (obj == NULL) { | 
					
						
							|  |  |  | 				fprintf(stderr, "ERROR: Could not parse json response from ipc" | 
					
						
							|  |  |  | 						". This is a bug in sway."); | 
					
						
							|  |  |  | 				ret = 1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if (raw) { | 
					
						
							|  |  |  | 					printf("%s\n", json_object_to_json_string(obj)); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					printf("%s\n", json_object_to_json_string_ext(obj, | 
					
						
							|  |  |  | 						JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				json_object_put(obj); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			free_ipc_response(reply); | 
					
						
							|  |  |  | 		} while (monitor); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	close(socketfd); | 
					
						
							| 
									
										
										
										
											2015-11-26 14:31:29 -05:00
										 |  |  | 	free(socket_path); | 
					
						
							| 
									
										
										
										
											2016-07-31 14:45:53 -04:00
										 |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2015-11-26 12:41:24 -05:00
										 |  |  | } |