~ubuntu-branches/ubuntu/intrepid/matchbox/intrepid

« back to all changes in this revision

Viewing changes to src/theme.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Hedderly
  • Date: 2002-03-18 14:02:52 UTC
  • Revision ID: james.westby@ubuntu.com-20020318140252-h2icfj2rv2vxsb3c
Tags: upstream-0.1.8
ImportĀ upstreamĀ versionĀ 0.1.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* matchbox - a lightweight window manager
 
2
 
 
3
   Copyright 2002 Matthew Allum
 
4
 
 
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)
 
8
   any later version.
 
9
 
 
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.
 
14
*/
 
15
 
 
16
#include "theme.h"
 
17
 
 
18
Theme* theme_new(wm *w, char *theme_conf)
 
19
{
 
20
    Theme *t;
 
21
    char *default_theme_conf = DEFAULTTHEME ;
 
22
 
 
23
    if ( (t = malloc(sizeof(Theme))) == NULL) err("err out of memory");
 
24
    
 
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);
 
29
    return t;
 
30
}
 
31
 
 
32
void
 
33
theme_switch(Wm *w, Theme *t, char *new_theme_conf)
 
34
{
 
35
   Client *p;
 
36
   int orig_border = WBW(w->head_client);
 
37
   
 
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)
 
42
      {
 
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)
 
48
         {
 
49
            ;
 
50
         } else {
 
51
            p->configure(p);
 
52
            p->move_resize(p);
 
53
         }
 
54
 
 
55
         client_deliver_config(p);
 
56
         */
 
57
         p->redraw(p,False);
 
58
      }
 
59
   END_CLIENT_LOOP(w,p);
 
60
 
 
61
}
 
62
 
 
63
int
 
64
theme_load(Wm *w, Theme *t, char *theme_conf)
 
65
{
 
66
   XGCValues gv, dummy_gv;
 
67
   Cursor curs;
 
68
 
 
69
#ifdef USE_XFT    
 
70
   XRenderColor colortmp;
 
71
   char *fontname = "mono";
 
72
   char *tbfontname = "mono";
 
73
#else
 
74
   char *fontname = "fixed";
 
75
   char *tbfontname = "fixed";
 
76
#endif
 
77
   
 
78
   dbg("opening %s\n", theme_conf);
 
79
   rc_load(theme_conf);
 
80
 
 
81
   if (rc_get("font:") != NULL) fontname = rc_get("font:");
 
82
   if (rc_get("toolbar.font:") != NULL) tbfontname = rc_get("toolbar.font:");
 
83
 
 
84
#ifdef USE_XFT    
 
85
    if (rc_get("xftfont:") != NULL) fontname = rc_get("xftfont:");
 
86
    if (rc_get("toolbar.xftfont:") != NULL)
 
87
       tbfontname = rc_get("toolbar.xftfont:");
 
88
    
 
89
    t->xftfont = XftFontOpenName(w->dpy, 0, fontname);
 
90
    if (!t->xftfont)
 
91
    {
 
92
       printf("xft font %s not found, trying mono font\n", fontname);
 
93
       if ((t->xftfont = XftFontOpenName(w->dpy, 0, "mono")) == NULL)
 
94
       {
 
95
          printf("Mono font not found, giving up....\n"); exit(1);
 
96
       }
 
97
    }
 
98
    t->toolbar_xftfont = XftFontOpenName(w->dpy, 0, tbfontname);
 
99
    if (!t->toolbar_xftfont)
 
100
    {
 
101
       printf("xft font %s not found, trying mon font\n", tbfontname );
 
102
       if ((t->toolbar_xftfont = XftFontOpenName(w->dpy, 0, "mono")) == NULL)
 
103
       {
 
104
          printf("Mono font not found, giving up....\n"); exit(1);
 
105
       }
 
106
    }
 
107
#else
 
108
    if (!(t->font = XLoadQueryFont(w->dpy, fontname)))
 
109
    {
 
110
       printf("font %s not found, trying fixed\n", fontname);
 
111
       if (!(t->font = XLoadQueryFont(w->dpy, "fixed")))
 
112
       {
 
113
          printf("fixed font not found, giving up...\n");
 
114
          exit(1);
 
115
       }
 
116
    }
 
117
 
 
118
 
 
119
    if (!(t->toolbar_font = XLoadQueryFont(w->dpy, tbfontname)))
 
120
    {
 
121
       printf("font %s not found, trying fixed\n", tbfontname);
 
122
       if (!(t->toolbar_font = XLoadQueryFont(w->dpy, "fixed")))
 
123
       {
 
124
          printf("fixed font not found, giving up...\n");
 
125
          exit(1);
 
126
       }
 
127
    }
 
128
#endif
 
129
    
 
130
    /* New */
 
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;
 
135
 
 
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");
 
146
 
 
147
    /* text_gc, toolbar_text_gc, bg_gc, fg_gc, effects_gc; */
 
148
 
 
149
    gv.graphics_exposures = FALSE;
 
150
    gv.function   = GXcopy;
 
151
    gv.foreground = (t->text_col).pixel;
 
152
#ifndef USE_XFT
 
153
    gv.font       = t->font->fid;
 
154
#endif
 
155
    t->text_gc = XCreateGC(w->dpy, w->root,
 
156
                     GCGraphicsExposures|GCFunction|GCForeground|GCFont, &gv);
 
157
#ifndef USE_XFT
 
158
    gv.font = t->toolbar_font->fid;
 
159
#endif
 
160
    t->toolbar_text_gc = XCreateGC(w->dpy, w->root,
 
161
                     GCGraphicsExposures|GCFunction|GCForeground|GCFont, &gv);
 
162
 
 
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);
 
