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 " <lines>"]
.RB [ \-fn " <font>"]
+ .RB [ \-fa " <xftfont>"]
.RB [ \-nb " <color>"]
.RB [ \-nf " <color>"]
.RB [ \-p " <prompt>"]
***************
*** 34,39 ****
--- 35,43 ----
.B \-fn <font>
defines the font.
.TP
+ .B \-fa <font>
+ defines the xft font.
+ .TP
.B \-nb <color>
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 <X11/extensions/Xinerama.h>
#endif
+ #include <X11/Xft/Xft.h>
/* 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 <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n"
" [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-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 <xid>] [-l <lines>] [-fn <font>] [-fa <xftfont>] [-nb <color>]\n"
" [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n");
if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
fprintf(stderr, "warning: no locale support\n");