diff options
| author | Jim Blandy | 1993-05-10 00:23:47 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-05-10 00:23:47 +0000 |
| commit | 31b245519739f916ec9e4ccb8274262aff879c69 (patch) | |
| tree | 7efb65938e746df65bf1f230fa1a2bcfdd0c6168 /src | |
| parent | 703f280806d8029ef900fa50a367fd53a71706ef (diff) | |
| download | emacs-31b245519739f916ec9e4ccb8274262aff879c69.tar.gz emacs-31b245519739f916ec9e4ccb8274262aff879c69.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 149 |
1 files changed, 134 insertions, 15 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index d8555f591b7..b7d554c7a39 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -516,6 +516,12 @@ redisplay () | |||
| 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; |
| @@ -1473,6 +1479,68 @@ try_window_id (window) | |||
| 1473 | return 1; | 1479 | return 1; |
| 1474 | } | 1480 | } |
| 1475 | 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 | |||
| 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. */ |
| @@ -1581,6 +1649,13 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 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; |
| @@ -1603,16 +1678,21 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 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; |
| @@ -1620,6 +1700,19 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 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) |
| @@ -1632,7 +1725,7 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 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') |
| @@ -1656,7 +1749,11 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 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 | { |
| @@ -1683,7 +1780,8 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 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 | { |
| @@ -1692,29 +1790,50 @@ display_text_line (w, start, vpos, hpos, taboffset) | |||
| 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 | ||