aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--config.h10
-rw-r--r--dmenu.c (renamed from main.c)149
-rw-r--r--dmenu.h41
-rw-r--r--draw.c61
-rw-r--r--util.c34
6 files changed, 149 insertions, 152 deletions
diff --git a/Makefile b/Makefile
index 35e30f5..dac3b6e 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
3 3
4include config.mk 4include config.mk
5 5
6SRC = draw.c main.c util.c 6SRC = dmenu.c
7OBJ = ${SRC:.c=.o} 7OBJ = ${SRC:.c=.o}
8 8
9all: options dmenu 9all: options dmenu
@@ -18,7 +18,7 @@ options:
18 @echo CC $< 18 @echo CC $<
19 @${CC} -c ${CFLAGS} $< 19 @${CC} -c ${CFLAGS} $<
20 20
21${OBJ}: dmenu.h config.mk 21${OBJ}: config.h config.mk
22 22
23dmenu: ${OBJ} 23dmenu: ${OBJ}
24 @echo CC -o $@ 24 @echo CC -o $@
@@ -31,7 +31,7 @@ clean:
31dist: clean 31dist: clean
32 @echo creating dist tarball 32 @echo creating dist tarball
33 @mkdir -p dmenu-${VERSION} 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 @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} 35 @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION}
36 @gzip dmenu-${VERSION}.tar 36 @gzip dmenu-${VERSION}.tar
37 @rm -rf dmenu-${VERSION} 37 @rm -rf dmenu-${VERSION}
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..973b2d1
--- /dev/null
+++ b/config.h
@@ -0,0 +1,10 @@
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 */
diff --git a/main.c b/dmenu.c
index fcabf01..b684175 100644
--- a/main.c
+++ b/dmenu.c
@@ -1,16 +1,37 @@
1/* See LICENSE file for copyright and license details. */ 1/* See LICENSE file for copyright and license details. */
2#include "dmenu.h"
3#include <ctype.h> 2#include <ctype.h>
4#include <locale.h> 3#include <locale.h>
4#include <stdarg.h>
5#include <stdlib.h> 5#include <stdlib.h>
6#include <stdio.h> 6#include <stdio.h>
7#include <string.h> 7#include <string.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <X11/Xlib.h>
9#include <X11/Xutil.h> 10#include <X11/Xutil.h>
10#include <X11/keysym.h> 11#include <X11/keysym.h>
11 12
13/* macros */
12#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) 14#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
13 15
16/* enums */
17enum { ColFG, ColBG, ColLast };
18
19/* typedefs */
20typedef 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
14typedef struct Item Item; 35typedef struct Item Item;
15struct Item { 36struct Item {
16 Item *next; /* traverses all items */ 37 Item *next; /* traverses all items */
@@ -18,8 +39,29 @@ struct Item {
18 char *text; 39 char *text;
19}; 40};
20 41
21/* static */ 42/* forward declarations */
43static void *emalloc(unsigned int size);
44static void eprint(const char *errstr, ...);
45static char *estrdup(const char *str);
46static void drawtext(const char *text, unsigned long col[ColLast]);
47static unsigned int textw(const char *text);
48static unsigned int textnw(const char *text, unsigned int len);
49static void calcoffsets(void);
50static void drawmenu(void);
51static Bool grabkeyboard(void);
52static unsigned long getcolor(const char *colstr);
53static void initfont(const char *fontstr);
54static int strido(const char *text, const char *pattern);
55static void match(char *pattern);
56static void kpress(XKeyEvent * e);
57static char *readstdin(void);
58static void usage(void);
59
22 60
61/* variables */
62static int screen;
63static Display *dpy;
64static DC dc = {0};
23static char text[4096]; 65static char text[4096];
24static char *prompt = NULL; 66static char *prompt = NULL;
25static int mw, mh; 67static int mw, mh;
@@ -38,6 +80,93 @@ static Item *curr = NULL;
38static Window root; 80static Window root;
39static Window win; 81static Window win;
40 82
83#include "config.h"
84
85static void *
86emalloc(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
94static void
95eprint(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
104static char *
105estrdup(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
114static void
115drawtext(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
154static unsigned int
155textw(const char *text) {
156 return textnw(text, strlen(text)) + dc.font.height;
157}
158
159static unsigned int
160textnw(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}
169
41static void 170static void
42calcoffsets(void) { 171calcoffsets(void) {
43 unsigned int tw, w; 172 unsigned int tw, w;
@@ -119,7 +248,7 @@ grabkeyboard(void) {
119} 248}
120 249
121static unsigned long 250static unsigned long
122initcolor(const char *colstr) { 251getcolor(const char *colstr) {
123 Colormap cmap = DefaultColormap(dpy, screen); 252 Colormap cmap = DefaultColormap(dpy, screen);
124 XColor color; 253 XColor color;
125 254
@@ -435,12 +564,6 @@ usage(void) {
435 " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); 564 " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n");
436} 565}
437 566
438/* extern */
439
440int screen;
441Display *dpy;
442DC dc = {0};
443
444int 567int
445main(int argc, char *argv[]) { 568main(int argc, char *argv[]) {
446 Bool bottom = False; 569 Bool bottom = False;
@@ -508,10 +631,10 @@ main(int argc, char *argv[]) {
508 } 631 }
509 XFreeModifiermap(modmap); 632 XFreeModifiermap(modmap);
510 /* style */ 633 /* style */
511 dc.norm[ColBG] = initcolor(normbg); 634 dc.norm[ColBG] = getcolor(normbg);
512 dc.norm[ColFG] = initcolor(normfg); 635 dc.norm[ColFG] = getcolor(normfg);
513 dc.sel[ColBG] = initcolor(selbg); 636 dc.sel[ColBG] = getcolor(selbg);
514 dc.sel[ColFG] = initcolor(selfg); 637 dc.sel[ColFG] = getcolor(selfg);
515 initfont(font); 638 initfont(font);
516 /* menu window */ 639 /* menu window */
517 wa.override_redirect = 1; 640 wa.override_redirect = 1;
diff --git a/dmenu.h b/dmenu.h
deleted file mode 100644
index 015e808..0000000
--- a/dmenu.h
+++ /dev/null
@@ -1,41 +0,0 @@
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 */
12enum { ColFG, ColBG, ColLast };
13
14typedef 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
29extern int screen;
30extern Display *dpy;
31extern DC dc; /* global drawing context */
32
33/* draw.c */
34void drawtext(const char *text, unsigned long col[ColLast]);
35unsigned int textw(const char *text);
36unsigned int textnw(const char *text, unsigned int len);
37
38/* util.c */
39void *emalloc(unsigned int size); /* allocates memory, exits on error */
40void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */
41char *estrdup(const char *str); /* duplicates str, exits on allocation error */
diff --git a/draw.c b/draw.c
deleted file mode 100644
index 72439c5..0000000
--- a/draw.c
+++ /dev/null
@@ -1,61 +0,0 @@
1/* See LICENSE file for copyright and license details. */
2#include "dmenu.h"
3#include <string.h>
4
5/* extern */
6
7void
8drawtext(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
47unsigned int
48textw(const char *text) {
49 return textnw(text, strlen(text)) + dc.font.height;
50}
51
52unsigned int
53textnw(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}
diff --git a/util.c b/util.c
deleted file mode 100644
index ff943d0..0000000
--- a/util.c
+++ /dev/null
@@ -1,34 +0,0 @@
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
8void *
9emalloc(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
17void
18eprint(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
27char *
28estrdup(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}