~ubuntu-branches/ubuntu/wily/lxappearance-obconf/wily-proposed

« back to all changes in this revision

Viewing changes to src/preview.c

  • Committer: Package Import Robot
  • Author(s): Daniel Baumann
  • Date: 2012-04-16 21:39:22 UTC
  • Revision ID: package-import@ubuntu.com-20120416213922-fcf49q5qsm9tv5ms
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 
2
 
 
3
   preview.c for ObConf, the configuration tool for Openbox
 
4
   Copyright (c) 2007        Javeed Shaikh
 
5
   Copyright (c) 2007        Dana Jansens
 
6
 
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 2 of the License, or
 
10
   (at your option) any later version.
 
11
 
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
 
 
17
   See the COPYING file for a copy of the GNU General Public License.
 
18
*/
 
19
 
 
20
#include "theme.h"
 
21
#include "main.h"
 
22
#include "tree.h"
 
23
 
 
24
#include <string.h>
 
25
 
 
26
#include <obrender/theme.h>
 
27
 
 
28
#if GTK_CHECK_VERSION(3, 0, 0)
 
29
#include <gdk/gdkx.h>
 
30
#endif
 
31
 
 
32
#define PADDING 2 /* openbox does it :/ */
 
33
 
 
34
/* Forwarded */
 
35
 
 
36
GdkPixbuf *preview_theme(const gchar *name, const gchar *titlelayout,
 
37
                         RrFont *active_window_font,
 
38
                         RrFont *inactive_window_font,
 
39
                         RrFont *menu_title_font,
 
40
                         RrFont *menu_item_font,
 
41
                         RrFont *osd_active_font,
 
42
                         RrFont *osd_inactive_font);
 
43
 
 
44
/* End forwarded */
 
45
 
 
46
static void theme_pixmap_paint(RrAppearance *a, gint w, gint h)
 
47
{
 
48
    Pixmap out = RrPaintPixmap(a, w, h);
 
49
    if (out) XFreePixmap(RrDisplay(a->inst), out);
 
50
}
 
51
 
 
52
static guint32 rr_color_pixel(const RrColor *c)
 
53
{
 
54
    return (guint32)((RrColorRed(c) << 24) + (RrColorGreen(c) << 16) +
 
55
                     + (RrColorBlue(c) << 8) + 0xff);
 
56
}
 
57
 
 
58
/* XXX: Make this more general */
 
59
static GdkPixbuf* preview_menu(RrTheme *theme)
 
60
{
 
61
    RrAppearance *title;
 
62
    RrAppearance *title_text;
 
63
 
 
64
    RrAppearance *menu;
 
65
    RrAppearance *background;
 
66
 
 
67
    RrAppearance *normal;
 
68
    RrAppearance *disabled;
 
69
    RrAppearance *selected;
 
70
    RrAppearance *bullet; /* for submenu */
 
71
#if GTK_CHECK_VERSION(3, 0, 0)
 
72
    cairo_surface_t *surface;
 
73
    Display *dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
 
74
#else
 
75
    GdkPixmap *pixmap;
 
76
#endif
 
77
    GdkPixbuf *pixbuf;
 
78
 
 
79
    /* width and height of the whole menu */
 
80
    gint width, height;
 
81
    gint x, y;
 
82
    gint title_h;
 
83
    gint tw, th;
 
84
    gint bw, bh;
 
85
    gint unused;
 
86
 
 
87
    /* set up appearances */
 
88
    title = theme->a_menu_title;
 
89
 
 
90
    title_text = theme->a_menu_text_title;
 
91
    title_text->surface.parent = title;
 
92
    title_text->texture[0].data.text.string = "Menu";
 
93
 
 
94
    normal = theme->a_menu_text_normal;
 
95
    normal->texture[0].data.text.string = "Normal";
 
96
 
 
97
    disabled = theme->a_menu_text_disabled;
 
98
    disabled->texture[0].data.text.string = "Disabled";
 
99
 
 
100
    selected = theme->a_menu_text_selected;
 
101
    selected->texture[0].data.text.string = "Selected";
 
102
 
 
103
    bullet = theme->a_menu_bullet_normal;
 
104
 
 
105
    /* determine window size */
 
106
    RrMinSize(normal, &width, &th);
 
107
    width += th + PADDING; /* make space for the bullet */
 
108
    //height = th;
 
109
 
 
110
    width += 2*theme->mbwidth + 2*PADDING;
 
111
 
 
112
    /* get minimum title size */
 
113
    RrMinSize(title, &tw, &title_h);
 
114
 
 
115
    /* size of background behind each text line */
 
116
    bw = width - 2*theme->mbwidth;
 
117
    //title_h += 2*PADDING;
 
118
    title_h = theme->menu_title_height;
 
119
 
 
120
    RrMinSize(normal, &unused, &th);
 
121
    bh = th + 2*PADDING;
 
122
 
 
123
    height = title_h + 3*bh + 3*theme->mbwidth;
 
124
 
 
125
    //height += 3*th + 3*theme->mbwidth + 5*PADDING;
 
126
 
 
127
    /* set border */
 
128
    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height);
 
