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 @@ -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); } 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 STRING %token 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); +}