]>
Dogcows Code - chaz/openbox/blob - render/render.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 render.c for the Openbox window manager
4 Copyright (c) 2003 Ben Jansens
5 Copyright (c) 2003 Derek Foreman
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.
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.
17 See the COPYING file for a copy of the GNU General Public License.
21 #include <X11/Xutil.h>
37 static void pixel_data_to_pixmap(RrAppearance
*l
,
38 gint x
, gint y
, gint w
, gint h
);
40 void RrPaint(RrAppearance
*a
, Window win
, gint w
, gint h
)
42 gint i
, transferred
= 0, sw
, sh
, partial_w
, partial_h
;
43 RrPixel32
*source
, *dest
;
45 RrRect tarea
; /* area in which to draw textures */
48 if (w
<= 0 || h
<= 0) return;
50 if (a
->surface
.parentx
< 0 || a
->surface
.parenty
< 0) {
51 /* ob_debug("Invalid parent co-ordinates\n"); */
54 resized
= (a
->w
!= w
|| a
->h
!= h
);
56 oldp
= a
->pixmap
; /* save to free after changing the visible pixmap */
57 a
->pixmap
= XCreatePixmap(RrDisplay(a
->inst
),
58 RrRootWindow(a
->inst
),
59 w
, h
, RrDepth(a
->inst
));
61 g_assert(a
->pixmap
!= None
);
65 if (a
->xftdraw
!= NULL
)
66 XftDrawDestroy(a
->xftdraw
);
67 a
->xftdraw
= XftDrawCreate(RrDisplay(a
->inst
), a
->pixmap
,
68 RrVisual(a
->inst
), RrColormap(a
->inst
));
69 g_assert(a
->xftdraw
!= NULL
);
71 g_free(a
->surface
.pixel_data
);
72 a
->surface
.pixel_data
= g_new(RrPixel32
, w
* h
);
74 if (a
->surface
.grad
== RR_SURFACE_PARENTREL
) {
75 g_assert (a
->surface
.parent
);
76 g_assert (a
->surface
.parent
->w
);
78 sw
= a
->surface
.parent
->w
;
79 sh
= a
->surface
.parent
->h
;
81 if (a
->surface
.parentx
>= sw
|| a
->surface
.parenty
>= sh
) {
85 source
= (a
->surface
.parent
->surface
.pixel_data
+
86 a
->surface
.parentx
+ sw
* a
->surface
.parenty
);
87 dest
= a
->surface
.pixel_data
;
89 if (a
->surface
.parentx
+ w
> sw
) {
90 partial_w
= sw
- a
->surface
.parentx
;
93 if (a
->surface
.parenty
+ h
> sh
) {
94 partial_h
= sh
- a
->surface
.parenty
;
97 for (i
= 0; i
< partial_h
; i
++, source
+= sw
, dest
+= w
) {
98 memcpy(dest
, source
, partial_w
* sizeof(RrPixel32
));
105 RrMargins(a
, &l
, &t
, &r
, &b
);
106 RECT_SET(tarea
, l
, t
, w
- l
- r
, h
- t
- b
);
109 for (i
= 0; i
< a
->textures
; i
++) {
110 switch (a
->texture
[i
].type
) {
111 case RR_TEXTURE_NONE
:
113 case RR_TEXTURE_TEXT
:
116 if (a
->surface
.grad
!= RR_SURFACE_SOLID
)
117 pixel_data_to_pixmap(a
, 0, 0, w
, h
);
119 if (a
->xftdraw
== NULL
) {
120 a
->xftdraw
= XftDrawCreate(RrDisplay(a
->inst
), a
->pixmap
,
122 RrColormap(a
->inst
));
124 RrFontDraw(a
->xftdraw
, &a
->texture
[i
].data
.text
, &tarea
);
126 case RR_TEXTURE_LINE_ART
:
129 if (a
->surface
.grad
!= RR_SURFACE_SOLID
)
130 pixel_data_to_pixmap(a
, 0, 0, w
, h
);
132 XDrawLine(RrDisplay(a
->inst
), a
->pixmap
,
133 RrColorGC(a
->texture
[i
].data
.lineart
.color
),
134 a
->texture
[i
].data
.lineart
.x1
,
135 a
->texture
[i
].data
.lineart
.y1
,
136 a
->texture
[i
].data
.lineart
.x2
,
137 a
->texture
[i
].data
.lineart
.y2
);
139 case RR_TEXTURE_MASK
:
142 if (a
->surface
.grad
!= RR_SURFACE_SOLID
)
143 pixel_data_to_pixmap(a
, 0, 0, w
, h
);
145 RrPixmapMaskDraw(a
->pixmap
, &a
->texture
[i
].data
.mask
, &tarea
);
147 case RR_TEXTURE_RGBA
:
148 g_assert(!transferred
);
149 RrImageDraw(a
->surface
.pixel_data
,
150 &a
->texture
[i
].data
.rgba
,
159 if (a
->surface
.grad
!= RR_SURFACE_SOLID
)
160 pixel_data_to_pixmap(a
, 0, 0, w
, h
);
163 XSetWindowBackgroundPixmap(RrDisplay(a
->inst
), win
, a
->pixmap
);
164 XClearWindow(RrDisplay(a
->inst
), win
);
165 if (oldp
) XFreePixmap(RrDisplay(a
->inst
), oldp
);
168 RrAppearance
*RrAppearanceNew(const RrInstance
*inst
, gint numtex
)
172 out
= g_new0(RrAppearance
, 1);
174 out
->textures
= numtex
;
175 if (numtex
) out
->texture
= g_new0(RrTexture
, numtex
);
180 RrAppearance
*RrAppearanceCopy(RrAppearance
*orig
)
182 RrSurface
*spo
, *spc
;
183 RrAppearance
*copy
= g_new(RrAppearance
, 1);
186 copy
->inst
= orig
->inst
;
188 spo
= &(orig
->surface
);
189 spc
= &(copy
->surface
);
190 spc
->grad
= spo
->grad
;
191 spc
->relief
= spo
->relief
;
192 spc
->bevel
= spo
->bevel
;
193 if (spo
->primary
!= NULL
)
194 spc
->primary
= RrColorNew(copy
->inst
,
198 else spc
->primary
= NULL
;
200 if (spo
->secondary
!= NULL
)
201 spc
->secondary
= RrColorNew(copy
->inst
,
205 else spc
->secondary
= NULL
;
207 if (spo
->border_color
!= NULL
)
208 spc
->border_color
= RrColorNew(copy
->inst
,
209 spo
->border_color
->r
,
210 spo
->border_color
->g
,
211 spo
->border_color
->b
);
212 else spc
->border_color
= NULL
;
214 if (spo
->interlace_color
!= NULL
)
215 spc
->interlace_color
= RrColorNew(copy
->inst
,
216 spo
->interlace_color
->r
,
217 spo
->interlace_color
->g
,
218 spo
->interlace_color
->b
);
219 else spc
->interlace_color
= NULL
;
221 if (spo
->bevel_dark
!= NULL
)
222 spc
->bevel_dark
= RrColorNew(copy
->inst
,
226 else spc
->bevel_dark
= NULL
;
228 if (spo
->bevel_light
!= NULL
)
229 spc
->bevel_light
= RrColorNew(copy
->inst
,
232 spo
->bevel_light
->b
);
233 else spc
->bevel_light
= NULL
;
235 spc
->interlaced
= spo
->interlaced
;
236 spc
->border
= spo
->border
;
238 spc
->parentx
= spc
->parenty
= 0;
239 spc
->pixel_data
= NULL
;
241 copy
->textures
= orig
->textures
;
242 copy
->texture
= g_memdup(orig
->texture
,
243 orig
->textures
* sizeof(RrTexture
));
244 for (i
= 0; i
< copy
->textures
; ++i
)
245 if (copy
->texture
[i
].type
== RR_TEXTURE_RGBA
) {
246 copy
->texture
[i
].data
.rgba
.cache
= NULL
;
249 copy
->xftdraw
= NULL
;
250 copy
->w
= copy
->h
= 0;
254 void RrAppearanceFree(RrAppearance
*a
)
260 if (a
->pixmap
!= None
) XFreePixmap(RrDisplay(a
->inst
), a
->pixmap
);
261 if (a
->xftdraw
!= NULL
) XftDrawDestroy(a
->xftdraw
);
262 for (i
= 0; i
< a
->textures
; ++i
)
263 if (a
->texture
[i
].type
== RR_TEXTURE_RGBA
) {
264 g_free(a
->texture
[i
].data
.rgba
.cache
);
265 a
->texture
[i
].data
.rgba
.cache
= NULL
;
270 RrColorFree(p
->primary
);
271 RrColorFree(p
->secondary
);
272 RrColorFree(p
->border_color
);
273 RrColorFree(p
->interlace_color
);
274 RrColorFree(p
->bevel_dark
);
275 RrColorFree(p
->bevel_light
);
276 g_free(p
->pixel_data
);
277 p
->pixel_data
= NULL
;
283 static void pixel_data_to_pixmap(RrAppearance
*l
,
284 gint x
, gint y
, gint w
, gint h
)
286 RrPixel32
*in
, *scratch
;
289 im
= XCreateImage(RrDisplay(l
->inst
), RrVisual(l
->inst
), RrDepth(l
->inst
),
290 ZPixmap
, 0, NULL
, w
, h
, 32, 0);
291 g_assert(im
!= NULL
);
293 in
= l
->surface
.pixel_data
;
296 /* this malloc is a complete waste of time on normal 32bpp
297 as reduce_depth just sets im->data = data and returns
299 scratch
= g_new(RrPixel32
, im
->width
* im
->height
);
300 im
->data
= (gchar
*) scratch
;
301 RrReduceDepth(l
->inst
, in
, im
);
302 XPutImage(RrDisplay(l
->inst
), out
,
303 DefaultGC(RrDisplay(l
->inst
), RrScreen(l
->inst
)),
304 im
, 0, 0, x
, y
, w
, h
);
310 void RrMargins (RrAppearance
*a
, gint
*l
, gint
*t
, gint
*r
, gint
*b
)
312 *l
= *t
= *r
= *b
= 0;
314 if (a
->surface
.grad
!= RR_SURFACE_PARENTREL
) {
315 if (a
->surface
.relief
!= RR_RELIEF_FLAT
) {
316 switch (a
->surface
.bevel
) {
318 *l
= *t
= *r
= *b
= 1;
321 *l
= *t
= *r
= *b
= 2;
324 } else if (a
->surface
.border
) {
325 *l
= *t
= *r
= *b
= 1;
330 void RrMinsize(RrAppearance
*a
, gint
*w
, gint
*h
)
337 for (i
= 0; i
< a
->textures
; ++i
) {
338 switch (a
->texture
[i
].type
) {
339 case RR_TEXTURE_NONE
:
341 case RR_TEXTURE_MASK
:
342 *w
= MAX(*w
, a
->texture
[i
].data
.mask
.mask
->width
);
343 *h
= MAX(*h
, a
->texture
[i
].data
.mask
.mask
->height
);
345 case RR_TEXTURE_TEXT
:
346 m
= RrFontMeasureString(a
->texture
[i
].data
.text
.font
,
347 a
->texture
[i
].data
.text
.string
);
348 *w
= MAX(*w
, m
->width
+ 4);
349 m
->height
= RrFontHeight(a
->texture
[i
].data
.text
.font
);
350 *h
+= MAX(*h
, m
->height
);
353 case RR_TEXTURE_RGBA
:
354 *w
+= MAX(*w
, a
->texture
[i
].data
.rgba
.width
);
355 *h
+= MAX(*h
, a
->texture
[i
].data
.rgba
.height
);
357 case RR_TEXTURE_LINE_ART
:
358 *w
+= MAX(*w
, MAX(a
->texture
[i
].data
.lineart
.x1
,
359 a
->texture
[i
].data
.lineart
.x2
));
360 *h
+= MAX(*h
, MAX(a
->texture
[i
].data
.lineart
.y1
,
361 a
->texture
[i
].data
.lineart
.y2
));
366 RrMargins(a
, &l
, &t
, &r
, &b
);
375 static void reverse_bits(gchar
*c
, gint n
)
378 for (i
= 0; i
< n
; i
++, *c
++)
379 *c
= (((*c
* 0x0802UL
& 0x22110UL
) |
380 (*c
* 0x8020UL
& 0x88440UL
)) * 0x10101UL
) >> 16;
383 gboolean
RrPixmapToRGBA(const RrInstance
*inst
,
384 Pixmap pmap
, Pixmap mask
,
385 gint
*w
, gint
*h
, RrPixel32
**data
)
389 guint pw
, ph
, mw
, mh
, xb
, xd
, i
, x
, y
, di
;
390 XImage
*xi
, *xm
= NULL
;
392 if (!XGetGeometry(RrDisplay(inst
), pmap
,
393 &xr
, &xx
, &xy
, &pw
, &ph
, &xb
, &xd
))
397 if (!XGetGeometry(RrDisplay(inst
), mask
,
398 &xr
, &xx
, &xy
, &mw
, &mh
, &xb
, &xd
))
400 if (pw
!= mw
|| ph
!= mh
|| xd
!= 1)
404 xi
= XGetImage(RrDisplay(inst
), pmap
,
405 0, 0, pw
, ph
, 0xffffffff, ZPixmap
);
410 xm
= XGetImage(RrDisplay(inst
), mask
,
411 0, 0, mw
, mh
, 0xffffffff, ZPixmap
);
416 if ((xm
->bits_per_pixel
== 1) && (xm
->bitmap_bit_order
!= LSBFirst
))
417 reverse_bits(xm
->data
, xm
->bytes_per_line
* xm
->height
);
420 if ((xi
->bits_per_pixel
== 1) && (xi
->bitmap_bit_order
!= LSBFirst
))
421 reverse_bits(xi
->data
, xi
->bytes_per_line
* xi
->height
);
423 *data
= g_new(RrPixel32
, pw
* ph
);
424 RrIncreaseDepth(inst
, *data
, xi
);
427 /* apply transparency from the mask */
429 for (i
= 0, y
= 0; y
< ph
; ++y
) {
430 for (x
= 0; x
< pw
; ++x
, ++i
) {
431 if (!((((unsigned)xm
->data
[di
+ x
/ 8]) >> (x
% 8)) & 0x1))
432 (*data
)[i
] &= ~(0xff << RrDefaultAlphaOffset
);
434 di
+= xm
->bytes_per_line
;
This page took 0.059709 seconds and 4 git commands to generate.