129
    gdk_pixbuf_fill(pixbuf, rr_color_pixel(theme->menu_border_color));
 
130
 
 
131
    /* draw title */
 
132
    x = y = theme->mbwidth;
 
133
    theme_pixmap_paint(title, bw, title_h);
 
134
 
 
135
    /* draw title text */
 
136
    title_text->surface.parentx = 0;
 
137
    title_text->surface.parenty = 0;
 
138
 
 
139
    theme_pixmap_paint(title_text, bw, title_h);
 
140
 
 
141
#if GTK_CHECK_VERSION(3, 0, 0)
 
142
    surface = cairo_xlib_surface_create(dpy,
 
143
                                                   title_text->pixmap,
 
144
                                                   DefaultVisual(dpy, 0),
 
145
                                                   x,
 
146
                                                   y);
 
147
 
 
148
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
149
                                        0,
 
150
                                        0,
 
151
                                        bw,
 
152
                                        title_h);
 
153
 
 
154
   cairo_surface_destroy(surface);
 
155
 
 
156
#else
 
157
    pixmap = gdk_pixmap_foreign_new(title_text->pixmap);
 
158
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
159
                                          gdk_colormap_get_system(),
 
160
                                          0, 0, x, y, bw, title_h);
 
161
#endif
 
162
    /* menu appears after title */
 
163
    y += theme->mbwidth + title_h;
 
164
 
 
165
    /* fill in menu appearance, used as the parent to every menu item's bg */
 
166
    menu = theme->a_menu;
 
167
    th = height - 3*theme->mbwidth - title_h;
 
168
    theme_pixmap_paint(menu, bw, th);
 
169
 
 
170
#if GTK_CHECK_VERSION(3, 0, 0)
 
171
    surface = cairo_xlib_surface_create(dpy,
 
172
                                                   menu->pixmap,
 
173
                                                   DefaultVisual(dpy, 0),
 
174
                                                   x,
 
175
                                                   y);
 
176
 
 
177
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
178
                                        0,
 
179
                                        0,
 
180
                                        bw,
 
181
                                        th);
 
182
 
 
183
   cairo_surface_destroy(surface);
 
184
 
 
185
#else
 
186
    pixmap = gdk_pixmap_foreign_new(menu->pixmap);
 
187
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
188
                                          gdk_colormap_get_system(),
 
189
                                          0, 0, x, y, bw, th);
 
190
#endif
 
191
 
 
192
    /* fill in background appearance, used as the parent to text items */
 
193
    background = theme->a_menu_normal;
 
194
    background->surface.parent = menu;
 
195
    background->surface.parentx = 0;
 
196
    background->surface.parenty = 0;
 
197
 
 
198
    /* draw background for normal entry */
 
199
    theme_pixmap_paint(background, bw, bh);
 
200
#if GTK_CHECK_VERSION(3, 0, 0)
 
201
    surface = cairo_xlib_surface_create(dpy,
 
202
                                                   background->pixmap,
 
203
                                                   DefaultVisual(dpy, 0),
 
204
                                                   x,
 
205
                                                   y);
 
206
 
 
207
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
208
                                        0,
 
