Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 498924 | Differences between
and this patch

Collapse All | Expand All

(-)a/config.mk (-2 / +6 lines)
Lines 12-20 X11LIB = /usr/X11R6/lib Link Here
12
XINERAMALIBS  = -lXinerama
12
XINERAMALIBS  = -lXinerama
13
XINERAMAFLAGS = -DXINERAMA
13
XINERAMAFLAGS = -DXINERAMA
14
14
15
# Xft, comment if you don't want it
16
XFTINC = $(shell pkg-config --cflags xft)
17
XFTLIBS = $(shell pkg-config --libs xft)
18
15
# includes and libs
19
# includes and libs
16
INCS = -I${X11INC}
20
INCS = -I${X11INC} ${XFTINC}
17
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS}
21
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS}
18
22
19
# flags
23
# flags
20
CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
24
CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
(-)a/dmenu.1 (-1 / +1 lines)
Lines 53-59 dmenu lists items vertically, with the given number of lines. Link Here
53
defines the prompt to be displayed to the left of the input field.
53
defines the prompt to be displayed to the left of the input field.
54
.TP
54
.TP
55
.BI \-fn " font"
55
.BI \-fn " font"
56
defines the font or font set used.
56
defines the font or font set used. eg. "fixed" or "Monospace-12:normal" (an xft font)
57
.TP
57
.TP
58
.BI \-nb " color"
58
.BI \-nb " color"
59
defines the normal background color.
59
defines the normal background color.
(-)a/dmenu.c (-15 / +30 lines)
Lines 17-22 Link Here
17
                             * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
17
                             * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
