micromizing dmenu step 1 06ae8944
Anselm R. Garbe · 2007-09-16 20:14 6 file(s) · +149 −152
Makefile +3 −3
3 3
4 4
include config.mk
5 5
6 -
SRC = draw.c main.c util.c
6 +
SRC = dmenu.c
7 7
OBJ = ${SRC:.c=.o}
8 8
9 9
all: options dmenu
18 18
	@echo CC $<
19 19
	@${CC} -c ${CFLAGS} $<
20 20
21 -
${OBJ}: dmenu.h config.mk
21 +
${OBJ}: config.h config.mk
22 22
23 23
dmenu: ${OBJ}
24 24
	@echo CC -o $@
31 31
dist: clean
32 32
	@echo creating dist tarball
33 33
	@mkdir -p dmenu-${VERSION}
34 -
	@cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.h dmenu_path ${SRC} dmenu-${VERSION}
34 +
	@cp -R LICENSE Makefile README config.mk dmenu.1 config.h dmenu_path ${SRC} dmenu-${VERSION}
35 35
	@tar -cf dmenu-${VERSION}.tar dmenu-${VERSION}
36 36
	@gzip dmenu-${VERSION}.tar
37 37
	@rm -rf dmenu-${VERSION}
config.h (added) +10 −0
1 +
/* See LICENSE file for copyright and license details. */
2 +
3 +
/* appearance */
4 +
#define FONT			"-*-terminus-medium-r-*-*-12-*-*-*-*-*-iso10646-*"
5 +
#define NORMBGCOLOR		"#000"
6 +
#define NORMFGCOLOR		"#ccc"
7 +
#define SELBGCOLOR		"#00f"
8 +
#define SELFGCOLOR		"#fff"
9 +
/* next macro defines the space between menu items */
10 +
#define SPACE			30 /* px */
dmenu.h (deleted) +0 −41
1 -
/* See LICENSE file for copyright and license details. */
2 -
#include <X11/Xlib.h>
3 -
4 -
#define FONT			"-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*"
5 -
#define NORMBGCOLOR		"#eeeeee"
6 -
#define NORMFGCOLOR		"#222222"
7 -
#define SELBGCOLOR		"#006699"
8 -
#define SELFGCOLOR		"#ffffff"
9 -
#define SPACE			30 /* px */
10 -
11 -
/* color */
12 -
enum { ColFG, ColBG, ColLast };
13 -
14 -
typedef struct {
15 -
	int x, y, w, h;
16 -
	unsigned long norm[ColLast];
17 -
	unsigned long sel[ColLast];
18 -
	Drawable drawable;
19 -
	GC gc;
20 -
	struct {
21 -
		XFontStruct *xfont;
22 -
		XFontSet set;
23 -
		int ascent;
24 -
		int descent;
25 -
		int height;
26 -
	} font;
27 -
} DC; /* draw context */
28 -
29 -
extern int screen;
30 -
extern Display *dpy;
31 -
extern DC dc;				/* global drawing context */
32 -
33 -
/* draw.c */
34 -
void drawtext(const char *text, unsigned long col[ColLast]);
35 -
unsigned int textw(const char *text);
36 -
unsigned int textnw(const char *text, unsigned int len);
37 -
38 -
/* util.c */
39 -
void *emalloc(unsigned int size);	/* allocates memory, exits on error */
40 -
void eprint(const char *errstr, ...);	/* prints errstr and exits with 1 */
41 -
char *estrdup(const char *str);		/* duplicates str, exits on allocation error */
draw.c (deleted) +0 −61
1 -
/* See LICENSE file for copyright and license details. */
2 -
#include "dmenu.h"
3 -
#include <string.h>
4 -
5 -
/* extern */
6 -
7 -
void
8 -
drawtext(const char *text, unsigned long col[ColLast]) {
9 -
	int x, y, w, h;
10 -
	static char buf[256];
11 -
	unsigned int len, olen;
12 -
	XRectangle r = { dc.x, dc.y, dc.w, dc.h };
13 -
14 -
	XSetForeground(dpy, dc.gc, col[ColBG]);
15 -
	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
16 -
	if(!text)
17 -
		return;
18 -
	w = 0;
19 -
	olen = len = strlen(text);
20 -
	if(len >= sizeof buf)
21 -
		len = sizeof buf - 1;
22 -
	memcpy(buf, text, len);
23 -
	buf[len] = 0;
24 -
	h = dc.font.ascent + dc.font.descent;
25 -
	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
26 -
	x = dc.x + (h / 2);
27 -
	/* shorten text if necessary */
28 -
	while(len && (w = textnw(buf, len)) > dc.w - h)
29 -
		buf[--len] = 0;
30 -
	if(len < olen) {
31 -
		if(len > 1)
32 -
			buf[len - 1] = '.';
33 -
		if(len > 2)
34 -
			buf[len - 2] = '.';
35 -
		if(len > 3)
36 -
			buf[len - 3] = '.';
37 -
	}
38 -
	if(w > dc.w)
39 -
		return; /* too long */
40 -
	XSetForeground(dpy, dc.gc, col[ColFG]);
41 -
	if(dc.font.set)
42 -
		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
43 -
	else
44 -
		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
45 -
}
46 -
47 -
unsigned int
48 -
textw(const char *text) {
49 -
	return textnw(text, strlen(text)) + dc.font.height;
50 -
}
51 -
52 -
unsigned int
53 -
textnw(const char *text, unsigned int len) {
54 -
	XRectangle r;
55 -
56 -
	if(dc.font.set) {
57 -
		XmbTextExtents(dc.font.set, text, len, NULL, &r);
58 -
		return r.width;
59 -
	}
60 -
	return XTextWidth(dc.font.xfont, text, len);
61 -
}
main.c → dmenu.c +136 −13
1 1
/* See LICENSE file for copyright and license details. */
2 -
#include "dmenu.h"
3 2
#include <ctype.h>
4 3
#include <locale.h>
4 +
#include <stdarg.h>
5 5
#include <stdlib.h>
6 6
#include <stdio.h>
7 7
#include <string.h>
8 8
#include <unistd.h>
9 +
#include <X11/Xlib.h>
9 10
#include <X11/Xutil.h>
10 11
#include <X11/keysym.h>
11 12
13 +
/* macros */
12 14
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
13 15
16 +
/* enums */
17 +
enum { ColFG, ColBG, ColLast };
18 +
19 +
/* typedefs */
20 +
typedef struct {
21 +
	int x, y, w, h;
22 +
	unsigned long norm[ColLast];
23 +
	unsigned long sel[ColLast];
24 +
	Drawable drawable;
25 +
	GC gc;
26 +
	struct {
27 +
		XFontStruct *xfont;
28 +
		XFontSet set;
29 +
		int ascent;
30 +
		int descent;
31 +
		int height;
32 +
	} font;
33 +
} DC; /* draw context */
34 +
14 35
typedef struct Item Item;
15 36
struct Item {
16 37
	Item *next;		/* traverses all items */
18 39
	char *text;
19 40
};
20 41
21 -
/* static */
42 +
/* forward declarations */
43 +
static void *emalloc(unsigned int size);
44 +
static void eprint(const char *errstr, ...);
45 +
static char *estrdup(const char *str);
46 +
static void drawtext(const char *text, unsigned long col[ColLast]);
47 +
static unsigned int textw(const char *text);
48 +
static unsigned int textnw(const char *text, unsigned int len);
49 +
static void calcoffsets(void);
50 +
static void drawmenu(void);
51 +
static Bool grabkeyboard(void);
52 +
static unsigned long getcolor(const char *colstr);
53 +
static void initfont(const char *fontstr);
54 +
static int strido(const char *text, const char *pattern);
55 +
static void match(char *pattern);
56 +
static void kpress(XKeyEvent * e);
57 +
static char *readstdin(void);
58 +
static void usage(void);
59 +
22 60
61 +
/* variables */
62 +
static int screen;
63 +
static Display *dpy;
64 +
static DC dc = {0};
23 65
static char text[4096];
24 66
static char *prompt = NULL;
25 67
static int mw, mh;
37 79
static Item *curr = NULL;
38 80
static Window root;
39 81
static Window win;
82 +
83 +
#include "config.h"
84 +
85 +
static void *
86 +
emalloc(unsigned int size) {
87 +
	void *res = malloc(size);
88 +
89 +
	if(!res)
90 +
		eprint("fatal: could not malloc() %u bytes\n", size);
91 +
	return res;
92 +
}
93 +
94 +
static void
95 +
eprint(const char *errstr, ...) {
96 +
	va_list ap;
97 +
98 +
	va_start(ap, errstr);
99 +
	vfprintf(stderr, errstr, ap);
100 +
	va_end(ap);
101 +
	exit(EXIT_FAILURE);
102 +
}
103 +
104 +
static char *
105 +
estrdup(const char *str) {
106 +
	void *res = strdup(str);
107 +
108 +
	if(!res)
109 +
		eprint("fatal: could not malloc() %u bytes\n", strlen(str));
110 +
	return res;
111 +
}
112 +
113 +
114 +
static void
115 +
drawtext(const char *text, unsigned long col[ColLast]) {
116 +
	int x, y, w, h;
117 +
	static char buf[256];
118 +
	unsigned int len, olen;
119 +
	XRectangle r = { dc.x, dc.y, dc.w, dc.h };
120 +
121 +
	XSetForeground(dpy, dc.gc, col[ColBG]);
122 +
	XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
123 +
	if(!text)
124 +
		return;
125 +
	w = 0;
126 +
	olen = len = strlen(text);
127 +
	if(len >= sizeof buf)
128 +
		len = sizeof buf - 1;
129 +
	memcpy(buf, text, len);
130 +
	buf[len] = 0;
131 +
	h = dc.font.ascent + dc.font.descent;
132 +
	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
133 +
	x = dc.x + (h / 2);
134 +
	/* shorten text if necessary */
135 +
	while(len && (w = textnw(buf, len)) > dc.w - h)
136 +
		buf[--len] = 0;
137 +
	if(len < olen) {
138 +
		if(len > 1)
139 +
			buf[len - 1] = '.';
140 +
		if(len > 2)
141 +
			buf[len - 2] = '.';
142 +
		if(len > 3)
143 +
			buf[len - 3] = '.';
144 +
	}
145 +
	if(w > dc.w)
146 +
		return; /* too long */
147 +
	XSetForeground(dpy, dc.gc, col[ColFG]);
148 +
	if(dc.font.set)
149 +
		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
150 +
	else
151 +
		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
152 +
}
153 +
154 +
static unsigned int
155 +
textw(const char *text) {
156 +
	return textnw(text, strlen(text)) + dc.font.height;
157 +
}
158 +
159 +
static unsigned int
160 +
textnw(const char *text, unsigned int len) {
161 +
	XRectangle r;
162 +
163 +
	if(dc.font.set) {
164 +
		XmbTextExtents(dc.font.set, text, len, NULL, &r);
165 +
		return r.width;
166 +
	}
167 +
	return XTextWidth(dc.font.xfont, text, len);
168 +
}
40 169
41 170
static void
42 171
calcoffsets(void) {
119 248
}
120 249
121 250
static unsigned long
122 -
initcolor(const char *colstr) {
251 +
getcolor(const char *colstr) {
123 252
	Colormap cmap = DefaultColormap(dpy, screen);
124 253
	XColor color;
125 254
435 564
		"             [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n");
436 565
}
437 566
438 -
/* extern */
439 -
440 -
int screen;
441 -
Display *dpy;
442 -
DC dc = {0};
443 -
444 567
int
445 568
main(int argc, char *argv[]) {
446 569
	Bool bottom = False;
508 631
	}
