diff options
author | minus <minus@mnus.de> | 2015-08-20 21:08:13 +0200 |
---|---|---|
committer | minus <minus@mnus.de> | 2015-08-20 21:13:01 +0200 |
commit | 754793aad4c0f0b93e30804c70807e9984741ae0 (patch) | |
tree | 783cf48873e5a3944cf670461bed69b140e56fc9 | |
parent | Merge pull request #102 from taiyu-len/master (diff) | |
download | sway-754793aad4c0f0b93e30804c70807e9984741ae0.tar.gz sway-754793aad4c0f0b93e30804c70807e9984741ae0.tar.zst sway-754793aad4c0f0b93e30804c70807e9984741ae0.zip |
added IPC messages get_workspaces and get_outputs
No escaping on container names is done yet, as well as some values are
hardcoded because they don't exist yet.
-rw-r--r-- | include/stringop.h | 1 | ||||
-rw-r--r-- | sway/ipc.c | 92 | ||||
-rw-r--r-- | sway/stringop.c | 39 |
3 files changed, 132 insertions, 0 deletions
diff --git a/include/stringop.h b/include/stringop.h index a5346829..4300f9ed 100644 --- a/include/stringop.h +++ b/include/stringop.h | |||
@@ -10,5 +10,6 @@ char *code_strchr(const char *string, char delimiter); | |||
10 | char *code_strstr(const char *haystack, const char *needle); | 10 | char *code_strstr(const char *haystack, const char *needle); |
11 | int unescape_string(char *string); | 11 | int unescape_string(char *string); |
12 | char *join_args(char **argv, int argc); | 12 | char *join_args(char **argv, int argc); |
13 | char *join_list(list_t *list, char *separator); | ||
13 | 14 | ||
14 | #endif | 15 | #endif |
@@ -11,10 +11,13 @@ | |||
11 | #include <stropts.h> | 11 | #include <stropts.h> |
12 | #include <sys/ioctl.h> | 12 | #include <sys/ioctl.h> |
13 | #include <fcntl.h> | 13 | #include <fcntl.h> |
14 | #include <ctype.h> | ||
14 | #include "ipc.h" | 15 | #include "ipc.h" |
15 | #include "log.h" | 16 | #include "log.h" |
16 | #include "config.h" | 17 | #include "config.h" |
17 | #include "commands.h" | 18 | #include "commands.h" |
19 | #include "list.h" | ||
20 | #include "stringop.h" | ||
18 | 21 | ||
19 | static int ipc_socket = -1; | 22 | static int ipc_socket = -1; |
20 | static struct wlc_event_source *ipc_event_source = NULL; | 23 | static struct wlc_event_source *ipc_event_source = NULL; |
@@ -37,6 +40,10 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data); | |||
37 | void ipc_client_disconnect(struct ipc_client *client); | 40 | void ipc_client_disconnect(struct ipc_client *client); |
38 | void ipc_client_handle_command(struct ipc_client *client); | 41 | void ipc_client_handle_command(struct ipc_client *client); |
39 | bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); | 42 | bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); |
43 | void ipc_get_workspaces_callback(swayc_t *container, void *data); | ||
44 | void ipc_get_outputs_callback(swayc_t *container, void *data); | ||
45 | |||
46 | char *json_list(list_t *items); | ||
40 | 47 | ||
41 | void ipc_init(void) { | 48 | void ipc_init(void) { |
42 | ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); | 49 | ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); |
@@ -195,6 +202,26 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
195 | ipc_send_reply(client, reply, (uint32_t) length); | 202 | ipc_send_reply(client, reply, (uint32_t) length); |
196 | break; | 203 | break; |
197 | } | 204 | } |
205 | case IPC_GET_WORKSPACES: | ||
206 | { | ||
207 | list_t *workspaces = create_list(); | ||
208 | container_map(&root_container, ipc_get_workspaces_callback, workspaces); | ||
209 | char *json = json_list(workspaces); | ||
210 | free_flat_list(workspaces); | ||
211 | ipc_send_reply(client, json, strlen(json)); | ||
212 | free(json); | ||
213 | break; | ||
214 | } | ||
215 | case IPC_GET_OUTPUTS: | ||
216 | { | ||
217 | list_t *outputs = create_list(); | ||
218 | container_map(&root_container, ipc_get_outputs_callback, outputs); | ||
219 | char *json = json_list(outputs); | ||
220 | free_flat_list(outputs); | ||
221 | ipc_send_reply(client, json, strlen(json)); | ||
222 | free(json); | ||
223 | break; | ||
224 | } | ||
198 | default: | 225 | default: |
199 | sway_log(L_INFO, "Unknown IPC command type %i", client->current_command); | 226 | sway_log(L_INFO, "Unknown IPC command type %i", client->current_command); |
200 | ipc_client_disconnect(client); | 227 | ipc_client_disconnect(client); |
@@ -227,3 +254,68 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay | |||
227 | 254 | ||
228 | return true; | 255 | return true; |
229 | } | 256 | } |
257 | |||
258 | char *json_list(list_t *items) { | ||
259 | char *json_elements = join_list(items, ","); | ||
260 | size_t len = strlen(json_elements); | ||
261 | char *json = malloc(len + 3); | ||
262 | json[0] = '['; | ||
263 | memcpy(json + 1, json_elements, len); | ||
264 | json[len+1] = ']'; | ||
265 | json[len+2] = '\0'; | ||
266 | free(json_elements); | ||
267 | return json; | ||
268 | } | ||
269 | |||
270 | void ipc_get_workspaces_callback(swayc_t *container, void *data) { | ||
271 | if (container->type == C_WORKSPACE) { | ||
272 | char *json = malloc(512); // Output should usually be around 180 chars | ||
273 | int num = isdigit(container->name[0]) ? atoi(container->name) : -1; | ||
274 | // TODO: escape the name (quotation marks, unicode) | ||
275 | sprintf(json, | ||
276 | "{" | ||
277 | "\"num\":%d," | ||
278 | "\"name\":\"%s\"," | ||
279 | "\"visible\":%s," | ||
280 | "\"focused\":%s," | ||
281 | "\"rect\":{" | ||
282 | "\"x\":%d," | ||
283 | "\"y\":%d," | ||
284 | "\"width\":%d," | ||
285 | "\"height\":%d" | ||
286 | "}," | ||
287 | "\"output\":\"%s\"," | ||
288 | "\"urgent\":%s" | ||
289 | "}", | ||
290 | num, container->name, container->visible ? "true" : "false", container->is_focused ? "true" : "false", | ||
291 | container->x, container->y, container->width, container->height, | ||
292 | container->parent->name, "false" // TODO: urgent hint | ||
293 | ); | ||
294 | list_add((list_t *)data, json); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | void ipc_get_outputs_callback(swayc_t *container, void *data) { | ||
299 | if (container->type == C_OUTPUT) { | ||
300 | char *json = malloc(512); // Output should usually be around 130 chars | ||
301 | // TODO: escape the name (quotation marks, unicode) | ||
302 | sprintf(json, | ||
303 | "{" | ||
304 | "\"name\":\"%s\"," | ||
305 | "\"active\":%s," | ||
306 | "\"primary\":%s," | ||
307 | "\"rect\":{" | ||
308 | "\"x\":%d," | ||
309 | "\"y\":%d," | ||
310 | "\"width\":%d," | ||
311 | "\"height\":%d" | ||
312 | "}," | ||
313 | "\"current_workspace\":\"%s\"" | ||
314 | "}", | ||
315 | container->name, "true", "false", // TODO: active, primary | ||
316 | container->x, container->y, container->width, container->height, | ||
317 | container->focused ? container->focused->name : "" | ||
318 | ); | ||
319 | list_add((list_t *)data, json); | ||
320 | } | ||
321 | } | ||
diff --git a/sway/stringop.c b/sway/stringop.c index 1dff97bf..c39e2c34 100644 --- a/sway/stringop.c +++ b/sway/stringop.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include "string.h" | 4 | #include "string.h" |
5 | #include "list.h" | 5 | #include "list.h" |
6 | #include <strings.h> | 6 | #include <strings.h> |
7 | #include <log.h> | ||
7 | 8 | ||
8 | /* Note: This returns 8 characters for trimmed_start per tab character. */ | 9 | /* Note: This returns 8 characters for trimmed_start per tab character. */ |
9 | char *strip_whitespace(char *_str, int *trimmed_start) { | 10 | char *strip_whitespace(char *_str, int *trimmed_start) { |
@@ -197,3 +198,41 @@ char *join_args(char **argv, int argc) { | |||
197 | res[len - 1] = '\0'; | 198 | res[len - 1] = '\0'; |
198 | return res; | 199 | return res; |
199 | } | 200 | } |
201 | |||
202 | /* | ||
203 | * Join a list of strings, adding separator in between. Separator can be NULL. | ||
204 | */ | ||
205 | char *join_list(list_t *list, char *separator) { | ||
206 | if (!sway_assert(list != NULL, "list != NULL") || list->length == 0) { | ||
207 | return NULL; | ||
208 | } | ||
209 | |||
210 | size_t len = 1; // NULL terminator | ||
211 | size_t sep_len = 0; | ||
212 | if (separator != NULL) { | ||
213 | sep_len = strlen(separator); | ||
214 | len += (list->length - 1) * sep_len; | ||
215 | } | ||
216 | |||
217 | for (int i = 0; i < list->length; i++) { | ||
218 | len += strlen(list->items[i]); | ||
219 | } | ||
220 | |||
221 | char *res = malloc(len); | ||
222 | |||
223 | char *p = res + strlen(list->items[0]); | ||
224 | strcpy(res, list->items[0]); | ||
225 | |||
226 | for (int i = 1; i < list->length; i++) { | ||
227 | if (sep_len) { | ||
228 | memcpy(p, separator, sep_len); | ||
229 | p += sep_len; | ||
230 | } | ||
231 | strcpy(p, list->items[i]); | ||
232 | p += strlen(list->items[i]); | ||
233 | } | ||
234 | |||
235 | *p = '\0'; | ||
236 | |||
237 | return res; | ||
238 | } | ||