aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnselm R. Garbe <arg@suckless.org>2007-02-19 15:49:50 +0100
committerAnselm R. Garbe <arg@suckless.org>2007-02-19 15:49:50 +0100
commit665488a6eedeecf743e44bd9624105c8b47c4f97 (patch)
tree6b564bcab3807ef1c470a44a079e3d22e82ff996
parent1e01ca03176e6e845a2a300545061e7384c4836d (diff)
removed draw.c, implemented C-w handling (backward word deletion)
-rw-r--r--Makefile2
-rw-r--r--config.mk2
-rw-r--r--dmenu.13
-rw-r--r--dmenu.h7
-rw-r--r--draw.c121
-rw-r--r--main.c127
6 files changed, 130 insertions, 132 deletions
diff --git a/Makefile b/Makefile
index 18279f6..66040d9 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 = main.c util.c
7OBJ = ${SRC:.c=.o} 7OBJ = ${SRC:.c=.o}
8 8
9all: options dmenu 9all: options dmenu
diff --git a/config.mk b/config.mk
index cc328ea..195fd4c 100644
--- a/config.mk
+++ b/config.mk
@@ -1,5 +1,5 @@
1# dmenu version 1# dmenu version
2VERSION = 2.2 2VERSION = 2.3
3 3
4# Customize below to fit your system 4# Customize below to fit your system
5 5
diff --git a/dmenu.1 b/dmenu.1
index c682711..2afa17c 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -90,6 +90,9 @@ Remove enough characters from the input field to change its filtering effect.
90.TP 90.TP
91.B Control-u 91.B Control-u
92Remove all characters from the input field. 92Remove all characters from the input field.
93.TP
94.B Control-w
95Remove all characters of current word from the input field.
93.SH SEE ALSO 96.SH SEE ALSO
94.BR dwm (1), 97.BR dwm (1),
95.BR wmii (1) . 98.BR wmii (1) .
diff --git a/dmenu.h b/dmenu.h
index b6c6aba..5c047ff 100644
--- a/dmenu.h
+++ b/dmenu.h
@@ -38,13 +38,6 @@ extern int screen;
38extern Display *dpy; 38extern Display *dpy;
39extern DC dc; /* global drawing context */ 39extern DC dc; /* global drawing context */
40 40
41/* draw.c */
42extern void drawtext(const char *text,
43 unsigned long col[ColLast]); /* draws text with the defined color tuple */
44extern unsigned long getcolor(const char *colstr); /* returns color of colstr */
45extern void setfont(const char *fontstr); /* sets global font */
46extern unsigned int textw(const char *text); /* returns width of text in px */
47
48/* util.c */ 41/* util.c */
49extern void *emalloc(unsigned int size); /* allocates memory, exits on error */ 42extern void *emalloc(unsigned int size); /* allocates memory, exits on error */
50extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ 43extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */
diff --git a/draw.c b/draw.c
deleted file mode 100644
index 92f07ca..0000000
--- a/draw.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/* (C)opyright MMIV-MMVII Anselm R. Garbe <garbeam at gmail dot com>
2 * See LICENSE file for license details.
3 */
4#include "dmenu.h"
5#include <stdio.h>
6#include <string.h>
7
8/* static */
9
10static unsigned int
11textnw(const char *text, unsigned int len) {
12 XRectangle r;
13
14 if(dc.font.set) {
15 XmbTextExtents(dc.font.set, text, len, NULL, &r);
16 return r.width;
17 }
18 return XTextWidth(dc.font.xfont, text, len);
19}
20
21/* extern */
22
23void
24drawtext(const char *text, unsigned long col[ColLast]) {
25 int x, y, w, h;
26 static char buf[256];
27 unsigned int len, olen;
28 XGCValues gcv;
29 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
30
31 XSetForeground(dpy, dc.gc, col[ColBG]);
32 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
33 if(!text)
34 return;
35 w = 0;
36 olen = len = strlen(text);
37 if(len >= sizeof buf)
38 len = sizeof buf - 1;
39 memcpy(buf, text, len);
40 buf[len] = 0;
41 h = dc.font.ascent + dc.font.descent;
42 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
43 x = dc.x + (h / 2);
44 /* shorten text if necessary */
45 while(len && (w = textnw(buf, len)) > dc.w - h)
46 buf[--len] = 0;
47 if(len < olen) {
48 if(len > 1)
49 buf[len - 1] = '.';
50 if(len > 2)
51 buf[len - 2] = '.';
52 if(len > 3)
53 buf[len - 3] = '.';
54 }
55 if(w > dc.w)
56 return; /* too long */
57 gcv.foreground = col[ColFG];
58 if(dc.font.set) {
59 XChangeGC(dpy, dc.gc, GCForeground, &gcv);
60 XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc,
61 x, y, buf, len);
62 }
63 else {
64 gcv.font = dc.font.xfont->fid;
65 XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
66 XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
67 }
68}
69
70unsigned long
71getcolor(const char *colstr) {
72 Colormap cmap = DefaultColormap(dpy, screen);
73 XColor color;
74
75 if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
76 eprint("error, cannot allocate color '%s'\n", colstr);
77 return color.pixel;
78}
79
80void
81setfont(const char *fontstr) {
82 char *def, **missing;
83 int i, n;
84
85 missing = NULL;
86 if(dc.font.set)
87 XFreeFontSet(dpy, dc.font.set);
88 dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
89 if(missing)
90 XFreeStringList(missing);
91 if(dc.font.set) {
92 XFontSetExtents *font_extents;
93 XFontStruct **xfonts;
94 char **font_names;
95 dc.font.ascent = dc.font.descent = 0;
96 font_extents = XExtentsOfFontSet(dc.font.set);
97 n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
98 for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
99 if(dc.font.ascent < (*xfonts)->ascent)
100 dc.font.ascent = (*xfonts)->ascent;
101 if(dc.font.descent < (*xfonts)->descent)
102 dc.font.descent = (*xfonts)->descent;
103 xfonts++;
104 }
105 }
106 else {
107 if(dc.font.xfont)
108 XFreeFont(dpy, dc.font.xfont);
109 dc.font.xfont = NULL;
110 if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
111 eprint("error, cannot load font: '%s'\n", fontstr);
112 dc.font.ascent = dc.font.xfont->ascent;
113 dc.font.descent = dc.font.xfont->descent;
114 }
115 dc.font.height = dc.font.ascent + dc.font.descent;
116}
117
118unsigned int
119textw(const char *text) {
120 return textnw(text, strlen(text)) + dc.font.height;
121}
diff --git a/main.c b/main.c
index f1f71fd..0840643 100644
--- a/main.c
+++ b/main.c
@@ -44,6 +44,22 @@ static Item *curr = NULL;
44static Window root; 44static Window root;
45static Window win; 45static Window win;
46 46
47static unsigned int
48textnw(const char *text, unsigned int len) {
49 XRectangle r;
50
51 if(dc.font.set) {
52 XmbTextExtents(dc.font.set, text, len, NULL, &r);
53 return r.width;
54 }
55 return XTextWidth(dc.font.xfont, text, len);
56}
57
58static unsigned int
59textw(const char *text) {
60 return textnw(text, strlen(text)) + dc.font.height;
61}
62
47static void 63static void
48calcoffsets(void) { 64calcoffsets(void) {
49 unsigned int tw, w; 65 unsigned int tw, w;
@@ -71,6 +87,53 @@ calcoffsets(void) {
71} 87}
72 88
73static void 89static void
90drawtext(const char *text, unsigned long col[ColLast]) {
91 int x, y, w, h;
92 static char buf[256];
93 unsigned int len, olen;
94 XGCValues gcv;
95 XRectangle r = { dc.x, dc.y, dc.w, dc.h };
96
97 XSetForeground(dpy, dc.gc, col[ColBG]);
98 XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
99 if(!text)
100 return;
101 w = 0;
102 olen = len = strlen(text);
103 if(len >= sizeof buf)
104 len = sizeof buf - 1;
105 memcpy(buf, text, len);
106 buf[len] = 0;
107 h = dc.font.ascent + dc.font.descent;
108 y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
109 x = dc.x + (h / 2);
110 /* shorten text if necessary */
111 while(len && (w = textnw(buf, len)) > dc.w - h)
112 buf[--len] = 0;
113 if(len < olen) {
114 if(len > 1)
115 buf[len - 1] = '.';
116 if(len > 2)
117 buf[len - 2] = '.';
118 if(len > 3)
119 buf[len - 3] = '.';
120 }
121 if(w > dc.w)
122 return; /* too long */
123 gcv.foreground = col[ColFG];
124 if(dc.font.set) {
125 XChangeGC(dpy, dc.gc, GCForeground, &gcv);
126 XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc,
127 x, y, buf, len);
128 }
129 else {
130 gcv.font = dc.font.xfont->fid;
131 XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
132 XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
133 }
134}
135
136static void
74drawmenu(void) { 137drawmenu(void) {
75 Item *i; 138 Item *i;
76 139
@@ -111,6 +174,54 @@ drawmenu(void) {
111 XFlush(dpy); 174 XFlush(dpy);
112} 175}
113 176
177static unsigned long
178getcolor(const char *colstr) {
179 Colormap cmap = DefaultColormap(dpy, screen);
180 XColor color;
181
182 if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
183 eprint("error, cannot allocate color '%s'\n", colstr);
184 return color.pixel;
185}
186
187static void
188setfont(const char *fontstr) {
189 char *def, **missing;
190 int i, n;
191
192 missing = NULL;
193 if(dc.font.set)
194 XFreeFontSet(dpy, dc.font.set);
195 dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
196 if(missing)
197 XFreeStringList(missing);
198 if(dc.font.set) {
199 XFontSetExtents *font_extents;
200 XFontStruct **xfonts;
201 char **font_names;
202 dc.font.ascent = dc.font.descent = 0;
203 font_extents = XExtentsOfFontSet(dc.font.set);
204 n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
205 for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
206 if(dc.font.ascent < (*xfonts)->ascent)
207 dc.font.ascent = (*xfonts)->ascent;
208 if(dc.font.descent < (*xfonts)->descent)
209 dc.font.descent = (*xfonts)->descent;
210 xfonts++;
211 }
212 }
213 else {
214 if(dc.font.xfont)
215 XFreeFont(dpy, dc.font.xfont);
216 dc.font.xfont = NULL;
217 if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
218 eprint("error, cannot load font: '%s'\n", fontstr);
219 dc.font.ascent = dc.font.xfont->ascent;
220 dc.font.descent = dc.font.xfont->descent;
221 }
222 dc.font.height = dc.font.ascent + dc.font.descent;
223}
224
114static void 225static void
115match(char *pattern) { 226match(char *pattern) {
116 unsigned int plen; 227 unsigned int plen;
@@ -151,8 +262,8 @@ match(char *pattern) {
151static void 262static void
152kpress(XKeyEvent * e) { 263kpress(XKeyEvent * e) {
153 char buf[32]; 264 char buf[32];
154 int num, prev_nitem; 265 int i, num, prev_nitem;
155 unsigned int i, len; 266 unsigned int len;
156 KeySym ksym; 267 KeySym ksym;
157 268
158 len = strlen(text); 269 len = strlen(text);
@@ -188,6 +299,18 @@ kpress(XKeyEvent * e) {
188 match(text); 299 match(text);
189 drawmenu(); 300 drawmenu();
190 return; 301 return;
302 case XK_w:
303 case XK_W:
304 if(len) {
305 i = len - 1;
306 while(i >= 0 && text[i] == ' ')
307 text[i--] = 0;
308 while(i >= 0 && text[i] != ' ')
309 text[i--] = 0;
310 match(text);
311 drawmenu();
312 }
313 return;
191 } 314 }
192 } 315 }
193 if(CLEANMASK(e->state) & Mod1Mask) { 316 if(CLEANMASK(e->state) & Mod1Mask) {