new libdraw, replaced cistrstr with fstrstr, simpler readstdin 00a60cb7
Connor Lane Smith · 2010-08-11 14:24 1 file(s) · +34 −40
dmenu.c +34 −40
13 13
#include <draw.h>
14 14
15 15
#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh))
16 -
#define LINEH                   (dc->font.height + 2)
17 16
#define MIN(a,b)                ((a) < (b) ? (a) : (b))
18 17
#define MAX(a,b)                ((a) > (b) ? (a) : (b))
19 18
#define UTF8_CODEPOINT(c)       (((c) & 0xc0) != 0x80)
27 26
28 27
static void appenditem(Item *item, Item **list, Item **last);
29 28
static void calcoffsets(void);
30 -
static char *cistrstr(const char *s, const char *sub);
31 29
static void drawmenu(void);
30 +
static char *fstrstr(const char *s, const char *sub);
32 31
static void grabkeyboard(void);
33 32
static void insert(const char *s, ssize_t n);
34 33
static void keypress(XKeyEvent *ev);
47 46
static const char *normfgcolor = "#000000";
48 47
static const char *selbgcolor  = "#0066ff";
49 48
static const char *selfgcolor  = "#ffffff";
49 +
static unsigned int bh, mw, mh;
50 50
static unsigned int inputw = 0;
51 51
static unsigned int lines = 0;
52 -
static unsigned int mw, mh;
53 52
static unsigned int promptw;
54 53
static unsigned long normcol[ColLast];
55 54
static unsigned long selcol[ColLast];
56 55
static Atom utf8;
57 56
static Bool topbar = True;
58 57
static DC *dc;
59 -
static Item *allitems, *matches;
60 -
static Item *curr, *prev, *next, *sel;
58 +
static Item *items = NULL;
59 +
static Item *matches, *sel;
60 +
static Item *prev, *curr, *next;
61 61
static Window root, win;
62 62
63 63
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
64 -
static char *(*fstrstr)(const char *, const char *) = strstr;
65 64
66 65
void
67 66
appenditem(Item *item, Item **list, Item **last) {
79 78
	unsigned int i, n;
80 79
81 80
	if(lines > 0)
82 -
		n = lines * LINEH;
81 +
		n = lines * bh;
83 82
	else
84 83
		n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">"));
85 84
86 85
	for(i = 0, next = curr; next; next = next->right)
87 -
		if((i += (lines > 0) ? LINEH : MIN(textw(dc, next->text), mw/3)) > n)
86 +
		if((i += (lines > 0) ? bh : MIN(textw(dc, next->text), mw/3)) > n)
88 87
			break;
89 88
	for(i = 0, prev = curr; prev && prev->left; prev = prev->left)
90 -
		if((i += (lines > 0) ? LINEH : MIN(textw(dc, prev->left->text), mw/3)) > n)
89 +
		if((i += (lines > 0) ? bh : MIN(textw(dc, prev->left->text), mw/3)) > n)
91 90
			break;
92 91
}
93 92
94 -
char *
95 -
cistrstr(const char *s, const char *sub) {
96 -
	size_t len;
97 -
98 -
	for(len = strlen(sub); *s; s++)
99 -
		if(!strncasecmp(s, sub, len))
100 -
			return (char *)s;
101 -
	return NULL;
102 -
}
103 -
104 93
void
105 94
drawmenu(void) {
106 95
	int curpos;
108 97
109 98
	dc->x = 0;
110 99
	dc->y = 0;
111 -
	dc->h = LINEH;
112 -
	drawrect(dc, 0, 0, mw, mh, BG(dc, normcol));
100 +
	dc->h = bh;
101 +
	drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol));
113 102
114 103
	if(prompt) {
115 104
		dc->w = promptw;
119 108
	dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
120 109
	drawtext(dc, text, normcol);
121 110
	if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w)
122 -
		drawrect(dc, curpos, 2, 1, dc->h - 4, FG(dc, normcol));
111 +
		drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol));
123 112
124 113
	if(lines > 0) {
125 114
		dc->w = mw - dc->x;
143 132
		if(next)
144 133
			drawtext(dc, ">", normcol);
145 134
	}
146 -
	commitdraw(dc, win);
135 +
	commitdraw(dc, win, mw, mh);
136 +
}
137 +
138 +
char *
139 +
fstrstr(const char *s, const char *sub) {
140 +
	size_t len;
141 +
142 +
	for(len = strlen(sub); *s; s++)
143 +
		if(!fstrncmp(s, sub, len))
144 +
			return (char *)s;
145 +
	return NULL;
147 146
}
148 147
149 148
void
338 337
339 338
	len = strlen(text);
340 339
	matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL;
341 -
	for(item = allitems; item; item = item->next)
340 +
	for(item = items; item; item = item->next)
342 341
		if(!fstrncmp(text, item->text, len + 1))
343 342
			appenditem(item, &lexact, &exactend);
344 343
		else if(!fstrncmp(text, item->text, len))
345 344
			appenditem(item, &lprefix, &prefixend);
346 345
		else if(fstrstr(item->text, text))
347 346
			appenditem(item, &lsubstr, &substrend);
347 +
348 348
	if(lexact) {
349 349
		matches = lexact;
350 350
		itemend = exactend;
387 387
void
388 388
readstdin(void) {
389 389
	char buf[sizeof text], *p;
390 -
	Item *item, *new;
390 +
	Item *item, **end;
391 391
392 -
	allitems = NULL;
393 -
	for(item = NULL; fgets(buf, sizeof buf, stdin); item = new) {
392 +
	for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) {
394 393
		if((p = strchr(buf, '\n')))
395 394
			*p = '\0';
396 -
		if(!(new = malloc(sizeof *new)))
397 -
			eprintf("cannot malloc %u bytes\n", sizeof *new);
398 -
		if(!(new->text = strdup(buf)))
395 +
		if(!(item = malloc(sizeof *item)))
396 +
			eprintf("cannot malloc %u bytes\n", sizeof *item);
397 +
		if(!(item->text = strdup(buf)))
399 398
			eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
400 -
		inputw = MAX(inputw, textw(dc, new->text));
401 -
		new->next = new->left = new->right = NULL;
402 -
		if(item)
403 -
			item->next = new;
404 -
		else
405 -
			allitems = new;
399 +
		inputw = MAX(inputw, textw(dc, item->text));
400 +
		item->next = item->left = item->right = NULL;
406 401
	}
407 402
}
408 403
449 444
	selcol[ColFG] = getcolor(dc, selfgcolor);
450 445
451 446
	/* menu geometry */
452 -
	mh = (lines + 1) * LINEH;
447 +
	bh = dc->font.height + 2;
448 +
	mh = (lines + 1) * bh;
453 449
#ifdef XINERAMA
454 450
	if((info = XineramaQueryScreens(dc->dpy, &n))) {
455 451
		int i, di;
510 506
		}
511 507
		else if(!strcmp(argv[i], "-b"))
512 508
			topbar = False;
513 -
		else if(!strcmp(argv[i], "-i")) {
509 +
		else if(!strcmp(argv[i], "-i"))
514 510
			fstrncmp = strncasecmp;
515 -
			fstrstr = cistrstr;
516 -
		}
517 511
		else if(i == argc-1)
518 512
			usage();
519 513
		/* double flags */