added dmenu.h, common.c 855a5663
Connor Lane Smith · 2010-07-02 06:49 6 file(s) · +204 −314
Makefile +7 −3
3 3
4 4
include config.mk
5 5
6 -
SRC = dinput.c dmenu.c
6 +
SRC = dinput.c dmenu.c common.c
7 7
OBJ = ${SRC:.c=.o}
8 8
9 9
all: options dinput dmenu
24 24
	@echo creating $@ from config.def.h
25 25
	@cp config.def.h $@
26 26
27 -
.o:
27 +
dinput: dinput.o common.o
28 28
	@echo CC -o $@
29 -
	@${CC} -o $@ $< ${LDFLAGS}
29 +
	@${CC} -o $@ $+ ${LDFLAGS}
30 +
31 +
dmenu: dmenu.o common.o
32 +
	@echo CC -o $@
33 +
	@${CC} -o $@ $+ ${LDFLAGS}
30 34
31 35
clean:
32 36
	@echo cleaning
common.c (added) +129 −0
1 +
/* See LICENSE file for copyright and license details. */
2 +
#include <stdlib.h>
3 +
#include <string.h>
4 +
#include <unistd.h>
5 +
#include <X11/keysym.h>
6 +
#ifdef XINERAMA
7 +
#include <X11/extensions/Xinerama.h>
8 +
#endif
9 +
#include "dmenu.h"
10 +
11 +
/* variables */
12 +
char *prompt = NULL;
13 +
char text[4096] = "";
14 +
int promptw = 0;
15 +
int screen;
16 +
unsigned int numlockmask = 0;
17 +
unsigned int mw, mh;
18 +
unsigned long normcol[ColLast];
19 +
unsigned long selcol[ColLast];
20 +
Bool topbar = True;
21 +
DC dc;
22 +
Display *dpy;
23 +
Window win, root;
24 +
25 +
void
26 +
grabkeyboard(void) {
27 +
	unsigned int len;
28 +
29 +
	for(len = 1000; len; len--) {
30 +
		if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
31 +
		== GrabSuccess)
32 +
			return;
33 +
		usleep(1000);
34 +
	}
35 +
	exit(EXIT_FAILURE);
36 +
}
37 +
38 +
void
39 +
run(void) {
40 +
	XEvent ev;
41 +
42 +
	/* main event loop */
43 +
	XSync(dpy, False);
44 +
	while(!XNextEvent(dpy, &ev))
45 +
		switch(ev.type) {
46 +
		case KeyPress:
47 +
			kpress(&ev.xkey);
48 +
			break;
49 +
		case Expose:
50 +
			if(ev.xexpose.count == 0)
51 +
				drawbar();
52 +
			break;
53 +
		case VisibilityNotify:
54 +
			if(ev.xvisibility.state != VisibilityUnobscured)
55 +
				XRaiseWindow(dpy, win);
56 +
			break;
57 +
		}
58 +
	exit(EXIT_FAILURE);
59 +
}
60 +
61 +
void
62 +
setup(unsigned int lines) {
63 +
	int i, j, x, y;
64 +
#if XINERAMA
65 +
	int n;
66 +
	XineramaScreenInfo *info = NULL;
67 +
#endif
68 +
	XModifierKeymap *modmap;
69 +
	XSetWindowAttributes wa;
70 +
71 +
	/* init modifier map */
72 +
	modmap = XGetModifierMapping(dpy);
73 +
	for(i = 0; i < 8; i++)
74 +
		for(j = 0; j < modmap->max_keypermod; j++) {
75 +
			if(modmap->modifiermap[i * modmap->max_keypermod + j]
76 +
			== XKeysymToKeycode(dpy, XK_Num_Lock))
77 +
				numlockmask = (1 << i);
78 +
		}
79 +
	XFreeModifiermap(modmap);
80 +
81 +
	dc.dpy = dpy;
82 +
	normcol[ColBG] = getcolor(&dc, normbgcolor);
83 +
	normcol[ColFG] = getcolor(&dc, normfgcolor);
84 +
	selcol[ColBG] = getcolor(&dc, selbgcolor);
85 +
	selcol[ColFG] = getcolor(&dc, selfgcolor);
86 +
	initfont(&dc, font);
87 +
88 +
	/* input window */
89 +
	wa.override_redirect = True;
90 +
	wa.background_pixmap = ParentRelative;
91 +
	wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
92 +
93 +
	/* input window geometry */
94 +
	mh = (dc.font.height + 2) * (lines + 1);
95 +
#if XINERAMA
96 +
	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
97 +
		i = 0;
98 +
		if(n > 1) {
99 +
			int di;
100 +
			unsigned int dui;
101 +
			Window dummy;
102 +
			if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
103 +
				for(i = 0; i < n; i++)
104 +
					if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
105 +
						break;
106 +
		}
107 +
		x = info[i].x_org;
108 +
		y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh;
109 +
		mw = info[i].width;
110 +
		XFree(info);
111 +
	}
