summary refs log tree commit diff
diff options
context:
space:
mode:
authorokan <okan>2009-05-17 23:40:57 +0000
committerokan <okan>2009-05-17 23:40:57 +0000
commit4d5dc5d9ea24d1b856c8b8c13c36a16daa396a4d (patch)
tree1981b9b6d512a7bfdf07dbe8c7e957de0e004d61
parent5d51c8e0e541449093913ff3b1f78989c82ed035 (diff)
downloadcwm-4d5dc5d9ea24d1b856c8b8c13c36a16daa396a4d.tar.gz
cwm-4d5dc5d9ea24d1b856c8b8c13c36a16daa396a4d.tar.xz
cwm-4d5dc5d9ea24d1b856c8b8c13c36a16daa396a4d.zip
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@
-rw-r--r--calmwm.c36
-rw-r--r--calmwm.h36
-rw-r--r--client.c16
-rw-r--r--conf.c33
-rw-r--r--cwmrc.514
-rw-r--r--font.c14
-rw-r--r--group.c4
-rw-r--r--menu.c15
-rw-r--r--parse.y34
-rw-r--r--xutil.c20
10 files changed, 158 insertions, 64 deletions
diff --git a/calmwm.c b/calmwm.c
index 36aa533..3c61a3e 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -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);
diff --git a/calmwm.h b/calmwm.h
index e102763..b3d41cb 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -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);
diff --git a/client.c b/client.c
index e1e0dbe..be4e379 100644
--- a/client.c
+++ b/client.c
@@ -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
diff --git a/conf.c b/conf.c
index 7dba8b1..bd7deb1 100644
--- a/conf.c
+++ b/conf.c
@@ -62,6 +62,21 @@ conf_font(struct conf *c)
 }
 
 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)
 {
 	if (parse_config(c->conf_path, c) == -1) {
@@ -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);
 }
 
diff --git a/cwmrc.5 b/cwmrc.5
index 64b88ec..87171d6 100644
--- a/cwmrc.5
+++ b/cwmrc.5
@@ -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
diff --git a/font.c b/font.c
index 622d17b..0322d50 100644
--- a/font.c
+++ b/font.c
@@ -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
diff --git a/group.c b/group.c
index 776a18d..301a9d2 100644
--- a/group.c
+++ b/group.c
@@ -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);
diff --git a/menu.c b/menu.c
index 7d0e1d8..f8c8abc 100644
--- a/menu.c
+++ b/menu.c
@@ -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 *
diff --git a/parse.y b/parse.y
index 2554ed3..272b587 100644
--- a/parse.y
+++ b/parse.y
@@ -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);
diff --git a/xutil.c b/xutil.c
index 7246531..e5129b6 100644
--- a/xutil.c
+++ b/xutil.c
@@ -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);
+}