commit ed809b8471e3878bceb69b049bc28c25fc381b99
parent 8ca9f3ca3ad36073958c39721a168d1b633081e9
Author: Kris Maglione <kris@suckless.org>
Date: Thu, 7 Oct 2010 16:31:41 -0400
[menu] Add vertical mode.
Diffstat:
27 files changed, 402 insertions(+), 467 deletions(-)
diff --git a/alternative_wmiircs/python/pygmi/util.py b/alternative_wmiircs/python/pygmi/util.py
@@ -29,14 +29,14 @@ def message(message):
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 --git a/cmd/menu/Makefile b/cmd/menu/Makefile
@@ -5,12 +5,13 @@ include $(ROOT)/mk/wmii.mk
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 --git a/cmd/menu/caret.c b/cmd/menu/caret.c
@@ -69,9 +69,7 @@ caret_find(int dir, int type) {
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 @@ caret_find(int dir, int type) {
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 --git a/cmd/menu/dat.h b/cmd/menu/dat.h
@@ -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 @@ EXTERN struct {
int filter_start;
} input;
-extern char binding_spec[];
-
-EXTERN int numlock;
-
-EXTERN long xtime;
-EXTERN Image* ibuf;
-EXTERN Font* font;
-EXTERN CTuple cnorm, csel;
-EXTERN bool ontop;
+EXTERN struct {
+ Window* win;
+ Image* buf;
+ char* prompt;
+ int height;
+ int rows;
+ bool ontop;
+ Rectangle itemr;
+ Point arrow;
+} menu;
-EXTERN Cursor cursor[1];
-EXTERN Visual* render_visual;
+extern char binding_spec[];
EXTERN IxpServer srv;
-EXTERN Window* barwin;
-
-EXTERN Item* items;
-EXTERN Item* matchfirst;
-EXTERN Item* matchstart;
-EXTERN Item* matchend;
-EXTERN Item* matchidx;
+EXTERN struct {
+ Item* all;
+ Item* first;
+ Item* start;
+ Item* end;
+ Item* sel;
+ int maxwidth;
+} match;
+
+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* prompt;
-EXTERN int promptw;
+EXTERN char* (*find)(const char*, const char*);
+EXTERN int (*compare)(const char*, const char*, size_t);
diff --git a/cmd/menu/history.c b/cmd/menu/history.c
@@ -19,25 +19,25 @@ history_search(int dir, char *string, int n) {
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 --git a/cmd/menu/keys.c b/cmd/menu/keys.c
@@ -13,7 +13,8 @@ struct Key {
char** action;
};
-static Key* bindings;
+static Key* bindings;
+static int numlock;
/*
* To do: Find my red black tree implementation.
diff --git a/cmd/menu/main.c b/cmd/menu/main.c
@@ -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 int screen_hint;
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 @@ populate_list(Biobuf *buf, bool hist) {
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 @@ populate_list(Biobuf *buf, bool hist) {
}
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 @@ check_competions(IxpConn *c) {
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 @@ update_filter(bool print) {
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 @@ init_screens(void) {
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 @@ init_screens(void) {
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 @@ main(int argc, char *argv[]) {
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 @@ main(int argc, char *argv[]) {
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 @@ main(int argc, char *argv[]) {
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 --git a/cmd/menu/menu.c b/cmd/menu/menu.c
@@ -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);
}
}
-static void
-menu_unmap(long id, void *p) {
+void
+menu_show(void) {
+ Rectangle r;
- USED(id, p);
- unmapwin(barwin);
- XFlush(display);
-}
+ if(menu.prompt)
+ promptw = textwidth(font, menu.prompt) + itempad;
-static void
-selectitem(Item *i) {
- if(i != matchidx) {
- caret_set(input.filter_start, input.pos - input.string);
- caret_insert(i->string, 0);
- matchidx = i;
- }
-}
+ r = textextents_l(font, "<", 1, nil);
+ menu.arrow = Pt(Dy(r) + itempad/2, Dx(r) + itempad/2);
-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.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_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;
+drawarrow(Image *img, Rectangle r, int up, Color *col) {
+ Point p[3], pt;
- 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;
- }
+ pt = Pt(menu.arrow.x - itempad/2, menu.arrow.y - itempad/2 & ~1);
- 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);
+ 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);
+}
- r2 = rd;
- r2.max.x = promptw + inputw;
- drawstring(ibuf, font, r2, West, input.string, &cnorm.fg);
+static Rectangle
+slice(Rectangle *rp, int x, int y) {
+ Rectangle r;
- 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);
+ 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;
+}
- if (prompt)
- drawstring(ibuf, font, rp, West, prompt, &cnorm.fg);
+static bool
+nextrect(Item *i, Rectangle *rp, Rectangle *src) {
+ Rectangle r;
- border(ibuf, rd, 1, &cnorm.border);
- copyimage(barwin, r, ibuf, ZP);
+ 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) {
- _menu_draw(true);
-}
-
-void
-menu_show(void) {
- Rectangle r;
- int height, pad;
-
- USED(menu_unmap);
-
- ltwidth = textwidth(font, "<");
+ 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);
+ }
- pad = (font->height & ~1)/2;
- height = labelh(font);
+ 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(ontop)
- r.max.y = r.min.y + height;
+ if(menu.ontop)
+ r.max.y = r.min.y + itemr.max.y;
else
- r.min.y = r.max.y - height;
- reshapewin(barwin, r);
+ r.min.y = r.max.y - barr.max.y;
+ reshapewin(menu.win, r);
- freeimage(ibuf);
- ibuf = allocimage(Dx(r), Dy(r), scr.depth);
+ /* Border window */
+ r = rectsubpt(r, r.min);
+ border(menu.buf, r, 1, &cnorm.border);
+ copyimage(menu.win, r, menu.buf, ZP);
+}
- mapwin(barwin);
- raisewin(barwin);
- menu_draw();
+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 != match.sel) {
+ caret_set(input.filter_start, input.pos - input.string);
+ caret_insert(i->string, 0);
+ match.sel = i;
+ if(i == match.start->prev)
+ match.start = pagestart(i);
+ if(i == match.end->next)
+ match.start = i;
+ }
}
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 @@ kdown_event(Window *w, void *aux, XKeyEvent *e) {
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 @@ kdown_event(Window *w, void *aux, XKeyEvent *e) {
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 --git a/cmd/tray/main.c b/cmd/tray/main.c
@@ -191,7 +191,7 @@ main(int argc, char *argv[]) {
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 --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c
@@ -195,9 +195,7 @@ bar_draw(WMScreen *s) {
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 --git a/cmd/wmii/client.c b/cmd/wmii/client.c
@@ -220,7 +220,8 @@ apply_rules(Client *c) {
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 @@ apply_rules(Client *c) {
}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 @@ client_extratags(Client *c) {
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 @@ client_applytags(Client *c, const char *tags) {
/* 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 --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h
@@ -313,8 +313,7 @@ EXTERN struct Defs {
uint keyssz;
Ruleset colrules;
Ruleset rules;
- char grabmod[5];
- ulong mod;
+ long mod;
uint border;
uint snap;
int colmode;
diff --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c
@@ -398,6 +398,7 @@ pushlabel(Image *img, Rectangle *rp, char *s, CTuple *col) {
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 @@ pushlabel(Image *img, Rectangle *rp, char *s, CTuple *col) {
drawstring(img, def.font, r, East,
s, &col->fg);
}
+ free(s);
}
void
@@ -415,7 +417,6 @@ frame_draw(Frame *f) {
CTuple *col;
Image *img;
char *s;
- uint w;
int n, m;
if(f == nil || f->view != selview || f->area == nil)
@@ -443,6 +444,9 @@ frame_draw(Frame *f) {
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 @@ frame_draw(Frame *f) {
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 @@ frame_draw(Frame *f) {
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, s, col);
- free(s);
+ pushlabel(img, &r, smprint("%d/%d", m, n), col);
}
+
/* Label clients with extra tags. */
- if((s = client_extratags(c))) {
+ 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 --git a/cmd/wmii/main.c b/cmd/wmii/main.c
@@ -372,8 +372,7 @@ main(int argc, char *argv[]) {
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 @@ main(int argc, char *argv[]) {
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 @@ main(int argc, char *argv[]) {
def.incmode = ISqueeze;
def.mod = Mod1Mask;
- strcpy(def.grabmod, "Mod1");
loadcolor(&def.focuscolor, FOCUSCOLORS, nil);
loadcolor(&def.normcolor, NORMCOLORS, nil);
diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c
@@ -656,7 +656,6 @@ message_root(void *p, IxpMsg *m) {
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 @@ readctl_root(void) {
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 --git a/cmd/wmiir.c b/cmd/wmiir.c
@@ -426,7 +426,7 @@ xnamespace(int argc, char *argv[]) {
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 --git a/cmd/x11/wmii9menu.c b/cmd/x11/wmii9menu.c
@@ -58,15 +58,8 @@ static Font* font;
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 create_window(void);
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 @@ main(int argc, char **argv)
char *cp;
int i;
- g_argc = argc;
- g_argv = argv;
-
ARGBEGIN{
case 'v':
lprint(1, "%s\n", version);
@@ -137,29 +121,24 @@ main(int argc, char **argv)
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 @@ main(int argc, char **argv)
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 @@ run_menu(void)
XEvent ev;
int i, old, wide, high;
- wide = 0;
high = labelh(font);
+ wide = 0;
for(i = 0; i < numitems; i++)
wide = max(wide, textwidth(font, labels[i]));
wide += font->height & ~1;
@@ -231,12 +204,10 @@ run_menu(void)
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 @@ run_menu(void)
}
}
-/* 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 @@ create_window(void)
&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 @@ size_window(int wide, int high)
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 --git a/img/mkfile b/img/mkfile
@@ -2,18 +2,22 @@ MKSHELL=rc
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 @@ iconheight = `{*=$epsbox; $calc '('$4 - $2') *' $iconscale}
!
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 --git a/include/stuff/clientutil.h b/include/stuff/clientutil.h
@@ -6,7 +6,7 @@
# define CLIENTEXTERN extern
#endif
-char* readctl(char*);
+char* readctl(char*, char*);
void client_init(char*);
CLIENTEXTERN IxpClient* client;
diff --git a/include/stuff/geom.h b/include/stuff/geom.h
@@ -30,8 +30,8 @@ typedef enum Align Align;
#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 --git a/include/stuff/util.h b/include/stuff/util.h
@@ -42,13 +42,10 @@ enum {
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 unquote(char*, char*[], int);
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 --git a/include/stuff/x11.h b/include/stuff/x11.h
@@ -261,6 +261,7 @@ void drawpoly(Image*, Point*, int, int cap, int w, Color*);
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 --git a/lib/libstuff/client_readconfig.c b/lib/libstuff/client_readconfig.c
@@ -11,13 +11,13 @@ void
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 --git a/lib/libstuff/clientutil.c b/lib/libstuff/clientutil.c
@@ -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 @@ readctl(char *key) {
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 --git a/lib/libstuff/x11/drawing/drawstring.c b/lib/libstuff/x11/drawing/drawstring.c
@@ -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 --git a/mk/common.mk b/mk/common.mk
@@ -41,8 +41,8 @@ tags:
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 --git a/util/compile b/util/compile
@@ -49,7 +49,7 @@ undup() { # GCC is crap.
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:" {