a long time coming - re-work the way we deal with colors: since we're

using Xft(3), use it to select the font color as well instead of trying
to build one; properly allocate and free colors at-will, e.g. we now
have configurable colors.

feedback and ok's todd@ and oga@
This commit is contained in:
okan 2009-05-17 23:40:57 +00:00
parent 5d51c8e0e5
commit 4d5dc5d9ea
10 changed files with 158 additions and 64 deletions

View File

@ -162,8 +162,6 @@ x_teardown(void)
void void
x_setupscreen(struct screen_ctx *sc, u_int which) x_setupscreen(struct screen_ctx *sc, u_int which)
{ {
XColor tmp;
XGCValues gv;
Window *wins, w0, w1; Window *wins, w0, w1;
XWindowAttributes winattr; XWindowAttributes winattr;
XSetWindowAttributes rootattr; XSetWindowAttributes rootattr;
@ -173,41 +171,11 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
Curscreen = sc; Curscreen = sc;
sc->which = which; sc->which = which;
sc->rootwin = RootWindow(X_Dpy, which); sc->rootwin = RootWindow(X_Dpy, sc->which);
sc->xmax = DisplayWidth(X_Dpy, sc->which); sc->xmax = DisplayWidth(X_Dpy, sc->which);
sc->ymax = DisplayHeight(X_Dpy, sc->which); sc->ymax = DisplayHeight(X_Dpy, sc->which);
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which), conf_color(&Conf);
"black", &sc->fgcolor, &tmp);
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
"#00cc00", &sc->bgcolor, &tmp);
XAllocNamedColor(X_Dpy,DefaultColormap(X_Dpy, which),
"blue", &sc->fccolor, &tmp);
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
"red", &sc->redcolor, &tmp);
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
"#666666", &sc->graycolor, &tmp);
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
"white", &sc->whitecolor, &tmp);
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
"black", &sc->blackcolor, &tmp);
sc->blackpixl = BlackPixel(X_Dpy, sc->which);
sc->whitepixl = WhitePixel(X_Dpy, sc->which);
sc->bluepixl = sc->fccolor.pixel;
sc->redpixl = sc->redcolor.pixel;
sc->graypixl = sc->graycolor.pixel;
gv.foreground = sc->blackpixl^sc->whitepixl;
gv.background = sc->whitepixl;
gv.function = GXxor;
gv.line_width = 1;
gv.subwindow_mode = IncludeInferiors;
sc->gc = XCreateGC(X_Dpy, sc->rootwin,
GCForeground|GCBackground|GCFunction|
GCLineWidth|GCSubwindowMode, &gv);
font_init(sc); font_init(sc);
conf_font(&Conf); conf_font(&Conf);

View File