167
 
 
168
    gv.foreground = (t->fg_col).pixel; /* line width ? */
 
169
    t->fg_gc = XCreateGC(w->dpy, w->root,
 
170
                    GCGraphicsExposures|GCFunction|GCForeground, &gv);
 
171
 
 
172
    gv.foreground  = (t->fg_start_col).pixel; 
 
173
    t->effects_gc = XCreateGC(w->dpy, w->root,
 
174
                    GCGraphicsExposures|GCFunction|GCForeground, &gv);
 
175
 
 
176
    t->mask_gc = XCreateGC(w->dpy, w->root, 0, &dummy_gv);
 
177
 
 
178
    gv.function = GXinvert;
 
179
    gv.subwindow_mode = IncludeInferiors;
 
180
    t->invert_gc = XCreateGC(w->dpy, w->root, GCFunction|GCSubwindowMode|GCLineWidth|GCFont, &gv);
 
181
 
 
182
#ifdef USE_XFT
 
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)),
 
190
                       &colortmp,
 
191
                       &t->xft_fg);
 
192
 
 
193
#endif
 
194
    
 
195
    curs = XCreateFontCursor(w->dpy, XC_right_ptr);
 
196
    XDefineCursor(w->dpy, w->root, curs);
 
197
    
 
198
    t->tile.width = 0; t->tile.height = 0;
 
199
    
 
200
    if (rc_get("xpm.tile:"))
 
201
       theme_load_pxm( w, rc_get("xpm.tile:"), &(t->tile) );
 
202
    else
 
203
    {
 
204
       //  memset(&(t->tile), 0, sizeof(Pxm));
 
205
       t->tile.width = 0; t->tile.height = 0;
 
206
    }
 
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] );
 
222
 
 
223
    rc_destroy();
 
224
 
 
225
    return True;
 
226
}
 
227
 
 
228
 
 
229
void
 
230
theme_load_pixmap(wm *w, char *filename, Pixmap *pxm, Pixmap *mask,
 
231
                  int *width, int *height )
 
232
{
 
233
  XpmAttributes attrib;
 
234
 
 
235
  attrib.valuemask = 0; /* TODO: improve */
 
236
 
 
237
  if (XpmReadFileToPixmap( w->dpy, w->root, filename,
 
238
                           pxm, mask, &attrib) != XpmSuccess )
 
239
  {
 
240
     fprintf(stderr, "theme: failed loading image '%s'\n", filename);
 
241
     exit(1);
 
242
  }
 
243
 
 
244
  *width  = attrib.width;
 
245
  *height = attrib.height;
 
246
}
 
247
 
 
248
int
 
249
theme_load_pxm(Wm *w, char *filename, Pxm *pxm )
 
250
{
 
251
  XpmAttributes attrib;
 
252
 
 
253
  attrib.valuemask = 0; /* TODO: improve */
 
254
 
 
255
  if (XpmReadFileToPixmap( w->dpy, w->root, filename,
 
256
                           &(pxm->pixmap), &(pxm->mask), &attrib)
 
257
      != XpmSuccess )
 
258
  {
 
259
     fprintf(stderr, "theme: failed loading image '%s'\n", filename);
 
260
     exit(1);
 
261
  }
 
262
 
 
263
  pxm->width  = attrib.width;
 
264
  pxm->height = attrib.height;
 
265
 
 
266
  return 1;
 
267
}
 
