#include #include #include #include "../shared/sockets.h" #include "../shared/debug.h" #include "screen.h" #include "widget.h" char *types[] = {"none", "string", "hbar", "vbar", "icon", "title", "scroller", "frame", "num", //"", NULL, }; static widget * widget_finder(LL *list, char *id); static int widget_remover(LL *list, widget *w); widget * widget_create() { widget *w; debug("widget_create()\n"); w = malloc(sizeof(widget)); if(!w) { fprintf(stderr, "widget_create: Error allocating widget\n"); return NULL; } w->id = NULL; w->type = 0; w->x = 1; w->y = 1; w->wid = 0; w->hgt = 0; w->left = 1; w->top = 1; w->right = 0; w->bottom = 0; w->length = 1; w->speed = 1; w->text = NULL; w->kids = NULL; return w; } int widget_destroy(widget *w) { LL * list; widget *foo; if(!w) return -1; debug("widget_destroy(%s)\n", w->id); if(w->id) free(w->id); //debug("widget_destroy: id...\n"); if(w->text) free(w->text); //debug("widget_destroy: text...\n"); // TODO: Free kids! if(w->kids) { list = w->kids; LL_Rewind(list); do { foo = LL_Get(list); if(foo) widget_destroy(foo); } while( 0 == LL_Next(list) ); LL_Destroy(list); w->kids = NULL; } free(w); //debug("widget_destroy: widget...\n"); return 0; } widget * widget_find(screen *s, char *id) { //widget *w, *err; if(!s) return NULL; if(!id) return NULL; debug("widget_find(%s)\n", id); return widget_finder(s->widgets, id); /* LL_Rewind(s->widgets); do { w = LL_Get(s->widgets); if( (w) && (0 == strcmp(w->id, id))) { debug("widget_find: Found %s\n", id); return w; } // TODO: Search kids too! if( w->type == WID_FRAME ) { err = widget_finder(w->kids, id); if(err) return err; } } while(LL_Next(s->widgets) == 0); return NULL; */ } widget * widget_finder(LL *list, char *id) { widget *w, *err; if(!list) return NULL; if(!id) return NULL; debug("widget_finder(%s)\n", id); LL_Rewind(list); do { //debug("widget_finder: Iteration\n"); w = LL_Get(list); if(w) { //debug("widget_finder: ...\n"); if(0 == strcmp(w->id, id)) { debug("widget_finder: Found %s\n", id); return w; } // Search kids recursively //debug("widget_finder: ...\n"); if( w->type == WID_FRAME ) { err = widget_finder(w->kids, id); if(err) return err; } //debug("widget_finder: ...\n"); } } while(LL_Next(list) == 0); return NULL; } int widget_add(screen *s, char *id, char *type, char *in, int sock) { int i; int valid=0; int wid_type=0; widget *w, *parent; LL *list; debug("widget_add(%s, %s, %s)\n", id, type, in); if(!s) return -1; if(!id) return -1; list = s->widgets; if(0 == strcmp(id, "heartbeat")) { s->heartbeat = 1; return 0; } // Make sure this screen doesn't already exist... w = widget_find(s, id); if(w) { // already exists sock_send_string(sock, "huh? You already have a widget with that id#\n"); return 1; } // Make sure the container, if any, is real if(in) { parent = widget_find(s, in); if(!parent) { // no frame to use as parent sock_send_string(sock, "huh? Frame doesn't exist\n"); return 3; } else { if(parent->type == WID_FRAME) { list = parent->kids; if(!list) fprintf(stderr, "widget_add: Parent has no kids\n"); } else { // no frame to use as parent sock_send_string(sock, "huh? Not a frame\n"); return 4; } } } // Make sure it's a valid widget type for(i=1; types[i]; i++) { if(0 == strcmp(types[i], type)) { valid=1; wid_type=i; } } if(!valid) { // invalid widget type sock_send_string(sock, "huh? Invalid widget type\n"); return 2; } debug("widget_add: making widget\n"); // Now, make it... w = widget_create(); if(!w) { fprintf(stderr, "widget_add: Error creating widget\n"); return -1; } w->id = strdup(id); if(!w->id) { fprintf(stderr, "widget_add: Error allocating id\n"); return -1; } w->type = wid_type; // Set up the container's widget list... if(w->type == WID_FRAME) { if(!w->kids) { w->kids = LL_new(); if(!w->kids) { fprintf(stderr, "widget_add: error allocating kids for frame\n"); return -1; } } } // TODO: Check for errors here? LL_Push(list, (void *)w); return 0; } int widget_remove(screen *s, char *id, int sock) { widget *w; LL *list; debug("widget_remove(%s)\n", id); if(!s) return -1; if(!id) return -1; list = s->widgets; if(0 == strcmp(id, "heartbeat")) { s->heartbeat = 0; return 0; } // Make sure this screen *does* exist... w = widget_find(s, id); if(!w) { sock_send_string(sock, "huh? You don't have a widget with that id#\n"); debug("widget_remove: Error finding widget %s\n", id); return 1; } /* // TODO: Check for errors here? // TODO: Make this work with frames... // LL_Remove(list, (void *)w); // TODO: Check for errors here? // widget_destroy(w); */ return widget_remover(list, w); // return 0; } int widget_remover(LL *list, widget *w) { widget *foo, *bar; int err; debug("widget_remover\n"); if(!list) return 0; if(!w) return 0; // Search through the list... LL_Rewind(list); do { // Test each item foo = LL_Get(list); if(foo) { // Frames require recursion to search and/or destroy if(foo->type == WID_FRAME) { // If removing a frame, kill all its kids, too... if(foo == w) { if(!foo->kids) { fprintf(stderr, "widget_remover: frame has no kids\n"); } else // Kill the kids... { LL_Rewind(foo->kids); do { bar = LL_Get(foo->kids); err = widget_remover(foo->kids, bar); } while(0 == LL_Next(foo->kids)); // Then kill the parent... LL_Remove(list, (void *)w); widget_destroy(w); } } else // Otherwise, search the frame recursively... { if(!foo->kids) { fprintf(stderr, "widget_remover: frame has no kids\n"); } else err = widget_remover(foo->kids, w); } } else // If not a frame, remove it if it matches... { if(foo == w) { LL_Remove(list, (void *)w); widget_destroy(w); } } } } while(0 == LL_Next(list)); return 0; }