]> git.sur5r.net Git - i3/i3/blob - i3bar/src/outputs.c
Draw the workspace-buttons
[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         i3_output*      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->next = NULL;
107                 new_output->bar = XCB_NONE;
108
109                 if (params->outputs == NULL) {
110                         params->outputs = new_output;
111                 } else {
112                         params->outputs_walk->next = new_output;
113                 }
114
115                 params->outputs_walk = new_output;
116                 return 1;
117         }
118
119         return 1;
120 }
121
122 static int outputs_map_key_cb(void* params_, const unsigned char* keyVal, unsigned int keyLen) {
123         struct outputs_json_params* params = (struct outputs_json_params*) params_;
124         FREE(params->cur_key);
125
126         params->cur_key = malloc(sizeof(unsigned char) * (keyLen + 1));
127         strncpy(params->cur_key, (const char*) keyVal, keyLen);
128         params->cur_key[keyLen] = '\0';
129
130         return 1;
131 }
132
133 yajl_callbacks outputs_callbacks = {
134         &outputs_null_cb,
135         &outputs_boolean_cb,
136         &outputs_integer_cb,
137         NULL,
138         NULL,
139         &outputs_string_cb,
140         &outputs_start_map_cb,
141         &outputs_map_key_cb,
142         NULL,
143         NULL,
144         NULL
145 };
146
147 void parse_outputs_json(char* json) {
148         /* FIXME: Fasciliate stream-processing, i.e. allow starting to interpret
149          * JSON in chunks */
150         struct outputs_json_params params;
151         params.outputs = NULL;
152         params.outputs_walk = NULL;
153         params.cur_key = NULL;
154         params.json = json;
155
156         yajl_handle handle;
157         yajl_parser_config parse_conf = { 0, 0 };
158         yajl_status state;
159         
160         handle = yajl_alloc(&outputs_callbacks, &parse_conf, NULL, (void*) &params);
161
162         state = yajl_parse(handle, (const unsigned char*) json, strlen(json));
163
164         /* FIXME: Propper errorhandling for JSON-parsing */
165         switch (state) {
166                 case yajl_status_ok:
167                         break;
168                 case yajl_status_client_canceled:
169                 case yajl_status_insufficient_data:
170                 case yajl_status_error:
171                         printf("ERROR: Could not parse outputs-reply!\n");
172                         exit(EXIT_FAILURE);
173                         break;
174         }
175         
176         yajl_free(handle);
177
178         free_outputs();
179         outputs = params.outputs;
180 }
181
182 void free_outputs() {
183         i3_output* tmp;
184         while (outputs != NULL) {
185                 tmp = outputs;
186                 outputs = outputs->next;
187                 FREE(tmp->name);
188                 FREE(tmp);
189         }
190 }
191
192 i3_output* get_output_by_name(char* name) {
193         if (outputs == NULL) {
194                 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
195                 return NULL;
196         }
197
198         i3_output* walk;
199
200         for (walk = outputs; walk != NULL; walk = walk->next) {
201                 if (!strcmp(walk->name, name)) {
202                         break;
203                 }
204         }
205
206         return walk;
207 }