[hackers] [wmii] [menu] Add vertical mode. || Kris Maglione

From: <hg_AT_suckless.org>
Date: Fri, 8 Oct 2010 18:41:49 +0000 (UTC)

changeset: 2781:3a09477a41ff
user: Kris Maglione <kris_AT_suckless.org>
date: Thu Oct 07 16:31:41 2010 -0400
files: alternative_wmiircs/python/pygmi/util.py cmd/menu/Makefile cmd/menu/caret.c cmd/menu/dat.h cmd/menu/history.c cmd/menu/keys.c cmd/menu/main.c cmd/menu/menu.c cmd/tray/main.c cmd/wmii/bar.c cmd/wmii/client.c cmd/wmii/dat.h cmd/wmii/frame.c cmd/wmii/main.c cmd/wmii/message.c cmd/wmiir.c cmd/x11/wmii9menu.c img/mkfile include/stuff/clientutil.h include/stuff/geom.h include/stuff/util.h include/stuff/x11.h lib/libstuff/client_readconfig.c lib/libstuff/clientutil.c lib/libstuff/x11/drawing/drawstring.c mk/common.mk util/compile
description:
[menu] Add vertical mode.

diff -r e638d4f40d56 -r 3a09477a41ff alternative_wmiircs/python/pygmi/util.py
--- a/alternative_wmiircs/python/pygmi/util.py Thu Oct 07 16:31:38 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/util.py Thu Oct 07 16:31:41 2010 -0400
@@ -29,14 +29,14 @@
     call(*args, input=message)
 
 def program_list(path):
- names = []
+ names = set()
     for d in path:
         try:
             for f in os.listdir(d):
                 p = '%s/%s' % (d, f)
- if f not in names and os.access(p, os.X_OK) and (
- os.path.isfile(p) or os.path.islink(p)):
- names.append(f)
+ if (f not in names and os.access(p, os.X_OK) and
+ os.path.isfile(p)):
+ names.add(f)
         except Exception:
             pass
     return sorted(names)
diff -r e638d4f40d56 -r 3a09477a41ff cmd/menu/Makefile
--- a/cmd/menu/Makefile Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/menu/Makefile Thu Oct 07 16:31:41 2010 -0400
@@ -5,12 +5,13 @@
 main.c: $(ROOT)/mk/wmii.mk
 
 bindings.c: keys.txt Makefile
- ( echo "char binding_spec[] = "; \
+ ( echo "char binding_spec[] ="; \
           sed 's/.*/ "&\\n"/' keys.txt; \
- echo " ;" ) >bindings.c
+ echo " ;" ) >$@
 
 TARG = wimenu
 HFILES= dat.h fns.h
+TAGFILES= dat.h
 
 PACKAGES += $(X11PACKAGES)
 
diff -r e638d4f40d56 -r 3a09477a41ff cmd/menu/caret.c
--- a/cmd/menu/caret.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/menu/caret.c Thu Oct 07 16:31:41 2010 -0400
@@ -69,9 +69,7 @@
                                 p = next;
                         return p;
                 case CHAR:
- if(p < end)
- return p+1;
- return p;
+ return next_rune(p, &r);
                 }
         }
         else if(dir == BACKWARD) {
@@ -88,9 +86,7 @@
                                 p = next;
                         return p;
                 case CHAR:
- if(p > end)
- return prev_rune(end, p, &r);
- return end;
+ return prev_rune(end, p, &r);
                 }
         }
         input.pos_end = nil;
diff -r e638d4f40d56 -r 3a09477a41ff cmd/menu/dat.h
--- a/cmd/menu/dat.h Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/menu/dat.h Thu Oct 07 16:31:41 2010 -0400
@@ -11,8 +11,6 @@
 #include <stuff/x.h>
 #include <stuff/util.h>
 
-#define BLOCK(x) do { x; }while(0)
-
 #ifndef EXTERN
 # define EXTERN extern
 #endif
@@ -69,38 +67,40 @@
         int filter_start;
 } input;
 
+EXTERN struct {
+ Window* win;
+ Image* buf;
+ char* prompt;
+ int height;
+ int rows;
+ bool ontop;
+ Rectangle itemr;
+ Point arrow;
+} menu;
+
 extern char binding_spec[];
 
-EXTERN int numlock;
-
-EXTERN long xtime;
-EXTERN Image* ibuf;
-EXTERN Font* font;
-EXTERN CTuple cnorm, csel;
-EXTERN bool ontop;
-
-EXTERN Cursor cursor[1];
-EXTERN Visual* render_visual;
-
 EXTERN IxpServer srv;
 
-EXTERN Window* barwin;
+EXTERN struct {
+ Item* all;
+ Item* first;
+ Item* start;
+ Item* end;
+ Item* sel;
+ int maxwidth;
+} match;
 
-EXTERN Item* items;
-EXTERN Item* matchfirst;
-EXTERN Item* matchstart;
-EXTERN Item* matchend;
-EXTERN Item* matchidx;
+Font* font;
+CTuple cnorm;
+CTuple csel;
 
 EXTERN Item hist;
-EXTERN Item* histidx;
+EXTERN Item* histsel;
 
-EXTERN int maxwidth;
+EXTERN int itempad;
 EXTERN int result;
 
-EXTERN char* (*find)(const char*, const char*);
-EXTERN int (*compare)(const char*, const char*, size_t);
+EXTERN char* (*find)(const char*, const char*);
+EXTERN int (*compare)(const char*, const char*, size_t);
 
-EXTERN char* prompt;
-EXTERN int promptw;
-
diff -r e638d4f40d56 -r 3a09477a41ff cmd/menu/history.c
--- a/cmd/menu/history.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/menu/history.c Thu Oct 07 16:31:41 2010 -0400
@@ -19,25 +19,25 @@
         Item *i;
 
         if(dir == FORWARD) {
- if(histidx == &hist)
+ if(histsel == &hist)
                         return hist.string;
- for(i=histidx->next; i != hist.next; i=i->next)
+ for(i=histsel->next; i != hist.next; i=i->next)
                         if(!i->string || !compare(i->string, string, n)) {
- histidx = i;
+ histsel = i;
                                 return i->string;
                         }
                 return string;
         }
         assert(dir == BACKWARD);
 
- if(histidx == &hist) {
+ if(histsel == &hist) {
                 free(hist.string);
                 hist.string = estrdup(input.string);
         }
 
- for(i=histidx->prev; i != &hist; i=i->prev)
+ for(i=histsel->prev; i != &hist; i=i->prev)
                 if(!compare(i->string, string, n)) {
- histidx = i;
+ histsel = i;
                         return i->string;
                 }
         return string;
diff -r e638d4f40d56 -r 3a09477a41ff cmd/menu/keys.c
--- a/cmd/menu/keys.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/menu/keys.c Thu Oct 07 16:31:41 2010 -0400
@@ -13,7 +13,8 @@
         char** action;
 };
 
-static Key* bindings;
+static Key* bindings;
+static int numlock;
 
 /*
  * To do: Find my red black tree implementation.
diff -r e638d4f40d56 -r 3a09477a41ff cmd/menu/main.c
--- a/cmd/menu/main.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/menu/main.c Thu Oct 07 16:31:41 2010 -0400
@@ -1,8 +1,6 @@
 /* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
  * See LICENSE file for license details.
  */