18
#define MIN(a,b)              ((a) < (b) ? (a) : (b))
18
#define MIN(a,b)              ((a) < (b) ? (a) : (b))
19
#define MAX(a,b)              ((a) > (b) ? (a) : (b))
19
#define MAX(a,b)              ((a) > (b) ? (a) : (b))
20
#define DEFFONT "fixed" /* xft example: "Monospace-11" */
20
21
21
typedef struct Item Item;
22
typedef struct Item Item;
22
struct Item {
23
struct Item {
Lines 26-31 struct Item { Link Here
26
27
27
static void appenditem(Item *item, Item **list, Item **last);
28
static void appenditem(Item *item, Item **list, Item **last);
28
static void calcoffsets(void);
29
static void calcoffsets(void);
30
static void cleanup(void);
29
static char *cistrstr(const char *s, const char *sub);
31
static char *cistrstr(const char *s, const char *sub);
30
static void drawmenu(void);
32
static void drawmenu(void);
31
static void grabkeyboard(void);
33
static void grabkeyboard(void);
Lines 50-59 static const char *normfgcolor = "#bbbbbb"; Link Here
50
static const char *selbgcolor  = "#005577";
52
static const char *selbgcolor  = "#005577";
51
static const char *selfgcolor  = "#eeeeee";
53
static const char *selfgcolor  = "#eeeeee";
52
static unsigned int lines = 0;
54
static unsigned int lines = 0;
53
static unsigned long normcol[ColLast];
55
static ColorSet *normcol;
54
static unsigned long selcol[ColLast];
56
static ColorSet *selcol;
55
static Atom clip, utf8;
57
static Atom clip, utf8;
56
static Bool topbar = True;
58
static Bool topbar = True;
59
static Bool running = True;
60
static int ret = 0;
57
static DC *dc;
61
static DC *dc;
58
static Item *items = NULL;
62
static Item *items = NULL;
59
static Item *matches, *matchend;
63
static Item *matches, *matchend;
Lines 104-110 main(int argc, char *argv[]) { Link Here
104
			usage();
108
			usage();
105
109
106
	dc = initdc();
110
	dc = initdc();
107
	initfont(dc, font);
111
	initfont(dc, font ? font : DEFFONT);
112
	normcol = initcolor(dc, normfgcolor, normbgcolor);
113
	selcol = initcolor(dc, selfgcolor, selbgcolor);
108
114
109
	if(fast) {
115
	if(fast) {
110
		grabkeyboard();
116
		grabkeyboard();
Lines 117-123 main(int argc, char *argv[]) { Link Here
117
	setup();
123
	setup();
118
	run();
124
	run();
119
125
120
	return 1; /* unreachable */
126
	cleanup();
127
	return ret;
121
}
128
}
122
129
123
void
130
void
Lines 160-165 cistrstr(const char *s, const char *sub) { Link Here
160
}
167
}
161
168
162
void
169
void
170
cleanup(void) {
171
    freecol(dc, normcol);
172
    freecol(dc, selcol);
173
    XDestroyWindow(dc->dpy, win);
174
    XUngrabKeyboard(dc->dpy, CurrentTime);
175
    freedc(dc);
176
}
177
178
void
163
drawmenu(void) {
179
drawmenu(void) {
164
	int curpos;
180
	int curpos;
165
	Item *item;
181
	Item *item;
Lines 167-173 drawmenu(void) { Link Here
167
	dc->x = 0;
183
	dc->x = 0;
168
	dc->y = 0;
184
	dc->y = 0;
169
	dc->h = bh;
185
	dc->h = bh;
170
	drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol));
186
	drawrect(dc, 0, 0, mw, mh, True, normcol->BG);
171
187
172
	if(prompt) {
188
	if(prompt) {
173
		dc->w = promptw;
189
		dc->w = promptw;
Lines 178-184 drawmenu(void) { Link Here
178
	dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
194
	dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
179
	drawtext(dc, text, normcol);
195
	drawtext(dc, text, normcol);
180
	if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w)
196
	if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w)
181
		drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol));
197
		drawrect(dc, curpos, 2, 1, dc->h - 4, True, normcol->FG);
182
198
183
	if(lines > 0) {
199
	if(lines > 0) {
184
		/* draw vertical list */
200
		/* draw vertical list */
Lines 321-327 keypress(XKeyEvent *ev) { Link Here
321
		sel = matchend;
337
		sel = matchend;
322
		break;
338
		break;
323
	case XK_Escape:
339
	case XK_Escape:
324
		exit(EXIT_FAILURE);
340
		ret = EXIT_FAILURE;
341
		running = False;
342
		break;
325
	case XK_Home:
343
	case XK_Home:
326
		if(sel == matches) {
344
		if(sel == matches) {
327
			cursor = 0;
345
			cursor = 0;
Lines 359-365 keypress(XKeyEvent *ev) { Link Here
359
	case XK_Return:
377
	case XK_Return:
360
	case XK_KP_Enter:
378
	case XK_KP_Enter:
361
		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
379
		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
362
		exit(EXIT_SUCCESS);
380
		ret = EXIT_SUCCESS;
381
		running = False;
382
		break;
363
	case XK_Right:
383
	case XK_Right:
364
		if(text[cursor] != '\0') {
384
		if(text[cursor] != '\0') {
365
			cursor = nextrune(+1);
385
			cursor = nextrune(+1);
Lines 490-496 void Link Here
490
run(void) {
510
run(void) {
491
	XEvent ev;
511
	XEvent ev;
492
512
493
	while(!XNextEvent(dc->dpy, &ev)) {
513
	while(running && !XNextEvent(dc->dpy, &ev)) {
494
		if(XFilterEvent(&ev, win))
514
		if(XFilterEvent(&ev, win))
495
			continue;
515
			continue;
496
		switch(ev.type) {
516
		switch(ev.type) {
Lines 524-534 setup(void) { Link Here
524
	XineramaScreenInfo *info;
544
	XineramaScreenInfo *info;
525
#endif
545
#endif
526
546
527
	normcol[ColBG] = getcolor(dc, normbgcolor);
528
	normcol[ColFG] = getcolor(dc, normfgcolor);
529
	selcol[ColBG]  = getcolor(dc, selbgcolor);
530
	selcol[ColFG]  = getcolor(dc, selfgcolor);
531
532
	clip = XInternAtom(dc->dpy, "CLIPBOARD",   False);
547
	clip = XInternAtom(dc->dpy, "CLIPBOARD",   False);
533
	utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False);
548
	utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False);
534
549
Lines 582-588 setup(void) { Link Here
582
597
583
	/* create menu window */
598
	/* create menu window */
584
	swa.override_redirect = True;
599
	swa.override_redirect = True;
585
	swa.background_pixel = normcol[ColBG];
600
	swa.background_pixel = normcol->BG;
586
	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
601
	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
587
	win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0,
602
	win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0,
588
	                    DefaultDepth(dc->dpy, screen), CopyFromParent,
603
	                    DefaultDepth(dc->dpy, screen), CopyFromParent,
(-)a/draw.c (-34 / +70 lines)
Lines 9-17 Link Here
9
9
10
#define MAX(a, b)  ((a) > (b) ? (a) : (b))
10
#define MAX(a, b)  ((a) > (b) ? (a) : (b))
11
#define MIN(a, b)  ((a) < (b) ? (a) : (b))
11
#define MIN(a, b)  ((a) < (b) ? (a) : (b))
12
#define DEFAULTFN  "fixed"
13
14
static Bool loadfont(DC *dc, const char *fontstr);
15
12
16
void
13
void
17
drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) {
14
drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) {
Lines 23-29 drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsign Link Here
23
}
20
}
24
21
25
void
22
void
26
drawtext(DC *dc, const char *text, unsigned long col[ColLast]) {
23
drawtext(DC *dc, const char *text, ColorSet *col) {
27
	char buf[BUFSIZ];
24
	char buf[BUFSIZ];
28
	size_t mn, n = strlen(text);
25
	size_t mn, n = strlen(text);
29
26
Lines 35-53 drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { Link Here
35
	if(mn < n)
32
	if(mn < n)
36
		for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');
33
		for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.');
37
34
38
	drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col));
35
	drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG);
39
	drawtextn(dc, buf, mn, col);
36
	drawtextn(dc, buf, mn, col);
40
}
37
}
41
38
42
void
39
void
43
drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) {
40
drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) {
44
	int x = dc->x + dc->font.height/2;
41
	int x = dc->x + dc->font.height/2;
45
	int y = dc->y + dc->font.ascent+1;
42
	int y = dc->y + dc->font.ascent+1;
46
43
47
	XSetForeground(dc->dpy, dc->gc, FG(dc, col));
44
	XSetForeground(dc->dpy, dc->gc, col->FG);
48
	if(dc->font.set)
45
	if(dc->font.xft_font) {
46
		if (!dc->xftdraw)
47
			eprintf("error, xft drawable does not exist");
48
		XftDrawStringUtf8(dc->xftdraw, &col->FG_xft,
49
			dc->font.xft_font, x, y, (unsigned char*)text, n);
50
	} else if(dc->font.set) {
49
		XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n);
51
		XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n);
50
	else {
52
	} else {
51
		XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid);
53
		XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid);
52
		XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n);
54
		XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n);
53
	}
55
	}
Lines 69-84 eprintf(const char *fmt, ...) { Link Here
69
}
71
}
70
72
71
void
73
void
74
freecol(DC *dc, ColorSet *col) {
75
    if(col) {
76
        if(&col->FG_xft)
77
            XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)),
78
                DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft);
79
        free(col); 
80
    }
81
}
82
83
void
72
freedc(DC *dc) {
84
freedc(DC *dc) {
85
    if(dc->font.xft_font) {
86
        XftFontClose(dc->dpy, dc->font.xft_font);
87
        XftDrawDestroy(dc->xftdraw);
88
    }
73
	if(dc->font.set)
89
	if(dc->font.set)
74
		XFreeFontSet(dc->dpy, dc->font.set);
90
		XFreeFontSet(dc->dpy, dc->font.set);
75
	if(dc->font.xfont)
91
    if(dc->font.xfont)
76
		XFreeFont(dc->dpy, dc->font.xfont);
92
		XFreeFont(dc->dpy, dc->font.xfont);
77
	if(dc->canvas)
93
    if(dc->canvas)
78
		XFreePixmap(dc->dpy, dc->canvas);
94
		XFreePixmap(dc->dpy, dc->canvas);
79
	XFreeGC(dc->dpy, dc->gc);
95
	if(dc->gc)
80
	XCloseDisplay(dc->dpy);
96
        XFreeGC(dc->dpy, dc->gc);
81
	free(dc);
97
	if(dc->dpy)
98
        XCloseDisplay(dc->dpy);
99
	if(dc)
100
        free(dc);
82
}
101
}
83
102
84
unsigned long
103
unsigned long
Lines 91-96 getcolor(DC *dc, const char *colstr) { Link Here
91
	return color.pixel;
110
	return color.pixel;
92
}
111
}
93
112
113
ColorSet *
114
initcolor(DC *dc, const char * foreground, const char * background) {
115
	ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet));
116
	if(!col)
117
		eprintf("error, cannot allocate memory for color set");
118
	col->BG = getcolor(dc, background);
119
	col->FG = getcolor(dc, foreground);
120
	if(dc->font.xft_font)
121
		if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)),