209
                                        0,
 
210
                                        bw,
 
211
                                        bh);
 
212
 
 
213
   cairo_surface_destroy(surface);
 
214
 
 
215
#else
 
216
    pixmap = gdk_pixmap_foreign_new(background->pixmap);
 
217
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
218
                                          gdk_colormap_get_system(),
 
219
                                          0, 0, x, y, bw, bh);
 
220
#endif
 
221
 
 
222
    /* draw normal entry */
 
223
    normal->surface.parent = background;
 
224
    normal->surface.parentx = PADDING;
 
225
    normal->surface.parenty = PADDING;
 
226
    x += PADDING;
 
227
    y += PADDING;
 
228
    RrMinSize(normal, &tw, &th);
 
229
    theme_pixmap_paint(normal, tw, th);
 
230
#if GTK_CHECK_VERSION(3, 0, 0)
 
231
    surface = cairo_xlib_surface_create(dpy,
 
232
                                                   normal->pixmap,
 
233
                                                   DefaultVisual(dpy, 0),
 
234
                                                   x,
 
235
                                                   y);
 
236
 
 
237
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
238
                                        0,
 
239
                                        0,
 
240
                                        tw,
 
241
                                        th);
 
242
 
 
243
   cairo_surface_destroy(surface);
 
244
 
 
245
#else
 
246
    pixmap = gdk_pixmap_foreign_new(normal->pixmap);
 
247
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
248
                                          gdk_colormap_get_system(),
 
249
                                          0, 0, x, y, tw, th);
 
250
#endif
 
251
 
 
252
    /* draw bullet */
 
253
    RrMinSize(normal, &tw, &th);
 
254
    bullet->surface.parent = background;
 
255
    bullet->surface.parentx = bw - th;
 
256
    bullet->surface.parenty = PADDING;
 
257
    theme_pixmap_paint(bullet, th, th);
 
258
#if GTK_CHECK_VERSION(3, 0, 0)
 
259
    surface = cairo_xlib_surface_create(dpy,
 
260
                                                   bullet->pixmap,
 
261
                                                   DefaultVisual(dpy, 0),
 
262
                                                   width - theme->mbwidth - th,
 
263
                                                   y);
 
264
 
 
265
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
266
                                        0,
 
267
                                        0,
 
268
                                        th,
 
269
                                        th);
 
270
 
 
271
   cairo_surface_destroy(surface);
 
272
 
 
273
#else
 
274
    pixmap = gdk_pixmap_foreign_new(bullet->pixmap);
 
275
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
276
                                          gdk_colormap_get_system(),
 
277
                                          0, 0, width - theme->mbwidth - th, y,
 
278
                                          th, th);
 
279
#endif
 
280
    y += th + 2*PADDING;
 
281
 
 
282
    /* draw background for disabled entry */
 
283
    background->surface.parenty = bh;
 
284
    theme_pixmap_paint(background, bw, bh);
 
285
#if GTK_CHECK_VERSION(3, 0, 0)
 
286
    surface = cairo_xlib_surface_create(dpy,
 
287
                                                   background->pixmap,
 
288
                                                   DefaultVisual(dpy, 0),
 
289
                                                   x - PADDING,
 
290
                                                   y - PADDING);
 
291
 
 
292
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
293
                                        0,
 
294
                                        0,
 
295
                                        bw,
 
296
                                        bh);
 
297
 
 
298
   cairo_surface_destroy(surface);
 
299
 
 
300
#else
 
301
    pixmap = gdk_pixmap_foreign_new(background->pixmap);
 
302
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
303
                                          gdk_colormap_get_system(),
 
304
                                          0, 0, x - PADDING, y - PADDING,
 
305
                                          bw, bh);
 
306
#endif
 
307
    /* draw disabled entry */
 
308
    RrMinSize(disabled, &tw, &th);
 
309
    disabled->surface.parent = background;
 
310
    disabled->surface.parentx = PADDING;
 
311
    disabled->surface.parenty = PADDING;
 
312
    theme_pixmap_paint(disabled, tw, th);
 
313
#if GTK_CHECK_VERSION(3, 0, 0)
 