-#define IXP_NO_P9_
-#define IXP_P9_STRUCTS
 #define EXTERN
 #include "dat.h"
 #include <X11/Xproto.h>
@@ -23,7 +21,9 @@
 
 static void
 usage(void) {
- fatal("usage: wimenu -i [-h <history>] [-a <address>] [-p <prompt>] [-s <screen>]\n");
+ fprint(2, "usage: %s -i [-a <address>] [-h <history>] [-p <prompt>] [-r <rows>] [-s <screen>]\n", argv0);
+ fprint(2, " See manual page for full usage details.\n");
+ exit(1);
 }
 
 static int
@@ -50,13 +50,13 @@
         bool stop;
 
         stop = !hist && !isatty(buf->fid);
+ ret.next_link = nil;
         i = &ret;
         while((p = Brdstr(buf, '\n', true))) {
                 if(stop && p[0] == '\0')
                         break;
- link(i, emallocz(sizeof *i));
- i->next_link = i->next;
- i = i->next;
+ i->next_link = emallocz(sizeof *i);
+ i = i->next_link;
                 i->string = p;
                 i->retstring = p;
                 if(cmdsep && (p = strstr(p, cmdsep))) {
@@ -65,15 +65,12 @@
                 }
                 if(!hist) {
                         i->len = strlen(i->string);
- i->width = textwidth_l(font, i->string, i->len);
- if(i->width > maxwidth)
- maxwidth = i->width;
+ i->width = textwidth_l(font, i->string, i->len) + itempad;
+ match.maxwidth = max(i->width, match.maxwidth);
                 }
         }
 
- link(i, &ret);
- splice(&ret);
- return ret.next != &ret ? ret.next : nil;
+ return ret.next_link;
 }
 
 static void
@@ -86,7 +83,7 @@
                 return;
         }
         input.filter_start = strtol(s, nil, 10);
- items = populate_list(cmplbuf, false);
+ match.all = populate_list(cmplbuf, false);
         update_filter(false);
         menu_draw();
 }
@@ -143,8 +140,8 @@
         if(input.pos < input.end)
                 filter = freelater(estrndup(filter, input.pos - filter));
 
- matchidx = nil;
- matchfirst = matchstart = filter_list(items, filter);
+ match.sel = nil;
+ match.first = match.start = filter_list(match.all, filter);
         if(print)
                 update_input();
 }
@@ -158,8 +155,7 @@
         int i, n;
 
         rects = xinerama_screens(&n);