122
			DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft))
123
			eprintf("error, cannot allocate xft font color '%s'\n", foreground);
124
	return col;
125
}
126
94
DC *
127
DC *
95
initdc(void) {
128
initdc(void) {
96
	DC *dc;
129
	DC *dc;
Lines 109-131 initdc(void) { Link Here
109
142
110
void
143
void
111
initfont(DC *dc, const char *fontstr) {
144
initfont(DC *dc, const char *fontstr) {
112
	if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) {
113
		if(fontstr != NULL)
114
			fprintf(stderr, "cannot load font '%s'\n", fontstr);
115
		if(fontstr == NULL || !loadfont(dc, DEFAULTFN))
116
			eprintf("cannot load font '%s'\n", DEFAULTFN);
117
	}
118
	dc->font.height = dc->font.ascent + dc->font.descent;
119
}
120
121
Bool
122
loadfont(DC *dc, const char *fontstr) {
123
	char *def, **missing, **names;
145
	char *def, **missing, **names;
124
	int i, n;
146
	int i, n;
125
	XFontStruct **xfonts;
147
	XFontStruct **xfonts;
126
148
127
	if(!*fontstr)
149
	missing = NULL;
128
		return False;
129
	if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
150
	if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
130
		n = XFontsOfFontSet(dc->font.set, &xfonts, &names);
151
		n = XFontsOfFontSet(dc->font.set, &xfonts, &names);
131
		for(i = 0; i < n; i++) {
152
		for(i = 0; i < n; i++) {
Lines 133-147 loadfont(DC *dc, const char *fontstr) { Link Here
133
			dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent);
154
			dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent);
134
			dc->font.width   = MAX(dc->font.width,   xfonts[i]->max_bounds.width);
155
			dc->font.width   = MAX(dc->font.width,   xfonts[i]->max_bounds.width);
135
		}
156
		}
136
	}
157
    } else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
137
	else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
158
		dc->font.ascent = dc->font.xfont->ascent;
138
		dc->font.ascent  = dc->font.xfont->ascent;
139
		dc->font.descent = dc->font.xfont->descent;
159
		dc->font.descent = dc->font.xfont->descent;
140
		dc->font.width   = dc->font.xfont->max_bounds.width;
160
		dc->font.width   = dc->font.xfont->max_bounds.width;
161
	} else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) {
162
		dc->font.ascent = dc->font.xft_font->ascent;
163
		dc->font.descent = dc->font.xft_font->descent;
164
		dc->font.width = dc->font.xft_font->max_advance_width;
165
	} else {
166
		eprintf("cannot load font '%s'\n", fontstr);
141
	}
