diff options
Diffstat (limited to 'src/FbTk/FbPixmap.cc')
-rw-r--r-- | src/FbTk/FbPixmap.cc | 166 |
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 | ||
33 | namespace FbTk { | 33 | namespace FbTk { |
34 | 34 | ||
35 | FbPixmap::FbPixmap():m_pm(0), | 35 | FbPixmap::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 | ||
39 | FbPixmap::FbPixmap(const FbPixmap &the_copy):m_pm(0), | 40 | FbPixmap::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 | ||
45 | FbPixmap::FbPixmap(Pixmap pm):m_pm(0), | 46 | FbPixmap::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 | ||
54 | FbPixmap::FbPixmap(const FbDrawable &src, | 55 | FbPixmap::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 | ||
63 | FbPixmap::FbPixmap(Drawable src, | 64 | FbPixmap::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 | ||
172 | void FbPixmap::rotate() { | 171 | void 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 | ||
206 | void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) { | 203 | void 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 | ||
253 | void FbPixmap::tile(unsigned int dest_width, unsigned int dest_height) { | 248 | void 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 | ||
289 | Pixmap FbPixmap::getRootPixmap(int screen_num) { | 284 | Pixmap 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 | ||
326 | void FbPixmap::free() { | 336 | void 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 | ||
336 | void FbPixmap::create(Drawable src, | 346 | void 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; |