]> git.sur5r.net Git - i3/i3/blob - i3bar/src/mode.c
Revert "use designated initializers for yajl_callbacks struct"
[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 #if YAJL_MAJOR >= 2
31 static int mode_string_cb(void *params_, const unsigned char *val, size_t len) {
32 #else
33 static int mode_string_cb(void *params_, const unsigned char *val, unsigned int len) {
34 #endif
35         struct mode_json_params *params = (struct mode_json_params*) params_;
36
37         if (!strcmp(params->cur_key, "change")) {
38
39             /* Save the name */
40             params->mode->name = i3string_from_utf8_with_length((const char *)val, len);
41             /* Save its rendered width */
42             params->mode->width = predict_text_width(params->mode->name);
43
44             DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name));
45             FREE(params->cur_key);
46
47             return 1;
48         }
49
50         return 0;
51 }
52
53 /*
54  * Parse a key.
55  *
56  * Essentially we just save it in the parsing-state
57  *
58  */
59 #if YAJL_MAJOR >= 2
60 static int mode_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
61 #else
62 static int mode_map_key_cb(void *params_, const unsigned char *keyVal, unsigned int keyLen) {
63 #endif
64     struct mode_json_params *params = (struct mode_json_params*) params_;
65     FREE(params->cur_key);
66
67     params->cur_key = smalloc(sizeof(unsigned char) * (keyLen + 1));
68     strncpy(params->cur_key, (const char*) keyVal, keyLen);
69     params->cur_key[keyLen] = '\0';
70
71     return 1;
72 }
73
74 /* A datastructure to pass all these callbacks to yajl */
75 yajl_callbacks mode_callbacks = {
76     NULL,
77     NULL,
78     NULL,
79     NULL,
80     NULL,
81     &mode_string_cb,
82     NULL,
83     &mode_map_key_cb,
84     NULL,
85     NULL,
86     NULL
87 };
88
89 /*
90  * Start parsing the received json-string
91  *
92  */
93 void parse_mode_json(char *json) {
94     /* FIXME: Fasciliate stream-processing, i.e. allow starting to interpret
95      * JSON in chunks */
96     struct mode_json_params params;
97
98     mode binding;
99
100     params.cur_key = NULL;
101     params.json = json;
102     params.mode = &binding;
103
104     yajl_handle handle;
105     yajl_status state;
106
107 #if YAJL_MAJOR < 2
108     yajl_parser_config parse_conf = { 0, 0 };
109
110     handle = yajl_alloc(&mode_callbacks, &parse_conf, NULL, (void*) &params);
111 #else
112     handle = yajl_alloc(&mode_callbacks, NULL, (void*) &params);
113 #endif
114
115     state = yajl_parse(handle, (const unsigned char*) json, strlen(json));
116
117     /* FIXME: Propper errorhandling for JSON-parsing */
118     switch (state) {
119         case yajl_status_ok:
120             break;
121         case yajl_status_client_canceled:
122 #if YAJL_MAJOR < 2
123         case yajl_status_insufficient_data:
124 #endif
125         case yajl_status_error:
126             ELOG("Could not parse mode-event!\n");
127             exit(EXIT_FAILURE);
128             break;
129     }
130
131     /* We don't want to indicate default binding mode */
132     if (strcmp("default", i3string_as_utf8(params.mode->name)) == 0)
133         I3STRING_FREE(params.mode->name);
134
135     /* Set the new binding mode */
136     set_current_mode(&binding);
137
138     yajl_free(handle);
139
140     FREE(params.cur_key);
141 }