]> git.sur5r.net Git - i3/i3/blob - i3bar/src/mode.c
i3bar: spelling fixes
[i3/i3] / i3bar / src / mode.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3bar - an xcb-based status- and ws-bar for i3
5  * © 2010-2012 Axel Wagner and contributors (see also: LICENSE)
6  *
7  * mode.c: Handle mode event and show current binding mode in the bar
8  *
9  */
10 #include <string.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <errno.h>
14 #include <yajl/yajl_parse.h>
15 #include <yajl/yajl_version.h>
16
17 #include "common.h"
18
19 /* A datatype to pass through the callbacks to save the state */
20 struct mode_json_params {
21     char *json;
22     char *cur_key;
23     mode *mode;
24 };
25
26 /*
27  * Parse a string (change)
28  *
29  */
30 static int mode_string_cb(void *params_, const unsigned char *val, size_t len) {
31     struct mode_json_params *params = (struct mode_json_params *)params_;
32
33     if (!strcmp(params->cur_key, "change")) {
34         /* Save the name */
35         params->mode->name = i3string_from_utf8_with_length((const char *)val, len);
36         /* Save its rendered width */
37         params->mode->width = predict_text_width(params->mode->name);
38
39         DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name));
40         FREE(params->cur_key);
41
42         return 1;
43     }
44
45     return 0;
46 }
47
48 /*
49  * Parse a key.
50  *
51  * Essentially we just save it in the parsing state
52  *
53  */
54 static int mode_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
55     struct mode_json_params *params = (struct mode_json_params *)params_;
56     FREE(params->cur_key);
57
58     params->cur_key = smalloc(sizeof(unsigned char) * (keyLen + 1));
59     strncpy(params->cur_key, (const char *)keyVal, keyLen);
60     params->cur_key[keyLen] = '\0';
61
62     return 1;
63 }
64
65 /* A datastructure to pass all these callbacks to yajl */
66 static yajl_callbacks mode_callbacks = {
67     .yajl_string = mode_string_cb,
68     .yajl_map_key = mode_map_key_cb,
69 };
70
71 /*
72  * Start parsing the received JSON string
73  *
74  */
75 void parse_mode_json(char *json) {
76     /* FIXME: Fasciliate stream processing, i.e. allow starting to interpret
77      * JSON in chunks */
78     struct mode_json_params params;
79
80     mode binding;
81
82     params.cur_key = NULL;
83     params.json = json;
84     params.mode = &binding;
85
86     yajl_handle handle;
87     yajl_status state;
88
89     handle = yajl_alloc(&mode_callbacks, NULL, (void *)&params);
90
91     state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
92
93     /* FIXME: Propper errorhandling for JSON-parsing */
94     switch (state) {
95         case yajl_status_ok:
96             break;
97         case yajl_status_client_canceled:
98         case yajl_status_error:
99             ELOG("Could not parse mode event!\n");
100             exit(EXIT_FAILURE);
101             break;
102     }
103
104     /* We don't want to indicate default binding mode */
105     if (strcmp("default", i3string_as_utf8(params.mode->name)) == 0)
106         I3STRING_FREE(params.mode->name);
107
108     /* Set the new binding mode */
109     set_current_mode(&binding);
110
111     yajl_free(handle);
112
113     FREE(params.cur_key);
114 }