wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit af906b93ecacd401be3a03377ec3b7fc829151ca
parent 68b921062609cf61370a552b133e9b4f006fbba6
Author: garbeam <garbeam@mmv.wmii.de>
Date:   Fri, 16 Dec 2005 20:11:44 +0200

finished container removal also in cmd/


Diffstat:
cmd/wmiibar.c | 160+++++++++++++++++++++++++++++++++++++++----------------------------------------
cmd/wmiibar2.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
cmd/wmiifs.c | 114++++++++++++++++++++++++++++++++++++++++++-------------------------------------
cmd/wmiikeys.c | 56+++++++++++++++++++++++++-------------------------------
cmd/wmiimenu.c | 160+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
5 files changed, 318 insertions(+), 258 deletions(-)

diff --git a/cmd/wmiibar.c b/cmd/wmiibar.c @@ -30,10 +30,12 @@ typedef enum { B_LAST } BarIndexes; -typedef struct { +typedef struct Item Item; +struct Item { File *root; Draw d; -} Item; + Item *next; +}; static unsigned int id = 0; static IXPServer *ixps = 0; @@ -43,10 +45,11 @@ static Window win; static XRectangle rect; static XRectangle brect; static int screen_num; -static int displayed = 0; -static char *sockfile = 0; +static Bool displayed = False; +static char *sockfile = nil; static File *file[B_LAST]; -static Container items = {0}; +static Item *items = nil; +static size_t nitems = 0; static Pixmap pmap; static XFontStruct *font; static Align align = SOUTH; @@ -194,57 +197,55 @@ static int comp_str(const void *s1, const void *s2) static void draw() { - Item *item; - unsigned int i, w, xoff = 0; + Item *i; + unsigned int idx = 0, w = 0, xoff = 0; unsigned expandable = 0; char buf[32]; - size_t size = cext_sizeof_container(&items); - if (!size) + if (!nitems) return; - expandable = blitz_strtonum(file[B_EXPANDABLE]->content, 0, size); + expandable = blitz_strtonum(file[B_EXPANDABLE]->content, 0, expandable); snprintf(buf, sizeof(buf), "/%d", expandable); if (!ixp_walk(ixps, buf)) expandable = 0; - w = 0; /* precalc */ - for (i = 0; i < size; i++) - if (i != expandable) { - item = cext_list_get_item(&items, i); - item->d.rect.width = brect.height; - if (item->d.data) { - if (!strncmp(item->d.data, "%m:", 3)) + for (i = items; i; i = i->next) { + if (idx != expandable) { + i->d.rect.width = brect.height; + if (i->d.data) { + if (!strncmp(i->d.data, "%m:", 3)) /* meter */ - item->d.rect.width = brect.height / 2; + i->d.rect.width = brect.height / 2; else - item->d.rect.width += XTextWidth(font, item->d.data, strlen(item->d.data)); + i->d.rect.width += XTextWidth(font, i->d.data, strlen(i->d.data)); } - w += item->d.rect.width; + w += i->d.rect.width; } + idx++; + } if (w > brect.width) { /* failsafe mode, give all labels same width */ - w = brect.width / size; - for (i = 0; i < size; i++) { - item = cext_list_get_item(&items, i); - item->d.rect.width = w; - } - item->d.rect.width = brect.width - item->d.rect.x; + w = brect.width / nitems; + for (i = items; i && i->next; i = i->next) + i->d.rect.width = w; + i->d.rect.width = w; + i->d.rect.width = brect.width - i->d.rect.x; } else { - item = cext_list_get_item(&items, expandable); - item->d.rect.width = brect.width - w; + idx = 0; + for (i = items; i && idx != expandable; i = i->next); + i->d.rect.width = brect.width - w; } - for (i = 0; i < size; i++) { - item = cext_list_get_item(&items, i); - item->d.font = font; - item->d.rect.x = xoff; - xoff += item->d.rect.width; - if (item->d.data && !strncmp(item->d.data, "%m:", 3)) - blitz_drawmeter(dpy, &item->d); + for (i = items; i; i = i->next) { + i->d.font = font; + i->d.rect.x = xoff; + xoff += i->d.rect.width; + if (i->d.data && !strncmp(i->d.data, "%m:", 3)) + blitz_drawmeter(dpy, &i->d); else - blitz_drawlabel(dpy, &item->d); + blitz_drawlabel(dpy, &i->d); } XCopyArea(dpy, pmap, win, gc, 0, 0, brect.width, brect.height, 0, 0); XSync(dpy, False); @@ -253,16 +254,17 @@ static void draw() static void draw_bar(void *obj, char *arg) { File *label = 0; - unsigned int i = 0, n = 0; - Item *item; + unsigned int j = 0; + Item *i, *it; char buf[512]; if (!displayed) return; - while ((item = cext_stack_get_top_item(&items))) { - cext_detach_item(&items, item); - free(item); + while ((i = items)) { + items = items->next; + free(i); } + it = items = nil; snprintf(buf, sizeof(buf), "%s", "/0"); label = ixp_walk(ixps, buf); if (!label) { @@ -283,60 +285,56 @@ static void draw_bar(void *obj, char *arg) * take order into account, directory names are used in * alphabetical order */ - n = 0; + nitems = 0; for (f = label; f; f = f->next) - n++; - paths = cext_emallocz(sizeof(char *) * n); - i = 0; + nitems++; + paths = cext_emallocz(sizeof(char *) * nitems); + j = 0; for (f = label; f; f = f->next) - paths[i++] = f->name; - qsort(paths, n, sizeof(char *), comp_str); - for (i = 0; i < n; i++) { - snprintf(buf, sizeof(buf), "/%s", paths[i]); - item = cext_emallocz(sizeof(Item)); - init_item(buf, item); - cext_attach_item(&items, item); + paths[j++] = f->name; + qsort(paths, nitems, sizeof(char *), comp_str); + for (j = 0; j < nitems; j++) { + snprintf(buf, sizeof(buf), "/%s", paths[j]); + i = cext_emallocz(sizeof(Item)); + init_item(buf, i); + if (!it) + it = items = i; + else { + it->next = i; + it = i; + } } free(paths); draw(); } } -static int comp_item_root(void *file, void *item) -{ - File *f = file; - Item *i = item; - - return f == i->root; -} - -static Item *get_item_for_file(File *f) +static Item *item_for_file(File *f) { - return cext_find_item(&items, f, comp_item_root); + Item *i; + for (i = items; i; i = i->next) { + if (f == i->root) + return i; + } + return nil; } -static void iter_buttonpress(void *item, void *bpress) +static void handle_buttonpress(XButtonPressedEvent *e) { - XButtonPressedEvent *e = bpress; - Item *i = item; + Item *i; File *p; char buf[MAX_BUF]; char path[512]; - - if (blitz_ispointinrect(e->x, e->y, &i->d.rect)) { - path[0] = 0; - wmii_get_ixppath(i->root, path, sizeof(path)); - snprintf(buf, MAX_BUF, "%s/b%upress", path, e->button); - if ((p = ixp_walk(ixps, buf))) - if (p->content) - wmii_spawn(dpy, p->content); - return; - } -} - -static void handle_buttonpress(XButtonPressedEvent *e) -{ - cext_list_iterate(&items, e, iter_buttonpress); + for (i = items; i; i = i->next) + if (blitz_ispointinrect(e->x, e->y, &i->d.rect)) { + path[0] = 0; + wmii_get_ixppath(i->root, path, sizeof(path)); + snprintf(buf, MAX_BUF, "%s/b%upress", path, e->button); + if ((p = ixp_walk(ixps, buf))) + if (p->content) + wmii_spawn(dpy, p->content); + return; + } } static void check_event(Connection * e) @@ -385,7 +383,7 @@ static void handle_after_write(IXPServer * s, File * f) buf[0] = 0; if (!strncmp(f->name, "data", 5)) { - if ((item = get_item_for_file(f->parent))) { + if ((item = item_for_file(f->parent))) { wmii_get_ixppath(f->parent, buf, sizeof(buf)); init_draw_label(buf, &item->d); draw(); diff --git a/cmd/wmiibar2.c b/cmd/wmiibar2.c @@ -72,10 +72,12 @@ static QFile qfilelist[] = { {0, 0}, }; -typedef struct { +typedef struct Map Map; +struct Map { u32 fid; Qid qid; -} Map; + Map *next; +}; typedef struct { int id; @@ -88,15 +90,15 @@ typedef struct { char event[5][256]; } Item; -static Container items = {0}; -static char *sockfile = 0; +static size_t nitems = 0; +static char *sockfile = nil; static pid_t mypid = 0; static IXPServer srv = { 0 }; static Qid root_qid; static Display *dpy; static int screen_num; -static char *align = 0; -static char *font = 0; +static char *align = nil; +static char *font = nil; /* static GC gc; static Window win; @@ -155,14 +157,13 @@ qpath_file(u64 path) } */ -static int comp_fid(void *fid, void *map) -{ - return ((Map *)map)->fid == *(u32 *)fid; -} - -static Map *fid_to_map(Container *maps, u32 fid) +static Map *fid_to_map(Map *maps, u32 fid) { - return cext_find_item(maps, &fid, comp_fid); + Map *m; + for (m = maps; m; m = m->next) + if (m->fid == fid) + return m; + return nil; } static Bool qfile_index(char *name, u16 * index) @@ -182,7 +183,7 @@ static Bool make_qid(Qid * dir, char *wname, Qid * new) const char *errstr; if (dir->type != IXP_QTDIR) return False; - new->version = 0; + new->version = nil; if (!qfile_index(wname, &idx)) { new->type = IXP_QTDIR; if (!strncmp(wname, "..", 3)) { @@ -194,7 +195,7 @@ static Bool make_qid(Qid * dir, char *wname, Qid * new) } /* check if wname is a number, otherwise file not found */ idx = (u16) cext_strtonum(wname, 1, 0xffff, &errstr); - if (errstr || cext_sizeof_container(&items) < idx) + if (errstr || nitems < idx) return False; /* found */ new->path = make_qpath(Ditem, idx, NONE); @@ -207,15 +208,18 @@ static Bool make_qid(Qid * dir, char *wname, Qid * new) static int attach(IXPServer *s, IXPConn *c) { - Container *cont = c->aux; - Map *map = cext_emallocz(sizeof(Map)); - - if (!cont) - cont = c->aux = cext_emallocz(sizeof(Container)); + Map *maps = c->aux; + Map *m, *new = cext_emallocz(sizeof(Map)); + + if (!maps) + c->aux = new; + else { + for (m = maps; m && m->next; m = m->next); + m->next = new; + } fprintf(stderr, "attaching %d %s %s\n", s->fcall.afid, s->fcall.uname, s->fcall.aname); - map->qid = root_qid; - map->fid = s->fcall.fid; - cext_attach_item(cont, map); + new->qid = root_qid; + new->fid = s->fcall.fid; s->fcall.id = RATTACH; s->fcall.qid = root_qid; return TRUE; @@ -251,15 +255,24 @@ static int walk(IXPServer * s, IXPConn * c) * the walk was complete */ if (nwqid == s->fcall.nwname) { - Container *cont = c->aux; + Map *m, *maps = c->aux; if (s->fcall.fid == s->fcall.newfid) { - cext_detach_item(cont, map); + if (maps == map) + maps = maps->next; + else { + for (m = maps; m && m->next != map; m = m->next); + m->next = map->next; + } free(map); } map = cext_emallocz(sizeof(Map)); map->qid = qid; map->fid = s->fcall.newfid; - cext_attach_item(cont, map); + for (m = maps; m && m->next; m = m->next); + if (!m) + maps = map; + else + m->next = map; } s->fcall.id = RWALK; s->fcall.nwqid = nwqid; @@ -356,14 +369,19 @@ static int _write(IXPServer *s, IXPConn *c) static int clunk(IXPServer *s, IXPConn *c) { - Container *cont = c->aux; - Map *map = fid_to_map(cont, s->fcall.fid); + Map *maps = c->aux; + Map *m, *map = fid_to_map(maps, s->fcall.fid); if (!map) { s->errstr = "invalid fid"; return FALSE; } - cext_detach_item(cont, map); + if (maps == map) + maps = maps->next; + else { + for (m = maps; m && m->next != map; m = m->next); + m->next = map->next; + } free(map); s->fcall.id = RCLUNK; return TRUE; @@ -371,11 +389,13 @@ static int clunk(IXPServer *s, IXPConn *c) static void freeconn(IXPServer * s, IXPConn * c) { - Container *cont = c->aux; - if (cont) { - free(cont); - c->aux = 0; + Map *m, *maps = c->aux; + + while ((m = maps)) { + maps = maps->next; + free(m); } + c->aux = nil; } static IXPTFunc funcs[] = { diff --git a/cmd/wmiifs.c b/cmd/wmiifs.c @@ -27,13 +27,14 @@ struct Bind { Route route[MAX_CONN * MAX_OPEN_FILES]; File *mount; char *prefix; + Bind *next; }; static Display *dpy; static IXPServer *ixps; -static char *sockfile = 0; +static char *sockfile = nil; static File *files[F_LAST]; -static Container bindings = {0}; +static Bind *bindings = nil; static void quit(void *obj, char *arg); static void bind(void *obj, char *arg); @@ -59,42 +60,44 @@ static void usage() exit(1); } -static void iter_unbind(void *bind, void *aux) -{ - Bind *b = bind; - if (b->mount) { - b->mount->content = 0; - ixp_remove(ixps, b->prefix); - if (ixps->errstr) - fprintf(stderr, "wmiifs: error on unbind %s: %s\n", b->prefix, ixps->errstr); - } -} - static void quit(void *obj, char *arg) { - cext_list_iterate(&bindings, nil, iter_unbind); + Bind *b; + while ((b = bindings)) { + bindings = bindings->next; + if (b->mount) { + b->mount->content = nil; + ixp_remove(ixps, b->prefix); + if (ixps->errstr) + fprintf(stderr, "wmiifs: error on unbind %s: %s\n", b->prefix, ixps->errstr); + } + free(b->prefix); + free(b); + } + bindings = nil; ixps->runlevel = SHUTDOWN; } -static void do_unbind(Bind * b) +static void do_unbind(Bind *bind) { - cext_detach_item(&bindings, b); - iter_unbind(b, nil); + Bind *b; + if (bind == bindings) + bindings = bind->next; + else { + for (b = bindings; b && b->next != bind; b = b->next); + b->next = bind->next; + } /* free stuff */ - deinit_client(b->client); - free(b->prefix); - free(b); -} - -static int comp_bindpath(void *path, void *bind) -{ - Bind *b = bind; - return !strncmp(b->prefix, path, strlen(b->prefix)); + deinit_client(bind->client); + free(bind->prefix); + free(bind); } static void unbind(void *obj, char *arg) { - Bind *b = cext_find_item(&bindings, arg, comp_bindpath); + Bind *b; + + for (b = bindings; b && strncmp(b->prefix, arg, strlen(b->prefix)); b = b->next); if (!b) { fprintf(stderr, "wmiifs: unbind: '%s' no such path\n", arg); @@ -105,7 +108,7 @@ static void unbind(void *obj, char *arg) static void bind(void *obj, char *arg) { - Bind *b = 0; + Bind *b, *new = nil; char cmd[1024]; char *sfile; @@ -123,19 +126,24 @@ static void bind(void *obj, char *arg) fprintf(stderr, "wmiifs: bind: '%s' without socket argument, ignoring\n", arg); return; /* shortcut with empty argument */ } - b = cext_emallocz(sizeof(Bind)); - b->client = init_ixp_client(sfile); + new = cext_emallocz(sizeof(Bind)); + new->client = init_ixp_client(sfile); - if (!b->client) { + if (!new->client) { fprintf(stderr, "wmiifs: bind: cannot connect to server '%s', ignoring\n", sfile); - free(b); + free(new); return; } - b->prefix = strdup(cmd); - b->mount = ixp_create(ixps, b->prefix); - b->mount->content = b->mount; /* shall be a directory */ - - cext_attach_item(&bindings, b); + new->prefix = strdup(cmd); + new->mount = ixp_create(ixps, new->prefix); + new->mount->content = new->mount; /* shall be a directory */ + + if (bindings) + bindings = b; + else { + for (b = bindings; b && b->next; b = b->next); + b->next = new; + } } static void handle_after_write(IXPServer * s, File * f) @@ -159,17 +167,15 @@ static void handle_after_write(IXPServer * s, File * f) static Bind *fd_to_bind(int fd, int *client_fd) { File *f = fd_to_file(ixps, fd); - unsigned int i, j; + unsigned int i; Bind *b; - size_t size = cext_sizeof_container(&bindings); if (!f) return nil; - for (i = 0; i < size; i++) { - b = cext_list_get_item(&bindings, i); - for (j = 0; j < MAX_CONN * MAX_OPEN_FILES; j++) { - if (&b->route[j].dest == f) { - *client_fd = b->route[j].src; + for (b = bindings; b; b = b->next) { + for (i = 0; i < MAX_CONN * MAX_OPEN_FILES; i++) { + if (&b->route[i].dest == f) { + *client_fd = b->route[i].src; return b; } } @@ -179,9 +185,11 @@ static Bind *fd_to_bind(int fd, int *client_fd) static File *fixp_create(IXPServer * s, char *path) { - Bind *b = cext_find_item(&bindings, path, comp_bindpath); + Bind *b; size_t len; + for (b = bindings; b && strncmp(b->prefix, path, strlen(b->prefix)); b = b->next); + if (!b) { File *f = ixp_create(s, path); return f; @@ -198,10 +206,12 @@ static File *fixp_create(IXPServer * s, char *path) static File *fixp_open(IXPServer * s, char *path) { - Bind *b = cext_find_item(&bindings, path, comp_bindpath); + Bind *b; int fd; size_t len; + for (b = bindings; b && strncmp(b->prefix, path, strlen(b->prefix)); b = b->next); + if (!b) { File *f = ixp_open(s, path); return f; @@ -219,9 +229,7 @@ static File *fixp_open(IXPServer * s, char *path) return &b->route[fd].dest; } -static size_t -fixp_read(IXPServer * s, int fd, size_t offset, void *out_buf, - size_t out_buf_len) +static size_t fixp_read(IXPServer * s, int fd, size_t offset, void *out_buf, size_t out_buf_len) { int cfd; Bind *b = fd_to_bind(fd, &cfd); @@ -241,9 +249,7 @@ fixp_read(IXPServer * s, int fd, size_t offset, void *out_buf, return result; } -static void -fixp_write(IXPServer * s, int fd, size_t offset, void *content, - size_t in_len) +static void fixp_write(IXPServer * s, int fd, size_t offset, void *content, size_t in_len) { int cfd; Bind *b = fd_to_bind(fd, &cfd); @@ -281,9 +287,11 @@ static void fixp_close(IXPServer * s, int fd) static void fixp_remove(IXPServer * s, char *path) { - Bind *b = cext_find_item(&bindings, path, comp_bindpath); + Bind *b; size_t len; + for (b = bindings; b && strncmp(b->prefix, path, strlen(b->prefix)); b = b->next); + if (!b) { ixp_remove(s, path); return; diff --git a/cmd/wmiikeys.c b/cmd/wmiikeys.c @@ -34,11 +34,12 @@ struct Shortcut { char name[MAX_BUF]; unsigned long mod; KeyCode key; - Shortcut *next; File *cmdfile; + Shortcut *snext; + Shortcut *next; }; -static IXPServer *ixps = 0; +static IXPServer *ixps = nil; static Display *dpy; static GC gc; static Window win; @@ -46,8 +47,8 @@ static Window root; static XRectangle krect; static XRectangle rect; static int screen_num; -static char *sockfile = 0; -static Container shortcuts = {0}; +static char *sockfile = nil; +static Shortcut *shortcuts = nil; static File *files[K_LAST]; static int grabkb = 0; static unsigned int num_lock_mask, valid_mask; @@ -126,8 +127,8 @@ static void create_shortcut(File * f) if (!s) r = s = cext_emallocz(sizeof(Shortcut)); else { - s->next = cext_emallocz(sizeof(Shortcut)); - s = s->next; + s->snext = cext_emallocz(sizeof(Shortcut)); + s = s->snext; } cext_strlcpy(s->name, chain[i], MAX_BUF); k = strrchr(chain[i], '-'); @@ -140,15 +141,20 @@ static void create_shortcut(File * f) } if (r) { s->cmdfile = f; - cext_attach_item(&shortcuts, r); + if (!shortcuts) + shortcuts = r; + else { + for (s = shortcuts; s && s->next; s = s->next); + s->next = r; + } grab_shortcut(r); } } static void destroy_shortcut(Shortcut * s, int ungrab) { - if (s->next) - destroy_shortcut(s->next, 0); + if (s->snext) + destroy_shortcut(s->snext, 0); if (ungrab) ungrab_shortcut(s); free(s); @@ -191,7 +197,7 @@ static void handle_shortcut_chain(Window w, Shortcut * processed, char *prefix, { unsigned long mod; KeyCode key; - Shortcut *s = processed->next; + Shortcut *s = processed->snext; if (grab) { XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); @@ -206,7 +212,7 @@ static void handle_shortcut_chain(Window w, Shortcut * processed, char *prefix, } else if ((s->mod == mod) && (s->key == key)) { if (s->cmdfile && s->cmdfile->content) wmii_spawn(dpy, s->cmdfile->content); - else if (s->next) { + else if (s->snext) { snprintf(buf, sizeof(buf), "%s/%s", prefix, s->name); handle_shortcut_chain(w, s, buf, 0); } @@ -218,23 +224,13 @@ static void handle_shortcut_chain(Window w, Shortcut * processed, char *prefix, } } -static int comp_shortcut(void *comp_short, void *shortcut) -{ - Shortcut *comp = comp_short; - Shortcut *s = shortcut; - return (s->mod == comp->mod) && (s->key == comp->key); -} - static void handle_shortcut_gkb(Window w, unsigned long mod, KeyCode key) { - Shortcut comp, *s; + Shortcut *s; if (!files[K_LOOKUP]->content) return; - comp.mod = mod; - comp.key = key; - - s = cext_find_item(&shortcuts, &comp, comp_shortcut); + for (s = shortcuts; s && ((s->mod != mod) && (s->key != key)); s = s->next); if (s && s->cmdfile && s->cmdfile->content) { wmii_spawn(dpy, s->cmdfile->content); return; @@ -244,19 +240,16 @@ static void handle_shortcut_gkb(Window w, unsigned long mod, KeyCode key) static void handle_shortcut(Window w, unsigned long mod, KeyCode key) { - Shortcut comp, *s; + Shortcut *s; if (!files[K_LOOKUP]->content) return; - comp.mod = mod; - comp.key = key; - - s = cext_find_item(&shortcuts, &comp, comp_shortcut); + for (s = shortcuts; s && ((s->mod != mod) && (s->key != key)); s = s->next); if (s && s->cmdfile && s->cmdfile->content) { wmii_spawn(dpy, s->cmdfile->content); return; } - if (s && s->next) + if (s && s->snext) handle_shortcut_chain(w, s, s->name, 1); } @@ -278,10 +271,11 @@ static void update() return; /* cannot update */ /* destroy existing shortcuts if any */ - while ((s = cext_stack_get_top_item(&shortcuts))) { - cext_detach_item(&shortcuts, s); + while ((s = shortcuts)) { + shortcuts = shortcuts->next; destroy_shortcut(s, 1); } + shortcuts = nil; if (grabkb) { XGrabKeyboard(dpy, root, True, GrabModeAsync, diff --git a/cmd/wmiimenu.c b/cmd/wmiimenu.c @@ -40,6 +40,13 @@ enum { OFF_NEXT, OFF_PREV, OFF_CURR, OFF_LAST }; +typedef struct Item Item; +struct Item { + File *file; + Item *next; + Item *prev; +}; + static IXPServer *ixps = 0; static Display *dpy; static GC gc; @@ -49,14 +56,16 @@ static XRectangle mrect; static int screen_num; static char *sockfile = 0; static File *files[M_LAST]; -static Container items = {0}; -static Container history = {0}; -static int offset[OFF_LAST]; +static size_t nitems = 0; +static Item *sel = nil; +static Item *items = nil; +static Item *selhist = nil; +static Item *history = nil; +static Item *offset[OFF_LAST]; static unsigned int cmdw = 0; static Pixmap pmap; static const int seek = 30; /* 30px */ static XFontStruct *font; -static unsigned int sel = 0; static Align align = SOUTH; static void check_event(Connection * c); @@ -65,7 +74,7 @@ static void handle_kpress(XKeyEvent * e); static void set_text(char *text); static void quit(void *obj, char *arg); static void display(void *obj, char *arg); -static int update_items(char *prefix); +static size_t update_items(char *prefix); static Action acttbl[2] = { {"quit", quit}, @@ -88,21 +97,31 @@ static void usage() static void add_history(char *cmd) { + Item *h, *new; char buf[MAX_BUF]; snprintf(buf, MAX_BUF, "/history/%ld", (long) time(0)); - cext_attach_item(&history, wmii_create_ixpfile(ixps, buf, cmd)); + + new = cext_emallocz(sizeof(Item)); + new->file = wmii_create_ixpfile(ixps, buf, cmd); + for (h = history; h && h->next; h = h->next); + if (!h) + history = new; + else { + h->next = new; + new->prev = h; + } + selhist = new; } static void exec_item(char *cmd) { - File *item = cext_list_get_item(&items, sel); char *rc = cmd; if (!cmd || cmd[0] == 0) return; - if (item && item->size) - rc = cmd = item->content; + if (sel && sel->file->size) + rc = cmd = sel->file->content; add_history(cmd); if (files[M_PRE_COMMAND]->content) { @@ -168,34 +187,35 @@ void set_text(char *text) static void update_offsets() { - File *item; - unsigned int i, w = cmdw + 2 * seek; + Item *i; + unsigned int w = cmdw + 2 * seek; - if (!cext_stack_get_top_item(&items)) + if (!sel) return; /* calc next offset */ - for (i = offset[OFF_CURR]; (item = cext_list_get_item(&items, i)); i++) { - w += XTextWidth(font, item->content, strlen(item->content)) + mrect.height; + for (i = offset[OFF_CURR]; i; i = i->next) { + w += XTextWidth(font, i->file->content, strlen(i->file->content)) + mrect.height; if (w > mrect.width) break; } offset[OFF_NEXT] = i; w = cmdw + 2 * seek; - for (i = offset[OFF_CURR] - 1; (i >= 0) && (item = cext_list_get_item(&items, i)); i--) { - w += XTextWidth(font, item->content, strlen(item->content)) + mrect.height; + for (i = offset[OFF_CURR]->prev; i; i = i->prev) { + w += XTextWidth(font, i->file->content, strlen(i->file->content)) + mrect.height; if (w > mrect.width) break; } - offset[OFF_PREV] = i + 1; + offset[OFF_PREV] = i->next; } -static int update_items(char *pattern) +static size_t update_items(char *pattern) { - size_t plen = pattern ? strlen(pattern) : 0, len, max = 0, size; + size_t plen = pattern ? strlen(pattern) : 0, len, max = 0; int matched = pattern ? plen == 0 : 1; File *f, *p, *maxitem; + Item *i, *new; if (!files[M_LOOKUP]->content) return 0; @@ -204,11 +224,14 @@ static int update_items(char *pattern) return 0; cmdw = 0; - offset[OFF_CURR] = offset[OFF_PREV] = offset[OFF_NEXT] = 0; - sel = 0; + offset[OFF_CURR] = offset[OFF_PREV] = offset[OFF_NEXT] = nil; - while ((p = cext_stack_get_top_item(&items))) - cext_detach_item(&items, p); + while ((i = items)) { + items = items->next; + free(i); + } + sel = items = nil; + nitems = 0; /* build new items */ for (p = f->content; p; p = p->next) { @@ -224,21 +247,39 @@ static int update_items(char *pattern) for (p = f->content; p; p = p->next) { if (matched || !strncmp(pattern, p->name, plen)) { - cext_attach_item(&items, p); + new = cext_emallocz(sizeof(Item)); + new->file = p; + nitems++; + if (!items) + items = i = new; + else { + i->next = new; + new->prev = i; + i = new; + } p->parent = 0; /* HACK to prevent doubled items */ } } for (p = f->content; p; p = p->next) { - if (p->parent && strstr(p->name, pattern)) - cext_attach_item(&items, p); + if (p->parent && strstr(p->name, pattern)) { + new = cext_emallocz(sizeof(Item)); + new->file = p; + nitems++; + if (!items) + items = i = new; + else { + i->next = new; + new->prev = i; + i = new; + } + } else p->parent = f; /* restore HACK */ } - size = cext_sizeof_container(&items); update_offsets(); - return size; + return nitems; } /* creates draw structs for menu mode drawing */ @@ -246,8 +287,7 @@ static void draw_menu() { Draw d = { 0 }; unsigned int offx = 0; - int i = 0; - File *item = 0, *selitem = cext_list_get_item(&items, sel); + Item *i = sel; d.gc = gc; d.font = font; @@ -264,29 +304,29 @@ static void draw_menu() d.font = font; d.fg = blitz_loadcolor(dpy, screen_num, files[M_NORM_TEXT_COLOR]->content); d.data = files[M_COMMAND]->content; - if (cmdw && selitem) + if (cmdw && sel) d.rect.width = cmdw; offx += d.rect.width; blitz_drawlabelnoborder(dpy, &d); d.align = CENTER; - if (selitem) { + if (sel) { d.bg = blitz_loadcolor(dpy, screen_num, files[M_NORM_BG_COLOR]->content); d.fg = blitz_loadcolor(dpy, screen_num, files[M_NORM_TEXT_COLOR]->content); - d.data = offset[OFF_CURR] ? "<" : 0; + d.data = offset[OFF_CURR] ? "<" : nil; d.rect.x = offx; d.rect.width = seek; offx += d.rect.width; blitz_drawlabelnoborder(dpy, &d); /* determine maximum items */ - for (i = offset[OFF_CURR]; (item = cext_list_get_item(&items, i)) && (i < offset[OFF_NEXT]); i++) { - d.data = item->name; + for (i = offset[OFF_CURR]; i && i != offset[OFF_NEXT]; i = i->next) { + d.data = i->file->name; d.rect.x = offx; d.rect.width = XTextWidth(d.font, d.data, strlen(d.data)) + mrect.height; offx += d.rect.width; /*fprintf(stderr, "%s (%d, %d, %d, %d)\n", item->name, d.rect.x, d.rect.y, d.rect.width, d.rect.height);*/ - if (selitem == item) { + if (sel == i) { d.bg = blitz_loadcolor(dpy, screen_num, files[M_SEL_BG_COLOR]->content); d.fg = blitz_loadcolor(dpy, screen_num, files[M_SEL_TEXT_COLOR]->content); d.border = blitz_loadcolor(dpy, screen_num, files[M_SEL_BORDER_COLOR]-> content); @@ -301,7 +341,7 @@ static void draw_menu() d.bg = blitz_loadcolor(dpy, screen_num, files[M_NORM_BG_COLOR]->content); d.fg = blitz_loadcolor(dpy, screen_num, files[M_NORM_TEXT_COLOR]->content); - d.data = item ? ">" : 0; + d.data = i ? ">" : nil; d.rect.x = mrect.width - seek; d.rect.width = seek; blitz_drawlabelnoborder(dpy, &d); @@ -316,9 +356,7 @@ static void handle_kpress(XKeyEvent * e) char buf[32]; int num; static char text[4096]; - size_t len = 0, size = cext_sizeof_container(&items); - File *selitem = cext_list_get_item(&items, sel); - File *hist = cext_stack_get_top_item(&history); + size_t len = 0; text[0] = 0; if (files[M_COMMAND]->content) { @@ -365,41 +403,43 @@ static void handle_kpress(XKeyEvent * e) } switch (ksym) { case XK_Left: - if (!selitem) + if (!sel) return; - if (sel > 0) { - selitem = cext_list_get_item(&items, --sel); - set_text(selitem->name); + if (sel->prev) { + sel = sel->prev; + set_text(sel->file->name); } else return; break; case XK_Right: case XK_Tab: - if (!selitem) + if (!sel) return; - if (sel < size - 1) { - selitem = cext_list_get_item(&items, ++sel); - set_text(selitem->name); + if (sel->next) { + sel = sel->next; + set_text(sel->file->name); } else return; break; case XK_Down: - if (hist) { - set_text(hist->content); - cext_stack_top_item(&history, cext_list_get_next_item(&items, hist)); + if (selhist) { + set_text(selhist->file->content); + if (selhist->next) + selhist = selhist->next; } update_items(files[M_COMMAND]->content); break; case XK_Up: - if (hist) { - set_text(hist->content); - cext_stack_top_item(&history, cext_list_get_prev_item(&items, hist)); + if (selhist) { + set_text(selhist->file->content); + if (selhist->prev) + selhist = selhist->prev; } update_items(files[M_COMMAND]->content); break; case XK_Return: - if (selitem) - exec_item(selitem->name); + if (sel) + exec_item(sel->file->name); else if (text) exec_item(text); case XK_Escape: @@ -411,7 +451,7 @@ static void handle_kpress(XKeyEvent * e) if (i) { do text[--i] = 0; - while (size && i && size == update_items(text)); + while (nitems && i && nitems == update_items(text)); } set_text(text); update_items(files[M_COMMAND]->content); @@ -428,11 +468,11 @@ static void handle_kpress(XKeyEvent * e) update_items(files[M_COMMAND]->content); } } - if (selitem) { - if (sel < offset[OFF_CURR]) { + if (sel) { + if (sel == offset[OFF_CURR]->prev) { offset[OFF_CURR] = offset[OFF_PREV]; update_offsets(); - } else if (sel >= offset[OFF_NEXT]) { + } else if (sel == offset[OFF_NEXT]->next) { offset[OFF_CURR] = offset[OFF_NEXT]; update_offsets(); }