- if (screen_hint >= 0 && screen_hint < n)
- /* We were given a valid screen index, use that. */
+ if(screen_hint >= 0 && screen_hint < n)
                 i = screen_hint;
         else {
                 /* Pick the screen with the pointer, for now. Later,
@@ -178,11 +174,11 @@
 
 int
 main(int argc, char *argv[]) {
- Item *item;
         static char *address;
         static char *histfile;
         static char *keyfile;
         static bool nokeys;
+ Item *item;
         int i;
         long ndump;
 
@@ -220,7 +216,10 @@
                 ndump = strtol(EARGF(usage()), nil, 10);
                 break;
         case 'p':
- prompt = EARGF(usage());
+ menu.prompt = EARGF(usage());
+ break;
+ case 'r':
+ menu.rows = strtol(EARGF(usage()), nil, 10);
                 break;
         case 's':
                 screen_hint = strtol(EARGF(usage()), nil, 10);
@@ -249,11 +248,13 @@
         srv.preselect = event_preselect;
         ixp_listen(&srv, ConnectionNumber(display), nil, event_fdready, event_fdclosed);
 
- ontop = !strcmp(readctl("bar on "), "top");
+ menu.ontop = !strcmp(readctl("/ctl", "bar "), "on top");
         client_readconfig(&cnorm, &csel, &font);
 
+ itempad = (font->height & ~1) + font->pad.min.x + font->pad.max.x;
+
         cmplbuf = Bfdopen(0, OREAD);
- items = populate_list(cmplbuf, false);
+ match.all = populate_list(cmplbuf, false);
         if(!isatty(cmplbuf->fid))
                 ixp_listen(&srv, cmplbuf->fid, inbuf, check_competions, nil);
 
@@ -268,21 +269,18 @@
                         parse_keys(buffer);
         }
 
- histidx = &hist;
+ histsel = &hist;
         link(&hist, &hist);
- if(histfile) {
- inbuf = Bopen(histfile, OREAD);
- if(inbuf) {
- item = populate_list(inbuf, true);
- if(item) {
- link(item->prev, &hist);
- link(&hist, item);
- }
- Bterm(inbuf);
+ if(histfile && (inbuf = Bopen(histfile, OREAD))) {
+ item = filter_list(populate_list(inbuf, true), "");
+ if(item->string) {
+ link(item->prev, &hist);
+ link(&hist, item);
                 }
+ Bterm(inbuf);
         }
 
- if(barwin == nil)
+ if(menu.win == nil)
                 menu_init();
 
         init_screens();
diff -r e638d4f40d56 -r 3a09477a41ff cmd/menu/menu.c
--- a/cmd/menu/menu.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/menu/menu.c Thu Oct 07 16:31:41 2010 -0400
@@ -4,270 +4,220 @@
 #include <unistd.h>
 #include "fns.h"
 
-static Handlers handlers;
-
-static int ltwidth;
-
-static void _menu_draw(bool);
-
-enum {
- ACCEPT = CARET_LAST,
- REJECT,
- HIST,
- KILL,
- CMPL_NEXT,
- CMPL_PREV,
- CMPL_FIRST,
- CMPL_LAST,
- CMPL_NEXT_PAGE,
- CMPL_PREV_PAGE,
-};
+static Handlers handlers;
+static int promptw;
 
 void
 menu_init(void) {
         WinAttr wa;
 
         wa.event_mask = ExposureMask | KeyPressMask;
- barwin = createwindow(&scr.root, Rect(-1, -1, 1, 1), scr.depth, InputOutput,
- &wa, CWEventMask);
+ menu.win = createwindow(&scr.root, Rect(-1, -1, 1, 1), scr.depth, InputOutput,
+ &wa, CWEventMask);
         if(scr.xim)
- barwin->xic = XCreateIC(scr.xim,
- XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
- XNClientWindow, barwin->xid,
- XNFocusWindow, barwin->xid,
- nil);
+ menu.win->xic = XCreateIC(scr.xim,
+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow, menu.win->xid,
+ XNFocusWindow, menu.win->xid,
+ nil);
 
- changeprop_long(barwin, Net("WM_WINDOW_TYPE"), "ATOM",
- (long[]){ TYPE("MENU") }, 1);
- changeprop_string(barwin, "_WMII_TAGS", "sel");
- changeprop_textlist(barwin, "WM_CLASS", "STRING",
- (char*[3]){ "wimenu", "wimenu", nil });
+ changeprop_long(menu.win, Net("WM_WINDOW_TYPE"), "ATOM", (long[]){ TYPE("MENU") }, 1);
+ changeprop_string(menu.win, "_WMII_TAGS", "sel");
+ changeprop_textlist(menu.win, "WM_CLASS", "STRING", (char*[3]){ "wimenu", "wimenu" });
 
- sethandler(barwin, &handlers);
- mapwin(barwin);
+ sethandler(menu.win, &handlers);
+ mapwin(menu.win);
 
         int i = 0;
- while(!grabkeyboard(barwin)) {
+ while(!grabkeyboard(menu.win)) {
                 if(i++ > 1000)
                         fatal("can't grab keyboard");
                 usleep(1000);
         }
 }
 
+void
+menu_show(void) {
+ Rectangle r;
+
+ if(menu.prompt)
+ promptw = textwidth(font, menu.prompt) + itempad;
+
+ r = textextents_l(font, "<", 1, nil);
+ menu.arrow = Pt(Dy(r) + itempad/2, Dx(r) + itempad/2);
+
+ menu.height = labelh(font);
+
+ freeimage(menu.buf);
+ menu.buf = allocimage(Dx(scr.rect),
+ !!menu.rows * 2 * menu.arrow.y + (menu.rows + 1) * menu.height,
+ menu.win->depth);
+
+ mapwin(menu.win);
+ raisewin(menu.win);
+ menu_draw();
+}
+
+/* I'd prefer to use ⌃ and ⌄, but few fonts support them. */
 static void
-menu_unmap(long id, void *p) {
+drawarrow(Image *img, Rectangle r, int up, Color *col) {
+ Point p[3], pt;
 
- USED(id, p);
- unmapwin(barwin);
- XFlush(display);
+ pt = Pt(menu.arrow.x - itempad/2, menu.arrow.y - itempad/2 & ~1);
+
+ p[1] = Pt(r.min.x + Dx(r)/2, up ? r.min.y + itempad/4 : r.max.y - itempad/4);
+ p[0] = Pt(p[1].x - pt.x/2, up ? p[1].y + pt.y : p[1].y - pt.y);
+ p[2] = Pt(p[1].x + pt.x/2, p[0].y);
+ drawpoly(img, p, nelem(p), CapProjecting, 1, col);
+}
+
+static Rectangle
+slice(Rectangle *rp, int x, int y) {
+ Rectangle r;
+
+ r = *rp;
+ if(x)
+ rp->min.x += x, r.max.x = min(rp->min.x, rp->max.x);
+ if(y)
+ rp->min.y += y, r.max.y = min(rp->min.y, rp->max.y);
+ return r;
+}
+
+static bool
+nextrect(Item *i, Rectangle *rp, Rectangle *src) {
+ Rectangle r;
+
+ if(menu.rows)
+ r = slice(src, 0, menu.height);
+ else
+ r = slice(src, i->width, 0);
+ return (Dx(*src) >= 0 && Dy(*src) >= 0) && (*rp = r, 1);
+}
+
+void
+menu_draw(void) {
+ Rectangle barr, extent, itemr, inputr, r, r2;
+ Item *item;
+ int inputw, offset;
+
+ barr = r2 = Rect(0, 0, Dx(menu.win->r), menu.height);
+
+ inputw = max(match.maxwidth + textwidth_l(font, input.string, min(input.filter_start, strlen(input.string))),
+ max(itempad + textwidth(font, input.string),
+ Dx(barr) / 3));
+
+ /* Calculate items box, w/ and w/o arrows */
+ if(menu.rows) {
+ menu.itemr = barr;
+ menu.itemr.max.y += Dy(barr) * (menu.rows - 1);
+ if(menu.ontop)
+ menu.itemr = rectaddpt(menu.itemr, Pt(0, Dy(barr)));
+ itemr = menu.itemr;
+ if(match.start != match.first)
+ menu.itemr = rectaddpt(menu.itemr, Pt(0, menu.arrow.y));
+ }
+ else {
+ itemr = r2;
+ slice(&itemr, inputw + promptw, 0);
+ menu.itemr = Rect(itemr.min.x + menu.arrow.x, itemr.min.y,
+ itemr.max.x - menu.arrow.x, itemr.max.y);
+ }
+
+ fill(menu.buf, menu.buf->r, &cnorm.bg);
+
+ /* Draw items */
+ item = match.start, r2 = menu.itemr;
+ nextrect(item, &r, &r2);
+ do {
+ match.end = item;
+ if(item->string)
+ fillstring(menu.buf, font, r, West, item->string,
+ (item == match.sel ? &csel : &cnorm), 0);
+ item = item->next;
+ } while(item != match.first && nextrect(item, &r, &r2));
+
+ /* Adjust dimensions for arrows/number of items */
+ if(menu.rows)
+ itemr.max.y = r.max.y + (match.end->next != match.first ? menu.arrow.y : 0);
+ else
+ itemr.max.x = r.max.x + menu.arrow.x;
+ if(menu.rows && !menu.ontop)
+ barr = rectaddpt(barr, Pt(0, itemr.max.y));
+
+ /* Draw indicators */
+ if(!menu.rows && match.start != match.first)
+ drawstring(menu.buf, font, itemr, West, "<", &cnorm.fg);
+ if(!menu.rows && match.end->next != match.first)
+ drawstring(menu.buf, font, itemr, East, ">", &cnorm.fg);
+
+ if(menu.rows && match.start != match.first)
+ drawarrow(menu.buf, itemr, 1, &cnorm.fg);
+ if(menu.rows && match.end->next != match.first)
+ drawarrow(menu.buf, itemr, 0, &cnorm.fg);
+
+ /* Draw prompt */
+ r2 = barr;
+ if(menu.prompt)
+ drawstring(menu.buf, font, slice(&r2, promptw, 0),
+ West, menu.prompt, &cnorm.fg);
+
+ /* Border input/horizontal items */
+ border(menu.buf, r2, 1, &cnorm.border);
+
+ /* Draw input */
+ inputr = slice(&r2, inputw, 0);
+ drawstring(menu.buf, font, inputr, West, input.string, &cnorm.fg);
+
+ /* Draw cursor */
+ extent = textextents_l(font, input.string, input.pos - input.string, &offset);
+ r2 = insetrect(inputr, 2);
+ r2.min.x = inputr.min.x - extent.min.x + offset + font->pad.min.x + itempad/2 - 1;
+ r2.max.x = r2.min.x + 1;
+ fill(menu.buf, r2, &cnorm.border);
+
+ /* Reshape window */
+ r = scr.rect;
+ if(menu.ontop)
+ r.max.y = r.min.y + itemr.max.y;
+ else
+ r.min.y = r.max.y - barr.max.y;
+ reshapewin(menu.win, r);
+
+ /* Border window */
+ r = rectsubpt(r, r.min);
+ border(menu.buf, r, 1, &cnorm.border);
+ copyimage(menu.win, r, menu.buf, ZP);
+}
+
+static Item*
+pagestart(Item *i) {
+ Rectangle r, r2;
+
+ r = menu.itemr;
+ nextrect(i, &r2, &r);
+ while(i->prev != match.first->prev && nextrect(i->prev, &r2, &r))
+ i = i->prev;
+ return i;
 }
 
 static void
 selectitem(Item *i) {
- if(i != matchidx) {
+ if(i != match.sel) {
                 caret_set(input.filter_start, input.pos - input.string);
                 caret_insert(i->string, 0);
- matchidx = i;
+ match.sel = i;
+ if(i == match.start->prev)
+ match.start = pagestart(i);
+ if(i == match.end->next)
+ match.start = i;
         }
 }
 
-static void
-menu_cmd(int op, int motion) {
- int n;
-
- switch(op) {
- case HIST:
- n = input.pos - input.string;
- caret_insert(history_search(motion, input.string, n), true);
- input.pos = input.string + n;
- break;
- case KILL:
- caret_delete(BACKWARD, motion);
- break;
- default:
- goto next;
- }
- update_filter(true);
-next:
- switch(op) {
- case ACCEPT:
- srv.running = false;
- if(!matchidx && matchfirst->retstring && !motion)
- if(input.filter_start == 0 && input.pos == input.end)
- menu_cmd(CMPL_FIRST, 0);
- if(!motion && matchidx && !strcmp(input.string, matchidx->string))
- lprint(1, "%s", matchidx->retstring);
- else
- lprint(1, "%s", input.string);
- break;
- case REJECT:
- srv.running = false;
- result = 1;
- break;
- case BACKWARD:
- case FORWARD:
- caret_move(op, motion);
- update_input();
- break;
- case CMPL_NEXT:
- selectitem(matchidx ? matchidx->next : matchfirst);
- break;
- case CMPL_PREV:
- selectitem((matchidx ? matchidx : matchstart)->prev);
- break;
- case CMPL_FIRST:
- matchstart = matchfirst;
- matchend = nil;
- selectitem(matchstart);
- break;
- case CMPL_LAST:
- selectitem(matchfirst->prev);
- break;
- case CMPL_NEXT_PAGE:
- if(matchend)
- selectitem(matchend->next);
- break;
- case CMPL_PREV_PAGE:
- matchend = matchstart->prev;
- matchidx = nil;
- _menu_draw(false);
- selectitem(matchstart);
- break;
- }
- menu_draw();
-}
-
-static void
-_menu_draw(bool draw) {
- Rectangle r, rd, rp, r2, extent;
- CTuple *c;
- Item *i;
- int inputw, itemoff, end, pad, n, offset;
-
- r = barwin->r;
- r = rectsetorigin(r, ZP);
-
- pad = (font->height & ~1) + font->pad.min.x + font->pad.max.x;
-
- rd = r;
- rp = ZR; // SET(rp)
- if (prompt) {
- if (!promptw)
- promptw = textwidth(font, prompt) + 2 * ltwidth + pad;
- rd.min.x += promptw;
-
- rp = r;
- rp.max.x = promptw;
- }
-
- inputw = min(Dx(rd) / 3, maxwidth);
- inputw = max(inputw, textwidth(font, input.string)) + pad;
- itemoff = inputw + 2 * ltwidth;
- end = Dx(rd) - ltwidth;
-
- fill(ibuf, r, &cnorm.bg);
-
- if(matchend && matchidx == matchend->next)
- matchstart = matchidx;
- else if(matchidx == matchstart->prev)
- matchend = matchidx;
- if (matchend == nil)
- matchend = matchstart;
-
- if(matchend == matchstart->prev && matchstart != matchidx) {
- n = itemoff;
- matchstart = matchend;
- for(i=matchend; ; i=i->prev) {
- n += i->width + pad;
- if(n > end)
- break;
- matchstart = i;
- if(i == matchfirst)
- break;
- }
- }
-
- if(!draw)
- return;
-
- r2 = rd;
- for(i=matchstart; i->string; i=i->next) {
- r2.min.x = promptw + itemoff;
- itemoff = itemoff + i->width + pad;
- r2.max.x = promptw + min(itemoff, end);
- if(i != matchstart && itemoff > end)
- break;
-
- c = (i == matchidx) ? &csel : &cnorm;
- fill(ibuf, r2, &c->bg);
- drawstring(ibuf, font, r2, Center, i->string, &c->fg);
- matchend = i;
- if(i->next == matchfirst)
- break;
- }
-
- r2 = rd;
- r2.min.x = promptw + inputw;
- if(matchstart != matchfirst)
- drawstring(ibuf, font, r2, West, "<", &cnorm.fg);
- if(matchend->next != matchfirst)
- drawstring(ibuf, font, r2, East, ">", &cnorm.fg);
-
- r2 = rd;
- r2.max.x = promptw + inputw;
- drawstring(ibuf, font, r2, West, input.string, &cnorm.fg);
-
- extent = textextents_l(font, input.string, input.pos - input.string, &offset);
- r2.min.x = promptw + offset + font->pad.min.x - extent.min.x + pad/2 - 1;
- r2.max.x = r2.min.x + 2;
- r2.min.y++;
- r2.max.y--;
- border(ibuf, r2, 1, &cnorm.border);
-
- if (prompt)
- drawstring(ibuf, font, rp, West, prompt, &cnorm.fg);
-
- border(ibuf, rd, 1, &cnorm.border);
- copyimage(barwin, r, ibuf, ZP);
-}
-
-void
-menu_draw(void) {
- _menu_draw(true);
-}
-
-void
-menu_show(void) {
- Rectangle r;
- int height, pad;
-
- USED(menu_unmap);
-
- ltwidth = textwidth(font, "<");
-
- pad = (font->height & ~1)/2;
- height = labelh(font);
-
- r = scr.rect;
- if(ontop)
- r.max.y = r.min.y + height;
- else
- r.min.y = r.max.y - height;
- reshapewin(barwin, r);
-
- freeimage(ibuf);
- ibuf = allocimage(Dx(r), Dy(r), scr.depth);
-
- mapwin(barwin);
- raisewin(barwin);
- menu_draw();
-}
-
 static bool
 kdown_event(Window *w, void *aux, XKeyEvent *e) {
         char **action, **p;
         char *key;
- char buf[32];
+ char buf[128];
         int num, status;
         KeySym ksym;
 
@@ -276,8 +226,7 @@
 
         status = XLookupBoth;
         if(w->xic)
- num = Xutf8LookupString(w->xic, e, buf, sizeof buf - 1, &ksym,
- &status);
+ num = Xutf8LookupString(w->xic, e, buf, sizeof buf - 1, &ksym, &status);
         else
                 num = XLookupString(e, buf, sizeof buf - 1, &ksym, nil);
 
@@ -319,37 +268,65 @@
                         have(LWORD) ? WORD :
                         have(LLINE) ? LINE :
                         -1);
+
                 switch(getsym(action[0])) {
+ default:
+ return false;
+ case LHISTORY:
+ num = input.pos - input.string;
+ amount = have(LBACKWARD) ? BACKWARD : FORWARD;
+ caret_insert(history_search(amount, input.string, num), true);
+ input.pos = input.string + num;
+ update_filter(true);
+ break;
+ case LKILL:
+ caret_delete(BACKWARD, amount);
+ update_filter(true);
+ break;
+
                 case LACCEPT:
- menu_cmd(ACCEPT, have(LLITERAL));
+ srv.running = false;
+ if(!have(LLITERAL) && !match.sel && match.start->retstring)
+ if(input.filter_start == 0 && input.pos == input.end)
+ selectitem(match.start);
+
+ if(!have(LLITERAL) && match.sel && !strcmp(input.string, match.sel->string))
+ lprint(1, "%s", match.sel->retstring);
+ else
+ lprint(1, "%s", input.string);
                         break;
                 case LBACKWARD:
- menu_cmd(BACKWARD, amount);
+ caret_move(BACKWARD, amount);
+ update_input();
                         break;
                 case LCOMPLETE:
- amount = (
- have(LNEXT) ? CMPL_NEXT :
- have(LPREV) ? CMPL_PREV :
- have(LNEXTPAGE) ? CMPL_NEXT_PAGE :
- have(LPREVPAGE) ? CMPL_PREV_PAGE :
- have(LFIRST) ? CMPL_FIRST :
- have(LLAST) ? CMPL_LAST :
- CMPL_NEXT);
- menu_cmd(amount, 0);
+ if(have(LNEXT))
+ selectitem(match.sel ? match.sel->next : match.first);
+ else if(have(LPREV))
+ selectitem((match.sel ? match.sel : match.start)->prev);
+ else if(have(LFIRST)) {
+ match.start = match.first;
+ selectitem(match.start);
+ }
+ else if(have(LLAST))
+ selectitem(match.first->prev);
+ else if(have(LNEXTPAGE))
+ selectitem(match.end->next);
+ else if(have(LPREVPAGE)) {
+ match.start = pagestart(match.start->prev);
+ selectitem(match.start);
+ }
                         break;
                 case LFORWARD:
- menu_cmd(FORWARD, amount);
- break;
- case LHISTORY:
- menu_cmd(HIST, have(LBACKWARD) ? BACKWARD : FORWARD);
- break;
- case LKILL:
- menu_cmd(KILL, amount);
+ caret_move(FORWARD, amount);
+ update_input();
                         break;
                 case LREJECT:
- menu_cmd(REJECT, 0);
+ srv.running = false;
+ result = 1;
                         break;
                 }
+ menu_draw();
         }
         return false;
 }
diff -r e638d4f40d56 -r 3a09477a41ff cmd/tray/main.c
--- a/cmd/tray/main.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/tray/main.c Thu Oct 07 16:31:41 2010 -0400
@@ -191,7 +191,7 @@
         client_init(nil);
 
         if(tray.edge == 0)
- tray.edge = West | (!strcmp(readctl("bar on "), "top") ? North : South);
+ tray.edge = West | (!strcmp(readctl("/ctl", "bar on "), "top") ? North : South);
 
         client_readconfig(&tray.normcolors, &tray.selcolors, &tray.font);
 
diff -r e638d4f40d56 -r 3a09477a41ff cmd/wmii/bar.c
--- a/cmd/wmii/bar.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/wmii/bar.c Thu Oct 07 16:31:41 2010 -0400
@@ -195,9 +195,7 @@
                 align = Center;
                 if(b == s->bar[BRight])
                         align = East;
- fill(ibuf, b->r, &b->colors.bg);
- drawstring(ibuf, def.font, b->r, align, b->text, &b->colors.fg);
- border(ibuf, b->r, 1, &b->colors.border);
+ fillstring(ibuf, def.font, b->r, align, b->text, &b->colors, 1);
         }
 
         if(s->barwin_rgba != (s->barwin->depth == 32))
