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)