167
	}
142
	if(missing)
168
	if(missing)
143
		XFreeStringList(missing);
169
		XFreeStringList(missing);
144
	return dc->font.set || dc->font.xfont;
170
	dc->font.height = dc->font.ascent + dc->font.descent;
171
	return;
145
}
172
}
146
173
147
void
174
void
Lines 151-170 mapdc(DC *dc, Window win, unsigned int w, unsigned int h) { Link Here
151
178
152
void
179
void
153
resizedc(DC *dc, unsigned int w, unsigned int h) {
180
resizedc(DC *dc, unsigned int w, unsigned int h) {
181
	int screen = DefaultScreen(dc->dpy);
154
	if(dc->canvas)
182
	if(dc->canvas)
155
		XFreePixmap(dc->dpy, dc->canvas);
183
		XFreePixmap(dc->dpy, dc->canvas);
156
184
157
	dc->w = w;
185
	dc->w = w;
158
	dc->h = h;
186
	dc->h = h;
159
	dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h,
187
	dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h,
160
	                           DefaultDepth(dc->dpy, DefaultScreen(dc->dpy)));
188
	                           DefaultDepth(dc->dpy, screen));
189
	if(dc->font.xft_font && !(dc->xftdraw)) {
190
		dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen));
191
		if(!(dc->xftdraw))
192
			eprintf("error, cannot create xft drawable\n");
193
	}
161
}
194
}
162
195
163
int
196
int
164
textnw(DC *dc, const char *text, size_t len) {
197
textnw(DC *dc, const char *text, size_t len) {
165
	if(dc->font.set) {
198
	if(dc->font.xft_font) {
199
		XGlyphInfo gi;
200
		XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi);
201
		return gi.width;
202
	} else if(dc->font.set) {
166
		XRectangle r;
203
		XRectangle r;
167
168
		XmbTextExtents(dc->font.set, text, len, NULL, &r);
204
		XmbTextExtents(dc->font.set, text, len, NULL, &r);
169
		return r.width;
205
		return r.width;
170
	}
206
	}
(-)a/draw.h (-6 / +13 lines)
Lines 1-9 Link Here
1
/* See LICENSE file for copyright and license details. */
1
/* See LICENSE file for copyright and license details. */
2
2
3
#define FG(dc, col)  ((col)[(dc)->invert ? ColBG : ColFG])
3
#include <X11/Xft/Xft.h>
4
#define BG(dc, col)  ((col)[(dc)->invert ? ColFG : ColBG])
5
6
enum { ColBG, ColFG, ColBorder, ColLast };
7
4
8
typedef struct {
5
typedef struct {
9
	int x, y, w, h;
6
	int x, y, w, h;
Lines 11-16 typedef struct { Link Here
11
	Display *dpy;
8
	Display *dpy;
12
	GC gc;
9
	GC gc;
13
	Pixmap canvas;
10
	Pixmap canvas;
11
	XftDraw *xftdraw;
14
	struct {
12
	struct {
15
		int ascent;
13
		int ascent;
16
		int descent;
14
		int descent;
Lines 18-32 typedef struct { Link Here
18
		int width;
16
		int width;
19
		XFontSet set;
17
		XFontSet set;
20
		XFontStruct *xfont;
18
		XFontStruct *xfont;
19
		XftFont *xft_font;
21
	} font;
20
	} font;
22
} DC;  /* draw context */
21
} DC;  /* draw context */
23
22
23
typedef struct {
24
	unsigned long FG;
25
	XftColor FG_xft;
26
	unsigned long BG;
27
} ColorSet;
28
24
void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color);
29
void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color);
25
void drawtext(DC *dc, const char *text, unsigned long col[ColLast]);
30
void drawtext(DC *dc, const char *text, ColorSet *col);
26
void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]);
31
void drawtextn(DC *dc, const char *text, size_t n, ColorSet *col);
32
void freecol(DC *dc, ColorSet *col);
27
void eprintf(const char *fmt, ...);
33
void eprintf(const char *fmt, ...);
28
void freedc(DC *dc);
34
void freedc(DC *dc);
29
unsigned long getcolor(DC *dc, const char *colstr);
35
unsigned long getcolor(DC *dc, const char *colstr);
36
ColorSet *initcolor(DC *dc, const char *foreground, const char *background);
30
DC *initdc(void);
37
DC *initdc(void);
31
void initfont(DC *dc, const char *fontstr);
38
void initfont(DC *dc, const char *fontstr);
32
void mapdc(DC *dc, Window win, unsigned int w, unsigned int h);
39
void mapdc(DC *dc, Window win, unsigned int w, unsigned int h);

Return to bug 498924