… | |
… | |
729 | return false; |
729 | return false; |
730 | |
730 | |
731 | if (!pixbuf) |
731 | if (!pixbuf) |
732 | return false; |
732 | return false; |
733 | |
733 | |
734 | #if !XRENDER |
|
|
735 | if (background_flags) |
734 | if (background_flags |
|
|
735 | && !(flags & HAS_RENDER)) |
736 | return false; |
736 | return false; |
737 | #endif |
|
|
738 | |
737 | |
739 | GdkPixbuf *result; |
738 | GdkPixbuf *result; |
740 | |
739 | |
741 | int image_width = gdk_pixbuf_get_width (pixbuf); |
740 | int image_width = gdk_pixbuf_get_width (pixbuf); |
742 | int image_height = gdk_pixbuf_get_height (pixbuf); |
741 | int image_height = gdk_pixbuf_get_height (pixbuf); |
… | |
… | |
909 | # endif /* HAVE_PIXBUF */ |
908 | # endif /* HAVE_PIXBUF */ |
910 | |
909 | |
911 | bool |
910 | bool |
912 | bgPixmap_t::set_file (const char *file) |
911 | bgPixmap_t::set_file (const char *file) |
913 | { |
912 | { |
914 | assert (file); |
913 | if (!file || !*file) |
|
|
914 | return false; |
915 | |
915 | |
916 | if (*file) |
|
|
917 | { |
|
|
918 | if (const char *p = strchr (file, ';')) |
916 | if (const char *p = strchr (file, ';')) |
919 | { |
917 | { |
920 | size_t len = p - file; |
918 | size_t len = p - file; |
921 | char *f = rxvt_temp_buf<char> (len + 1); |
919 | char *f = rxvt_temp_buf<char> (len + 1); |
922 | memcpy (f, file, len); |
920 | memcpy (f, file, len); |
923 | f[len] = '\0'; |
921 | f[len] = '\0'; |
924 | file = f; |
922 | file = f; |
925 | } |
923 | } |
926 | |
924 | |
927 | # ifdef HAVE_AFTERIMAGE |
925 | # ifdef HAVE_AFTERIMAGE |
928 | if (!target->asimman) |
926 | if (!target->asimman) |
929 | target->asimman = create_generic_imageman (target->rs[Rs_path]); |
927 | target->asimman = create_generic_imageman (target->rs[Rs_path]); |
930 | ASImage *image = get_asimage (target->asimman, file, 0xFFFFFFFF, 100); |
928 | ASImage *image = get_asimage (target->asimman, file, 0xFFFFFFFF, 100); |
931 | if (image) |
929 | if (image) |
932 | { |
930 | { |
933 | if (original_asim) |
931 | if (original_asim) |
934 | safe_asimage_destroy (original_asim); |
932 | safe_asimage_destroy (original_asim); |
935 | original_asim = image; |
933 | original_asim = image; |
936 | have_image = true; |
934 | have_image = true; |
937 | return true; |
935 | return true; |
938 | } |
936 | } |
939 | # endif |
937 | # endif |
940 | |
938 | |
941 | # ifdef HAVE_PIXBUF |
939 | # ifdef HAVE_PIXBUF |
942 | GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL); |
940 | GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL); |
943 | if (image) |
941 | if (image) |
944 | { |
942 | { |
945 | if (pixbuf) |
943 | if (pixbuf) |
946 | g_object_unref (pixbuf); |
944 | g_object_unref (pixbuf); |
947 | pixbuf = image; |
945 | pixbuf = image; |
948 | have_image = true; |
946 | have_image = true; |
949 | return true; |
947 | return true; |
950 | } |
948 | } |
951 | # endif |
949 | # endif |
952 | } |
|
|
953 | |
950 | |
954 | return false; |
951 | return false; |
955 | } |
952 | } |
956 | |
953 | |
957 | # endif /* BG_IMAGE_FROM_FILE */ |
954 | # endif /* BG_IMAGE_FROM_FILE */ |
… | |
… | |
999 | |
996 | |
1000 | if (v_blurRadius == 0 && h_blurRadius == 0) |
997 | if (v_blurRadius == 0 && h_blurRadius == 0) |
1001 | flags &= ~blurNeeded; |
998 | flags &= ~blurNeeded; |
1002 | else |
999 | else |
1003 | flags |= blurNeeded; |
1000 | flags |= blurNeeded; |
1004 | |
|
|
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 | |
1001 | |
1017 | return (changed > 0); |
1002 | return (changed > 0); |
1018 | } |
1003 | } |
1019 | |
1004 | |
1020 | static inline unsigned long |
1005 | static inline unsigned long |
… | |
… | |
1041 | { |
1026 | { |
1042 | if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700) |
1027 | if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700) |
1043 | && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700)) |
1028 | && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700)) |
1044 | { |
1029 | { |
1045 | flags |= bgPixmap_t::tintNeeded; |
1030 | 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 | } |
1031 | } |
1059 | } |
1032 | } |
1060 | |
1033 | |
1061 | return flags; |
1034 | return flags; |
1062 | } |
1035 | } |
… | |
… | |
1338 | Pixmap recoded_root_pmap = root_pixmap; |
1311 | Pixmap recoded_root_pmap = root_pixmap; |
1339 | |
1312 | |
1340 | if (root_pixmap != None && root_depth != target->depth) |
1313 | if (root_pixmap != None && root_depth != target->depth) |
1341 | { |
1314 | { |
1342 | #if XRENDER |
1315 | #if XRENDER |
|
|
1316 | if (flags & HAS_RENDER) |
|
|
1317 | { |
1343 | XRenderPictureAttributes pa; |
1318 | XRenderPictureAttributes pa; |
1344 | |
1319 | |
1345 | XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); |
1320 | XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); |
1346 | Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); |
1321 | Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); |
1347 | |
1322 | |
1348 | recoded_root_pmap = XCreatePixmap (dpy, target->vt, root_pmap_width, root_pmap_height, target->depth); |
1323 | recoded_root_pmap = XCreatePixmap (dpy, target->vt, root_pmap_width, root_pmap_height, target->depth); |
1349 | XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, target->visual); |
1324 | XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, target->visual); |
1350 | Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); |
1325 | Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); |
1351 | |
1326 | |
1352 | if (src && dst) |
1327 | if (src && dst) |
1353 | XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); |
1328 | XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); |
|
|
1329 | else |
|
|
1330 | { |
|
|
1331 | XFreePixmap (dpy, recoded_root_pmap); |
|
|
1332 | root_pixmap = None; |
|
|
1333 | } |
|
|
1334 | |
|
|
1335 | XRenderFreePicture (dpy, src); |
|
|
1336 | XRenderFreePicture (dpy, dst); |
|
|
1337 | } |
1354 | else |
1338 | else |
1355 | { |
1339 | #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; |
1340 | root_pixmap = None; |
1364 | #endif |
|
|
1365 | } |
1341 | } |
1366 | |
1342 | |
1367 | if (root_pixmap == None) |
1343 | if (root_pixmap == None) |
1368 | return 0; |
1344 | return 0; |
1369 | |
1345 | |
… | |
… | |
1393 | if (tiled_root_pmap != None) |
1369 | if (tiled_root_pmap != None) |
1394 | { |
1370 | { |
1395 | if (!need_client_side_rendering ()) |
1371 | if (!need_client_side_rendering ()) |
1396 | { |
1372 | { |
1397 | if ((flags & blurNeeded) |
1373 | if ((flags & blurNeeded) |
1398 | && (flags & blurServerSide)) |
1374 | && (flags & HAS_RENDER_CONV)) |
1399 | { |
1375 | { |
1400 | if (blur_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) |
1376 | if (blur_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) |
1401 | result |= transpPmapBlurred; |
1377 | result |= transpPmapBlurred; |
1402 | } |
1378 | } |
1403 | if ((flags & tintNeeded) |
1379 | if ((flags & tintNeeded) |
1404 | && (flags & tintServerSide)) |
1380 | && (flags & (tintWholesome | HAS_RENDER))) |
1405 | { |
1381 | { |
1406 | if (tint_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) |
1382 | if (tint_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) |
1407 | result |= transpPmapTinted; |
1383 | result |= transpPmapTinted; |
1408 | } |
1384 | } |
1409 | } /* server side rendering completed */ |
1385 | } /* server side rendering completed */ |
… | |
… | |
1515 | valid_since = ev::now (); |
1491 | valid_since = ev::now (); |
1516 | |
1492 | |
1517 | return true; |
1493 | return true; |
1518 | } |
1494 | } |
1519 | |
1495 | |
1520 | bool |
1496 | void |
1521 | bgPixmap_t::set_target (rxvt_term *new_target) |
1497 | bgPixmap_t::set_target (rxvt_term *new_target) |
1522 | { |
1498 | { |
1523 | if (new_target) |
|
|
1524 | if (target != new_target) |
|
|
1525 | { |
|
|
1526 | target = new_target; |
1499 | target = new_target; |
1527 | return true; |
1500 | |
|
|
1501 | flags &= ~(HAS_RENDER | HAS_RENDER_CONV); |
|
|
1502 | #if XRENDER |
|
|
1503 | int major, minor; |
|
|
1504 | if (XRenderQueryVersion (target->dpy, &major, &minor)) |
|
|
1505 | flags |= HAS_RENDER; |
|
|
1506 | XFilters *filters = XRenderQueryFilters (target->dpy, target->vt); |
|
|
1507 | if (filters) |
|
|
1508 | { |
|
|
1509 | for (int i = 0; i < filters->nfilter; i++) |
|
|
1510 | if (!strcmp (filters->filter[i], FilterConvolution)) |
|
|
1511 | flags |= HAS_RENDER_CONV; |
|
|
1512 | |
|
|
1513 | XFree (filters); |
1528 | } |
1514 | } |
1529 | |
1515 | #endif |
1530 | return false; |
|
|
1531 | } |
1516 | } |
1532 | |
1517 | |
1533 | void |
1518 | void |
1534 | bgPixmap_t::apply () |
1519 | bgPixmap_t::apply () |
1535 | { |
1520 | { |
1536 | if (target) |
1521 | if (target == NULL) |
1537 | { |
1522 | return; |
|
|
1523 | |
1538 | if (pixmap != None) |
1524 | if (pixmap != None) |
1539 | { |
1525 | { |
1540 | /* set target's background to pixmap */ |
1526 | /* set target's background to pixmap */ |
1541 | # ifdef ENABLE_TRANSPARENCY |
1527 | # ifdef ENABLE_TRANSPARENCY |
1542 | if (flags & isTransparent) |
1528 | if (flags & isTransparent) |
1543 | { |
1529 | { |
1544 | XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); |
1530 | XSetWindowBackgroundPixmap (target->dpy, target->parent[0], pixmap); |
1545 | XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); |
1531 | XSetWindowBackgroundPixmap (target->dpy, target->vt, ParentRelative); |
1546 | |
1532 | |
1547 | if (target->scrollBar.win) |
1533 | if (target->scrollBar.win) |
1548 | XSetWindowBackgroundPixmap (target->dpy, target->scrollBar.win, ParentRelative); |
1534 | XSetWindowBackgroundPixmap (target->dpy, target->scrollBar.win, ParentRelative); |
1549 | } |
1535 | } |
1550 | else |
1536 | else |
1551 | # endif |
1537 | # endif |
1552 | { |
1538 | { |
1553 | /* force old pixmap dereference in case it was transparent before :*/ |
1539 | /* force old pixmap dereference in case it was transparent before :*/ |
1554 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
|
|
1555 | XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap); |
|
|
1556 | /* do we also need to set scrollbar's background here ? */ |
|
|
1557 | |
|
|
1558 | if (target->scrollBar.win) |
|
|
1559 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
|
|
1560 | } |
|
|
1561 | } |
|
|
1562 | else |
|
|
1563 | { |
|
|
1564 | /* set target background to a pixel */ |
|
|
1565 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
1540 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
1566 | XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); |
1541 | XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap); |
1567 | /* do we also need to set scrollbar's background here ? */ |
1542 | /* do we also need to set scrollbar's background here ? */ |
|
|
1543 | |
1568 | if (target->scrollBar.win) |
1544 | if (target->scrollBar.win) |
1569 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
1545 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
1570 | } |
1546 | } |
|
|
1547 | } |
|
|
1548 | else |
|
|
1549 | { |
|
|
1550 | /* set target background to a pixel */ |
|
|
1551 | XSetWindowBackground (target->dpy, target->parent[0], target->pix_colors[Color_border]); |
|
|
1552 | XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]); |
|
|
1553 | /* do we also need to set scrollbar's background here ? */ |
|
|
1554 | if (target->scrollBar.win) |
|
|
1555 | XSetWindowBackground (target->dpy, target->scrollBar.win, target->pix_colors[Color_border]); |
|
|
1556 | } |
1571 | |
1557 | |
1572 | /* don't want Expose on the parent or vt. It is better to use |
1558 | /* don't want Expose on the parent or vt. It is better to use |
1573 | scr_touch or we get a great deal of flicker otherwise: */ |
1559 | scr_touch or we get a great deal of flicker otherwise: */ |
1574 | XClearWindow (target->dpy, target->parent[0]); |
1560 | XClearWindow (target->dpy, target->parent[0]); |
1575 | |
1561 | |
1576 | if (target->scrollBar.state && target->scrollBar.win) |
1562 | if (target->scrollBar.state && target->scrollBar.win) |
1577 | { |
1563 | { |
1578 | target->scrollBar.state = STATE_IDLE; |
1564 | target->scrollBar.state = STATE_IDLE; |
1579 | target->scrollBar.show (0); |
1565 | target->scrollBar.show (0); |
1580 | } |
1566 | } |
1581 | |
1567 | |
1582 | target->want_refresh = 1; |
1568 | target->want_refresh = 1; |
1583 | flags |= hasChanged; |
1569 | flags |= hasChanged; |
1584 | } |
|
|
1585 | } |
1570 | } |
1586 | |
1571 | |
1587 | #endif /* HAVE_BG_PIXMAP */ |
1572 | #endif /* HAVE_BG_PIXMAP */ |
1588 | |
1573 | |
1589 | #if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) && !XRENDER |
1574 | #if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) && !XRENDER |