112 +
	else
113 +
#endif
114 +
	{
115 +
		x = 0;
116 +
		y = topbar ? 0 : DisplayHeight(dpy, screen) - mh;
117 +
		mw = DisplayWidth(dpy, screen);
118 +
	}
119 +
120 +
	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
121 +
			DefaultDepth(dpy, screen), CopyFromParent,
122 +
			DefaultVisual(dpy, screen),
123 +
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
124 +
125 +
	setupdraw(&dc, win);
126 +
	if(prompt)
127 +
		promptw = MIN(textw(&dc, prompt), mw / 5);
128 +
	XMapRaised(dpy, win);
129 +
}
config.def.h +5 −6
1 1
/* See LICENSE file for copyright and license details. */
2 2
3 3
/* appearance */
4 -
const char *font        = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*";
5 -
const char *normbgcolor = "#cccccc";
6 -
const char *normfgcolor = "#000000";
7 -
const char *selbgcolor  = "#0066ff";
8 -
const char *selfgcolor  = "#ffffff";
9 -
unsigned int spaceitem  = 30; /* px between menu items */
4 +
static const char *font        = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*";
5 +
static const char *normbgcolor = "#cccccc";
6 +
static const char *normfgcolor = "#000000";
7 +
static const char *selbgcolor  = "#0066ff";
8 +
static const char *selfgcolor  = "#ffffff";
dinput.c +8 −142
4 4
#include <stdio.h>
5 5
#include <stdlib.h>
6 6
#include <string.h>
7 -
#include <unistd.h>
8 7
#include <X11/keysym.h>
9 8
#include <X11/Xlib.h>
10 9
#include <X11/Xutil.h>
11 -
#ifdef XINERAMA
12 -
#include <X11/extensions/Xinerama.h>
13 -
#endif
14 -
#include <draw.h>
15 -
16 -
/* macros */
17 -
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
18 -
#define MIN(a, b)               ((a) < (b) ? (a) : (b))
19 -
#define MAX(a, b)               ((a) > (b) ? (a) : (b))
20 -
#define IS_UTF8_1ST_CHAR(c)     ((((c) & 0xc0) == 0xc0) || !((c) & 0x80))
10 +
#include "dmenu.h"
21 11
22 12
/* forward declarations */
23 13
static void cleanup(void);
24 -
static void drawinput(void);
25 -
static void grabkeyboard(void);
26 -
static void kpress(XKeyEvent *e);
27 -
static void run(void);
28 -
static void setup(void);
29 -
30 -
#include "config.h"
31 14
32 15
/* variables */
33 -
static char *prompt = NULL;
34 -
static char text[4096];
35 -
static int promptw = 0;
36 -
static int screen;
37 16
static size_t cursor = 0;
38 -
static unsigned int numlockmask = 0;
39 -
static unsigned int mw, mh;
40 -
static unsigned long normcol[ColLast];
41 -
static unsigned long selcol[ColLast];
42 -
static Bool topbar = True;
43 -
static DC dc;
44 -
static Display *dpy;
45 -
static Window win, root;
46 17
47 18
void
48 19
cleanup(void) {
53 24
}
54 25
55 26
void
56 -
drawinput(void)
27 +
drawbar(void)
57 28
{
58 29
	dc.x = 0;
59 30
	dc.y = 0;
70 41
	drawtext(&dc, text, normcol);
71 42
	drawcursor(&dc, text, cursor, normcol);
72 43
	commitdraw(&dc, win);
73 -
}
74 -
75 -
void
76 -
grabkeyboard(void) {
77 -
	unsigned int len;
78 -
79 -
	for(len = 1000; len; len--) {
80 -
		if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
81 -
		== GrabSuccess)
82 -
			return;
83 -
		usleep(1000);
84 -
	}
