1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2008 Lubos Lunak <l.lunak@kde.org>
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 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
21 #include "kwinxrenderutils.h"
23 #ifdef KWIN_HAVE_XRENDER_COMPOSITING
33 // Convert QRegion to XserverRegion. All code uses XserverRegion
34 // only when really necessary as the shared implementation uses
36 XserverRegion
toXserverRegion( QRegion region
)
38 QVector
< QRect
> rects
= region
.rects();
39 XRectangle
* xr
= new XRectangle
[ rects
.count() ];
44 xr
[ i
].x
= rects
[ i
].x();
45 xr
[ i
].y
= rects
[ i
].y();
46 xr
[ i
].width
= rects
[ i
].width();
47 xr
[ i
].height
= rects
[ i
].height();
49 XserverRegion ret
= XFixesCreateRegion( display(), xr
, rects
.count());
54 // adapted from Qt, because this really sucks ;)
55 XRenderColor
preMultiply(const QColor
&c
, float opacity
)
58 const uint A
= c
.alpha() * opacity
,
62 color
.alpha
= (A
| A
<< 8);
63 color
.red
= (R
| R
<< 8) * color
.alpha
/ 0x10000;
64 color
.green
= (G
| G
<< 8) * color
.alpha
/ 0x10000;
65 color
.blue
= (B
| B
<< 8) * color
.alpha
/ 0x10000;
69 XRenderPicture
xRenderFill( const XRenderColor
*xc
)
71 Pixmap pixmap
= XCreatePixmap( display(), rootWindow(), 1, 1, 32 );
72 XRenderPictureAttributes pa
; pa
.repeat
= True
;
73 XRenderPicture
fill( pixmap
, 32 );
74 XFreePixmap( display(), pixmap
);
75 XRenderChangePicture (display(), fill
, CPRepeat
, &pa
);
76 XRenderFillRectangle( display(), PictOpSrc
, fill
, xc
, 0, 0, 1, 1 );
80 XRenderPicture
xRenderFill( const QColor
&c
)
82 XRenderColor xc
= preMultiply(c
);
83 return xRenderFill( &xc
);
87 static XRenderPicture
*_circle
[4] = {NULL
, NULL
, NULL
, NULL
};
89 #define DUMP_CNR(_SECT_, _W_, _H_, _XOFF_, _YOFF_)\
90 dump = QPixmap(_W_, _H_);\
91 dump.fill(Qt::transparent);\
93 p.drawPixmap( 0, 0, tmp, _XOFF_, _YOFF_, _W_, _H_ );\
95 _circle[_SECT_] = new XRenderPicture(dump);
99 static XRenderPicture
*circle(int i
)
103 QPixmap
tmp(2*CS
, 2*CS
);
104 tmp
.fill(Qt::transparent
);
106 p
.setRenderHint(QPainter::Antialiasing
);
107 p
.setPen(Qt::NoPen
); p
.setBrush(Qt::black
);
108 p
.drawEllipse(tmp
.rect());
111 DUMP_CNR(0, CS
, CS
, 0, 0);
112 DUMP_CNR(1, CS
, CS
, CS
, 0);
113 DUMP_CNR(2, CS
, CS
, CS
, CS
);
114 DUMP_CNR(3, CS
, CS
, 0, CS
);
119 void xRenderRoundBox( Picture pict
, const QRect
&rect
, int , const QColor
&c
)
121 XRenderPicture fill
= xRenderFill(c
);
122 int op
= c
.alpha() == 255 ? PictOpSrc
: PictOpOver
;
123 // TODO: implement second paramenter "roundness"
124 // so rather use ?? XRenderCompositeTriFan (dpy, op, src, dst, maskFormat, xSrc, ySrc,
125 //XPointFixed *points, npoint);
126 // this will require "points on a circle" calculation, however...
128 int s
= qMin(CS
, qMin(rect
.height()/2, rect
.width()/2));
130 rect
.getCoords(&x
,&y
,&r
,&b
);
133 XRenderComposite( display(), PictOpOver
, fill
, *circle(0), pict
, 0, 0, 0, 0, x
, y
, CS
, CS
);
134 XRenderComposite( display(), PictOpOver
, fill
, *circle(1), pict
, 0, 0, CS
-s
, 0, r
, y
, s
, s
);
135 XRenderComposite( display(), PictOpOver
, fill
, *circle(2), pict
, 0, 0, CS
-s
, CS
-s
, r
, b
, s
, s
);
136 XRenderComposite( display(), PictOpOver
, fill
, *circle(3), pict
, 0, 0, 0, CS
-s
, x
, b
, s
, s
);
137 XRenderComposite( display(), op
, fill
, 0, pict
, 0, 0, 0, 0, x
+s
, y
, rect
.width()-2*s
, s
);
138 XRenderComposite( display(), op
, fill
, 0, pict
, 0, 0, 0, 0, x
, y
+s
, rect
.width(), rect
.height()-2*s
);
139 XRenderComposite( display(), op
, fill
, 0, pict
, 0, 0, 0, 0, x
+s
, b
, rect
.width()-2*s
, s
);
145 // XRenderFind(Standard)Format() is a roundtrip, so cache the results
146 static XRenderPictFormat
* renderformats
[ 33 ];
148 static Picture
createPicture( Pixmap pix
, int depth
)
152 if( renderformats
[ depth
] == NULL
)
157 renderformats
[ 1 ] = XRenderFindStandardFormat( display(), PictStandardA1
);
160 renderformats
[ 8 ] = XRenderFindStandardFormat( display(), PictStandardA8
);
163 renderformats
[ 24 ] = XRenderFindStandardFormat( display(), PictStandardRGB24
);
166 renderformats
[ 32 ] = XRenderFindStandardFormat( display(), PictStandardARGB32
);
170 XRenderPictFormat req
;
171 long mask
= PictFormatType
| PictFormatDepth
;
172 req
.type
= PictTypeDirect
;
174 renderformats
[ depth
] = XRenderFindFormat( display(), mask
, &req
, 0 );
178 if( renderformats
[ depth
] == NULL
)
180 kWarning( 1212 ) << "Could not find XRender format for depth" << depth
;
184 return XRenderCreatePicture( display(), pix
, renderformats
[ depth
], 0, NULL
);
187 XRenderPicture::XRenderPicture( QPixmap pix
)
188 : d( new XRenderPictureData( createPicture( pix
.handle(), pix
.depth())))
192 XRenderPicture::XRenderPicture( Pixmap pix
, int depth
)
193 : d( new XRenderPictureData( createPicture( pix
, depth
)))