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