aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2015-08-26 18:48:50 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2015-08-26 18:48:50 -0400
commiteb53f173c5cc3739149b3fafc50ab55d5503a649 (patch)
tree49eae9ae84adbe27d639005515111b324a328fad
parentsome function documentation, fixed gaps on config reload (diff)
parentfixed container_map (diff)
downloadsway-eb53f173c5cc3739149b3fafc50ab55d5503a649.tar.gz
sway-eb53f173c5cc3739149b3fafc50ab55d5503a649.tar.zst
sway-eb53f173c5cc3739149b3fafc50ab55d5503a649.zip
Merge pull request #137 from minus7/json
added json-c lib and implemented IPC get_version
-rw-r--r--CMake/FindJsonC.cmake17
-rw-r--r--CMakeLists.txt3
-rw-r--r--sway/container.c5
-rw-r--r--sway/ipc.c126
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
10find_package(PkgConfig)
11pkg_check_modules(PC_JSONC QUIET JSONC)
12find_path(JSONC_INCLUDE_DIRS NAMES json-c/json.h HINTS ${PC_JSONC_INCLUDE_DIRS})
13find_library(JSONC_LIBRARIES NAMES json-c HINTS ${PC_JSONC_LIBRARY_DIRS})
14
15include(FindPackageHandleStandardArgs)
16find_package_handle_standard_args(JSONC DEFAULT_MSG JSONC_LIBRARIES JSONC_INCLUDE_DIRS)
17mark_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)
22find_package(WLC REQUIRED) 22find_package(WLC REQUIRED)
23find_package(A2X REQUIRED) 23find_package(A2X REQUIRED)
24find_package(PCRE REQUIRED) 24find_package(PCRE REQUIRED)
25find_package(JsonC REQUIRED)
25 26
26FILE(GLOB sources ${PROJECT_SOURCE_DIR}/sway/*.c) 27FILE(GLOB sources ${PROJECT_SOURCE_DIR}/sway/*.c)
27 28
28include_directories( 29include_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
44INSTALL( 47INSTALL(
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
504void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { 504void 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 }
diff --git a/sway/ipc.c b/sway/ipc.c
index 0b36d758..d278c0a0 100644
--- a/sway/ipc.c
+++ b/sway/ipc.c
@@ -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);
40void ipc_client_disconnect(struct ipc_client *client); 41void ipc_client_disconnect(struct ipc_client *client);
41void ipc_client_handle_command(struct ipc_client *client); 42void ipc_client_handle_command(struct ipc_client *client);
42bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); 43bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
43void ipc_get_workspaces_callback(swayc_t *container, void *data); 44void ipc_get_workspaces_callback(swayc_t *workspace, void *data);
44void ipc_get_outputs_callback(swayc_t *container, void *data); 45void ipc_get_outputs_callback(swayc_t *container, void *data);
45 46
46char *json_list(list_t *items);
47
48void ipc_init(void) { 47void 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
262char *json_list(list_t *items) { 271void 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));
274void 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
302void ipc_get_outputs_callback(swayc_t *container, void *data) { 294void 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}