[c5c522c] | 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 | } |
---|