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
x_setupscreen(struct screen_ctx *sc, u_int which)
{
XColor tmp;
XGCValues gv;
Window *wins, w0, w1;
XWindowAttributes winattr;
XSetWindowAttributes rootattr;
@ -173,41 +171,11 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
Curscreen = sc;
sc->which = which;
sc->rootwin = RootWindow(X_Dpy, which);
sc->rootwin = RootWindow(X_Dpy, sc->which);
sc->xmax = DisplayWidth(X_Dpy, sc->which);
sc->ymax = DisplayHeight(X_Dpy, sc->which);
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
"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);
conf_color(&Conf);
font_init(sc);
conf_font(&Conf);

View File

@ -34,6 +34,21 @@
#define ButtonMask (ButtonPressMask|ButtonReleaseMask)
#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;
TAILQ_HEAD(cycle_entry_q, client_ctx);
@ -44,10 +59,8 @@ struct screen_ctx {
u_int which;
Window rootwin;
Window menuwin;
Colormap colormap;
XColor bgcolor, fgcolor, fccolor, redcolor, graycolor,
whitecolor, blackcolor;
unsigned long blackpixl, whitepixl, redpixl, bluepixl, graypixl;
struct color color[CWM_COLOR_MAX];
GC gc;
int altpersist;
@ -78,8 +91,8 @@ TAILQ_HEAD(screen_ctx_q, screen_ctx);
#define CLIENT_DOVMAXIMIZE 0x10
#define CLIENT_VMAXIMIZED 0x20
#define CLIENT_HIGHLIGHT_BLUE 1
#define CLIENT_HIGHLIGHT_RED 2
#define CLIENT_HIGHLIGHT_GROUP 1
#define CLIENT_HIGHLIGHT_UNGROUP 2
struct winname {
TAILQ_ENTRY(winname) entry;
@ -259,6 +272,14 @@ struct conf {
#define CONF_MAMOUNT 1
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 lockpath[MAXPATHLEN];
@ -393,6 +414,8 @@ int xu_getprop(struct client_ctx *, Atom, Atom, long,
char *xu_getstrprop(struct client_ctx *, Atom atm);
void xu_setstate(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 *);
void u_exec(char *);
@ -422,6 +445,7 @@ void conf_mouseunbind(struct conf *, struct mousebinding *);
void conf_grab_mouse(struct client_ctx *);
void conf_reload(struct conf *);
void conf_font(struct conf *);
void conf_color(struct conf *);
void conf_init(struct conf *);
void conf_clear(struct conf *);
void conf_cmd_add(struct conf *, char *, char *, int);

View File

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

33
conf.c
View File

@ -61,6 +61,21 @@ conf_font(struct conf *c)
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
conf_reload(struct conf *c)
{
@ -69,6 +84,7 @@ conf_reload(struct conf *c)
return;
}
conf_color(c);
conf_font(c);
}
@ -157,6 +173,19 @@ conf_init(struct conf *c)
strlcpy(c->termpath, "xterm", sizeof(c->termpath));
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);
}
@ -168,6 +197,7 @@ conf_clear(struct conf *c)
struct winmatch *wm;
struct cmd *cmd;
struct mousebinding *mb;
int i;
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
TAILQ_REMOVE(&c->cmdq, cmd, entry);
@ -198,6 +228,9 @@ conf_clear(struct conf *c)
xfree(mb);
}
for (i = 0; i < CWM_COLOR_MAX; i++)
xfree(c->color[i].name);
xfree(c->DefaultFontName);
}

14
cwmrc.5
View File

@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: May 14 2009 $
.Dd $Mdocdate: May 17 2009 $
.Dt CWMRC 5
.Os
.Sh NAME
@ -84,6 +84,18 @@ application.
Set the window border width to
.Ar pixels .
.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
Every
.Ar name

14
font.c
View File

@ -22,22 +22,14 @@
void
font_init(struct screen_ctx *sc)
{
XColor xcolor, tmp;
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which));
if (sc->xftdraw == NULL)
errx(1, "XftDrawCreate");
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which),
"black", &xcolor, &tmp))
errx(1, "XAllocNamedColor");
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;
if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which),
DefaultColormap(X_Dpy, sc->which), "black", &sc->xftcolor))
errx(1, "XftColorAllocName");
}
int

View File

@ -168,10 +168,10 @@ group_sticky_toggle_enter(struct client_ctx *cc)
if (gc == cc->group) {
_group_remove(cc);
cc->highlight = CLIENT_HIGHLIGHT_RED;
cc->highlight = CLIENT_HIGHLIGHT_UNGROUP;
} else {
_group_add(gc, cc);
cc->highlight = CLIENT_HIGHLIGHT_BLUE;
cc->highlight = CLIENT_HIGHLIGHT_GROUP;
}
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
menu_init(struct screen_ctx *sc)
{
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0,
1, 1, 1, sc->blackpixl, sc->whitepixl);
XGCValues gv;
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 *

34
parse.y
View File

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