268
 
 
269
 
 
270
void
 
271
theme_render_area(wm *w, Drawable dest, int x, int y,
 
272
                  int width, int height )
 
273
{
 
274
   Theme *t = w->theme;
 
275
 
 
276
   XFillRectangle(w->dpy, dest, t->fg_gc, x, y, width, height);
 
277
 
 
278
   if ( t->fg_start_col.pixel != t->fg_end_col.pixel )
 
279
   {
 
280
      XColor tmp_col;
 
281
      int i;
 
282
      
 
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;
 
286
      
 
287
      for(i=height;i;i--)
 
288
      {
 
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) ));
 
292
         
 
293
         XAllocColor(w->dpy, DefaultColormap(w->dpy, DefaultScreen(w->dpy)),
 
294
                     &tmp_col);
 
295
         XSetForeground(w->dpy, t->effects_gc, tmp_col.pixel); 
 
296
         XDrawLine(w->dpy, dest,t->effects_gc, x, y+height-i,
 
297
                   width, y+height-i);
 
298
      }
 
299
   }
 
300
   
 
301
   if (t->tile.width && t->tile.height) {  
 
302
      int x,y;
 
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);
 
308
               /*
 
309
            XCopyArea(w->dpy,
 
310
                      t->tile.pixmap,
 
311
                      dest, t->effects_gc,
 
312
                      0, 0, ww, h, x, y);
 
313
               */
 
314
   } 
 
315
 
 
316
   if (t->bevel)
 
317
   {
 
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,
 
325
                                         x+width, y);
 
326
      XDrawLine(w->dpy, dest, t->effects_gc, x, y,
 
327
                                         x, y+height-1);
 
328
   }
 
329
 
 
330
      
 
331
}
 
332
 
 
333
void
 
334
theme_paint_pxm(wm *w, Drawable dest, int x, int y, Pxm *p)
 
335
{
 
336
   XGCValues gc_vals;
 
337
   unsigned long valuemask = 0;
 
338
      
 
339
   XSetClipMask(w->dpy, w->theme->mask_gc, p->mask);
 
340
    
 
341
   gc_vals.clip_x_origin = x;
 
342
   gc_vals.clip_y_origin = y;
 
343
   
 
344
   valuemask =  GCClipXOrigin | GCClipYOrigin ;
 
345
   XChangeGC(w->dpy, w->theme->mask_gc, valuemask, &gc_vals);
 
346
 
 
347
   XCopyArea(w->dpy, p->pixmap, dest, w->theme->mask_gc,
 
348
             0, 0, p->width, p->height, x, y );
 
349
}
 
350
    
 
351
void
 
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 ? */
 
355
{
 
356
   XColor tmp_col;
 
357
   int i;
 
358
 
 
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;
 
362
 
 
363
   for(i=height;i;i--)
 
364
   {
 
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) ));
 
368
      
 
369
      XAllocColor(w->dpy, DefaultColormap(w->dpy, DefaultScreen(w->dpy)),
 
370
                  &tmp_col);
 
371
      XSetForeground(w->dpy, gc, tmp_col.pixel); 
 
372
      XDrawLine(w->dpy, dest, gc, x, y+height-i, width, y+height-i);
 
373
   }
 
374
   
 
375
}
 
376
 
 
377
 
 
378
int
 
379
_XColorFromStr(Display *display, XColor *col, const char *defstr)
 
380
{
 
381
  char *str;
 
382
  const char delim[] = ",:";
 
383
  char *token;
 
384
  XColor exact;
 
385
 
 
386
  if ((strchr(defstr, delim[0]) != NULL)
 
387
      || (strchr(defstr, delim[1]) != NULL) )
 
388
  {
 
389
     str = strdup(defstr);
 
390
 
 
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;
 
397
 
 
398
     return XAllocColor(display,
 
399
                        DefaultColormap(display, DefaultScreen(display)),
 
400
                        col);
 
401
  } else {
 
402
     return XAllocNamedColor(display,
 
403
                             DefaultColormap(display, DefaultScreen(display)),
 
404
                             defstr, col, &exact);
 
405
  }
 
406
}
 
407