Difference between revisions of "Dmenu-4.0-xft.diff"
From HaskellWiki
Tomjaguarpaw (talk | contribs) (Deleting page that hasn't been edited for over 10 years) |
m (Reverted edits by Tomjaguarpaw (talk) to last revision by Jsyjr) |
||
Line 1: | Line 1: | ||
− | + | <pre> | |
+ | diff -r cdaa1062e534 config.h | ||
+ | --- a/config.h Fri May 22 06:02:00 2009 -0400 | ||
+ | +++ b/config.h Wed May 27 20:39:52 2009 -0400 | ||
+ | @@ -5,5 +5,4 @@ | ||
+ | static const char *normbgcolor = "#cccccc"; | ||
+ | static const char *normfgcolor = "#000000"; | ||
+ | static const char *selbgcolor = "#0066ff"; | ||
+ | -static const char *selfgcolor = "#ffffff"; | ||
+ | static unsigned int spaceitem = 30; /* px between menu items */ | ||
+ | diff -r cdaa1062e534 config.mk | ||
+ | --- a/config.mk Fri May 22 06:02:00 2009 -0400 | ||
+ | +++ b/config.mk Wed May 27 20:39:52 2009 -0400 | ||
+ | @@ -14,12 +14,17 @@ | ||
+ | XINERAMALIBS = -L${X11LIB} -lXinerama | ||
+ | XINERAMAFLAGS = -DXINERAMA | ||
+ | |||
+ | +# Xft, comment if you don't want it | ||
+ | +XFTINCS = `pkg-config --cflags xft` | ||
+ | +XFTLIBS = `pkg-config --libs xft` | ||
+ | +XFTFLAGS = -DXFT | ||
+ | + | ||
+ | # includes and libs | ||
+ | -INCS = -I. -I/usr/include -I${X11INC} | ||
+ | -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} | ||
+ | +INCS = -I. -I/usr/include -I${X11INC} ${XFTINCS} | ||
+ | +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} | ||
+ | |||
+ | # flags | ||
+ | -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} | ||
+ | +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${XFTFLAGS} | ||
+ | CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} | ||
+ | LDFLAGS = -s ${LIBS} | ||
+ | |||
+ | diff -r cdaa1062e534 dmenu.c | ||
+ | --- a/dmenu.c Fri May 22 06:02:00 2009 -0400 | ||
+ | +++ b/dmenu.c Wed May 27 20:39:52 2009 -0400 | ||
+ | @@ -10,6 +10,9 @@ | ||
+ | #include <X11/keysym.h> | ||
+ | #include <X11/Xlib.h> | ||
+ | #include <X11/Xutil.h> | ||
+ | +#ifdef XFT | ||
+ | +#include <X11/Xft/Xft.h> | ||
+ | +#endif | ||
+ | #ifdef XINERAMA | ||
+ | #include <X11/extensions/Xinerama.h> | ||
+ | #endif | ||
+ | @@ -28,6 +31,11 @@ | ||
+ | unsigned long norm[ColLast]; | ||
+ | unsigned long sel[ColLast]; | ||
+ | Drawable drawable; | ||
+ | +#ifdef XFT | ||
+ | + XftColor xftnorm[ColLast]; | ||
+ | + XftColor xftsel[ColLast]; | ||
+ | + XftDraw *xftdrawable; | ||
+ | +#endif | ||
+ | GC gc; | ||
+ | struct { | ||
+ | XFontStruct *xfont; | ||
+ | @@ -35,6 +43,10 @@ | ||
+ | int ascent; | ||
+ | int descent; | ||
+ | int height; | ||
+ | +#ifdef XFT | ||
+ | + XftFont *xftfont; | ||
+ | + XGlyphInfo *extents; | ||
+ | +#endif | ||
+ | } font; | ||
+ | } DC; /* draw context */ | ||
+ | |||
+ | @@ -54,6 +66,9 @@ | ||
+ | static void drawtext(const char *text, unsigned long col[ColLast]); | ||
+ | static void eprint(const char *errstr, ...); | ||
+ | static unsigned long getcolor(const char *colstr); | ||
+ | +#ifdef XFT | ||
+ | +static unsigned long getxftcolor(const char *colstr, XftColor *color); | ||
+ | +#endif | ||
+ | static Bool grabkeyboard(void); | ||
+ | static void initfont(const char *fontstr); | ||
+ | static void kpress(XKeyEvent * e); | ||
+ | @@ -74,7 +89,7 @@ | ||
+ | static int promptw = 0; | ||
+ | static int ret = 0; | ||
+ | static int screen; | ||
+ | -static unsigned int mw, mh; | ||
+ | +static unsigned int mw, mh, bh; | ||
+ | static unsigned int numlockmask = 0; | ||
+ | static Bool running = True; | ||
+ | static Display *dpy; | ||
+ | @@ -160,10 +175,12 @@ | ||
+ | free(allitems); | ||
+ | allitems = itm; | ||
+ | } | ||
+ | - if(dc.font.set) | ||
+ | - XFreeFontSet(dpy, dc.font.set); | ||
+ | - else | ||
+ | - XFreeFont(dpy, dc.font.xfont); | ||
+ | + if(!dc.font.xftfont) { | ||
+ | + if(dc.font.set) | ||
+ | + XFreeFontSet(dpy, dc.font.set); | ||
+ | + else | ||
+ | + XFreeFont(dpy, dc.font.xfont); | ||
+ | + } | ||
+ | XFreePixmap(dpy, dc.drawable); | ||
+ | XFreeGC(dpy, dc.gc); | ||
+ | XDestroyWindow(dpy, win); | ||
+ | @@ -232,11 +249,19 @@ | ||
+ | memcpy(buf, text, len); | ||
+ | if(len < olen) | ||
+ | for(i = len; i && i > len - 3; buf[--i] = '.'); | ||
+ | +#ifdef XFT | ||
+ | + if(dc.font.xftfont) | ||
+ | + XftDrawStringUtf8(dc.xftdrawable, &dc.xftnorm[ColFG], dc.font.xftfont, x, y, (unsigned char*) buf, len); | ||
+ | + else { | ||
+ | +#endif | ||
+ | XSetForeground(dpy, dc.gc, col[ColFG]); | ||
+ | if(dc.font.set) | ||
+ | XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); | ||
+ | else | ||
+ | XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); | ||
+ | +#ifdef XFT | ||
+ | + } | ||
+ | +#endif | ||
+ | } | ||
+ | |||
+ | void | ||
+ | @@ -259,6 +284,18 @@ | ||
+ | return color.pixel; | ||
+ | } | ||
+ | |||
+ | +#ifdef XFT | ||
+ | +unsigned long | ||
+ | +getxftcolor(const char *colstr, XftColor *color) { | ||
+ | + Colormap cmap = DefaultColormap(dpy, screen); | ||
+ | + Visual *vis = DefaultVisual(dpy, screen); | ||
+ | + | ||
+ | + if(!XftColorAllocName(dpy, vis, cmap, colstr, color)) | ||
+ | + eprint("error, cannot allocate color '%s'\n", colstr); | ||
+ | + return color->pixel; | ||
+ | +} | ||
+ | +#endif | ||
+ | + | ||
+ | Bool | ||
+ | grabkeyboard(void) { | ||
+ | unsigned int len; | ||
+ | @@ -274,6 +311,22 @@ | ||
+ | |||
+ | void | ||
+ | initfont(const char *fontstr) { | ||
+ | +#ifdef XFT | ||
+ | + dc.font.xftfont = 0; | ||
+ | + if(cistrstr(fontstr,"xft:")) { | ||
+ | + dc.font.xftfont = XftFontOpenXlfd(dpy, screen, fontstr+4); | ||
+ | + if(!dc.font.xftfont) | ||
+ | + dc.font.xftfont = XftFontOpenName(dpy, screen, fontstr+4); | ||
+ | + if(!dc.font.xftfont) | ||
+ | + eprint("error, cannot load font: '%s'\n", fontstr+4); | ||
+ | + dc.font.extents = malloc(sizeof(XGlyphInfo)); | ||
+ | + XftTextExtentsUtf8(dpy, dc.font.xftfont, (unsigned const char *) fontstr+4, strlen(fontstr+4), dc.font.extents); | ||
+ | + dc.font.height = dc.font.xftfont->ascent + dc.font.xftfont->descent; | ||
+ | + dc.font.ascent = dc.font.xftfont->ascent; | ||
+ | + dc.font.descent = dc.font.xftfont->descent; | ||
+ | + } | ||
+ | + else { | ||
+ | +#endif | ||
+ | char *def, **missing; | ||
+ | int i, n; | ||
+ | |||
+ | @@ -306,6 +359,9 @@ | ||
+ | dc.font.descent = dc.font.xfont->descent; | ||
+ | } | ||
+ | dc.font.height = dc.font.ascent + dc.font.descent; | ||
+ | +#ifdef XFT | ||
+ | + } | ||
+ | +#endif | ||
+ | } | ||
+ | |||
+ | void | ||
+ | @@ -585,11 +641,21 @@ | ||
+ | XFreeModifiermap(modmap); | ||
+ | |||
+ | /* style */ | ||
+ | + initfont(font); | ||
+ | +#ifdef XFT | ||
+ | + if(dc.font.xftfont) { | ||
+ | + dc.norm[ColBG] = getxftcolor(normbgcolor, &dc.xftnorm[ColBG]); | ||
+ | + dc.norm[ColFG] = getxftcolor(normfgcolor, &dc.xftnorm[ColFG]); | ||
+ | + dc.sel[ColBG] = getxftcolor(selbgcolor, &dc.xftsel[ColBG]); | ||
+ | + } | ||
+ | + else { | ||
+ | +#endif | ||
+ | dc.norm[ColBG] = getcolor(normbgcolor); | ||
+ | dc.norm[ColFG] = getcolor(normfgcolor); | ||
+ | dc.sel[ColBG] = getcolor(selbgcolor); | ||
+ | - dc.sel[ColFG] = getcolor(selfgcolor); | ||
+ | - initfont(font); | ||
+ | +#ifdef XFT | ||
+ | + } | ||
+ | +#endif | ||
+ | |||
+ | /* menu window */ | ||
+ | wa.override_redirect = True; | ||
+ | @@ -598,6 +664,8 @@ | ||
+ | |||
+ | /* menu window geometry */ | ||
+ | mh = dc.font.height + 2; | ||
+ | + if(mh < bh) | ||
+ | + mh = bh; | ||
+ | #if XINERAMA | ||
+ | if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { | ||
+ | i = 0; | ||
+ | @@ -632,8 +700,19 @@ | ||
+ | dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); | ||
+ | dc.gc = XCreateGC(dpy, root, 0, NULL); | ||
+ | XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); | ||
+ | +#ifdef XFT | ||
+ | + if(dc.font.xftfont) { | ||
+ | + dc.xftdrawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen)); | ||
+ | + if(!dc.xftdrawable) | ||
+ | + eprint("error, cannot create drawable\n"); | ||
+ | + } | ||
+ | + else { | ||
+ | +#endif | ||
+ | if(!dc.font.set) | ||
+ | XSetFont(dpy, dc.gc, dc.font.xfont->fid); | ||
+ | +#ifdef XFT | ||
+ | + } | ||
+ | +#endif | ||
+ | if(maxname) | ||
+ | cmdw = textw(maxname); | ||
+ | if(cmdw > mw / 3) | ||
+ | @@ -649,6 +728,15 @@ | ||
+ | |||
+ | int | ||
+ | textnw(const char *text, unsigned int len) { | ||
+ | +#ifdef XFT | ||
+ | + if (dc.font.xftfont) { | ||
+ | + XftTextExtentsUtf8(dpy, dc.font.xftfont, (unsigned const char *) text, strlen(text), dc.font.extents); | ||
+ | + if(dc.font.extents->height > dc.font.height) | ||
+ | + dc.font.height = dc.font.extents->height; | ||
+ | + return dc.font.extents->xOff; | ||
+ | + } | ||
+ | + else { | ||
+ | +#endif | ||
+ | XRectangle r; | ||
+ | |||
+ | if(dc.font.set) { | ||
+ | @@ -656,6 +744,9 @@ | ||
+ | return r.width; | ||
+ | } | ||
+ | return XTextWidth(dc.font.xfont, text, len); | ||
+ | +#ifdef XFT | ||
+ | + } | ||
+ | +#endif | ||
+ | } | ||
+ | |||
+ | int | ||
+ | @@ -691,14 +782,14 @@ | ||
+ | else if(!strcmp(argv[i], "-sb")) { | ||
+ | if(++i < argc) selbgcolor = argv[i]; | ||
+ | } | ||
+ | - else if(!strcmp(argv[i], "-sf")) { | ||
+ | - if(++i < argc) selfgcolor = argv[i]; | ||
+ | + else if(!strcmp(argv[i], "-bh")) { | ||
+ | + if(++i < argc) bh = atoi(argv[i]); | ||
+ | } | ||
+ | else if(!strcmp(argv[i], "-v")) | ||
+ | eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); | ||
+ | else | ||
+ | eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" | ||
+ | - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); | ||
+ | + " [-sb <color>] [-bh <height>] [-p <prompt>] [-v]\n"); | ||
+ | if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) | ||
+ | fprintf(stderr, "warning: no locale support\n"); | ||
+ | if(!(dpy = XOpenDisplay(NULL))) | ||
+ | </pre> |
Latest revision as of 15:19, 6 February 2021
diff -r cdaa1062e534 config.h --- a/config.h Fri May 22 06:02:00 2009 -0400 +++ b/config.h Wed May 27 20:39:52 2009 -0400 @@ -5,5 +5,4 @@ static const char *normbgcolor = "#cccccc"; static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; -static const char *selfgcolor = "#ffffff"; static unsigned int spaceitem = 30; /* px between menu items */ diff -r cdaa1062e534 config.mk --- a/config.mk Fri May 22 06:02:00 2009 -0400 +++ b/config.mk Wed May 27 20:39:52 2009 -0400 @@ -14,12 +14,17 @@ XINERAMALIBS = -L${X11LIB} -lXinerama XINERAMAFLAGS = -DXINERAMA +# Xft, comment if you don't want it +XFTINCS = `pkg-config --cflags xft` +XFTLIBS = `pkg-config --libs xft` +XFTFLAGS = -DXFT + # includes and libs -INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} +INCS = -I. -I/usr/include -I${X11INC} ${XFTINCS} +LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} ${XFTLIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${XFTFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} diff -r cdaa1062e534 dmenu.c --- a/dmenu.c Fri May 22 06:02:00 2009 -0400 +++ b/dmenu.c Wed May 27 20:39:52 2009 -0400 @@ -10,6 +10,9 @@ #include <X11/keysym.h> #include <X11/Xlib.h> #include <X11/Xutil.h> +#ifdef XFT +#include <X11/Xft/Xft.h> +#endif #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif @@ -28,6 +31,11 @@ unsigned long norm[ColLast]; unsigned long sel[ColLast]; Drawable drawable; +#ifdef XFT + XftColor xftnorm[ColLast]; + XftColor xftsel[ColLast]; + XftDraw *xftdrawable; +#endif GC gc; struct { XFontStruct *xfont; @@ -35,6 +43,10 @@ int ascent; int descent; int height; +#ifdef XFT + XftFont *xftfont; + XGlyphInfo *extents; +#endif } font; } DC; /* draw context */ @@ -54,6 +66,9 @@ static void drawtext(const char *text, unsigned long col[ColLast]); static void eprint(const char *errstr, ...); static unsigned long getcolor(const char *colstr); +#ifdef XFT +static unsigned long getxftcolor(const char *colstr, XftColor *color); +#endif static Bool grabkeyboard(void); static void initfont(const char *fontstr); static void kpress(XKeyEvent * e); @@ -74,7 +89,7 @@ static int promptw = 0; static int ret = 0; static int screen; -static unsigned int mw, mh; +static unsigned int mw, mh, bh; static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; @@ -160,10 +175,12 @@ free(allitems); allitems = itm; } - if(dc.font.set) - XFreeFontSet(dpy, dc.font.set); - else - XFreeFont(dpy, dc.font.xfont); + if(!dc.font.xftfont) { + if(dc.font.set) + XFreeFontSet(dpy, dc.font.set); + else + XFreeFont(dpy, dc.font.xfont); + } XFreePixmap(dpy, dc.drawable); XFreeGC(dpy, dc.gc); XDestroyWindow(dpy, win); @@ -232,11 +249,19 @@ memcpy(buf, text, len); if(len < olen) for(i = len; i && i > len - 3; buf[--i] = '.'); +#ifdef XFT + if(dc.font.xftfont) + XftDrawStringUtf8(dc.xftdrawable, &dc.xftnorm[ColFG], dc.font.xftfont, x, y, (unsigned char*) buf, len); + else { +#endif XSetForeground(dpy, dc.gc, col[ColFG]); if(dc.font.set) XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); else XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); +#ifdef XFT + } +#endif } void @@ -259,6 +284,18 @@ return color.pixel; } +#ifdef XFT +unsigned long +getxftcolor(const char *colstr, XftColor *color) { + Colormap cmap = DefaultColormap(dpy, screen); + Visual *vis = DefaultVisual(dpy, screen); + + if(!XftColorAllocName(dpy, vis, cmap, colstr, color)) + eprint("error, cannot allocate color '%s'\n", colstr); + return color->pixel; +} +#endif + Bool grabkeyboard(void) { unsigned int len; @@ -274,6 +311,22 @@ void initfont(const char *fontstr) { +#ifdef XFT + dc.font.xftfont = 0; + if(cistrstr(fontstr,"xft:")) { + dc.font.xftfont = XftFontOpenXlfd(dpy, screen, fontstr+4); + if(!dc.font.xftfont) + dc.font.xftfont = XftFontOpenName(dpy, screen, fontstr+4); + if(!dc.font.xftfont) + eprint("error, cannot load font: '%s'\n", fontstr+4); + dc.font.extents = malloc(sizeof(XGlyphInfo)); + XftTextExtentsUtf8(dpy, dc.font.xftfont, (unsigned const char *) fontstr+4, strlen(fontstr+4), dc.font.extents); + dc.font.height = dc.font.xftfont->ascent + dc.font.xftfont->descent; + dc.font.ascent = dc.font.xftfont->ascent; + dc.font.descent = dc.font.xftfont->descent; + } + else { +#endif char *def, **missing; int i, n; @@ -306,6 +359,9 @@ dc.font.descent = dc.font.xfont->descent; } dc.font.height = dc.font.ascent + dc.font.descent; +#ifdef XFT + } +#endif } void @@ -585,11 +641,21 @@ XFreeModifiermap(modmap); /* style */ + initfont(font); +#ifdef XFT + if(dc.font.xftfont) { + dc.norm[ColBG] = getxftcolor(normbgcolor, &dc.xftnorm[ColBG]); + dc.norm[ColFG] = getxftcolor(normfgcolor, &dc.xftnorm[ColFG]); + dc.sel[ColBG] = getxftcolor(selbgcolor, &dc.xftsel[ColBG]); + } + else { +#endif dc.norm[ColBG] = getcolor(normbgcolor); dc.norm[ColFG] = getcolor(normfgcolor); dc.sel[ColBG] = getcolor(selbgcolor); - dc.sel[ColFG] = getcolor(selfgcolor); - initfont(font); +#ifdef XFT + } +#endif /* menu window */ wa.override_redirect = True; @@ -598,6 +664,8 @@ /* menu window geometry */ mh = dc.font.height + 2; + if(mh < bh) + mh = bh; #if XINERAMA if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; @@ -632,8 +700,19 @@ dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); +#ifdef XFT + if(dc.font.xftfont) { + dc.xftdrawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen)); + if(!dc.xftdrawable) + eprint("error, cannot create drawable\n"); + } + else { +#endif if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); +#ifdef XFT + } +#endif if(maxname) cmdw = textw(maxname); if(cmdw > mw / 3) @@ -649,6 +728,15 @@ int textnw(const char *text, unsigned int len) { +#ifdef XFT + if (dc.font.xftfont) { + XftTextExtentsUtf8(dpy, dc.font.xftfont, (unsigned const char *) text, strlen(text), dc.font.extents); + if(dc.font.extents->height > dc.font.height) + dc.font.height = dc.font.extents->height; + return dc.font.extents->xOff; + } + else { +#endif XRectangle r; if(dc.font.set) { @@ -656,6 +744,9 @@ return r.width; } return XTextWidth(dc.font.xfont, text, len); +#ifdef XFT + } +#endif } int @@ -691,14 +782,14 @@ else if(!strcmp(argv[i], "-sb")) { if(++i < argc) selbgcolor = argv[i]; } - else if(!strcmp(argv[i], "-sf")) { - if(++i < argc) selfgcolor = argv[i]; + else if(!strcmp(argv[i], "-bh")) { + if(++i < argc) bh = atoi(argv[i]); } else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n"); else eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n" - " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); + " [-sb <color>] [-bh <height>] [-p <prompt>] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL)))