diff -r e638d4f40d56 -r 3a09477a41ff cmd/wmii/client.c
--- a/cmd/wmii/client.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/wmii/client.c Thu Oct 07 16:31:41 2010 -0400
@@ -220,7 +220,8 @@
         bool ret, more;
 
         ret = true;
- for(r=def.rules.rule; r; r=r->next)
+ more = true;
+ for(r=def.rules.rule; r && more; r=r->next)
                 if(regexec(r->regex, c->props, nil, 0)) {
                         more = false;
                         for(rv=r->values; rv; rv=rv->next) {
@@ -234,15 +235,15 @@
                                 }else {
                                         bufclear();
                                         bufprint("%s %s", rv->key, rv->value);
- m = ixp_message(buffer, sizeof buffer, MsgPack);
- if(!waserror()) {
+ m = ixp_message(buffer, _buf_end - buffer, MsgPack);
+ if(waserror())
+ warning("processing rule %q=%q: %r", rv->key, rv->value);
+ else {
                                                 message_client(c, &m);
                                                 poperror();
                                         }
                                 }
                         }
- if(!more)
- return ret;
                 }
         return ret;
 }
@@ -1093,6 +1094,11 @@
         toks[i] = nil;
         tags = comm(CLeft, toks, c->retags);
 
+ if(i == 1 && !c->tagre.regex && !c->tagvre.regex) {
+ free(tags);
+ return nil;
+ }
+
         fmtstrinit(&fmt);
         if(i > 1)
                 join(tags, "+", &fmt);