@ -34,6 +34,21 @@
#define ButtonMask (ButtonPressMask|ButtonReleaseMask) #define ButtonMask (ButtonPressMask|ButtonReleaseMask)
#define MouseMask (ButtonMask|PointerMotionMask) #define MouseMask (ButtonMask|PointerMotionMask)
enum cwmcolor {
CWM_COLOR_BORDOR_ACTIVE,
CWM_COLOR_BORDER_INACTIVE,
CWM_COLOR_BORDER_GROUP,
CWM_COLOR_BORDER_UNGROUP,
CWM_COLOR_FG_MENU,
CWM_COLOR_BG_MENU,
CWM_COLOR_MAX
};
struct color {
unsigned long pixel;
char *name;
};
struct client_ctx; struct client_ctx;
TAILQ_HEAD(cycle_entry_q, client_ctx); TAILQ_HEAD(cycle_entry_q, client_ctx);
@ -44,10 +59,8 @@ struct screen_ctx {
u_int which; u_int which;
Window rootwin; Window rootwin;
Window menuwin; Window menuwin;
Colormap colormap;
XColor bgcolor, fgcolor, fccolor, redcolor, graycolor, struct color color[CWM_COLOR_MAX];
whitecolor, blackcolor;
unsigned long blackpixl, whitepixl, redpixl, bluepixl, graypixl;
GC gc; GC gc;
int altpersist; int altpersist;
@ -78,8 +91,8 @@ TAILQ_HEAD(screen_ctx_q, screen_ctx);
#define CLIENT_DOVMAXIMIZE 0x10 #define CLIENT_DOVMAXIMIZE 0x10
#define CLIENT_VMAXIMIZED 0x20 #define CLIENT_VMAXIMIZED 0x20
#define CLIENT_HIGHLIGHT_BLUE 1 #define CLIENT_HIGHLIGHT_GROUP 1
#define CLIENT_HIGHLIGHT_RED 2 #define CLIENT_HIGHLIGHT_UNGROUP 2
struct winname { struct winname {
TAILQ_ENTRY(winname) entry; TAILQ_ENTRY(winname) entry;
@ -259,6 +272,14 @@ struct conf {
#define CONF_MAMOUNT 1 #define CONF_MAMOUNT 1
int mamount; int mamount;
#define CONF_COLOR_ACTIVEBORDER "#CCCCCC"
#define CONF_COLOR_INACTIVEBORDER "#666666"
#define CONF_COLOR_GROUPBORDER "blue"
#define CONF_COLOR_UNGROUPBORDER "red"
#define CONF_COLOR_MENUFG "black"
#define CONF_COLOR_MENUBG "white"
struct color color[CWM_COLOR_MAX];
char termpath[MAXPATHLEN]; char termpath[MAXPATHLEN];
char lockpath[MAXPATHLEN]; char lockpath[MAXPATHLEN];
@ -393,6 +414,8 @@ int xu_getprop(struct client_ctx *, Atom, Atom, long,
char *xu_getstrprop(struct client_ctx *, Atom atm); char *xu_getstrprop(struct client_ctx *, Atom atm);
void xu_setstate(struct client_ctx *, int); void xu_setstate(struct client_ctx *, int);
int xu_getstate(struct client_ctx *, int *); int xu_getstate(struct client_ctx *, int *);
unsigned long xu_getcolor(struct screen_ctx *, char *);
void xu_freecolor(struct screen_ctx *, unsigned long);
int u_spawn(char *); int u_spawn(char *);
void u_exec(char *); void u_exec(char *);
@ -422,6 +445,7 @@ void conf_mouseunbind(struct conf *, struct mousebinding *);
void conf_grab_mouse(struct client_ctx *); void conf_grab_mouse(struct client_ctx *);
void conf_reload(struct conf *); void conf_reload(struct conf *);
void conf_font(struct conf *); void conf_font(struct conf *);
void conf_color(struct conf *);
void conf_init(struct conf *); void conf_init(struct conf *);
void conf_clear(struct conf *); void conf_clear(struct conf *);
void conf_cmd_add(struct conf *, char *, char *, int); void conf_cmd_add(struct conf *, char *, char *, int);

View File

@ -403,25 +403,25 @@ void
client_draw_border(struct client_ctx *cc) client_draw_border(struct client_ctx *cc)
{ {
struct screen_ctx *sc = CCTOSC(cc); struct screen_ctx *sc = CCTOSC(cc);
u_long pixl; unsigned long pixel;
if (cc->active) if (cc->active)
switch (cc->highlight) { switch (cc->highlight) {
case CLIENT_HIGHLIGHT_BLUE: case CLIENT_HIGHLIGHT_GROUP:
pixl = sc->bluepixl; pixel = sc->color[CWM_COLOR_BORDER_GROUP].pixel;
break; break;
case CLIENT_HIGHLIGHT_RED: case CLIENT_HIGHLIGHT_UNGROUP:
pixl = sc->redpixl; pixel = sc->color[CWM_COLOR_BORDER_UNGROUP].pixel;
break; break;
default: default:
pixl = sc->whitepixl; pixel = sc->color[CWM_COLOR_BORDOR_ACTIVE].pixel;
break; break;
} }
else else
pixl = sc->graypixl; pixel = sc->color[CWM_COLOR_BORDER_INACTIVE].pixel;
XSetWindowBorderWidth(X_Dpy, cc->win, cc->bwidth); XSetWindowBorderWidth(X_Dpy, cc->win, cc->bwidth);
XSetWindowBorder(X_Dpy, cc->win, pixl); XSetWindowBorder(X_Dpy, cc->win, pixel);
} }
void void

33
conf.c
View File

@ -61,6 +61,21 @@ conf_font(struct conf *c)
c->FontHeight = font_ascent() + font_descent() + 1; c->FontHeight = font_ascent() + font_descent() + 1;
} }
void
conf_color(struct conf *c)
{
struct screen_ctx *sc;
int i;
sc = screen_current();
for (i = 0; i < CWM_COLOR_MAX; i++) {
xu_freecolor(sc, sc->color[i].pixel);
sc->color[i].pixel = xu_getcolor(sc, c->color[i].name);
}
}
void void
conf_reload(struct conf *c) conf_reload(struct conf *c)
{ {
@ -69,6 +84,7 @@ conf_reload(struct conf *c)
return; return;
} }
conf_color(c);
conf_font(c); conf_font(c);
} }
@ -157,6 +173,19 @@ conf_init(struct conf *c)
strlcpy(c->termpath, "xterm", sizeof(c->termpath)); strlcpy(c->termpath, "xterm", sizeof(c->termpath));
strlcpy(c->lockpath, "xlock", sizeof(c->lockpath)); strlcpy(c->lockpath, "xlock", sizeof(c->lockpath));
c->color[CWM_COLOR_BORDOR_ACTIVE].name =
xstrdup(CONF_COLOR_ACTIVEBORDER);
c->color[CWM_COLOR_BORDER_INACTIVE].name =
xstrdup(CONF_COLOR_INACTIVEBORDER);
c->color[CWM_COLOR_BORDER_GROUP].name =
xstrdup(CONF_COLOR_GROUPBORDER);
c->color[CWM_COLOR_BORDER_UNGROUP].name =
xstrdup(CONF_COLOR_UNGROUPBORDER);
c->color[CWM_COLOR_FG_MENU].name =
xstrdup(CONF_COLOR_MENUFG);
c->color[CWM_COLOR_BG_MENU].name =
xstrdup(CONF_COLOR_MENUBG);
c->DefaultFontName = xstrdup(DEFAULTFONTNAME); c->DefaultFontName = xstrdup(DEFAULTFONTNAME);
} }
@ -168,6 +197,7 @@ conf_clear(struct conf *c)
struct winmatch *wm; struct winmatch *wm;
struct cmd *cmd; struct cmd *cmd;
struct mousebinding *mb; struct mousebinding *mb;
int i;
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) { while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
TAILQ_REMOVE(&c->cmdq, cmd, entry); TAILQ_REMOVE(&c->cmdq, cmd, entry);
@ -198,6 +228,9 @@ conf_clear(struct conf *c)
xfree(mb); xfree(mb);
} }
for (i = 0; i < CWM_COLOR_MAX; i++)
xfree(c->color[i].name);
xfree(c->DefaultFontName); xfree(c->DefaultFontName);
} }

