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();
}