2 /* Copyright (C) 2002 Olivier Chapuis */
3 /* This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 /* ---------------------------- included header files ---------------------- */
27 #include "PictureBase.h"
29 #include "PictureGraphics.h"
30 #include "FRenderInit.h"
32 #include "FRenderInterface.h"
34 /* ---------------------------- local definitions -------------------------- */
36 /* ---------------------------- local macros ------------------------------- */
38 /* ---------------------------- imports ------------------------------------ */
40 /* ---------------------------- included code files ------------------------ */
42 /* ---------------------------- local types -------------------------------- */
44 /* ---------------------------- forward declarations ----------------------- */
46 /* ---------------------------- local variables ---------------------------- */
48 static FRenderPictFormat
*PFrenderVisualFormat
= NULL
;
49 static FRenderPictFormat
*PFrenderAlphaFormat
= NULL
;
50 static FRenderPictFormat
*PFrenderMaskFormat
= NULL
;
51 static FRenderPictFormat
*PFrenderDirectFormat
= NULL
;
52 static FRenderPictFormat
*PFrenderAbsoluteFormat
= NULL
;
53 Bool FRenderVisualInitialized
= False
;
55 /* #define USE_ABSOLUTE_FORMAT 1*/
57 /* ---------------------------- exported variables (globals) --------------- */
59 /* ---------------------------- local functions ---------------------------- */
62 void FRenderVisualInit(Display
*dpy
)
66 if (!XRenderSupport
|| !FRenderGetExtensionSupported())
71 PFrenderVisualFormat
= FRenderFindVisualFormat (dpy
, Pvisual
);
72 if (!PFrenderVisualFormat
)
74 fprintf(stderr
,"[fvwmlibs][FRenderInit] -- ERROR: "
75 "fail to create XRender Visual Format\n");
79 pf
.type
= FRenderPictTypeDirect
;
81 pf
.direct
.alphaMask
= 0xff;
82 PFrenderAlphaFormat
= FRenderFindFormat(
83 dpy
, FRenderPictFormatType
| FRenderPictFormatDepth
|
84 FRenderPictFormatAlpha
| FRenderPictFormatAlphaMask
, &pf
, 0);
85 if (!PFrenderAlphaFormat
)
87 fprintf(stderr
,"[fvwmlibs][FRenderInit] -- ERROR: "
88 "fail to create XRender Alpha Format\n");
92 pf
.type
= FRenderPictTypeDirect
;
94 pf
.direct
.alphaMask
= 1;
95 PFrenderMaskFormat
= FRenderFindFormat(
96 dpy
, FRenderPictFormatType
| FRenderPictFormatDepth
|
97 FRenderPictFormatAlpha
| FRenderPictFormatAlphaMask
, &pf
, 0);
98 if (!PFrenderMaskFormat
)
100 fprintf(stderr
,"[fvwmlibs][FRenderInit] -- ERROR: "
101 "fail to create XRender Mask Format\n");
105 pf
.type
= FRenderPictTypeDirect
;
107 pf
.direct
.alphaMask
= 0;
109 pf
.direct
.redMask
= 0xff;
111 pf
.direct
.greenMask
= 0xff;
113 pf
.direct
.blueMask
= 0xff;
114 PFrenderDirectFormat
= FRenderFindFormat(
115 dpy
, FRenderPictFormatType
| FRenderPictFormatDepth
|
116 FRenderPictFormatRed
| FRenderPictFormatRedMask
|
117 FRenderPictFormatGreen
| FRenderPictFormatGreenMask
|
118 FRenderPictFormatBlue
| FRenderPictFormatBlueMask
|
119 FRenderPictFormatAlpha
| FRenderPictFormatAlphaMask
, &pf
, 0);
120 if (!PFrenderDirectFormat
)
122 fprintf(stderr
,"[fvwmlibs][FRenderInit] -- ERROR: "
123 "fail to create XRender Direct Format\n");
127 pf
.type
= FRenderPictTypeDirect
;
128 pf
.direct
.alpha
= 24;
129 pf
.direct
.alphaMask
= 0xff;
131 pf
.direct
.redMask
= 0xff;
133 pf
.direct
.greenMask
= 0xff;
135 pf
.direct
.blueMask
= 0xff;
136 PFrenderAbsoluteFormat
= FRenderFindFormat(
137 dpy
, FRenderPictFormatType
| FRenderPictFormatDepth
|
138 FRenderPictFormatRed
| FRenderPictFormatRedMask
|
139 FRenderPictFormatGreen
| FRenderPictFormatGreenMask
|
140 FRenderPictFormatBlue
| FRenderPictFormatBlueMask
|
141 FRenderPictFormatAlpha
| FRenderPictFormatAlphaMask
, &pf
, 0);
142 if (!PFrenderAbsoluteFormat
)
144 fprintf(stderr
,"[fvwmlibs][FRenderInit] -- ERROR: "
145 "fail to create XRender Absolute Format\n");
151 Bool
FRenderCompositeAndCheck(
152 Display
*dpy
, int op
, FRenderPicture src
, FRenderPicture alpha
,
153 FRenderPicture dest
, int x
, int y
, int a_x
, int a_y
,
154 int d_x
, int d_y
, int d_w
, int d_h
)
157 dpy
, op
, src
, alpha
, dest
, x
, y
, a_x
, a_y
, d_x
, d_y
, d_w
, d_h
);
164 Bool
FRenderCreateShadePicture(
165 Display
*dpy
, Window win
, int alpha_percent
)
167 static Pixmap shade_pixmap
= None
;
168 static FRenderPicture shade_picture
= None
;
169 static int saved_alpha_percent
= 0;
170 Bool force_update
= False
;
173 if (!XRenderSupport
|| !FRenderGetExtensionSupported())
178 /* FRender Visuals should be already initialized */
180 if (!shade_pixmap
|| !shade_picture
)
182 FRenderPictureAttributes pa
;
186 shade_pixmap
= XCreatePixmap(dpy
, win
, 1, 1, 8);
191 shade_picture
= FRenderCreatePicture(
192 dpy
, shade_pixmap
, PFrenderAlphaFormat
,
193 FRenderCPRepeat
, &pa
);
198 (alpha_percent
!= saved_alpha_percent
|| force_update
))
200 frc
.red
= frc
.green
= frc
.blue
= 0;
201 frc
.alpha
= 0xffff * (alpha_percent
)/100;
202 FRenderFillRectangle(
203 dpy
, FRenderPictOpSrc
, shade_picture
, &frc
,
205 saved_alpha_percent
= alpha_percent
;
208 return shade_picture
;
212 Bool
FRenderTintPicture(
213 Display
*dpy
, Window win
, Pixel tint
, int tint_percent
,
214 FRenderPicture dest_picture
,
215 int dest_x
, int dest_y
, int dest_w
, int dest_h
)
217 static Pixel saved_tint
= 0;
218 static int saved_tint_percent
= 0;
219 static Pixmap tint_pixmap
= None
;
220 static FRenderPicture tint_picture
= None
;
221 FRenderPicture shade_picture
= None
;
222 FRenderColor frc_tint
;
223 Bool force_update
= False
;
224 FRenderPictureAttributes pa
;
232 if (!tint_pixmap
|| !tint_picture
)
237 tint_pixmap
= XCreatePixmap(dpy
, win
, 1, 1, 32);
241 tint_picture
= FRenderCreatePicture(
243 PFrenderAbsoluteFormat
,
244 FRenderCPRepeat
, &pa
);
257 (tint
!= saved_tint
|| tint_percent
!= saved_tint_percent
||
261 float alpha_factor
= (float)tint_percent
/100;
263 force_update
= False
;
265 XQueryColor(dpy
, Pcmap
, &color
);
266 frc_tint
.red
= color
.red
* alpha_factor
;
267 frc_tint
.green
= color
.green
* alpha_factor
;
268 frc_tint
.blue
= color
.blue
* alpha_factor
;
269 frc_tint
.alpha
= 0xffff * alpha_factor
;
270 FRenderFillRectangle(
271 dpy
, FRenderPictOpSrc
, tint_picture
, &frc_tint
,
274 saved_tint_percent
= tint_percent
;
278 shade_picture
= FRenderCreateShadePicture(dpy
, win
, 100);
281 rv
= FRenderCompositeAndCheck(
282 dpy
, FRenderPictOpOver
, tint_picture
, shade_picture
,
283 dest_picture
, 0, 0, 0, 0, dest_x
, dest_y
, dest_w
, dest_h
);
289 /* ---------------------------- interface functions ------------------------ */
292 Bool
FRenderTintRectangle(
293 Display
*dpy
, Window win
, Pixmap mask
, Pixel tint
, int tint_percent
,
294 Drawable d
, int dest_x
, int dest_y
, int dest_w
, int dest_h
)
296 FRenderPicture dest_picture
= None
;
297 FRenderPictureAttributes pa
;
298 unsigned int val
= 0;
302 if (!XRenderSupport
|| !FRenderGetExtensionSupported())
307 if (!FRenderVisualInitialized
)
309 FRenderVisualInitialized
= True
;
310 FRenderVisualInit(dpy
);
313 if (!PFrenderVisualFormat
|| !PFrenderAlphaFormat
||
314 !PFrenderAbsoluteFormat
|| !PFrenderMaskFormat
)
320 val
= FRenderCPClipMask
;
322 if (!(dest_picture
= FRenderCreatePicture(
323 dpy
, d
, PFrenderVisualFormat
, val
, &pa
)))
328 rv
= FRenderTintPicture(
329 dpy
, win
, tint_percent
, tint
, dest_picture
, dest_x
, dest_y
,
332 FRenderFreePicture(dpy
, dest_picture
);
337 Display
*dpy
, Window win
, Pixmap pixmap
, Pixmap mask
, Pixmap alpha
,
338 int depth
, int added_alpha_percent
, Pixel tint
, int tint_percent
,
339 Drawable d
, GC gc
, GC alpha_gc
,
340 int src_x
, int src_y
, int src_w
, int src_h
,
341 int dest_x
, int dest_y
, int dest_w
, int dest_h
,
345 Pixmap pixmap_copy
= None
;
346 Pixmap alpha_copy
= None
;
347 FRenderPicture shade_picture
= None
;
348 FRenderPicture alpha_picture
= None
;
349 FRenderPicture mask_picture
= None
;
350 FRenderPicture src_picture
= None
;
351 FRenderPicture dest_picture
= None
;
352 FRenderPicture root_picture
= None
;
353 FRenderPictureAttributes pa
;
354 unsigned long pam
= 0;
358 Bool free_alpha_gc
= False
;
360 if (!XRenderSupport
|| !FRenderGetExtensionSupported())
365 if (!FRenderVisualInitialized
)
367 FRenderVisualInitialized
= True
;
368 FRenderVisualInit(dpy
);
371 if (!PFrenderVisualFormat
|| !PFrenderAlphaFormat
||
372 !PFrenderAbsoluteFormat
|| !PFrenderMaskFormat
)
377 /* it is a bitmap ? */
378 if (Pdepth
!= depth
&& pixmap
)
380 pixmap_copy
= PictureBitmapToPixmap(
381 dpy
, win
, pixmap
, Pdepth
, gc
, src_x
, src_y
, src_w
,
386 pam
= FRenderCPRepeat
;
397 * build the src_picture
399 if (pixmap
== ParentRelative
)
401 /* need backing store and good preparation of the win */
404 gc
= PictureDefaultGC(dpy
, win
);
406 pixmap_copy
= XCreatePixmap(dpy
, win
, src_w
, src_h
, Pdepth
);
407 if (pixmap_copy
&& gc
)
410 dpy
, win
, pixmap_copy
, gc
,
411 src_x
, src_y
, src_w
, src_h
, 0, 0);
415 else if (tint_percent
> 0 && !pixmap_copy
)
419 gc
= PictureDefaultGC(dpy
, win
);
421 pixmap_copy
= XCreatePixmap(dpy
, win
, src_w
, src_h
, Pdepth
);
422 if (pixmap_copy
&& gc
)
425 dpy
, pixmap
, pixmap_copy
, gc
,
426 src_x
, src_y
, src_w
, src_h
, 0, 0);
430 else if (!pixmap_copy
)
432 src_picture
= FRenderCreatePicture(
433 dpy
, pixmap
, PFrenderVisualFormat
, pam
, &pa
);
436 if (!src_picture
&& pixmap_copy
)
438 src_picture
= FRenderCreatePicture(
439 dpy
, pixmap_copy
, PFrenderVisualFormat
, pam
, &pa
);
447 /* tint the src, it is why we have done a pixmap copy */
448 if (tint_percent
> 0)
451 dpy
, win
, tint
, tint_percent
, src_picture
,
452 src_x
, src_y
, src_w
, src_h
);
455 if (added_alpha_percent
>= 100)
459 alpha_picture
= FRenderCreatePicture(
460 dpy
, alpha
, PFrenderAlphaFormat
, pam
, &pa
);
462 else if (mask
!= None
)
464 alpha_picture
= FRenderCreatePicture(
465 dpy
, mask
, PFrenderMaskFormat
, pam
, &pa
);
469 /* fix a bug in certain XRender server implementation?
471 if (!(shade_picture
= FRenderCreateShadePicture(
476 alpha_x
= alpha_y
= 0;
483 alpha_copy
= XCreatePixmap(dpy
, win
, src_w
, src_h
, 8);
486 alpha_gc
= fvwmlib_XCreateGC(
487 dpy
, alpha
, 0, NULL
);
488 free_alpha_gc
= True
;
490 if (alpha_copy
&& alpha_gc
)
492 XCopyArea(dpy
, alpha
, alpha_copy
, alpha_gc
,
493 alpha_x
, alpha_y
, src_w
, src_h
, 0, 0);
494 alpha_picture
= FRenderCreatePicture(
495 dpy
, alpha_copy
, PFrenderAlphaFormat
,
498 if (alpha_gc
&& free_alpha_gc
)
500 XFreeGC(dpy
, alpha_gc
);
502 alpha_x
= alpha_y
= 0;
504 else if (mask
!= None
)
506 alpha_copy
= XCreatePixmap(dpy
, win
, src_w
, src_h
, 8);
509 alpha_picture
= FRenderCreatePicture(
510 dpy
, alpha_copy
, PFrenderAlphaFormat
,
515 frc
.red
= frc
.green
= frc
.blue
= frc
.alpha
= 0;
516 FRenderFillRectangle(
517 dpy
, FRenderPictOpSrc
, alpha_picture
,
518 &frc
, 0, 0, src_w
, src_h
);
520 mask_picture
= FRenderCreatePicture(
521 dpy
, mask
, PFrenderMaskFormat
, pam
, &pa
);
525 alpha_x
= alpha_y
= 0;
528 if (!(shade_picture
= FRenderCreateShadePicture(
529 dpy
, win
, added_alpha_percent
)))
535 if (alpha
!= None
&& alpha_picture
&& shade_picture
)
537 if (!FRenderCompositeAndCheck(
538 dpy
, FRenderPictOpAtopReverse
, shade_picture
,
539 alpha_picture
, alpha_picture
,
540 0, 0, alpha_x
, alpha_y
, 0, 0, src_w
, src_h
))
544 alpha_x
= alpha_y
= 0;
546 else if (mask
!= None
&& alpha_picture
&& shade_picture
)
548 if (!FRenderCompositeAndCheck(
549 dpy
, FRenderPictOpAtopReverse
, shade_picture
,
550 mask_picture
, alpha_picture
,
551 0, 0, alpha_x
, alpha_y
, 0, 0, src_w
, src_h
))
555 alpha_x
= alpha_y
= 0;
559 if (alpha_picture
== None
)
561 alpha_picture
= shade_picture
;
564 dest_picture
= FRenderCreatePicture(
565 dpy
, d
, PFrenderVisualFormat
, 0, &pa
);
569 rv
= FRenderCompositeAndCheck(
570 dpy
, FRenderPictOpOver
, src_picture
, alpha_picture
,
571 dest_picture
, src_x
, src_y
, alpha_x
, alpha_y
,
572 dest_x
, dest_y
, dest_w
, dest_h
);
578 FRenderFreePicture(dpy
, dest_picture
);
582 FRenderFreePicture(dpy
, src_picture
);
584 if (alpha_picture
&& alpha_picture
!= shade_picture
)
586 FRenderFreePicture(dpy
, alpha_picture
);
590 FRenderFreePicture(dpy
, mask_picture
);
594 FRenderFreePicture(dpy
, root_picture
);
598 XFreePixmap(dpy
, alpha_copy
);
602 XFreePixmap(dpy
, pixmap_copy
);