Mercurial > vim
comparison src/terminal.c @ 12152:69af108df70e v8.0.0956
patch 8.0.0956: scrolling in a terminal window has flicker
commit https://github.com/vim/vim/commit/cfce71710b6a2e1fb7f7f27d2a359e4b926f3af9
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Aug 17 20:31:48 2017 +0200
patch 8.0.0956: scrolling in a terminal window has flicker
Problem: Scrolling in a terminal hwindow as flicker when the Normal
background differs from the terminal window background.
Solution: Set the attribute to clear with.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 17 Aug 2017 20:45:04 +0200 |
parents | 59c1e09cf1a9 |
children | 71e10b81226d |
comparison
equal
deleted
inserted
replaced
12151:dcab6d218e96 | 12152:69af108df70e |
---|---|
1481 else | 1481 else |
1482 cursor_off(); | 1482 cursor_off(); |
1483 } | 1483 } |
1484 } | 1484 } |
1485 | 1485 |
1486 /* | |
1487 * Reverse engineer the RGB value into a cterm color index. | |
1488 * First color is 1. Return 0 if no match found. | |
1489 */ | |
1490 static int | |
1491 color2index(VTermColor *color, int fg, int *boldp) | |
1492 { | |
1493 int red = color->red; | |
1494 int blue = color->blue; | |
1495 int green = color->green; | |
1496 | |
1497 /* The argument for lookup_color() is for the color_names[] table. */ | |
1498 if (red == 0) | |
1499 { | |
1500 if (green == 0) | |
1501 { | |
1502 if (blue == 0) | |
1503 return lookup_color(0, fg, boldp) + 1; /* black */ | |
1504 if (blue == 224) | |
1505 return lookup_color(1, fg, boldp) + 1; /* dark blue */ | |
1506 } | |
1507 else if (green == 224) | |
1508 { | |
1509 if (blue == 0) | |
1510 return lookup_color(2, fg, boldp) + 1; /* dark green */ | |
1511 if (blue == 224) | |
1512 return lookup_color(3, fg, boldp) + 1; /* dark cyan */ | |
1513 } | |
1514 } | |
1515 else if (red == 224) | |
1516 { | |
1517 if (green == 0) | |
1518 { | |
1519 if (blue == 0) | |
1520 return lookup_color(4, fg, boldp) + 1; /* dark red */ | |
1521 if (blue == 224) | |
1522 return lookup_color(5, fg, boldp) + 1; /* dark magenta */ | |
1523 } | |
1524 else if (green == 224) | |
1525 { | |
1526 if (blue == 0) | |
1527 return lookup_color(6, fg, boldp) + 1; /* dark yellow / brown */ | |
1528 if (blue == 224) | |
1529 return lookup_color(8, fg, boldp) + 1; /* white / light grey */ | |
1530 } | |
1531 } | |
1532 else if (red == 128) | |
1533 { | |
1534 if (green == 128 && blue == 128) | |
1535 return lookup_color(12, fg, boldp) + 1; /* high intensity black / dark grey */ | |
1536 } | |
1537 else if (red == 255) | |
1538 { | |
1539 if (green == 64) | |
1540 { | |
1541 if (blue == 64) | |
1542 return lookup_color(20, fg, boldp) + 1; /* light red */ | |
1543 if (blue == 255) | |
1544 return lookup_color(22, fg, boldp) + 1; /* light magenta */ | |
1545 } | |
1546 else if (green == 255) | |
1547 { | |
1548 if (blue == 64) | |
1549 return lookup_color(24, fg, boldp) + 1; /* yellow */ | |
1550 if (blue == 255) | |
1551 return lookup_color(26, fg, boldp) + 1; /* white */ | |
1552 } | |
1553 } | |
1554 else if (red == 64) | |
1555 { | |
1556 if (green == 64) | |
1557 { | |
1558 if (blue == 255) | |
1559 return lookup_color(14, fg, boldp) + 1; /* light blue */ | |
1560 } | |
1561 else if (green == 255) | |
1562 { | |
1563 if (blue == 64) | |
1564 return lookup_color(16, fg, boldp) + 1; /* light green */ | |
1565 if (blue == 255) | |
1566 return lookup_color(18, fg, boldp) + 1; /* light cyan */ | |
1567 } | |
1568 } | |
1569 if (t_colors >= 256) | |
1570 { | |
1571 if (red == blue && red == green) | |
1572 { | |
1573 /* 24-color greyscale */ | |
1574 static int cutoff[23] = { | |
1575 0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52, | |
1576 0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB, | |
1577 0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9}; | |
1578 int i; | |
1579 | |
1580 for (i = 0; i < 23; ++i) | |
1581 if (red < cutoff[i]) | |
1582 return i + 233; | |
1583 return 256; | |
1584 } | |
1585 | |
1586 /* 216-color cube */ | |
1587 return 17 + ((red + 25) / 0x33) * 36 | |
1588 + ((green + 25) / 0x33) * 6 | |
1589 + (blue + 25) / 0x33; | |
1590 } | |
1591 return 0; | |
1592 } | |
1593 | |
1594 /* | |
1595 * Convert the attributes of a vterm cell into an attribute index. | |
1596 */ | |
1597 static int | |
1598 cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg) | |
1599 { | |
1600 int attr = 0; | |
1601 | |
1602 if (cellattrs.bold) | |
1603 attr |= HL_BOLD; | |
1604 if (cellattrs.underline) | |
1605 attr |= HL_UNDERLINE; | |
1606 if (cellattrs.italic) | |
1607 attr |= HL_ITALIC; | |
1608 if (cellattrs.strike) | |
1609 attr |= HL_STANDOUT; | |
1610 if (cellattrs.reverse) | |
1611 attr |= HL_INVERSE; | |
1612 | |
1613 #ifdef FEAT_GUI | |
1614 if (gui.in_use) | |
1615 { | |
1616 guicolor_T fg, bg; | |
1617 | |
1618 fg = gui_mch_get_rgb_color(cellfg.red, cellfg.green, cellfg.blue); | |
1619 bg = gui_mch_get_rgb_color(cellbg.red, cellbg.green, cellbg.blue); | |
1620 return get_gui_attr_idx(attr, fg, bg); | |
1621 } | |
1622 else | |
1623 #endif | |
1624 #ifdef FEAT_TERMGUICOLORS | |
1625 if (p_tgc) | |
1626 { | |
1627 guicolor_T fg, bg; | |
1628 | |
1629 fg = gui_get_rgb_color_cmn(cellfg.red, cellfg.green, cellfg.blue); | |
1630 bg = gui_get_rgb_color_cmn(cellbg.red, cellbg.green, cellbg.blue); | |
1631 | |
1632 return get_tgc_attr_idx(attr, fg, bg); | |
1633 } | |
1634 else | |
1635 #endif | |
1636 { | |
1637 int bold = MAYBE; | |
1638 int fg = color2index(&cellfg, TRUE, &bold); | |
1639 int bg = color2index(&cellbg, FALSE, &bold); | |
1640 | |
1641 /* with 8 colors set the bold attribute to get a bright foreground */ | |
1642 if (bold == TRUE) | |
1643 attr |= HL_BOLD; | |
1644 return get_cterm_attr_idx(attr, fg, bg); | |
1645 } | |
1646 return 0; | |
1647 } | |
1648 | |
1486 static int | 1649 static int |
1487 handle_damage(VTermRect rect, void *user) | 1650 handle_damage(VTermRect rect, void *user) |
1488 { | 1651 { |
1489 term_T *term = (term_T *)user; | 1652 term_T *term = (term_T *)user; |
1490 | 1653 |
1496 | 1659 |
1497 static int | 1660 static int |
1498 handle_moverect(VTermRect dest, VTermRect src, void *user) | 1661 handle_moverect(VTermRect dest, VTermRect src, void *user) |
1499 { | 1662 { |
1500 term_T *term = (term_T *)user; | 1663 term_T *term = (term_T *)user; |
1501 win_T *wp; | 1664 |
1502 | 1665 /* Scrolling up is done much more efficiently by deleting lines instead of |
1666 * redrawing the text. */ | |
1503 if (dest.start_col == src.start_col | 1667 if (dest.start_col == src.start_col |
1504 && dest.end_col == src.end_col | 1668 && dest.end_col == src.end_col |
1505 && dest.start_row < src.start_row) | 1669 && dest.start_row < src.start_row) |
1670 { | |
1671 win_T *wp; | |
1672 VTermColor fg, bg; | |
1673 VTermScreenCellAttrs attr; | |
1674 int clear_attr; | |
1675 | |
1676 /* Set the color to clear lines with. */ | |
1677 vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm), | |
1678 &fg, &bg); | |
1679 vim_memset(&attr, 0, sizeof(attr)); | |
1680 clear_attr = cell2attr(attr, fg, bg); | |
1681 | |
1506 FOR_ALL_WINDOWS(wp) | 1682 FOR_ALL_WINDOWS(wp) |
1507 { | 1683 { |
1508 if (wp->w_buffer == term->tl_buffer) | 1684 if (wp->w_buffer == term->tl_buffer) |
1509 /* scrolling up is much more efficient when deleting lines */ | |
1510 win_del_lines(wp, dest.start_row, | 1685 win_del_lines(wp, dest.start_row, |
1511 src.start_row - dest.start_row, FALSE, FALSE); | 1686 src.start_row - dest.start_row, FALSE, FALSE, |
1512 } | 1687 clear_attr); |
1688 } | |
1689 } | |
1513 redraw_buf_later(term->tl_buffer, NOT_VALID); | 1690 redraw_buf_later(term->tl_buffer, NOT_VALID); |
1514 return 1; | 1691 return 1; |
1515 } | 1692 } |
1516 | 1693 |
1517 static int | 1694 static int |
1769 if (term->tl_job == ch->ch_job) | 1946 if (term->tl_job == ch->ch_job) |
1770 maketitle(); | 1947 maketitle(); |
1771 update_cursor(term, term->tl_cursor_visible); | 1948 update_cursor(term, term->tl_cursor_visible); |
1772 } | 1949 } |
1773 } | 1950 } |
1774 } | |
1775 | |
1776 /* | |
1777 * Reverse engineer the RGB value into a cterm color index. | |
1778 * First color is 1. Return 0 if no match found. | |
1779 */ | |
1780 static int | |
1781 color2index(VTermColor *color, int fg, int *boldp) | |
1782 { | |
1783 int red = color->red; | |
1784 int blue = color->blue; | |
1785 int green = color->green; | |
1786 | |
1787 /* The argument for lookup_color() is for the color_names[] table. */ | |
1788 if (red == 0) | |
1789 { | |
1790 if (green == 0) | |
1791 { | |
1792 if (blue == 0) | |
1793 return lookup_color(0, fg, boldp) + 1; /* black */ | |
1794 if (blue == 224) | |
1795 return lookup_color(1, fg, boldp) + 1; /* dark blue */ | |
1796 } | |
1797 else if (green == 224) | |
1798 { | |
1799 if (blue == 0) | |
1800 return lookup_color(2, fg, boldp) + 1; /* dark green */ | |
1801 if (blue == 224) | |
1802 return lookup_color(3, fg, boldp) + 1; /* dark cyan */ | |
1803 } | |
1804 } | |
1805 else if (red == 224) | |
1806 { | |
1807 if (green == 0) | |
1808 { | |
1809 if (blue == 0) | |
1810 return lookup_color(4, fg, boldp) + 1; /* dark red */ | |
1811 if (blue == 224) | |
1812 return lookup_color(5, fg, boldp) + 1; /* dark magenta */ | |
1813 } | |
1814 else if (green == 224) | |
1815 { | |
1816 if (blue == 0) | |
1817 return lookup_color(6, fg, boldp) + 1; /* dark yellow / brown */ | |
1818 if (blue == 224) | |
1819 return lookup_color(8, fg, boldp) + 1; /* white / light grey */ | |
1820 } | |
1821 } | |
1822 else if (red == 128) | |
1823 { | |
1824 if (green == 128 && blue == 128) | |
1825 return lookup_color(12, fg, boldp) + 1; /* high intensity black / dark grey */ | |
1826 } | |
1827 else if (red == 255) | |
1828 { | |
1829 if (green == 64) | |
1830 { | |
1831 if (blue == 64) | |
1832 return lookup_color(20, fg, boldp) + 1; /* light red */ | |
1833 if (blue == 255) | |
1834 return lookup_color(22, fg, boldp) + 1; /* light magenta */ | |
1835 } | |
1836 else if (green == 255) | |
1837 { | |
1838 if (blue == 64) | |
1839 return lookup_color(24, fg, boldp) + 1; /* yellow */ | |
1840 if (blue == 255) | |
1841 return lookup_color(26, fg, boldp) + 1; /* white */ | |
1842 } | |
1843 } | |
1844 else if (red == 64) | |
1845 { | |
1846 if (green == 64) | |
1847 { | |
1848 if (blue == 255) | |
1849 return lookup_color(14, fg, boldp) + 1; /* light blue */ | |
1850 } | |
1851 else if (green == 255) | |
1852 { | |
1853 if (blue == 64) | |
1854 return lookup_color(16, fg, boldp) + 1; /* light green */ | |
1855 if (blue == 255) | |
1856 return lookup_color(18, fg, boldp) + 1; /* light cyan */ | |
1857 } | |
1858 } | |
1859 if (t_colors >= 256) | |
1860 { | |
1861 if (red == blue && red == green) | |
1862 { | |
1863 /* 24-color greyscale */ | |
1864 static int cutoff[23] = { | |
1865 0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52, | |
1866 0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB, | |
1867 0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9}; | |
1868 int i; | |
1869 | |
1870 for (i = 0; i < 23; ++i) | |
1871 if (red < cutoff[i]) | |
1872 return i + 233; | |
1873 return 256; | |
1874 } | |
1875 | |
1876 /* 216-color cube */ | |
1877 return 17 + ((red + 25) / 0x33) * 36 | |
1878 + ((green + 25) / 0x33) * 6 | |
1879 + (blue + 25) / 0x33; | |
1880 } | |
1881 return 0; | |
1882 } | |
1883 | |
1884 /* | |
1885 * Convert the attributes of a vterm cell into an attribute index. | |
1886 */ | |
1887 static int | |
1888 cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg) | |
1889 { | |
1890 int attr = 0; | |
1891 | |
1892 if (cellattrs.bold) | |
1893 attr |= HL_BOLD; | |
1894 if (cellattrs.underline) | |
1895 attr |= HL_UNDERLINE; | |
1896 if (cellattrs.italic) | |
1897 attr |= HL_ITALIC; | |
1898 if (cellattrs.strike) | |
1899 attr |= HL_STANDOUT; | |
1900 if (cellattrs.reverse) | |
1901 attr |= HL_INVERSE; | |
1902 | |
1903 #ifdef FEAT_GUI | |
1904 if (gui.in_use) | |
1905 { | |
1906 guicolor_T fg, bg; | |
1907 | |
1908 fg = gui_mch_get_rgb_color(cellfg.red, cellfg.green, cellfg.blue); | |
1909 bg = gui_mch_get_rgb_color(cellbg.red, cellbg.green, cellbg.blue); | |
1910 return get_gui_attr_idx(attr, fg, bg); | |
1911 } | |
1912 else | |
1913 #endif | |
1914 #ifdef FEAT_TERMGUICOLORS | |
1915 if (p_tgc) | |
1916 { | |
1917 guicolor_T fg, bg; | |
1918 | |
1919 fg = gui_get_rgb_color_cmn(cellfg.red, cellfg.green, cellfg.blue); | |
1920 bg = gui_get_rgb_color_cmn(cellbg.red, cellbg.green, cellbg.blue); | |
1921 | |
1922 return get_tgc_attr_idx(attr, fg, bg); | |
1923 } | |
1924 else | |
1925 #endif | |
1926 { | |
1927 int bold = MAYBE; | |
1928 int fg = color2index(&cellfg, TRUE, &bold); | |
1929 int bg = color2index(&cellbg, FALSE, &bold); | |
1930 | |
1931 /* with 8 colors set the bold attribute to get a bright foreground */ | |
1932 if (bold == TRUE) | |
1933 attr |= HL_BOLD; | |
1934 return get_cterm_attr_idx(attr, fg, bg); | |
1935 } | |
1936 return 0; | |
1937 } | 1951 } |
1938 | 1952 |
1939 /* | 1953 /* |
1940 * Called to update a window that contains an active terminal. | 1954 * Called to update a window that contains an active terminal. |
1941 * Returns FAIL when there is no terminal running in this window or in | 1955 * Returns FAIL when there is no terminal running in this window or in |