diff options
-rw-r--r-- | CMake/FindJsonC.cmake | 17 | ||||
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | sway/container.c | 5 | ||||
-rw-r--r-- | sway/ipc.c | 126 |
4 files changed, 78 insertions, 73 deletions
diff --git a/CMake/FindJsonC.cmake b/CMake/FindJsonC.cmake new file mode 100644 index 00000000..2ca0df39 --- /dev/null +++ b/CMake/FindJsonC.cmake | |||
@@ -0,0 +1,17 @@ | |||
1 | # - Find json-c | ||
2 | # Find the json-c libraries | ||
3 | # | ||
4 | # This module defines the following variables: | ||
5 | # JSONC_FOUND - True if JSONC is found | ||
6 | # JSONC_LIBRARIES - JSONC libraries | ||
7 | # JSONC_INCLUDE_DIRS - JSONC include directories | ||
8 | # | ||
9 | |||
10 | find_package(PkgConfig) | ||
11 | pkg_check_modules(PC_JSONC QUIET JSONC) | ||
12 | find_path(JSONC_INCLUDE_DIRS NAMES json-c/json.h HINTS ${PC_JSONC_INCLUDE_DIRS}) | ||
13 | find_library(JSONC_LIBRARIES NAMES json-c HINTS ${PC_JSONC_LIBRARY_DIRS}) | ||
14 | |||
15 | include(FindPackageHandleStandardArgs) | ||
16 | find_package_handle_standard_args(JSONC DEFAULT_MSG JSONC_LIBRARIES JSONC_INCLUDE_DIRS) | ||
17 | mark_as_advanced(JSONC_LIBRARIES JSONC_INCLUDE_DIRS) | ||
diff --git a/CMakeLists.txt b/CMakeLists.txt index bbf61299..aad7f54d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -22,12 +22,14 @@ find_package(XKBCommon REQUIRED) | |||
22 | find_package(WLC REQUIRED) | 22 | find_package(WLC REQUIRED) |
23 | find_package(A2X REQUIRED) | 23 | find_package(A2X REQUIRED) |
24 | find_package(PCRE REQUIRED) | 24 | find_package(PCRE REQUIRED) |
25 | find_package(JsonC REQUIRED) | ||
25 | 26 | ||
26 | FILE(GLOB sources ${PROJECT_SOURCE_DIR}/sway/*.c) | 27 | FILE(GLOB sources ${PROJECT_SOURCE_DIR}/sway/*.c) |
27 | 28 | ||
28 | include_directories( | 29 | include_directories( |
29 | ${WLC_INCLUDE_DIRS} | 30 | ${WLC_INCLUDE_DIRS} |
30 | ${PCRE_INCLUDE_DIRS} | 31 | ${PCRE_INCLUDE_DIRS} |
32 | ${JSONC_INCLUDE_DIRS} | ||
31 | include/ | 33 | include/ |
32 | ) | 34 | ) |
33 | 35 | ||
@@ -39,6 +41,7 @@ target_link_libraries(sway | |||
39 | ${WLC_LIBRARIES} | 41 | ${WLC_LIBRARIES} |
40 | ${XKBCOMMON_LIBRARIES} | 42 | ${XKBCOMMON_LIBRARIES} |
41 | ${PCRE_LIBRARIES} | 43 | ${PCRE_LIBRARIES} |
44 | ${JSONC_LIBRARIES} | ||
42 | ) | 45 | ) |
43 | 46 | ||
44 | INSTALL( | 47 | INSTALL( |
diff --git a/sway/container.c b/sway/container.c index 5321e3cd..fda90e5b 100644 --- a/sway/container.c +++ b/sway/container.c | |||
@@ -152,7 +152,7 @@ swayc_t *new_workspace(swayc_t *output, const char *name) { | |||
152 | workspace->width = output->width; | 152 | workspace->width = output->width; |
153 | workspace->height = output->height; | 153 | workspace->height = output->height; |
154 | workspace->name = strdup(name); | 154 | workspace->name = strdup(name); |
155 | workspace->visible = true; | 155 | workspace->visible = false; |
156 | workspace->floating = create_list(); | 156 | workspace->floating = create_list(); |
157 | 157 | ||
158 | add_child(output, workspace); | 158 | add_child(output, workspace); |
@@ -503,18 +503,17 @@ bool swayc_is_active(swayc_t *view) { | |||
503 | 503 | ||
504 | void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { | 504 | void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { |
505 | if (container) { | 505 | if (container) { |
506 | f(container, data); | ||
506 | int i; | 507 | int i; |
507 | if (container->children) { | 508 | if (container->children) { |
508 | for (i = 0; i < container->children->length; ++i) { | 509 | for (i = 0; i < container->children->length; ++i) { |
509 | swayc_t *child = container->children->items[i]; | 510 | swayc_t *child = container->children->items[i]; |
510 | f(child, data); | ||
511 | container_map(child, f, data); | 511 | container_map(child, f, data); |
512 | } | 512 | } |
513 | } | 513 | } |
514 | if (container->floating) { | 514 | if (container->floating) { |
515 | for (i = 0; i < container->floating->length; ++i) { | 515 | for (i = 0; i < container->floating->length; ++i) { |
516 | swayc_t *child = container->floating->items[i]; | 516 | swayc_t *child = container->floating->items[i]; |
517 | f(child, data); | ||
518 | container_map(child, f, data); | 517 | container_map(child, f, data); |
519 | } | 518 | } |
520 | } | 519 | } |
@@ -12,6 +12,7 @@ | |||
12 | #include <sys/ioctl.h> | 12 | #include <sys/ioctl.h> |
13 | #include <fcntl.h> | 13 | #include <fcntl.h> |
14 | #include <ctype.h> | 14 | #include <ctype.h> |
15 | #include <json-c/json.h> | ||
15 | #include "ipc.h" | 16 | #include "ipc.h" |
16 | #include "log.h" | 17 | #include "log.h" |
17 | #include "config.h" | 18 | #include "config.h" |
@@ -40,11 +41,9 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data); | |||
40 | void ipc_client_disconnect(struct ipc_client *client); | 41 | void ipc_client_disconnect(struct ipc_client *client); |
41 | void ipc_client_handle_command(struct ipc_client *client); | 42 | void ipc_client_handle_command(struct ipc_client *client); |
42 | bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); | 43 | 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_workspaces_callback(swayc_t *workspace, void *data); |
44 | void ipc_get_outputs_callback(swayc_t *container, void *data); | 45 | void ipc_get_outputs_callback(swayc_t *container, void *data); |
45 | 46 | ||
46 | char *json_list(list_t *items); | ||
47 | |||
48 | void ipc_init(void) { | 47 | void ipc_init(void) { |
49 | ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); | 48 | ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); |
50 | if (ipc_socket == -1) { | 49 | if (ipc_socket == -1) { |
@@ -208,22 +207,32 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
208 | } | 207 | } |
209 | case IPC_GET_WORKSPACES: | 208 | case IPC_GET_WORKSPACES: |
210 | { | 209 | { |
211 | list_t *workspaces = create_list(); | 210 | json_object *workspaces = json_object_new_array(); |
212 | container_map(&root_container, ipc_get_workspaces_callback, workspaces); | 211 | container_map(&root_container, ipc_get_workspaces_callback, workspaces); |
213 | char *json = json_list(workspaces); | 212 | const char *json_string = json_object_to_json_string(workspaces); |
214 | free_flat_list(workspaces); | 213 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); |
215 | ipc_send_reply(client, json, strlen(json)); | 214 | json_object_put(workspaces); // free |
216 | free(json); | ||
217 | break; | 215 | break; |
218 | } | 216 | } |
219 | case IPC_GET_OUTPUTS: | 217 | case IPC_GET_OUTPUTS: |
220 | { | 218 | { |
221 | list_t *outputs = create_list(); | 219 | json_object *outputs = json_object_new_array(); |
222 | container_map(&root_container, ipc_get_outputs_callback, outputs); | 220 | container_map(&root_container, ipc_get_outputs_callback, outputs); |
223 | char *json = json_list(outputs); | 221 | const char *json_string = json_object_to_json_string(outputs); |
224 | free_flat_list(outputs); | 222 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); |
225 | ipc_send_reply(client, json, strlen(json)); | 223 | json_object_put(outputs); // free |
226 | free(json); | 224 | break; |
225 | } | ||
226 | case IPC_GET_VERSION: | ||
227 | { | ||
228 | json_object *json = json_object_new_object(); | ||
229 | json_object_object_add(json, "human_readable", json_object_new_string(SWAY_GIT_VERSION)); | ||
230 | json_object_object_add(json, "major", json_object_new_int(0)); | ||
231 | json_object_object_add(json, "minor", json_object_new_int(0)); | ||
232 | json_object_object_add(json, "patch", json_object_new_int(1)); | ||
233 | const char *json_string = json_object_to_json_string(json); | ||
234 | ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); | ||
235 | json_object_put(json); // free | ||
227 | break; | 236 | break; |
228 | } | 237 | } |
229 | default: | 238 | default: |
@@ -259,67 +268,44 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay | |||
259 | return true; | 268 | return true; |
260 | } | 269 | } |
261 | 270 | ||
262 | char *json_list(list_t *items) { | 271 | void ipc_get_workspaces_callback(swayc_t *workspace, void *data) { |
263 | char *json_elements = join_list(items, ","); | 272 | if (workspace->type == C_WORKSPACE) { |
264 | size_t len = strlen(json_elements); | 273 | int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1; |
265 | char *json = malloc(len + 3); | 274 | json_object *object = json_object_new_object(); |
266 | json[0] = '['; | 275 | json_object *rect = json_object_new_object(); |
267 | memcpy(json + 1, json_elements, len); | 276 | json_object_object_add(rect, "x", json_object_new_int((int32_t) workspace->x)); |
268 | json[len+1] = ']'; | 277 | json_object_object_add(rect, "y", json_object_new_int((int32_t) workspace->y)); |
269 | json[len+2] = '\0'; | 278 | json_object_object_add(rect, "width", json_object_new_int((int32_t) workspace->width)); |
270 | free(json_elements); | 279 | json_object_object_add(rect, "height", json_object_new_int((int32_t) workspace->height)); |
271 | return json; | 280 | |
272 | } | 281 | json_object_object_add(object, "num", json_object_new_int(num)); |
273 | 282 | json_object_object_add(object, "name", json_object_new_string(workspace->name)); | |
274 | void ipc_get_workspaces_callback(swayc_t *container, void *data) { | 283 | json_object_object_add(object, "visible", json_object_new_boolean(workspace->visible)); |
275 | if (container->type == C_WORKSPACE) { | 284 | bool focused = root_container.focused == workspace->parent && workspace->parent->focused == workspace; |
276 | char *json = malloc(512); // Output should usually be around 180 chars | 285 | json_object_object_add(object, "focused", json_object_new_boolean(focused)); |
277 | int num = isdigit(container->name[0]) ? atoi(container->name) : -1; | 286 | json_object_object_add(object, "rect", rect); |
278 | // TODO: escape the name (quotation marks, unicode) | 287 | json_object_object_add(object, "output", json_object_new_string(workspace->parent->name)); |
279 | sprintf(json, | 288 | json_object_object_add(object, "urgent", json_object_new_boolean(false)); |
280 | "{" | 289 | |
281 | "\"num\":%d," | 290 | json_object_array_add((json_object *)data, object); |
282 | "\"name\":\"%s\"," | ||
283 | "\"visible\":%s," | ||
284 | "\"focused\":%s," | ||
285 | "\"rect\":{" | ||
286 | "\"x\":%d," | ||
287 | "\"y\":%d," | ||
288 | "\"width\":%d," | ||
289 | "\"height\":%d" | ||
290 | "}," | ||
291 | "\"output\":\"%s\"," | ||
292 | "\"urgent\":%s" | ||
293 | "}", | ||
294 | num, container->name, container->visible ? "true" : "false", container->is_focused ? "true" : "false", | ||
295 | (int)container->x, (int)container->y, (int)container->width, (int)container->height, | ||
296 | container->parent->name, "false" // TODO: urgent hint | ||
297 | ); | ||
298 | list_add((list_t *)data, json); | ||
299 | } | 291 | } |
300 | } | 292 | } |
301 | 293 | ||
302 | void ipc_get_outputs_callback(swayc_t *container, void *data) { | 294 | void ipc_get_outputs_callback(swayc_t *container, void *data) { |
303 | if (container->type == C_OUTPUT) { | 295 | if (container->type == C_OUTPUT) { |
304 | char *json = malloc(512); // Output should usually be around 130 chars | 296 | json_object *object = json_object_new_object(); |
305 | // TODO: escape the name (quotation marks, unicode) | 297 | json_object *rect = json_object_new_object(); |
306 | sprintf(json, | 298 | json_object_object_add(rect, "x", json_object_new_int((int32_t) container->x)); |
307 | "{" | 299 | json_object_object_add(rect, "y", json_object_new_int((int32_t) container->y)); |
308 | "\"name\":\"%s\"," | 300 | json_object_object_add(rect, "width", json_object_new_int((int32_t) container->width)); |
309 | "\"active\":%s," | 301 | json_object_object_add(rect, "height", json_object_new_int((int32_t) container->height)); |
310 | "\"primary\":%s," | 302 | |
311 | "\"rect\":{" | 303 | json_object_object_add(object, "name", json_object_new_string(container->name)); |
312 | "\"x\":%d," | 304 | json_object_object_add(object, "active", json_object_new_boolean(true)); |
313 | "\"y\":%d," | 305 | json_object_object_add(object, "primary", json_object_new_boolean(false)); |
314 | "\"width\":%d," | 306 | json_object_object_add(object, "rect", rect); |
315 | "\"height\":%d" | 307 | json_object_object_add(object, "current_workspace", container->focused ? json_object_new_string(container->focused->name) : NULL); |
316 | "}," | 308 | |
317 | "\"current_workspace\":\"%s\"" | 309 | json_object_array_add((json_object *)data, object); |
318 | "}", | ||
319 | container->name, "true", "false", // TODO: active, primary | ||
320 | (int)container->x, (int)container->y, (int)container->width, (int)container->height, | ||
321 | container->focused ? container->focused->name : "" | ||
322 | ); | ||
323 | list_add((list_t *)data, json); | ||
324 | } | 310 | } |
325 | } | 311 | } |