*
* i3 - an improved dynamic tiling window manager
*
- * © 2009-2010 Michael Stapelberg and contributors
+ * © 2009-2011 Michael Stapelberg and contributors
*
* See file LICENSE for license information.
*
#include <ev.h>
#include <yajl/yajl_gen.h>
#include <yajl/yajl_parse.h>
+#include <yajl/yajl_version.h>
#include "all.h"
+char *current_socketpath = NULL;
+
/* Shorter names for all those yajl_gen_* functions */
#define y(x, ...) yajl_gen_ ## x (gen, ##__VA_ARGS__)
#define ystr(str) yajl_gen_string(gen, (unsigned char*)str, strlen(str))
char msg[buffer_size];
char *walk = msg;
- strcpy(walk, "i3-ipc");
+ strncpy(walk, "i3-ipc", buffer_size - 1);
walk += strlen("i3-ipc");
memcpy(walk, &message_size, sizeof(uint32_t));
walk += sizeof(uint32_t);
strncpy(command, (const char*)message, message_size);
LOG("IPC: received: *%s*\n", command);
const char *reply = parse_cmd((const char*)command);
- tree_render();
free(command);
/* If no reply was provided, we just use the default success message */
}
ystr("percent");
- y(double, con->percent);
+ if (con->percent == 0.0)
+ y(null);
+ else y(double, con->percent);
ystr("urgent");
- y(integer, con->urgent);
+ y(bool, con->urgent);
ystr("focused");
- y(integer, (con == focused));
+ y(bool, (con == focused));
ystr("layout");
- y(integer, con->layout);
+ switch (con->layout) {
+ case L_DEFAULT:
+ ystr("default");
+ break;
+ case L_STACKED:
+ ystr("stacked");
+ break;
+ case L_TABBED:
+ ystr("tabbed");
+ break;
+ case L_DOCKAREA:
+ ystr("dockarea");
+ break;
+ case L_OUTPUT:
+ ystr("output");
+ break;
+ }
ystr("border");
- y(integer, con->border_style);
+ switch (con->border_style) {
+ case BS_NORMAL:
+ ystr("normal");
+ break;
+ case BS_NONE:
+ ystr("none");
+ break;
+ case BS_1PIXEL:
+ ystr("1pixel");
+ break;
+ }
dump_rect(gen, "rect", con->rect);
dump_rect(gen, "window_rect", con->window_rect);
+ dump_rect(gen, "geometry", con->geometry);
ystr("name");
ystr(con->name);
ystr("nodes");
y(array_open);
Con *node;
- TAILQ_FOREACH(node, &(con->nodes_head), nodes) {
- dump_node(gen, node, inplace_restart);
+ if (con->type != CT_DOCKAREA || !inplace_restart) {
+ TAILQ_FOREACH(node, &(con->nodes_head), nodes) {
+ dump_node(gen, node, inplace_restart);
+ }
}
y(array_close);
ystr("fullscreen_mode");
y(integer, con->fullscreen_mode);
+ ystr("swallows");
+ y(array_open);
+ Match *match;
+ TAILQ_FOREACH(match, &(con->swallow_head), matches) {
+ if (match->dock != -1) {
+ y(map_open);
+ ystr("dock");
+ y(integer, match->dock);
+ ystr("insert_where");
+ y(integer, match->insert_where);
+ y(map_close);
+ }
+
+ /* TODO: the other swallow keys */
+ }
+
if (inplace_restart) {
if (con->window != NULL) {
- ystr("swallows");
- y(array_open);
y(map_open);
ystr("id");
y(integer, con->window->id);
y(map_close);
- y(array_close);
}
}
+ y(array_close);
y(map_close);
}
IPC_HANDLER(tree) {
setlocale(LC_NUMERIC, "C");
+#if YAJL_MAJOR >= 2
+ yajl_gen gen = yajl_gen_alloc(NULL);
+#else
yajl_gen gen = yajl_gen_alloc(NULL, NULL);
+#endif
dump_node(gen, croot, false);
setlocale(LC_NUMERIC, "");
const unsigned char *payload;
+#if YAJL_MAJOR >= 2
+ size_t length;
+#else
unsigned int length;
+#endif
y(get_buf, &payload, &length);
ipc_send_message(fd, payload, I3_IPC_REPLY_TYPE_TREE, length);
*
*/
IPC_HANDLER(get_workspaces) {
+#if YAJL_MAJOR >= 2
+ yajl_gen gen = yajl_gen_alloc(NULL);
+#else
yajl_gen gen = yajl_gen_alloc(NULL, NULL);
+#endif
y(array_open);
Con *focused_ws = con_get_workspace(focused);
Con *output;
TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
Con *ws;
- TAILQ_FOREACH(ws, &(output->nodes_head), nodes) {
+ TAILQ_FOREACH(ws, &(output_get_content(output)->nodes_head), nodes) {
assert(ws->type == CT_WORKSPACE);
y(map_open);
y(array_close);
const unsigned char *payload;
+#if YAJL_MAJOR >= 2
+ size_t length;
+#else
unsigned int length;
+#endif
y(get_buf, &payload, &length);
ipc_send_message(fd, payload, I3_IPC_REPLY_TYPE_WORKSPACES, length);
*
*/
IPC_HANDLER(get_outputs) {
+#if YAJL_MAJOR >= 2
+ yajl_gen gen = yajl_gen_alloc(NULL);
+#else
yajl_gen gen = yajl_gen_alloc(NULL, NULL);
+#endif
y(array_open);
Output *output;
ystr("current_workspace");
Con *ws = NULL;
- if (output->con && (ws = con_get_fullscreen_con(output->con)))
+ if (output->con && (ws = con_get_fullscreen_con(output->con, CF_OUTPUT)))
ystr(ws->name);
else y(null);
y(array_close);
const unsigned char *payload;
+#if YAJL_MAJOR >= 2
+ size_t length;
+#else
unsigned int length;
+#endif
y(get_buf, &payload, &length);
ipc_send_message(fd, payload, I3_IPC_REPLY_TYPE_OUTPUTS, length);
* Callback for the YAJL parser (will be called when a string is parsed).
*
*/
+#if YAJL_MAJOR < 2
static int add_subscription(void *extra, const unsigned char *s,
unsigned int len) {
+#else
+static int add_subscription(void *extra, const unsigned char *s,
+ size_t len) {
+#endif
ipc_client *client = extra;
DLOG("should add subscription to extra %p, sub %.*s\n", client, len, s);
memset(&callbacks, 0, sizeof(yajl_callbacks));
callbacks.yajl_string = add_subscription;
+#if YAJL_MAJOR >= 2
+ p = yajl_alloc(&callbacks, NULL, (void*)client);
+#else
p = yajl_alloc(&callbacks, NULL, NULL, (void*)client);
+#endif
stat = yajl_parse(p, (const unsigned char*)message, message_size);
if (stat != yajl_status_ok) {
unsigned char *err;
n -= strlen(I3_IPC_MAGIC);
/* The next 32 bit after the magic are the message size */
- uint32_t message_size = *((uint32_t*)message);
+ uint32_t message_size;
+ memcpy(&message_size, (uint32_t*)message, sizeof(uint32_t));
message += sizeof(uint32_t);
n -= sizeof(uint32_t);
}
/* The last 32 bits of the header are the message type */
- uint32_t message_type = *((uint32_t*)message);
+ uint32_t message_type;
+ memcpy(&message_type, (uint32_t*)message, sizeof(uint32_t));
message += sizeof(uint32_t);
n -= sizeof(uint32_t);
int ipc_create_socket(const char *filename) {
int sockfd;
+ FREE(current_socketpath);
+
char *resolved = resolve_tilde(filename);
DLOG("Creating IPC-socket at %s\n", resolved);
char *copy = sstrdup(resolved);
return -1;
}
- free(resolved);
set_nonblock(sockfd);
if (listen(sockfd, 5) < 0) {
perror("listen()");
+ free(resolved);
return -1;
}
+ current_socketpath = resolved;
return sockfd;
}