diff options
-rw-r--r-- | dmenu.h | 3 | ||||
-rw-r--r-- | draw.c | 10 | ||||
-rw-r--r-- | main.c | 27 | ||||
-rw-r--r-- | util.c | 5 |
4 files changed, 8 insertions, 37 deletions
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
2 | * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||
3 | * See LICENSE file for license details. | 2 | * See LICENSE file for license details. |
4 | */ | 3 | */ |
5 | 4 | ||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* (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. | 2 | * See LICENSE file for license details. |
4 | */ | 3 | */ |
5 | #include "dmenu.h" | 4 | #include "dmenu.h" |
@@ -32,21 +31,17 @@ drawtext(const char *text, unsigned long col[ColLast]) { | |||
32 | 31 | ||
33 | XSetForeground(dpy, dc.gc, col[ColBG]); | 32 | XSetForeground(dpy, dc.gc, col[ColBG]); |
34 | XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); | 33 | XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); |
35 | |||
36 | if(!text) | 34 | if(!text) |
37 | return; | 35 | return; |
38 | |||
39 | w = 0; | 36 | w = 0; |
40 | olen = len = strlen(text); | 37 | olen = len = strlen(text); |
41 | if(len >= sizeof(buf)) | 38 | if(len >= sizeof(buf)) |
42 | len = sizeof(buf) - 1; | 39 | len = sizeof(buf) - 1; |
43 | memcpy(buf, text, len); | 40 | memcpy(buf, text, len); |
44 | buf[len] = 0; | 41 | buf[len] = 0; |
45 | |||
46 | h = dc.font.ascent + dc.font.descent; | 42 | h = dc.font.ascent + dc.font.descent; |
47 | y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; | 43 | y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; |
48 | x = dc.x + (h / 2); | 44 | x = dc.x + (h / 2); |
49 | |||
50 | /* shorten text if necessary */ | 45 | /* shorten text if necessary */ |
51 | while(len && (w = textnw(buf, len)) > dc.w - h) | 46 | while(len && (w = textnw(buf, len)) > dc.w - h) |
52 | buf[--len] = 0; | 47 | buf[--len] = 0; |
@@ -58,10 +53,8 @@ drawtext(const char *text, unsigned long col[ColLast]) { | |||
58 | if(len > 3) | 53 | if(len > 3) |
59 | buf[len - 3] = '.'; | 54 | buf[len - 3] = '.'; |
60 | } | 55 | } |
61 | |||
62 | if(w > dc.w) | 56 | if(w > dc.w) |
63 | return; /* too long */ | 57 | return; /* too long */ |
64 | |||
65 | gcv.foreground = col[ColFG]; | 58 | gcv.foreground = col[ColFG]; |
66 | if(dc.font.set) { | 59 | if(dc.font.set) { |
67 | XChangeGC(dpy, dc.gc, GCForeground, &gcv); | 60 | XChangeGC(dpy, dc.gc, GCForeground, &gcv); |
@@ -106,7 +99,6 @@ setfont(const char *fontstr) { | |||
106 | XFontSetExtents *font_extents; | 99 | XFontSetExtents *font_extents; |
107 | XFontStruct **xfonts; | 100 | XFontStruct **xfonts; |
108 | char **font_names; | 101 | char **font_names; |
109 | |||
110 | dc.font.ascent = dc.font.descent = 0; | 102 | dc.font.ascent = dc.font.descent = 0; |
111 | font_extents = XExtentsOfFontSet(dc.font.set); | 103 | font_extents = XExtentsOfFontSet(dc.font.set); |
112 | n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); | 104 | n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names); |
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
2 | * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||
3 | * (C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com> | 2 | * (C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com> |
4 | * See LICENSE file for license details. | 3 | * See LICENSE file for license details. |
5 | */ | 4 | */ |
@@ -47,7 +46,6 @@ calcoffsets(void) { | |||
47 | 46 | ||
48 | if(!curr) | 47 | if(!curr) |
49 | return; | 48 | return; |
50 | |||
51 | w = cmdw + 2 * SPACE; | 49 | w = cmdw + 2 * SPACE; |
52 | for(next = curr; next; next=next->right) { | 50 | for(next = curr; next; next=next->right) { |
53 | tw = textw(next->text); | 51 | tw = textw(next->text); |
@@ -57,7 +55,6 @@ calcoffsets(void) { | |||
57 | if(w > mw) | 55 | if(w > mw) |
58 | break; | 56 | break; |
59 | } | 57 | } |
60 | |||
61 | w = cmdw + 2 * SPACE; | 58 | w = cmdw + 2 * SPACE; |
62 | for(prev = curr; prev && prev->left; prev=prev->left) { | 59 | for(prev = curr; prev && prev->left; prev=prev->left) { |
63 | tw = textw(prev->left->text); | 60 | tw = textw(prev->left->text); |
@@ -78,18 +75,15 @@ drawmenu(void) { | |||
78 | dc.w = mw; | 75 | dc.w = mw; |
79 | dc.h = mh; | 76 | dc.h = mh; |
80 | drawtext(NULL, dc.norm); | 77 | drawtext(NULL, dc.norm); |
81 | |||
82 | /* print command */ | 78 | /* print command */ |
83 | if(cmdw && item) | 79 | if(cmdw && item) |
84 | dc.w = cmdw; | 80 | dc.w = cmdw; |
85 | drawtext(text[0] ? text : NULL, dc.norm); | 81 | drawtext(text[0] ? text : NULL, dc.norm); |
86 | dc.x += cmdw; | 82 | dc.x += cmdw; |
87 | |||
88 | if(curr) { | 83 | if(curr) { |
89 | dc.w = SPACE; | 84 | dc.w = SPACE; |
90 | drawtext((curr && curr->left) ? "<" : NULL, dc.norm); | 85 | drawtext((curr && curr->left) ? "<" : NULL, dc.norm); |
91 | dc.x += dc.w; | 86 | dc.x += dc.w; |
92 | |||
93 | /* determine maximum items */ | 87 | /* determine maximum items */ |
94 | for(i = curr; i != next; i=i->right) { | 88 | for(i = curr; i != next; i=i->right) { |
95 | dc.w = textw(i->text); | 89 | dc.w = textw(i->text); |
@@ -98,7 +92,6 @@ drawmenu(void) { | |||
98 | drawtext(i->text, (sel == i) ? dc.sel : dc.norm); | 92 | drawtext(i->text, (sel == i) ? dc.sel : dc.norm); |
99 | dc.x += dc.w; | 93 | dc.x += dc.w; |
100 | } | 94 | } |
101 | |||
102 | dc.x = mw - SPACE; | 95 | dc.x = mw - SPACE; |
103 | dc.w = SPACE; | 96 | dc.w = SPACE; |
104 | drawtext(next ? ">" : NULL, dc.norm); | 97 | drawtext(next ? ">" : NULL, dc.norm); |
@@ -114,11 +107,9 @@ match(char *pattern) { | |||
114 | 107 | ||
115 | if(!pattern) | 108 | if(!pattern) |
116 | return; | 109 | return; |
117 | |||
118 | plen = strlen(pattern); | 110 | plen = strlen(pattern); |
119 | item = j = NULL; | 111 | item = j = NULL; |
120 | nitem = 0; | 112 | nitem = 0; |
121 | |||
122 | for(i = allitems; i; i=i->next) | 113 | for(i = allitems; i; i=i->next) |
123 | if(!plen || !strncmp(pattern, i->text, plen)) { | 114 | if(!plen || !strncmp(pattern, i->text, plen)) { |
124 | if(!j) | 115 | if(!j) |
@@ -142,7 +133,6 @@ match(char *pattern) { | |||
142 | j = i; | 133 | j = i; |
143 | nitem++; | 134 | nitem++; |
144 | } | 135 | } |
145 | |||
146 | curr = prev = next = sel = item; | 136 | curr = prev = next = sel = item; |
147 | calcoffsets(); | 137 | calcoffsets(); |
148 | } | 138 | } |
@@ -157,12 +147,10 @@ kpress(XKeyEvent * e) { | |||
157 | len = strlen(text); | 147 | len = strlen(text); |
158 | buf[0] = 0; | 148 | buf[0] = 0; |
159 | num = XLookupString(e, buf, sizeof(buf), &ksym, 0); | 149 | num = XLookupString(e, buf, sizeof(buf), &ksym, 0); |
160 | |||
161 | if(IsFunctionKey(ksym) || IsKeypadKey(ksym) | 150 | if(IsFunctionKey(ksym) || IsKeypadKey(ksym) |
162 | || IsMiscFunctionKey(ksym) || IsPFKey(ksym) | 151 | || IsMiscFunctionKey(ksym) || IsPFKey(ksym) |
163 | || IsPrivateKeypadKey(ksym)) | 152 | || IsPrivateKeypadKey(ksym)) |
164 | return; | 153 | return; |
165 | |||
166 | /* first check if a control mask is omitted */ | 154 | /* first check if a control mask is omitted */ |
167 | if(e->state & ControlMask) { | 155 | if(e->state & ControlMask) { |
168 | switch (ksym) { | 156 | switch (ksym) { |
@@ -261,7 +249,6 @@ readstdin(void) { | |||
261 | maxname = p; | 249 | maxname = p; |
262 | max = len; | 250 | max = len; |
263 | } | 251 | } |
264 | |||
265 | new = emalloc(sizeof(Item)); | 252 | new = emalloc(sizeof(Item)); |
266 | new->next = new->left = new->right = NULL; | 253 | new->next = new->left = new->right = NULL; |
267 | new->text = p; | 254 | new->text = p; |
@@ -318,7 +305,6 @@ main(int argc, char *argv[]) { | |||
318 | } | 305 | } |
319 | else | 306 | else |
320 | eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-t <seconds>] [-v]\n", stdout); | 307 | eprint("usage: dmenu [-font <name>] [-{norm,sel}{bg,fg} <color>] [-t <seconds>] [-v]\n", stdout); |
321 | |||
322 | dpy = XOpenDisplay(0); | 308 | dpy = XOpenDisplay(0); |
323 | if(!dpy) | 309 | if(!dpy) |
324 | eprint("dmenu: cannot open display\n"); | 310 | eprint("dmenu: cannot open display\n"); |
@@ -333,44 +319,37 @@ main(int argc, char *argv[]) { | |||
333 | while(XGrabKeyboard(dpy, root, True, GrabModeAsync, | 319 | while(XGrabKeyboard(dpy, root, True, GrabModeAsync, |
334 | GrabModeAsync, CurrentTime) != GrabSuccess) | 320 | GrabModeAsync, CurrentTime) != GrabSuccess) |
335 | usleep(1000); | 321 | usleep(1000); |
336 | |||
337 | FD_ZERO(&rd); | 322 | FD_ZERO(&rd); |
338 | FD_SET(STDIN_FILENO, &rd); | 323 | FD_SET(STDIN_FILENO, &rd); |
339 | if(select(ConnectionNumber(dpy) + 1, &rd, NULL, NULL, &timeout) < 1) | 324 | if(select(ConnectionNumber(dpy) + 1, &rd, NULL, NULL, &timeout) < 1) |
340 | goto UninitializedEnd; | 325 | goto UninitializedEnd; |
341 | maxname = readstdin(); | 326 | maxname = readstdin(); |
342 | |||
343 | /* style */ | 327 | /* style */ |
344 | dc.norm[ColBG] = getcolor(normbg); | 328 | dc.norm[ColBG] = getcolor(normbg); |
345 | dc.norm[ColFG] = getcolor(normfg); | 329 | dc.norm[ColFG] = getcolor(normfg); |
346 | dc.sel[ColBG] = getcolor(selbg); | 330 | dc.sel[ColBG] = getcolor(selbg); |
347 | dc.sel[ColFG] = getcolor(selfg); | 331 | dc.sel[ColFG] = getcolor(selfg); |
348 | setfont(font); | 332 | setfont(font); |
349 | 333 | /* menu window */ | |
350 | wa.override_redirect = 1; | 334 | wa.override_redirect = 1; |
351 | wa.background_pixmap = ParentRelative; | 335 | wa.background_pixmap = ParentRelative; |
352 | wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; | 336 | wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask; |
353 | |||
354 | mx = my = 0; | 337 | mx = my = 0; |
355 | mw = DisplayWidth(dpy, screen); | 338 | mw = DisplayWidth(dpy, screen); |
356 | mh = dc.font.height + 2; | 339 | mh = dc.font.height + 2; |
357 | |||
358 | win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, | 340 | win = XCreateWindow(dpy, root, mx, my, mw, mh, 0, |
359 | DefaultDepth(dpy, screen), CopyFromParent, | 341 | DefaultDepth(dpy, screen), CopyFromParent, |
360 | DefaultVisual(dpy, screen), | 342 | DefaultVisual(dpy, screen), |
361 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); | 343 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |
362 | XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); | 344 | XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_xterm)); |
363 | |||
364 | /* pixmap */ | 345 | /* pixmap */ |
365 | dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); | 346 | dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); |
366 | dc.gc = XCreateGC(dpy, root, 0, 0); | 347 | dc.gc = XCreateGC(dpy, root, 0, 0); |
367 | XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); | 348 | XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); |
368 | |||
369 | if(maxname) | 349 | if(maxname) |
370 | cmdw = textw(maxname); | 350 | cmdw = textw(maxname); |
371 | if(cmdw > mw / 3) | 351 | if(cmdw > mw / 3) |
372 | cmdw = mw / 3; | 352 | cmdw = mw / 3; |
373 | |||
374 | text[0] = 0; | 353 | text[0] = 0; |
375 | match(text); | 354 | match(text); |
376 | XMapRaised(dpy, win); | 355 | XMapRaised(dpy, win); |
@@ -392,6 +371,7 @@ main(int argc, char *argv[]) { | |||
392 | } | 371 | } |
393 | } | 372 | } |
394 | 373 | ||
374 | /* cleanup */ | ||
395 | while(allitems) { | 375 | while(allitems) { |
396 | itm = allitems->next; | 376 | itm = allitems->next; |
397 | free(allitems->text); | 377 | free(allitems->text); |
@@ -408,6 +388,5 @@ main(int argc, char *argv[]) { | |||
408 | UninitializedEnd: | 388 | UninitializedEnd: |
409 | XUngrabKeyboard(dpy, CurrentTime); | 389 | XUngrabKeyboard(dpy, CurrentTime); |
410 | XCloseDisplay(dpy); | 390 | XCloseDisplay(dpy); |
411 | |||
412 | return ret; | 391 | return ret; |
413 | } | 392 | } |
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
2 | * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||
3 | * See LICENSE file for license details. | 2 | * See LICENSE file for license details. |
4 | */ | 3 | */ |
5 | #include "dmenu.h" | 4 | #include "dmenu.h" |
@@ -22,6 +21,7 @@ badmalloc(unsigned int size) { | |||
22 | void * | 21 | void * |
23 | emalloc(unsigned int size) { | 22 | emalloc(unsigned int size) { |
24 | void *res = malloc(size); | 23 | void *res = malloc(size); |
24 | |||
25 | if(!res) | 25 | if(!res) |
26 | badmalloc(size); | 26 | badmalloc(size); |
27 | return res; | 27 | return res; |
@@ -40,6 +40,7 @@ eprint(const char *errstr, ...) { | |||
40 | char * | 40 | char * |
41 | estrdup(const char *str) { | 41 | estrdup(const char *str) { |
42 | void *res = strdup(str); | 42 | void *res = strdup(str); |
43 | |||
43 | if(!res) | 44 | if(!res) |
44 | badmalloc(strlen(str)); | 45 | badmalloc(strlen(str)); |
45 | return res; | 46 | return res; |