diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2011-02-21 18:21:38 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2011-02-21 18:21:38 (GMT) |
commit | 341b2f43e511e39dd6a938e8fbdef8a0d5e66c9a (patch) | |
tree | 1c507755255a1ede671061511ea34f775d74b4fb /src | |
parent | ccb5ef6624636f684a941caad2d0ade4d4f7cd96 (diff) | |
download | fluxbox-341b2f43e511e39dd6a938e8fbdef8a0d5e66c9a.zip fluxbox-341b2f43e511e39dd6a938e8fbdef8a0d5e66c9a.tar.bz2 |
Fix bug: 'src_image' might be NULL if width||height are 0 (#3188223)
With ROT90-SystemTray fluxbox crashed. It is a bit unclear of where
to catch pixmaps / windows with either width or height equal to 0; IMHO
this needs more investigation.
Diffstat (limited to 'src')
-rw-r--r-- | src/FbTk/FbPixmap.cc | 89 |
1 files changed, 49 insertions, 40 deletions
diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc index a347e23..160d478 100644 --- a/src/FbTk/FbPixmap.cc +++ b/src/FbTk/FbPixmap.cc | |||
@@ -218,61 +218,70 @@ void FbPixmap::rotate(FbTk::Orientation orient) { | |||
218 | unsigned int neww = oldw, newh = oldh; | 218 | unsigned int neww = oldw, newh = oldh; |
219 | translateSize(orient, neww, newh); | 219 | translateSize(orient, neww, newh); |
220 | 220 | ||
221 | // reverse height/width for new pixmap | ||
222 | FbPixmap new_pm(drawable(), neww, newh, depth()); | ||
223 | |||
224 | // width|height could be 0. this happens (for example) if | ||
225 | // the systemtray-tool is ROT90. in that case 'src_image' | ||
226 | // becomes NULL and caused a SIGSEV upon XDestroyImage() | ||
227 | // TODO: catch dimensions with '0' earlier? | ||
228 | // | ||
221 | // make an image copy | 229 | // make an image copy |
222 | XImage *src_image = XGetImage(display(), drawable(), | 230 | XImage *src_image = XGetImage(display(), drawable(), |
223 | 0, 0, // pos | 231 | 0, 0, // pos |
224 | oldw, oldh, // size | 232 | oldw, oldh, // size |
225 | ~0, // plane mask | 233 | ~0, // plane mask |
226 | ZPixmap); // format | 234 | ZPixmap); // format |
227 | // reverse height/width for new pixmap | 235 | if (src_image) { |
228 | FbPixmap new_pm(drawable(), neww, newh, depth()); | ||
229 | 236 | ||
230 | GContext gc(drawable()); | 237 | GContext gc(drawable()); |
231 | 238 | ||
232 | if (orient == ROT180) { | 239 | if (orient == ROT180) { |
233 | unsigned int srcx, srcy, destx, desty; | 240 | unsigned int srcx, srcy, destx, desty; |
234 | for (srcy = 0, desty = oldh; srcy < oldh; ++srcy, --desty) { | 241 | for (srcy = 0, desty = oldh; srcy < oldh; ++srcy, --desty) { |
235 | for (srcx = 0, destx = oldw; srcx < oldw; ++srcx, --destx) { | 242 | for (srcx = 0, destx = oldw; srcx < oldw; ++srcx, --destx) { |
236 | gc.setForeground(XGetPixel(src_image, srcx, srcy)); | 243 | gc.setForeground(XGetPixel(src_image, srcx, srcy)); |
237 | XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); | 244 | XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); |
245 | } | ||
246 | } | ||
247 | } else { | ||
248 | // need to flip x and y | ||
249 | |||
250 | // set start, end and direction based on rotation | ||
251 | // NOTE that startx etc are in the direction of the OLD pixmap | ||
252 | unsigned int startx = 0, starty = 0; | ||
253 | int dirx = 0, diry = 0; | ||
254 | switch (orient) { | ||
255 | case ROT90: | ||
256 | startx = neww-1; | ||
257 | starty = 0; | ||
258 | dirx = -1; | ||
259 | diry = 1; | ||
260 | break; | ||
261 | case ROT270: | ||
262 | startx = 0; | ||
263 | starty = newh-1; | ||
264 | dirx = 1; | ||
265 | diry = -1; | ||
266 | break; | ||
267 | default: // kill warning | ||
268 | break; | ||
238 | } | 269 | } |
239 | } | ||
240 | } else { | ||
241 | // need to flip x and y | ||
242 | |||
243 | // set start, end and direction based on rotation | ||
244 | // NOTE that startx etc are in the direction of the OLD pixmap | ||
245 | unsigned int startx = 0, starty = 0; | ||
246 | int dirx = 0, diry = 0; | ||
247 | switch (orient) { | ||
248 | case ROT90: | ||
249 | startx = neww-1; | ||
250 | starty = 0; | ||
251 | dirx = -1; | ||
252 | diry = 1; | ||
253 | break; | ||
254 | case ROT270: | ||
255 | startx = 0; | ||
256 | starty = newh-1; | ||
257 | dirx = 1; | ||
258 | diry = -1; | ||
259 | break; | ||
260 | default: // kill warning | ||
261 | break; | ||
262 | } | ||
263 | 270 | ||
264 | 271 | ||
265 | // copy new area | 272 | // copy new area |
266 | unsigned int srcx, srcy, destx, desty; | 273 | unsigned int srcx, srcy, destx, desty; |
267 | for (srcy = 0, destx = startx; srcy < oldh; ++srcy, destx+=dirx) { | 274 | for (srcy = 0, destx = startx; srcy < oldh; ++srcy, destx+=dirx) { |
268 | for (srcx = 0, desty = starty; srcx < oldw; ++srcx, desty+=diry) { | 275 | for (srcx = 0, desty = starty; srcx < oldw; ++srcx, desty+=diry) { |
269 | gc.setForeground(XGetPixel(src_image, srcx, srcy)); | 276 | gc.setForeground(XGetPixel(src_image, srcx, srcy)); |
270 | XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); | 277 | XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty); |
278 | } | ||
271 | } | 279 | } |
272 | } | 280 | } |
281 | |||
282 | XDestroyImage(src_image); | ||
273 | } | 283 | } |
274 | 284 | ||
275 | XDestroyImage(src_image); | ||
276 | // free old pixmap and set new from new_pm | 285 | // free old pixmap and set new from new_pm |
277 | free(); | 286 | free(); |
278 | 287 | ||