]>
Dogcows Code - chaz/openbox/blob - otk/rendercontrol.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "rendercontrol.hh"
6 #include "truerendercontrol.hh"
7 #include "pseudorendercontrol.hh"
8 #include "rendertexture.hh"
9 #include "rendercolor.hh"
10 #include "renderstyle.hh"
12 #include "screeninfo.hh"
16 #include "property.hh"
19 #ifdef HAVE_SYS_WAIT_H
20 # include <sys/wait.h>
21 #endif // HAVE_SYS_WAIT_H
25 #endif // HAVE_UNISTD_H
27 #include "../src/gettext.h"
28 #define _(str) gettext(str)
35 RenderControl
*RenderControl::createRenderControl(int screen
)
37 // get the visual on the screen and return the correct type of RenderControl
38 int vclass
= display
->screenInfo(screen
)->visual()->c_class
;
41 return new TrueRenderControl(screen
);
44 return new PseudoRenderControl(screen
);
47 return new PseudoRenderControl(screen
);
49 printf(_("RenderControl: Unsupported visual %d specified. Aborting.\n"),
55 RenderControl::RenderControl(int screen
)
59 printf("Initializing RenderControl\n");
63 RenderControl::~RenderControl()
65 printf("Destroying RenderControl\n");
68 void RenderControl::drawString(Surface
& sf
, const Font
&font
, int x
, int y
,
69 const RenderColor
&color
,
70 const ustring
&string
) const
72 assert(sf
._screen
== _screen
);
73 XftDraw
*d
= sf
._xftdraw
;
74 assert(d
); // this means that the background hasn't been rendered yet!
81 c
.color
.alpha
= font
._tint
| font
._tint
<< 8; // transparent shadow
82 c
.pixel
= BlackPixel(**display
, _screen
);
85 XftDrawStringUtf8(d
, &c
, font
._xftfont
, x
+ font
._offset
,
86 font
._xftfont
->ascent
+ y
+ font
._offset
,
87 (FcChar8
*)string
.c_str(), string
.bytes());
89 XftDrawString8(d
, &c
, font
._xftfont
, x
+ font
._offset
,
90 font
._xftfont
->ascent
+ y
+ font
._offset
,
91 (FcChar8
*)string
.c_str(), string
.bytes());
95 c
.color
.red
= color
.red() | color
.red() << 8;
96 c
.color
.green
= color
.green() | color
.green() << 8;
97 c
.color
.blue
= color
.blue() | color
.blue() << 8;
98 c
.pixel
= color
.pixel();
99 c
.color
.alpha
= 0xff | 0xff << 8; // no transparency in Color yet
102 XftDrawStringUtf8(d
, &c
, font
._xftfont
, x
, font
._xftfont
->ascent
+ y
,
103 (FcChar8
*)string
.c_str(), string
.bytes());
105 XftDrawString8(d
, &c
, font
._xftfont
, x
, font
._xftfont
->ascent
+ y
,
106 (FcChar8
*)string
.c_str(), string
.bytes());
110 void RenderControl::drawSolidBackground(Surface
& sf
,
111 const RenderTexture
& texture
) const
113 assert(_screen
== sf
._screen
);
114 assert(_screen
== texture
.color().screen());
116 if (texture
.parentRelative()) return;
118 sf
.setPixmap(texture
.color());
120 int width
= sf
.size().width(), height
= sf
.size().height();
121 int left
= 0, top
= 0, right
= width
- 1, bottom
= height
- 1;
123 if (texture
.interlaced())
124 for (int i
= 0; i
< height
; i
+= 2)
125 XDrawLine(**display
, sf
.pixmap(), texture
.interlaceColor().gc(),
128 switch (texture
.relief()) {
129 case RenderTexture::Raised
:
130 switch (texture
.bevel()) {
131 case RenderTexture::Bevel1
:
132 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
133 left
, bottom
, right
, bottom
);
134 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
135 right
, bottom
, right
, top
);
137 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
138 left
, top
, right
, top
);
139 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
140 left
, bottom
, left
, top
);
142 case RenderTexture::Bevel2
:
143 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
144 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
145 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
146 right
- 2, bottom
- 2, right
- 2, top
+ 1);
148 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
149 left
+ 1, top
+ 1, right
- 2, top
+ 1);
150 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
151 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
154 assert(false); // unhandled RenderTexture::BevelType
157 case RenderTexture::Sunken
:
158 switch (texture
.bevel()) {
159 case RenderTexture::Bevel1
:
160 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
161 left
, bottom
, right
, bottom
);
162 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
163 right
, bottom
, right
, top
);
165 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
166 left
, top
, right
, top
);
167 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
168 left
, bottom
, left
, top
);
170 case RenderTexture::Bevel2
:
171 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
172 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
173 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
174 right
- 2, bottom
- 2, right
- 2, top
+ 1);
176 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
177 left
+ 1, top
+ 1, right
- 2, top
+ 1);
178 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
179 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
182 assert(false); // unhandled RenderTexture::BevelType
185 case RenderTexture::Flat
:
186 if (texture
.border())
187 XDrawRectangle(**display
, sf
.pixmap(), texture
.borderColor().gc(),
188 left
, top
, right
, bottom
);
191 assert(false); // unhandled RenderTexture::ReliefType
195 void RenderControl::drawMask(Surface
&sf
, const RenderColor
&color
,
196 const PixmapMask
&mask
) const
198 assert(_screen
== sf
._screen
);
199 assert(_screen
== color
.screen());
201 if (mask
.mask
== None
) return; // no mask given
203 int width
= sf
.size().width(), height
= sf
.size().height();
205 // set the clip region
206 int x
= (width
- mask
.w
) / 2, y
= (height
- mask
.h
) / 2;
207 XSetClipMask(**display
, color
.gc(), mask
.mask
);
208 XSetClipOrigin(**display
, color
.gc(), x
, y
);
210 // fill in the clipped region
211 XFillRectangle(**display
, sf
.pixmap(), color
.gc(), x
, y
,
212 x
+ mask
.w
, y
+ mask
.h
);
214 // unset the clip region
215 XSetClipMask(**display
, color
.gc(), None
);
216 XSetClipOrigin(**display
, color
.gc(), 0, 0);
219 void RenderControl::drawGradientBackground(
220 Surface
&sf
, const RenderTexture
&texture
) const
223 int w
= sf
.size().width(), h
= sf
.size().height();
226 const ScreenInfo
*info
= display
->screenInfo(_screen
);
227 XImage
*im
= XCreateImage(**display
, info
->visual(), info
->depth(),
228 ZPixmap
, 0, NULL
, w
, h
, 32, 0);
229 im
->byte_order
= endian
;
231 switch (texture
.gradient()) {
232 case RenderTexture::Vertical
:
233 verticalGradient(sf
, texture
);
235 case RenderTexture::Horizontal
:
236 horizontalGradient(sf
, texture
);
238 case RenderTexture::Diagonal
:
239 diagonalGradient(sf
, texture
);
241 case RenderTexture::CrossDiagonal
:
242 crossDiagonalGradient(sf
, texture
);
245 printf("unhandled gradient\n");
248 pixel32
*data
= sf
.pixelData();
251 if (texture
.relief() == RenderTexture::Flat
&& texture
.border()) {
252 r
= texture
.borderColor().red();
253 g
= texture
.borderColor().green();
254 b
= texture
.borderColor().blue();
255 current
= (r
<< default_red_shift
)
256 + (g
<< default_green_shift
)
257 + (b
<< default_blue_shift
);
258 for (off
= 0, x
= 0; x
< w
; ++x
, off
++) {
259 *(data
+ off
) = current
;
260 *(data
+ off
+ ((h
-1) * w
)) = current
;
262 for (off
= 0, x
= 0; x
< h
; ++x
, off
++) {
263 *(data
+ (off
* w
)) = current
;
264 *(data
+ (off
* w
) + w
- 1) = current
;
268 if (texture
.relief() != RenderTexture::Flat
) {
269 if (texture
.bevel() == RenderTexture::Bevel1
) {
270 for (off
= 1, x
= 1; x
< w
- 1; ++x
, off
++)
271 highlight(data
+ off
,
272 data
+ off
+ (h
-1) * w
,
273 texture
.relief()==RenderTexture::Raised
);
274 for (off
= 0, x
= 0; x
< h
; ++x
, off
++)
275 highlight(data
+ off
* w
,
276 data
+ off
* w
+ w
- 1,
277 texture
.relief()==RenderTexture::Raised
);
280 if (texture
.bevel() == RenderTexture::Bevel2
) {
281 for (off
= 2, x
= 2; x
< w
- 2; ++x
, off
++)
282 highlight(data
+ off
+ w
,
283 data
+ off
+ (h
-2) * w
,
284 texture
.relief()==RenderTexture::Raised
);
285 for (off
= 1, x
= 1; x
< h
-1; ++x
, off
++)
286 highlight(data
+ off
* w
+ 1,
287 data
+ off
* w
+ w
- 2,
288 texture
.relief()==RenderTexture::Raised
);
297 void RenderControl::verticalGradient(Surface
&sf
,
298 const RenderTexture
&texture
) const
300 pixel32
*data
= sf
.pixelData();
304 int w
= sf
.size().width(), h
= sf
.size().height();
306 dr
= (float)(texture
.secondary_color().red() - texture
.color().red());
309 dg
= (float)(texture
.secondary_color().green() - texture
.color().green());
312 db
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
315 for (int y
= 0; y
< h
; ++y
) {
316 r
= texture
.color().red() + (int)(dr
* y
);
317 g
= texture
.color().green() + (int)(dg
* y
);
318 b
= texture
.color().blue() + (int)(db
* y
);
319 current
= (r
<< default_red_shift
)
320 + (g
<< default_green_shift
)
321 + (b
<< default_blue_shift
);
322 for (int x
= 0; x
< w
; ++x
, ++data
)
327 void RenderControl::horizontalGradient(Surface
&sf
,
328 const RenderTexture
&texture
) const
330 pixel32
*data
= sf
.pixelData();
334 int w
= sf
.size().width(), h
= sf
.size().height();
336 dr
= (float)(texture
.secondary_color().red() - texture
.color().red());
339 dg
= (float)(texture
.secondary_color().green() - texture
.color().green());
342 db
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
345 for (int x
= 0; x
< w
; ++x
, ++data
) {
346 r
= texture
.color().red() + (int)(dr
* x
);
347 g
= texture
.color().green() + (int)(dg
* x
);
348 b
= texture
.color().blue() + (int)(db
* x
);
349 current
= (r
<< default_red_shift
)
350 + (g
<< default_green_shift
)
351 + (b
<< default_blue_shift
);
352 for (int y
= 0; y
< h
; ++y
)
353 *(data
+ y
*w
) = current
;
357 void RenderControl::diagonalGradient(Surface
&sf
,
358 const RenderTexture
&texture
) const
360 pixel32
*data
= sf
.pixelData();
362 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
364 int w
= sf
.size().width(), h
= sf
.size().height();
366 for (int y
= 0; y
< h
; ++y
) {
367 drx
= (float)(texture
.secondary_color().red() - texture
.color().red());
371 dgx
= (float)(texture
.secondary_color().green() - texture
.color().green());
375 dbx
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
378 for (int x
= 0; x
< w
; ++x
, ++data
) {
379 r
= texture
.color().red() + ((int)(drx
* x
) + (int)(dry
* y
))/2;
380 g
= texture
.color().green() + ((int)(dgx
* x
) + (int)(dgy
* y
))/2;
381 b
= texture
.color().blue() + ((int)(dbx
* x
) + (int)(dby
* y
))/2;
382 current
= (r
<< default_red_shift
)
383 + (g
<< default_green_shift
)
384 + (b
<< default_blue_shift
);
390 void RenderControl::crossDiagonalGradient(
391 Surface
&sf
, const RenderTexture
&texture
) const
393 pixel32
*data
= sf
.pixelData();
395 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
397 int w
= sf
.size().width(), h
= sf
.size().height();
399 for (int y
= 0; y
< h
; ++y
) {
400 drx
= (float)(texture
.secondary_color().red() - texture
.color().red());
404 dgx
= (float)(texture
.secondary_color().green() - texture
.color().green());
408 dbx
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
411 for (int x
= w
; x
> 0; --x
, ++data
) {
412 r
= texture
.color().red() + ((int)(drx
* (x
-1)) + (int)(dry
* y
))/2;
413 g
= texture
.color().green() + ((int)(dgx
* (x
-1)) + (int)(dgy
* y
))/2;
414 b
= texture
.color().blue() + ((int)(dbx
* (x
-1)) + (int)(dby
* y
))/2;
415 current
= (r
<< default_red_shift
)
416 + (g
<< default_green_shift
)
417 + (b
<< default_blue_shift
);
423 void RenderControl::highlight(pixel32
*x
, pixel32
*y
, bool raised
) const
435 r
= (*up
>> default_red_shift
) & 0xFF;
437 g
= (*up
>> default_green_shift
) & 0xFF;
439 b
= (*up
>> default_blue_shift
) & 0xFF;
441 if (r
> 255) r
= 255;
442 if (g
> 255) g
= 255;
443 if (b
> 255) b
= 255;
444 *up
= (r
<< default_red_shift
) + (g
<< default_green_shift
)
445 + (b
<< default_blue_shift
);
447 r
= (*down
>> default_red_shift
) & 0xFF;
448 r
= (r
>> 1) + (r
>> 2);
449 g
= (*down
>> default_green_shift
) & 0xFF;
450 g
= (g
>> 1) + (g
>> 2);
451 b
= (*down
>> default_blue_shift
) & 0xFF;
452 b
= (b
>> 1) + (b
>> 2);
453 *down
= (r
<< default_red_shift
) + (g
<< default_green_shift
)
454 + (b
<< default_blue_shift
);
457 void RenderControl::drawBackground(Surface
& sf
,
458 const RenderTexture
&texture
) const
460 assert(_screen
== sf
._screen
);
461 assert(_screen
== texture
.color().screen());
463 if (texture
.gradient() == RenderTexture::Solid
)
464 drawSolidBackground(sf
, texture
);
466 drawGradientBackground(sf
, texture
);
470 void RenderControl::drawImage(Surface
&sf
, int w
, int h
,
471 unsigned long *data
) const
473 pixel32
*bg
= sf
.pixelData();
475 unsigned int i
, e
, bgi
;
476 sfw
= sf
.size().width();
477 sfh
= sf
.size().height();
481 unsigned long *olddata
= data
;
482 unsigned long newdata
[sfw
*sfh
];
483 double dx
= w
/ (double)sfw
;
484 double dy
= h
/ (double)sfh
;
488 for (i
= 0, c
= 0, e
= sfw
*sfh
; i
< e
; ++i
) {
489 newdata
[i
] = olddata
[(int)px
+ iy
];
500 // apply the alpha channel
501 for (i
= 0, c
= 0, e
= sfw
*sfh
; i
< e
; ++i
, ++bgi
) {
502 unsigned char alpha
= data
[i
] >> 24;
503 unsigned char r
= data
[i
] >> 16;
504 unsigned char g
= data
[i
] >> 8;
505 unsigned char b
= data
[i
];
508 unsigned char bgr
= bg
[i
] >> default_red_shift
;
509 unsigned char bgg
= bg
[i
] >> default_green_shift
;
510 unsigned char bgb
= bg
[i
] >> default_blue_shift
;
512 r
= bgr
+ (((r
- bgr
) * alpha
) >> 8);
513 g
= bgg
+ (((g
- bgg
) * alpha
) >> 8);
514 b
= bgb
+ (((b
- bgb
) * alpha
) >> 8);
516 bg
[i
] = (r
<< default_red_shift
) | (g
<< default_green_shift
) |
517 (b
<< default_blue_shift
);
521 const ScreenInfo
*info
= display
->screenInfo(_screen
);
522 XImage
*im
= XCreateImage(**display
, info
->visual(), info
->depth(),
523 ZPixmap
, 0, NULL
, sf
.size().width(),
524 sf
.size().height(), 32, 0);
525 im
->byte_order
= endian
;
532 void RenderControl::drawImage(Surface
&sf
, Pixmap pixmap
, Pixmap mask
) const
534 int junk
, sfw
, sfh
, w
, h
, depth
, mw
, mh
, mdepth
;
536 const ScreenInfo
*info
= display
->screenInfo(_screen
);
539 assert(pixmap
!= None
);
541 sfw
= sf
.size().width();
542 sfh
= sf
.size().height();
544 XGetGeometry(**display
, pixmap
, &wjunk
, &junk
, &junk
,
545 (unsigned int*)&w
, (unsigned int*)&h
,
546 (unsigned int*)&junk
, (unsigned int*)&depth
);
548 XGetGeometry(**display
, mask
, &wjunk
, &junk
, &junk
,
549 (unsigned int*)&mw
, (unsigned int*)&mh
,
550 (unsigned int*)&junk
, (unsigned int*)&mdepth
);
551 if (mw
!= w
|| mh
!= h
|| mdepth
!= 1)
555 Pixmap p
= XCreatePixmap(**display
, info
->rootWindow(), sfw
, sfh
,
561 m
= XCreatePixmap(**display
, info
->rootWindow(), sfw
, sfh
, 1);
563 gcv
.subwindow_mode
= IncludeInferiors
;
564 gcv
.graphics_exposures
= false;
565 mgc
= XCreateGC(**display
, m
, GCGraphicsExposures
|
566 GCSubwindowMode
, &gcv
);
570 for (int y
= sfh
- 1; y
>= 0; --y
) {
571 int yy
= y
* h
/ sfh
;
572 for (int x
= sfw
- 1; x
>= 0; --x
) {
573 int xx
= x
* w
/ sfw
;
574 if (depth
!= info
->depth()) {
575 XCopyPlane(**display
, pixmap
, p
, DefaultGC(**display
, _screen
),
576 xx
, yy
, 1, 1, x
, y
, 1);
578 XCopyArea(**display
, pixmap
, p
, DefaultGC(**display
, _screen
),
582 XCopyArea(**display
, mask
, m
, mgc
, xx
, yy
, 1, 1, x
, y
);
586 XSetClipMask(**display
, DefaultGC(**display
, _screen
), m
);
587 XSetClipOrigin(**display
, DefaultGC(**display
, _screen
), 0, 0);
588 XCopyArea(**display
, p
, sf
.pixmap(), DefaultGC(**display
, _screen
), 0, 0,
590 XSetClipMask(**display
, DefaultGC(**display
, _screen
), None
);
592 XFreePixmap(**display
, p
);
593 if (m
!= None
) XFreePixmap(**display
, m
);
This page took 0.061849 seconds and 4 git commands to generate.