From 06cf9a31163fdb6ce86ebfdd39e17aad68992b79 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Sat, 11 Oct 2008 11:20:20 +0200 Subject: [PATCH] [Xft] New feature: Freetype font \o/ --- CMakeLists.txt | 3 ++- config.c | 30 ++++++++---------------------- layout.c | 8 +++----- tag.c | 1 + util.c | 38 +++++++++++++++++++++++++++++--------- wmfs.c | 50 ++++++++++++++++++++------------------------------ wmfs.h | 31 +++++++++++++++---------------- wmfsrc | 8 +------- 8 files changed, 79 insertions(+), 90 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dafabfe..a35e03b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,8 @@ endif (X11_FOUND) set(LIBRARIES_TO_LINK ${FREETYPE_LIBRARIES} ${X11_LIBRARIES} - confuse) + confuse + Xft) target_link_libraries(wmfs ${LIBRARIES_TO_LINK}) diff --git a/config.c b/config.c index 08e5bfa..427678f 100644 --- a/config.c +++ b/config.c @@ -155,6 +155,7 @@ init_conf(void) static cfg_opt_t misc_opts[] = { + CFG_STR("font", "sans-9", CFGF_NONE), CFG_STR("bar_position", "top", CFGF_NONE), CFG_BOOL("raisefocus", cfg_false, CFGF_NONE), CFG_BOOL("raiseswitch", cfg_true, CFGF_NONE), @@ -164,14 +165,6 @@ init_conf(void) CFG_END() }; - static cfg_opt_t font_opts[] = - { - CFG_STR("face", "fixed", CFGF_NONE), - CFG_STR("style", "medium", CFGF_NONE), - CFG_INT("size", 12, CFGF_NONE), - CFG_END() - }; - static cfg_opt_t colors_opts[] = { CFG_STR("background", "#090909", CFGF_NONE), @@ -274,7 +267,6 @@ init_conf(void) static cfg_opt_t opts[] = { CFG_SEC("misc", misc_opts, CFGF_NONE), - CFG_SEC("font", font_opts, CFGF_NONE), CFG_SEC("variables", variables_opts, CFGF_NONE), CFG_SEC("colors", colors_opts, CFGF_NONE), CFG_SEC("layouts", layouts_opts, CFGF_NONE), @@ -286,7 +278,6 @@ init_conf(void) cfg_t *cfg; cfg_t *cfg_misc; - cfg_t *cfg_font; cfg_t *cfg_colors; cfg_t *cfg_variables; cfg_t *cfg_layouts; @@ -315,7 +306,6 @@ init_conf(void) } cfg_misc = cfg_getsec(cfg, "misc"); - cfg_font = cfg_getsec(cfg, "font"); cfg_variables = cfg_getsec(cfg, "variables"); cfg_colors = cfg_getsec(cfg, "colors"); cfg_layouts = cfg_getsec(cfg, "layouts"); @@ -337,6 +327,7 @@ init_conf(void) } /* misc */ + conf.font = var_to_str(strdup(cfg_getstr(cfg_misc, "font"))); conf.raisefocus = cfg_getbool(cfg_misc, "raisefocus"); conf.raiseswitch = cfg_getbool(cfg_misc, "raiseswitch"); conf.borderheight = cfg_getint(cfg_misc, "border_height"); @@ -344,24 +335,19 @@ init_conf(void) conf.tagbordwidth = cfg_getint(cfg_misc, "tag_border_width"); conf.bartop = (strcmp(strdup(cfg_getstr(cfg_misc, "bar_position")), "top") == 0) ? True : False; - /* font */ - conf.font.face = strdup(var_to_str(cfg_getstr(cfg_font, "face"))); - conf.font.style = strdup(var_to_str(cfg_getstr(cfg_font, "style"))); - conf.font.size = cfg_getint(cfg_font, "size"); - /* colors */ conf.colors.background = getcolor(var_to_str(cfg_getstr(cfg_colors, "background"))); conf.colors.bordernormal = getcolor(var_to_str(cfg_getstr(cfg_colors, "border_normal"))); conf.colors.borderfocus = getcolor(var_to_str(cfg_getstr(cfg_colors, "border_focus"))); conf.colors.bar = getcolor(var_to_str(cfg_getstr(cfg_colors, "bar_bg"))); - conf.colors.text = getcolor(var_to_str(cfg_getstr(cfg_colors, "bar_fg"))); - conf.colors.tagselfg = getcolor(var_to_str(cfg_getstr(cfg_colors, "tag_sel_fg"))); + conf.colors.text = strdup(var_to_str(cfg_getstr(cfg_colors, "bar_fg"))); + conf.colors.tagselfg = strdup(var_to_str(cfg_getstr(cfg_colors, "tag_sel_fg"))); conf.colors.tagselbg = getcolor(var_to_str(cfg_getstr(cfg_colors, "tag_sel_bg"))); conf.colors.tagbord = getcolor(var_to_str(cfg_getstr(cfg_colors, "tag_border"))); - conf.colors.layout_fg = getcolor(var_to_str(cfg_getstr(cfg_colors, "layout_fg"))); + conf.colors.layout_fg = strdup(var_to_str(cfg_getstr(cfg_colors, "layout_fg"))); conf.colors.layout_bg = getcolor(var_to_str(cfg_getstr(cfg_colors, "layout_bg"))); - conf.colors.ttbar_text_focus = getcolor(var_to_str(cfg_getstr(cfg_colors, "titlebar_text_focus"))); - conf.colors.ttbar_text_normal = getcolor(var_to_str(cfg_getstr(cfg_colors, "titlebar_text_normal"))); + conf.colors.ttbar_text_focus = strdup(var_to_str(cfg_getstr(cfg_colors, "titlebar_text_focus"))); + conf.colors.ttbar_text_normal = strdup(var_to_str(cfg_getstr(cfg_colors, "titlebar_text_normal"))); conf.colors.button = getcolor(var_to_str(cfg_getstr(cfg_colors, "button"))); conf.colors.button_border = getcolor(var_to_str(cfg_getstr(cfg_colors, "button_border"))); @@ -475,7 +461,7 @@ init_conf(void) } conf.barbutton[i].nmousesec = cfg_size(cfgtmp2, "mouse"); conf.barbutton[i].text = strdup(var_to_str(cfg_getstr(cfgtmp2, "text"))); - conf.barbutton[i].fg_color = getcolor(strdup(var_to_str(cfg_getstr(cfgtmp2, "fg_color")))); + conf.barbutton[i].fg_color = strdup(var_to_str(cfg_getstr(cfgtmp2, "fg_color"))); conf.barbutton[i].bg_color = getcolor(strdup(var_to_str(cfg_getstr(cfgtmp2, "bg_color")))); conf.barbutton[i].x = cfg_getint(cfgtmp2, "x"); } diff --git a/layout.c b/layout.c index 907cfc3..4e074ee 100644 --- a/layout.c +++ b/layout.c @@ -72,7 +72,7 @@ layoutswitch(Bool b) } arrange(); - return; + ; return; } void @@ -100,10 +100,8 @@ maxlayout(void) { c->tile = False; c->lmax = True; - c->ox = c->x; - c->oy = c->y; - c->ow = c->w; - c->oh = c->h; + c->ox = c->x; c->oy = c->y; + c->ow = c->w; c->oh = c->h; moveresize(c, 0, (conf.ttbarheight + ((conf.bartop) ? barheight : 0)), (mw - (conf.borderheight * 2)), diff --git a/tag.c b/tag.c index 03c5f33..41b22d7 100644 --- a/tag.c +++ b/tag.c @@ -85,6 +85,7 @@ uicb_tagtransfert(uicb_t cmd) if(!sel) return; + if(!n) n = 1; diff --git a/util.c b/util.c index ae135cd..38a9a6a 100644 --- a/util.c +++ b/util.c @@ -46,10 +46,9 @@ emalloc(uint element, uint size) ulong getcolor(char *color) { - Colormap cmap = DefaultColormap(dpy, screen); XColor xcolor; - if(!XAllocNamedColor(dpy, cmap, color, &xcolor, &xcolor)) + if(!XAllocNamedColor(dpy,DefaultColormap(dpy, screen), color, &xcolor, &xcolor)) fprintf(stderr,"WMFS Error: cannot allocate color \"%s\"\n", color); return xcolor.pixel; } @@ -79,15 +78,36 @@ uicb_spawn(uicb_t cmd) return; } -void -xprint(Drawable d, int x, int y, - uint fg, uint bg, - int d1, int d2, char *str) +ushort +textw(const char *text) { + XGlyphInfo gl; + + XftTextExtentsUtf8(dpy, xftfont, (FcChar8 *)text, strlen(text), &gl); + + return gl.width; +} + +void +xprint(Drawable d, int x, int y, char* fg, uint bg, int decx, int decw, char *str) +{ + XftColor xftcolor; + XftDraw *xftd; + + /* Transform X Drawable -> Xft Drawable */ + xftd = XftDrawCreate(dpy, d, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen)); + + /* Color the text font */ XSetForeground(dpy, gc, bg); - XFillRectangle(dpy, d, gc, x - d1, 0, TEXTW(str) - d2, barheight); - XSetForeground(dpy, gc, fg); - XDrawString(dpy, d, gc, x, y, str, strlen(str)); + XFillRectangle(dpy, d, gc, x - decx, 0, textw(str) - decw, barheight); + + /* Alloc text color and draw */ + XftColorAllocName(dpy, + DefaultVisual(dpy, screen), + DefaultColormap(dpy, screen), + fg, &xftcolor); + XftDrawStringUtf8(xftd, &xftcolor, xftfont, x, y, (FcChar8 *)str, strlen(str)); + XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &xftcolor); return; } diff --git a/wmfs.c b/wmfs.c index c4487c8..e9bf0ab 100644 --- a/wmfs.c +++ b/wmfs.c @@ -336,7 +336,6 @@ init(void) XSetWindowAttributes at; XModifierKeymap *modmap; int i, j; - char fontbuf[128]; /* FIRST INIT */ gc = DefaultGC (dpy, screen); @@ -351,24 +350,16 @@ init(void) for(i = 0; i < conf.ntag + 1; ++i) tags[i] = conf.tag[i - 1]; - /* INIT FONT - * make the font string with - * the configuration information */ - - sprintf(fontbuf, "-*-%s-%s-*-%d-*", - conf.font.face, - conf.font.style, - conf.font.size); - font = XLoadQueryFont(dpy, fontbuf); - if(!font) + /* INIT FONT */ + xftfont = XftFontOpenName(dpy, screen, conf.font); + if(!xftfont) { - fprintf(stderr, "XLoadQueryFont: failed loading font '%s'\n" - "Load the default font.\n", fontbuf); - font = XLoadQueryFont(dpy, "*-*-*-*-12-*"); + fprintf(stderr, "WMFS Error: Cannot initialize font\n"); + xftfont = XftFontOpenName(dpy, screen, "sans-10"); } - XSetFont(dpy, gc, font->fid); - fonth = (font->ascent + font->descent); - barheight = fonth + 4; + fonth = (xftfont->ascent + xftfont->descent) - 1; + barheight = fonth + 5; + /* INIT CURSOR */ cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); @@ -952,12 +943,12 @@ updatebar(void) /* Make the tags string */ ITOA(p, clientpertag(i+1)); sprintf(buf[i], "%s<%s>", tags[i+1].name, (clientpertag(i+1)) ? p : ""); - taglen[i+1] = taglen[i] + TEXTW(buf[i]) + sp; + taglen[i+1] = (taglen[i] + textw(buf[i])) + sp*2; /* Draw tags */ xprint(dr, taglen[i], fonth, ((i+1 == seltag) ? conf.colors.tagselfg : conf.colors.text), - ((i+1 == seltag) ? conf.colors.tagselbg : conf.colors.bar), sp, -sp, buf[i]); + ((i+1 == seltag) ? conf.colors.tagselbg : conf.colors.bar), sp, -sp*2, buf[i]); /* Tags border separation */ XSetForeground(dpy, gc, conf.colors.tagbord); @@ -966,14 +957,13 @@ updatebar(void) } /* Layout symbol */ - xprint(dr, taglen[conf.ntag] - sp/2 - 1, fonth, + xprint(dr, taglen[conf.ntag] - sp/2, fonth, conf.colors.layout_fg, conf.colors.layout_bg, - 1, 0, tags[seltag].layout.symbol); + 2, -4, tags[seltag].layout.symbol); /* Draw status text */ - k = TEXTW(bartext); + k = textw(bartext) + 2; xprint(dr, mw-k, fonth, conf.colors.text, conf.colors.bar, 0, 0, bartext); - XDrawLine(dpy, dr, gc, mw-k-5, 0, mw-k-5, barheight); /* Bar border */ if(conf.tagbordwidth) @@ -981,6 +971,7 @@ updatebar(void) XSetForeground(dpy, gc, conf.colors.tagbord); XFillRectangle(dpy, dr, gc, 0, ((conf.bartop) ? barheight-1: 0), mw, 1); + XFillRectangle(dpy, dr, gc, mw-k-5, 0, 1, barheight); } XCopyArea(dpy, dr, bar, gc, 0, 0, mw, barheight, 0, 0); @@ -998,30 +989,30 @@ void updatebutton(Bool c) { int i, j, x, pm = 0; - int y = 3, h = barheight - 5; + int y = 3, h = barheight - 6; XSetWindowAttributes at; at.override_redirect = 1; at.background_pixmap = ParentRelative; at.event_mask = ButtonPressMask | ExposureMask; - j = taglen[conf.ntag] + TEXTW(tags[seltag].layout.symbol); + j = taglen[conf.ntag] + textw(tags[seltag].layout.symbol); if(!conf.bartop) - y = bary + 3; + y = bary + 4; for(i = 0; i < conf.nbutton; ++i) { if(!(x = conf.barbutton[i].x)) { if(i) - pm += TEXTW(conf.barbutton[i-1].text); + pm += textw(conf.barbutton[i-1].text) + 4; x = (!i) ? j : j + pm; } if(!c) { - conf.barbutton[i].win = XCreateWindow(dpy, root, x, y, TEXTW(conf.barbutton[i].text), h, + conf.barbutton[i].win = XCreateWindow(dpy, root, x, y, TEXTW(conf.barbutton[i].text) + 4, h, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &at); @@ -1070,7 +1061,7 @@ updatetitle(Client *c) if(conf.ttbarheight > 10) { XClearWindow(dpy, c->tbar); - xprint(c->tbar, 3, ((fonth - 3) + ((conf.ttbarheight - fonth) / 2)), + xprint(c->tbar, 3, ((fonth - 2) + ((conf.ttbarheight - fonth) / 2)), ((c == sel) ? conf.colors.ttbar_text_focus : conf.colors.ttbar_text_normal), conf.colors.bar, 0, 0, c->title); } @@ -1133,7 +1124,6 @@ main(int argc, char **argv) mainloop(); /* Exiting WMFS :'( */ - XFreeFont(dpy, font); XUngrabKey(dpy, AnyKey, AnyModifier, root); XFreeCursor(dpy, cursor[CurNormal]); XFreeCursor(dpy, cursor[CurMove]); diff --git a/wmfs.h b/wmfs.h index 7ba35da..51b4d01 100644 --- a/wmfs.h +++ b/wmfs.h @@ -48,6 +48,7 @@ #include #include #include +#include #include #include "config.h" @@ -64,7 +65,7 @@ #define BUTY(y) y - conf.ttbarheight + 3 #define BUTH conf.ttbarheight - 6 #define BUTX(x, w) x + w - BUTH/400 -#define TEXTW(x) XTextWidth(font, x, strlen(x)) + (fonth / 10) +#define TEXTW(x) textw(x)//XTextWidth(font, x, strlen(x)) + (fonth / 10) #define MAXLAYOUT 3 /* Client Structure & Typedef */ @@ -105,7 +106,7 @@ typedef struct { char *text; Window win; - int fg_color; + char *fg_color; int bg_color; uint x; int nmousesec; @@ -134,6 +135,7 @@ typedef struct /* Configuration structure */ typedef struct { + char *font; bool raisefocus; bool raiseswitch; bool bartop; @@ -141,25 +143,19 @@ typedef struct int ttbarheight; int tagbordwidth; struct - { - char *face; - char *style; - int size; - } font; - struct { uint background; uint bordernormal; uint borderfocus; uint bar; - uint text; - uint tagselfg; + char *text; + char *tagselfg; uint tagselbg; uint tagbord; - uint layout_fg; + char *layout_fg; uint layout_bg; - uint ttbar_text_focus; - uint ttbar_text_normal; + char *ttbar_text_focus; + char *ttbar_text_normal; uint button; uint button_border; } colors; @@ -224,9 +220,10 @@ void getevent(void); /* util.c */ void *emalloc(uint elemet, uint size); ulong getcolor(char *color); +ushort textw(const char *text); void xprint(Drawable d, int x, int y, - uint fg, uint bg, - int d1, int d2, char* str); + char* fg, uint bg, + int decx, int decw, char* str); void uicb_spawn(uicb_t); /* tag.c */ @@ -264,6 +261,7 @@ Client* gettbar(Window w); void grabbuttons(Client *c, Bool focused); void grabkeys(void); void hide(Client *c); + void init(void); Bool ishide(Client *c); void mainloop(void); @@ -308,8 +306,9 @@ Atom net_atom[NetLast]; Cursor cursor[CurLast]; /* Fonts */ -XFontStruct *font; int fonth; +XftFont *xftfont; + /* Bar / Tags */ Window bar; diff --git a/wmfsrc b/wmfsrc index c365a48..47b4317 100644 --- a/wmfsrc +++ b/wmfsrc @@ -7,6 +7,7 @@ variables misc { + font = "sans-9" bar_position = "top" raisefocus = false raiseswitch = true @@ -15,13 +16,6 @@ misc tag_border_width = 1 } -font -{ - face = "fixed" - style = "medium" - size = 12 -} - colors { #Desktop