@@ -1131,17 +1137,16 @@
                 /* Check for regex. */
                 if(cur[0] == '/') {
                         cur++;
- *strchr(cur, '/') = '\0';
+ *strrchr(cur, '/') = '\0';
                         if(add == '+')
                                 reinit(&c->tagre, cur);
                         else if(add == '-')
                                 reinit(&c->tagvre, cur);
                 }
-
- trim(cur, " \t\r\n");
- if(!strcmp(cur, "~"))
+ else if(!strcmp(cur, "~"))
                         c->floating = add ? On : Never;
                 else {
+ trim(cur, " \t\r\n");
                         if(!strcmp(cur, "sel"))
                                 cur = selview->name;
                         else if(Mbsearch(cur, badtags, bsstrcmp))
diff -r e638d4f40d56 -r 3a09477a41ff cmd/wmii/dat.h
--- a/cmd/wmii/dat.h Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/wmii/dat.h Thu Oct 07 16:31:41 2010 -0400
@@ -313,8 +313,7 @@
         uint keyssz;
         Ruleset colrules;
         Ruleset rules;
- char grabmod[5];
- ulong mod;
+ long mod;
         uint border;
         uint snap;
         int colmode;
diff -r e638d4f40d56 -r 3a09477a41ff cmd/wmii/frame.c
--- a/cmd/wmii/frame.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/wmii/frame.c Thu Oct 07 16:31:41 2010 -0400
@@ -398,6 +398,7 @@
         w = min(w, Dx(*rp) - 30); /* Magic number. */
         if(w > 0) {
                 r = *rp;
+ r.min.x = r.max.x - w;
                 rp->max.x -= w;
                 if(0)
                 drawline(img, Pt(rp->max.x, r.min.y+2),
@@ -406,6 +407,7 @@
                 drawstring(img, def.font, r, East,
                            s, &col->fg);
         }
+ free(s);
 }
 
 void
@@ -415,7 +417,6 @@
         CTuple *col;
         Image *img;
         char *s;
- uint w;
         int n, m;
 
         if(f == nil || f->view != selview || f->area == nil)
@@ -443,6 +444,9 @@
         f->titlebar = insetrect(r, 3);
         f->titlebar.max.y += 3;
 
+ f->grabbox = insetrect(r, 2);
+ f->grabbox.max.x = f->grabbox.min.x + Dy(f->grabbox);
+
         /* Odd focus. Unselected, with keyboard focus. */
         /* Draw a border just inside the titlebar. */
         if(c != selclient() && c == disp.focus) {
@@ -450,15 +454,9 @@
                 border(img, insetrect(r, 2), 1, &def.focuscolor.border);
         }
 
- /* grabbox */
- r.min = Pt(2, 2);
- r.max.y -= 2;
- r.max.x = r.min.x + Dy(r);
- f->grabbox = r;
-
         if(c->urgent)
- fill(img, r, &col->fg);
- border(img, r, 1, &col->border);
+ fill(img, f->grabbox, &col->fg);
+ border(img, f->grabbox, 1, &col->border);
 
         /* Odd focus. Selected, without keyboard focus. */
         /* Draw a border around the grabbox. */
@@ -466,38 +464,34 @@
                 border(img, insetrect(r, -1), 1, &def.normcolor.bg);
 
         /* Draw a border on borderless+titleless selected apps. */
- if(f->area->floating && c->borderless && c->titleless && !c->fullscreen && c == selclient())
+ if(c->borderless && c->titleless && f->area->floating && !c->fullscreen && c == selclient())
                 setborder(c->framewin, def.border, &def.focuscolor.border);
         else
                 setborder(c->framewin, 0, &def.focuscolor.border);
 
         /* Label */
- r.min.x = r.max.x;
- r.max.x = fr.max.x;
- r.min.y = 0;
- r.max.y = labelh(def.font);
+ r = Rect(f->grabbox.max.x, 0, fr.max.x, labelh(def.font));
+
         /* Draw count on frames in 'max' columns. */
         if(f->area->max && !resizing) {
- /* XXX */
                 n = stack_count(f, &m);
- s = smprint("%d/%d", m, n);
+ pushlabel(img, &r, smprint("%d/%d", m, n), col);
+ }
+
+ /* Label clients with extra tags. */
+ if((s = client_extratags(c)))
                 pushlabel(img, &r, s, col);
- free(s);
- }
- /* Label clients with extra tags. */
- if((s = client_extratags(c))) {
- pushlabel(img, &r, s, col);
- free(s);
- }else if(f->area->floating) /* Make sure floating clients have room for their indicators. */
- r.max.x -= Dx(f->grabbox);
+
+ if(f->area->floating) /* Make sure floating clients have room for their indicators. */
+ r.max.x -= f->grabbox.max.x;
 
         if(!ewmh_responsive_p(c))
                 r.min.x += drawstring(img, def.font, r, West, "(wedged) ", &col->fg);