314
    surface = cairo_xlib_surface_create(dpy,
 
315
                                                   disabled->pixmap,
 
316
                                                   DefaultVisual(dpy, 0),
 
317
                                                   x,
 
318
                                                   y);
 
319
 
 
320
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
321
                                        0,
 
322
                                        0,
 
323
                                        tw,
 
324
                                        th);
 
325
 
 
326
   cairo_surface_destroy(surface);
 
327
 
 
328
#else
 
329
    pixmap = gdk_pixmap_foreign_new(disabled->pixmap);
 
330
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
331
                                          gdk_colormap_get_system(),
 
332
                                          0, 0, x, y, tw, th);
 
333
#endif
 
334
    y += th + 2*PADDING;
 
335
 
 
336
    /* draw background for selected entry */
 
337
    background = theme->a_menu_selected;
 
338
    background->surface.parent = menu;
 
339
    background->surface.parentx = 2*bh;
 
340
 
 
341
    theme_pixmap_paint(background, bw, bh);
 
342
#if GTK_CHECK_VERSION(3, 0, 0)
 
343
    surface = cairo_xlib_surface_create(dpy,
 
344
                                                   background->pixmap,
 
345
                                                   DefaultVisual(dpy, 0),
 
346
                                                   x - PADDING,
 
347
                                                   y - PADDING);
 
348
 
 
349
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
350
                                        0,
 
351
                                        0,
 
352
                                        bw,
 
353
                                        bh);
 
354
 
 
355
   cairo_surface_destroy(surface);
 
356
 
 
357
#else
 
358
    pixmap = gdk_pixmap_foreign_new(background->pixmap);
 
359
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
360
                                          gdk_colormap_get_system(),
 
361
                                          0, 0, x - PADDING, y - PADDING,
 
362
                                          bw, bh);
 
363
#endif
 
364
 
 
365
    /* draw selected entry */
 
366
    RrMinSize(selected, &tw, &th);
 
367
    selected->surface.parent = background;
 
368
    selected->surface.parentx = PADDING;
 
369
    selected->surface.parenty = PADDING;
 
370
    theme_pixmap_paint(selected, tw, th);
 
371
#if GTK_CHECK_VERSION(3, 0, 0)
 
372
    surface = cairo_xlib_surface_create(dpy,
 
373
                                                   selected->pixmap,
 
374
                                                   DefaultVisual(dpy, 0),
 
375
                                                   x,
 
376
                                                   y);
 
377
 
 
378
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
379
                                        0,
 
380
                                        0,
 
381
                                        tw,
 
382
                                        th);
 
383
 
 
384
   cairo_surface_destroy(surface);
 
385
 
 
386
#else
 
387
    pixmap = gdk_pixmap_foreign_new(selected->pixmap);
 
388
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
389
                                          gdk_colormap_get_system(),
 
390
                                          0, 0, x, y, tw, th);
 
391
#endif
 
392
    return pixbuf;
 
393
}
 
394
 
 
395
static GdkPixbuf* preview_window(RrTheme *theme, const gchar *titlelayout,
 
396
                                 gboolean focus, gint width, gint height)
 
397
{
 
398
    RrAppearance *title;
 
399
    RrAppearance *handle;
 
400
    RrAppearance *a;
 
401
#if GTK_CHECK_VERSION(3, 0, 0)
 
402
    cairo_surface_t *surface;
 
403
    Display *dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
 
404
#else
 
405
    GdkPixmap *pixmap;
 
406
#endif
 
407
    GdkPixbuf *pixbuf = NULL;
 
408
    GdkPixbuf *scratch;
 
409
 
 
410
    gint w, label_w, h, x, y;
 
411
 
 
412
    const gchar *layout;
 
413
 
 
414
    title = focus ? theme->a_focused_title : theme->a_unfocused_title;
 
415
 
 
416
    /* set border */
 
417
    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
 
418
    gdk_pixbuf_fill(pixbuf,
 
419
                    rr_color_pixel(focus ?
 
420
                                   theme->frame_focused_border_color :
 
421
                                   theme->frame_unfocused_border_color));
 
422
 
 
423
    /* title */
 
424
    w = width - 2*theme->fbwidth;
 
425
    h = theme->title_height;
 
426
    theme_pixmap_paint(title, w, h);
 
427
 
 
428
    x = y = theme->fbwidth;
 
429
#if GTK_CHECK_VERSION(3, 0, 0)
 
430
    surface = cairo_xlib_surface_create(dpy,
 
431
                                                   title->pixmap,
 
432
                                                   DefaultVisual(dpy, 0),
 
433
                                                   x,
 
434
                                                   y);
 
435
 
 
436
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
437
                                        0,
 
438
                                        0,
 
439
                                        w,
 
440
                                        h);
 
