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.104 by sf-exg, Sun Oct 31 17:44:39 2010 UTC vs.
Revision 1.112 by sf-exg, Sat Nov 6 17:16:15 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
1392 1373
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 | blurServerSide)) 1378 if ((flags & blurNeeded)
1379 && (flags & HAS_RENDER_CONV))
1398 { 1380 {
1399 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))
1400 result |= transpPmapBlurred; 1382 result |= transpPmapBlurred;
1401 } 1383 }
1402 if (flags & (tintNeeded | tintServerSide)) 1384 if ((flags & tintNeeded)
1385 && (flags & (tintWholesome | HAS_RENDER)))
1403 { 1386 {
1404 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))
1405 result |= transpPmapTinted; 1388 result |= transpPmapTinted;
1406 } 1389 }
1407 } /* server side rendering completed */ 1390 } /* server side rendering completed */
1430 1413
1431 root_pixmap = new_root_pixmap; 1414 root_pixmap = new_root_pixmap;
1432} 1415}
1433# endif /* ENABLE_TRANSPARENCY */ 1416# endif /* ENABLE_TRANSPARENCY */
1434 1417
1435# ifndef HAVE_AFTERIMAGE 1418#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1436static void ShadeXImage(Visual *visual, XImage *srcImage, int shade, int rm, int gm, int bm); 1419static void ShadeXImage(Visual *visual, XImage *srcImage, int shade, int rm, int gm, int bm);
1437# endif 1420# endif
1438 1421
1439bool 1422bool
1440bgPixmap_t::render () 1423bgPixmap_t::render ()
1464 if (render_image (background_flags)) 1447 if (render_image (background_flags))
1465 flags = flags & ~isInvalid; 1448 flags = flags & ~isInvalid;
1466 } 1449 }
1467# endif 1450# endif
1468 1451
1452# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1469 XImage *result = NULL; 1453 XImage *result = NULL;
1470 1454
1471 if (background_flags && (flags & isInvalid)) 1455 if (background_flags && (flags & isInvalid))
1472 { 1456 {
1473 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);
1474 } 1458 }
1475 1459
1476 if (result) 1460 if (result)
1477 { 1461 {
1478# if !defined(HAVE_AFTERIMAGE) && !XRENDER
1479 /* our own client-side tinting */ 1462 /* our own client-side tinting */
1480 if (!(background_flags & transpPmapTinted) && (flags & tintNeeded)) 1463 if (!(background_flags & transpPmapTinted) && (flags & tintNeeded))
1481 { 1464 {
1482 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 1465 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
1483 if (flags & tintSet) 1466 if (flags & tintSet)
1484 tint.get (c); 1467 tint.get (c);
1485 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);
1486 } 1469 }
1487# endif
1488 1470
1489 GC gc = XCreateGC (target->dpy, target->vt, 0UL, NULL); 1471 GC gc = XCreateGC (target->dpy, target->vt, 0UL, NULL);
1490 1472
1491 if (gc) 1473 if (gc)
1492 { 1474 {
1496 flags = flags & ~isInvalid; 1478 flags = flags & ~isInvalid;
1497 } 1479 }
1498 1480
1499 XDestroyImage (result); 1481 XDestroyImage (result);
1500 } 1482 }
1483# endif
1501 1484
1502 if (flags & isInvalid) 1485 if (flags & isInvalid)
1503 { 1486 {
1504 if (pixmap != None) 1487 if (pixmap != None)
1505 { 1488 {
1513 valid_since = ev::now (); 1496 valid_since = ev::now ();
1514 1497
1515 return true; 1498 return true;
1516} 1499}
1517 1500
1518bool 1501void
1519bgPixmap_t::set_target (rxvt_term *new_target) 1502bgPixmap_t::set_target (rxvt_term *new_target)
1520{ 1503{
1521 if (new_target)
1522 if (target != new_target)
1523 {
1524 target = new_target; 1504 target = new_target;
1525 return true; 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);
1526 } 1519 }
1527 1520#endif
1528 return false;
1529} 1521}
1530 1522
1531void 1523void
1532bgPixmap_t::apply () 1524bgPixmap_t::apply ()
1533{ 1525{
1534 if (target) 1526 if (target == NULL)
1535 { 1527 return;
1528
1536 if (pixmap != None) 1529 if (pixmap != None)
1537 { 1530 {
1538 /* set target's background to pixmap */ 1531 /* set target's background to pixmap */
1539# ifdef ENABLE_TRANSPARENCY 1532# ifdef ENABLE_TRANSPARENCY
1540 if (flags & isTransparent) 1533 if (flags & isTransparent)
1541 { 1534 {
1542 XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); 1535 XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap);
1543 XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); 1536 XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative);
1544 1537
1545 if (target->scrollBar.win) 1538 if (target->scrollBar.win)
1546 XSetWindowBackgroundPixmap (target->dpy, target->scrollBar.win, ParentRelative); 1539 XSetWindowBackgroundPixmap (target->dpy, target->scrollBar.win, ParentRelative);
1547 } 1540 }
1548 else 1541 else
1549# endif 1542# endif
1550 { 1543 {
1551 /* force old pixmap dereference in case it was transparent before :*/ 1544 /* force old pixmap dereference in case it was transparent before :*/
1552 XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]);
1553 XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap);
1554 /* do we also need to set scrollbar's background here ? */
1555
1556 if (target->scrollBar.win)
1557 XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]);
1558 }
1559 }
1560 else
1561 {
1562 /* set target background to a pixel */
1563 XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); 1545 XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]);
1564 XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); 1546 XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap);
1565 /* do we also need to set scrollbar's background here ? */ 1547 /* do we also need to set scrollbar's background here ? */
1548
1566 if (target->scrollBar.win) 1549 if (target->scrollBar.win)
1567 XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); 1550 XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]);
1568 } 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 }
1569 1562
1570 /* 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
1571 scr_touch or we get a great deal of flicker otherwise: */ 1564 scr_touch or we get a great deal of flicker otherwise: */
1572 XClearWindow (target->dpy, target->parent[0]); 1565 XClearWindow (target->dpy, target->parent[0]);
1573 1566
1574 if (target->scrollBar.state && target->scrollBar.win) 1567 if (target->scrollBar.state && target->scrollBar.win)
1575 { 1568 {
1576 target->scrollBar.state = STATE_IDLE; 1569 target->scrollBar.state = STATE_IDLE;
1577 target->scrollBar.show (0); 1570 target->scrollBar.show (0);
1578 } 1571 }
1579 1572
1580 target->want_refresh = 1; 1573 target->want_refresh = 1;
1581 flags |= hasChanged; 1574 flags |= hasChanged;
1582 }
1583} 1575}
1584 1576
1585#endif /* HAVE_BG_PIXMAP */ 1577#endif /* HAVE_BG_PIXMAP */
1586 1578
1587#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) && !XRENDER 1579#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1588/* taken from aterm-0.4.2 */ 1580/* taken from aterm-0.4.2 */
1589 1581
1590static void 1582static void
1591ShadeXImage(Visual *visual, XImage *srcImage, int shade, int rm, int gm, int bm) 1583ShadeXImage(Visual *visual, XImage *srcImage, int shade, int rm, int gm, int bm)
1592{ 1584{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines