incorporating Xft instead of cairo, cairo provides far too many options fd3c19bd
anselm@garbe.us · 2012-11-02 12:17 3 file(s) · +38 −68
config.def.h +1 −1
1 1
/* See LICENSE file for copyright and license details. */
2 2
3 3
/* appearance */
4 -
static const char font[]            = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
4 +
static const char font[]            = "Liberation Mono:pixelsize=12:antialias=false:autohint=false";
5 5
static const char normbordercolor[] = "#444444";
6 6
static const char normbgcolor[]     = "#222222";
7 7
static const char normfgcolor[]     = "#bbbbbb";
config.mk +2 −2
15 15
XINERAMAFLAGS = -DXINERAMA
16 16
17 17
# includes and libs
18 -
INCS = -I${X11INC}
19 -
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS}
18 +
INCS = -I${X11INC} -I/usr/include/freetype2
19 +
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} -lutil -lXext -lXft -lfontconfig
20 20
21 21
# flags
22 22
CPPFLAGS = -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
dwm.c +35 −65
37 37
#include <X11/Xproto.h>
38 38
#include <X11/Xutil.h>
39 39
#include <X11/XKBlib.h>
40 +
#include <fontconfig/fontconfig.h>
41 +
#include <X11/Xft/Xft.h>
40 42
#ifdef XINERAMA
41 43
#include <X11/extensions/Xinerama.h>
42 44
#endif /* XINERAMA */
100 102
101 103
typedef struct {
102 104
	int x, y, w, h;
103 -
	unsigned long norm[ColLast];
104 -
	unsigned long sel[ColLast];
105 +
	XftColor norm[ColLast];
106 +
	XftColor sel[ColLast];
105 107
	Drawable drawable;
106 108
	GC gc;
107 109
	struct {
108 110
		int ascent;
109 111
		int descent;
110 112
		int height;
111 -
		XFontSet set;
112 -
		XFontStruct *xfont;
113 +
		XftFont *xfont;
113 114
	} font;
114 115
} DC; /* draw context */
115 116
179 180
static Monitor *dirtomon(int dir);
180 181
static void drawbar(Monitor *m);
181 182
static void drawbars(void);
182 -
static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
183 -
static void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
183 +
static void drawsquare(Bool filled, Bool empty, Bool invert, XftColor col[ColLast]);
184 +
static void drawtext(const char *text, XftColor col[ColLast], Bool invert);
184 185
static void enternotify(XEvent *e);
185 186
static void expose(XEvent *e);
186 187
static void focus(Client *c);
187 188
static void focusin(XEvent *e);
188 189
static void focusmon(const Arg *arg);
189 190
static void focusstack(const Arg *arg);
190 -
static unsigned long getcolor(const char *colstr);
191 +
static XftColor getcolor(const char *colstr);
191 192
static Bool getrootptr(int *x, int *y);
192 193
static long getstate(Window w);
193 194
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
487 488
	for(m = mons; m; m = m->next)
488 489
		while(m->stack)
489 490
			unmanage(m->stack, False);
490 -
	if(dc.font.set)
491 -
		XFreeFontSet(dpy, dc.font.set);
492 -
	else
493 -
		XFreeFont(dpy, dc.font.xfont);
494 491
	XUngrabKey(dpy, AnyKey, AnyModifier, root);
495 492
	XFreePixmap(dpy, dc.drawable);
496 493
	XFreeGC(dpy, dc.gc);
723 720
drawbar(Monitor *m) {
724 721
	int x;
725 722
	unsigned int i, occ = 0, urg = 0;
726 -
	unsigned long *col;
723 +
	XftColor *col;
727 724
	Client *c;
728 725
729 726
	for(c = m->clients; c; c = c->next) {
778 775
}
779 776
780 777
void
781 -
drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
778 +
drawsquare(Bool filled, Bool empty, Bool invert, XftColor col[ColLast]) {
782 779
	int x;
783 780
784 -
	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
781 +
	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG].pixel);
785 782
	x = (dc.font.ascent + dc.font.descent + 2) / 4;
786 783
	if(filled)
787 784
		XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1);
790 787
}
791 788
792 789
void
793 -
drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
790 +
drawtext(const char *text, XftColor col[ColLast], Bool invert) {
794 791
	char buf[256];
795 792
	int i, x, y, h, len, olen;
793 +
	XftDraw *d;
796 794
797 -
	XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]);
795 +
	XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG].pixel);
798 796
	XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
799 797
	if(!text)
800 798
		return;
809 807
	memcpy(buf, text, len);
810 808
	if(len < olen)
811 809
		for(i = len; i && i > len - 3; buf[--i] = '.');
812 -
	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
813 -
	if(dc.font.set)
814 -
		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
815 -
	else
816 -
		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
810 +
811 +
	d = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy, screen), DefaultColormap(dpy,screen));
812 +
813 +
	XftDrawStringUtf8(d, &col[invert ? ColBG : ColFG], dc.font.xfont, x, y, (XftChar8 *) buf, len);
814 +
	XftDrawDestroy(d);
817 815
}
818 816
819 817
void
859 857
		detachstack(c);
860 858
		attachstack(c);
861 859
		grabbuttons(c, True);
862 -
		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
860 +
		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder].pixel);
863 861
		setfocus(c);
864 862
	}
865 863
	else {
933 931
	return atom;
934 932
}
935 933
936 -
unsigned long
934 +
XftColor 
937 935
getcolor(const char *colstr) {
938 -
	Colormap cmap = DefaultColormap(dpy, screen);
939 -
	XColor color;
936 +
	XftColor color;
940 937
941 -
	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
938 +
	if(!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), colstr, &color))
942 939
		die("error, cannot allocate color '%s'\n", colstr);
943 -
	return color.pixel;
940 +
941 +
	return color;
944 942
}
945 943
946 944
Bool
1041 1039
1042 1040
void
1043 1041
initfont(const char *fontstr) {
1044 -
	char *def, **missing;
1045 -
	int n;
1046 1042
1047 -
	dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
1048 -
	if(missing) {
1049 -
		while(n--)
1050 -
			fprintf(stderr, "dwm: missing fontset: %s\n", missing[n]);
1051 -
		XFreeStringList(missing);
1052 -
	}
1053 -
	if(dc.font.set) {
1054 -
		XFontStruct **xfonts;
1055 -
		char **font_names;
1043 +
	if(!(dc.font.xfont = XftFontOpenName(dpy,screen,fontstr))
1044 +
	&& !(dc.font.xfont = XftFontOpenName(dpy,screen,"fixed")))
1045 +
		die("error, cannot load font: '%s'\n", fontstr);
1056 1046
1057 -
		dc.font.ascent = dc.font.descent = 0;
1058 -
		XExtentsOfFontSet(dc.font.set);
1059 -
		n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
1060 -
		while(n--) {
1061 -
			dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent);
1062 -
			dc.font.descent = MAX(dc.font.descent,(*xfonts)->descent);
1063 -
			xfonts++;
1064 -
		}
1065 -
	}
1066 -
	else {
1067 -
		if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))
1068 -
		&& !(dc.font.xfont = XLoadQueryFont(dpy, "fixed")))
1069 -
			die("error, cannot load font: '%s'\n", fontstr);
1070 -
		dc.font.ascent = dc.font.xfont->ascent;
1071 -
		dc.font.descent = dc.font.xfont->descent;
1072 -
	}
1047 +
	dc.font.ascent = dc.font.xfont->ascent;
1048 +
	dc.font.descent = dc.font.xfont->descent;
1073 1049
	dc.font.height = dc.font.ascent + dc.font.descent;
1074 1050
}
1075 1051
1151 1127
1152 1128
	wc.border_width = c->bw;
1153 1129
	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
1154 -
	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
1130 +
	XSetWindowBorder(dpy, w, dc.norm[ColBorder].pixel);
1155 1131
	configure(c); /* propagates border_width, if size doesn't change */
1156 1132
	updatewindowtype(c);
1157 1133
	updatesizehints(c);
1640 1616
	dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen));
1641 1617
	dc.gc = XCreateGC(dpy, root, 0, NULL);
1642 1618
	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
1643 -
	if(!dc.font.set)
1644 -
		XSetFont(dpy, dc.gc, dc.font.xfont->fid);
1645 1619
	/* init bars */
1646 1620
	updatebars();
1647 1621
	updatestatus();
1712 1686
1713 1687
int
1714 1688
textnw(const char *text, unsigned int len) {
1715 -
	XRectangle r;
1716 -
1717 -
	if(dc.font.set) {
1718 -
		XmbTextExtents(dc.font.set, text, len, NULL, &r);
1719 -
		return r.width;
1720 -
	}
1721 -
	return XTextWidth(dc.font.xfont, text, len);
1689 +
	XGlyphInfo ext;
1690 +
	XftTextExtentsUtf8(dpy, dc.font.xfont, (XftChar8 *) text, len, &ext);
1691 +
	return ext.xOff;
1722 1692
}
1723 1693
1724 1694
void
1798 1768
	if(!c)
1799 1769
		return;
1800 1770
	grabbuttons(c, False);
1801 -
	XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
1771 +
	XSetWindowBorder(dpy, c->win, dc.norm[ColBorder].pixel);
1802 1772
	if(setfocus) {
1803 1773
		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
1804 1774
		XDeleteProperty(dpy, root, netatom[NetActiveWindow]);