aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Transparent.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/Transparent.cc')
-rw-r--r--src/FbTk/Transparent.cc233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/FbTk/Transparent.cc b/src/FbTk/Transparent.cc
new file mode 100644
index 0000000..e3e1698
--- /dev/null
+++ b/src/FbTk/Transparent.cc
@@ -0,0 +1,233 @@
1// Transparent.cc for FbTk - Fluxbox Toolkit
2// Copyright (c) 2003 Henrik Kinnunen (fluxgen(at)users.sourceforge.net)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: Transparent.cc,v 1.1 2003/04/20 13:27:16 fluxgen Exp $
23
24#include "Transparent.hh"
25#include "App.hh"
26
27// #ifdef HAVE_XRENDER
28#include <X11/extensions/Xrender.h>
29// #endif // HAVE_XRENDER
30
31#include <iostream>
32using namespace std;
33
34namespace {
35
36Picture createAlphaPic(Window drawable, unsigned char alpha) {
37 Display *disp = FbTk::App::instance()->display();
38
39 // try to find a specific render format
40 XRenderPictFormat pic_format;
41 pic_format.type = PictTypeDirect;
42 pic_format.depth = 8; // alpha with bit depth 8
43 pic_format.direct.alphaMask = 0xff;
44 XRenderPictFormat *format = XRenderFindFormat(disp, PictFormatType |
45 PictFormatDepth | PictFormatAlphaMask,
46 &pic_format, 0);
47 if (format == 0) {
48 cerr<<"Warning! FbTk::Transparent: Failed to find valid format for alpha."<<endl;
49 return 0;
50 }
51
52 // create one pixel pixmap with depth 8 for alpha
53 Pixmap alpha_pm = XCreatePixmap(disp, drawable,
54 1, 1, 8);
55 if (alpha_pm == 0) {
56 cerr<<"Warning! FbTk::Transparent: Failed to create alpha pixmap."<<endl;
57 return 0;
58 }
59
60 // create picture with alpha_pm as repeated background
61 XRenderPictureAttributes attr;
62 attr.repeat = True; // small bitmap repeated
63 Picture alpha_pic = XRenderCreatePicture(disp, alpha_pm,
64 format, CPRepeat, &attr);
65 if (alpha_pic == 0) {
66 XFreePixmap(disp, alpha_pm);
67 cerr<<"Warning! FbTk::Transparent: Failed to create alpha picture."<<endl;
68 return 0;
69 }
70
71 // finaly set alpha and fill with it
72 XRenderColor color;
73 // calculate alpha percent and then scale it to short
74 color.red = 0xFF;
75 color.blue = 0xFF;
76 color.green = 0xFF;
77 color.alpha = ((unsigned short) (255 * alpha) << 8);
78
79 XRenderFillRectangle(disp, PictOpSrc, alpha_pic, &color,
80 0, 0, 1, 1);
81
82 XFreePixmap(disp, alpha_pm);
83
84 return alpha_pic;
85}
86
87};
88
89namespace FbTk {
90
91
92Transparent::Transparent(Drawable src, Drawable dest, unsigned char alpha, int screen_num):
93 m_alpha_pic(0), m_src_pic(0), m_dest_pic(0),
94 m_source(src), m_dest(dest), m_alpha(alpha) {
95
96 allocAlpha(m_alpha);
97
98 Display *disp = FbTk::App::instance()->display();
99
100 XRenderPictFormat *format =
101 XRenderFindVisualFormat(disp,
102 DefaultVisual(disp, screen_num));
103
104
105 if (src != 0 && format != 0) {
106 m_src_pic = XRenderCreatePicture(disp, src, format,
107 0, 0);
108 }
109
110 if (dest != 0 && format != 0) {
111 m_dest_pic = XRenderCreatePicture(disp, dest, format,
112 0, 0);
113 }
114
115}
116
117Transparent::~Transparent() {
118 if (m_alpha_pic != 0)
119 freeAlpha();
120
121 Display *disp = FbTk::App::instance()->display();
122
123 if (m_dest_pic != 0)
124 XRenderFreePicture(disp, m_dest_pic);
125
126 if (m_src_pic != 0)
127 XRenderFreePicture(disp, m_src_pic);
128}
129
130void Transparent::setAlpha(unsigned char alpha) {
131 if (m_source == 0)
132 return;
133
134 freeAlpha();
135 allocAlpha(alpha);
136}
137
138void Transparent::setDest(Drawable dest, int screen_num) {
139 if (m_dest == dest)
140 return;
141
142 Display *disp = FbTk::App::instance()->display();
143
144 if (m_dest_pic != 0) {
145 XRenderFreePicture(disp, m_dest_pic);
146 m_dest_pic = 0;
147 }
148 // create new dest pic if we have a valid dest drawable
149 if (dest != 0) {
150
151 XRenderPictFormat *format =
152 XRenderFindVisualFormat(disp,
153 DefaultVisual(disp, screen_num));
154 if (format == 0)
155 cerr<<"Warning! FbTk::Transparent: Failed to find format for screen("<<screen_num<<")"<<endl;
156 m_dest_pic = XRenderCreatePicture(disp, dest, format, 0, 0);
157
158
159 }
160 m_dest = dest;
161
162}
163
164void Transparent::setSource(Drawable source, int screen_num) {
165 if (m_source == source)
166 return;
167
168 if (m_alpha_pic != 0)
169 freeAlpha();
170
171 Display *disp = FbTk::App::instance()->display();
172
173 if (m_src_pic != 0) {
174 XRenderFreePicture(disp, m_src_pic);
175 m_src_pic = 0;
176 }
177
178 m_source = source;
179 allocAlpha(m_alpha);
180
181 // create new source pic if we have a valid source drawable
182 if (m_source != 0) {
183
184 XRenderPictFormat *format =
185 XRenderFindVisualFormat(disp,
186 DefaultVisual(disp, screen_num));
187 if (format == 0)
188 cerr<<"Warning! FbTk::Transparent: Failed to find format for screen("<<screen_num<<")"<<endl;
189 m_src_pic = XRenderCreatePicture(disp, m_source, format,
190 0, 0);
191 }
192}
193
194void Transparent::render(int src_x, int src_y,
195 int dest_x, int dest_y,
196 unsigned int width, unsigned int height) const {
197 if (m_src_pic == 0 || m_dest_pic == 0 ||
198 m_alpha_pic == 0)
199 return;
200 // render src+alpha to dest picture
201 XRenderComposite(FbTk::App::instance()->display(),
202 PictOpOver,
203 m_src_pic,
204 m_alpha_pic,
205 m_dest_pic,
206 src_x, src_y,
207 0, 0,
208 dest_x, dest_y,
209 width, height);
210
211
212}
213
214void Transparent::allocAlpha(unsigned char alpha) {
215 if (m_source == 0)
216 return;
217 if (m_alpha_pic != 0)
218 freeAlpha();
219
220 m_alpha_pic = createAlphaPic(m_source, alpha);
221 m_alpha = alpha;
222}
223
224void Transparent::freeAlpha() {
225 XRenderFreePicture(FbTk::App::instance()->display(), m_alpha_pic);
226 m_alpha_pic = 0;
227 m_alpha = 255;
228}
229
230}; // end namespace FbTk
231
232
233