441
 
 
442
   cairo_surface_destroy(surface);
 
443
 
 
444
#else
 
445
    pixmap = gdk_pixmap_foreign_new(title->pixmap);
 
446
    pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
447
                                          gdk_colormap_get_system(),
 
448
                                          0, 0, x, y, w, h);
 
449
#endif
 
450
    /* calculate label width */
 
451
    label_w = width - (theme->paddingx + theme->fbwidth + 1) * 2;
 
452
 
 
453
    for (layout = titlelayout; *layout; layout++) {
 
454
        switch (*layout) {
 
455
        case 'N':
 
456
            label_w -= theme->button_size + 2 + theme->paddingx + 1;
 
457
            break;
 
458
        case 'D':
 
459
        case 'S':
 
460
        case 'I':
 
461
        case 'M':
 
462
        case 'C':
 
463
            label_w -= theme->button_size + theme->paddingx + 1;
 
464
            break;
 
465
        default:
 
466
            break;
 
467
        }
 
468
    }
 
469
 
 
470
    x = theme->paddingx + theme->fbwidth + 1;
 
471
    y += theme->paddingy;
 
472
    for (layout = titlelayout; *layout; layout++) {
 
473
        /* icon */
 
474
        if (*layout == 'N') {
 
475
            a = theme->a_icon;
 
476
            /* set default icon */
 
477
            a->texture[0].type = RR_TEXTURE_RGBA;
 
478
            a->texture[0].data.rgba.width = 48;
 
479
            a->texture[0].data.rgba.height = 48;
 
480
            a->texture[0].data.rgba.alpha = 0xff;
 
481
            a->texture[0].data.rgba.data = theme->def_win_icon;
 
482
 
 
483
            a->surface.parent = title;
 
484
            a->surface.parentx = x - theme->fbwidth;
 
485
            a->surface.parenty = theme->paddingy;
 
486
 
 
487
            w = h = theme->button_size + 2;
 
488
 
 
489
            theme_pixmap_paint(a, w, h);
 
490
#if GTK_CHECK_VERSION(3, 0, 0)
 
491
    surface = cairo_xlib_surface_create(dpy,
 
492
                                                   a->pixmap,
 
493
                                                   DefaultVisual(dpy, 0),
 
494
                                                   x,
 
495
                                                   y);
 
496
 
 
497
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
498
                                        0,
 
499
                                        0,
 
500
                                        w,
 
501
                                        h);
 
502
 
 
503
   cairo_surface_destroy(surface);
 
504
 
 
505
#else
 
506
            pixmap = gdk_pixmap_foreign_new(a->pixmap);
 
507
            pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
508
                                                  gdk_colormap_get_system(),
 
509
                                                  0, 0, x, y, w, h);
 
510
#endif
 
511
 
 
512
            x += theme->button_size + 2 + theme->paddingx + 1;
 
513
        } else if (*layout == 'L') { /* label */
 
514
            a = focus ? theme->a_focused_label : theme->a_unfocused_label;
 
515
            a->texture[0].data.text.string = focus ? "Active" : "Inactive";
 
516
 
 
517
            a->surface.parent = title;
 
518
            a->surface.parentx = x - theme->fbwidth;
 
519
            a->surface.parenty = theme->paddingy;
 
520
            w = label_w;
 
521
            h = theme->label_height;
 
522
 
 
523
            theme_pixmap_paint(a, w, h);
 
524
#if GTK_CHECK_VERSION(3, 0, 0)
 
525
    surface = cairo_xlib_surface_create(dpy,
 
526
                                                   a->pixmap,
 
527
                                                   DefaultVisual(dpy, 0),
 
528
                                                   x,
 
529
                                                   y);
 
530
 
 
531
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
532
                                        0,
 
533
                                        0,
 
534
                                        w,
 
535
                                        h);
 
