ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/background.C
(Generate patch)

Comparing rxvt-unicode/src/background.C (file contents):
Revision 1.106 by sf-exg, Mon Nov 1 11:37:02 2010 UTC vs.
Revision 1.111 by sf-exg, Fri Nov 5 17:27:58 2010 UTC

23 *---------------------------------------------------------------------*/ 23 *---------------------------------------------------------------------*/
24 24
25#include <cmath> 25#include <cmath>
26#include "../config.h" /* NECESSARY */ 26#include "../config.h" /* NECESSARY */
27#include "rxvt.h" /* NECESSARY */ 27#include "rxvt.h" /* NECESSARY */
28
29#if XRENDER
30# include <X11/extensions/Xrender.h>
31#endif
28 32
29#define DO_TIMING_TEST 0 33#define DO_TIMING_TEST 0
30 34
31#if DO_TIMING_TEST 35#if DO_TIMING_TEST
32# include <sys/time.h> 36# include <sys/time.h>
250} 254}
251 255
252bool 256bool
253bgPixmap_t::set_geometry (const char *geom) 257bgPixmap_t::set_geometry (const char *geom)
254{ 258{
259 bool changed = false;
255 int geom_flags = 0, changed = 0; 260 int geom_flags = 0;
256 int x = 0, y = 0; 261 int x = 0, y = 0;
257 unsigned int w = 0, h = 0; 262 unsigned int w = 0, h = 0;
258 unsigned int n; 263 unsigned int n;
259 unsigned long new_flags = (flags & (~geometryFlags)); 264 unsigned long new_flags = (flags & (~geometryFlags));
260 const char *p; 265 const char *p;
416 421
417 while (*ops != ':' && *ops != '\0') ++ops; 422 while (*ops != ':' && *ops != '\0') ++ops;
418 } /* done parsing ops */ 423 } /* done parsing ops */
419 } 424 }
420 425
421 if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) ++changed; 426 if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) changed = true;
422 if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) ++changed; 427 if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) changed = true;
423 if (check_set_align_value (geom_flags, XValue, h_align, x)) ++changed; 428 if (check_set_align_value (geom_flags, XValue, h_align, x)) changed = true;
424 if (check_set_align_value (geom_flags, YValue, v_align, y)) ++changed; 429 if (check_set_align_value (geom_flags, YValue, v_align, y)) changed = true;
425 } 430 }
426 431
427 if (new_flags != flags) 432 if (new_flags != flags)
428 { 433 {
429 flags = new_flags; 434 flags = new_flags;
430 changed++; 435 changed = true;
431 } 436 }
432 437
433 return (changed > 0); 438 return changed;
434} 439}
435 440
436void 441void
437bgPixmap_t::get_image_geometry (int image_width, int image_height, int &w, int &h, int &x, int &y) 442bgPixmap_t::get_image_geometry (int image_width, int image_height, int &w, int &h, int &x, int &y)
438{ 443{
729 return false; 734 return false;
730 735
731 if (!pixbuf) 736 if (!pixbuf)
732 return false; 737 return false;
733 738
734#if !XRENDER
735 if (background_flags) 739 if (background_flags
740 && !(flags & HAS_RENDER))
736 return false; 741 return false;
737#endif
738 742
739 GdkPixbuf *result; 743 GdkPixbuf *result;
740 744
741 int image_width = gdk_pixbuf_get_width (pixbuf); 745 int image_width = gdk_pixbuf_get_width (pixbuf);
742 int image_height = gdk_pixbuf_get_height (pixbuf); 746 int image_height = gdk_pixbuf_get_height (pixbuf);
909# endif /* HAVE_PIXBUF */ 913# endif /* HAVE_PIXBUF */
910 914
911bool 915bool
912bgPixmap_t::set_file (const char *file) 916bgPixmap_t::set_file (const char *file)
913{ 917{
914 assert (file); 918 if (!file || !*file)
919 return false;
915 920
916 if (*file)
917 {
918 if (const char *p = strchr (file, ';')) 921 if (const char *p = strchr (file, ';'))
919 { 922 {
920 size_t len = p - file; 923 size_t len = p - file;
921 char *f = rxvt_temp_buf<char> (len + 1); 924 char *f = rxvt_temp_buf<char> (len + 1);
922 memcpy (f, file, len); 925 memcpy (f, file, len);
923 f[len] = '\0'; 926 f[len] = '\0';
924 file = f; 927 file = f;
925 } 928 }
926 929
927# ifdef HAVE_AFTERIMAGE 930# ifdef HAVE_AFTERIMAGE
928 if (!target->asimman) 931 if (!target->asimman)
929 target->asimman = create_generic_imageman (target->rs[Rs_path]); 932 target->asimman = create_generic_imageman (target->rs[Rs_path]);
930 ASImage *image = get_asimage (target->asimman, file, 0xFFFFFFFF, 100); 933 ASImage *image = get_asimage (target->asimman, file, 0xFFFFFFFF, 100);
931 if (image) 934 if (image)
932 { 935 {
933 if (original_asim) 936 if (original_asim)
934 safe_asimage_destroy (original_asim); 937 safe_asimage_destroy (original_asim);
935 original_asim = image; 938 original_asim = image;
936 have_image = true; 939 have_image = true;
937 return true; 940 return true;
938 } 941 }
939# endif 942# endif
940 943
941# ifdef HAVE_PIXBUF 944# ifdef HAVE_PIXBUF
942 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL); 945 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL);
943 if (image) 946 if (image)
944 { 947 {
945 if (pixbuf) 948 if (pixbuf)
946 g_object_unref (pixbuf); 949 g_object_unref (pixbuf);
947 pixbuf = image; 950 pixbuf = image;
948 have_image = true; 951 have_image = true;
949 return true; 952 return true;
950 } 953 }
951# endif 954# endif
952 }
953 955
954 return false; 956 return false;
955} 957}
956 958
957# endif /* BG_IMAGE_FROM_FILE */ 959# endif /* BG_IMAGE_FROM_FILE */
970} 972}
971 973
972bool 974bool
973bgPixmap_t::set_blur_radius (const char *geom) 975bgPixmap_t::set_blur_radius (const char *geom)
974{ 976{
975 int changed = 0; 977 bool changed = false;
976 unsigned int hr, vr; 978 unsigned int hr, vr;
977 int junk; 979 int junk;
978 int geom_flags = XParseGeometry (geom, &junk, &junk, &hr, &vr); 980 int geom_flags = XParseGeometry (geom, &junk, &junk, &hr, &vr);
979 981
980 if (!(geom_flags & WidthValue)) 982 if (!(geom_flags & WidthValue))
985 min_it (hr, 128); 987 min_it (hr, 128);
986 min_it (vr, 128); 988 min_it (vr, 128);
987 989
988 if (h_blurRadius != hr) 990 if (h_blurRadius != hr)
989 { 991 {
990 ++changed; 992 changed = true;
991 h_blurRadius = hr; 993 h_blurRadius = hr;
992 } 994 }
993 995
994 if (v_blurRadius != vr) 996 if (v_blurRadius != vr)
995 { 997 {
996 ++changed; 998 changed = true;
997 v_blurRadius = vr; 999 v_blurRadius = vr;
998 } 1000 }
999 1001
1000 if (v_blurRadius == 0 && h_blurRadius == 0) 1002 if (v_blurRadius == 0 && h_blurRadius == 0)
1001 flags &= ~blurNeeded; 1003 flags &= ~blurNeeded;
1002 else 1004 else
1003 flags |= blurNeeded; 1005 flags |= blurNeeded;
1004 1006
1005#if XRENDER
1006 XFilters *filters = XRenderQueryFilters (target->dpy, target->vt);
1007 if (filters)
1008 {
1009 for (int i = 0; i < filters->nfilter; i++)
1010 if (!strcmp (filters->filter[i], FilterConvolution))
1011 flags |= bgPixmap_t::blurServerSide;
1012
1013 XFree (filters);
1014 }
1015#endif
1016
1017 return (changed > 0); 1007 return changed;
1018} 1008}
1019 1009
1020static inline unsigned long 1010static inline unsigned long
1021compute_tint_shade_flags (rxvt_color *tint, int shade) 1011compute_tint_shade_flags (rxvt_color *tint, int shade)
1022{ 1012{
1041 { 1031 {
1042 if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700) 1032 if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700)
1043 && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700)) 1033 && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700))
1044 { 1034 {
1045 flags |= bgPixmap_t::tintNeeded; 1035 flags |= bgPixmap_t::tintNeeded;
1046 }
1047 }
1048
1049 if (flags & bgPixmap_t::tintNeeded)
1050 {
1051 if (flags & bgPixmap_t::tintWholesome)
1052 flags |= bgPixmap_t::tintServerSide;
1053 else
1054 {
1055#if XRENDER
1056 flags |= bgPixmap_t::tintServerSide;
1057#endif
1058 } 1036 }
1059 } 1037 }
1060 1038
1061 return flags; 1039 return flags;
1062} 1040}
1338 Pixmap recoded_root_pmap = root_pixmap; 1316 Pixmap recoded_root_pmap = root_pixmap;
1339 1317
1340 if (root_pixmap != None && root_depth != target->depth) 1318 if (root_pixmap != None && root_depth != target->depth)
1341 { 1319 {
1342#if XRENDER 1320#if XRENDER
1321 if (flags & HAS_RENDER)
1322 {
1343 XRenderPictureAttributes pa; 1323 XRenderPictureAttributes pa;
1344 1324
1345 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1325 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1346 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1326 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa);
1347 1327
1348 recoded_root_pmap = XCreatePixmap (dpy, target->vt, root_pmap_width, root_pmap_height, target->depth); 1328 recoded_root_pmap = XCreatePixmap (dpy, target->vt, root_pmap_width, root_pmap_height, target->depth);
1349 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, target->visual); 1329 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, target->visual);
1350 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1330 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa);
1351 1331
1352 if (src && dst) 1332 if (src && dst)
1353 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); 1333 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height);
1334 else
1335 {
1336 XFreePixmap (dpy, recoded_root_pmap);
1337 root_pixmap = None;
1338 }
1339
1340 XRenderFreePicture (dpy, src);
1341 XRenderFreePicture (dpy, dst);
1342 }
1354 else 1343 else
1355 { 1344#endif
1356 XFreePixmap (dpy, recoded_root_pmap);
1357 root_pixmap = None;
1358 }
1359
1360 XRenderFreePicture (dpy, src);
1361 XRenderFreePicture (dpy, dst);
1362#else
1363 root_pixmap = None; 1345 root_pixmap = None;
1364#endif
1365 } 1346 }
1366 1347
1367 if (root_pixmap == None) 1348 if (root_pixmap == None)
1368 return 0; 1349 return 0;
1369 1350
1393 if (tiled_root_pmap != None) 1374 if (tiled_root_pmap != None)
1394 { 1375 {
1395 if (!need_client_side_rendering ()) 1376 if (!need_client_side_rendering ())
1396 { 1377 {
1397 if ((flags & blurNeeded) 1378 if ((flags & blurNeeded)
1398 && (flags & blurServerSide)) 1379 && (flags & HAS_RENDER_CONV))
1399 { 1380 {
1400 if (blur_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) 1381 if (blur_pixmap (tiled_root_pmap, target->visual, window_width, window_height))
1401 result |= transpPmapBlurred; 1382 result |= transpPmapBlurred;
1402 } 1383 }
1403 if ((flags & tintNeeded) 1384 if ((flags & tintNeeded)
1404 && (flags & tintServerSide)) 1385 && (flags & (tintWholesome | HAS_RENDER)))
1405 { 1386 {
1406 if (tint_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) 1387 if (tint_pixmap (tiled_root_pmap, target->visual, window_width, window_height))
1407 result |= transpPmapTinted; 1388 result |= transpPmapTinted;
1408 } 1389 }
1409 } /* server side rendering completed */ 1390 } /* server side rendering completed */
1466 if (render_image (background_flags)) 1447 if (render_image (background_flags))
1467 flags = flags & ~isInvalid; 1448 flags = flags & ~isInvalid;
1468 } 1449 }
1469# endif 1450# endif
1470 1451
1452# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) && !XRENDER
1471 XImage *result = NULL; 1453 XImage *result = NULL;
1472 1454
1473 if (background_flags && (flags & isInvalid)) 1455 if (background_flags && (flags & isInvalid))
1474 { 1456 {
1475 result = XGetImage (target->dpy, pixmap, 0, 0, pmap_width, pmap_height, AllPlanes, ZPixmap); 1457 result = XGetImage (target->dpy, pixmap, 0, 0, pmap_width, pmap_height, AllPlanes, ZPixmap);
1476 } 1458 }
1477 1459
1478 if (result) 1460 if (result)
1479 { 1461 {
1480# if !defined(HAVE_AFTERIMAGE) && !XRENDER
1481 /* our own client-side tinting */ 1462 /* our own client-side tinting */
1482 if (!(background_flags & transpPmapTinted) && (flags & tintNeeded)) 1463 if (!(background_flags & transpPmapTinted) && (flags & tintNeeded))
1483 { 1464 {
1484 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 1465 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
1485 if (flags & tintSet) 1466 if (flags & tintSet)
1486 tint.get (c); 1467 tint.get (c);
1487 ShadeXImage (DefaultVisual (target->dpy, target->display->screen), result, shade, c.r, c.g, c.b); 1468 ShadeXImage (DefaultVisual (target->dpy, target->display->screen), result, shade, c.r, c.g, c.b);
1488 } 1469 }
1489# endif
1490 1470
1491 GC gc = XCreateGC (target->dpy, target->vt, 0UL, NULL); 1471 GC gc = XCreateGC (target->dpy, target->vt, 0UL, NULL);
1492 1472
1493 if (gc) 1473 if (gc)
1494 { 1474 {
1498 flags = flags & ~isInvalid; 1478 flags = flags & ~isInvalid;
1499 } 1479 }
1500 1480
1501 XDestroyImage (result); 1481 XDestroyImage (result);
1502 } 1482 }
1483# endif
1503 1484
1504 if (flags & isInvalid) 1485 if (flags & isInvalid)
1505 { 1486 {
1506 if (pixmap != None) 1487 if (pixmap != None)
1507 { 1488 {
1519 1500
1520void 1501void
1521bgPixmap_t::set_target (rxvt_term *new_target) 1502bgPixmap_t::set_target (rxvt_term *new_target)
1522{ 1503{
1523 target = new_target; 1504 target = new_target;
1505
1506 flags &= ~(HAS_RENDER | HAS_RENDER_CONV);
1507#if XRENDER
1508 int major, minor;
1509 if (XRenderQueryVersion (target->dpy, &major, &minor))
1510 flags |= HAS_RENDER;
1511 XFilters *filters = XRenderQueryFilters (target->dpy, target->vt);
1512 if (filters)
1513 {
1514 for (int i = 0; i < filters->nfilter; i++)
1515 if (!strcmp (filters->filter[i], FilterConvolution))
1516 flags |= HAS_RENDER_CONV;
1517
1518 XFree (filters);
1519 }
1520#endif
1524} 1521}
1525 1522
1526void 1523void
1527bgPixmap_t::apply () 1524bgPixmap_t::apply ()
1528{ 1525{
1529 if (target) 1526 if (target == NULL)
1530 { 1527 return;
1528
1531 if (pixmap != None) 1529 if (pixmap != None)
1532 { 1530 {
1533 /* set target's background to pixmap */ 1531 /* set target's background to pixmap */
1534# ifdef ENABLE_TRANSPARENCY 1532# ifdef ENABLE_TRANSPARENCY
1535 if (flags & isTransparent) 1533 if (flags & isTransparent)
1536 { 1534 {
1537 XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); 1535 XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap);
1538 XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); 1536 XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative);
1539 1537
1540 if (target->scrollBar.win) 1538 if (target->scrollBar.win)
1541 XSetWindowBackgroundPixmap (target->dpy, target->scrollBar.win, ParentRelative); 1539 XSetWindowBackgroundPixmap (target->dpy, target->scrollBar.win, ParentRelative);
1542 } 1540 }
1543 else 1541 else
1544# endif 1542# endif
1545 { 1543 {
1546 /* force old pixmap dereference in case it was transparent before :*/ 1544 /* force old pixmap dereference in case it was transparent before :*/
1547 XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]);
1548 XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap);
1549 /* do we also need to set scrollbar's background here ? */
1550
1551 if (target->scrollBar.win)
1552 XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]);
1553 }
1554 }
1555 else
1556 {
1557 /* set target background to a pixel */
1558 XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); 1545 XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]);
1559 XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); 1546 XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap);
1560 /* do we also need to set scrollbar's background here ? */ 1547 /* do we also need to set scrollbar's background here ? */
1548
1561 if (target->scrollBar.win) 1549 if (target->scrollBar.win)
1562 XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); 1550 XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]);
1563 } 1551 }
1552 }
1553 else
1554 {
1555 /* set target background to a pixel */
1556 XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]);
1557 XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]);
1558 /* do we also need to set scrollbar's background here ? */
1559 if (target->scrollBar.win)
1560 XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]);
1561 }
1564 1562
1565 /* don't want Expose on the parent or vt. It is better to use 1563 /* don't want Expose on the parent or vt. It is better to use
1566 scr_touch or we get a great deal of flicker otherwise: */ 1564 scr_touch or we get a great deal of flicker otherwise: */
1567 XClearWindow (target->dpy, target->parent[0]); 1565 XClearWindow (target->dpy, target->parent[0]);
1568 1566
1569 if (target->scrollBar.state && target->scrollBar.win) 1567 if (target->scrollBar.state && target->scrollBar.win)
1570 { 1568 {
1571 target->scrollBar.state = STATE_IDLE; 1569 target->scrollBar.state = STATE_IDLE;
1572 target->scrollBar.show (0); 1570 target->scrollBar.show (0);
1573 } 1571 }
1574 1572
1575 target->want_refresh = 1; 1573 target->want_refresh = 1;
1576 flags |= hasChanged; 1574 flags |= hasChanged;
1577 }
1578} 1575}
1579 1576
1580#endif /* HAVE_BG_PIXMAP */ 1577#endif /* HAVE_BG_PIXMAP */
1581 1578
1582#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) && !XRENDER 1579#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) && !XRENDER

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines