aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarg@10ksloc.org <unknown>2006-08-04 10:23:36 +0200
committerarg@10ksloc.org <unknown>2006-08-04 10:23:36 +0200
commit5077207088b08e6b21601cb19925d20e9d5af573 (patch)
tree053bd64a2dc6a33526dbb249d18697fedd74a1ab
parent7817523a685f0dbba2e074a448099558a54b1b9c (diff)
rearranged several stuff
-rw-r--r--LICENSE1
-rw-r--r--config.mk2
-rw-r--r--dmenu.h29
-rw-r--r--draw.c184
-rw-r--r--main.c256
-rw-r--r--util.c18
6 files changed, 220 insertions, 270 deletions
diff --git a/LICENSE b/LICENSE
index aa0a3ab..67e22c3 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,7 @@
1MIT/X Consortium License 1MIT/X Consortium License
2 2
3(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 3(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
4(C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com>
4 5
5Permission is hereby granted, free of charge, to any person obtaining a 6Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"), 7copy of this software and associated documentation files (the "Software"),
diff --git a/config.mk b/config.mk
index a4d21ac..2531d27 100644
--- a/config.mk
+++ b/config.mk
@@ -1,4 +1,4 @@
1# dwm version 1# dmenu version
2VERSION = 0.0 2VERSION = 0.0
3 3
4# Customize below to fit your system 4# Customize below to fit your system
diff --git a/dmenu.h b/dmenu.h
index 8d630ba..75b6266 100644
--- a/dmenu.h
+++ b/dmenu.h
@@ -7,6 +7,8 @@
7#include <X11/Xlib.h> 7#include <X11/Xlib.h>
8#include <X11/Xlocale.h> 8#include <X11/Xlocale.h>
9 9
10#define SPACE 30 /* px */
11
10typedef struct Brush Brush; 12typedef struct Brush Brush;
11typedef struct DC DC; 13typedef struct DC DC;
12typedef struct Fnt Fnt; 14typedef struct Fnt Fnt;
@@ -29,30 +31,17 @@ struct DC { /* draw context */
29 GC gc; 31 GC gc;
30}; 32};
31 33
32struct Brush { 34extern int screen;
33 GC gc; 35extern Display *dpy;
34 Drawable drawable; 36extern DC dc;
35 int x, y, w, h;
36 Fnt font;
37 unsigned long bg;
38 unsigned long fg;
39 unsigned long border;
40};
41
42
43 37
44/* draw.c */ 38/* draw.c */
45extern void draw(Display *dpy, Brush *b, Bool border, const char *text); 39extern void drawtext(const char *text, Bool invert, Bool border);
46extern void loadcolors(Display *dpy, int screen, Brush *b, 40extern unsigned long getcolor(const char *colstr);
47 const char *bg, const char *fg, const char *bo); 41extern void setfont(const char *fontstr);
48extern void loadfont(Display *dpy, Fnt *font, const char *fontstr); 42extern unsigned int textw(const char *text);
49extern unsigned int textnw(Fnt *font, char *text, unsigned int len);
50extern unsigned int textw(Fnt *font, char *text);
51extern unsigned int texth(Fnt *font);
52 43
53/* util.c */ 44/* util.c */
54extern void *emalloc(unsigned int size); 45extern void *emalloc(unsigned int size);
55extern void *emallocz(unsigned int size);
56extern void eprint(const char *errstr, ...); 46extern void eprint(const char *errstr, ...);
57extern char *estrdup(const char *str); 47extern char *estrdup(const char *str);
58extern void swap(void **p1, void **p2);
diff --git a/draw.c b/draw.c
index d747629..e0ff001 100644
--- a/draw.c
+++ b/draw.c
@@ -2,45 +2,62 @@
2 * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> 2 * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 * See LICENSE file for license details. 3 * See LICENSE file for license details.
4 */ 4 */
5 5#include "dmenu.h"
6#include <stdio.h> 6#include <stdio.h>
7#include <string.h> 7#include <string.h>
8#include <X11/Xlocale.h>
8 9
9#include "dmenu.h" 10/* static */
10 11
11static void 12static void
12drawborder(Display *dpy, Brush *b) 13drawborder(void)
13{ 14{
14 XPoint points[5]; 15 XPoint points[5];
15 XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter); 16
16 XSetForeground(dpy, b->gc, b->border); 17 XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
17 points[0].x = b->x; 18 XSetForeground(dpy, dc.gc, dc.border);
18 points[0].y = b->y; 19 points[0].x = dc.x;
19 points[1].x = b->w - 1; 20 points[0].y = dc.y;
21 points[1].x = dc.w - 1;
20 points[1].y = 0; 22 points[1].y = 0;
21 points[2].x = 0; 23 points[2].x = 0;
22 points[2].y = b->h - 1; 24 points[2].y = dc.h - 1;
23 points[3].x = -(b->w - 1); 25 points[3].x = -(dc.w - 1);
24 points[3].y = 0; 26 points[3].y = 0;
25 points[4].x = 0; 27 points[4].x = 0;
26 points[4].y = -(b->h - 1); 28 points[4].y = -(dc.h - 1);
27 XDrawLines(dpy, b->drawable, b->gc, points, 5, CoordModePrevious); 29 XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
30}
31
32static unsigned int
33textnw(const char *text, unsigned int len)
34{
35 XRectangle r;
36
37 if(dc.font.set) {
38 XmbTextExtents(dc.font.set, text, len, NULL, &r);
39 return r.width;
40 }
41 return XTextWidth(dc.font.xfont, text, len);
28} 42}
29 43
44/* extern */
45
30void 46void
31draw(Display *dpy, Brush *b, Bool border, const char *text) 47drawtext(const char *text, Bool invert, Bool border)
32{ 48{
33 unsigned int x, y, w, h, len; 49 int x, y, w, h;
34 static char buf[256]; 50 static char buf[256];
51 unsigned int len;
35 XGCValues gcv; 52 XGCValues gcv;
36 XRectangle r = { b->x, b->y, b->w, b->h }; 53 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
37 54
38 XSetForeground(dpy, b->gc, b->bg); 55 XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg);
39 XFillRectangles(dpy, b->drawable, b->gc, &r, 1); 56 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
40 57
41 w = 0; 58 w = 0;
42 if(border) 59 if(border)
43 drawborder(dpy, b); 60 drawborder();
44 61
45 if(!text) 62 if(!text)
46 return; 63 return;
@@ -51,121 +68,94 @@ draw(Display *dpy, Brush *b, Bool border, const char *text)
51 memcpy(buf, text, len); 68 memcpy(buf, text, len);
52 buf[len] = 0; 69 buf[len] = 0;
53 70
54 h = b->font.ascent + b->font.descent; 71 h = dc.font.ascent + dc.font.descent;
55 y = b->y + (b->h / 2) - (h / 2) + b->font.ascent; 72 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
56 x = b->x + (h / 2); 73 x = dc.x + (h / 2);
57 74
58 /* shorten text if necessary */ 75 /* shorten text if necessary */
59 while(len && (w = textnw(&b->font, buf, len)) > b->w - h) 76 while(len && (w = textnw(buf, len)) > dc.w - h)
60 buf[--len] = 0; 77 buf[--len] = 0;
61 78
62 if(w > b->w) 79 if(w > dc.w)
63 return; /* too long */ 80 return; /* too long */
64 81
65 gcv.foreground = b->fg; 82 gcv.foreground = invert ? dc.bg : dc.fg;
66 gcv.background = b->bg; 83 gcv.background = invert ? dc.fg : dc.bg;
67 if(b->font.set) { 84 if(dc.font.set) {
68 XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv); 85 XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv);
69 XmbDrawImageString(dpy, b->drawable, b->font.set, b->gc, 86 XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc,
70 x, y, buf, len); 87 x, y, buf, len);
71 } 88 }
72 else { 89 else {
73 gcv.font = b->font.xfont->fid; 90 gcv.font = dc.font.xfont->fid;
74 XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv); 91 XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv);
75 XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len); 92 XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len);
76 } 93 }
77} 94}
78 95
79static unsigned long 96unsigned long
80xloadcolors(Display *dpy, Colormap cmap, const char *colstr) 97getcolor(const char *colstr)
81{ 98{
99 Colormap cmap = DefaultColormap(dpy, screen);
82 XColor color; 100 XColor color;
101
83 XAllocNamedColor(dpy, cmap, colstr, &color, &color); 102 XAllocNamedColor(dpy, cmap, colstr, &color, &color);
84 return color.pixel; 103 return color.pixel;
85} 104}
86 105
87void 106void
88loadcolors(Display *dpy, int screen, Brush *b, 107setfont(const char *fontstr)
89 const char *bg, const char *fg, const char *border)
90{
91 Colormap cmap = DefaultColormap(dpy, screen);
92 b->bg = xloadcolors(dpy, cmap, bg);
93 b->fg = xloadcolors(dpy, cmap, fg);
94 b->border = xloadcolors(dpy, cmap, border);
95}
96
97unsigned int
98textnw(Fnt *font, char *text, unsigned int len)
99{
100 XRectangle r;
101 if(font->set) {
102 XmbTextExtents(font->set, text, len, NULL, &r);
103 return r.width;
104 }
105 return XTextWidth(font->xfont, text, len);
106}
107
108unsigned int
109textw(Fnt *font, char *text)
110{
111 return textnw(font, text, strlen(text));
112}
113
114unsigned int
115texth(Fnt *font)
116{
117 return font->height + 4;
118}
119
120void
121loadfont(Display *dpy, Fnt *font, const char *fontstr)
122{ 108{
123 char **missing, *def; 109 char **missing, *def;
124 int n; 110 int i, n;
125 111
126 missing = NULL; 112 missing = NULL;
127 def = "?";
128 setlocale(LC_ALL, ""); 113 setlocale(LC_ALL, "");
129 if(font->set) 114 if(dc.font.set)
130 XFreeFontSet(dpy, font->set); 115 XFreeFontSet(dpy, dc.font.set);
131 font->set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); 116 dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
132 if(missing) { 117 if(missing) {
133 while(n--) 118 while(n--)
134 fprintf(stderr, "missing fontset: %s\n", missing[n]); 119 fprintf(stderr, "missing fontset: %s\n", missing[n]);
135 XFreeStringList(missing); 120 XFreeStringList(missing);
136 if(font->set) { 121 if(dc.font.set) {
137 XFreeFontSet(dpy, font->set); 122 XFreeFontSet(dpy, dc.font.set);
138 font->set = NULL; 123 dc.font.set = NULL;
139 } 124 }
140 } 125 }
141 if(font->set) { 126 if(dc.font.set) {
142 XFontSetExtents *font_extents; 127 XFontSetExtents *font_extents;
143 XFontStruct **xfonts; 128 XFontStruct **xfonts;
144 char **font_names; 129 char **font_names;
145 unsigned int i; 130
146 131 dc.font.ascent = dc.font.descent = 0;
147 font->ascent = font->descent = 0; 132 font_extents = XExtentsOfFontSet(dc.font.set);
148 font_extents = XExtentsOfFontSet(font->set); 133 n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
149 n = XFontsOfFontSet(font->set, &xfonts, &font_names); 134 for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
150 for(i = 0, font->ascent = 0, font->descent = 0; i < n; i++) { 135 if(dc.font.ascent < (*xfonts)->ascent)
151 if(font->ascent < (*xfonts)->ascent) 136 dc.font.ascent = (*xfonts)->ascent;
152 font->ascent = (*xfonts)->ascent; 137 if(dc.font.descent < (*xfonts)->descent)
153 if(font->descent < (*xfonts)->descent) 138 dc.font.descent = (*xfonts)->descent;
154 font->descent = (*xfonts)->descent;
155 xfonts++; 139 xfonts++;
156 } 140 }
157 } 141 }
158 else { 142 else {
159 if(font->xfont) 143 if(dc.font.xfont)
160 XFreeFont(dpy, font->xfont); 144 XFreeFont(dpy, dc.font.xfont);
161 font->xfont = NULL; 145 dc.font.xfont = NULL;
162 font->xfont = XLoadQueryFont(dpy, fontstr); 146 dc.font.xfont = XLoadQueryFont(dpy, fontstr);
163 if (!font->xfont) 147 if (!dc.font.xfont)
164 font->xfont = XLoadQueryFont(dpy, "fixed"); 148 dc.font.xfont = XLoadQueryFont(dpy, "fixed");
165 if (!font->xfont) 149 if (!dc.font.xfont)
166 eprint("error, cannot load 'fixed' font\n"); 150 eprint("error, cannot init 'fixed' font\n");
167 font->ascent = font->xfont->ascent; 151 dc.font.ascent = dc.font.xfont->ascent;
168 font->descent = font->xfont->descent; 152 dc.font.descent = dc.font.xfont->descent;
169 } 153 }
170 font->height = font->ascent + font->descent; 154 dc.font.height = dc.font.ascent + dc.font.descent;
155}
156
157unsigned int
158textw(const char *text)
159{
160 return textnw(text, strlen(text)) + dc.font.height;
171} 161}
diff --git a/main.c b/main.c
index 18263d5..14524c9 100644
--- a/main.c
+++ b/main.c
@@ -16,74 +16,112 @@
16#include <X11/keysym.h> 16#include <X11/keysym.h>
17 17
18typedef struct Item Item; 18typedef struct Item Item;
19
20struct Item { 19struct Item {
21 Item *next; /* traverses all items */ 20 Item *next; /* traverses all items */
22 Item *left, *right; /* traverses items matching current search pattern */ 21 Item *left, *right; /* traverses items matching current search pattern */
23 char *text; 22 char *text;
24}; 23};
25 24
26static Display *dpy; 25/* static */
27static Window root;
28static Window win;
29static Bool done = False;
30
31static Item *allitem = NULL; /* first of all items */
32static Item *item = NULL; /* first of pattern matching items */
33static Item *sel = NULL;
34static Item *nextoff = NULL;
35static Item *prevoff = NULL;
36static Item *curroff = NULL;
37 26
38static int screen, mx, my, mw, mh; 27static char *title, text[4096];
39static char *title = NULL; 28static int mx, my, mw, mh;
40static char text[4096];
41static int ret = 0; 29static int ret = 0;
42static int nitem = 0; 30static int nitem = 0;
43static unsigned int cmdw = 0; 31static unsigned int cmdw = 0;
44static unsigned int tw = 0; 32static unsigned int tw = 0;
45static unsigned int cw = 0; 33static unsigned int cw = 0;
46static const int seek = 30; /* 30px */ 34static Bool done = False;
47 35static Item *allitems = NULL; /* first of all items */
48static Brush brush = {0}; 36static Item *item = NULL; /* first of pattern matching items */
49 37static Item *sel = NULL;
50static void draw_menu(); 38static Item *next = NULL;
51static void kpress(XKeyEvent * e); 39static Item *prev = NULL;
52 40static Item *curr = NULL;
53static char version[] = "dmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; 41static Window root;
42static Window win;
54 43
55static void 44static void
56update_offsets() 45calcoffsets()
57{ 46{
58 unsigned int tw, w = cmdw + 2 * seek; 47 unsigned int tw, w;
59 48
60 if(!curroff) 49 if(!curr)
61 return; 50 return;
62 51
63 for(nextoff = curroff; nextoff; nextoff=nextoff->right) { 52 w = cmdw + 2 * SPACE;
64 tw = textw(&brush.font, nextoff->text); 53 for(next = curr; next; next=next->right) {
54 tw = textw(next->text);
65 if(tw > mw / 3) 55 if(tw > mw / 3)
66 tw = mw / 3; 56 tw = mw / 3;
67 w += tw + brush.font.height; 57 w += tw;
68 if(w > mw) 58 if(w > mw)
69 break; 59 break;
70 } 60 }
71 61
72 w = cmdw + 2 * seek; 62 w = cmdw + 2 * SPACE;
73 for(prevoff = curroff; prevoff && prevoff->left; prevoff=prevoff->left) { 63 for(prev = curr; prev && prev->left; prev=prev->left) {
74 tw = textw(&brush.font, prevoff->left->text); 64 tw = textw(prev->left->text);
75 if(tw > mw / 3) 65 if(tw > mw / 3)
76 tw = mw / 3; 66 tw = mw / 3;
77 w += tw + brush.font.height; 67 w += tw;
78 if(w > mw) 68 if(w > mw)
79 break; 69 break;
80 } 70 }
81} 71}
82 72
83static void 73static void
84update_items(char *pattern) 74drawmenu()
75{
76 Item *i;
77
78 dc.x = 0;
79 dc.y = 0;
80 dc.w = mw;
81 dc.h = mh;
82 drawtext(NULL, False, False);
83
84 /* print command */
85 if(!title || text[0]) {
86 cmdw = cw;
87 if(cmdw && item)
88 dc.w = cmdw;
89 drawtext(text, False, False);
90 }
91 else {
92 cmdw = tw;
93 dc.w = cmdw;
94 drawtext(title, False, False);
95 }
96 dc.x += dc.w;
97
98 if(curr) {
99 dc.w = SPACE;
100 drawtext((curr && curr->left) ? "<" : NULL, False, False);
101 dc.x += dc.w;
102
103 /* determine maximum items */
104 for(i = curr; i != next; i=i->right) {
105 dc.border = False;
106 dc.w = textw(i->text);
107 if(dc.w > mw / 3)
108 dc.w = mw / 3;
109 drawtext(i->text, sel == i, sel == i);
110 dc.x += dc.w;
111 }
112
113 dc.x = mw - SPACE;
114 dc.w = SPACE;
115 drawtext(next ? ">" : NULL, False, False);
116 }
117 XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0);
118 XFlush(dpy);
119}
120
121static void
122input(char *pattern)
85{ 123{
86 unsigned int plen = strlen(pattern); 124 unsigned int plen;
87 Item *i, *j; 125 Item *i, *j;
88 126
89 if(!pattern) 127 if(!pattern)
@@ -94,10 +132,11 @@ update_items(char *pattern)
94 else 132 else
95 cmdw = tw; 133 cmdw = tw;
96 134
135 plen = strlen(pattern);
97 item = j = NULL; 136 item = j = NULL;
98 nitem = 0; 137 nitem = 0;
99 138
100 for(i = allitem; i; i=i->next) 139 for(i = allitems; i; i=i->next)
101 if(!plen || !strncmp(pattern, i->text, plen)) { 140 if(!plen || !strncmp(pattern, i->text, plen)) {
102 if(!j) 141 if(!j)
103 item = i; 142 item = i;
@@ -108,7 +147,7 @@ update_items(char *pattern)
108 j = i; 147 j = i;
109 nitem++; 148 nitem++;
110 } 149 }
111 for(i = allitem; i; i=i->next) 150 for(i = allitems; i; i=i->next)
112 if(plen && strncmp(pattern, i->text, plen) 151 if(plen && strncmp(pattern, i->text, plen)
113 && strstr(i->text, pattern)) { 152 && strstr(i->text, pattern)) {
114 if(!j) 153 if(!j)
@@ -121,75 +160,19 @@ update_items(char *pattern)
121 nitem++; 160 nitem++;
122 } 161 }
123 162
124 curroff = prevoff = nextoff = sel = item; 163 curr = prev = next = sel = item;
125 164 calcoffsets();
126 update_offsets();
127}
128
129/* creates brush structs for brush mode drawing */
130static void
131draw_menu()
132{
133 Item *i;
134
135 brush.x = 0;
136 brush.y = 0;
137 brush.w = mw;
138 brush.h = mh;
139 draw(dpy, &brush, False, 0);
140
141 /* print command */
142 if(!title || text[0]) {
143 cmdw = cw;
144 if(cmdw && item)
145 brush.w = cmdw;
146 draw(dpy, &brush, False, text);
147 }
148 else {
149 cmdw = tw;
150 brush.w = cmdw;
151 draw(dpy, &brush, False, title);
152 }
153 brush.x += brush.w;
154
155 if(curroff) {
156 brush.w = seek;
157 draw(dpy, &brush, False, (curroff && curroff->left) ? "<" : 0);
158 brush.x += brush.w;
159
160 /* determine maximum items */
161 for(i = curroff; i != nextoff; i=i->right) {
162 brush.border = False;
163 brush.w = textw(&brush.font, i->text);
164 if(brush.w > mw / 3)
165 brush.w = mw / 3;
166 brush.w += brush.font.height;
167 if(sel == i) {
168 swap((void **)&brush.fg, (void **)&brush.bg);
169 draw(dpy, &brush, True, i->text);
170 swap((void **)&brush.fg, (void **)&brush.bg);
171 }
172 else
173 draw(dpy, &brush, False, i->text);
174 brush.x += brush.w;
175 }
176
177 brush.x = mw - seek;
178 brush.w = seek;
179 draw(dpy, &brush, False, nextoff ? ">" : 0);
180 }
181 XCopyArea(dpy, brush.drawable, win, brush.gc, 0, 0, mw, mh, 0, 0);
182 XFlush(dpy);
183} 165}
184 166
185static void 167static void
186kpress(XKeyEvent * e) 168kpress(XKeyEvent * e)
187{ 169{
188 KeySym ksym;
189 char buf[32]; 170 char buf[32];
190 int num, prev_nitem; 171 int num, prev_nitem;
191 unsigned int i, len = strlen(text); 172 unsigned int i, len;
173 KeySym ksym;
192 174
175 len = strlen(text);
193 buf[0] = 0; 176 buf[0] = 0;
194 num = XLookupString(e, buf, sizeof(buf), &ksym, 0); 177 num = XLookupString(e, buf, sizeof(buf), &ksym, 0);
195 178
@@ -210,8 +193,8 @@ kpress(XKeyEvent * e)
210 case XK_U: 193 case XK_U:
211 case XK_u: 194 case XK_u:
212 text[0] = 0; 195 text[0] = 0;
213 update_items(text); 196 input(text);
214 draw_menu(); 197 drawmenu();
215 return; 198 return;
216 break; 199 break;
217 case XK_bracketleft: 200 case XK_bracketleft:
@@ -224,24 +207,24 @@ kpress(XKeyEvent * e)
224 if(!(sel && sel->left)) 207 if(!(sel && sel->left))
225 return; 208 return;
226 sel=sel->left; 209 sel=sel->left;
227 if(sel->right == curroff) { 210 if(sel->right == curr) {
228 curroff = prevoff; 211 curr = prev;
229 update_offsets(); 212 calcoffsets();
230 } 213 }
231 break; 214 break;
232 case XK_Tab: 215 case XK_Tab:
233 if(!sel) 216 if(!sel)
234 return; 217 return;
235 strncpy(text, sel->text, sizeof(text)); 218 strncpy(text, sel->text, sizeof(text));
236 update_items(text); 219 input(text);
237 break; 220 break;
238 case XK_Right: 221 case XK_Right:
239 if(!(sel && sel->right)) 222 if(!(sel && sel->right))
240 return; 223 return;
241 sel=sel->right; 224 sel=sel->right;
242 if(sel == nextoff) { 225 if(sel == next) {
243 curroff = nextoff; 226 curr = next;
244 update_offsets(); 227 calcoffsets();
245 } 228 }
246 break; 229 break;
247 case XK_Return: 230 case XK_Return:
@@ -265,9 +248,9 @@ kpress(XKeyEvent * e)
265 prev_nitem = nitem; 248 prev_nitem = nitem;
266 do { 249 do {
267 text[--i] = 0; 250 text[--i] = 0;
268 update_items(text); 251 input(text);
269 } while(i && nitem && prev_nitem == nitem); 252 } while(i && nitem && prev_nitem == nitem);
270 update_items(text); 253 input(text);
271 } 254 }
272 break; 255 break;
273 default: 256 default:
@@ -277,14 +260,14 @@ kpress(XKeyEvent * e)
277 strncat(text, buf, sizeof(text)); 260 strncat(text, buf, sizeof(text));
278 else 261 else
279 strncpy(text, buf, sizeof(text)); 262 strncpy(text, buf, sizeof(text));
280 update_items(text); 263 input(text);
281 } 264 }
282 } 265 }
283 draw_menu(); 266 drawmenu();
284} 267}
285 268
286static char * 269static char *
287read_allitems() 270readinput()
288{ 271{
289 static char *maxname = NULL; 272 static char *maxname = NULL;
290 char *p, buf[1024]; 273 char *p, buf[1024];
@@ -306,7 +289,7 @@ read_allitems()
306 new->next = new->left = new->right = NULL; 289 new->next = new->left = new->right = NULL;
307 new->text = p; 290 new->text = p;
308 if(!i) 291 if(!i)
309 allitem = new; 292 allitems = new;
310 else 293 else
311 i->next = new; 294 i->next = new;
312 i = new; 295 i = new;
@@ -315,21 +298,27 @@ read_allitems()
315 return maxname; 298 return maxname;
316} 299}
317 300
301/* extern */
302
303int screen;
304Display *dpy;
305DC dc = {0};
306
318int 307int
319main(int argc, char *argv[]) 308main(int argc, char *argv[])
320{ 309{
321 int i;
322 XSetWindowAttributes wa;
323 char *maxname; 310 char *maxname;
311 int i;
324 XEvent ev; 312 XEvent ev;
313 XSetWindowAttributes wa;
325 314
326 /* command line args */ 315 /* command line args */
327 for(i = 1; i < argc; i++) { 316 for(i = 1; i < argc; i++) {
328 if (argv[i][0] == '-') 317 if (argv[i][0] == '-')
329 switch (argv[i][1]) { 318 switch (argv[i][1]) {
330 case 'v': 319 case 'v':
331 fprintf(stdout, "%s", version); 320 fputs("dmenu-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
332 exit(0); 321 exit(EXIT_SUCCESS);
333 break; 322 break;
334 case 't': 323 case 't':
335 if(++i < argc) { 324 if(++i < argc) {
@@ -350,7 +339,7 @@ main(int argc, char *argv[])
350 screen = DefaultScreen(dpy); 339 screen = DefaultScreen(dpy);
351 root = RootWindow(dpy, screen); 340 root = RootWindow(dpy, screen);
352 341
353 maxname = read_allitems(); 342 maxname = readinput();
354 343
355 /* grab as early as possible, but after reading all items!!! */ 344 /* grab as early as possible, but after reading all items!!! */
356 while(XGrabKeyboard(dpy, root, True, GrabModeAsync, 345 while(XGrabKeyboard(dpy, root, True, GrabModeAsync,
@@ -358,8 +347,10 @@ main(int argc, char *argv[])
358 usleep(1000); 347 usleep(1000);
359 348
360 /* style */ 349 /* style */
361 loadcolors(dpy, screen, &brush, BGCOLOR, FGCOLOR, BORDERCOLOR); 350 dc.bg = getcolor(BGCOLOR);
362 loadfont(dpy, &brush.font, FONT); 351 dc.fg = getcolor(FGCOLOR);
352 dc.border = getcolor(BORDERCOLOR);
353 setfont(FONT);
363 354
364 wa.override_redirect = 1; 355 wa.override_redirect = 1;
365 wa.background_pixmap = ParentRelative; 356 wa.background_pixmap = ParentRelative;
@@ -367,28 +358,25 @@ main(int argc, char *argv[])
367 358
368 mx = my = 0; 359 mx = my = 0;
369 mw = DisplayWidth(dpy, screen); 360 mw = DisplayWidth(dpy, screen);
370 mh = texth(&brush.font); 361 mh = dc.font.height + 4;
371 362
372 win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, 363 win = XCreateWindow(dpy, root, mx, my, mw, mh, 0,
373 DefaultDepth(dpy, screen), CopyFromParent, 364 DefaultDepth(dpy, screen), CopyFromParent,
374 DefaultVisual(dpy, screen), 365 DefaultVisual(dpy, screen),
375 CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); 366 CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
376 XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); 367 XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm));
377 XFlush(dpy);
378 368
379 /* pixmap */ 369 /* pixmap */
380 brush.gc = XCreateGC(dpy, root, 0, 0); 370 dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen));
381 brush.drawable = XCreatePixmap(dpy, win, mw, mh, 371 dc.gc = XCreateGC(dpy, root, 0, 0);
382 DefaultDepth(dpy, screen));
383 XFlush(dpy);
384 372
385 if(maxname) 373 if(maxname)
386 cw = textw(&brush.font, maxname) + brush.font.height; 374 cw = textw(maxname);
387 if(cw > mw / 3) 375 if(cw > mw / 3)
388 cw = mw / 3; 376 cw = mw / 3;
389 377
390 if(title) { 378 if(title) {
391 tw = textw(&brush.font, title) + brush.font.height; 379 tw = textw(title);
392 if(tw > mw / 3) 380 if(tw > mw / 3)
393 tw = mw / 3; 381 tw = mw / 3;
394 } 382 }
@@ -396,10 +384,10 @@ main(int argc, char *argv[])
396 cmdw = title ? tw : cw; 384 cmdw = title ? tw : cw;
397 385
398 text[0] = 0; 386 text[0] = 0;
399 update_items(text); 387 input(text);
400 XMapRaised(dpy, win); 388 XMapRaised(dpy, win);
401 draw_menu(); 389 drawmenu();
402 XFlush(dpy); 390 XSync(dpy, False);
403 391
404 /* main event loop */ 392 /* main event loop */
405 while(!done && !XNextEvent(dpy, &ev)) { 393 while(!done && !XNextEvent(dpy, &ev)) {
@@ -409,7 +397,7 @@ main(int argc, char *argv[])
409 break; 397 break;
410 case Expose: 398 case Expose:
411 if(ev.xexpose.count == 0) 399 if(ev.xexpose.count == 0)
412 draw_menu(); 400 drawmenu();
413 break; 401 break;
414 default: 402 default:
415 break; 403 break;
@@ -417,8 +405,8 @@ main(int argc, char *argv[])
417 } 405 }
418 406
419 XUngrabKeyboard(dpy, CurrentTime); 407 XUngrabKeyboard(dpy, CurrentTime);
420 XFreePixmap(dpy, brush.drawable); 408 XFreePixmap(dpy, dc.drawable);
421 XFreeGC(dpy, brush.gc); 409 XFreeGC(dpy, dc.gc);
422 XDestroyWindow(dpy, win); 410 XDestroyWindow(dpy, win);
423 XCloseDisplay(dpy); 411 XCloseDisplay(dpy);
424 412
diff --git a/util.c b/util.c
index dff7af7..1b9bc57 100644
--- a/util.c
+++ b/util.c
@@ -29,16 +29,6 @@ emalloc(unsigned int size)
29 return res; 29 return res;
30} 30}
31 31
32void *
33emallocz(unsigned int size)
34{
35 void *res = calloc(1, size);
36
37 if(!res)
38 bad_malloc(size);
39 return res;
40}
41
42void 32void
43eprint(const char *errstr, ...) 33eprint(const char *errstr, ...)
44{ 34{
@@ -58,11 +48,3 @@ estrdup(const char *str)
58 bad_malloc(strlen(str)); 48 bad_malloc(strlen(str));
59 return res; 49 return res;
60} 50}
61
62void
63swap(void **p1, void **p2)
64{
65 void *tmp = *p1;
66 *p1 = *p2;
67 *p2 = tmp;
68}