509 632
	XFreeModifiermap(modmap);
510 633
	/* style */
511 -
	dc.norm[ColBG] = initcolor(normbg);
512 -
	dc.norm[ColFG] = initcolor(normfg);
513 -
	dc.sel[ColBG] = initcolor(selbg);
514 -
	dc.sel[ColFG] = initcolor(selfg);
634 +
	dc.norm[ColBG] = getcolor(normbg);
635 +
	dc.norm[ColFG] = getcolor(normfg);
636 +
	dc.sel[ColBG] = getcolor(selbg);
637 +
	dc.sel[ColFG] = getcolor(selfg);
515 638
	initfont(font);
516 639
	/* menu window */
517 640
	wa.override_redirect = 1;
util.c (deleted) +0 −34
1 -
/* See LICENSE file for copyright and license details. */
2 -
#include "dmenu.h"
3 -
#include <stdarg.h>
4 -
#include <stdio.h>
5 -
#include <stdlib.h>
6 -
#include <string.h>
7 -
8 -
void *
9 -
emalloc(unsigned int size) {
10 -
	void *res = malloc(size);
11 -
12 -
	if(!res)
13 -
		eprint("fatal: could not malloc() %u bytes\n", size);
14 -
	return res;
15 -
}
16 -
17 -
void
18 -
eprint(const char *errstr, ...) {
19 -
	va_list ap;
20 -
21 -
	va_start(ap, errstr);
22 -
	vfprintf(stderr, errstr, ap);
23 -
	va_end(ap);
24 -
	exit(EXIT_FAILURE);
25 -
}
26 -
27 -
char *
28 -
estrdup(const char *str) {
29 -
	void *res = strdup(str);
30 -
31 -
	if(!res)
32 -
		eprint("fatal: could not malloc() %u bytes\n", strlen(str));
33 -
	return res;
34 -
}