536
 
 
537
   cairo_surface_destroy(surface);
 
538
 
 
539
#else
 
540
            pixmap = gdk_pixmap_foreign_new(a->pixmap);
 
541
            pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
542
                                                  gdk_colormap_get_system(),
 
543
                                                  0, 0, x, y, w, h);
 
544
#endif
 
545
 
 
546
            x += w + theme->paddingx + 1;
 
547
        } else {
 
548
            /* buttons */
 
549
            switch (*layout) {
 
550
            case 'D':
 
551
                a = focus ?
 
552
                    theme->a_focused_unpressed_desk :
 
553
                    theme->a_unfocused_unpressed_desk;
 
554
                break;
 
555
            case 'S':
 
556
                a = focus ?
 
557
                    theme->a_focused_unpressed_shade :
 
558
                    theme->a_unfocused_unpressed_shade;
 
559
                break;
 
560
            case 'I':
 
561
                a = focus ?
 
562
                    theme->a_focused_unpressed_iconify :
 
563
                    theme->a_unfocused_unpressed_iconify;
 
564
                break;
 
565
            case 'M':
 
566
                a = focus ?
 
567
                    theme->a_focused_unpressed_max :
 
568
                    theme->a_unfocused_unpressed_max;
 
569
                break;
 
570
            case 'C':
 
571
                a = focus ?
 
572
                    theme->a_focused_unpressed_close :
 
573
                    theme->a_unfocused_unpressed_close;
 
574
                break;
 
575
            default:
 
576
                continue;
 
577
            }
 
578
 
 
579
            a->surface.parent = title;
 
580
            a->surface.parentx = x - theme->fbwidth;
 
581
            a->surface.parenty = theme->paddingy + 1;
 
582
 
 
583
            w = theme->button_size;
 
584
            h = theme->button_size;
 
585
 
 
586
            theme_pixmap_paint(a, w, h);
 
587
#if GTK_CHECK_VERSION(3, 0, 0)
 
588
    surface = cairo_xlib_surface_create(dpy,
 
589
                                                   a->pixmap,
 
590
                                                   DefaultVisual(dpy, 0),
 
591
                                                   x,
 
592
                                                   y + 1);
 
593
 
 
594
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
595
                                        0,
 
596
                                        0,
 
597
                                        w,
 
598
                                        h);
 
599
 
 
600
   cairo_surface_destroy(surface);
 
601
 
 
602
#else
 
603
            pixmap = gdk_pixmap_foreign_new(a->pixmap);
 
604
            /* use y + 1 because these buttons should be centered wrt the label
 
605
             */
 
606
            pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
607
                                                  gdk_colormap_get_system(),
 
608
                                                  0, 0, x, y + 1, w, h);
 
609
#endif
 
610
 
 
611
            x += theme->button_size + theme->paddingx + 1;
 
612
        }
 
613
    }
 
614
 
 
615
    if (theme->handle_height) {
 
616
        /* handle */
 
617
        handle = focus ? theme->a_focused_handle : theme->a_unfocused_handle;
 
618
        x = 2*theme->fbwidth + theme->grip_width;
 
619
        y = height - theme->fbwidth - theme->handle_height;
 
620
        w = width - 4*theme->fbwidth - 2*theme->grip_width;
 
621
        h = theme->handle_height;
 
622
 
 
623
        theme_pixmap_paint(handle, w, h);
 
624
#if GTK_CHECK_VERSION(3, 0, 0)
 
625
    surface = cairo_xlib_surface_create(dpy,
 
626
                                                   handle->pixmap,
 
627
                                                   DefaultVisual(dpy, 0),
 
628
                                                   x,
 
629
                                                   y);
 
630
 
 
631
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
632
                                        0,
 
633
                                        0,
 
634
                                        w,
 
635
                                        h);
 