14
cwmrc.5
View File

@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: May 14 2009 $ .Dd $Mdocdate: May 17 2009 $
.Dt CWMRC 5 .Dt CWMRC 5
.Os .Os
.Sh NAME .Sh NAME
@ -84,6 +84,18 @@ application.
Set the window border width to Set the window border width to
.Ar pixels . .Ar pixels .
.Pp .Pp
.It Ic color activeborder Ar color
Set the color of the active border.
.Pp
.It Ic color groupborder Ar color
Set the color of the border while grouping a window.
.Pp
.It Ic color inactiveborder Ar color
Set the color of the inactive border.
.Pp
.It Ic color ungroupborder Ar color
Set the color of the border while ungrouping a window.
.Pp
.It Ic command Ar name Ar path .It Ic command Ar name Ar path
Every Every
.Ar name .Ar name

14
font.c
View File

@ -22,22 +22,14 @@
void void
font_init(struct screen_ctx *sc) font_init(struct screen_ctx *sc)
{ {
XColor xcolor, tmp;
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin, sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which)); DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which));
if (sc->xftdraw == NULL) if (sc->xftdraw == NULL)
errx(1, "XftDrawCreate"); errx(1, "XftDrawCreate");
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which), if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which),
"black", &xcolor, &tmp)) DefaultColormap(X_Dpy, sc->which), "black", &sc->xftcolor))
errx(1, "XAllocNamedColor"); errx(1, "XftColorAllocName");
sc->xftcolor.color.red = xcolor.red;
sc->xftcolor.color.green = xcolor.green;
sc->xftcolor.color.blue = xcolor.blue;
sc->xftcolor.color.alpha = 0x00ff00;
sc->xftcolor.pixel = xcolor.pixel;
} }
int int

View File

@ -168,10 +168,10 @@ group_sticky_toggle_enter(struct client_ctx *cc)
if (gc == cc->group) { if (gc == cc->group) {
_group_remove(cc); _group_remove(cc);
cc->highlight = CLIENT_HIGHLIGHT_RED; cc->highlight = CLIENT_HIGHLIGHT_UNGROUP;
} else { } else {
_group_add(gc, cc); _group_add(gc, cc);
cc->highlight = CLIENT_HIGHLIGHT_BLUE; cc->highlight = CLIENT_HIGHLIGHT_GROUP;
} }
client_draw_border(cc); client_draw_border(cc);

15
menu.c
View File

@ -58,8 +58,19 @@ static int menu_calc_entry(struct screen_ctx *, struct menu_ctx *,
void void
menu_init(struct screen_ctx *sc) menu_init(struct screen_ctx *sc)
{ {
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, XGCValues gv;
1, 1, 1, sc->blackpixl, sc->whitepixl);
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1, 0,
sc->color[CWM_COLOR_BG_MENU].pixel,
sc->color[CWM_COLOR_BG_MENU].pixel);
gv.foreground =
sc->color[CWM_COLOR_FG_MENU].pixel^sc->color[CWM_COLOR_BG_MENU].pixel;
gv.background = sc->color[CWM_COLOR_BG_MENU].pixel;
gv.function = GXxor;
sc->gc = XCreateGC(X_Dpy, sc->menuwin,
GCForeground|GCBackground|GCFunction, &gv);
} }
struct menu * struct menu *

34
parse.y
View File

@ -67,6 +67,9 @@ typedef struct {
%token FONTNAME STICKY GAP MOUSEBIND %token FONTNAME STICKY GAP MOUSEBIND
%token AUTOGROUP BIND COMMAND IGNORE %token AUTOGROUP BIND COMMAND IGNORE
%token YES NO BORDERWIDTH MOVEAMOUNT %token YES NO BORDERWIDTH MOVEAMOUNT
%token COLOR
%token ACTIVEBORDER INACTIVEBORDER
%token GROUPBORDER UNGROUPBORDER
%token ERROR %token ERROR
%token <v.string> STRING %token <v.string> STRING
%token <v.number> NUMBER %token <v.number> NUMBER
@ -77,6 +80,7 @@ typedef struct {
grammar : /* empty */ grammar : /* empty */
| grammar '\n' | grammar '\n'
| grammar main '\n' | grammar main '\n'
| grammar color '\n'
| grammar error '\n' { file->errors++; } | grammar error '\n' { file->errors++; }
; ;
@ -170,6 +174,27 @@ main : FONTNAME STRING {
free($3); free($3);
} }
; ;
color : COLOR colors
;
colors : ACTIVEBORDER STRING {
free(conf->color[CWM_COLOR_BORDOR_ACTIVE].name);
conf->color[CWM_COLOR_BORDOR_ACTIVE].name = $2;
}
| INACTIVEBORDER STRING {
free(conf->color[CWM_COLOR_BORDER_INACTIVE].name);
conf->color[CWM_COLOR_BORDER_INACTIVE].name = $2;
}
| GROUPBORDER STRING {
free(conf->color[CWM_COLOR_BORDER_GROUP].name);
conf->color[CWM_COLOR_BORDER_GROUP].name = $2;
}
| UNGROUPBORDER STRING {
free(conf->color[CWM_COLOR_BORDER_UNGROUP].name);
conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2;
}
;
%% %%
struct keywords { struct keywords {
@ -202,17 +227,22 @@ lookup(char *s)
{ {
/* this has to be sorted always */ /* this has to be sorted always */
static const struct keywords keywords[] = { static const struct keywords keywords[] = {
{ "activeborder", ACTIVEBORDER},
{ "autogroup", AUTOGROUP}, { "autogroup", AUTOGROUP},
{ "bind", BIND}, { "bind", BIND},
{ "borderwidth", BORDERWIDTH}, { "borderwidth", BORDERWIDTH},
{ "color", COLOR},
{ "command", COMMAND}, { "command", COMMAND},
{ "fontname", FONTNAME}, { "fontname", FONTNAME},
{ "gap", GAP}, { "gap", GAP},
{ "groupborder", GROUPBORDER},
{ "ignore", IGNORE}, { "ignore", IGNORE},
{ "inactiveborder", INACTIVEBORDER},
{ "mousebind", MOUSEBIND}, { "mousebind", MOUSEBIND},
{ "moveamount", MOVEAMOUNT}, { "moveamount", MOVEAMOUNT},
{ "no", NO}, { "no", NO},
{ "sticky", STICKY}, { "sticky", STICKY},
{ "ungroupborder", UNGROUPBORDER},
{ "yes", YES} { "yes", YES}
}; };
const struct keywords *p; const struct keywords *p;
@ -498,6 +528,7 @@ parse_config(const char *filename, struct conf *xconf)
struct winmatch *wm; struct winmatch *wm;
struct cmd *cmd; struct cmd *cmd;
struct mousebinding *mb; struct mousebinding *mb;
int i;
conf_clear(xconf); conf_clear(xconf);
@ -535,6 +566,9 @@ parse_config(const char *filename, struct conf *xconf)
strlcpy(xconf->lockpath, conf->lockpath, strlcpy(xconf->lockpath, conf->lockpath,
sizeof(xconf->lockpath)); sizeof(xconf->lockpath));
for (i = 0; i < CWM_COLOR_MAX; i++)
xconf->color[i].name = conf->color[i].name;
xconf->DefaultFontName = conf->DefaultFontName; xconf->DefaultFontName = conf->DefaultFontName;
bcopy(&(conf->gap_top), &(xconf->gap_top), sizeof(int) * 4); bcopy(&(conf->gap_top), &(xconf->gap_top), sizeof(int) * 4);

20
xutil.c
View File

@ -184,3 +184,23 @@ xu_getatoms(void)
{ {
XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms); XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms);
} }
unsigned long
xu_getcolor(struct screen_ctx *sc, char *name)
{
XColor color, tmp;
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which),
name, &color, &tmp)) {
warnx("XAllocNamedColor error: '%s'", name);
return 0;
}
return color.pixel;
}
void
xu_freecolor(struct screen_ctx *sc, unsigned long pixel)
{
XFreeColors(X_Dpy, DefaultColormap(X_Dpy, sc->which), &pixel, 1, 0L);
}