diff options
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/FbPixmap.cc | 141 | ||||
-rw-r--r-- | src/FbTk/FbPixmap.hh | 9 |
2 files changed, 115 insertions, 35 deletions
diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc index b2937c3..ce28f0e 100644 --- a/src/FbTk/FbPixmap.cc +++ b/src/FbTk/FbPixmap.cc | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "FbPixmap.hh" | 24 | #include "FbPixmap.hh" |
25 | #include "App.hh" | 25 | #include "App.hh" |
26 | #include "GContext.hh" | 26 | #include "GContext.hh" |
27 | #include "Transparent.hh" | ||
27 | 28 | ||
28 | #include <X11/Xutil.h> | 29 | #include <X11/Xutil.h> |
29 | #include <X11/Xatom.h> | 30 | #include <X11/Xatom.h> |
@@ -34,6 +35,22 @@ using namespace std; | |||
34 | 35 | ||
35 | namespace FbTk { | 36 | namespace FbTk { |
36 | 37 | ||
38 | Pixmap *FbPixmap::m_root_pixmaps = 0; | ||
39 | |||
40 | const char* FbPixmap::root_prop_ids[] = { | ||
41 | "_XROOTPMAP_ID", | ||
42 | "_XSETROOT_ID", | ||
43 | 0 | ||
44 | }; | ||
45 | |||
46 | // same number as in root_prop_ids | ||
47 | Atom FbPixmap::root_prop_atoms[] = { | ||
48 | None, | ||
49 | None, | ||
50 | None | ||
51 | }; | ||
52 | |||
53 | |||
37 | FbPixmap::FbPixmap():m_pm(0), | 54 | FbPixmap::FbPixmap():m_pm(0), |
38 | m_width(0), m_height(0), | 55 | m_width(0), m_height(0), |
39 | m_depth(0) { | 56 | m_depth(0) { |
@@ -297,53 +314,107 @@ Pixmap FbPixmap::release() { | |||
297 | return ret; | 314 | return ret; |
298 | } | 315 | } |
299 | 316 | ||
317 | void FbPixmap::rootwinPropertyNotify(int screen_num, Atom atom) { | ||
318 | if (!FbTk::Transparent::haveRender()) | ||
319 | return; | ||
320 | |||
321 | checkAtoms(); | ||
322 | for (int i=0; root_prop_ids[i] != 0; ++i) { | ||
323 | if (root_prop_atoms[i] == atom) { | ||
324 | Pixmap root_pm = None; | ||
325 | Atom real_type; | ||
326 | int real_format; | ||
327 | unsigned long items_read, items_left; | ||
328 | unsigned long *data; | ||
329 | |||
330 | unsigned int prop = 0; | ||
331 | if (XGetWindowProperty(display(), | ||
332 | RootWindow(display(), i), | ||
333 | root_prop_atoms[i], | ||
334 | 0l, 1l, | ||
335 | False, XA_PIXMAP, | ||
336 | &real_type, &real_format, | ||
337 | &items_read, &items_left, | ||
338 | (unsigned char **) &data) == Success) { | ||
339 | if (real_format == 32 && items_read == 1) { | ||
340 | root_pm = (Pixmap) (*data); | ||
341 | } | ||
342 | XFree(data); | ||
343 | if (root_pm != None) | ||
344 | setRootPixmap(screen_num, root_pm); | ||
345 | } | ||
346 | break; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | void FbPixmap::setRootPixmap(int screen_num, Pixmap pm) { | ||
352 | if (!m_root_pixmaps) { | ||
353 | m_root_pixmaps = new Pixmap[ScreenCount(display())]; | ||
354 | } | ||
355 | |||
356 | m_root_pixmaps[screen_num] = pm; | ||
357 | } | ||
358 | |||
300 | Pixmap FbPixmap::getRootPixmap(int screen_num) { | 359 | Pixmap FbPixmap::getRootPixmap(int screen_num) { |
360 | if (!FbTk::Transparent::haveRender()) | ||
361 | return None; | ||
362 | |||
363 | if (!m_root_pixmaps) { | ||
364 | int numscreens = ScreenCount(display()); | ||
365 | for (int i=0; i < numscreens; ++i) { | ||
366 | Atom real_type; | ||
367 | int real_format; | ||
368 | unsigned long items_read, items_left; | ||
369 | unsigned long *data; | ||
301 | 370 | ||
302 | Atom real_type; | 371 | unsigned int prop = 0; |
303 | int real_format; | 372 | |
304 | unsigned long items_read, items_left; | 373 | static bool print_error = true; // print error_message only once |
305 | unsigned long *data; | 374 | static const char* error_message = { "\n\n !!! WARNING WARNING WARNING WARNING !!!!!\n" |
306 | |||
307 | unsigned int prop = 0; | ||
308 | static const char* prop_ids[] = { | ||
309 | "_XROOTPMAP_ID", | ||
310 | "_XSETROOT_ID", | ||
311 | 0 | ||
312 | }; | ||
313 | static bool print_error = true; // print error_message only once | ||
314 | static const char* error_message = { "\n\n !!! WARNING WARNING WARNING WARNING !!!!!\n" | ||
315 | " if you experience problems with transparency:\n" | 375 | " if you experience problems with transparency:\n" |
316 | " you are using a wallpapersetter that \n" | 376 | " you are using a wallpapersetter that \n" |
317 | " uses _XSETROOT_ID .. which we do not support.\n" | 377 | " uses _XSETROOT_ID .. which we do not support.\n" |
318 | " consult 'fbsetbg -i' or try any other wallpapersetter\n" | 378 | " consult 'fbsetbg -i' or try any other wallpapersetter\n" |
319 | " that uses _XROOTPMAP_ID !\n" | 379 | " that uses _XROOTPMAP_ID !\n" |
320 | " !!! WARNING WARNING WARNING WARNING !!!!!!\n\n" | 380 | " !!! WARNING WARNING WARNING WARNING !!!!!!\n\n" |
321 | }; | 381 | }; |
322 | 382 | ||
323 | Pixmap root_pm = None; | 383 | Pixmap root_pm = None; |
324 | for (prop = 0; prop_ids[prop]; prop++) { | 384 | for (prop = 0; root_prop_ids[prop]; prop++) { |
325 | if (XGetWindowProperty(display(), | 385 | checkAtoms(); |
326 | RootWindow(display(), screen_num), | 386 | if (XGetWindowProperty(display(), |
327 | XInternAtom(display(), prop_ids[prop], False), | 387 | RootWindow(display(), i), |
328 | 0l, 1l, | 388 | root_prop_atoms[i], |
329 | False, XA_PIXMAP, | 389 | 0l, 1l, |
330 | &real_type, &real_format, | 390 | False, XA_PIXMAP, |
331 | &items_read, &items_left, | 391 | &real_type, &real_format, |
332 | (unsigned char **) &data) == Success) { | 392 | &items_read, &items_left, |
333 | if (real_format == 32 && items_read == 1) { | 393 | (unsigned char **) &data) == Success) { |
334 | if (print_error && strcmp(prop_ids[prop], "_XSETROOT_ID") == 0) { | 394 | if (real_format == 32 && items_read == 1) { |
335 | cerr<<error_message; | 395 | if (print_error && strcmp(root_prop_ids[prop], "_XSETROOT_ID") == 0) { |
336 | print_error = false; | 396 | cerr<<error_message; |
337 | } else | 397 | print_error = false; |
338 | root_pm = (Pixmap) (*data); | 398 | } else |
399 | root_pm = (Pixmap) (*data); | ||
400 | } | ||
401 | XFree(data); | ||
402 | if (root_pm != None) | ||
403 | break; | ||
404 | } | ||
339 | } | 405 | } |
340 | XFree(data); | 406 | setRootPixmap(i, root_pm); |
341 | if (root_pm != None) | ||
342 | break; | ||
343 | } | 407 | } |
344 | } | 408 | } |
409 | return m_root_pixmaps[screen_num]; | ||
410 | } | ||
345 | 411 | ||
346 | return root_pm; | 412 | void FbPixmap::checkAtoms() { |
413 | for (int i=0; root_prop_ids[i] != 0; ++i) { | ||
414 | if (root_prop_atoms[i] == None) { | ||
415 | root_prop_atoms[i] = XInternAtom(display(), root_prop_ids[i], False); | ||
416 | } | ||
417 | } | ||
347 | } | 418 | } |
348 | 419 | ||
349 | void FbPixmap::free() { | 420 | void FbPixmap::free() { |
diff --git a/src/FbTk/FbPixmap.hh b/src/FbTk/FbPixmap.hh index c8640a2..ca81cf4 100644 --- a/src/FbTk/FbPixmap.hh +++ b/src/FbTk/FbPixmap.hh | |||
@@ -69,6 +69,7 @@ public: | |||
69 | inline int depth() const { return m_depth; } | 69 | inline int depth() const { return m_depth; } |
70 | 70 | ||
71 | static Pixmap getRootPixmap(int screen_num); | 71 | static Pixmap getRootPixmap(int screen_num); |
72 | static void FbPixmap::rootwinPropertyNotify(int screen_num, Atom atom); | ||
72 | 73 | ||
73 | void create(Drawable src, | 74 | void create(Drawable src, |
74 | unsigned int width, unsigned int height, | 75 | unsigned int width, unsigned int height, |
@@ -79,6 +80,14 @@ private: | |||
79 | Pixmap m_pm; | 80 | Pixmap m_pm; |
80 | unsigned int m_width, m_height; | 81 | unsigned int m_width, m_height; |
81 | int m_depth; | 82 | int m_depth; |
83 | |||
84 | /// Functions relating to the maintenance of root window pixmap caching | ||
85 | static void checkAtoms(); | ||
86 | static void setRootPixmap(int screen_num, Pixmap pm); | ||
87 | // array of pixmaps: 1 per screen | ||
88 | static Pixmap *m_root_pixmaps; | ||
89 | static const char *root_prop_ids[]; | ||
90 | static Atom root_prop_atoms[]; | ||
82 | }; | 91 | }; |
83 | 92 | ||
84 | } // end namespace FbTk | 93 | } // end namespace FbTk |