diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-04-03 07:27:25 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2017-04-03 07:27:25 -0400 |
commit | 60ce81e06adc9ea133e8cfd030465e94295a95ff (patch) | |
tree | eb34022e36dd9277b40bed5bb4def27d5a1de5e0 /swaymsg | |
parent | Update README.md (diff) | |
download | sway-60ce81e06adc9ea133e8cfd030465e94295a95ff.tar.gz sway-60ce81e06adc9ea133e8cfd030465e94295a95ff.tar.zst sway-60ce81e06adc9ea133e8cfd030465e94295a95ff.zip |
Add pretty printing to swaymsg
If stdout is a tty, it will pretty print unless -r (--raw) is given.
Sample outputs:
```
~/s/s/build > ./bin/swaymsg fullscreen toggle
Error: Permission denied for fullscreen toggle via IPC
~/s/s/build > ./bin/swaymsg -t get_workspaces
Workspace 3:三
Output: DVI-I-1
Layout: splith
Workspace 1:一 (off-screen)
Output: HDMI-A-1
Layout: splith
Workspace 5:五 (focused)
Output: HDMI-A-1
Layout: splith
~/s/s/build > ./bin/swaymsg -t get_inputs
Input device Metadot - Das Keyboard Das Keyboard
Type: Keyboard
Sway ID: 9456:320:Metadot_-_Das_Keyboard_Das_Keyb
Input device Wacom Intuos S 2 Pen
Type: Tablet tool
Sway ID: 1386:827:Wacom_Intuos_S_2
Input device Wacom Intuos S 2 Pad
Type: Tablet pad
Sway ID: 1386:827:Wacom_Intuos_S_2
Input device Logitech Gaming Mouse G502
Type: Keyboard, Mouse
Sway ID: 1133:49277:Logitech_Gaming_Mous
~/s/s/build > ./bin/swaymsg -t get_outputs
Output DVI-I-1
Geometry: 1920x1080 @ 3840,0
Scale factor: 1x
Workspace: 3:三
Output DVI-D-1
Geometry: 1920x1080 @ 0,0
Scale factor: 1x
Workspace: 4:四
Output HDMI-A-1
Geometry: 1920x1080 @ 1920,0
Scale factor: 1x
Workspace: 5:五
```
Diffstat (limited to 'swaymsg')
-rw-r--r-- | swaymsg/main.c | 184 | ||||
-rw-r--r-- | swaymsg/swaymsg.1.txt | 7 |
2 files changed, 184 insertions, 7 deletions
diff --git a/swaymsg/main.c b/swaymsg/main.c index 2c418127..2d2b0f60 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <stdint.h> | 7 | #include <stdint.h> |
8 | #include <sys/un.h> | 8 | #include <sys/un.h> |
9 | #include <sys/socket.h> | 9 | #include <sys/socket.h> |
10 | #include <ctype.h> | ||
10 | #include <unistd.h> | 11 | #include <unistd.h> |
11 | #include <json-c/json.h> | 12 | #include <json-c/json.h> |
12 | #include "stringop.h" | 13 | #include "stringop.h" |
@@ -18,8 +19,169 @@ void sway_terminate(int exit_code) { | |||
18 | exit(exit_code); | 19 | exit(exit_code); |
19 | } | 20 | } |
20 | 21 | ||
22 | static void pretty_print_cmd(json_object *r) { | ||
23 | bool _success; | ||
24 | json_object *success; | ||
25 | if (!json_object_object_get_ex(r, "success", &success)) { | ||
26 | _success = true; | ||
27 | } else { | ||
28 | _success = json_object_get_boolean(success); | ||
29 | } | ||
30 | if (!_success) { | ||
31 | json_object *error; | ||
32 | if (!json_object_object_get_ex(r, "error", &error)) { | ||
33 | printf("An unknkown error occured"); | ||
34 | } else { | ||
35 | printf("Error: %s\n", json_object_get_string(error)); | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | |||
40 | static void pretty_print_workspace(json_object *w) { | ||
41 | json_object *name, *rect, *visible, *output, *urgent, *layout, *focused; | ||
42 | json_object_object_get_ex(w, "name", &name); | ||
43 | json_object_object_get_ex(w, "rect", &rect); | ||
44 | json_object_object_get_ex(w, "visible", &visible); | ||
45 | json_object_object_get_ex(w, "output", &output); | ||
46 | json_object_object_get_ex(w, "urgent", &urgent); | ||
47 | json_object_object_get_ex(w, "layout", &layout); | ||
48 | json_object_object_get_ex(w, "focused", &focused); | ||
49 | printf( | ||
50 | "Workspace %s%s%s%s\n" | ||
51 | " Output: %s\n" | ||
52 | " Layout: %s\n\n", | ||
53 | json_object_get_string(name), | ||
54 | json_object_get_boolean(focused) ? " (focused)" : "", | ||
55 | !json_object_get_boolean(visible) ? " (off-screen)" : "", | ||
56 | json_object_get_boolean(urgent) ? " (urgent)" : "", | ||
57 | json_object_get_string(output), | ||
58 | json_object_get_string(layout) | ||
59 | ); | ||
60 | } | ||
61 | |||
62 | static void pretty_print_input(json_object *i) { | ||
63 | json_object *id, *name, *size, *caps; | ||
64 | json_object_object_get_ex(i, "identifier", &id); | ||
65 | json_object_object_get_ex(i, "name", &name); | ||
66 | json_object_object_get_ex(i, "size", &size); | ||
67 | json_object_object_get_ex(i, "capabilities", &caps); | ||
68 | |||
69 | printf( "Input device %s\n Type: ", json_object_get_string(name)); | ||
70 | |||
71 | struct { | ||
72 | const char *a; | ||
73 | const char *b; | ||
74 | } cap_names[] = { | ||
75 | { "keyboard", "Keyboard" }, | ||
76 | { "pointer", "Mouse" }, | ||
77 | { "touch", "Touch" }, | ||
78 | { "tablet_tool", "Tablet tool" }, | ||
79 | { "tablet_pad", "Tablet pad" }, | ||
80 | { "gesture", "Gesture" }, | ||
81 | { "switch", "Switch" }, | ||
82 | }; | ||
83 | |||
84 | size_t len = json_object_array_length(caps); | ||
85 | if (len == 0) { | ||
86 | printf("Unknown"); | ||
87 | } | ||
88 | |||
89 | json_object *cap; | ||
90 | for (size_t i = 0; i < len; ++i) { | ||
91 | cap = json_object_array_get_idx(caps, i); | ||
92 | const char *cap_s = json_object_get_string(cap); | ||
93 | const char *_name = NULL; | ||
94 | for (size_t j = 0; j < sizeof(cap_names) / sizeof(cap_names[0]); ++i) { | ||
95 | if (strcmp(cap_names[i].a, cap_s) == 0) { | ||
96 | _name = cap_names[i].b; | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | printf("%s%s", _name ? _name : cap_s, len > 1 && i != len - 1 ? ", " : ""); | ||
101 | } | ||
102 | printf("\n Sway ID: %s\n", json_object_get_string(id)); | ||
103 | if (size) { | ||
104 | json_object *width, *height; | ||
105 | json_object_object_get_ex(size, "width", &width); | ||
106 | json_object_object_get_ex(size, "height", &height); | ||
107 | printf(" Size: %lfmm x %lfmm\n", | ||
108 | json_object_get_double(width), json_object_get_double(height)); | ||
109 | } | ||
110 | printf("\n"); | ||
111 | } | ||
112 | |||
113 | static void pretty_print_output(json_object *o) { | ||
114 | json_object *name, *rect, *focused, *active, *ws, *scale; | ||
115 | json_object_object_get_ex(o, "name", &name); | ||
116 | json_object_object_get_ex(o, "rect", &rect); | ||
117 | json_object_object_get_ex(o, "focused", &focused); | ||
118 | json_object_object_get_ex(o, "active", &active); | ||
119 | json_object_object_get_ex(o, "current_workspace", &ws); | ||
120 | json_object_object_get_ex(o, "scale", &scale); | ||
121 | json_object *x, *y, *width, *height; | ||
122 | json_object_object_get_ex(rect, "x", &x); | ||
123 | json_object_object_get_ex(rect, "y", &y); | ||
124 | json_object_object_get_ex(rect, "width", &width); | ||
125 | json_object_object_get_ex(rect, "height", &height); | ||
126 | printf( | ||
127 | "Output %s%s%s\n" | ||
128 | " Geometry: %dx%d @ %d,%d\n" | ||
129 | " Scale factor: %dx\n" | ||
130 | " Workspace: %s\n\n", | ||
131 | json_object_get_string(name), | ||
132 | json_object_get_boolean(focused) ? " (focused)" : "", | ||
133 | !json_object_get_boolean(active) ? " (inactive)" : "", | ||
134 | json_object_get_int(width), json_object_get_int(height), | ||
135 | json_object_get_int(x), json_object_get_int(y), | ||
136 | json_object_get_int(scale), | ||
137 | json_object_get_string(ws) | ||
138 | ); | ||
139 | } | ||
140 | |||
141 | static void pretty_print_version(json_object *v) { | ||
142 | json_object *ver; | ||
143 | json_object_object_get_ex(v, "human_readable", &ver); | ||
144 | printf("sway version %s\n", json_object_get_string(ver)); | ||
145 | } | ||
146 | |||
147 | static void pretty_print(int type, json_object *resp) { | ||
148 | if (type != IPC_COMMAND && type != IPC_GET_WORKSPACES && | ||
149 | type != IPC_GET_INPUTS && type != IPC_GET_OUTPUTS && | ||
150 | type != IPC_GET_VERSION) { | ||
151 | printf("%s\n", json_object_to_json_string_ext(resp, | ||
152 | JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | ||
153 | return; | ||
154 | } | ||
155 | |||
156 | if (type == IPC_GET_VERSION) { | ||
157 | pretty_print_version(resp); | ||
158 | return; | ||
159 | } | ||
160 | |||
161 | json_object *obj; | ||
162 | size_t len = json_object_array_length(resp); | ||
163 | for (size_t i = 0; i < len; ++i) { | ||
164 | obj = json_object_array_get_idx(resp, i); | ||
165 | switch (type) { | ||
166 | case IPC_COMMAND: | ||
167 | pretty_print_cmd(obj); | ||
168 | break; | ||
169 | case IPC_GET_WORKSPACES: | ||
170 | pretty_print_workspace(obj); | ||
171 | break; | ||
172 | case IPC_GET_INPUTS: | ||
173 | pretty_print_input(obj); | ||
174 | break; | ||
175 | case IPC_GET_OUTPUTS: | ||
176 | pretty_print_output(obj); | ||
177 | break; | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
21 | int main(int argc, char **argv) { | 182 | int main(int argc, char **argv) { |
22 | static int quiet = 0; | 183 | static int quiet = 0; |
184 | static int raw = 0; | ||
23 | char *socket_path = NULL; | 185 | char *socket_path = NULL; |
24 | char *cmdtype = NULL; | 186 | char *cmdtype = NULL; |
25 | 187 | ||
@@ -28,9 +190,10 @@ int main(int argc, char **argv) { | |||
28 | static struct option long_options[] = { | 190 | static struct option long_options[] = { |
29 | {"help", no_argument, NULL, 'h'}, | 191 | {"help", no_argument, NULL, 'h'}, |
30 | {"quiet", no_argument, NULL, 'q'}, | 192 | {"quiet", no_argument, NULL, 'q'}, |
31 | {"version", no_argument, NULL, 'v'}, | 193 | {"raw", no_argument, NULL, 'r'}, |
32 | {"socket", required_argument, NULL, 's'}, | 194 | {"socket", required_argument, NULL, 's'}, |
33 | {"type", required_argument, NULL, 't'}, | 195 | {"type", required_argument, NULL, 't'}, |
196 | {"version", no_argument, NULL, 'v'}, | ||
34 | {0, 0, 0, 0} | 197 | {0, 0, 0, 0} |
35 | }; | 198 | }; |
36 | 199 | ||
@@ -39,14 +202,17 @@ int main(int argc, char **argv) { | |||
39 | "\n" | 202 | "\n" |
40 | " -h, --help Show help message and quit.\n" | 203 | " -h, --help Show help message and quit.\n" |
41 | " -q, --quiet Be quiet.\n" | 204 | " -q, --quiet Be quiet.\n" |
42 | " -v, --version Show the version number and quit.\n" | 205 | " -r, --raw Use raw output even if using a tty\n" |
43 | " -s, --socket <socket> Use the specified socket.\n" | 206 | " -s, --socket <socket> Use the specified socket.\n" |
44 | " -t, --type <type> Specify the message type.\n"; | 207 | " -t, --type <type> Specify the message type.\n" |
208 | " -v, --version Show the version number and quit.\n"; | ||
209 | |||
210 | raw = !isatty(STDOUT_FILENO); | ||
45 | 211 | ||
46 | int c; | 212 | int c; |
47 | while (1) { | 213 | while (1) { |
48 | int option_index = 0; | 214 | int option_index = 0; |
49 | c = getopt_long(argc, argv, "hqvs:t:", long_options, &option_index); | 215 | c = getopt_long(argc, argv, "hqrs:t:v", long_options, &option_index); |
50 | if (c == -1) { | 216 | if (c == -1) { |
51 | break; | 217 | break; |
52 | } | 218 | } |
@@ -54,6 +220,9 @@ int main(int argc, char **argv) { | |||
54 | case 'q': // Quiet | 220 | case 'q': // Quiet |
55 | quiet = 1; | 221 | quiet = 1; |
56 | break; | 222 | break; |
223 | case 'r': // Raw | ||
224 | raw = 1; | ||
225 | break; | ||
57 | case 's': // Socket | 226 | case 's': // Socket |
58 | socket_path = strdup(optarg); | 227 | socket_path = strdup(optarg); |
59 | break; | 228 | break; |
@@ -125,7 +294,12 @@ int main(int argc, char **argv) { | |||
125 | printf("%s\n", resp); | 294 | printf("%s\n", resp); |
126 | ret = 1; | 295 | ret = 1; |
127 | } else { | 296 | } else { |
128 | printf("%s\n", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | 297 | if (raw) { |
298 | printf("%s\n", json_object_to_json_string_ext(obj, | ||
299 | JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | ||
300 | } else { | ||
301 | pretty_print(type, obj); | ||
302 | } | ||
129 | free(obj); | 303 | free(obj); |
130 | } | 304 | } |
131 | } | 305 | } |
diff --git a/swaymsg/swaymsg.1.txt b/swaymsg/swaymsg.1.txt index c3af28d5..1f03bee3 100644 --- a/swaymsg/swaymsg.1.txt +++ b/swaymsg/swaymsg.1.txt | |||
@@ -23,8 +23,8 @@ Options | |||
23 | *-q, \--quiet*:: | 23 | *-q, \--quiet*:: |
24 | Sends the IPC message but does not print the response from sway. | 24 | Sends the IPC message but does not print the response from sway. |
25 | 25 | ||
26 | *-v, \--version*:: | 26 | *-r, \--raw*:: |
27 | Print the version (of swaymsg) and quit. | 27 | Use raw output even if using a tty. |
28 | 28 | ||
29 | *-s, --socket* <path>:: | 29 | *-s, --socket* <path>:: |
30 | Use the specified socket path. Otherwise, swaymsg will ask sway where the | 30 | Use the specified socket path. Otherwise, swaymsg will ask sway where the |
@@ -33,6 +33,9 @@ Options | |||
33 | *-t, \--type* <type>:: | 33 | *-t, \--type* <type>:: |
34 | Specify the type of IPC message. See below. | 34 | Specify the type of IPC message. See below. |
35 | 35 | ||
36 | *-v, \--version*:: | ||
37 | Print the version (of swaymsg) and quit. | ||
38 | |||
36 | IPC Message Types | 39 | IPC Message Types |
37 | ----------------- | 40 | ----------------- |
38 | 41 | ||