]> git.sur5r.net Git - i3/i3/blob - i3bar/src/outputs.c
Be more strict with encapsulation
[i3/i3] / i3bar / src / outputs.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <i3/ipc.h>
5 #include <yajl/yajl_parse.h>
6
7 #include "common.h"
8
9 struct outputs_json_params {
10     struct outputs_head *outputs;
11     i3_output           *outputs_walk;
12     char                *cur_key;
13     char                *json;
14 };
15
16 static int outputs_null_cb(void *params_) {
17     struct outputs_json_params *params = (struct outputs_json_params*) params_;
18
19     if (strcmp(params->cur_key, "current_workspace")) {
20         return 0;
21     }
22
23     FREE(params->cur_key);
24
25     return 1;
26 }
27
28 static int outputs_boolean_cb(void *params_, bool val) {
29     struct outputs_json_params *params = (struct outputs_json_params*) params_;
30
31     if (strcmp(params->cur_key, "active")) {
32         return 0;
33     }
34
35     params->outputs_walk->active = val;
36
37     FREE(params->cur_key);
38
39     return 1;
40 }
41
42 static int outputs_integer_cb(void *params_, long val) {
43     struct outputs_json_params *params = (struct outputs_json_params*) params_;
44
45     if (!strcmp(params->cur_key, "current_workspace")) {
46         params->outputs_walk->ws = (int) val;
47         FREE(params->cur_key);
48         return 1;
49     }
50
51     if (!strcmp(params->cur_key, "x")) {
52         params->outputs_walk->rect.x = (int) val;
53         FREE(params->cur_key);
54         return 1;
55     }
56
57     if (!strcmp(params->cur_key, "y")) {
58         params->outputs_walk->rect.y = (int) val;
59         FREE(params->cur_key);
60         return 1;
61     }
62
63     if (!strcmp(params->cur_key, "width")) {
64         params->outputs_walk->rect.w = (int) val;
65         FREE(params->cur_key);
66         return 1;
67     }
68
69     if (!strcmp(params->cur_key, "height")) {
70         params->outputs_walk->rect.h = (int) val;
71         FREE(params->cur_key);
72         return 1;
73     }
74
75     return 0;
76 }
77
78 static int outputs_string_cb(void *params_, const unsigned char *val, unsigned int len) {
79     struct outputs_json_params *params = (struct outputs_json_params*) params_;
80
81     if (strcmp(params->cur_key, "name")) {
82         return 0;
83     }
84
85     params->outputs_walk->name = malloc(sizeof(const unsigned char) * (len + 1));
86     strncpy(params->outputs_walk->name, (const char*) val, len);
87     params->outputs_walk->name[len] = '\0';
88
89     FREE(params->cur_key);
90
91     return 1;
92 }
93
94 static int outputs_start_map_cb(void *params_) {
95     struct outputs_json_params *params = (struct outputs_json_params*) params_;
96     i3_output *new_output = NULL;
97
98     if (params->cur_key == NULL) {
99         new_output = malloc(sizeof(i3_output));
100         new_output->name = NULL;
101         new_output->ws = 0,
102         memset(&new_output->rect, 0, sizeof(rect));
103         new_output->bar = XCB_NONE;
104
105         new_output->workspaces = malloc(sizeof(struct ws_head));
106         TAILQ_INIT(new_output->workspaces);
107
108         SLIST_INSERT_HEAD(params->outputs, new_output, slist);
109
110         params->outputs_walk = SLIST_FIRST(params->outputs);
111
112         return 1;
113     }
114
115     return 1;
116 }
117
118 static int outputs_map_key_cb(void *params_, const unsigned char *keyVal, unsigned int keyLen) {
119     struct outputs_json_params *params = (struct outputs_json_params*) params_;
120     FREE(params->cur_key);
121
122     params->cur_key = malloc(sizeof(unsigned char) * (keyLen + 1));
123     strncpy(params->cur_key, (const char*) keyVal, keyLen);
124     params->cur_key[keyLen] = '\0';
125
126     return 1;
127 }
128
129 yajl_callbacks outputs_callbacks = {
130     &outputs_null_cb,
131     &outputs_boolean_cb,
132     &outputs_integer_cb,
133     NULL,
134     NULL,
135     &outputs_string_cb,
136     &outputs_start_map_cb,
137     &outputs_map_key_cb,
138     NULL,
139     NULL,
140     NULL
141 };
142
143 void parse_outputs_json(char *json) {
144     /* FIXME: Fasciliate stream-processing, i.e. allow starting to interpret
145      * JSON in chunks */
146     struct outputs_json_params params;
147     printf(json);
148     params.outputs = malloc(sizeof(struct outputs_head));
149     SLIST_INIT(params.outputs);
150
151     params.outputs_walk = NULL;
152     params.cur_key = NULL;
153     params.json = json;
154
155     yajl_handle handle;
156     yajl_parser_config parse_conf = { 0, 0 };
157     yajl_status state;
158
159     handle = yajl_alloc(&outputs_callbacks, &parse_conf, NULL, (void*) &params);
160
161     state = yajl_parse(handle, (const unsigned char*) json, strlen(json));
162
163     /* FIXME: Propper errorhandling for JSON-parsing */
164     switch (state) {
165         case yajl_status_ok:
166             break;
167         case yajl_status_client_canceled:
168         case yajl_status_insufficient_data:
169         case yajl_status_error:
170             printf("ERROR: Could not parse outputs-reply!\n");
171             exit(EXIT_FAILURE);
172             break;
173     }
174
175     yajl_free(handle);
176
177     if (outputs != NULL) {
178         FREE_SLIST(outputs, i3_output);
179     }
180
181     outputs = params.outputs;
182 }
183
184 i3_output *get_output_by_name(char *name) {
185     i3_output *walk;
186     SLIST_FOREACH(walk, outputs, slist) {
187         if (!strcmp(walk->name, name)) {
188             break;
189         }
190     }
191
192     return walk;
193 }