85 -
	exit(EXIT_FAILURE);
86 44
}
87 45
88 46
void
207 165
		while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor]));
208 166
		break;
209 167
	}
210 -
	drawinput();
211 -
}
212 -
213 -
void
214 -
run(void) {
215 -
	XEvent ev;
216 -
217 -
	/* main event loop */
218 -
	XSync(dpy, False);
219 -
	while(!XNextEvent(dpy, &ev))
220 -
		switch(ev.type) {
221 -
		case KeyPress:
222 -
			kpress(&ev.xkey);
223 -
			break;
224 -
		case Expose:
225 -
			if(ev.xexpose.count == 0)
226 -
				drawinput();
227 -
			break;
228 -
		case VisibilityNotify:
229 -
			if(ev.xvisibility.state != VisibilityUnobscured)
230 -
				XRaiseWindow(dpy, win);
231 -
			break;
232 -
		}
233 -
	exit(EXIT_FAILURE);
234 -
}
235 -
236 -
void
237 -
setup(void) {
238 -
	int i, j, x, y;
239 -
#if XINERAMA
240 -
	int n;
241 -
	XineramaScreenInfo *info = NULL;
242 -
#endif
243 -
	XModifierKeymap *modmap;
244 -
	XSetWindowAttributes wa;
245 -
246 -
	/* init modifier map */
247 -
	modmap = XGetModifierMapping(dpy);
248 -
	for(i = 0; i < 8; i++)
249 -
		for(j = 0; j < modmap->max_keypermod; j++) {
250 -
			if(modmap->modifiermap[i * modmap->max_keypermod + j]
251 -
			== XKeysymToKeycode(dpy, XK_Num_Lock))
252 -
				numlockmask = (1 << i);
253 -
		}
254 -
	XFreeModifiermap(modmap);
255 -
256 -
	dc.dpy = dpy;
257 -
	normcol[ColBG] = getcolor(&dc, normbgcolor);
258 -
	normcol[ColFG] = getcolor(&dc, normfgcolor);
259 -
	selcol[ColBG] = getcolor(&dc, selbgcolor);
260 -
	selcol[ColFG] = getcolor(&dc, selfgcolor);
261 -
	initfont(&dc, font);
262 -
263 -
	/* input window */
264 -
	wa.override_redirect = True;
265 -
	wa.background_pixmap = ParentRelative;
266 -
	wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
267 -
268 -
	/* input window geometry */
269 -
	mh = dc.font.height + 2;
270 -
#if XINERAMA
271 -
	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
272 -
		i = 0;
273 -
		if(n > 1) {
274 -
			int di;
275 -
			unsigned int dui;
276 -
			Window dummy;
277 -
			if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
278 -
				for(i = 0; i < n; i++)
279 -
					if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
280 -
						break;
281 -
		}
282 -
		x = info[i].x_org;
283 -
		y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh;
284 -
		mw = info[i].width;
285 -
		XFree(info);
286 -
	}
287 -
	else
288 -
#endif
289 -
	{
290 -
		x = 0;
291 -
		y = topbar ? 0 : DisplayHeight(dpy, screen) - mh;
292 -
		mw = DisplayWidth(dpy, screen);
293 -
	}
294 -
295 -
	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
296 -
			DefaultDepth(dpy, screen), CopyFromParent,
297 -
			DefaultVisual(dpy, screen),
298 -
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
299 -
300 -
	setupdraw(&dc, win);
301 -
	if(prompt)
302 -
		promptw = MIN(textw(&dc, prompt), mw / 5);
303 -
	cursor = strlen(text);
304 -
	XMapRaised(dpy, win);
168 +
	drawbar();
305 169
}
306 170
307 171
int
336 200
			if(++i < argc) selfgcolor = argv[i];
337 201
		}
338 202
		else if(!strcmp(argv[i], "-v")) {
339 -
			printf("dinput-"VERSION", © 2006-2010 dinput engineers, see LICENSE for details\n");
203 +
			printf("dinput-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n");
340 204
			exit(EXIT_SUCCESS);
341 205
		}
342 -
		else if(!*text)
