1
/* matchbox - a lightweight window manager
3
Copyright 2002 Matthew Allum
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2, or (at your option)
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
18
Theme* theme_new(wm *w, char *theme_conf)
21
char *default_theme_conf = DEFAULTTHEME ;
23
if ( (t = malloc(sizeof(Theme))) == NULL) err("err out of memory");
25
if (theme_conf == NULL) theme_conf = default_theme_conf;
26
XChangeProperty(w->dpy, w->root, w->mb_theme, XA_STRING, 8,
27
PropModeReplace, theme_conf, strlen(theme_conf));
28
theme_load(w, t, theme_conf);
33
theme_switch(Wm *w, Theme *t, char *new_theme_conf)
36
int orig_border = WBW(w->head_client);
38
theme_load(w, t, new_theme_conf);
39
t->win_border_width = orig_border;
40
START_CLIENT_LOOP(w,p);
41
if (p->type != docked)
43
XSetWindowBorder(w->dpy, p->window, (t->bg_col).pixel);
44
XSetWindowBorder(w->dpy, p->frame, (t->bg_col).pixel);
45
/* -- TODO fix border size change on resize --
46
XSetWindowBorderWidth(w->dpy, p->frame, WBW(p));
47
if (p->type == toolbar && client_get_state(p) == IconicState)
55
client_deliver_config(p);
64
theme_load(Wm *w, Theme *t, char *theme_conf)
66
XGCValues gv, dummy_gv;
70
XRenderColor colortmp;
71
char *fontname = "mono";
72
char *tbfontname = "mono";
74
char *fontname = "fixed";
75
char *tbfontname = "fixed";
78
dbg("opening %s\n", theme_conf);
81
if (rc_get("font:") != NULL) fontname = rc_get("font:");
82
if (rc_get("toolbar.font:") != NULL) tbfontname = rc_get("toolbar.font:");
85
if (rc_get("xftfont:") != NULL) fontname = rc_get("xftfont:");
86
if (rc_get("toolbar.xftfont:") != NULL)
87
tbfontname = rc_get("toolbar.xftfont:");
89
t->xftfont = XftFontOpenName(w->dpy, 0, fontname);
92
printf("xft font %s not found, trying mono font\n", fontname);
93
if ((t->xftfont = XftFontOpenName(w->dpy, 0, "mono")) == NULL)
95
printf("Mono font not found, giving up....\n"); exit(1);
98
t->toolbar_xftfont = XftFontOpenName(w->dpy, 0, tbfontname);
99
if (!t->toolbar_xftfont)
101
printf("xft font %s not found, trying mon font\n", tbfontname );
102
if ((t->toolbar_xftfont = XftFontOpenName(w->dpy, 0, "mono")) == NULL)
104
printf("Mono font not found, giving up....\n"); exit(1);
108
if (!(t->font = XLoadQueryFont(w->dpy, fontname)))
110
printf("font %s not found, trying fixed\n", fontname);
111
if (!(t->font = XLoadQueryFont(w->dpy, "fixed")))
113
printf("fixed font not found, giving up...\n");
119
if (!(t->toolbar_font = XLoadQueryFont(w->dpy, tbfontname)))
121
printf("font %s not found, trying fixed\n", tbfontname);
122
if (!(t->toolbar_font = XLoadQueryFont(w->dpy, "fixed")))
124
printf("fixed font not found, giving up...\n");
131
t->win_border_width = rc_get("win.border:") ? atoi(rc_get("win.border:")) : 2;
132
t->padding = rc_get("win.padding:")? atoi(rc_get("win.padding:")) : 2;;
133
t->bevel = (rc_get("win.bevel:") && (strcmp(rc_get("win.bevel:"),"YES") == 0)) ? 1 : 0;
134
//t->type = gradient;
136
_XColorFromStr(w->dpy, &(t->bg_col), rc_get("bg.color:") ?
137
rc_get("bg.color:") : "black" );
138
_XColorFromStr(w->dpy, &(t->text_col), rc_get("text.color:") ?
139
rc_get("text.color:") : "black");
140
_XColorFromStr(w->dpy, &(t->fg_col), rc_get("fg.color:") ?
141
rc_get("fg.color:") : "white");
142
_XColorFromStr(w->dpy, &(t->fg_start_col), rc_get("fg.start.color:") ?
143
rc_get("fg.start.color:") : "white");
144
_XColorFromStr(w->dpy, &(t->fg_end_col), rc_get("fg.end.color:") ?
145
rc_get("fg.end.color:") : "white");
147
/* text_gc, toolbar_text_gc, bg_gc, fg_gc, effects_gc; */
149
gv.graphics_exposures = FALSE;
150
gv.function = GXcopy;
151
gv.foreground = (t->text_col).pixel;
153
gv.font = t->font->fid;
155
t->text_gc = XCreateGC(w->dpy, w->root,
156
GCGraphicsExposures|GCFunction|GCForeground|GCFont, &gv);
158
gv.font = t->toolbar_font->fid;
160
t->toolbar_text_gc = XCreateGC(w->dpy, w->root,
161
GCGraphicsExposures|GCFunction|GCForeground|GCFont, &gv);
163
gv.foreground = (t->bg_col).pixel;
164
gv.line_width = t->win_border_width;
165
t->bg_gc = XCreateGC(w->dpy, w->root,
166
GCGraphicsExposures|GCFunction|GCForeground|GCLineWidth, &gv);
168
gv.foreground = (t->fg_col).pixel; /* line width ? */
169
t->fg_gc = XCreateGC(w->dpy, w->root,
170
GCGraphicsExposures|GCFunction|GCForeground, &gv);
172
gv.foreground = (t->fg_start_col).pixel;
173
t->effects_gc = XCreateGC(w->dpy, w->root,
174
GCGraphicsExposures|GCFunction|GCForeground, &gv);
176
t->mask_gc = XCreateGC(w->dpy, w->root, 0, &dummy_gv);
178
gv.function = GXinvert;
179
gv.subwindow_mode = IncludeInferiors;
180
t->invert_gc = XCreateGC(w->dpy, w->root, GCFunction|GCSubwindowMode|GCLineWidth|GCFont, &gv);
183
colortmp.red = (t->text_col).red;
184
colortmp.green = (t->text_col).green;
185
colortmp.blue = (t->text_col).blue;
186
colortmp.alpha = 0xffff;
187
XftColorAllocValue(w->dpy,
188
DefaultVisual(w->dpy, DefaultScreen(w->dpy)),
189
DefaultColormap(w->dpy,DefaultScreen(w->dpy)),
195
curs = XCreateFontCursor(w->dpy, XC_right_ptr);
196
XDefineCursor(w->dpy, w->root, curs);
198
t->tile.width = 0; t->tile.height = 0;
200
if (rc_get("xpm.tile:"))
201
theme_load_pxm( w, rc_get("xpm.tile:"), &(t->tile) );
204
// memset(&(t->tile), 0, sizeof(Pxm));
205
t->tile.width = 0; t->tile.height = 0;
207
theme_load_pxm(w, rc_get("xpm.prev:") ? rc_get("xpm.prev:") : XPM_PREV,
208
&t->buttons[BUTTON_PREV] );
209
theme_load_pxm(w, rc_get("xpm.next:") ? rc_get("xpm.next:") : XPM_NEXT,
210
&t->buttons[BUTTON_NEXT] );
211
theme_load_pxm(w, rc_get("xpm.close:") ? rc_get("xpm.close:") : XPM_CLOSE,
212
&t->buttons[BUTTON_CLOSE] );
213
theme_load_pxm(w, rc_get("xpm.toolbar:")
214
? rc_get("xpm.toolbar:") : XPM_TOOLBAR,
215
&t->buttons[BUTTON_TOOLBAR] );
216
theme_load_pxm(w, rc_get("xpm.toolbar.close:")
217
? rc_get("xpm.toolbar.close:") : XPM_TOOLBAR_CLOSE,
218
&t->buttons[BUTTON_TOOLBAR_CLOSE] );
219
theme_load_pxm(w, rc_get("xpm.select:")
220
? rc_get("xpm.select:") : XPM_MENU_SELECT,
221
&t->buttons[BUTTON_MENU_SELECT] );
230
theme_load_pixmap(wm *w, char *filename, Pixmap *pxm, Pixmap *mask,
231
int *width, int *height )
233
XpmAttributes attrib;
235
attrib.valuemask = 0; /* TODO: improve */
237
if (XpmReadFileToPixmap( w->dpy, w->root, filename,
238
pxm, mask, &attrib) != XpmSuccess )
240
fprintf(stderr, "theme: failed loading image '%s'\n", filename);
244
*width = attrib.width;
245
*height = attrib.height;
249
theme_load_pxm(Wm *w, char *filename, Pxm *pxm )
251
XpmAttributes attrib;
253
attrib.valuemask = 0; /* TODO: improve */
255
if (XpmReadFileToPixmap( w->dpy, w->root, filename,
256
&(pxm->pixmap), &(pxm->mask), &attrib)
259
fprintf(stderr, "theme: failed loading image '%s'\n", filename);
263
pxm->width = attrib.width;
264
pxm->height = attrib.height;
271
theme_render_area(wm *w, Drawable dest, int x, int y,
272
int width, int height )
276
XFillRectangle(w->dpy, dest, t->fg_gc, x, y, width, height);
278
if ( t->fg_start_col.pixel != t->fg_end_col.pixel )
283
float red_step = (t->fg_end_col.red - t->fg_start_col.red) / height;
284
float green_step = (t->fg_end_col.green - t->fg_start_col.green)/ height;
285
float blue_step = (t->fg_end_col.blue - t->fg_start_col.blue ) / height;
289
tmp_col.red = (t->fg_start_col.red + (red_step * (height-i) ));
290
tmp_col.green = (t->fg_start_col.green + ( green_step * (height-i) ));
291
tmp_col.blue = (t->fg_start_col.blue + ( blue_step * (height-i) ));
293
XAllocColor(w->dpy, DefaultColormap(w->dpy, DefaultScreen(w->dpy)),
295
XSetForeground(w->dpy, t->effects_gc, tmp_col.pixel);
296
XDrawLine(w->dpy, dest,t->effects_gc, x, y+height-i,
301
if (t->tile.width && t->tile.height) {
303
int ww = t->tile.width;
304
int h = t->tile.height;
305
for(x=0;x<width;x+=ww)
306
for(y=0;y<height;y+=h)
307
theme_paint_pxm(w, dest, x, y, &t->tile);
318
XSetForeground(w->dpy, t->effects_gc, t->fg_start_col.pixel);
319
XDrawLine(w->dpy, dest, t->effects_gc, x, y+height-1,
320
x+width, y+height-1);
321
XDrawLine(w->dpy, dest, t->effects_gc, x+width, y,
322
x+width, y+height-1);
323
XSetForeground(w->dpy, t->effects_gc, t->fg_end_col.pixel);
324
XDrawLine(w->dpy, dest, t->effects_gc, x, y,
326
XDrawLine(w->dpy, dest, t->effects_gc, x, y,
334
theme_paint_pxm(wm *w, Drawable dest, int x, int y, Pxm *p)
337
unsigned long valuemask = 0;
339
XSetClipMask(w->dpy, w->theme->mask_gc, p->mask);
341
gc_vals.clip_x_origin = x;
342
gc_vals.clip_y_origin = y;
344
valuemask = GCClipXOrigin | GCClipYOrigin ;
345
XChangeGC(w->dpy, w->theme->mask_gc, valuemask, &gc_vals);
347
XCopyArea(w->dpy, p->pixmap, dest, w->theme->mask_gc,
348
0, 0, p->width, p->height, x, y );
352
theme_draw_gradient(wm *w, Drawable dest, GC gc, int x, int y,
353
int width, int height,
354
XColor* start_col, XColor* end_col) /* TOGO ? */
359
float red_step = ( end_col->red - start_col->red) / height;
360
float green_step = (end_col->green - start_col->green ) / height;
361
float blue_step = (end_col->blue - start_col->blue ) / height;
365
tmp_col.red = ( start_col->red + ( red_step * (height-i) ));
366
tmp_col.green = ( start_col->green + ( green_step * (height-i) ));
367
tmp_col.blue = ( start_col->blue + ( blue_step * (height-i) ));
369
XAllocColor(w->dpy, DefaultColormap(w->dpy, DefaultScreen(w->dpy)),
371
XSetForeground(w->dpy, gc, tmp_col.pixel);
372
XDrawLine(w->dpy, dest, gc, x, y+height-i, width, y+height-i);
379
_XColorFromStr(Display *display, XColor *col, const char *defstr)
382
const char delim[] = ",:";
386
if ((strchr(defstr, delim[0]) != NULL)
387
|| (strchr(defstr, delim[1]) != NULL) )
389
str = strdup(defstr);
391
token = strsep (&str, delim);
392
col->red = ( atoi(token) * 65535 ) / 255;
393
token = strsep (&str, delim);
394
col->green = ( atoi(token) * 65535 ) / 255;
395
token = strsep (&str, delim);
396
col->blue = ( atoi(token) * 65535 ) / 255;
398
return XAllocColor(display,
399
DefaultColormap(display, DefaultScreen(display)),
402
return XAllocNamedColor(display,
403
DefaultColormap(display, DefaultScreen(display)),
404
defstr, col, &exact);