- w = drawstring(img, def.font, r, West, c->name, &col->fg);
+ r.min.x += drawstring(img, def.font, r, West, c->name, &col->fg);
 
         /* Draw inner border on floating clients. */
         if(f->area->floating) {
- r.min.x = r.min.x + w + 10;
+ r.min.x += 10;
                 r.max.x += Dx(f->grabbox);
                 r.min.y = f->grabbox.min.y;
                 r.max.y = f->grabbox.max.y;
diff -r e638d4f40d56 -r 3a09477a41ff cmd/wmii/main.c
--- a/cmd/wmii/main.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/wmii/main.c Thu Oct 07 16:31:41 2010 -0400
@@ -372,8 +372,7 @@
         initdisplay();
 
         traperrors(true);
- selectinput(&scr.root, EnterWindowMask
- | SubstructureRedirectMask);
+ selectinput(&scr.root, SubstructureRedirectMask);
         if(traperrors(false))
                 fatal("another window manager is already running");
 
@@ -388,7 +387,7 @@
 
         sock = ixp_announce(address);
         if(sock < 0)
- fatal("Can't create socket '%s': %r", address);
+ fatal("Can't create socket %q: %r", address);
         closeexec(ConnectionNumber(display));
         closeexec(sock);
 
@@ -413,7 +412,6 @@
         def.incmode = ISqueeze;
 
         def.mod = Mod1Mask;
- strcpy(def.grabmod, "Mod1");
 
         loadcolor(&def.focuscolor, FOCUSCOLORS, nil);
         loadcolor(&def.normcolor, NORMCOLORS, nil);
diff -r e638d4f40d56 -r 3a09477a41ff cmd/wmii/message.c
--- a/cmd/wmii/message.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/wmii/message.c Thu Oct 07 16:31:41 2010 -0400
@@ -656,7 +656,6 @@
                 if(!parsekey(s, &i, nil) || i == 0)
                         return Ebadvalue;
 
- utflcpy(def.grabmod, s, sizeof def.grabmod);
                 def.mod = i;
                 break;
         case LINCMODE:
@@ -700,7 +699,7 @@
         bufprint("font %s\n", def.font->name);
         bufprint("fontpad %d %d %d %d\n", def.font->pad.min.x, def.font->pad.max.x,
                  def.font->pad.max.y, def.font->pad.min.y);
- bufprint("grabmod %s\n", def.grabmod);
+ bufprint("grabmod %s\n", (Mask){&def.mod, modkey_names});
         bufprint("incmode %s\n", incmodetab[def.incmode]);
         bufprint("normcolors %s\n", def.normcolor.colstr);
         bufprint("view %s\n", selview->name);
diff -r e638d4f40d56 -r 3a09477a41ff cmd/wmiir.c
--- a/cmd/wmiir.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/wmiir.c Thu Oct 07 16:31:41 2010 -0400
@@ -426,7 +426,7 @@
         path = ixp_namespace();
         if(path == nil)
                 fatal("can't find namespace: %r\n");
- Blprint(outbuf, "%s\n", path);
+ Blprint(outbuf, "%s", path);
         return 0;
 }
 
diff -r e638d4f40d56 -r 3a09477a41ff cmd/x11/wmii9menu.c
--- a/cmd/x11/wmii9menu.c Thu Oct 07 16:31:38 2010 -0400
+++ b/cmd/x11/wmii9menu.c Thu Oct 07 16:31:41 2010 -0400
@@ -58,15 +58,8 @@
 
 static int wborder;
 
-char buffer[8092];
-char* _buffer;
-
-/* for XSetWMProperties to use */
-int g_argc;
-char **g_argv;
-
-char *initial = "";
-int cur;
+static char* initial = "";
+static int cur;
 
 static char** labels; /* list of labels and commands */
 static char** commands;
@@ -78,13 +71,7 @@
 void size_window(int, int);
 void redraw(int, int);
 void warpmouse(int, int);
-void memory(void);
-int args(void);
 
-Cursor cursor[1];
-Visual* render_visual;
-
-void init_screens(void);
 void
 init_screens(void) {
         Rectangle *rects;
@@ -111,9 +98,6 @@
         char *cp;
         int i;
 
- g_argc = argc;
- g_argv = argv;
-
         ARGBEGIN{
         case 'v':
                 lprint(1, "%s\n", version);
@@ -137,29 +121,24 @@
         create_window();
 
         numitems = argc;
-
         labels = emalloc(numitems * sizeof *labels);
         commands = emalloc(numitems * sizeof *labels);
 
         for(i = 0; i < numitems; i++) {
                 labels[i] = argv[i];
+ commands[i] = argv[i];
                 if((cp = strchr(labels[i], ':')) != nil) {
                         *cp++ = '\0';
                         commands[i] = cp;
- } else
- commands[i] = labels[i];
+ }
                 if(strcmp(labels[i], initial) == 0)
                         cur = i;
         }
 
         client_init(address);
 
- wborder = strtol(readctl("border "), nil, 10);
- loadcolor(&cnorm, readctl("normcolors "), nil);
- loadcolor(&csel, readctl("focuscolors "), nil);
- font = loadfont(readctl("font "));
- if(!font)
- fatal("Can't load font");
+ wborder = strtol(readctl("/ctl", "border "), nil, 10);
+ client_readconfig(&cnorm, &csel, &font);
 
         run_menu();
 
@@ -167,28 +146,22 @@
         return 0;
 }
 
