aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/FbPixmap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/FbPixmap.cc')
-rw-r--r--src/FbTk/FbPixmap.cc166
1 files changed, 88 insertions, 78 deletions
diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc
index c698ce6..43e74d8 100644
--- a/src/FbTk/FbPixmap.cc
+++ b/src/FbTk/FbPixmap.cc
@@ -19,7 +19,7 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22// $Id: FbPixmap.cc,v 1.13 2004/09/09 14:29:10 akir Exp $ 22// $Id: FbPixmap.cc,v 1.14 2004/09/10 15:46:08 akir Exp $
23 23
24#include "FbPixmap.hh" 24#include "FbPixmap.hh"
25#include "App.hh" 25#include "App.hh"
@@ -32,17 +32,18 @@ using namespace std;
32 32
33namespace FbTk { 33namespace FbTk {
34 34
35FbPixmap::FbPixmap():m_pm(0), 35FbPixmap::FbPixmap():m_pm(0),
36 m_width(0), m_height(0), 36 m_width(0), m_height(0),
37 m_depth(0) { } 37 m_depth(0) {
38}
38 39
39FbPixmap::FbPixmap(const FbPixmap &the_copy):m_pm(0), 40FbPixmap::FbPixmap(const FbPixmap &the_copy):FbDrawable(), m_pm(0),
40 m_width(0), m_height(0), 41 m_width(0), m_height(0),
41 m_depth(0) { 42 m_depth(0){
42 copy(the_copy); 43 copy(the_copy);
43} 44}
44 45
45FbPixmap::FbPixmap(Pixmap pm):m_pm(0), 46FbPixmap::FbPixmap(Pixmap pm):m_pm(0),
46 m_width(0), m_height(0), 47 m_width(0), m_height(0),
47 m_depth(0) { 48 m_depth(0) {
48 if (pm == 0) 49 if (pm == 0)
@@ -51,19 +52,19 @@ FbPixmap::FbPixmap(Pixmap pm):m_pm(0),
51 (*this) = pm; 52 (*this) = pm;
52} 53}
53 54
54FbPixmap::FbPixmap(const FbDrawable &src, 55FbPixmap::FbPixmap(const FbDrawable &src,
55 unsigned int width, unsigned int height, 56 unsigned int width, unsigned int height,
56 int depth):m_pm(0), 57 int depth):m_pm(0),
57 m_width(0), m_height(0), 58 m_width(0), m_height(0),
58 m_depth(0) { 59 m_depth(0) {
59 60
60 create(src.drawable(), width, height, depth); 61 create(src.drawable(), width, height, depth);
61} 62}
62 63
63FbPixmap::FbPixmap(Drawable src, 64FbPixmap::FbPixmap(Drawable src,
64 unsigned int width, unsigned int height, 65 unsigned int width, unsigned int height,
65 int depth):m_pm(0), 66 int depth):m_pm(0),
66 m_width(0), m_height(0), 67 m_width(0), m_height(0),
67 m_depth(0) { 68 m_depth(0) {
68 69
69 create(src, width, height, depth); 70 create(src, width, height, depth);
@@ -88,8 +89,8 @@ FbPixmap &FbPixmap::operator = (Pixmap pm) {
88 // get width, height and depth for the pixmap 89 // get width, height and depth for the pixmap
89 Window root; 90 Window root;
90 int x, y; 91 int x, y;
91 unsigned int border_width, bpp; 92 unsigned int border_width, bpp;
92 XGetGeometry(FbTk::App::instance()->display(), 93 XGetGeometry(s_display,
93 pm, 94 pm,
94 &root, 95 &root,
95 &x, &y, 96 &x, &y,
@@ -113,20 +114,20 @@ void FbPixmap::copy(const FbPixmap &the_copy) {
113 the_copy.depth() != depth() || 114 the_copy.depth() != depth() ||
114 drawable() == 0) 115 drawable() == 0)
115 create_new = true; 116 create_new = true;
116 117
117 if (create_new) 118 if (create_new)
118 free(); 119 free();
119 120
120 if (the_copy.drawable() != 0) { 121 if (the_copy.drawable() != 0) {
121 if (create_new) { 122 if (create_new) {
122 create(the_copy.drawable(), 123 create(the_copy.drawable(),
123 the_copy.width(), the_copy.height(), 124 the_copy.width(), the_copy.height(),
124 the_copy.depth()); 125 the_copy.depth());
125 } 126 }
126 127
127 if (drawable()) { 128 if (drawable()) {
128 GContext gc(drawable()); 129 GContext gc(drawable());
129 130
130 copyArea(the_copy.drawable(), 131 copyArea(the_copy.drawable(),
131 gc.gc(), 132 gc.gc(),
132 0, 0, 133 0, 0,
@@ -147,7 +148,7 @@ void FbPixmap::copy(Pixmap pm) {
147 unsigned int border_width, bpp; 148 unsigned int border_width, bpp;
148 unsigned int new_width, new_height; 149 unsigned int new_width, new_height;
149 150
150 XGetGeometry(FbTk::App::instance()->display(), 151 XGetGeometry(s_display,
151 pm, 152 pm,
152 &root, 153 &root,
153 &x, &y, 154 &x, &y,
@@ -156,25 +157,21 @@ void FbPixmap::copy(Pixmap pm) {
156 &bpp); 157 &bpp);
157 // create new pixmap and copy area 158 // create new pixmap and copy area
158 create(root, new_width, new_height, bpp); 159 create(root, new_width, new_height, bpp);
159
160 Display *disp = FbTk::App::instance()->display();
161 160
162 GC gc = XCreateGC(disp, drawable(), 0, 0); 161 GC gc = XCreateGC(s_display, drawable(), 0, 0);
163 162
164 XCopyArea(disp, pm, drawable(), gc, 163 XCopyArea(s_display, pm, drawable(), gc,
165 0, 0, 164 0, 0,
166 width(), height(), 165 width(), height(),
167 0, 0); 166 0, 0);
168 167
169 XFreeGC(disp, gc); 168 XFreeGC(s_display, gc);
170} 169}
171 170
172void FbPixmap::rotate() { 171void FbPixmap::rotate() {
173 172
174 Display *dpy = FbTk::App::instance()->display();
175
176 // make an image copy 173 // make an image copy
177 XImage *src_image = XGetImage(dpy, drawable(), 174 XImage *src_image = XGetImage(s_display, drawable(),
178 0, 0, // pos 175 0, 0, // pos
179 width(), height(), // size 176 width(), height(), // size
180 ~0, // plane mask 177 ~0, // plane mask
@@ -185,11 +182,11 @@ void FbPixmap::rotate() {
185 GContext gc(drawable()); 182 GContext gc(drawable());
186 183
187 // copy new area 184 // copy new area
188 for (int y = 0; y < static_cast<signed>(height()); ++y) { 185 for (unsigned int y = 0; y < height(); ++y) {
189 for (int x = 0; x < static_cast<signed>(width()); ++x) { 186 for (unsigned int x = 0; x < width(); ++x) {
190 gc.setForeground(XGetPixel(src_image, x, y)); 187 gc.setForeground(XGetPixel(src_image, x, y));
191 // revers coordinates 188 // revers coordinates
192 XDrawPoint(dpy, new_pm.drawable(), gc.gc(), y, x); 189 XDrawPoint(s_display, new_pm.drawable(), gc.gc(), y, x);
193 } 190 }
194 } 191 }
195 192
@@ -204,14 +201,12 @@ void FbPixmap::rotate() {
204} 201}
205 202
206void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) { 203void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) {
207 204
208 if (drawable() == 0 || 205 if (drawable() == 0 ||
209 (dest_width == width() && dest_height == height())) 206 (dest_width == width() && dest_height == height()))
210 return; 207 return;
211 208
212 Display *dpy = FbTk::App::instance()->display(); 209 XImage *src_image = XGetImage(s_display, drawable(),
213
214 XImage *src_image = XGetImage(dpy, drawable(),
215 0, 0, // pos 210 0, 0, // pos
216 width(), height(), // size 211 width(), height(), // size
217 ~0, // plane mask 212 ~0, // plane mask
@@ -229,13 +224,13 @@ void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) {
229 224
230 // start scaling 225 // start scaling
231 float src_x = 0, src_y = 0; 226 float src_x = 0, src_y = 0;
232 for (int tx=0; tx < static_cast<signed>(dest_width); ++tx, src_x += zoom_x) { 227 for (unsigned int tx=0; tx < dest_width; ++tx, src_x += zoom_x) {
233 src_y = 0; 228 src_y = 0;
234 for (int ty=0; ty < static_cast<signed>(dest_height); ++ty, src_y += zoom_y) { 229 for (unsigned int ty=0; ty < dest_height; ++ty, src_y += zoom_y) {
235 gc.setForeground(XGetPixel(src_image, 230 gc.setForeground(XGetPixel(src_image,
236 static_cast<int>(src_x), 231 static_cast<int>(src_x),
237 static_cast<int>(src_y))); 232 static_cast<int>(src_y)));
238 XDrawPoint(dpy, new_pm.drawable(), gc.gc(), tx, ty); 233 XDrawPoint(s_display, new_pm.drawable(), gc.gc(), tx, ty);
239 } 234 }
240 } 235 }
241 236
@@ -251,23 +246,23 @@ void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) {
251} 246}
252 247
253void FbPixmap::tile(unsigned int dest_width, unsigned int dest_height) { 248void FbPixmap::tile(unsigned int dest_width, unsigned int dest_height) {
254 if (drawable() == 0 || 249 if (drawable() == 0 ||
255 (dest_width == width() && dest_height == height())) 250 (dest_width == width() && dest_height == height()))
256 return; 251 return;
257 252
258 FbPixmap new_pm(drawable(), width(), height(), depth()); 253 FbPixmap new_pm(drawable(), width(), height(), depth());
259 254
260 new_pm.copy(m_pm); 255 new_pm.copy(m_pm);
261 256
262 resize(dest_width, dest_height); 257 resize(dest_width, dest_height);
263 258
264 FbTk::GContext gc(*this); 259 FbTk::GContext gc(*this);
265 260
266 gc.setTile(new_pm); 261 gc.setTile(new_pm);
267 gc.setFillStyle(FillTiled); 262 gc.setFillStyle(FillTiled);
268 263
269 fillRectangle(gc.gc(), 0, 0, dest_width, dest_height); 264 fillRectangle(gc.gc(), 0, 0, dest_width, dest_height);
270 265
271} 266}
272 267
273 268
@@ -287,45 +282,60 @@ Pixmap FbPixmap::release() {
287} 282}
288 283
289Pixmap FbPixmap::getRootPixmap(int screen_num) { 284Pixmap FbPixmap::getRootPixmap(int screen_num) {
290 285
291 Pixmap root_pm = 0;
292 // get root pixmap for transparency
293 Display *disp = FbTk::App::instance()->display();
294 Atom real_type; 286 Atom real_type;
295 int real_format; 287 int real_format;
296 unsigned long items_read, items_left; 288 unsigned long items_read, items_left;
297 unsigned int *data; 289 unsigned int *data;
298 if (XGetWindowProperty(disp, RootWindow(disp, screen_num),
299 XInternAtom(disp, "_XROOTPMAP_ID", false),
300 0L, 1L,
301 false, XA_PIXMAP, &real_type,
302 &real_format, &items_read, &items_left,
303 (unsigned char **) &data) == Success &&
304 items_read) {
305 root_pm = (Pixmap) (*data);
306 XFree(data);
307/* TODO: analyze why this doesnt work
308 } else if (XGetWindowProperty(disp, RootWindow(disp, screen_num),
309 XInternAtom(disp, "_XSETROOT_ID", false),
310 0L, 1L,
311 false, XA_PIXMAP, &real_type,
312 &real_format, &items_read, &items_left,
313 (unsigned char **) &data) == Success &&
314 items_read) {
315 root_pm = (Pixmap) (*data);
316 XFree(data);
317*/
318 }
319
320
321 return root_pm;
322 290
291 unsigned int prop = 0;
292 static const char* prop_ids[] = {
293 "_XROOTPMAP_ID",
294 "_XSETROOT_ID",
295 0
296 };
297 static bool print_error = true; // print error_message only once
298 static const char* error_message = { "\n\n !!! WARNING WARNING WARNING WARNING !!!!!\n"
299 " if you experience problems with transparency:\n"
300 " you are using a wallpapersetter that \n"
301 " uses _XSETROOT_ID .. which we do not support.\n"
302 " consult 'fbsetbg -i' or try any other wallpapersetter\n"
303 " that uses _XROOTPMAP_ID !\n"
304 " !!! WARNING WARNING WARNING WARNING !!!!!!\n\n"
305 };
306
307 Pixmap root_pm = None;
308
309 for (prop = 0; prop_ids[prop]; prop++) {
310 if (XGetWindowProperty(s_display,
311 RootWindow(s_display, screen_num),
312 XInternAtom(s_display, prop_ids[prop], False),
313 0L, 4,
314 False, XA_PIXMAP,
315 &real_type, &real_format,
316 &items_read, &items_left,
317 (unsigned char **) &data) == Success &&
318 real_format == 32 && items_read == 1) {
319
320 if (strcmp(prop_ids[prop], "_XSETROOT_ID") == 0) {
321 if (print_error) {
322 fprintf(stderr, "%s", error_message);
323 print_error = false;
324 }
325 } else
326 root_pm = (Pixmap) (*data);
327
328 XFree(data);
329 break;
330 }
331 }
323 332
333 return root_pm;
324} 334}
325 335
326void FbPixmap::free() { 336void FbPixmap::free() {
327 if (m_pm != 0) { 337 if (m_pm != 0) {
328 XFreePixmap(FbTk::App::instance()->display(), m_pm); 338 XFreePixmap(s_display, m_pm);
329 m_pm = 0; 339 m_pm = 0;
330 } 340 }
331 m_width = 0; 341 m_width = 0;
@@ -333,13 +343,13 @@ void FbPixmap::free() {
333 m_depth = 0; 343 m_depth = 0;
334} 344}
335 345
336void FbPixmap::create(Drawable src, 346void FbPixmap::create(Drawable src,
337 unsigned int width, unsigned int height, 347 unsigned int width, unsigned int height,
338 int depth) { 348 int depth) {
339 if (src == 0) 349 if (src == 0)
340 return; 350 return;
341 351
342 m_pm = XCreatePixmap(FbTk::App::instance()->display(), 352 m_pm = XCreatePixmap(s_display,
343 src, width, height, depth); 353 src, width, height, depth);
344 if (m_pm == 0) 354 if (m_pm == 0)
345 return; 355 return;