636
 
 
637
   cairo_surface_destroy(surface);
 
638
 
 
639
#else
 
640
        pixmap = gdk_pixmap_foreign_new(handle->pixmap);
 
641
        pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
642
                                              gdk_colormap_get_system(),
 
643
                                              0, 0, x, y, w, h);
 
644
#endif
 
645
 
 
646
        /* openbox handles this drawing stuff differently (it fills the bottom
 
647
         * of the window with the handle), so it avoids this bug where
 
648
         * parentrelative grips are not fully filled. i'm avoiding it slightly
 
649
         * differently. */
 
650
 
 
651
        theme_pixmap_paint(handle, width, h);
 
652
 
 
653
        /* grips */
 
654
        a = focus ? theme->a_focused_grip : theme->a_unfocused_grip;
 
655
        a->surface.parent = handle;
 
656
 
 
657
        x = theme->fbwidth;
 
658
        /* same y and h as handle */
 
659
        w = theme->grip_width;
 
660
 
 
661
        theme_pixmap_paint(a, w, h);
 
662
#if GTK_CHECK_VERSION(3, 0, 0)
 
663
    surface = cairo_xlib_surface_create(dpy,
 
664
                                                   a->pixmap,
 
665
                                                   DefaultVisual(dpy, 0),
 
666
                                                   x,
 
667
                                                   y);
 
668
 
 
669
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
670
                                        0,
 
671
                                        0,
 
672
                                        w,
 
673
                                        h);
 
674
 
 
675
   cairo_surface_destroy(surface);
 
676
 
 
677
#else
 
678
        pixmap = gdk_pixmap_foreign_new(a->pixmap);
 
679
        pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
680
                                              gdk_colormap_get_system(),
 
681
                                              0, 0, x, y, w, h);
 
682
#endif
 
683
 
 
684
        /* right grip */
 
685
        x = width - theme->fbwidth - theme->grip_width;
 
686
#if GTK_CHECK_VERSION(3, 0, 0)
 
687
    surface = cairo_xlib_surface_create(dpy,
 
688
                                                   a->pixmap,
 
689
                                                   DefaultVisual(dpy, 0),
 
690
                                                   x,
 
691
                                                   y);
 
692
 
 
693
    pixbuf = gdk_pixbuf_get_from_surface(surface,
 
694
                                        0,
 
695
                                        0,
 
696
                                        w,
 
697
                                        h);
 
698
 
 
699
   cairo_surface_destroy(surface);
 
700
 
 
701
#else
 
702
        pixbuf = gdk_pixbuf_get_from_drawable(pixbuf, pixmap,
 
703
                                              gdk_colormap_get_system(),
 
704
                                              0, 0, x, y, w, h);
 
705
#endif
 
706
    }
 
707
 
 
708
    /* title separator colour */
 
709
    x = theme->fbwidth;
 
710
    y = theme->fbwidth + theme->title_height;
 
711
    w = width - 2*theme->fbwidth;
 
712
    h = theme->fbwidth;
 
713
 
 
714
    scratch = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
 
715
    gdk_pixbuf_fill(scratch, rr_color_pixel(focus ?
 
716
                                            theme->title_separator_focused_color :
 
717
                                            theme->title_separator_unfocused_color));
 
718
 
 
719
    gdk_pixbuf_copy_area(scratch, 0, 0, w, h, pixbuf, x, y);
 
720
 
 
721
    /* retarded way of adding client colour */
 
722
    x = theme->fbwidth;
 
723
    y = theme->title_height + 2*theme->fbwidth;
 
724
    w = width - 2*theme->fbwidth;
 
725
    h = height - theme->title_height - 3*theme->fbwidth -
 
726
        (theme->handle_height ? (theme->fbwidth + theme->handle_height) : 0);
 
727
 
 
728
    scratch = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
 
729
    gdk_pixbuf_fill(scratch, rr_color_pixel(focus ?
 
730
                                            theme->cb_focused_color :
 
731
                                            theme->cb_unfocused_color));
 
732
 
 
733
    gdk_pixbuf_copy_area(scratch, 0, 0, w, h, pixbuf, x, y);
 
