diff -crB dmenu-4.1.1/config.def.h dmenu-patched/config.def.h *** dmenu-4.1.1/config.def.h 2010-07-23 01:32:31.000000000 +0400 --- dmenu-patched/config.def.h 2010-07-23 02:32:30.000000000 +0400 *************** *** 7,9 **** --- 7,10 ---- static const char *selbgcolor = "#0066ff"; static const char *selfgcolor = "#ffffff"; static unsigned int spaceitem = 30; /* px between menu items */ + static const char *fontxft = "Monospace-10:normal"; /*if set xft is used */ Только в dmenu-patched: config.def.h.orig Только в dmenu-patched: config.h diff -crB dmenu-4.1.1/config.mk dmenu-patched/config.mk *** dmenu-4.1.1/config.mk 2010-07-23 01:32:32.000000000 +0400 --- dmenu-patched/config.mk 2010-07-23 02:32:30.000000000 +0400 *************** *** 15,22 **** XINERAMAFLAGS = -DXINERAMA # includes and libs ! INCS = -I. -I/usr/include -I${X11INC} ! LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} --- 15,22 ---- XINERAMAFLAGS = -DXINERAMA # includes and libs ! INCS = -I. -I/usr/include -I${X11INC} -I/usr/include -I/usr/include/freetype2 ! LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} -lXft -lX11 -lXrender -lfreetype -lz -lfontconfig -lXrender -lX11 # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} Только в dmenu-patched: config.mk.orig diff -crB dmenu-4.1.1/dmenu.1 dmenu-patched/dmenu.1 *** dmenu-4.1.1/dmenu.1 2010-07-23 01:32:32.000000000 +0400 --- dmenu-patched/dmenu.1 2010-07-23 02:32:30.000000000 +0400 *************** *** 7,12 **** --- 7,13 ---- .RB [ \-b ] .RB [ \-l " "] .RB [ \-fn " "] + .RB [ \-fa " "] .RB [ \-nb " "] .RB [ \-nf " "] .RB [ \-p " "] *************** *** 34,39 **** --- 35,43 ---- .B \-fn defines the font. .TP + .B \-fa + defines the xft font. + .TP .B \-nb defines the normal background color (#RGB, #RRGGBB, and color names are supported). .TP Только в dmenu-patched: dmenu.1.orig Только в dmenu-patched: dmenu-4.1.1-xft.diff Только в dmenu-patched: dmenu-4.1.1-xft.diff.1 diff -crB dmenu-4.1.1/dmenu.c dmenu-patched/dmenu.c *** dmenu-4.1.1/dmenu.c 2010-07-23 01:32:31.000000000 +0400 --- dmenu-patched/dmenu.c 2010-07-23 16:03:17.000000000 +0400 *************** *** 13,18 **** --- 13,19 ---- #ifdef XINERAMA #include #endif + #include /* macros */ #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) *************** *** 29,34 **** --- 30,36 ---- int x, y, w, h; unsigned long norm[ColLast]; unsigned long sel[ColLast]; + Bool selected; Drawable drawable; GC gc; struct { *************** *** 38,43 **** --- 40,55 ---- int descent; int height; } font; + XftDraw *xftdraw; + XftColor xftselcolor; + XftColor xftcolor; + XGlyphInfo gi; + struct { + XftFont *xft_font; + int ascent; + int descent; + int height; + } xftfont; } DC; /* draw context */ typedef struct Item Item; *************** *** 135,152 **** void calcoffsetsv(void) { static unsigned int h; if(!curr) return; ! h = (dc.font.height + 2) * (lines + 1); for(next = curr; next; next=next->right) { ! h -= dc.font.height + 2; if(h <= 0) break; } ! h = (dc.font.height + 2) * (lines + 1); for(prev = curr; prev && prev->left; prev=prev->left) { ! h -= dc.font.height + 2; if(h <= 0) break; } --- 147,169 ---- void calcoffsetsv(void) { static unsigned int h; + int h2; if(!curr) return; ! if(fontxft) ! h2 = dc.xftfont.height; ! else ! h2 = dc.font.height; ! h = (h2 + 2) * (lines + 1); for(next = curr; next; next=next->right) { ! h -= h2 + 2; if(h <= 0) break; } ! h = (h2 + 2) * (lines + 1); for(prev = curr; prev && prev->left; prev=prev->left) { ! h -= h2 + 2; if(h <= 0) break; } *************** *** 185,193 **** free(allitems); allitems = itm; } if(dc.font.set) XFreeFontSet(dpy, dc.font.set); ! else XFreeFont(dpy, dc.font.xfont); XFreePixmap(dpy, dc.drawable); XFreeGC(dpy, dc.gc); --- 202,215 ---- free(allitems); allitems = itm; } + if(fontxft) { + XftColorFree (dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &dc.xftcolor); + XftFontClose (dpy, dc.xftfont.xft_font); + XftDrawDestroy(dc.xftdraw); + } if(dc.font.set) XFreeFontSet(dpy, dc.font.set); ! else if(!fontxft) XFreeFont(dpy, dc.font.xfont); XFreePixmap(dpy, dc.drawable); XFreeGC(dpy, dc.gc); *************** *** 198,205 **** void drawcursor(void) { XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; ! r.x += textnw(text, cursor) + dc.font.height / 2; XSetForeground(dpy, dc.gc, dc.norm[ColFG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); --- 220,234 ---- void drawcursor(void) { XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; + int h2; ! if(fontxft) ! h2 = dc.xftfont.height; ! else ! h2 = dc.font.height; ! ! r.height = h2 - 2; ! r.x += textnw(text, cursor) + h2 / 2; XSetForeground(dpy, dc.gc, dc.norm[ColFG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); *************** *** 213,221 **** dc.h = mh; drawtext(NULL, dc.norm); /* print prompt? */ ! if(prompt) { dc.w = promptw; drawtext(prompt, dc.sel); dc.x += dc.w; } dc.w = mw - dc.x; --- 242,252 ---- dc.h = mh; drawtext(NULL, dc.norm); /* print prompt? */ ! if(promptw) { dc.w = promptw; + dc.selected = True; drawtext(prompt, dc.sel); + dc.selected = False; dc.x += dc.w; } dc.w = mw - dc.x; *************** *** 244,250 **** dc.x += dc.w; for(i = curr; i != next; i=i->right) { dc.w = MIN(textw(i->text), mw / 3); ! drawtext(i->text, (sel == i) ? dc.sel : dc.norm); dc.x += dc.w; } dc.w = spaceitem; --- 275,287 ---- dc.x += dc.w; for(i = curr; i != next; i=i->right) { dc.w = MIN(textw(i->text), mw / 3); ! if(sel == i) { ! dc.selected = True; ! drawtext(i->text, dc.sel); ! dc.selected = False; ! } else { ! drawtext(i->text, dc.norm); ! } dc.x += dc.w; } dc.w = spaceitem; *************** *** 255,266 **** void drawmenuv(void) { Item *i; dc.w = mw - dc.x; ! dc.y += dc.font.height + 2; for(i = curr; i != next; i=i->right) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); ! dc.y += dc.font.height + 2; } drawtext(NULL, dc.norm); } --- 292,309 ---- void drawmenuv(void) { Item *i; + int h2; + + if(fontxft) + h2 = dc.xftfont.height; + else + h2 = dc.font.height; dc.w = mw - dc.x; ! dc.y += h2 + 2; for(i = curr; i != next; i=i->right) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); ! dc.y += h2 + 2; } drawtext(NULL, dc.norm); } *************** *** 268,274 **** void drawtext(const char *text, unsigned long col[ColLast]) { char buf[256]; ! int i, x, y, h, len, olen; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); --- 311,317 ---- void drawtext(const char *text, unsigned long col[ColLast]) { char buf[256]; ! int i, x, y, h, a, len, olen; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); *************** *** 276,283 **** if(!text) return; olen = strlen(text); ! h = dc.font.height; ! y = dc.y + ((h+2) / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); /* shorten text if necessary */ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); --- 319,338 ---- if(!text) return; olen = strlen(text); ! if(!fontxft) { ! h = dc.font.height; ! a = dc.font.ascent; ! } else { ! h = dc.xftfont.height; ! a = dc.xftfont.ascent; ! } ! y = dc.y + ((h+2) / 2) - (h / 2) + a; ! #if 0 ! if(dc.xftfont.xft_font) { ! h = dc.xftfont.ascent + dc.xftfont.descent; ! y = dc.y + (dc.h / 2) - (h / 2) + dc.xftfont.ascent; ! } ! #endif x = dc.x + (h / 2); /* shorten text if necessary */ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--); *************** *** 287,293 **** if(len < olen) for(i = len; i && i > len - 3; buf[--i] = '.'); 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); --- 342,356 ---- if(len < olen) for(i = len; i && i > len - 3; buf[--i] = '.'); XSetForeground(dpy, dc.gc, col[ColFG]); ! if(fontxft) { ! if (!dc.xftdraw) ! eprint("error, creating xft drawable failed"); ! if(dc.selected) { ! XftDrawStringUtf8(dc.xftdraw, &dc.xftselcolor, dc.xftfont.xft_font, x, y, (unsigned char*)buf, len); ! } else { ! XftDrawStringUtf8(dc.xftdraw, &dc.xftcolor, dc.xftfont.xft_font, x, y, (unsigned char*)buf, len); ! } ! } else 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); *************** *** 359,364 **** --- 421,435 ---- } void + initxft() { + if(!(dc.xftfont.xft_font = XftFontOpenName (dpy, screen, fontxft))) + eprint("error, cannot load xft font\n" ); + dc.xftfont.ascent = dc.xftfont.xft_font->ascent; + dc.xftfont.descent = dc.xftfont.xft_font->descent; + dc.xftfont.height = dc.xftfont.ascent + dc.xftfont.descent; + } + + void kpress(XKeyEvent * e) { char buf[sizeof text]; int i, num, off; *************** *** 697,703 **** dc.norm[ColFG] = getcolor(normfgcolor); dc.sel[ColBG] = getcolor(selbgcolor); dc.sel[ColFG] = getcolor(selfgcolor); ! initfont(font); /* menu window */ wa.override_redirect = True; --- 768,782 ---- dc.norm[ColFG] = getcolor(normfgcolor); dc.sel[ColBG] = getcolor(selbgcolor); dc.sel[ColFG] = getcolor(selfgcolor); ! dc.selected = False; ! if(fontxft){ ! if(!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), (const char*)normfgcolor, &dc.xftcolor)) ! eprint("error, cannot allocate xft font color '%s'\n", normfgcolor); ! if(!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), (const char*)selfgcolor, &dc.xftselcolor)) ! eprint("error, cannot allocate xft font color '%s'\n", normfgcolor); ! else ! initxft(); ! } else initfont(font); /* menu window */ wa.override_redirect = True; *************** *** 705,711 **** wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; /* menu window geometry */ ! mh = (dc.font.height + 2) * (lines + 1); #if XINERAMA if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; --- 784,793 ---- wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; /* menu window geometry */ ! if(fontxft) ! mh = (dc.xftfont.height + 2) * (lines + 1); ! else ! mh = (dc.font.height + 2) * (lines + 1); #if XINERAMA if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { i = 0; *************** *** 741,747 **** dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, parent, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); ! if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); if(maxname) cmdw = MIN(textw(maxname), mw / 3); --- 823,829 ---- dc.drawable = XCreatePixmap(dpy, parent, mw, mh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, parent, 0, NULL); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); ! if(!dc.font.set && !fontxft) XSetFont(dpy, dc.gc, dc.font.xfont->fid); if(maxname) cmdw = MIN(textw(maxname), mw / 3); *************** *** 750,762 **** text[0] = '\0'; match(text); XMapRaised(dpy, win); } int textnw(const char *text, unsigned int len) { ! XRectangle r; ! ! if(dc.font.set) { XmbTextExtents(dc.font.set, text, len, NULL, &r); return r.width; } --- 832,851 ---- text[0] = '\0'; match(text); XMapRaised(dpy, win); + if(fontxft) { + dc.xftdraw = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen)); + if(!dc.xftdraw) + eprint("error, cannot create xft drawable\n"); + } } int textnw(const char *text, unsigned int len) { ! if(fontxft) { ! XftTextExtentsUtf8(dpy, dc.xftfont.xft_font, (const FcChar8*)text, len, &dc.gi); ! return dc.gi.width; ! } else if(dc.font.set) { ! XRectangle r; XmbTextExtents(dc.font.set, text, len, NULL, &r); return r.width; } *************** *** 765,770 **** --- 854,861 ---- int textw(const char *text) { + if(fontxft) + return textnw(text, strlen(text)) + dc.xftfont.height; return textnw(text, strlen(text)) + dc.font.height; } *************** *** 791,796 **** --- 882,890 ---- else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } + else if(!strcmp(argv[i], "-fa")) { + if(++i < argc) fontxft = argv[i]; + } else if(!strcmp(argv[i], "-nb")) { if(++i < argc) normbgcolor = argv[i]; } *************** *** 809,815 **** else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); else ! eprint("usage: dmenu [-i] [-b] [-e ] [-l ] [-fn ] [-nb ]\n" " [-nf ] [-p ] [-sb ] [-sf ] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n"); --- 903,909 ---- else if(!strcmp(argv[i], "-v")) eprint("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); else ! eprint("usage: dmenu [-i] [-b] [-e ] [-l ] [-fn ] [-fa ] [-nb ]\n" " [-nf ] [-p ] [-sb ] [-sf ] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "warning: no locale support\n");