-/* usage --- print a usage message and die */
-
 void
 usage(void)
 {
- lprint(2, "usage: %s -v\n", argv0);
- lprint(2, " %s [-a <address>] [-i <arg>] menitem[:command] ...\n", argv0);
+ lprint(2, "usage: %s [-a <address>] [-i <arg>] <menitem>[:<command>] ...\n", argv0);
+ lprint(2, " %s -v\n", argv0);
         exit(0);
 }
 
-/* run_menu --- put up the window, execute selected commands */
-
 enum {
- MouseMask =
- ButtonPressMask
- | ButtonReleaseMask
- | ButtonMotionMask
- | PointerMotionMask,
- MenuMask =
- MouseMask
- | StructureNotifyMask
- | ExposureMask
+ MouseMask = ButtonPressMask
+ | ButtonReleaseMask
+ | ButtonMotionMask
+ | PointerMotionMask,
+ MenuMask = MouseMask
+ | StructureNotifyMask
+ | ExposureMask
 };
 
 void
@@ -197,8 +170,8 @@
         XEvent ev;
         int i, old, wide, high;
 
+ high = labelh(font);
         wide = 0;
- high = labelh(font);
         for(i = 0; i < numitems; i++)
                 wide = max(wide, textwidth(font, labels[i]));
         wide += font->height & ~1;
@@ -231,12 +204,10 @@
                                 break;
                         redraw(high, wide);
                         break;
- case MapNotify:
- redraw(high, wide);
- break;
                 case Expose:
                         redraw(high, wide);
                         break;
+ case MapNotify:
                 case ConfigureNotify:
                 case MappingNotify:
                         break;
@@ -244,13 +215,10 @@
         }
 }
 
-/* set_wm_hints --- set all the window manager hints */
-
 void
 create_window(void)
 {
         WinAttr wa = { 0 };
- XEvent e;
 
         wa.override_redirect = true;
         menuwin = createwindow(&scr.root, Rect(-1, -1, 0, 0),
@@ -258,10 +226,8 @@
                                &wa, CWOverrideRedirect);
         selectinput(menuwin, MenuMask);
         mapwin(menuwin);
- XMaskEvent(display, StructureNotifyMask, &e);
         if(!grabpointer(menuwin, nil, 0, MouseMask))
                 fatal("Failed to grab the mouse\n");
- XSetCommand(display, menuwin->xid, g_argv, g_argc);
 }
 
 void
@@ -284,34 +250,22 @@
         p.y = min(p.y, scr.rect.max.y - h);
 
         reshapewin(menuwin, rectaddpt(r, p));
-
- //XSetWindowBackground(display, menuwin->xid, cnorm.bg);
         setborder(menuwin, 1, &cnorm.border);
 }
 
-/* redraw --- actually redraw the menu */
-
 void
 redraw(int high, int wide)
 {
         Rectangle r;
- CTuple *c;
         int i;
 
         r = Rect(0, 0, wide, high);
         for(i = 0; i < numitems; i++) {
- if(cur == i)
- c = &csel;
- else
- c = &cnorm;
                 r = rectsetorigin(r, Pt(0, i * high));
- fill(menuwin, r, &c->bg);
- drawstring(menuwin, font, r, Center, labels[i], &c->fg);
+ fillstring(menuwin, font, r, Center, labels[i], (cur == i ? &csel : &cnorm), 0);
         }
 }
 