206 +
		else if(!*text) {
343 207
			strncpy(text, argv[i], sizeof text);
208 +
			cursor = strlen(text);
209 +
		}
344 210
		else {
345 211
			fputs("usage: dinput [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n"
346 212
			      "              [-p <prompt>] [-sb <color>] [-sf <color>] [-v] [<text>]\n", stderr);
356 222
	root = RootWindow(dpy, screen);
357 223
358 224
	grabkeyboard();
359 -
	setup();
225 +
	setup(0);
360 226
	run();
361 227
	return 0;
362 228
}
dmenu.c +25 −163
8 8
#include <X11/keysym.h>
9 9
#include <X11/Xlib.h>
10 10
#include <X11/Xutil.h>
11 -
#ifdef XINERAMA
12 -
#include <X11/extensions/Xinerama.h>
13 -
#endif
14 -
#include <draw.h>
15 -
16 -
/* macros */
17 -
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
18 -
#define MIN(a, b)               ((a) < (b) ? (a) : (b))
19 -
#define MAX(a, b)               ((a) > (b) ? (a) : (b))
20 -
#define IS_UTF8_1ST_CHAR(c)     ((((c) & 0xc0) == 0xc0) || !((c) & 0x80))
11 +
#include "dmenu.h"
21 12
22 13
typedef struct Item Item;
23 14
struct Item {
33 24
static char *cistrstr(const char *s, const char *sub);
34 25
static void cleanup(void);
35 26
static void dinput(void);
36 -
static void drawmenu(void);
37 27
static void drawmenuh(void);
38 28
static void drawmenuv(void);
39 -
static void grabkeyboard(void);
40 -
static void kpress(XKeyEvent *e);
41 -
static void match(char *pattern);
29 +
static void match(void);
42 30
static void readstdin(void);
43 -
static void run(void);
44 -
static void setup(void);
45 -
46 -
#include "config.h"
47 31
48 32
/* variables */
49 33
static char **argp = NULL;
50 34
static char *maxname = NULL;
51 -
static char *prompt = NULL;
52 -
static char text[4096];
53 -
static int cmdw = 0;
54 -
static int promptw = 0;
55 -
static int screen;
35 +
static unsigned int cmdw = 0;
56 36
static unsigned int lines = 0;
57 -
static unsigned int numlockmask = 0;
58 -
static unsigned int mw, mh;
59 -
static unsigned long normcol[ColLast];
60 -
static unsigned long selcol[ColLast];
61 -
static Bool topbar = True;
62 -
static DC dc;
63 -
static Display *dpy;
64 37
static Item *allitems = NULL;  /* first of all items */
65 38
static Item *item = NULL;      /* first of pattern matching items */
66 39
static Item *sel = NULL;
67 40
static Item *next = NULL;
68 41
static Item *prev = NULL;
69 42
static Item *curr = NULL;
70 -
static Window win, root;
71 43
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
72 44
static char *(*fstrstr)(const char *, const char *) = strstr;
73 45
static void (*calcoffsets)(void) = calcoffsetsh;
85 57
86 58
void
87 59
calcoffsetsh(void) {
88 -
	unsigned int x;
60 +
	unsigned int w, x;
89 61
90 -
	x = promptw + cmdw + (2 * spaceitem);
91 -
	for(next = curr; next; next = next->right)
62 +
	w = promptw + cmdw + textw(&dc, "<") + textw(&dc, ">");
63 +
	for(x = w, next = curr; next; next = next->right)
92 64
		if((x += MIN(textw(&dc, next->text), mw / 3)) > mw)
93 65
			break;
94 -
	x = promptw + cmdw + (2 * spaceitem);
95 -
	for(prev = curr; prev && prev->left; prev = prev->left)
66 +
	for(x = w, prev = curr; prev && prev->left; prev = prev->left)
96 67
		if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw)
97 68
			break;
98 69
}
157 128
}
158 129
159 130
void
160 -
drawmenu(void) {
131 +
drawbar(void) {
161 132
	dc.x = 0;
162 133
	dc.y = 0;
163 134
	dc.w = mw;
188 159
	Item *i;
189 160
190 161
	dc.x += cmdw;
191 -
	dc.w = spaceitem;
162 +
	dc.w = textw(&dc, "<");
192 163
	drawtext(&dc, curr->left ? "<" : NULL, normcol);
193 164
	dc.x += dc.w;
194 165
	for(i = curr; i != next; i = i->right) {
196 167
		drawtext(&dc, i->text, (sel == i) ? selcol : normcol);
197 168
		dc.x += dc.w;
198 169
	}
199 -
	dc.w = spaceitem;
170 +
	dc.w = textw(&dc, ">");
200 171
	dc.x = mw - dc.w;
201 172
	drawtext(&dc, next ? ">" : NULL, normcol);
202 173
}
218 189
}
219 190
220 191
void
221 -
grabkeyboard(void) {
222 -
	unsigned int len;
223 -
224 -
	for(len = 1000; len; len--) {
225 -
		if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
226 -
		== GrabSuccess)
227 -
			return;
228 -
		usleep(1000);
229 -
	}
