aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE18
-rw-r--r--config.h4
-rw-r--r--config.mk4
-rw-r--r--dmenu.c130
4 files changed, 74 insertions, 82 deletions
diff --git a/LICENSE b/LICENSE
index 8e87c0f..8f13918 100644
--- a/LICENSE
+++ b/LICENSE
@@ -8,16 +8,16 @@ Permission is hereby granted, free of charge, to any person obtaining a
8copy of this software and associated documentation files (the "Software"), 8copy of this software and associated documentation files (the "Software"),
9to deal in the Software without restriction, including without limitation 9to deal in the Software without restriction, including without limitation
10the rights to use, copy, modify, merge, publish, distribute, sublicense, 10the rights to use, copy, modify, merge, publish, distribute, sublicense,
11and/or sell copies of the Software, and to permit persons to whom the 11and/or sell copies of the Software, and to permit persons to whom the
12Software is furnished to do so, subject to the following conditions: 12Software is furnished to do so, subject to the following conditions:
13 13
14The above copyright notice and this permission notice shall be included in 14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software. 15all copies or substantial portions of the Software.
16 16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23DEALINGS IN THE SOFTWARE. 23DEALINGS IN THE SOFTWARE.
diff --git a/config.h b/config.h
index 1afae6f..73cfe00 100644
--- a/config.h
+++ b/config.h
@@ -6,5 +6,5 @@
6#define NORMFGCOLOR "#000000" 6#define NORMFGCOLOR "#000000"
7#define SELBGCOLOR "#0066ff" 7#define SELBGCOLOR "#0066ff"
8#define SELFGCOLOR "#ffffff" 8#define SELFGCOLOR "#ffffff"
9/* next macro defines the space between menu items */ 9
10#define SPACE 30 /* px */ 10static uint spaceitem = 30; /* px between menu items */
diff --git a/config.mk b/config.mk
index c3ed11b..556086f 100644
--- a/config.mk
+++ b/config.mk
@@ -20,10 +20,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
20 20
21# flags 21# flags
22CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} 22CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
23CFLAGS = -Os ${INCS} ${CPPFLAGS} 23CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
24LDFLAGS = -s ${LIBS} 24LDFLAGS = -s ${LIBS}
25#CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
26#LDFLAGS = -g ${LIBS}
27 25
28# Solaris 26# Solaris
29#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" 27#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
diff --git a/dmenu.c b/dmenu.c
index 849746c..0f728c2 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -2,13 +2,14 @@
2#include <ctype.h> 2#include <ctype.h>
3#include <locale.h> 3#include <locale.h>
4#include <stdarg.h> 4#include <stdarg.h>
5#include <stdlib.h>
6#include <stdio.h> 5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h> 7#include <string.h>
8#include <strings.h>
8#include <unistd.h> 9#include <unistd.h>
10#include <X11/keysym.h>
9#include <X11/Xlib.h> 11#include <X11/Xlib.h>
10#include <X11/Xutil.h> 12#include <X11/Xutil.h>
11#include <X11/keysym.h>
12#ifdef XINERAMA 13#ifdef XINERAMA
13#include <X11/extensions/Xinerama.h> 14#include <X11/extensions/Xinerama.h>
14#endif 15#endif
@@ -45,55 +46,54 @@ struct Item {
45}; 46};
46 47
47/* forward declarations */ 48/* forward declarations */
48void appenditem(Item *i, Item **list, Item **last); 49static void appenditem(Item *i, Item **list, Item **last);
49void calcoffsets(void); 50static void calcoffsets(void);
50char *cistrstr(const char *s, const char *sub); 51static char *cistrstr(const char *s, const char *sub);
51void cleanup(void); 52static void cleanup(void);
52void drawmenu(void); 53static void drawmenu(void);
53void drawtext(const char *text, ulong col[ColLast]); 54static void drawtext(const char *text, ulong col[ColLast]);
54void *emalloc(uint size); 55static void *emalloc(uint size);
55void eprint(const char *errstr, ...); 56static void eprint(const char *errstr, ...);
56char *estrdup(const char *str); 57static ulong getcolor(const char *colstr);
57ulong getcolor(const char *colstr); 58static Bool grabkeyboard(void);
58Bool grabkeyboard(void); 59static void initfont(const char *fontstr);
59void initfont(const char *fontstr); 60static void kpress(XKeyEvent * e);
60void kpress(XKeyEvent * e); 61static void match(char *pattern);
61void match(char *pattern); 62static void readstdin(void);
62void readstdin(void); 63static void run(void);
63void run(void); 64static void setup(Bool topbar);
64void setup(Bool topbar); 65static int textnw(const char *text, uint len);
65uint textnw(const char *text, uint len); 66static int textw(const char *text);
66uint textw(const char *text);
67 67
68#include "config.h" 68#include "config.h"
69 69
70/* variables */ 70/* variables */
71char *font = FONT; 71static char *font = FONT;
72char *maxname = NULL; 72static char *maxname = NULL;
73char *normbg = NORMBGCOLOR; 73static char *normbg = NORMBGCOLOR;
74char *normfg = NORMFGCOLOR; 74static char *normfg = NORMFGCOLOR;
75char *prompt = NULL; 75static char *prompt = NULL;
76char *selbg = SELBGCOLOR; 76static char *selbg = SELBGCOLOR;
77char *selfg = SELFGCOLOR; 77static char *selfg = SELFGCOLOR;
78char text[4096]; 78static char text[4096];
79int screen; 79static int cmdw = 0;
80int ret = 0; 80static int promptw = 0;
81uint cmdw = 0; 81static int ret = 0;
82uint mw, mh; 82static int screen;
83uint promptw = 0; 83static uint mw, mh;
84uint numlockmask = 0; 84static uint numlockmask = 0;
85Bool running = True; 85static Bool running = True;
86Display *dpy; 86static Display *dpy;
87DC dc = {0}; 87static DC dc = {0};
88Item *allitems = NULL; /* first of all items */ 88static Item *allitems = NULL; /* first of all items */
89Item *item = NULL; /* first of pattern matching items */ 89static Item *item = NULL; /* first of pattern matching items */
90Item *sel = NULL; 90static Item *sel = NULL;
91Item *next = NULL; 91static Item *next = NULL;
92Item *prev = NULL; 92static Item *prev = NULL;
93Item *curr = NULL; 93static Item *curr = NULL;
94Window root, win; 94static Window root, win;
95int (*fstrncmp)(const char *, const char *, size_t n) = strncmp; 95static int (*fstrncmp)(const char *, const char *, size_t n) = strncmp;
96char *(*fstrstr)(const char *, const char *) = strstr; 96static char *(*fstrstr)(const char *, const char *) = strstr;
97 97
98void 98void
99appenditem(Item *i, Item **list, Item **last) { 99appenditem(Item *i, Item **list, Item **last) {
@@ -108,11 +108,12 @@ appenditem(Item *i, Item **list, Item **last) {
108 108
109void 109void
110calcoffsets(void) { 110calcoffsets(void) {
111 uint tw, w; 111 int tw;
112 uint w;
112 113
113 if(!curr) 114 if(!curr)
114 return; 115 return;
115 w = promptw + cmdw + 2 * SPACE; 116 w = promptw + cmdw + 2 * spaceitem;
116 for(next = curr; next; next=next->right) { 117 for(next = curr; next; next=next->right) {
117 tw = textw(next->text); 118 tw = textw(next->text);
118 if(tw > mw / 3) 119 if(tw > mw / 3)
@@ -121,7 +122,7 @@ calcoffsets(void) {
121 if(w > mw) 122 if(w > mw)
122 break; 123 break;
123 } 124 }
124 w = promptw + cmdw + 2 * SPACE; 125 w = promptw + cmdw + 2 * spaceitem;
125 for(prev = curr; prev && prev->left; prev=prev->left) { 126 for(prev = curr; prev && prev->left; prev=prev->left) {
126 tw = textw(prev->left->text); 127 tw = textw(prev->left->text);
127 if(tw > mw / 3) 128 if(tw > mw / 3)
@@ -197,7 +198,7 @@ drawmenu(void) {
197 drawtext(text[0] ? text : NULL, dc.norm); 198 drawtext(text[0] ? text : NULL, dc.norm);
198 dc.x += cmdw; 199 dc.x += cmdw;
199 if(curr) { 200 if(curr) {
200 dc.w = SPACE; 201 dc.w = spaceitem;
201 drawtext((curr && curr->left) ? "<" : NULL, dc.norm); 202 drawtext((curr && curr->left) ? "<" : NULL, dc.norm);
202 dc.x += dc.w; 203 dc.x += dc.w;
203 /* determine maximum items */ 204 /* determine maximum items */
@@ -208,8 +209,8 @@ drawmenu(void) {
208 drawtext(i->text, (sel == i) ? dc.sel : dc.norm); 209 drawtext(i->text, (sel == i) ? dc.sel : dc.norm);
209 dc.x += dc.w; 210 dc.x += dc.w;
210 } 211 }
211 dc.x = mw - SPACE; 212 dc.x = mw - spaceitem;
212 dc.w = SPACE; 213 dc.w = spaceitem;
213 drawtext(next ? ">" : NULL, dc.norm); 214 drawtext(next ? ">" : NULL, dc.norm);
214 } 215 }
215 XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); 216 XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0);
@@ -275,15 +276,6 @@ eprint(const char *errstr, ...) {
275 exit(EXIT_FAILURE); 276 exit(EXIT_FAILURE);
276} 277}
277 278
278char *
279estrdup(const char *str) {
280 void *res = strdup(str);
281
282 if(!res)
283 eprint("fatal: could not malloc() %u bytes\n", strlen(str));
284 return res;
285}
286
287ulong 279ulong
288getcolor(const char *colstr) { 280getcolor(const char *colstr) {
289 Colormap cmap = DefaultColormap(dpy, screen); 281 Colormap cmap = DefaultColormap(dpy, screen);
@@ -358,14 +350,15 @@ kpress(XKeyEvent * e) {
358 len = strlen(text); 350 len = strlen(text);
359 buf[0] = 0; 351 buf[0] = 0;
360 num = XLookupString(e, buf, sizeof buf, &ksym, 0); 352 num = XLookupString(e, buf, sizeof buf, &ksym, 0);
361 if(IsKeypadKey(ksym)) 353 if(IsKeypadKey(ksym)) {
362 if(ksym == XK_KP_Enter) 354 if(ksym == XK_KP_Enter)
363 ksym = XK_Return; 355 ksym = XK_Return;
364 else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) 356 else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
365 ksym = (ksym - XK_KP_0) + XK_0; 357 ksym = (ksym - XK_KP_0) + XK_0;
358 }
366 if(IsFunctionKey(ksym) || IsKeypadKey(ksym) 359 if(IsFunctionKey(ksym) || IsKeypadKey(ksym)
367 || IsMiscFunctionKey(ksym) || IsPFKey(ksym) 360 || IsMiscFunctionKey(ksym) || IsPFKey(ksym)
368 || IsPrivateKeypadKey(ksym)) 361 || IsPrivateKeypadKey(ksym))
369 return; 362 return;
370 /* first check if a control mask is omitted */ 363 /* first check if a control mask is omitted */
371 if(e->state & ControlMask) { 364 if(e->state & ControlMask) {
@@ -569,7 +562,8 @@ readstdin(void) {
569 len = strlen(buf); 562 len = strlen(buf);
570 if (buf[len - 1] == '\n') 563 if (buf[len - 1] == '\n')
571 buf[len - 1] = 0; 564 buf[len - 1] = 0;
572 p = estrdup(buf); 565 if(!(p = strdup(buf)))
566 eprint("fatal: could not strdup() %u bytes\n", strlen(buf));
573 if(max < len) { 567 if(max < len) {
574 maxname = p; 568 maxname = p;
575 max = len; 569 max = len;
@@ -677,7 +671,7 @@ setup(Bool topbar) {
677 XMapRaised(dpy, win); 671 XMapRaised(dpy, win);
678} 672}
679 673
680uint 674int
681textnw(const char *text, uint len) { 675textnw(const char *text, uint len) {
682 XRectangle r; 676 XRectangle r;
683 677
@@ -688,7 +682,7 @@ textnw(const char *text, uint len) {
688 return XTextWidth(dc.font.xfont, text, len); 682 return XTextWidth(dc.font.xfont, text, len);
689} 683}
690 684
691uint 685int
692textw(const char *text) { 686textw(const char *text) {
693 return textnw(text, strlen(text)) + dc.font.height; 687 return textnw(text, strlen(text)) + dc.font.height;
694} 688}