Mercurial > emacs
comparison src/xdisp.c @ 2729:76afd3322533
Arrange to tell redisplay about changes in overlays.
* xdisp.c (redisplay_region): New function.
* buffer.c (Fmove_overlay): Call redisplay_region on the areas the
overlay has enclosed or left.
(Fdelete_overlay): Call redisplay_region on the area the overlay
used to occupy.
(Foverlay_put): Call redisplay_region on the area the overlay now
occupies; we may have put a face property on it.
* xdisp.c (redisplay): If we're doing a thorough redisplay (all
windows on all frames involved), go ahead and flush the GC cache -
call clear_face_vector.
* xdisp.c (display_text_line): Apply faces to characters
according to overlays and text properties; use
compute_char_face and compute_glyph_face to figure out what
face to use, and where a new face starts.
* xterm.c (dumpglyphs): Use the upper bits of the glyphs to decide
which frame face to use. Call GLYPH_FOLLOW_ALIASES to make sure
we're implementing the glyph table properly. If we're not using
the default or mode line face, call intern_face to find a display
face for the frame face selected by the glyph code. Implement
underlining. Remove the `font' argument; we have to derive this
from the frame and face anyway. Change all callers.
* disptab.h (GLYPH_FOLLOW_ALIASES): New macro.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Mon, 10 May 1993 00:23:47 +0000 |
parents | bcba821c17bc |
children | 7800e6a86421 |
comparison
equal
deleted
inserted
replaced
2728:93c9529b2b69 | 2729:76afd3322533 |
---|---|
514 | 514 |
515 if (all_windows) | 515 if (all_windows) |
516 { | 516 { |
517 Lisp_Object tail, frame; | 517 Lisp_Object tail, frame; |
518 | 518 |
519 #ifdef HAVE_X_WINDOWS | |
520 /* Since we're doing a thorough redisplay, we might as well | |
521 recompute all our display faces. */ | |
522 clear_face_vector (); | |
523 #endif | |
524 | |
519 /* Recompute # windows showing selected buffer. | 525 /* Recompute # windows showing selected buffer. |
520 This will be incremented each time such a window is displayed. */ | 526 This will be incremented each time such a window is displayed. */ |
521 buffer_shared = 0; | 527 buffer_shared = 0; |
522 | 528 |
523 FOR_EACH_FRAME (tail, frame) | 529 FOR_EACH_FRAME (tail, frame) |
1470 abort (); | 1476 abort (); |
1471 } | 1477 } |
1472 | 1478 |
1473 return 1; | 1479 return 1; |
1474 } | 1480 } |
1481 | |
1482 /* Mark a section of BUF as modified, but only for the sake of redisplay. | |
1483 This is useful for recording changes to overlays. | |
1484 | |
1485 We increment the buffer's modification timestamp and set the | |
1486 redisplay caches (windows_or_buffers_changed, beg_unchanged, etc) | |
1487 as if the region of text between START and END had been modified; | |
1488 the redisplay code will check this against the windows' timestamps, | |
1489 and redraw the appropriate area of the buffer. | |
1490 | |
1491 However, if the buffer is unmodified, we bump the last-save | |
1492 timestamp as well, so that incrementing the timestamp doesn't fool | |
1493 Emacs into thinking that the buffer's text has been modified. | |
1494 | |
1495 Tweaking the timestamps shouldn't hurt the first-modification | |
1496 timestamps recorded in the undo records; those values aren't | |
1497 written until just before a real text modification is made, so they | |
1498 will never catch the timestamp value just before this function gets | |
1499 called. */ | |
1500 | |
1501 void | |
1502 redisplay_region (buf, start, end) | |
1503 struct buffer *buf; | |
1504 int start, end; | |
1505 { | |
1506 if (start == end) | |
1507 return; | |
1508 | |
1509 if (start > end) | |
1510 { | |
1511 int temp = start; | |
1512 start = end; end = temp; | |
1513 } | |
1514 | |
1515 if (buf != current_buffer) | |
1516 windows_or_buffers_changed = 1; | |
1517 else | |
1518 { | |
1519 if (unchanged_modified == MODIFF) | |
1520 { | |
1521 beg_unchanged = start - BEG; | |
1522 end_unchanged = Z - end; | |
1523 } | |
1524 else | |
1525 { | |
1526 if (Z - end < end_unchanged) | |
1527 end_unchanged = Z - end; | |
1528 if (start - BEG < beg_unchanged) | |
1529 beg_unchanged = start - BEG; | |
1530 } | |
1531 } | |
1532 | |
1533 /* Increment the buffer's time stamp, but also increment the save | |
1534 and autosave timestamps, so as not to screw up that timekeeping. */ | |
1535 if (BUF_MODIFF (buf) == buf->save_modified) | |
1536 buf->save_modified++; | |
1537 if (BUF_MODIFF (buf) == buf->auto_save_modified) | |
1538 buf->auto_save_modified++; | |
1539 | |
1540 BUF_MODIFF (buf) ++; | |
1541 } | |
1542 | |
1475 | 1543 |
1476 /* Copy glyphs from the vector FROM to the rope T. | 1544 /* Copy glyphs from the vector FROM to the rope T. |
1477 But don't actually copy the parts that would come in before S. | 1545 But don't actually copy the parts that would come in before S. |
1478 Value is T, advanced past the copied data. */ | 1546 Value is T, advanced past the copied data. */ |
1479 | 1547 |
1579 GLYPH truncator = (dp == 0 || XTYPE (DISP_TRUNC_GLYPH (dp)) != Lisp_Int | 1647 GLYPH truncator = (dp == 0 || XTYPE (DISP_TRUNC_GLYPH (dp)) != Lisp_Int |
1580 ? '$' : XINT (DISP_TRUNC_GLYPH (dp))); | 1648 ? '$' : XINT (DISP_TRUNC_GLYPH (dp))); |
1581 GLYPH continuer = (dp == 0 || XTYPE (DISP_CONTINUE_GLYPH (dp)) != Lisp_Int | 1649 GLYPH continuer = (dp == 0 || XTYPE (DISP_CONTINUE_GLYPH (dp)) != Lisp_Int |
1582 ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp))); | 1650 ? '\\' : XINT (DISP_CONTINUE_GLYPH (dp))); |
1583 | 1651 |
1652 /* The next buffer location at which the face should change, due | |
1653 to overlays or text property changes. */ | |
1654 int next_face_change; | |
1655 | |
1656 /* The face we're currently using. */ | |
1657 int current_face; | |
1658 | |
1584 hpos += XFASTINT (w->left); | 1659 hpos += XFASTINT (w->left); |
1585 get_display_line (f, vpos, XFASTINT (w->left)); | 1660 get_display_line (f, vpos, XFASTINT (w->left)); |
1586 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; | 1661 if (tab_width <= 0 || tab_width > 1000) tab_width = 8; |
1587 | 1662 |
1588 if (MINI_WINDOW_P (w) && start == 1 | 1663 if (MINI_WINDOW_P (w) && start == 1 |
1601 startp = desired_glyphs->glyphs[vpos] + XFASTINT (w->left); | 1676 startp = desired_glyphs->glyphs[vpos] + XFASTINT (w->left); |
1602 endp = startp + width; | 1677 endp = startp + width; |
1603 | 1678 |
1604 /* Loop generating characters. | 1679 /* Loop generating characters. |
1605 Stop at end of buffer, before newline, | 1680 Stop at end of buffer, before newline, |
1606 or if reach or pass continuation column. */ | 1681 if reach or pass continuation column, |
1607 | 1682 or at face change. */ |
1608 pause = pos; | 1683 pause = pos; |
1684 next_face_change = pos; | |
1609 while (p1 < endp) | 1685 while (p1 < endp) |
1610 { | 1686 { |
1611 p1prev = p1; | 1687 p1prev = p1; |
1612 if (pos == pause) | 1688 if (pos >= pause) |
1613 { | 1689 { |
1614 if (pos == end) | 1690 /* Did we hit the end of the visible region of the buffer? |
1691 Stop here. */ | |
1692 if (pos >= end) | |
1615 break; | 1693 break; |
1694 | |
1695 /* Did we reach point? Record the cursor location. */ | |
1616 if (pos == point && cursor_vpos < 0) | 1696 if (pos == point && cursor_vpos < 0) |
1617 { | 1697 { |
1618 cursor_vpos = vpos; | 1698 cursor_vpos = vpos; |
1619 cursor_hpos = p1 - startp; | 1699 cursor_hpos = p1 - startp; |
1620 } | 1700 } |
1621 | 1701 |
1622 pause = end; | 1702 pause = end; |
1703 | |
1704 /* Did we hit a face change? Figure out what face we should | |
1705 use now. We also hit this the first time through the | |
1706 loop, to see what face we should start with. */ | |
1707 if (pos == next_face_change) | |
1708 { | |
1709 current_face = compute_char_face (f, w, pos, &next_face_change); | |
1710 if (pos < next_face_change && next_face_change < pause) | |
1711 pause = next_face_change; | |
1712 } | |
1713 | |
1714 /* Wouldn't you hate to read the next line to someone over | |
1715 the phone? */ | |
1623 if (pos < point && point < pause) | 1716 if (pos < point && point < pause) |
1624 pause = point; | 1717 pause = point; |
1625 if (pos < GPT && GPT < pause) | 1718 if (pos < GPT && GPT < pause) |
1626 pause = GPT; | 1719 pause = GPT; |
1627 | 1720 |
1630 c = *p++; | 1723 c = *p++; |
1631 if (c >= 040 && c < 0177 | 1724 if (c >= 040 && c < 0177 |
1632 && (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector)) | 1725 && (dp == 0 || XTYPE (DISP_CHAR_VECTOR (dp, c)) != Lisp_Vector)) |
1633 { | 1726 { |
1634 if (p1 >= startp) | 1727 if (p1 >= startp) |
1635 *p1 = c; | 1728 *p1 = MAKE_GLYPH (c, 0); |
1636 p1++; | 1729 p1++; |
1637 } | 1730 } |
1638 else if (c == '\n') | 1731 else if (c == '\n') |
1639 { | 1732 { |
1640 invis = 0; | 1733 invis = 0; |
1654 p1 = endp; | 1747 p1 = endp; |
1655 copy_part_of_rope (p1prev, p1prev, | 1748 copy_part_of_rope (p1prev, p1prev, |
1656 XVECTOR (DISP_INVIS_VECTOR (dp))->contents, | 1749 XVECTOR (DISP_INVIS_VECTOR (dp))->contents, |
1657 (p1 - p1prev)); | 1750 (p1 - p1prev)); |
1658 } | 1751 } |
1659 break; | 1752 |
1753 /* This assures we'll exit the loop, but still gives us a chance to | |
1754 apply current_face to the glyphs we've laid down. */ | |
1755 end = pos; | |
1756 pause = end; | |
1660 } | 1757 } |
1661 else if (c == '\t') | 1758 else if (c == '\t') |
1662 { | 1759 { |
1663 do | 1760 do |
1664 { | 1761 { |
1681 p1 = endp; | 1778 p1 = endp; |
1682 copy_part_of_rope (p1prev, p1prev, | 1779 copy_part_of_rope (p1prev, p1prev, |
1683 XVECTOR(DISP_INVIS_VECTOR (dp))->contents, | 1780 XVECTOR(DISP_INVIS_VECTOR (dp))->contents, |
1684 (p1 - p1prev)); | 1781 (p1 - p1prev)); |
1685 } | 1782 } |
1686 break; | 1783 end = pos; |
1784 pause = end; | |
1687 } | 1785 } |
1688 else if (dp != 0 && XTYPE (DISP_CHAR_VECTOR (dp, c)) == Lisp_Vector) | 1786 else if (dp != 0 && XTYPE (DISP_CHAR_VECTOR (dp, c)) == Lisp_Vector) |
1689 { | 1787 { |
1690 p1 = copy_rope (p1, startp, DISP_CHAR_VECTOR (dp, c)); | 1788 p1 = copy_rope (p1, startp, DISP_CHAR_VECTOR (dp, c)); |
1691 } | 1789 } |
1692 else if (c < 0200 && ctl_arrow) | 1790 else if (c < 0200 && ctl_arrow) |
1693 { | 1791 { |
1694 if (p1 >= startp) | 1792 if (p1 >= startp) |
1695 *p1 = (dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int | 1793 *p1 = MAKE_GLYPH ((dp && XTYPE (DISP_CTRL_GLYPH (dp)) == Lisp_Int |
1696 ? XINT (DISP_CTRL_GLYPH (dp)) : '^'); | 1794 ? XINT (DISP_CTRL_GLYPH (dp)) : '^'), |
1795 0); | |
1697 p1++; | 1796 p1++; |
1698 if (p1 >= startp && p1 < endp) | 1797 if (p1 >= startp && p1 < endp) |
1699 *p1 = c ^ 0100; | 1798 *p1 = MAKE_GLYPH (c ^ 0100, 0); |
1700 p1++; | 1799 p1++; |
1701 } | 1800 } |
1702 else | 1801 else |
1703 { | 1802 { |
1704 if (p1 >= startp) | 1803 if (p1 >= startp) |
1705 *p1 = (dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int | 1804 *p1 = MAKE_GLYPH ((dp && XTYPE (DISP_ESCAPE_GLYPH (dp)) == Lisp_Int |
1706 ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'); | 1805 ? XINT (DISP_ESCAPE_GLYPH (dp)) : '\\'), |
1806 0); | |
1707 p1++; | 1807 p1++; |
1708 if (p1 >= startp && p1 < endp) | 1808 if (p1 >= startp && p1 < endp) |
1709 *p1 = (c >> 6) + '0'; | 1809 *p1 = MAKE_GLYPH ((c >> 6) + '0', 0); |
1710 p1++; | 1810 p1++; |
1711 if (p1 >= startp && p1 < endp) | 1811 if (p1 >= startp && p1 < endp) |
1712 *p1 = (7 & (c >> 3)) + '0'; | 1812 *p1 = MAKE_GLYPH ((7 & (c >> 3)) + '0', 0); |
1713 p1++; | 1813 p1++; |
1714 if (p1 >= startp && p1 < endp) | 1814 if (p1 >= startp && p1 < endp) |
1715 *p1 = (7 & c) + '0'; | 1815 *p1 = MAKE_GLYPH ((7 & c) + '0', 0); |
1716 p1++; | 1816 p1++; |
1717 } | 1817 } |
1818 | |
1819 /* Now we've laid down some characters between p1prev and p1. | |
1820 Let's apply current_face to those who have a face of zero | |
1821 (the default), and apply Vglyph_table to the result. */ | |
1822 if (current_face) | |
1823 { | |
1824 GLYPH *gstart, *gp, *gend; | |
1825 | |
1826 gstart = (p1prev > startp) ? p1prev : startp; | |
1827 gend = (p1 < endp) ? p1 : endp; | |
1828 | |
1829 for (gp = gstart; gp < gend; gp++) | |
1830 *gp = MAKE_GLYPH (GLYPH_CHAR (*gp), | |
1831 (GLYPH_FACE (*gp) == 0 | |
1832 ? current_face | |
1833 : compute_glyph_face (f, FRAME_DEFAULT_FACE (f), | |
1834 GLYPH_FACE (*gp)))); | |
1835 } | |
1836 | |
1718 pos++; | 1837 pos++; |
1719 } | 1838 } |
1720 | 1839 |
1721 val.hpos = - XINT (w->hscroll); | 1840 val.hpos = - XINT (w->hscroll); |
1722 if (val.hpos) | 1841 if (val.hpos) |