]> git.sur5r.net Git - i3/i3/blob - i3bar/src/outputs.c
Modify the active-flag on parsing the output-list
[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     bool                init;
15 };
16
17 static int outputs_null_cb(void *params_) {
18     struct outputs_json_params *params = (struct outputs_json_params*) params_;
19
20     if (strcmp(params->cur_key, "current_workspace")) {
21         return 0;
22     }
23
24     FREE(params->cur_key);
25
26     return 1;
27 }
28
29 static int outputs_boolean_cb(void *params_, bool val) {
30     struct outputs_json_params *params = (struct outputs_json_params*) params_;
31
32     if (strcmp(params->cur_key, "active")) {
33         return 0;
34     }
35
36     params->outputs_walk->active = val;
37
38     FREE(params->cur_key);
39
40     return 1;
41 }
42
43 static int outputs_integer_cb(void *params_, long val) {
44     struct outputs_json_params *params = (struct outputs_json_params*) params_;
45
46     if (!strcmp(params->cur_key, "current_workspace")) {
47         params->outputs_walk->ws = (int) val;
48         FREE(params->cur_key);
49         return 1;
50     }
51
52     if (!strcmp(params->cur_key, "x")) {
53         params->outputs_walk->rect.x = (int) val;
54         FREE(params->cur_key);
55         return 1;
56     }
57
58     if (!strcmp(params->cur_key, "y")) {
59         params->outputs_walk->rect.y = (int) val;
60         FREE(params->cur_key);
61         return 1;
62     }
63
64     if (!strcmp(params->cur_key, "width")) {
65         params->outputs_walk->rect.w = (int) val;
66         FREE(params->cur_key);
67         return 1;
68     }
69
70     if (!strcmp(params->cur_key, "height")) {
71         params->outputs_walk->rect.h = (int) val;
72         FREE(params->cur_key);
73         return 1;
74     }
75
76     return 0;
77 }
78
79 static int outputs_string_cb(void *params_, const unsigned char *val, unsigned int len) {
80     struct outputs_json_params *params = (struct outputs_json_params*) params_;
81
82     if (strcmp(params->cur_key, "name")) {
83         return 0;
84     }
85
86     char *name = malloc(sizeof(const unsigned char) * (len + 1));
87     strncpy(name, (const char*) val, len);
88     name[len] = '\0';
89
90     params->outputs_walk->name = name;
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         params->outputs_walk = new_output;
112
113         return 1;
114     }
115
116     return 1;
117 }
118
119 static int outputs_end_map_cb(void *params_) {
120     struct outputs_json_params *params = (struct outputs_json_params*) params_;
121
122     i3_output *target = get_output_by_name(params->outputs_walk->name);
123
124     if (target == NULL) {
125         SLIST_INSERT_HEAD(outputs, params->outputs_walk, slist);
126     } else {
127         target->active = params->outputs_walk->active;
128         target->ws = params->outputs_walk->ws;
129         target->rect = params->outputs_walk->rect;
130     }
131     return 1;
132 }
133
134 static int outputs_map_key_cb(void *params_, const unsigned char *keyVal, unsigned int keyLen) {
135     struct outputs_json_params *params = (struct outputs_json_params*) params_;
136     FREE(params->cur_key);
137
138     params->cur_key = malloc(sizeof(unsigned char) * (keyLen + 1));
139     strncpy(params->cur_key, (const char*) keyVal, keyLen);
140     params->cur_key[keyLen] = '\0';
141
142     return 1;
143 }
144
145 yajl_callbacks outputs_callbacks = {
146     &outputs_null_cb,
147     &outputs_boolean_cb,
148     &outputs_integer_cb,
149     NULL,
150     NULL,
151     &outputs_string_cb,
152     &outputs_start_map_cb,
153     &outputs_map_key_cb,
154     &outputs_end_map_cb,
155     NULL,
156     NULL
157 };
158
159 void init_outputs() {
160     outputs = malloc(sizeof(struct outputs_head));
161     SLIST_INIT(outputs);
162 }
163
164 void parse_outputs_json(char *json) {
165     struct outputs_json_params params;
166
167     params.outputs_walk = NULL;
168     params.cur_key = NULL;
169     params.json = json;
170
171     yajl_handle handle;
172     yajl_parser_config parse_conf = { 0, 0 };
173     yajl_status state;
174
175     handle = yajl_alloc(&outputs_callbacks, &parse_conf, NULL, (void*) &params);
176
177     state = yajl_parse(handle, (const unsigned char*) json, strlen(json));
178
179     /* FIXME: Propper errorhandling for JSON-parsing */
180     switch (state) {
181         case yajl_status_ok:
182             break;
183         case yajl_status_client_canceled:
184         case yajl_status_insufficient_data:
185         case yajl_status_error:
186             printf("ERROR: Could not parse outputs-reply!\n");
187             exit(EXIT_FAILURE);
188             break;
189     }
190
191     yajl_free(handle);
192 }
193
194 i3_output *get_output_by_name(char *name) {
195     i3_output *walk;
196     if (name == NULL) {
197         return NULL;
198     }
199     SLIST_FOREACH(walk, outputs, slist) {
200         if (!strcmp(walk->name, name)) {
201             break;
202         }
203     }
204
205     return walk;
206 }