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