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 |
… | |
… | |
28 | #include "rxvt.h" /* NECESSARY */ |
25 | #include "rxvt.h" /* NECESSARY */ |
29 | |
26 | |
30 | #define DO_TIMING_TEST 0 |
27 | #define DO_TIMING_TEST 0 |
31 | |
28 | |
32 | #if DO_TIMING_TEST |
29 | #if DO_TIMING_TEST |
|
|
30 | # include <sys/time.h> |
33 | #define TIMING_TEST_START(id) \ |
31 | #define TIMING_TEST_START(id) \ |
34 | struct timeval timing_test_##id##_stv;\ |
32 | struct timeval timing_test_##id##_stv;\ |
35 | gettimeofday (&timing_test_##id##_stv, NULL); |
33 | gettimeofday (&timing_test_##id##_stv, NULL); |
36 | |
34 | |
37 | #define TIMING_TEST_PRINT_RESULT(id) \ |
35 | #define TIMING_TEST_PRINT_RESULT(id) \ |
… | |
… | |
305 | y = x; |
303 | y = x; |
306 | geom_flags |= YValue; |
304 | geom_flags |= YValue; |
307 | } |
305 | } |
308 | |
306 | |
309 | if (flags & geometrySet) |
307 | if (flags & geometrySet) |
|
|
308 | { |
310 | {/* new geometry is an adjustment to the old one ! */ |
309 | /* new geometry is an adjustment to the old one ! */ |
311 | if ((geom_flags & WidthValue) && (geom_flags & HeightValue)) |
310 | if ((geom_flags & WidthValue) && (geom_flags & HeightValue)) |
312 | { |
311 | { |
313 | if (w == 0 && h != 0) |
312 | if (w == 0 && h != 0) |
314 | { |
313 | { |
315 | w = h_scale; |
314 | w = h_scale; |
… | |
… | |
331 | } |
330 | } |
332 | } |
331 | } |
333 | else /* setting up geometry from scratch */ |
332 | else /* setting up geometry from scratch */ |
334 | { |
333 | { |
335 | if (!(geom_flags & XValue)) |
334 | if (!(geom_flags & XValue)) |
|
|
335 | { |
336 | {/* use default geometry - centered */ |
336 | /* use default geometry - centered */ |
337 | x = y = defaultAlign; |
337 | x = y = defaultAlign; |
338 | } |
338 | } |
339 | else if (!(geom_flags & YValue)) |
339 | else if (!(geom_flags & YValue)) |
340 | y = x; |
340 | y = x; |
341 | |
341 | |
342 | if ((geom_flags & (WidthValue|HeightValue)) == 0) |
342 | if ((geom_flags & (WidthValue|HeightValue)) == 0) |
|
|
343 | { |
343 | {/* use default geometry - scaled */ |
344 | /* use default geometry - scaled */ |
344 | w = h = defaultScale; |
345 | w = h = defaultScale; |
345 | } |
346 | } |
346 | else if (geom_flags & WidthValue) |
347 | else if (geom_flags & WidthValue) |
347 | { |
348 | { |
348 | if (!(geom_flags & HeightValue)) |
349 | if (!(geom_flags & HeightValue)) |
… | |
… | |
351 | else |
352 | else |
352 | w = h; |
353 | w = h; |
353 | } |
354 | } |
354 | } /* done parsing geometry string */ |
355 | } /* done parsing geometry string */ |
355 | else if (!(flags & geometrySet)) |
356 | else if (!(flags & geometrySet)) |
|
|
357 | { |
356 | { /* default geometry - scaled and centered */ |
358 | /* default geometry - scaled and centered */ |
357 | x = y = defaultAlign; |
359 | x = y = defaultAlign; |
358 | w = h = defaultScale; |
360 | w = h = defaultScale; |
359 | } |
361 | } |
360 | |
362 | |
361 | if (!(flags & geometrySet)) |
363 | if (!(flags & geometrySet)) |
… | |
… | |
433 | if (new_flags != flags) |
435 | if (new_flags != flags) |
434 | { |
436 | { |
435 | flags = new_flags; |
437 | flags = new_flags; |
436 | changed++; |
438 | changed++; |
437 | } |
439 | } |
438 | //fprintf( stderr, "flags = %lX, scale = %ux%u, align=%+d%+d\n", |
440 | //fprintf (stderr, "flags = %lX, scale = %ux%u, align=%+d%+d\n", |
439 | // flags, h_scale, v_scale, h_align, v_align); |
441 | // flags, h_scale, v_scale, h_align, v_align); |
440 | return (changed > 0); |
442 | return (changed > 0); |
441 | } |
443 | } |
442 | |
444 | |
443 | # ifdef HAVE_AFTERIMAGE |
445 | # ifdef HAVE_AFTERIMAGE |
… | |
… | |
507 | h > 0 ? h : original_asim->height, |
509 | h > 0 ? h : original_asim->height, |
508 | background ? ASA_ASImage : ASA_XImage, |
510 | background ? ASA_ASImage : ASA_XImage, |
509 | 100, ASIMAGE_QUALITY_DEFAULT); |
511 | 100, ASIMAGE_QUALITY_DEFAULT); |
510 | } |
512 | } |
511 | if (background == NULL) |
513 | if (background == NULL) |
|
|
514 | { |
512 | {/* if tiling - pixmap has to be sized exactly as the image, |
515 | /* if tiling - pixmap has to be sized exactly as the image, |
513 | but there is no need to make it bigger then the window! */ |
516 | but there is no need to make it bigger then the window! */ |
514 | if (h_scale == 0) |
517 | if (h_scale == 0) |
515 | new_pmap_width = min (result->width, target_width); |
518 | new_pmap_width = min (result->width, target_width); |
516 | if (v_scale == 0) |
519 | if (v_scale == 0) |
517 | new_pmap_height = min (result->height, target_height); |
520 | new_pmap_height = min (result->height, target_height); |
518 | /* we also need to tile our image in one or both directions */ |
521 | /* we also need to tile our image in one or both directions */ |
… | |
… | |
532 | result = tmp; |
535 | result = tmp; |
533 | } |
536 | } |
534 | } |
537 | } |
535 | } |
538 | } |
536 | else |
539 | else |
|
|
540 | { |
537 | {/* if blending background and image - pixmap has to be sized same as target window */ |
541 | /* if blending background and image - pixmap has to be sized same as target window */ |
538 | ASImageLayer *layers = create_image_layers (2); |
542 | ASImageLayer *layers = create_image_layers (2); |
539 | ASImage *merged_im = NULL; |
543 | ASImage *merged_im = NULL; |
540 | |
544 | |
541 | layers[0].im = background; |
545 | layers[0].im = background; |
542 | layers[0].clip_width = target_width; |
546 | layers[0].clip_width = target_width; |
543 | layers[0].clip_height = target_height; |
547 | layers[0].clip_height = target_height; |
544 | layers[0].tint = background_tint; |
548 | layers[0].tint = background_tint; |
545 | layers[1].im = result; |
549 | layers[1].im = result; |
546 | if (w <= 0) |
550 | if (w <= 0) |
|
|
551 | { |
547 | {/* tile horizontally */ |
552 | /* tile horizontally */ |
548 | while (x > 0) x -= (int)result->width; |
553 | while (x > 0) x -= (int)result->width; |
549 | layers[1].dst_x = x; |
554 | layers[1].dst_x = x; |
550 | layers[1].clip_width = result->width+target_width; |
555 | layers[1].clip_width = result->width+target_width; |
551 | } |
556 | } |
552 | else |
557 | else |
|
|
558 | { |
553 | {/* clip horizontally */ |
559 | /* clip horizontally */ |
554 | layers[1].dst_x = x; |
560 | layers[1].dst_x = x; |
555 | layers[1].clip_width = result->width; |
561 | layers[1].clip_width = result->width; |
556 | } |
562 | } |
557 | if (h <= 0) |
563 | if (h <= 0) |
558 | { |
564 | { |
… | |
… | |
845 | if (sx + window_width <= 0 || sy + window_height <= 0 |
851 | if (sx + window_width <= 0 || sy + window_height <= 0 |
846 | || sx >= root_width || sy >= root_height) |
852 | || sx >= root_width || sy >= root_height) |
847 | return 0; |
853 | return 0; |
848 | |
854 | |
849 | if (root_pixmap != None) |
855 | if (root_pixmap != None) |
|
|
856 | { |
850 | {/* we want to validate the pixmap and get it's size at the same time : */ |
857 | /* we want to validate the pixmap and get it's size at the same time : */ |
851 | int junk; |
858 | int junk; |
852 | unsigned int ujunk; |
859 | unsigned int ujunk; |
853 | /* root pixmap may be bad - allow a error */ |
860 | /* root pixmap may be bad - allow a error */ |
854 | target->allowedxerror = -1; |
861 | target->allowedxerror = -1; |
855 | |
862 | |
… | |
… | |
864 | |
871 | |
865 | if (tiled_root_pmap == None) /* something really bad happened - abort */ |
872 | if (tiled_root_pmap == None) /* something really bad happened - abort */ |
866 | return 0; |
873 | return 0; |
867 | |
874 | |
868 | if (root_pixmap == None) |
875 | if (root_pixmap == None) |
|
|
876 | { |
869 | { /* use tricks to obtain the root background image :*/ |
877 | /* use tricks to obtain the root background image :*/ |
870 | /* we want to create Overrideredirect window overlapping out window |
878 | /* we want to create Overrideredirect window overlapping out window |
871 | with background type of Parent Relative and then grab it */ |
879 | with background type of Parent Relative and then grab it */ |
872 | XSetWindowAttributes attr; |
880 | XSetWindowAttributes attr; |
873 | Window src; |
881 | Window src; |
874 | bool success = false; |
882 | bool success = false; |
… | |
… | |
894 | * but to be on the safe side - let's check for the actuall event to arrive : */ |
902 | * but to be on the safe side - let's check for the actuall event to arrive : */ |
895 | while (XCheckWindowEvent (dpy, src, ExposureMask, &event)) |
903 | while (XCheckWindowEvent (dpy, src, ExposureMask, &event)) |
896 | ++ev_count; |
904 | ++ev_count; |
897 | |
905 | |
898 | if (ev_count > 0); |
906 | if (ev_count > 0); |
|
|
907 | { |
899 | { /* hooray! - we can grab the image! */ |
908 | /* hooray! - we can grab the image! */ |
900 | gc = XCreateGC (dpy, root, 0, NULL); |
909 | gc = XCreateGC (dpy, root, 0, NULL); |
901 | if (gc) |
910 | if (gc) |
902 | { |
911 | { |
903 | XCopyArea (dpy, src, tiled_root_pmap, gc, 0, 0, window_width, window_height, 0, 0); |
912 | XCopyArea (dpy, src, tiled_root_pmap, gc, 0, 0, window_width, window_height, 0, 0); |
904 | success = true; |
913 | success = true; |
… | |
… | |
916 | } |
925 | } |
917 | else |
926 | else |
918 | result |= transpPmapTiled; |
927 | result |= transpPmapTiled; |
919 | } |
928 | } |
920 | else |
929 | else |
|
|
930 | { |
921 | {/* strightforward pixmap copy */ |
931 | /* strightforward pixmap copy */ |
922 | gcv.tile = root_pixmap; |
932 | gcv.tile = root_pixmap; |
923 | gcv.fill_style = FillTiled; |
933 | gcv.fill_style = FillTiled; |
924 | |
934 | |
925 | while (sx < 0) sx += (int)root_width; |
935 | while (sx < 0) sx += (int)root_width; |
926 | while (sy < 0) sy += (int)root_height; |
936 | while (sy < 0) sy += (int)root_height; |
… | |
… | |
974 | { |
984 | { |
975 | c.r = (c.r * shade) / 100; |
985 | c.r = (c.r * shade) / 100; |
976 | c.g = (c.g * shade) / 100; |
986 | c.g = (c.g * shade) / 100; |
977 | c.b = (c.b * shade) / 100; |
987 | c.b = (c.b * shade) / 100; |
978 | } |
988 | } |
979 | else if( shade > 100 && shade < 200) |
989 | else if (shade > 100 && shade < 200) |
980 | { |
990 | { |
981 | c.r = (c.r * (200 - shade)) / 100; |
991 | c.r = (c.r * (200 - shade)) / 100; |
982 | c.g = (c.g * (200 - shade)) / 100; |
992 | c.g = (c.g * (200 - shade)) / 100; |
983 | c.b = (c.b * (200 - shade)) / 100; |
993 | c.b = (c.b * (200 - shade)) / 100; |
984 | } |
994 | } |
… | |
… | |
1189 | pmap_width = result->width; |
1199 | pmap_width = result->width; |
1190 | pmap_height = result->height; |
1200 | pmap_height = result->height; |
1191 | pmap_depth = target->depth; |
1201 | pmap_depth = target->depth; |
1192 | } |
1202 | } |
1193 | if (pmap_depth != result->depth) |
1203 | if (pmap_depth != result->depth) |
|
|
1204 | { |
1194 | { /* Bad Match error will ensue ! stupid X !!!! */ |
1205 | /* Bad Match error will ensue ! stupid X !!!! */ |
1195 | if( result->depth == 24 && pmap_depth == 32) |
1206 | if (result->depth == 24 && pmap_depth == 32) |
1196 | result->depth = 32; |
1207 | result->depth = 32; |
1197 | else if( result->depth == 32 && pmap_depth == 24) |
1208 | else if (result->depth == 32 && pmap_depth == 24) |
1198 | result->depth = 24; |
1209 | result->depth = 24; |
1199 | else |
1210 | else |
1200 | { |
1211 | { |
1201 | /* TODO: implement image recoding */ |
1212 | /* TODO: implement image recoding */ |
1202 | } |
1213 | } |
… | |
… | |
1245 | { |
1256 | { |
1246 | if (target) |
1257 | if (target) |
1247 | { |
1258 | { |
1248 | flags &= ~isVtOrigin; |
1259 | flags &= ~isVtOrigin; |
1249 | if (pixmap != None) |
1260 | if (pixmap != None) |
|
|
1261 | { |
1250 | { /* set target's background to pixmap */ |
1262 | /* set target's background to pixmap */ |
1251 | # ifdef ENABLE_TRANSPARENCY |
1263 | # ifdef ENABLE_TRANSPARENCY |
1252 | if (flags & isTransparent) |
1264 | if (flags & isTransparent) |
1253 | { |
1265 | { |
1254 | XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); |
1266 | XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); |
1255 | XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); |
1267 | XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); |
… | |
… | |
1271 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
1283 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
1272 | # endif |
1284 | # endif |
1273 | } |
1285 | } |
1274 | } |
1286 | } |
1275 | else |
1287 | else |
|
|
1288 | { |
1276 | { /* set target background to a pixel */ |
1289 | /* set target background to a pixel */ |
1277 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
1290 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
1278 | XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); |
1291 | XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); |
1279 | /* do we also need to set scrollbar's background here ? */ |
1292 | /* do we also need to set scrollbar's background here ? */ |
1280 | # if HAVE_SCROLLBARS |
1293 | # if HAVE_SCROLLBARS |
1281 | if (target->scrollBar.win) |
1294 | if (target->scrollBar.win) |