230 -
	exit(EXIT_FAILURE);
231 -
}
232 -
233 -
void
234 192
kpress(XKeyEvent *e) {
235 193
	char buf[sizeof text];
236 194
	int num;
285 243
			break;
286 244
		case XK_u:
287 245
			text[0] = '\0';
288 -
			match(text);
246 +
			match();
289 247
			break;
290 248
		case XK_w:
291 249
			if(len == 0)
294 252
			while(i-- > 0 && text[i] == ' ');
295 253
			while(i-- > 0 && text[i] != ' ');
296 254
			text[++i] = '\0';
297 -
			match(text);
255 +
			match();
298 256
			break;
299 257
		}
300 258
	}
304 262
		if(num && !iscntrl((int) buf[0])) {
305 263
			memcpy(text + len, buf, num + 1);
306 264
			len += num;
307 -
			match(text);
265 +
			match();
308 266
		}
309 267
		break;
310 268
	case XK_BackSpace:
313 271
		for(i = 1; len - i > 0 && !IS_UTF8_1ST_CHAR(text[len - i]); i++);
314 272
		len -= i;
315 273
		text[len] = '\0';
316 -
		match(text);
274 +
		match();
317 275
		break;
318 276
	case XK_End:
319 277
		while(next) {
373 331
		dinput();
374 332
		break;
375 333
	}
376 -
	drawmenu();
334 +
	drawbar();
