1 | #include <stdlib.h> |
---|
2 | #include <stdio.h> |
---|
3 | #include <string.h> |
---|
4 | |
---|
5 | #include "../shared/sockets.h" |
---|
6 | #include "../shared/debug.h" |
---|
7 | |
---|
8 | #include "screen.h" |
---|
9 | #include "widget.h" |
---|
10 | |
---|
11 | |
---|
12 | char *types[] = {"none", |
---|
13 | "string", |
---|
14 | "hbar", |
---|
15 | "vbar", |
---|
16 | "icon", |
---|
17 | "title", |
---|
18 | "scroller", |
---|
19 | "frame", |
---|
20 | "num", |
---|
21 | //"", |
---|
22 | NULL, |
---|
23 | }; |
---|
24 | |
---|
25 | |
---|
26 | static widget * widget_finder(LL *list, char *id); |
---|
27 | static int widget_remover(LL *list, widget *w); |
---|
28 | |
---|
29 | |
---|
30 | widget * widget_create() |
---|
31 | { |
---|
32 | widget *w; |
---|
33 | |
---|
34 | debug("widget_create()\n"); |
---|
35 | |
---|
36 | w = malloc(sizeof(widget)); |
---|
37 | if(!w) |
---|
38 | { |
---|
39 | fprintf(stderr, "widget_create: Error allocating widget\n"); |
---|
40 | return NULL; |
---|
41 | } |
---|
42 | |
---|
43 | w->id = NULL; |
---|
44 | w->type = 0; |
---|
45 | w->x = 1; |
---|
46 | w->y = 1; |
---|
47 | w->wid = 0; |
---|
48 | w->hgt = 0; |
---|
49 | w->left = 1; |
---|
50 | w->top = 1; |
---|
51 | w->right = 0; |
---|
52 | w->bottom = 0; |
---|
53 | w->length = 1; |
---|
54 | w->speed = 1; |
---|
55 | w->text = NULL; |
---|
56 | w->kids = NULL; |
---|
57 | |
---|
58 | return w; |
---|
59 | } |
---|
60 | |
---|
61 | int widget_destroy(widget *w) |
---|
62 | { |
---|
63 | LL * list; |
---|
64 | widget *foo; |
---|
65 | |
---|
66 | if(!w) return -1; |
---|
67 | |
---|
68 | debug("widget_destroy(%s)\n", w->id); |
---|
69 | |
---|
70 | if(w->id) free(w->id); |
---|
71 | //debug("widget_destroy: id...\n"); |
---|
72 | if(w->text) free(w->text); |
---|
73 | //debug("widget_destroy: text...\n"); |
---|
74 | |
---|
75 | // TODO: Free kids! |
---|
76 | if(w->kids) |
---|
77 | { |
---|
78 | list = w->kids; |
---|
79 | LL_Rewind(list); |
---|
80 | do { |
---|
81 | foo = LL_Get(list); |
---|
82 | if(foo) |
---|
83 | widget_destroy(foo); |
---|
84 | } while( 0 == LL_Next(list) ); |
---|
85 | |
---|
86 | LL_Destroy(list); |
---|
87 | w->kids = NULL; |
---|
88 | } |
---|
89 | |
---|
90 | free(w); |
---|
91 | //debug("widget_destroy: widget...\n"); |
---|
92 | |
---|
93 | return 0; |
---|
94 | } |
---|
95 | |
---|
96 | widget * widget_find(screen *s, char *id) |
---|
97 | { |
---|
98 | //widget *w, *err; |
---|
99 | |
---|
100 | if(!s) return NULL; |
---|
101 | if(!id) return NULL; |
---|
102 | |
---|
103 | debug("widget_find(%s)\n", id); |
---|
104 | |
---|
105 | return widget_finder(s->widgets, id); |
---|
106 | /* |
---|
107 | LL_Rewind(s->widgets); |
---|
108 | do { |
---|
109 | w = LL_Get(s->widgets); |
---|
110 | if( (w) && (0 == strcmp(w->id, id))) |
---|
111 | { |
---|
112 | debug("widget_find: Found %s\n", id); |
---|
113 | return w; |
---|
114 | } |
---|
115 | // TODO: Search kids too! |
---|
116 | if( w->type == WID_FRAME ) |
---|
117 | { |
---|
118 | err = widget_finder(w->kids, id); |
---|
119 | if(err) return err; |
---|
120 | } |
---|
121 | |
---|
122 | } while(LL_Next(s->widgets) == 0); |
---|
123 | |
---|
124 | return NULL; |
---|
125 | */ |
---|
126 | } |
---|
127 | |
---|
128 | widget * widget_finder(LL *list, char *id) |
---|
129 | { |
---|
130 | widget *w, *err; |
---|
131 | |
---|
132 | if(!list) return NULL; |
---|
133 | if(!id) return NULL; |
---|
134 | |
---|
135 | debug("widget_finder(%s)\n", id); |
---|
136 | |
---|
137 | LL_Rewind(list); |
---|
138 | do { |
---|
139 | //debug("widget_finder: Iteration\n"); |
---|
140 | w = LL_Get(list); |
---|
141 | if(w) |
---|
142 | { |
---|
143 | //debug("widget_finder: ...\n"); |
---|
144 | if(0 == strcmp(w->id, id)) |
---|
145 | { |
---|
146 | debug("widget_finder: Found %s\n", id); |
---|
147 | return w; |
---|
148 | } |
---|
149 | // Search kids recursively |
---|
150 | //debug("widget_finder: ...\n"); |
---|
151 | if( w->type == WID_FRAME ) |
---|
152 | { |
---|
153 | err = widget_finder(w->kids, id); |
---|
154 | if(err) return err; |
---|
155 | } |
---|
156 | //debug("widget_finder: ...\n"); |
---|
157 | } |
---|
158 | |
---|
159 | } while(LL_Next(list) == 0); |
---|
160 | |
---|
161 | return NULL; |
---|
162 | } |
---|
163 | |
---|
164 | int widget_add(screen *s, char *id, char *type, char *in, int sock) |
---|
165 | { |
---|
166 | int i; |
---|
167 | int valid=0; |
---|
168 | int wid_type=0; |
---|
169 | widget *w, *parent; |
---|
170 | LL *list; |
---|
171 | |
---|
172 | debug("widget_add(%s, %s, %s)\n", id, type, in); |
---|
173 | |
---|
174 | |
---|
175 | if(!s) return -1; |
---|
176 | if(!id) return -1; |
---|
177 | |
---|
178 | list = s->widgets; |
---|
179 | |
---|
180 | |
---|
181 | if(0 == strcmp(id, "heartbeat")) |
---|
182 | { |
---|
183 | s->heartbeat = 1; |
---|
184 | return 0; |
---|
185 | } |
---|
186 | |
---|
187 | // Make sure this screen doesn't already exist... |
---|
188 | w = widget_find(s, id); |
---|
189 | if(w) |
---|
190 | { |
---|
191 | // already exists |
---|
192 | sock_send_string(sock, |
---|
193 | "huh? You already have a widget with that id#\n"); |
---|
194 | return 1; |
---|
195 | } |
---|
196 | |
---|
197 | // Make sure the container, if any, is real |
---|
198 | if(in) |
---|
199 | { |
---|
200 | parent = widget_find(s, in); |
---|
201 | if(!parent) |
---|
202 | { |
---|
203 | // no frame to use as parent |
---|
204 | sock_send_string(sock, "huh? Frame doesn't exist\n"); |
---|
205 | return 3; |
---|
206 | } |
---|
207 | else |
---|
208 | { |
---|
209 | if(parent->type == WID_FRAME) |
---|
210 | { |
---|
211 | list = parent->kids; |
---|
212 | if(!list) fprintf(stderr, "widget_add: Parent has no kids\n"); |
---|
213 | } |
---|
214 | else |
---|
215 | { |
---|
216 | // no frame to use as parent |
---|
217 | sock_send_string(sock, "huh? Not a frame\n"); |
---|
218 | return 4; |
---|
219 | } |
---|
220 | } |
---|
221 | } |
---|
222 | |
---|
223 | // Make sure it's a valid widget type |
---|
224 | for(i=1; types[i]; i++) |
---|
225 | { |
---|
226 | if(0 == strcmp(types[i], type)) |
---|
227 | { |
---|
228 | valid=1; |
---|
229 | wid_type=i; |
---|
230 | } |
---|
231 | } |
---|
232 | if(!valid) |
---|
233 | { |
---|
234 | // invalid widget type |
---|
235 | sock_send_string(sock, "huh? Invalid widget type\n"); |
---|
236 | return 2; |
---|
237 | } |
---|
238 | |
---|
239 | |
---|
240 | debug("widget_add: making widget\n"); |
---|
241 | |
---|
242 | |
---|
243 | // Now, make it... |
---|
244 | w = widget_create(); |
---|
245 | if(!w) |
---|
246 | { |
---|
247 | fprintf(stderr, "widget_add: Error creating widget\n"); |
---|
248 | return -1; |
---|
249 | } |
---|
250 | |
---|
251 | w->id = strdup(id); |
---|
252 | if(!w->id) |
---|
253 | { |
---|
254 | fprintf(stderr, "widget_add: Error allocating id\n"); |
---|
255 | return -1; |
---|
256 | } |
---|
257 | |
---|
258 | w->type = wid_type; |
---|
259 | |
---|
260 | // Set up the container's widget list... |
---|
261 | if(w->type == WID_FRAME) |
---|
262 | { |
---|
263 | if(!w->kids) |
---|
264 | { |
---|
265 | w->kids = LL_new(); |
---|
266 | if(!w->kids) |
---|
267 | { |
---|
268 | fprintf(stderr, "widget_add: error allocating kids for frame\n"); |
---|
269 | return -1; |
---|
270 | } |
---|
271 | } |
---|
272 | } |
---|
273 | |
---|
274 | |
---|
275 | // TODO: Check for errors here? |
---|
276 | LL_Push(list, (void *)w); |
---|
277 | |
---|
278 | |
---|
279 | return 0; |
---|
280 | } |
---|
281 | |
---|
282 | int widget_remove(screen *s, char *id, int sock) |
---|
283 | { |
---|
284 | widget *w; |
---|
285 | LL *list; |
---|
286 | |
---|
287 | debug("widget_remove(%s)\n", id); |
---|
288 | |
---|
289 | if(!s) return -1; |
---|
290 | if(!id) return -1; |
---|
291 | |
---|
292 | list = s->widgets; |
---|
293 | |
---|
294 | |
---|
295 | if(0 == strcmp(id, "heartbeat")) |
---|
296 | { |
---|
297 | s->heartbeat = 0; |
---|
298 | return 0; |
---|
299 | } |
---|
300 | |
---|
301 | // Make sure this screen *does* exist... |
---|
302 | w = widget_find(s, id); |
---|
303 | if(!w) |
---|
304 | { |
---|
305 | sock_send_string(sock, |
---|
306 | "huh? You don't have a widget with that id#\n"); |
---|
307 | debug("widget_remove: Error finding widget %s\n", id); |
---|
308 | return 1; |
---|
309 | } |
---|
310 | |
---|
311 | /* |
---|
312 | // TODO: Check for errors here? |
---|
313 | // TODO: Make this work with frames... |
---|
314 | // LL_Remove(list, (void *)w); |
---|
315 | |
---|
316 | |
---|
317 | // TODO: Check for errors here? |
---|
318 | // widget_destroy(w); |
---|
319 | */ |
---|
320 | |
---|
321 | return widget_remover(list, w); |
---|
322 | |
---|
323 | // return 0; |
---|
324 | } |
---|
325 | |
---|
326 | |
---|
327 | int widget_remover(LL *list, widget *w) |
---|
328 | { |
---|
329 | widget *foo, *bar; |
---|
330 | int err; |
---|
331 | |
---|
332 | debug("widget_remover\n"); |
---|
333 | |
---|
334 | if(!list) return 0; |
---|
335 | if(!w) return 0; |
---|
336 | |
---|
337 | |
---|
338 | // Search through the list... |
---|
339 | LL_Rewind(list); |
---|
340 | do { |
---|
341 | // Test each item |
---|
342 | foo = LL_Get(list); |
---|
343 | if(foo) |
---|
344 | { |
---|
345 | // Frames require recursion to search and/or destroy |
---|
346 | if(foo->type == WID_FRAME) |
---|
347 | { |
---|
348 | // If removing a frame, kill all its kids, too... |
---|
349 | if(foo == w) |
---|
350 | { |
---|
351 | if(!foo->kids) |
---|
352 | { |
---|
353 | fprintf(stderr, "widget_remover: frame has no kids\n"); |
---|
354 | } |
---|
355 | else // Kill the kids... |
---|
356 | { |
---|
357 | LL_Rewind(foo->kids); |
---|
358 | do { |
---|
359 | bar = LL_Get(foo->kids); |
---|
360 | err = widget_remover(foo->kids, bar); |
---|
361 | } while(0 == LL_Next(foo->kids)); |
---|
362 | |
---|
363 | // Then kill the parent... |
---|
364 | LL_Remove(list, (void *)w); |
---|
365 | widget_destroy(w); |
---|
366 | } |
---|
367 | |
---|
368 | } |
---|
369 | else // Otherwise, search the frame recursively... |
---|
370 | { |
---|
371 | if(!foo->kids) |
---|
372 | { |
---|
373 | fprintf(stderr, "widget_remover: frame has no kids\n"); |
---|
374 | } |
---|
375 | else err = widget_remover(foo->kids, w); |
---|
376 | |
---|
377 | } |
---|
378 | } |
---|
379 | else // If not a frame, remove it if it matches... |
---|
380 | { |
---|
381 | if(foo == w) |
---|
382 | { |
---|
383 | LL_Remove(list, (void *)w); |
---|
384 | widget_destroy(w); |
---|
385 | } |
---|
386 | } |
---|
387 | } |
---|
388 | } while(0 == LL_Next(list)); |
---|
389 | |
---|
390 | return 0; |
---|
391 | } |
---|