2 * vim:ts=4:sw=4:expandtab
4 * i3bar - an xcb-based status- and ws-bar for i3
5 * © 2010 Axel Wagner and contributors (see also: LICENSE)
7 * mode.c: Handle mode event and show current binding mode in the bar
14 #include <yajl/yajl_parse.h>
15 #include <yajl/yajl_version.h>
19 /* A datatype to pass through the callbacks to save the state */
20 struct mode_json_params {
29 * Parse a string (change)
32 static int mode_string_cb(void *params_, const unsigned char *val, size_t len) {
33 struct mode_json_params *params = (struct mode_json_params *)params_;
35 if (!strcmp(params->cur_key, "change")) {
36 char *copy = smalloc(sizeof(const unsigned char) * (len + 1));
37 strncpy(copy, (const char *)val, len);
41 FREE(params->cur_key);
45 FREE(params->cur_key);
53 static int mode_boolean_cb(void *params_, int val) {
54 struct mode_json_params *params = (struct mode_json_params *)params_;
56 if (strcmp(params->cur_key, "pango_markup") == 0) {
57 DLOG("Setting pango_markup to %d.\n", val);
58 params->pango_markup = val;
60 FREE(params->cur_key);
64 FREE(params->cur_key);
71 * Essentially we just save it in the parsing state
74 static int mode_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
75 struct mode_json_params *params = (struct mode_json_params *)params_;
76 FREE(params->cur_key);
78 params->cur_key = smalloc(sizeof(unsigned char) * (keyLen + 1));
79 strncpy(params->cur_key, (const char *)keyVal, keyLen);
80 params->cur_key[keyLen] = '\0';
85 static int mode_end_map_cb(void *params_) {
86 struct mode_json_params *params = (struct mode_json_params *)params_;
89 params->mode->name = i3string_from_utf8(params->name);
90 i3string_set_markup(params->mode->name, params->pango_markup);
91 /* Save its rendered width */
92 params->mode->width = predict_text_width(params->mode->name);
94 DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name));
95 FREE(params->cur_key);
100 /* A datastructure to pass all these callbacks to yajl */
101 static yajl_callbacks mode_callbacks = {
102 .yajl_string = mode_string_cb,
103 .yajl_boolean = mode_boolean_cb,
104 .yajl_map_key = mode_map_key_cb,
105 .yajl_end_map = mode_end_map_cb,
109 * Start parsing the received JSON string
112 void parse_mode_json(char *json) {
113 /* FIXME: Fasciliate stream processing, i.e. allow starting to interpret
115 struct mode_json_params params;
119 params.cur_key = NULL;
121 params.mode = &binding;
126 handle = yajl_alloc(&mode_callbacks, NULL, (void *)¶ms);
128 state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
130 /* FIXME: Propper error handling for JSON parsing */
134 case yajl_status_client_canceled:
135 case yajl_status_error:
136 ELOG("Could not parse mode event!\n");
141 /* We don't want to indicate default binding mode */
142 if (strcmp("default", i3string_as_utf8(params.mode->name)) == 0)
143 I3STRING_FREE(params.mode->name);
145 /* Set the new binding mode */
146 set_current_mode(&binding);
150 FREE(params.cur_key);