377 335
}
378 336
379 337
void
380 -
match(char *pattern) {
381 -
	unsigned int plen;
338 +
match(void) {
339 +
	unsigned int len;
382 340
	Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend;
383 341
384 -
	if(!pattern)
385 -
		return;
386 -
	plen = strlen(pattern);
342 +
	len = strlen(text);
387 343
	item = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL;
388 344
	for(i = allitems; i; i = i->next)
389 -
		if(!fstrncmp(pattern, i->text, plen + 1))
345 +
		if(!fstrncmp(text, i->text, len + 1))
390 346
			appenditem(i, &lexact, &exactend);
391 -
		else if(!fstrncmp(pattern, i->text, plen))
347 +
		else if(!fstrncmp(text, i->text, len))
392 348
			appenditem(i, &lprefix, &prefixend);
393 -
		else if(fstrstr(i->text, pattern))
349 +
		else if(fstrstr(i->text, text))
394 350
			appenditem(i, &lsubstr, &substrend);
395 351
	if(lexact) {
396 352
		item = lexact;
444 400
	}
445 401
}
446 402
447 -
void
448 -
run(void) {
449 -
	XEvent ev;
450 -
451 -
	/* main event loop */
452 -
	XSync(dpy, False);
453 -
	while(!XNextEvent(dpy, &ev))
454 -
		switch(ev.type) {
455 -
		case KeyPress:
456 -
			kpress(&ev.xkey);
457 -
			break;
458 -
		case Expose:
459 -
			if(ev.xexpose.count == 0)
460 -
				drawmenu();
461 -
			break;
462 -
		case VisibilityNotify:
463 -
			if(ev.xvisibility.state != VisibilityUnobscured)
464 -
				XRaiseWindow(dpy, win);
465 -
			break;
466 -
		}
467 -
	exit(EXIT_FAILURE);
468 -
}
469 -
470 -
void
471 -
setup(void) {
472 -
	int i, j, x, y;
473 -
#if XINERAMA
474 -
	int n;
475 -
	XineramaScreenInfo *info = NULL;
476 -
#endif
477 -
	XModifierKeymap *modmap;
478 -
	XSetWindowAttributes wa;
479 -
480 -
	/* init modifier map */
481 -
	modmap = XGetModifierMapping(dpy);
482 -
	for(i = 0; i < 8; i++)
483 -
		for(j = 0; j < modmap->max_keypermod; j++) {
484 -
			if(modmap->modifiermap[i * modmap->max_keypermod + j]
485 -
			== XKeysymToKeycode(dpy, XK_Num_Lock))
486 -
				numlockmask = (1 << i);
487 -
		}
488 -
	XFreeModifiermap(modmap);
489 -
490 -
	dc.dpy = dpy;
491 -
	normcol[ColBG] = getcolor(&dc, normbgcolor);
492 -
	normcol[ColFG] = getcolor(&dc, normfgcolor);
493 -
	selcol[ColBG] = getcolor(&dc, selbgcolor);
494 -
	selcol[ColFG] = getcolor(&dc, selfgcolor);
495 -
	initfont(&dc, font);
496 -
497 -
	/* menu window */
498 -
	wa.override_redirect = True;
499 -
	wa.background_pixmap = ParentRelative;
500 -
	wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
501 -
502 -
	/* menu window geometry */
503 -
	mh = (dc.font.height + 2) * (lines + 1);
504 -
#if XINERAMA
505 -
	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
506 -
		i = 0;
507 -
		if(n > 1) {
508 -
			int di;
509 -
			unsigned int dui;
510 -
			Window dummy;
511 -
			if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
512 -
				for(i = 0; i < n; i++)
513 -
					if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
514 -
						break;
515 -
		}
516 -
		x = info[i].x_org;
517 -
		y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh;
518 -
		mw = info[i].width;
519 -
		XFree(info);
520 -
	}
521 -
	else
522 -
#endif
523 -
	{
524 -
		x = 0;
525 -
		y = topbar ? 0 : mh - DisplayHeight(dpy, screen);
526 -
		mw = DisplayWidth(dpy, screen);
527 -
	}
528 -
529 -
	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
530 -
			DefaultDepth(dpy, screen), CopyFromParent,
531 -
			DefaultVisual(dpy, screen),
532 -
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
533 -
534 -
	setupdraw(&dc, win);
535 -
	if(maxname)
536 -
		cmdw = MIN(textw(&dc, maxname), mw / 3);
537 -
	if(prompt)
538 -
		promptw = MIN(textw(&dc, prompt), mw / 5);
539 -
	text[0] = '\0';
540 -
	match(text);
541 -
	XMapRaised(dpy, win);
542 -
}
543 -
544 403
int
545 404
main(int argc, char *argv[]) {
546 405
	unsigned int i;
600 459
601 460
	readstdin();
602 461
	grabkeyboard();
603 -
	setup();
462 +
	setup(lines);
463 +
	if(maxname)
464 +
		cmdw = MIN(textw(&dc, maxname), mw / 3);
465 +
	match();
604 466
	run();
605 467
	return 0;
606 468
}
dmenu.h (added) +30 −0
1 +
#include <X11/Xlib.h>
2 +
#include <draw.h>
3 +
#include "config.h"
4 +
5 +
/* macros */
6 +
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
7 +
#define MIN(a, b)               ((a) < (b) ? (a) : (b))
8 +
#define MAX(a, b)               ((a) > (b) ? (a) : (b))
9 +
#define IS_UTF8_1ST_CHAR(c)     ((((c) & 0xc0) == 0xc0) || !((c) & 0x80))
10 +
11 +
/* forward declarations */
12 +
void drawbar(void);
13 +
void grabkeyboard(void);
14 +
void kpress(XKeyEvent *e);
15 +
void run(void);
16 +
void setup(unsigned int lines);
17 +
18 +
/* variables */
19 +
extern char *prompt;
20 +
extern char text[4096];
21 +
extern int promptw;
22 +
extern int screen;
23 +
extern unsigned int numlockmask;
24 +
extern unsigned int mw, mh;
25 +
extern unsigned long normcol[ColLast];
26 +
extern unsigned long selcol[ColLast];
27 +
extern Bool topbar;
28 +
extern DC dc;
29 +
extern Display *dpy;
30 +
extern Window win, root;