10 #include "../kernel/openbox.h"
13 Visual
*render_visual
;
14 Colormap render_colormap
;
15 int render_red_offset
= 0, render_green_offset
= 0, render_blue_offset
= 0;
16 int render_red_shift
, render_green_shift
, render_blue_shift
;
18 void render_startup(void)
22 render_depth
= DefaultDepth(ob_display
, ob_screen
);
23 render_visual
= DefaultVisual(ob_display
, ob_screen
);
24 render_colormap
= DefaultColormap(ob_display
, ob_screen
);
26 if (render_depth
< 8) {
27 XVisualInfo vinfo_template
, *vinfo_return
;
28 /* search for a TrueColor Visual... if we can't find one...
29 we will use the default visual for the screen */
33 vinfo_template
.screen
= ob_screen
;
34 vinfo_template
.class = TrueColor
;
35 vinfo_return
= XGetVisualInfo(ob_display
,
36 VisualScreenMask
| VisualClassMask
,
37 &vinfo_template
, &vinfo_nitems
);
41 for (i
= 0; i
< vinfo_nitems
; ++i
) {
42 if (vinfo_return
[i
].depth
> max_depth
) {
43 if (max_depth
== 24 && vinfo_return
[i
].depth
> 24)
44 break; /* prefer 24 bit over 32 */
45 max_depth
= vinfo_return
[i
].depth
;
49 if (max_depth
< render_depth
) best
= -1;
52 render_depth
= vinfo_return
[best
].depth
;
53 render_visual
= vinfo_return
[best
].visual
;
54 render_colormap
= XCreateColormap(ob_display
, ob_root
, render_visual
,
62 void truecolor_startup(void)
64 unsigned long red_mask
, green_mask
, blue_mask
;
65 XImage
*timage
= NULL
;
67 timage
= XCreateImage(ob_display
, render_visual
, render_depth
,
68 ZPixmap
, 0, NULL
, 1, 1, 32, 0);
69 g_assert(timage
!= NULL
);
70 /* find the offsets for each color in the visual's masks */
71 red_mask
= timage
->red_mask
;
72 green_mask
= timage
->green_mask
;
73 blue_mask
= timage
->blue_mask
;
75 render_red_offset
= 0;
76 render_green_offset
= 0;
77 render_blue_offset
= 0;
79 while (! (red_mask
& 1)) { render_red_offset
++; red_mask
>>= 1; }
80 while (! (green_mask
& 1)) { render_green_offset
++; green_mask
>>= 1; }
81 while (! (blue_mask
& 1)) { render_blue_offset
++; blue_mask
>>= 1; }
83 render_red_shift
= render_green_shift
= render_blue_shift
= 8;
84 while (red_mask
) { red_mask
>>= 1; render_red_shift
--; }
85 while (green_mask
) { green_mask
>>= 1; render_green_shift
--; }
86 while (blue_mask
) { blue_mask
>>= 1; render_blue_shift
--; }
90 void x_paint(Window win
, Appearance
*l
)
92 int i
, transferred
= 0, sw
;
93 pixel32
*source
, *dest
;
97 int w
= l
->area
.width
;
98 int h
= l
->area
.height
;
100 if (w
<= 0 || h
<= 0 || x
+w
<= 0 || y
+h
<= 0) return;
102 g_assert(l
->surface
.type
== Surface_Planar
);
104 oldp
= l
->pixmap
; /* save to free after changing the visible pixmap */
105 l
->pixmap
= XCreatePixmap(ob_display
, ob_root
, x
+w
, y
+h
, render_depth
);
106 g_assert(l
->pixmap
!= None
);
108 if (l
->xftdraw
!= NULL
)
109 XftDrawDestroy(l
->xftdraw
);
110 l
->xftdraw
= XftDrawCreate(ob_display
, l
->pixmap
, render_visual
,
112 g_assert(l
->xftdraw
!= NULL
);
114 g_free(l
->surface
.data
.planar
.pixel_data
);
115 l
->surface
.data
.planar
.pixel_data
= g_new(pixel32
, w
* h
);
118 if (l
->surface
.data
.planar
.grad
== Background_ParentRelative
) {
119 sw
= l
->surface
.data
.planar
.parent
->area
.width
;
120 source
= l
->surface
.data
.planar
.parent
->surface
.data
.planar
.pixel_data
121 + l
->surface
.data
.planar
.parentx
122 + sw
* l
->surface
.data
.planar
.parenty
;
123 dest
= l
->surface
.data
.planar
.pixel_data
;
124 for (i
= 0; i
< h
; i
++, source
+= sw
, dest
+= w
) {
125 memcpy(dest
, source
, w
* sizeof(pixel32
));
128 else if (l
->surface
.data
.planar
.grad
== Background_Solid
)
129 gradient_solid(l
, x
, y
, w
, h
);
130 else gradient_render(&l
->surface
, w
, h
);
132 for (i
= 0; i
< l
->textures
; i
++) {
133 switch (l
->texture
[i
].type
) {
137 if (l
->surface
.data
.planar
.grad
!= Background_Solid
)
138 pixel32_to_pixmap(l
->surface
.data
.planar
.pixel_data
,
141 if (l
->xftdraw
== NULL
) {
142 l
->xftdraw
= XftDrawCreate(ob_display
, l
->pixmap
,
143 render_visual
, render_colormap
);
145 font_draw(l
->xftdraw
, &l
->texture
[i
].data
.text
,
146 &l
->texture
[i
].position
);
151 if (l
->surface
.data
.planar
.grad
!= Background_Solid
)
152 pixel32_to_pixmap(l
->surface
.data
.planar
.pixel_data
,
155 if (l
->texture
[i
].data
.mask
.color
->gc
== None
)
156 color_allocate_gc(l
->texture
[i
].data
.mask
.color
);
157 mask_draw(l
->pixmap
, &l
->texture
[i
].data
.mask
,
158 &l
->texture
[i
].position
);
161 image_draw(l
->surface
.data
.planar
.pixel_data
,
162 &l
->texture
[i
].data
.rgba
,
163 &l
->texture
[i
].position
);
170 if (l
->surface
.data
.planar
.grad
!= Background_Solid
)
171 pixel32_to_pixmap(l
->surface
.data
.planar
.pixel_data
, l
->pixmap
176 XSetWindowBackgroundPixmap(ob_display
, win
, l
->pixmap
);
177 XClearWindow(ob_display
, win
);
178 if (oldp
!= None
) XFreePixmap(ob_display
, oldp
);
182 void gl_paint(Window win, Appearance *l)
184 glXMakeCurrent(ob_display, win, gl_context);
188 void render_shutdown(void)
192 Appearance
*appearance_new(SurfaceType type
, int numtex
)
197 out
= g_new(Appearance
, 1);
198 out
->surface
.type
= type
;
199 out
->textures
= numtex
;
201 if (numtex
) out
->texture
= g_new0(Texture
, numtex
);
202 else out
->texture
= NULL
;
207 p
= &out
->surface
.data
.planar
;
210 p
->border_color
= NULL
;
211 p
->pixel_data
= NULL
;
217 Appearance
*appearance_copy(Appearance
*orig
)
219 PlanarSurface
*spo
, *spc
;
220 Appearance
*copy
= g_new(Appearance
, 1);
221 copy
->surface
.type
= orig
->surface
.type
;
222 switch (orig
->surface
.type
) {
224 spo
= &(orig
->surface
.data
.planar
);
225 spc
= &(copy
->surface
.data
.planar
);
226 spc
->grad
= spo
->grad
;
227 spc
->relief
= spo
->relief
;
228 spc
->bevel
= spo
->bevel
;
229 if (spo
->primary
!= NULL
)
230 spc
->primary
= color_new(spo
->primary
->r
,
233 else spc
->primary
= NULL
;
235 if (spo
->secondary
!= NULL
)
236 spc
->secondary
= color_new(spo
->secondary
->r
,
239 else spc
->secondary
= NULL
;
241 if (spo
->border_color
!= NULL
)
242 spc
->border_color
= color_new(spo
->border_color
->r
,
243 spo
->border_color
->g
,
244 spo
->border_color
->b
);
245 else spc
->border_color
= NULL
;
247 spc
->interlaced
= spo
->interlaced
;
248 spc
->border
= spo
->border
;
249 spc
->pixel_data
= NULL
;
252 copy
->textures
= orig
->textures
;
253 copy
->texture
= g_memdup(orig
->texture
, orig
->textures
* sizeof(Texture
));
255 copy
->xftdraw
= NULL
;
259 void appearance_free(Appearance
*a
)
262 if (a
->pixmap
!= None
) XFreePixmap(ob_display
, a
->pixmap
);
263 if (a
->xftdraw
!= NULL
) XftDrawDestroy(a
->xftdraw
);
266 if (a
->surface
.type
== Surface_Planar
) {
267 p
= &a
->surface
.data
.planar
;
268 if (p
->primary
!= NULL
) color_free(p
->primary
);
269 if (p
->secondary
!= NULL
) color_free(p
->secondary
);
270 if (p
->border_color
!= NULL
) color_free(p
->border_color
);
271 if (p
->pixel_data
!= NULL
) g_free(p
->pixel_data
);
277 void pixel32_to_pixmap(pixel32
*in
, Pixmap out
, int x
, int y
, int w
, int h
)
280 im
= XCreateImage(ob_display
, render_visual
, render_depth
,
281 ZPixmap
, 0, NULL
, w
, h
, 32, 0);
282 g_assert(im
!= NULL
);
283 im
->byte_order
= endian
;
284 im
->data
= (char *)in
;
285 reduce_depth((pixel32
*)im
->data
, im
);
286 XPutImage(ob_display
, out
, DefaultGC(ob_display
, ob_screen
),
287 im
, 0, 0, x
, y
, w
, h
);