-/* warpmouse --- bring the mouse to the menu */
-
 void
 warpmouse(int wide, int high)
 {
diff -r e638d4f40d56 -r 3a09477a41ff img/mkfile
--- a/img/mkfile Thu Oct 07 16:31:38 2010 -0400
+++ b/img/mkfile Thu Oct 07 16:31:41 2010 -0400
@@ -2,18 +2,22 @@
 path=$PLAN9/bin $path
 
 eps = wmii.eps
-calc = rc -c 'hoc -e $"*'
+calc = rc -c 'echo 4k $* p | dc}
 
-epsbox = `{sed -n '/^%%BoundingBox:/{s/.*://p; q;}' $eps}
-iconwidth = 154
-iconscale = `{*=$epsbox; $calc $iconwidth / '('$3 - $1')'}
-iconheight = `{*=$epsbox; $calc '('$4 - $2') *' $iconscale}
+iconwidth = 16
+imagewidth = 154
 
-%.png: %.eps
+%.pdf: %.eps
+ sh epstopdf $stem.eps
+
+%-small.png: %.eps
+ epsbox = `{sed -n '/^%%BoundingBox:/{s/.*://p; q;}' $stem.eps}
+ iconscale = `{*=$epsbox; $calc $iconwidth $3 $1 -/}
+ iconheight = `{*=$epsbox; $calc $4 $2 - $iconscale '*'}
         * = `{hoc -e'-('$epsbox')'}
         x = $1
         y = $2
- gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$iconwidth'x'$iconheight - <<!
+ gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$iconwidth^x^$iconheight - <<!
                 $iconscale $iconscale scale
                 $x $y translate
                 ($eps) run
@@ -22,18 +26,15 @@
         !
         optipng -fix $target
 
-%.pdf: %.eps
- sh epstopdf $stem.eps
-
-%-small.png: %.eps
- iconwidth = 16
- iconscale = `{*=$epsbox; hoc -e $iconwidth/'('$3-' '$1')'}
- iconheight = `{*=$epsbox; hoc -e '('$4-' '$2')*'$iconscale}
+%.png: %.eps
+ epsbox = `{sed -n '/^%%BoundingBox:/{s/.*://p; q;}' $stem.eps}
+ imagescale = `{*=$epsbox; $calc $imagewidth $3 $1 -/}
+ imageheight = `{*=$epsbox; $calc $4 $2 - $imagescale '*'}
         * = `{hoc -e'-('$epsbox')'}
         x = $1
         y = $2
- gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$iconwidth'x'$iconheight - <<!
- $iconscale $iconscale scale
+ gs -q -dBATCH -dNOPAUSE -s'DEVICE=pngalpha' -s'OutputFile='$target -g$imagewidth^x^$imageheight - <<!
+ $imagescale $imagescale scale
                 $x $y translate
                 ($eps) run
                 showpage
diff -r e638d4f40d56 -r 3a09477a41ff include/stuff/clientutil.h
--- a/include/stuff/clientutil.h Thu Oct 07 16:31:38 2010 -0400
+++ b/include/stuff/clientutil.h Thu Oct 07 16:31:41 2010 -0400
@@ -6,7 +6,7 @@
 # define CLIENTEXTERN extern
 #endif
 
-char* readctl(char*);
+char* readctl(char*, char*);
 void client_init(char*);
 
 CLIENTEXTERN IxpClient* client;
diff -r e638d4f40d56 -r 3a09477a41ff include/stuff/geom.h
--- a/include/stuff/geom.h Thu Oct 07 16:31:38 2010 -0400
+++ b/include/stuff/geom.h Thu Oct 07 16:31:41 2010 -0400
@@ -30,8 +30,8 @@
 #define Dx(r) ((r).max.x - (r).min.x)
 #define Dy(r) ((r).max.y - (r).min.y)
 #define Pt(x, y) ((Point){(x), (y)})
-#define Rpt(p, q) ((Rectangle){p, q})
-#define Rect(x0, y0, x1, y1) ((Rectangle){Pt(x0, y0), Pt(x1, y1)})
+#define Rpt(p, q) ((Rectangle){(p), (q)})
+#define Rect(x0, y0, x1, y1) Rpt(Pt(x0, y0), Pt(x1, y1))
 
 Point addpt(Point, Point);
 Point divpt(Point, Point);
diff -r e638d4f40d56 -r 3a09477a41ff include/stuff/util.h
--- a/include/stuff/util.h Thu Oct 07 16:31:38 2010 -0400
+++ b/include/stuff/util.h Thu Oct 07 16:31:41 2010 -0400
@@ -42,13 +42,10 @@
 
 int Blprint(Biobuf*, const char*, ...);
 int Bvlprint(Biobuf*, const char*, va_list);
-extern char* _buffer;
 void _die(char*, int, char*, ...);
 void backtrace(char*);
-extern char buffer[8092];
 void closeexec(int);
 char** comm(int, char**, char**);
-extern char* const _buf_end;
 int doublefork(void);
 void* emalloc(uint);
 void* emallocz(uint);
@@ -90,6 +87,10 @@
 int utflcpy(char*, const char*, int);
 int vlprint(int, const char*, va_list);
 char* vsxprint(const char*, va_list);
+
+extern char* _buffer;
+extern char buffer[8092];
+extern char* const _buf_end;
 #define bufclear() \
         BLOCK( _buffer = buffer; _buffer[0] = '\0' )
 #define bufprint(...) \
diff -r e638d4f40d56 -r 3a09477a41ff include/stuff/x11.h
--- a/include/stuff/x11.h Thu Oct 07 16:31:38 2010 -0400
+++ b/include/stuff/x11.h Thu Oct 07 16:31:41 2010 -0400
@@ -261,6 +261,7 @@
 uint drawstring(Image*, Font*, Rectangle, Align, const char*, Color*);
 void fill(Image*, Rectangle, Color*);
 void fillpoly(Image*, Point*, int, Color*);
+uint fillstring(Image*, Font*, Rectangle, Align, const char*, CTuple*, int border);
 Window* findwin(XWindow);
 void freefont(Font*);
 void freeimage(Image *);
diff -r e638d4f40d56 -r 3a09477a41ff lib/libstuff/client_readconfig.c
--- a/lib/libstuff/client_readconfig.c Thu Oct 07 16:31:38 2010 -0400
+++ b/lib/libstuff/client_readconfig.c Thu Oct 07 16:31:41 2010 -0400
@@ -11,13 +11,13 @@
 client_readconfig(CTuple *norm, CTuple *focus, Font **font) {
 
         if(norm)
- loadcolor(norm, readctl("normcolors "), nil);
+ loadcolor(norm, readctl("/ctl", "normcolors "), nil);
         if(focus)
- loadcolor(focus, readctl("focuscolors "), nil);
- *font = loadfont(readctl("font "));
+ loadcolor(focus, readctl("/ctl", "focuscolors "), nil);
+ *font = loadfont(readctl("/ctl", "font "));
         if(!*font)
- fatal("Can't load font %q", readctl("font "));
- sscanf(readctl("fontpad "), "%d %d %d %d",
+ fatal("Can't load font %q", readctl("/ctl", "font "));
+ sscanf(readctl("/ctl", "fontpad "), "%d %d %d %d",
                &(*font)->pad.min.x, &(*font)->pad.max.x,
                &(*font)->pad.min.x, &(*font)->pad.max.y);
 }
diff -r e638d4f40d56 -r 3a09477a41ff lib/libstuff/clientutil.c
--- a/lib/libstuff/clientutil.c Thu Oct 07 16:31:38 2010 -0400
+++ b/lib/libstuff/clientutil.c Thu Oct 07 16:31:41 2010 -0400
@@ -10,20 +10,21 @@
 #include <stuff/clientutil.h>
 #include <stuff/util.h>
 
-static IxpCFid* ctlfid;
-static char ctl[1024];
-static char* ectl;
-
 char*
-readctl(char *key) {
+readctl(char *ctlname, char *key) {
+ static char ctlfile[128];
+ static char ctl[1024];
+ static char* ectl;
+ IxpCFid *fid;
         char *s, *p;
         int nkey, n;
 
- if(ctlfid == nil) {
- ctlfid = ixp_open(client, "ctl", OREAD);
- n = ixp_read(ctlfid, ctl, 1023);
+ if(strcmp(ctlname, ctlfile)) {
+ strncpy(ctlfile, ctlname, sizeof ctlfile);
+ fid = ixp_open(client, ctlfile, OREAD);
+ n = ixp_read(fid, ctl, sizeof ctl - 1);
                 ectl = ctl + n;
- ixp_close(ctlfid);
+ ixp_close(fid);
         }
 
         nkey = strlen(key);
@@ -36,7 +37,7 @@
                         n = (s ? s : ectl) - p;
                         s = freelater(emalloc(n + 1));
                         s[n] = '\0';
- return strncpy(s, p, n);
+ return memcpy(s, p, n);
                 }
         } while((p = strchr(p, '\n')));
         return "";
diff -r e638d4f40d56 -r 3a09477a41ff lib/libstuff/x11/drawing/drawstring.c
--- a/lib/libstuff/x11/drawing/drawstring.c Thu Oct 07 16:31:38 2010 -0400
+++ b/lib/libstuff/x11/drawing/drawstring.c Thu Oct 07 16:31:41 2010 -0400
@@ -5,6 +5,17 @@
 #include "../x11.h"
 
 uint
+fillstring(Image *dst, Font *font,
+ Rectangle r, Align align,
+ const char *text, CTuple *col, int borderw) {
+
+ fill(dst, r, &col->bg);
+ if(borderw)
+ border(dst, r, borderw, &col->border);
+ return drawstring(dst, font, r, align, text, &col->fg);
+}
+
+uint
 drawstring(Image *dst, Font *font,
            Rectangle r, Align align,
            const char *text, Color *col) {
diff -r e638d4f40d56 -r 3a09477a41ff mk/common.mk
--- a/mk/common.mk Thu Oct 07 16:31:38 2010 -0400
+++ b/mk/common.mk Thu Oct 07 16:31:41 2010 -0400
@@ -41,8 +41,8 @@
         for f in $(OBJ); do \
                 [ -f "$$f.c" ] && files="$$files $$f.c"; \
         done; \
- echo CTAGS $$files $(TAGFILES) || \
- ctags $$files $(TAGFILES)
+ echo CTAGS $$files $(TAGFILES); \
+ $(DEBUG) $(CTAGS) $$files $(TAGFILES)
 
 .PHONY: all options clean dist install uninstall depend cleandep tags
 .PHONY: simpleuninstall simpleinstall
diff -r e638d4f40d56 -r 3a09477a41ff util/compile
--- a/util/compile Thu Oct 07 16:31:38 2010 -0400
+++ b/util/compile Thu Oct 07 16:31:41 2010 -0400
@@ -49,7 +49,7 @@
                 nl=0
                 maxl=6
         }
- /: (error|note): .?Each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: In function |: At top level:|support .long long.|use of C99 long long|ISO C forbids conversion|warning:.*warn_unused_result/ {
+ tolower($0) ~ /: (error|note): .?each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: in function |: at top level:|support .long long.|use of c99 long long|iso c forbids conversion|warning:.*warn_unused_result/ {
                 next
         }
         $1 == "warning:" {
Received on Fri Oct 08 2010 - 20:41:49 CEST

This archive was generated by hypermail 2.2.0 : Fri Oct 08 2010 - 20:48:04 CEST