1 | /*----------------------------------------------------------------------* |
1 | /*----------------------------------------------------------------------* |
2 | * File: background.C - former xpm.C |
2 | * File: background.C - former xpm.C |
3 | *----------------------------------------------------------------------* |
3 | *----------------------------------------------------------------------* |
4 | * |
4 | * |
5 | * All portions of code are copyright by their respective author/s. |
5 | * All portions of code are copyright by their respective author/s. |
6 | * Copyright (c) 1997 Carsten Haitzler <raster@zip.com.au> |
|
|
7 | * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de> |
|
|
8 | * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> |
|
|
9 | * Copyright (c) 2005-2006 Marc Lehmann <pcg@goof.com> |
6 | * Copyright (c) 2005-2006 Marc Lehmann <pcg@goof.com> |
10 | * Copyright (c) 2007 Sasha Vasko <sasha@aftercode.net> |
7 | * Copyright (c) 2007 Sasha Vasko <sasha@aftercode.net> |
11 | * |
8 | * |
12 | * This program is free software; you can redistribute it and/or modify |
9 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by |
10 | * it under the terms of the GNU General Public License as published by |
… | |
… | |
87 | * scale Scale both up and down |
84 | * scale Scale both up and down |
88 | * auto Same as 100x100+50+50 |
85 | * auto Same as 100x100+50+50 |
89 | */ |
86 | */ |
90 | |
87 | |
91 | #ifdef HAVE_BG_PIXMAP |
88 | #ifdef HAVE_BG_PIXMAP |
92 | bgPixmap_t::bgPixmap_t() |
89 | bgPixmap_t::bgPixmap_t () |
93 | { |
90 | { |
94 | #ifdef HAVE_AFTERIMAGE |
91 | #ifdef HAVE_AFTERIMAGE |
95 | original_asim = NULL; |
92 | original_asim = NULL; |
96 | #endif |
93 | #endif |
97 | #ifdef BG_IMAGE_FROM_FILE |
94 | #ifdef BG_IMAGE_FROM_FILE |
… | |
… | |
100 | #endif |
97 | #endif |
101 | flags = 0; |
98 | flags = 0; |
102 | pixmap = None; |
99 | pixmap = None; |
103 | } |
100 | } |
104 | |
101 | |
105 | bgPixmap_t::~bgPixmap_t() |
102 | void |
|
|
103 | bgPixmap_t::destroy () |
106 | { |
104 | { |
107 | #ifdef HAVE_AFTERIMAGE |
105 | #ifdef HAVE_AFTERIMAGE |
108 | if (original_asim) |
106 | if (original_asim) |
109 | safe_asimage_destroy (original_asim); |
107 | safe_asimage_destroy (original_asim); |
110 | #endif |
108 | #endif |
|
|
109 | |
111 | if (pixmap && target) |
110 | if (pixmap && target) |
112 | XFreePixmap (target->dpy, pixmap); |
111 | XFreePixmap (target->dpy, pixmap); |
113 | } |
112 | } |
114 | |
113 | |
115 | bool |
114 | bool |
… | |
… | |
303 | y = x; |
302 | y = x; |
304 | geom_flags |= YValue; |
303 | geom_flags |= YValue; |
305 | } |
304 | } |
306 | |
305 | |
307 | if (flags & geometrySet) |
306 | if (flags & geometrySet) |
|
|
307 | { |
308 | {/* new geometry is an adjustment to the old one ! */ |
308 | /* new geometry is an adjustment to the old one ! */ |
309 | if ((geom_flags & WidthValue) && (geom_flags & HeightValue)) |
309 | if ((geom_flags & WidthValue) && (geom_flags & HeightValue)) |
310 | { |
310 | { |
311 | if (w == 0 && h != 0) |
311 | if (w == 0 && h != 0) |
312 | { |
312 | { |
313 | w = h_scale; |
313 | w = h_scale; |
… | |
… | |
329 | } |
329 | } |
330 | } |
330 | } |
331 | else /* setting up geometry from scratch */ |
331 | else /* setting up geometry from scratch */ |
332 | { |
332 | { |
333 | if (!(geom_flags & XValue)) |
333 | if (!(geom_flags & XValue)) |
|
|
334 | { |
334 | {/* use default geometry - centered */ |
335 | /* use default geometry - centered */ |
335 | x = y = defaultAlign; |
336 | x = y = defaultAlign; |
336 | } |
337 | } |
337 | else if (!(geom_flags & YValue)) |
338 | else if (!(geom_flags & YValue)) |
338 | y = x; |
339 | y = x; |
339 | |
340 | |
340 | if ((geom_flags & (WidthValue|HeightValue)) == 0) |
341 | if ((geom_flags & (WidthValue|HeightValue)) == 0) |
|
|
342 | { |
341 | {/* use default geometry - scaled */ |
343 | /* use default geometry - scaled */ |
342 | w = h = defaultScale; |
344 | w = h = defaultScale; |
343 | } |
345 | } |
344 | else if (geom_flags & WidthValue) |
346 | else if (geom_flags & WidthValue) |
345 | { |
347 | { |
346 | if (!(geom_flags & HeightValue)) |
348 | if (!(geom_flags & HeightValue)) |
… | |
… | |
349 | else |
351 | else |
350 | w = h; |
352 | w = h; |
351 | } |
353 | } |
352 | } /* done parsing geometry string */ |
354 | } /* done parsing geometry string */ |
353 | else if (!(flags & geometrySet)) |
355 | else if (!(flags & geometrySet)) |
|
|
356 | { |
354 | { /* default geometry - scaled and centered */ |
357 | /* default geometry - scaled and centered */ |
355 | x = y = defaultAlign; |
358 | x = y = defaultAlign; |
356 | w = h = defaultScale; |
359 | w = h = defaultScale; |
357 | } |
360 | } |
358 | |
361 | |
359 | if (!(flags & geometrySet)) |
362 | if (!(flags & geometrySet)) |
… | |
… | |
505 | h > 0 ? h : original_asim->height, |
508 | h > 0 ? h : original_asim->height, |
506 | background ? ASA_ASImage : ASA_XImage, |
509 | background ? ASA_ASImage : ASA_XImage, |
507 | 100, ASIMAGE_QUALITY_DEFAULT); |
510 | 100, ASIMAGE_QUALITY_DEFAULT); |
508 | } |
511 | } |
509 | if (background == NULL) |
512 | if (background == NULL) |
|
|
513 | { |
510 | {/* if tiling - pixmap has to be sized exactly as the image, |
514 | /* if tiling - pixmap has to be sized exactly as the image, |
511 | but there is no need to make it bigger then the window! */ |
515 | but there is no need to make it bigger then the window! */ |
512 | if (h_scale == 0) |
516 | if (h_scale == 0) |
513 | new_pmap_width = min (result->width, target_width); |
517 | new_pmap_width = min (result->width, target_width); |
514 | if (v_scale == 0) |
518 | if (v_scale == 0) |
515 | new_pmap_height = min (result->height, target_height); |
519 | new_pmap_height = min (result->height, target_height); |
516 | /* we also need to tile our image in one or both directions */ |
520 | /* we also need to tile our image in one or both directions */ |
… | |
… | |
530 | result = tmp; |
534 | result = tmp; |
531 | } |
535 | } |
532 | } |
536 | } |
533 | } |
537 | } |
534 | else |
538 | else |
|
|
539 | { |
535 | {/* if blending background and image - pixmap has to be sized same as target window */ |
540 | /* if blending background and image - pixmap has to be sized same as target window */ |
536 | ASImageLayer *layers = create_image_layers (2); |
541 | ASImageLayer *layers = create_image_layers (2); |
537 | ASImage *merged_im = NULL; |
542 | ASImage *merged_im = NULL; |
538 | |
543 | |
539 | layers[0].im = background; |
544 | layers[0].im = background; |
540 | layers[0].clip_width = target_width; |
545 | layers[0].clip_width = target_width; |
541 | layers[0].clip_height = target_height; |
546 | layers[0].clip_height = target_height; |
542 | layers[0].tint = background_tint; |
547 | layers[0].tint = background_tint; |
543 | layers[1].im = result; |
548 | layers[1].im = result; |
544 | if (w <= 0) |
549 | if (w <= 0) |
|
|
550 | { |
545 | {/* tile horizontally */ |
551 | /* tile horizontally */ |
546 | while (x > 0) x -= (int)result->width; |
552 | while (x > 0) x -= (int)result->width; |
547 | layers[1].dst_x = x; |
553 | layers[1].dst_x = x; |
548 | layers[1].clip_width = result->width+target_width; |
554 | layers[1].clip_width = result->width+target_width; |
549 | } |
555 | } |
550 | else |
556 | else |
|
|
557 | { |
551 | {/* clip horizontally */ |
558 | /* clip horizontally */ |
552 | layers[1].dst_x = x; |
559 | layers[1].dst_x = x; |
553 | layers[1].clip_width = result->width; |
560 | layers[1].clip_width = result->width; |
554 | } |
561 | } |
555 | if (h <= 0) |
562 | if (h <= 0) |
556 | { |
563 | { |
… | |
… | |
843 | if (sx + window_width <= 0 || sy + window_height <= 0 |
850 | if (sx + window_width <= 0 || sy + window_height <= 0 |
844 | || sx >= root_width || sy >= root_height) |
851 | || sx >= root_width || sy >= root_height) |
845 | return 0; |
852 | return 0; |
846 | |
853 | |
847 | if (root_pixmap != None) |
854 | if (root_pixmap != None) |
|
|
855 | { |
848 | {/* we want to validate the pixmap and get it's size at the same time : */ |
856 | /* we want to validate the pixmap and get it's size at the same time : */ |
849 | int junk; |
857 | int junk; |
850 | unsigned int ujunk; |
858 | unsigned int ujunk; |
851 | /* root pixmap may be bad - allow a error */ |
859 | /* root pixmap may be bad - allow a error */ |
852 | target->allowedxerror = -1; |
860 | target->allowedxerror = -1; |
853 | |
861 | |
… | |
… | |
862 | |
870 | |
863 | if (tiled_root_pmap == None) /* something really bad happened - abort */ |
871 | if (tiled_root_pmap == None) /* something really bad happened - abort */ |
864 | return 0; |
872 | return 0; |
865 | |
873 | |
866 | if (root_pixmap == None) |
874 | if (root_pixmap == None) |
|
|
875 | { |
867 | { /* use tricks to obtain the root background image :*/ |
876 | /* use tricks to obtain the root background image :*/ |
868 | /* we want to create Overrideredirect window overlapping out window |
877 | /* we want to create Overrideredirect window overlapping out window |
869 | with background type of Parent Relative and then grab it */ |
878 | with background type of Parent Relative and then grab it */ |
870 | XSetWindowAttributes attr; |
879 | XSetWindowAttributes attr; |
871 | Window src; |
880 | Window src; |
872 | bool success = false; |
881 | bool success = false; |
… | |
… | |
892 | * but to be on the safe side - let's check for the actuall event to arrive : */ |
901 | * but to be on the safe side - let's check for the actuall event to arrive : */ |
893 | while (XCheckWindowEvent (dpy, src, ExposureMask, &event)) |
902 | while (XCheckWindowEvent (dpy, src, ExposureMask, &event)) |
894 | ++ev_count; |
903 | ++ev_count; |
895 | |
904 | |
896 | if (ev_count > 0); |
905 | if (ev_count > 0); |
|
|
906 | { |
897 | { /* hooray! - we can grab the image! */ |
907 | /* hooray! - we can grab the image! */ |
898 | gc = XCreateGC (dpy, root, 0, NULL); |
908 | gc = XCreateGC (dpy, root, 0, NULL); |
899 | if (gc) |
909 | if (gc) |
900 | { |
910 | { |
901 | XCopyArea (dpy, src, tiled_root_pmap, gc, 0, 0, window_width, window_height, 0, 0); |
911 | XCopyArea (dpy, src, tiled_root_pmap, gc, 0, 0, window_width, window_height, 0, 0); |
902 | success = true; |
912 | success = true; |
… | |
… | |
914 | } |
924 | } |
915 | else |
925 | else |
916 | result |= transpPmapTiled; |
926 | result |= transpPmapTiled; |
917 | } |
927 | } |
918 | else |
928 | else |
|
|
929 | { |
919 | {/* strightforward pixmap copy */ |
930 | /* strightforward pixmap copy */ |
920 | gcv.tile = root_pixmap; |
931 | gcv.tile = root_pixmap; |
921 | gcv.fill_style = FillTiled; |
932 | gcv.fill_style = FillTiled; |
922 | |
933 | |
923 | while (sx < 0) sx += (int)root_width; |
934 | while (sx < 0) sx += (int)root_width; |
924 | while (sy < 0) sy += (int)root_height; |
935 | while (sy < 0) sy += (int)root_height; |
… | |
… | |
1187 | pmap_width = result->width; |
1198 | pmap_width = result->width; |
1188 | pmap_height = result->height; |
1199 | pmap_height = result->height; |
1189 | pmap_depth = target->depth; |
1200 | pmap_depth = target->depth; |
1190 | } |
1201 | } |
1191 | if (pmap_depth != result->depth) |
1202 | if (pmap_depth != result->depth) |
|
|
1203 | { |
1192 | { /* Bad Match error will ensue ! stupid X !!!! */ |
1204 | /* Bad Match error will ensue ! stupid X !!!! */ |
1193 | if( result->depth == 24 && pmap_depth == 32) |
1205 | if( result->depth == 24 && pmap_depth == 32) |
1194 | result->depth = 32; |
1206 | result->depth = 32; |
1195 | else if( result->depth == 32 && pmap_depth == 24) |
1207 | else if( result->depth == 32 && pmap_depth == 24) |
1196 | result->depth = 24; |
1208 | result->depth = 24; |
1197 | else |
1209 | else |
… | |
… | |
1243 | { |
1255 | { |
1244 | if (target) |
1256 | if (target) |
1245 | { |
1257 | { |
1246 | flags &= ~isVtOrigin; |
1258 | flags &= ~isVtOrigin; |
1247 | if (pixmap != None) |
1259 | if (pixmap != None) |
|
|
1260 | { |
1248 | { /* set target's background to pixmap */ |
1261 | /* set target's background to pixmap */ |
1249 | # ifdef ENABLE_TRANSPARENCY |
1262 | # ifdef ENABLE_TRANSPARENCY |
1250 | if (flags & isTransparent) |
1263 | if (flags & isTransparent) |
1251 | { |
1264 | { |
1252 | XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); |
1265 | XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); |
1253 | XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); |
1266 | XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); |
… | |
… | |
1269 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
1282 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
1270 | # endif |
1283 | # endif |
1271 | } |
1284 | } |
1272 | } |
1285 | } |
1273 | else |
1286 | else |
|
|
1287 | { |
1274 | { /* set target background to a pixel */ |
1288 | /* set target background to a pixel */ |
1275 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
1289 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
1276 | XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); |
1290 | XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); |
1277 | /* do we also need to set scrollbar's background here ? */ |
1291 | /* do we also need to set scrollbar's background here ? */ |
1278 | # if HAVE_SCROLLBARS |
1292 | # if HAVE_SCROLLBARS |
1279 | if (target->scrollBar.win) |
1293 | if (target->scrollBar.win) |