734
 
 
735
    /* clear (no alpha!) the area where the client resides */
 
736
    gdk_pixbuf_fill(scratch, 0xffffffff);
 
737
    gdk_pixbuf_copy_area(scratch, 0, 0,
 
738
                         w - 2*theme->cbwidthx,
 
739
                         h - 2*theme->cbwidthy,
 
740
                         pixbuf,
 
741
                         x + theme->cbwidthx,
 
742
                         y + theme->cbwidthy);
 
743
 
 
744
    return pixbuf;
 
745
}
 
746
 
 
747
static gint theme_label_width(RrTheme *theme, gboolean active)
 
748
{
 
749
    RrAppearance *label;
 
750
 
 
751
    if (active) {
 
752
        label = theme->a_focused_label;
 
753
        label->texture[0].data.text.string = "Active";
 
754
    } else {
 
755
        label = theme->a_unfocused_label;
 
756
        label->texture[0].data.text.string = "Inactive";
 
757
    }
 
758
 
 
759
    return RrMinWidth(label);
 
760
}
 
761
 
 
762
static gint theme_window_min_width(RrTheme *theme, const gchar *titlelayout)
 
763
{
 
764
    gint numbuttons = strlen(titlelayout);
 
765
    gint w =  2 * theme->fbwidth + (numbuttons + 3) * (theme->paddingx + 1);
 
766
 
 
767
    if (g_strrstr(titlelayout, "L")) {
 
768
        numbuttons--;
 
769
        w += MAX(theme_label_width(theme, TRUE),
 
770
                 theme_label_width(theme, FALSE));
 
771
    }
 
772
 
 
773
    w += theme->button_size * numbuttons;
 
774
 
 
775
    return w;
 
776
}
 
777
 
 
778
GdkPixbuf *preview_theme(const gchar *name, const gchar *titlelayout,
 
779
                         RrFont *active_window_font,
 
780
                         RrFont *inactive_window_font,
 
781
                         RrFont *menu_title_font,
 
782
                         RrFont *menu_item_font,
 
783
                         RrFont *osd_active_font,
 
784
                         RrFont *osd_inactive_font)
 
785
{
 
786
 
 
787
    GdkPixbuf *preview;
 
788
    GdkPixbuf *menu;
 
789
    GdkPixbuf *window;
 
790
 
 
791
    gint window_w;
 
792
    gint menu_w;
 
793
 
 
794
    gint w, h;
 
795
 
 
796
    RrTheme *theme = RrThemeNew(rrinst, name, FALSE,
 
797
                                active_window_font, inactive_window_font,
 
798
                                menu_title_font, menu_item_font,
 
799
                                osd_active_font, osd_inactive_font);
 
800
    if (!theme)
 
801
        return NULL;
 
802
 
 
803
    menu = preview_menu(theme);
 
804
  
 
805
    window_w = theme_window_min_width(theme, titlelayout);
 
806
 
 
807
    menu_w = gdk_pixbuf_get_width(menu);
 
808
    h = gdk_pixbuf_get_height(menu);
 
809
 
 
810
    w = MAX(window_w, menu_w) + 20;
 
811
  
 
812
    /* we don't want windows disappearing on us */
 
813
    if (!window_w) window_w = menu_w;
 
814
 
 
815
    preview = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
 
816
                             w, h + 2*(theme->title_height +5) + 1);
 
817
    gdk_pixbuf_fill(preview, 0); /* clear */
 
818
 
 
819
    window = preview_window(theme, titlelayout, FALSE, window_w, h);
 
820
    gdk_pixbuf_copy_area(window, 0, 0, window_w, h, preview, 20, 0);
 
821
 
 
822
    window = preview_window(theme, titlelayout, TRUE, window_w, h);
 
823
    gdk_pixbuf_copy_area(window, 0, 0, window_w, h,
 
824
                         preview, 10, theme->title_height + 5);
 
825
 
 
826
    gdk_pixbuf_copy_area(menu, 0, 0, menu_w, h,
 
827
                         preview, 0, 2 * (theme->title_height + 5));
 
828
 
 
829
    RrThemeFree(theme);
 
830
 
 
831
    return preview;
 
832
}