aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit4
-rw-r--r--src/ChangeLog180
-rw-r--r--src/alloc.c2
-rw-r--r--src/bidi.c2
-rw-r--r--src/buffer.c77
-rw-r--r--src/buffer.h66
-rw-r--r--src/bytecode.c2
-rw-r--r--src/callint.c2
-rw-r--r--src/callproc.c2
-rw-r--r--src/casefiddle.c2
-rw-r--r--src/casetab.c2
-rw-r--r--src/category.c5
-rw-r--r--src/category.h26
-rw-r--r--src/character.c3
-rw-r--r--src/cmds.c2
-rw-r--r--src/coding.c5
-rw-r--r--src/composite.c2
-rw-r--r--src/dired.c2
-rw-r--r--src/dispextern.h10
-rw-r--r--src/dispnew.c2
-rw-r--r--src/doc.c2
-rw-r--r--src/dosfns.c2
-rw-r--r--src/editfns.c2
-rw-r--r--src/emacs.c1
-rw-r--r--src/fileio.c2
-rw-r--r--src/filelock.c2
-rw-r--r--src/font.c2
-rw-r--r--src/fontset.c2
-rw-r--r--src/fringe.c1
-rw-r--r--src/indent.c2
-rw-r--r--src/insdel.c2
-rw-r--r--src/intervals.c1
-rw-r--r--src/keyboard.c2
-rw-r--r--src/keymap.c2
-rw-r--r--src/lisp.h151
-rw-r--r--src/lread.c2
-rw-r--r--src/macros.c1
-rw-r--r--src/makefile.w32-in13
-rw-r--r--src/marker.c2
-rw-r--r--src/minibuf.c1
-rw-r--r--src/nsfns.m2
-rw-r--r--src/nsmenu.m1
-rw-r--r--src/nsterm.m162
-rw-r--r--src/print.c2
-rw-r--r--src/process.c137
-rw-r--r--src/process.h2
-rw-r--r--src/regex.c2
-rw-r--r--src/region-cache.c1
-rw-r--r--src/s/bsd-common.h9
-rw-r--r--src/s/template.h1
-rw-r--r--src/s/usg5-4-common.h3
-rw-r--r--src/search.c2
-rw-r--r--src/syntax.c2
-rw-r--r--src/term.c2
-rw-r--r--src/textprop.c1
-rw-r--r--src/undo.c1
-rw-r--r--src/unexsol.c1
-rw-r--r--src/w16select.c2
-rw-r--r--src/w32fns.c2
-rw-r--r--src/w32menu.c1
-rw-r--r--src/w32term.c196
-rw-r--r--src/window.c41
-rw-r--r--src/xdisp.c39
-rw-r--r--src/xfaces.c125
-rw-r--r--src/xfns.c2
-rw-r--r--src/xmenu.c1
-rw-r--r--src/xml.c1
-rw-r--r--src/xselect.c2
-rw-r--r--src/xterm.c199
69 files changed, 1067 insertions, 468 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index df3a9cd7124..1db25324ea0 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -60,7 +60,7 @@ define xgetint
60 if gdb_use_struct 60 if gdb_use_struct
61 set $bugfix = $bugfix.i 61 set $bugfix = $bugfix.i
62 end 62 end
63 set $int = gdb_use_lsb ? $bugfix >> (gdb_gctypebits - 1) : $bugfix << gdb_gctypebits) >> gdb_gctypebits 63 set $int = gdb_use_lsb ? $bugfix >> (gdb_gctypebits - 1) : $bugfix << (gdb_gctypebits - 1) >> (gdb_gctypebits - 1)
64end 64end
65 65
66define xgettype 66define xgettype
@@ -1189,7 +1189,7 @@ define hookpost-backtrace
1189end 1189end
1190 1190
1191define xreload 1191define xreload
1192 set $tagmask = (((long)1 << gdb_gctypebits) - 1) 1192 set $tagmask = ((1 << gdb_gctypebits) - 1)
1193 # The consing_since_gc business widens the 1 to EMACS_INT, 1193 # The consing_since_gc business widens the 1 to EMACS_INT,
1194 # a symbol not directly visible to GDB. 1194 # a symbol not directly visible to GDB.
1195 set $valmask = gdb_use_lsb ? ~($tagmask) : ((consing_since_gc - consing_since_gc + 1) << gdb_valbits) - 1 1195 set $valmask = gdb_use_lsb ? ~($tagmask) : ((consing_since_gc - consing_since_gc + 1) << gdb_valbits) - 1
diff --git a/src/ChangeLog b/src/ChangeLog
index 19a9ace0728..9a239de5b99 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,183 @@
12012-06-18 Martin Rudalics <rudalics@gmx.at>
2
3 * buffer.c (Fkill_buffer): Don't throw an error when the buffer
4 gets killed during executing of this function (Bug#11665). Try
5 to always return Qt when the buffer has been actually killed.
6 (Vkill_buffer_query_functions): In doc-string say that functions
7 run by this hook should not change the current buffer.
8
92012-06-18 Paul Eggert <eggert@cs.ucla.edu>
10
11 Fix recently-introduced process.c problems found by static checking.
12 * process.c (write_queue_push, write_queue_pop, send_process):
13 Use ptrdiff_t, not int or EMACS_INT, for buffer lengths and offsets.
14 (write_queue_pop): Fix pointer signedness problem.
15 (send_process): Remove unused local.
16
172012-06-17 Chong Yidong <cyd@gnu.org>
18
19 * xdisp.c (redisplay_internal): No need to redisplay terminal
20 frames that are not on top.
21
222012-06-17 Troels Nielsen <bn.troels@gmail.com>
23
24 * process.c (make_process): Initialize write_queue.
25 (write_queue_push, write_queue_pop): New functions.
26 (send_process): Use them to maintain correct ordering of process
27 writes (Bug#10815).
28
292012-06-17 Paul Eggert <eggert@cs.ucla.edu>
30
31 * lisp.h (eassert): Assume C89 or later.
32 This removes the need for CHECK.
33 (CHECK): Remove. Its comments about always evaluating its
34 argument were confusing, as 'eassert' typically does not evaluate
35 its argument.
36
37 * coding.c (produce_chars): Use ptrdiff_t, not int.
38
39 * xterm.c (x_draw_underwave): Check for integer overflow.
40 This pacifies gcc 4.7.0 -Wunsafe-loop-optimizations on x86-64.
41
422012-06-17 Jan Djärv <jan.h.d@swipnet.se>
43
44 * nsterm.m (x_free_frame_resources): Move xfree so freed memory isn't
45 referenced (Bug#11583).
46
472012-06-16 Aurelien Aptel <aurelien.aptel@gmail.com>
48
49 Implement wave-style variant of underlining.
50 * dispextern.h (face_underline_type): New enum.
51 (face): Add field for underline type.
52 * nsterm.m (ns_draw_underwave): New function.
53 (ns_draw_text_decoration): Use it.
54 * w32term.c (w32_restore_glyph_string_clip, w32_draw_underwave):
55 New functions.
56 (x_draw_glyph_string): Use them.
57 * xfaces.c (Qline, Qwave): New Lisp objects.
58 (check_lface_attrs, merge_face_ref)
59 (Finternal_set_lisp_face_attribute, realize_x_face): Handle
60 wave-style underline face attributes.
61 * xterm.c (x_draw_underwave): New function.
62 (x_draw_glyph_string): Use it.
63
642012-06-16 Juanma Barranquero <lekktu@gmail.com>
65
66 * makefile.w32-in ($(BLD)/emacs.$(O), $(BLD)/fringe.$(O))
67 ($(BLD)/xml.$(O), $(BLD)/intervals.$(O), $(BLD)/macros.$(O))
68 ($(BLD)/minibuf.$(O), $(BLD)/regex.$(O), $(BLD)/region-cache.$(O))
69 ($(BLD)/textprop.$(O), $(BLD)/undo.$(O), $(BLD)/window.$(O))
70 ($(BLD)/w32select.$(O)): Update dependencies.
71
722012-06-16 Andreas Schwab <schwab@linux-m68k.org>
73
74 * buffer.h (FETCH_MULTIBYTE_CHAR): Define as inline.
75 (BUF_FETCH_MULTIBYTE_CHAR): Likewise.
76 * character.c (_fetch_multibyte_char_p): Remove.
77 * alloc.c: Include "character.h" before "buffer.h".
78 * bidi.c: Likewise.
79 * buffer.c: Likewise.
80 * bytecode.c: Likewise.
81 * callint.c: Likewise.
82 * callproc.c: Likewise.
83 * casefiddle.c: Likewise.
84 * casetab.c: Likewise.
85 * category.c: Likewise.
86 * cmds.c: Likewise.
87 * coding.c: Likewise.
88 * composite.c: Likewise.
89 * dired.c: Likewise.
90 * dispnew.c: Likewise.
91 * doc.c: Likewise.
92 * dosfns.c: Likewise.
93 * editfns.c: Likewise.
94 * emacs.c: Likewise.
95 * fileio.c: Likewise.
96 * filelock.c: Likewise.
97 * font.c: Likewise.
98 * fontset.c: Likewise.
99 * fringe.c: Likewise.
100 * indent.c: Likewise.
101 * insdel.c: Likewise.
102 * intervals.c: Likewise.
103 * keyboard.c: Likewise.
104 * keymap.c: Likewise.
105 * lread.c: Likewise.
106 * macros.c: Likewise.
107 * marker.c: Likewise.
108 * minibuf.c: Likewise.
109 * nsfns.m: Likewise.
110 * nsmenu.m: Likewise.
111 * print.c: Likewise.
112 * process.c: Likewise.
113 * regex.c: Likewise.
114 * region-cache.c: Likewise.
115 * search.c: Likewise.
116 * syntax.c: Likewise.
117 * term.c: Likewise.
118 * textprop.c: Likewise.
119 * undo.c: Likewise.
120 * unexsol.c: Likewise.
121 * w16select.c: Likewise.
122 * w32fns.c: Likewise.
123 * w32menu.c: Likewise.
124 * window.c: Likewise.
125 * xdisp.c: Likewise.
126 * xfns.c: Likewise.
127 * xmenu.c: Likewise.
128 * xml.c: Likewise.
129 * xselect.c: Likewise.
130
1312012-06-16 Eli Zaretskii <eliz@gnu.org>
132
133 * xdisp.c (set_cursor_from_row): Don't dereference glyphs_end. If
134 all the glyphs of the glyph row came from strings, and we have no
135 cursor positioning clues, put the cursor on the first glyph of the
136 row.
137 (handle_face_prop): Use chunk-relative overlay string index when
138 indexing into it->string_overlays array. (Bug#11653)
139 (set_cursor_from_row): Use the leftmost glyph as GLYPH_BEFORE, not
140 the rightmost. (Bug#11720)
141
1422012-06-16 Andreas Schwab <schwab@linux-m68k.org>
143
144 * category.h (CHAR_HAS_CATEGORY): Define as inline.
145 (CATEGORY_MEMBER): Enforce 1/0 value.
146 * category.c (_temp_category_set): Remove.
147
1482012-06-16 Eli Zaretskii <eliz@gnu.org>
149
150 * window.c (Fdelete_other_windows_internal)
151 (Fdelete_window_internal): Don't access frame's mouse highlight
152 info of the initial frame. (Bug#11677)
153
1542012-06-14 Paul Eggert <eggert@cs.ucla.edu>
155
156 * .gdbinit (xgetint): Fix recently-introduced paren typo.
157 Assume USE_2_TAGS_FOR_INTS.
158 (xreload): Adjust $tagmask width to match recent lisp.h change.
159
160 Simplify lisp.h in minor ways that should not affect code.
161 * lisp.h (USE_2_TAGS_FOR_INTS): Remove, as it was always defined.
162 (LISP_INT_TAG, case_Lisp_Int, LISP_STRING_TAG, LISP_INT_TAG_P)
163 (LISP_INT1_TAG, enum Lisp_Type, XINT, XUINT, make_number):
164 Simplify under the assumption that USE_2_TAGS_FOR_INTS is defined.
165 (INTTYPEBITS): New macro, for clarity.
166 (INTMASK, MOST_POSITIVE_FIXNUM): Use it.
167 (LISP_INT1_TAG, LISP_STRING_TAG, LISP_INT_TAG_P): Simplify
168 now that USE_LSB_TAG is always defined.
169 (TYPEMASK, XINT) [USE_LSB_TAG]: Remove unnecessary cast.
170 (make_number) [!USE_LSB_TAG]: Use INTMASK; that's simpler.
171
1722012-06-13 Juanma Barranquero <lekktu@gmail.com>
173
174 * makefile.w32-in ($(BLD)/data.$(O)): Update dependencies.
175
1762012-06-13 Glenn Morris <rgm@gnu.org>
177
178 * s/bsd-common.h (BSD4_3):
179 * s/usg5-4-common.h (USG5_4): No longer define; unused.
180
12012-06-13 Andreas Schwab <schwab@linux-m68k.org> 1812012-06-13 Andreas Schwab <schwab@linux-m68k.org>
2 182
3 * lisp.h (Lisp_Object) [CHECK_LISP_OBJECT_TYPE]: Define as struct 183 * lisp.h (Lisp_Object) [CHECK_LISP_OBJECT_TYPE]: Define as struct
diff --git a/src/alloc.c b/src/alloc.c
index 1478ce9ae4e..5c6297faae5 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -38,12 +38,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
38#include "process.h" 38#include "process.h"
39#include "intervals.h" 39#include "intervals.h"
40#include "puresize.h" 40#include "puresize.h"
41#include "character.h"
41#include "buffer.h" 42#include "buffer.h"
42#include "window.h" 43#include "window.h"
43#include "keyboard.h" 44#include "keyboard.h"
44#include "frame.h" 45#include "frame.h"
45#include "blockinput.h" 46#include "blockinput.h"
46#include "character.h"
47#include "syssignal.h" 47#include "syssignal.h"
48#include "termhooks.h" /* For struct terminal. */ 48#include "termhooks.h" /* For struct terminal. */
49#include <setjmp.h> 49#include <setjmp.h>
diff --git a/src/bidi.c b/src/bidi.c
index 7a716d3f0b0..675e2028d92 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -59,8 +59,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
59#include <setjmp.h> 59#include <setjmp.h>
60 60
61#include "lisp.h" 61#include "lisp.h"
62#include "buffer.h"
63#include "character.h" 62#include "character.h"
63#include "buffer.h"
64#include "dispextern.h" 64#include "dispextern.h"
65 65
66static int bidi_initialized = 0; 66static int bidi_initialized = 0;
diff --git a/src/buffer.c b/src/buffer.c
index 504d477494b..e501c9b73cc 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -33,8 +33,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
33#include "intervals.h" 33#include "intervals.h"
34#include "window.h" 34#include "window.h"
35#include "commands.h" 35#include "commands.h"
36#include "buffer.h"
37#include "character.h" 36#include "character.h"
37#include "buffer.h"
38#include "region-cache.h" 38#include "region-cache.h"
39#include "indent.h" 39#include "indent.h"
40#include "blockinput.h" 40#include "blockinput.h"
@@ -1434,24 +1434,26 @@ No argument or nil as argument means do this for the current buffer. */)
1434 DEFVAR_LISP ("kill-buffer-hook", ..., "\ 1434 DEFVAR_LISP ("kill-buffer-hook", ..., "\
1435Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\ 1435Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
1436The buffer being killed will be current while the hook is running.\n\ 1436The buffer being killed will be current while the hook is running.\n\
1437See `kill-buffer'." 1437
1438 */ 1438Functions run by this hook are supposed to not change the current
1439buffer. See `kill-buffer'."
1440*/
1439DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ", 1441DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
1440 doc: /* Kill buffer BUFFER-OR-NAME. 1442 doc: /* Kill the buffer specified by BUFFER-OR-NAME.
1441The argument may be a buffer or the name of an existing buffer. 1443The argument may be a buffer or the name of an existing buffer.
1442Argument nil or omitted means kill the current buffer. Return t if the 1444Argument nil or omitted means kill the current buffer. Return t if the
1443buffer is actually killed, nil otherwise. 1445buffer is actually killed, nil otherwise.
1444 1446
1445This function calls `replace-buffer-in-windows' for cleaning up all 1447The functions in `kill-buffer-query-functions' are called with the
1446windows currently displaying the buffer to be killed. The functions in 1448buffer to be killed as the current buffer. If any of them returns nil,
1447`kill-buffer-query-functions' are called with the buffer to be killed as 1449the buffer is not killed. The hook `kill-buffer-hook' is run before the
1448the current buffer. If any of them returns nil, the buffer is not 1450buffer is actually killed. The buffer being killed will be current
1449killed. The hook `kill-buffer-hook' is run before the buffer is 1451while the hook is running. Functions called by any of these hooks are
1450actually killed. The buffer being killed will be current while the hook 1452supposed to not change the current buffer.
1451is running.
1452 1453
1453Any processes that have this buffer as the `process-buffer' are killed 1454Any processes that have this buffer as the `process-buffer' are killed
1454with SIGHUP. */) 1455with SIGHUP. This function calls `replace-buffer-in-windows' for
1456cleaning up all windows currently displaying the buffer to be killed. */)
1455 (Lisp_Object buffer_or_name) 1457 (Lisp_Object buffer_or_name)
1456{ 1458{
1457 Lisp_Object buffer; 1459 Lisp_Object buffer;
@@ -1505,6 +1507,10 @@ with SIGHUP. */)
1505 unbind_to (count, Qnil); 1507 unbind_to (count, Qnil);
1506 } 1508 }
1507 1509
1510 /* If the hooks have killed the buffer, exit now. */
1511 if (NILP (BVAR (b, name)))
1512 return Qt;
1513
1508 /* We have no more questions to ask. Verify that it is valid 1514 /* We have no more questions to ask. Verify that it is valid
1509 to kill the buffer. This must be done after the questions 1515 to kill the buffer. This must be done after the questions
1510 since anything can happen within do_yes_or_no_p. */ 1516 since anything can happen within do_yes_or_no_p. */
@@ -1513,9 +1519,6 @@ with SIGHUP. */)
1513 if (EQ (buffer, XWINDOW (minibuf_window)->buffer)) 1519 if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
1514 return Qnil; 1520 return Qnil;
1515 1521
1516 if (NILP (BVAR (b, name)))
1517 return Qnil;
1518
1519 /* When we kill a base buffer, kill all its indirect buffers. 1522 /* When we kill a base buffer, kill all its indirect buffers.
1520 We do it at this stage so nothing terrible happens if they 1523 We do it at this stage so nothing terrible happens if they
1521 ask questions or their hooks get errors. */ 1524 ask questions or their hooks get errors. */
@@ -1536,6 +1539,10 @@ with SIGHUP. */)
1536 } 1539 }
1537 1540
1538 UNGCPRO; 1541 UNGCPRO;
1542
1543 /* Exit if we now have killed the base buffer (Bug#11665). */
1544 if (NILP (BVAR (b, name)))
1545 return Qt;
1539 } 1546 }
1540 1547
1541 /* Run replace_buffer_in_windows before making another buffer current 1548 /* Run replace_buffer_in_windows before making another buffer current
@@ -1544,9 +1551,12 @@ with SIGHUP. */)
1544 buffer. (Bug#10114) */ 1551 buffer. (Bug#10114) */
1545 replace_buffer_in_windows (buffer); 1552 replace_buffer_in_windows (buffer);
1546 1553
1547 /* Make this buffer not be current. 1554 /* Exit if replacing the buffer in windows has killed our buffer. */
1548 In the process, notice if this is the sole visible buffer 1555 if (NILP (BVAR (b, name)))
1549 and give up if so. */ 1556 return Qt;
1557
1558 /* Make this buffer not be current. Exit if it is the sole visible
1559 buffer. */
1550 if (b == current_buffer) 1560 if (b == current_buffer)
1551 { 1561 {
1552 tem = Fother_buffer (buffer, Qnil, Qnil); 1562 tem = Fother_buffer (buffer, Qnil, Qnil);
@@ -1555,15 +1565,12 @@ with SIGHUP. */)
1555 return Qnil; 1565 return Qnil;
1556 } 1566 }
1557 1567
1558 /* Notice if the buffer to kill is the sole visible buffer 1568 /* If the buffer now current is shown in the minibuffer and our buffer
1559 when we're currently in the mini-buffer, and give up if so. */ 1569 is the sole other buffer give up. */
1560 XSETBUFFER (tem, current_buffer); 1570 XSETBUFFER (tem, current_buffer);
1561 if (EQ (tem, XWINDOW (minibuf_window)->buffer)) 1571 if (EQ (tem, XWINDOW (minibuf_window)->buffer)
1562 { 1572 && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
1563 tem = Fother_buffer (buffer, Qnil, Qnil); 1573 return Qnil;
1564 if (EQ (buffer, tem))
1565 return Qnil;
1566 }
1567 1574
1568 /* Now there is no question: we can kill the buffer. */ 1575 /* Now there is no question: we can kill the buffer. */
1569 1576
@@ -1576,11 +1583,10 @@ with SIGHUP. */)
1576 kill_buffer_processes (buffer); 1583 kill_buffer_processes (buffer);
1577 UNGCPRO; 1584 UNGCPRO;
1578 1585
1579 /* Killing buffer processes may run sentinels which may 1586 /* Killing buffer processes may run sentinels which may have killed
1580 have called kill-buffer. */ 1587 our buffer. */
1581
1582 if (NILP (BVAR (b, name))) 1588 if (NILP (BVAR (b, name)))
1583 return Qnil; 1589 return Qt;
1584 1590
1585 /* These may run Lisp code and into infinite loops (if someone 1591 /* These may run Lisp code and into infinite loops (if someone
1586 insisted on circular lists) so allow quitting here. */ 1592 insisted on circular lists) so allow quitting here. */
@@ -1592,8 +1598,7 @@ with SIGHUP. */)
1592 Vinhibit_quit = Qt; 1598 Vinhibit_quit = Qt;
1593 /* Remove the buffer from the list of all buffers. */ 1599 /* Remove the buffer from the list of all buffers. */
1594 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist); 1600 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
1595 /* If replace_buffer_in_windows didn't do its job correctly fix that 1601 /* If replace_buffer_in_windows didn't do its job fix that now. */
1596 now. */
1597 replace_buffer_in_windows_safely (buffer); 1602 replace_buffer_in_windows_safely (buffer);
1598 Vinhibit_quit = tem; 1603 Vinhibit_quit = tem;
1599 1604
@@ -1611,6 +1616,10 @@ with SIGHUP. */)
1611 internal_delete_file (BVAR (b, auto_save_file_name)); 1616 internal_delete_file (BVAR (b, auto_save_file_name));
1612 } 1617 }
1613 1618
1619 /* Deleting an auto-save file could have killed our buffer. */
1620 if (NILP (BVAR (b, name)))
1621 return Qt;
1622
1614 if (b->base_buffer) 1623 if (b->base_buffer)
1615 { 1624 {
1616 /* Unchain all markers that belong to this indirect buffer. 1625 /* Unchain all markers that belong to this indirect buffer.
@@ -5991,7 +6000,9 @@ Use Custom to set this variable and update the display." */);
5991 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions, 6000 DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
5992 doc: /* List of functions called with no args to query before killing a buffer. 6001 doc: /* List of functions called with no args to query before killing a buffer.
5993The buffer being killed will be current while the functions are running. 6002The buffer being killed will be current while the functions are running.
5994If any of them returns nil, the buffer is not killed. */); 6003
6004If any of them returns nil, the buffer is not killed. Functions run by
6005this hook are supposed to not change the current buffer. */);
5995 Vkill_buffer_query_functions = Qnil; 6006 Vkill_buffer_query_functions = Qnil;
5996 6007
5997 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook, 6008 DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
diff --git a/src/buffer.h b/src/buffer.h
index 3aa4b11c450..8e0604e90c2 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -355,28 +355,6 @@ while (0)
355 355
356#define FETCH_BYTE(n) *(BYTE_POS_ADDR ((n))) 356#define FETCH_BYTE(n) *(BYTE_POS_ADDR ((n)))
357 357
358/* Variables used locally in FETCH_MULTIBYTE_CHAR. */
359extern unsigned char *_fetch_multibyte_char_p;
360
361/* Return character code of multi-byte form at byte position POS. If POS
362 doesn't point the head of valid multi-byte form, only the byte at
363 POS is returned. No range checking.
364
365 WARNING: The character returned by this macro could be "unified"
366 inside STRING_CHAR, if the original character in the buffer belongs
367 to one of the Private Use Areas (PUAs) of codepoints that Emacs
368 uses to support non-unified CJK characters. If that happens,
369 CHAR_BYTES will return a value that is different from the length of
370 the original multibyte sequence stored in the buffer. Therefore,
371 do _not_ use FETCH_MULTIBYTE_CHAR if you need to advance through
372 the buffer to the next character after fetching this one. Instead,
373 use either FETCH_CHAR_ADVANCE or STRING_CHAR_AND_LENGTH. */
374
375#define FETCH_MULTIBYTE_CHAR(pos) \
376 (_fetch_multibyte_char_p = (((pos) >= GPT_BYTE ? GAP_SIZE : 0) \
377 + (pos) + BEG_ADDR - BEG_BYTE), \
378 STRING_CHAR (_fetch_multibyte_char_p))
379
380/* Return character at byte position POS. If the current buffer is unibyte 358/* Return character at byte position POS. If the current buffer is unibyte
381 and the character is not ASCII, make the returning character 359 and the character is not ASCII, make the returning character
382 multibyte. */ 360 multibyte. */
@@ -425,16 +403,6 @@ extern unsigned char *_fetch_multibyte_char_p;
425 403
426#define BUF_FETCH_BYTE(buf, n) \ 404#define BUF_FETCH_BYTE(buf, n) \
427 *(BUF_BYTE_ADDRESS ((buf), (n))) 405 *(BUF_BYTE_ADDRESS ((buf), (n)))
428
429/* Return character code of multi-byte form at byte position POS in BUF.
430 If POS doesn't point the head of valid multi-byte form, only the byte at
431 POS is returned. No range checking. */
432
433#define BUF_FETCH_MULTIBYTE_CHAR(buf, pos) \
434 (_fetch_multibyte_char_p \
435 = (((pos) >= BUF_GPT_BYTE (buf) ? BUF_GAP_SIZE (buf) : 0) \
436 + (pos) + BUF_BEG_ADDR (buf) - BEG_BYTE), \
437 STRING_CHAR (_fetch_multibyte_char_p))
438 406
439/* Define the actual buffer data structures. */ 407/* Define the actual buffer data structures. */
440 408
@@ -945,7 +913,41 @@ EXFUN (Fbuffer_local_value, 2);
945extern Lisp_Object Qbefore_change_functions; 913extern Lisp_Object Qbefore_change_functions;
946extern Lisp_Object Qafter_change_functions; 914extern Lisp_Object Qafter_change_functions;
947extern Lisp_Object Qfirst_change_hook; 915extern Lisp_Object Qfirst_change_hook;
916
917/* Return character code of multi-byte form at byte position POS. If POS
918 doesn't point the head of valid multi-byte form, only the byte at
919 POS is returned. No range checking.
920
921 WARNING: The character returned by this macro could be "unified"
922 inside STRING_CHAR, if the original character in the buffer belongs
923 to one of the Private Use Areas (PUAs) of codepoints that Emacs
924 uses to support non-unified CJK characters. If that happens,
925 CHAR_BYTES will return a value that is different from the length of
926 the original multibyte sequence stored in the buffer. Therefore,
927 do _not_ use FETCH_MULTIBYTE_CHAR if you need to advance through
928 the buffer to the next character after fetching this one. Instead,
929 use either FETCH_CHAR_ADVANCE or STRING_CHAR_AND_LENGTH. */
948 930
931static inline int
932FETCH_MULTIBYTE_CHAR (ptrdiff_t pos)
933{
934 unsigned char *p = ((pos >= GPT_BYTE ? GAP_SIZE : 0)
935 + pos + BEG_ADDR - BEG_BYTE);
936 return STRING_CHAR (p);
937}
938
939/* Return character code of multi-byte form at byte position POS in BUF.
940 If POS doesn't point the head of valid multi-byte form, only the byte at
941 POS is returned. No range checking. */
942
943static inline int
944BUF_FETCH_MULTIBYTE_CHAR (struct buffer *buf, ptrdiff_t pos)
945{
946 unsigned char *p
947 = ((pos >= BUF_GPT_BYTE (buf) ? BUF_GAP_SIZE (buf) : 0)
948 + pos + BUF_BEG_ADDR (buf) - BEG_BYTE);
949 return STRING_CHAR (p);
950}
949 951
950/* Overlays */ 952/* Overlays */
951 953
diff --git a/src/bytecode.c b/src/bytecode.c
index e2370254f36..2e6ee3d4445 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -35,8 +35,8 @@ by Hallvard:
35#include <config.h> 35#include <config.h>
36#include <setjmp.h> 36#include <setjmp.h>
37#include "lisp.h" 37#include "lisp.h"
38#include "buffer.h"
39#include "character.h" 38#include "character.h"
39#include "buffer.h"
40#include "syntax.h" 40#include "syntax.h"
41#include "window.h" 41#include "window.h"
42 42
diff --git a/src/callint.c b/src/callint.c
index bfa981ec65a..e5ff99714c0 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -22,12 +22,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <setjmp.h> 22#include <setjmp.h>
23 23
24#include "lisp.h" 24#include "lisp.h"
25#include "character.h"
25#include "buffer.h" 26#include "buffer.h"
26#include "commands.h" 27#include "commands.h"
27#include "keyboard.h" 28#include "keyboard.h"
28#include "window.h" 29#include "window.h"
29#include "keymap.h" 30#include "keymap.h"
30#include "character.h"
31 31
32Lisp_Object Qminus, Qplus; 32Lisp_Object Qminus, Qplus;
33Lisp_Object Qcall_interactively; 33Lisp_Object Qcall_interactively;
diff --git a/src/callproc.c b/src/callproc.c
index 976d3061c8b..804af1e9abb 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -44,8 +44,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
44#endif /* MSDOS */ 44#endif /* MSDOS */
45 45
46#include "commands.h" 46#include "commands.h"
47#include "buffer.h"
48#include "character.h" 47#include "character.h"
48#include "buffer.h"
49#include "ccl.h" 49#include "ccl.h"
50#include "coding.h" 50#include "coding.h"
51#include "composite.h" 51#include "composite.h"
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 278806b3030..19fbc832288 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -21,8 +21,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22#include <setjmp.h> 22#include <setjmp.h>
23#include "lisp.h" 23#include "lisp.h"
24#include "buffer.h"
25#include "character.h" 24#include "character.h"
25#include "buffer.h"
26#include "commands.h" 26#include "commands.h"
27#include "syntax.h" 27#include "syntax.h"
28#include "composite.h" 28#include "composite.h"
diff --git a/src/casetab.c b/src/casetab.c
index c28f0c08d5e..86dbca4d026 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -21,8 +21,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22#include <setjmp.h> 22#include <setjmp.h>
23#include "lisp.h" 23#include "lisp.h"
24#include "buffer.h"
25#include "character.h" 24#include "character.h"
25#include "buffer.h"
26 26
27static Lisp_Object Qcase_table_p, Qcase_table; 27static Lisp_Object Qcase_table_p, Qcase_table;
28Lisp_Object Vascii_downcase_table; 28Lisp_Object Vascii_downcase_table;
diff --git a/src/category.c b/src/category.c
index a59ad3da53e..7d0f72d284d 100644
--- a/src/category.c
+++ b/src/category.c
@@ -32,8 +32,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include <ctype.h> 32#include <ctype.h>
33#include <setjmp.h> 33#include <setjmp.h>
34#include "lisp.h" 34#include "lisp.h"
35#include "buffer.h"
36#include "character.h" 35#include "character.h"
36#include "buffer.h"
37#include "charset.h" 37#include "charset.h"
38#include "category.h" 38#include "category.h"
39#include "keymap.h" 39#include "keymap.h"
@@ -50,9 +50,6 @@ static int category_table_version;
50 50
51static Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, Qcategory_table_p; 51static Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, Qcategory_table_p;
52 52
53/* Temporary internal variable used in macro CHAR_HAS_CATEGORY. */
54Lisp_Object _temp_category_set;
55
56/* Make CATEGORY_SET includes (if VAL is t) or excludes (if VAL is 53/* Make CATEGORY_SET includes (if VAL is t) or excludes (if VAL is
57 nil) CATEGORY. */ 54 nil) CATEGORY. */
58#define SET_CATEGORY_SET(category_set, category, val) \ 55#define SET_CATEGORY_SET(category_set, category, val) \
diff --git a/src/category.h b/src/category.h
index 423270100b3..580e516afd9 100644
--- a/src/category.h
+++ b/src/category.h
@@ -1,6 +1,6 @@
1/* Declarations having to do with Emacs category tables. 1/* Declarations having to do with Emacs category tables.
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008, 2009, 2010, 2011 3 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 National Institute of Advanced Industrial Science and Technology (AIST) 4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H14PRO021 5 Registration Number H14PRO021
6 Copyright (C) 2003 6 Copyright (C) 2003
@@ -69,27 +69,27 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
69#define CHECK_CATEGORY_SET(x) \ 69#define CHECK_CATEGORY_SET(x) \
70 CHECK_TYPE (CATEGORY_SET_P (x), Qcategorysetp, x) 70 CHECK_TYPE (CATEGORY_SET_P (x), Qcategorysetp, x)
71 71
72/* Return the category set of character C in the current category table. */
73#define CATEGORY_SET(c) char_category_set (c)
74
72/* Return 1 if CATEGORY_SET contains CATEGORY, else return 0. 75/* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
73 The faster version of `!NILP (Faref (category_set, category))'. */ 76 The faster version of `!NILP (Faref (category_set, category))'. */
74#define CATEGORY_MEMBER(category, category_set) \ 77#define CATEGORY_MEMBER(category, category_set) \
75 (XCATEGORY_SET (category_set)->data[(category) / 8] \ 78 ((XCATEGORY_SET (category_set)->data[(category) / 8] \
76 & (1 << ((category) % 8))) 79 >> ((category) % 8)) & 1)
77
78/* Temporary internal variable used in macro CHAR_HAS_CATEGORY. */
79extern Lisp_Object _temp_category_set;
80 80
81/* Return 1 if category set of CH contains CATEGORY, elt return 0. */ 81/* Return 1 if category set of CH contains CATEGORY, else return 0. */
82#define CHAR_HAS_CATEGORY(ch, category) \ 82static inline int
83 (_temp_category_set = CATEGORY_SET (ch), \ 83CHAR_HAS_CATEGORY (int ch, int category)
84 CATEGORY_MEMBER (category, _temp_category_set)) 84{
85 Lisp_Object category_set = CATEGORY_SET (ch);
86 return CATEGORY_MEMBER (category, category_set);
87}
85 88
86/* The standard category table is stored where it will automatically 89/* The standard category table is stored where it will automatically
87 be used in all new buffers. */ 90 be used in all new buffers. */
88#define Vstandard_category_table BVAR (&buffer_defaults, category_table) 91#define Vstandard_category_table BVAR (&buffer_defaults, category_table)
89 92
90/* Return the category set of character C in the current category table. */
91#define CATEGORY_SET(c) char_category_set (c)
92
93/* Return the doc string of CATEGORY in category table TABLE. */ 93/* Return the doc string of CATEGORY in category table TABLE. */
94#define CATEGORY_DOCSTRING(table, category) \ 94#define CATEGORY_DOCSTRING(table, category) \
95 XVECTOR (Fchar_table_extra_slot (table, make_number (0)))->contents[(category) - ' '] 95 XVECTOR (Fchar_table_extra_slot (table, make_number (0)))->contents[(category) - ' ']
diff --git a/src/character.c b/src/character.c
index b85cedad937..fbd23409d08 100644
--- a/src/character.c
+++ b/src/character.c
@@ -57,9 +57,6 @@ static Lisp_Object Qauto_fill_chars;
57 Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */ 57 Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */
58Lisp_Object Vchar_unify_table; 58Lisp_Object Vchar_unify_table;
59 59
60/* Variable used locally in the macro FETCH_MULTIBYTE_CHAR. */
61unsigned char *_fetch_multibyte_char_p;
62
63static Lisp_Object Qchar_script_table; 60static Lisp_Object Qchar_script_table;
64 61
65 62
diff --git a/src/cmds.c b/src/cmds.c
index 225c26b082c..d617c7f81d9 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -22,8 +22,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <setjmp.h> 22#include <setjmp.h>
23#include "lisp.h" 23#include "lisp.h"
24#include "commands.h" 24#include "commands.h"
25#include "buffer.h"
26#include "character.h" 25#include "character.h"
26#include "buffer.h"
27#include "syntax.h" 27#include "syntax.h"
28#include "window.h" 28#include "window.h"
29#include "keyboard.h" 29#include "keyboard.h"
diff --git a/src/coding.c b/src/coding.c
index 17e342298b9..64826ae16b9 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -288,8 +288,8 @@ encode_coding_XXX (struct coding_system *coding)
288#include <setjmp.h> 288#include <setjmp.h>
289 289
290#include "lisp.h" 290#include "lisp.h"
291#include "buffer.h"
292#include "character.h" 291#include "character.h"
292#include "buffer.h"
293#include "charset.h" 293#include "charset.h"
294#include "ccl.h" 294#include "ccl.h"
295#include "composite.h" 295#include "composite.h"
@@ -6765,7 +6765,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
6765 6765
6766 while (buf < buf_end) 6766 while (buf < buf_end)
6767 { 6767 {
6768 int c = *buf, i; 6768 int c = *buf;
6769 ptrdiff_t i;
6769 6770
6770 if (c >= 0) 6771 if (c >= 0)
6771 { 6772 {
diff --git a/src/composite.c b/src/composite.c
index 50aca156ba4..6070e4070f0 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -25,8 +25,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25#include <config.h> 25#include <config.h>
26#include <setjmp.h> 26#include <setjmp.h>
27#include "lisp.h" 27#include "lisp.h"
28#include "buffer.h"
29#include "character.h" 28#include "character.h"
29#include "buffer.h"
30#include "coding.h" 30#include "coding.h"
31#include "intervals.h" 31#include "intervals.h"
32#include "window.h" 32#include "window.h"
diff --git a/src/dired.c b/src/dired.c
index 38dfa23c1bf..1ce236d5674 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -71,9 +71,9 @@ extern struct direct *readdir (DIR *);
71 71
72#include "lisp.h" 72#include "lisp.h"
73#include "systime.h" 73#include "systime.h"
74#include "character.h"
74#include "buffer.h" 75#include "buffer.h"
75#include "commands.h" 76#include "commands.h"
76#include "character.h"
77#include "charset.h" 77#include "charset.h"
78#include "coding.h" 78#include "coding.h"
79#include "regex.h" 79#include "regex.h"
diff --git a/src/dispextern.h b/src/dispextern.h
index 76e98437cf1..db7a91299d0 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1520,6 +1520,13 @@ enum face_box_type
1520 FACE_SUNKEN_BOX 1520 FACE_SUNKEN_BOX
1521}; 1521};
1522 1522
1523/* Underline type. */
1524
1525enum face_underline_type
1526{
1527 FACE_UNDER_LINE,
1528 FACE_UNDER_WAVE
1529};
1523 1530
1524/* Structure describing a realized face. 1531/* Structure describing a realized face.
1525 1532
@@ -1595,6 +1602,9 @@ struct face
1595 drawing shadows. */ 1602 drawing shadows. */
1596 unsigned use_box_color_for_shadows_p : 1; 1603 unsigned use_box_color_for_shadows_p : 1;
1597 1604
1605 /* Style of underlining. */
1606 enum face_underline_type underline_type;
1607
1598 /* Non-zero if text in this face should be underlined, overlined, 1608 /* Non-zero if text in this face should be underlined, overlined,
1599 strike-through or have a box drawn around it. */ 1609 strike-through or have a box drawn around it. */
1600 unsigned underline_p : 1; 1610 unsigned underline_p : 1;
diff --git a/src/dispnew.c b/src/dispnew.c
index b8ce90bff9f..36f2c686ac0 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -29,8 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29/* cm.h must come after dispextern.h on Windows. */ 29/* cm.h must come after dispextern.h on Windows. */
30#include "dispextern.h" 30#include "dispextern.h"
31#include "cm.h" 31#include "cm.h"
32#include "buffer.h"
33#include "character.h" 32#include "character.h"
33#include "buffer.h"
34#include "keyboard.h" 34#include "keyboard.h"
35#include "frame.h" 35#include "frame.h"
36#include "termhooks.h" 36#include "termhooks.h"
diff --git a/src/doc.c b/src/doc.c
index cd23d9266a2..223741c3bf5 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -28,9 +28,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include <unistd.h> 28#include <unistd.h>
29 29
30#include "lisp.h" 30#include "lisp.h"
31#include "character.h"
31#include "buffer.h" 32#include "buffer.h"
32#include "keyboard.h" 33#include "keyboard.h"
33#include "character.h"
34#include "keymap.h" 34#include "keymap.h"
35#include "buildobj.h" 35#include "buildobj.h"
36 36
diff --git a/src/dosfns.c b/src/dosfns.c
index d4b96e9df90..e8c0187172d 100644
--- a/src/dosfns.c
+++ b/src/dosfns.c
@@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#include <dos.h> 26#include <dos.h>
27#include <setjmp.h> 27#include <setjmp.h>
28#include "lisp.h" 28#include "lisp.h"
29#include "character.h"
29#include "buffer.h" 30#include "buffer.h"
30#include "termchar.h" 31#include "termchar.h"
31#include "frame.h" 32#include "frame.h"
@@ -35,7 +36,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35#include "dosfns.h" 36#include "dosfns.h"
36#include "msdos.h" 37#include "msdos.h"
37#include "dispextern.h" 38#include "dispextern.h"
38#include "character.h"
39#include "coding.h" 39#include "coding.h"
40#include "process.h" 40#include "process.h"
41#include <dpmi.h> 41#include <dpmi.h>
diff --git a/src/editfns.c b/src/editfns.c
index 8f7b2aee76c..1fb20b07e70 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -52,8 +52,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
52#include <verify.h> 52#include <verify.h>
53 53
54#include "intervals.h" 54#include "intervals.h"
55#include "buffer.h"
56#include "character.h" 55#include "character.h"
56#include "buffer.h"
57#include "coding.h" 57#include "coding.h"
58#include "frame.h" 58#include "frame.h"
59#include "window.h" 59#include "window.h"
diff --git a/src/emacs.c b/src/emacs.c
index 0b679c7747a..1354352abd9 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -45,6 +45,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45 45
46#include "commands.h" 46#include "commands.h"
47#include "intervals.h" 47#include "intervals.h"
48#include "character.h"
48#include "buffer.h" 49#include "buffer.h"
49#include "window.h" 50#include "window.h"
50 51
diff --git a/src/fileio.c b/src/fileio.c
index 496f9d7efa4..388ae84b6f3 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -40,8 +40,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40 40
41#include "lisp.h" 41#include "lisp.h"
42#include "intervals.h" 42#include "intervals.h"
43#include "buffer.h"
44#include "character.h" 43#include "character.h"
44#include "buffer.h"
45#include "coding.h" 45#include "coding.h"
46#include "window.h" 46#include "window.h"
47#include "blockinput.h" 47#include "blockinput.h"
diff --git a/src/filelock.c b/src/filelock.c
index d8914c73328..a0ac154a0d2 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -40,8 +40,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40#include <errno.h> 40#include <errno.h>
41 41
42#include "lisp.h" 42#include "lisp.h"
43#include "buffer.h"
44#include "character.h" 43#include "character.h"
44#include "buffer.h"
45#include "coding.h" 45#include "coding.h"
46#include "systime.h" 46#include "systime.h"
47 47
diff --git a/src/font.c b/src/font.c
index 16d09af01b3..dbea3a3ca3c 100644
--- a/src/font.c
+++ b/src/font.c
@@ -27,12 +27,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
27#include <setjmp.h> 27#include <setjmp.h>
28 28
29#include "lisp.h" 29#include "lisp.h"
30#include "character.h"
30#include "buffer.h" 31#include "buffer.h"
31#include "frame.h" 32#include "frame.h"
32#include "window.h" 33#include "window.h"
33#include "dispextern.h" 34#include "dispextern.h"
34#include "charset.h" 35#include "charset.h"
35#include "character.h"
36#include "composite.h" 36#include "composite.h"
37#include "fontset.h" 37#include "fontset.h"
38#include "font.h" 38#include "font.h"
diff --git a/src/fontset.c b/src/fontset.c
index b2c7249625e..1d704a5900e 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -32,8 +32,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32 32
33#include "lisp.h" 33#include "lisp.h"
34#include "blockinput.h" 34#include "blockinput.h"
35#include "buffer.h"
36#include "character.h" 35#include "character.h"
36#include "buffer.h"
37#include "charset.h" 37#include "charset.h"
38#include "ccl.h" 38#include "ccl.h"
39#include "keyboard.h" 39#include "keyboard.h"
diff --git a/src/fringe.c b/src/fringe.c
index 39f7e8dbb54..0224ea73e3e 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include "frame.h" 24#include "frame.h"
25#include "window.h" 25#include "window.h"
26#include "dispextern.h" 26#include "dispextern.h"
27#include "character.h"
27#include "buffer.h" 28#include "buffer.h"
28#include "blockinput.h" 29#include "blockinput.h"
29#include "termhooks.h" 30#include "termhooks.h"
diff --git a/src/indent.c b/src/indent.c
index 32533438e2a..88cc0ab4798 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -22,8 +22,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <setjmp.h> 22#include <setjmp.h>
23 23
24#include "lisp.h" 24#include "lisp.h"
25#include "buffer.h"
26#include "character.h" 25#include "character.h"
26#include "buffer.h"
27#include "category.h" 27#include "category.h"
28#include "composite.h" 28#include "composite.h"
29#include "indent.h" 29#include "indent.h"
diff --git a/src/insdel.c b/src/insdel.c
index 148ba221940..060f83f7a2f 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -25,8 +25,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 25
26#include "lisp.h" 26#include "lisp.h"
27#include "intervals.h" 27#include "intervals.h"
28#include "buffer.h"
29#include "character.h" 28#include "character.h"
29#include "buffer.h"
30#include "window.h" 30#include "window.h"
31#include "blockinput.h" 31#include "blockinput.h"
32#include "region-cache.h" 32#include "region-cache.h"
diff --git a/src/intervals.c b/src/intervals.c
index 0b332caf897..2c652cd9ad9 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -42,6 +42,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
42#include <intprops.h> 42#include <intprops.h>
43#include "lisp.h" 43#include "lisp.h"
44#include "intervals.h" 44#include "intervals.h"
45#include "character.h"
45#include "buffer.h" 46#include "buffer.h"
46#include "puresize.h" 47#include "puresize.h"
47#include "keyboard.h" 48#include "keyboard.h"
diff --git a/src/keyboard.c b/src/keyboard.c
index ba473ac8a2b..6be81728102 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -30,8 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30#include "keyboard.h" 30#include "keyboard.h"
31#include "window.h" 31#include "window.h"
32#include "commands.h" 32#include "commands.h"
33#include "buffer.h"
34#include "character.h" 33#include "character.h"
34#include "buffer.h"
35#include "disptab.h" 35#include "disptab.h"
36#include "dispextern.h" 36#include "dispextern.h"
37#include "syntax.h" 37#include "syntax.h"
diff --git a/src/keymap.c b/src/keymap.c
index 2f5558c171f..6c59a4a78d0 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -43,8 +43,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
43#include <setjmp.h> 43#include <setjmp.h>
44#include "lisp.h" 44#include "lisp.h"
45#include "commands.h" 45#include "commands.h"
46#include "buffer.h"
47#include "character.h" 46#include "character.h"
47#include "buffer.h"
48#include "charset.h" 48#include "charset.h"
49#include "keyboard.h" 49#include "keyboard.h"
50#include "frame.h" 50#include "frame.h"
diff --git a/src/lisp.h b/src/lisp.h
index c655413544c..991dec431cc 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -106,7 +106,12 @@ typedef EMACS_UINT uprintmax_t;
106 106
107/* Extra internal type checking? */ 107/* Extra internal type checking? */
108 108
109#ifdef ENABLE_CHECKING 109/* Define an Emacs version of 'assert (COND)', since some
110 system-defined 'assert's are flaky. COND should be free of side
111 effects; it may or may not be evaluated. */
112#ifndef ENABLE_CHECKING
113# define eassert(X) ((void) (0 && (X))) /* Check that X compiles. */
114#else /* ENABLE_CHECKING */
110 115
111extern void die (const char *, const char *, int) NO_RETURN; 116extern void die (const char *, const char *, int) NO_RETURN;
112 117
@@ -114,39 +119,16 @@ extern void die (const char *, const char *, int) NO_RETURN;
114 it to 1 using a debugger to temporarily disable aborting on 119 it to 1 using a debugger to temporarily disable aborting on
115 detected internal inconsistencies or error conditions. 120 detected internal inconsistencies or error conditions.
116 121
117 Testing suppress_checking after the supplied condition ensures that
118 the side effects produced by CHECK will be consistent, independent
119 of whether ENABLE_CHECKING is defined, or whether the checks are
120 suppressed at run time.
121
122 In some cases, a good compiler may be able to optimize away the 122 In some cases, a good compiler may be able to optimize away the
123 CHECK macro altogether, e.g., if XSTRING (x) uses CHECK to test 123 eassert macro altogether, e.g., if XSTRING (x) uses eassert to test
124 STRINGP (x), but a particular use of XSTRING is invoked only after 124 STRINGP (x), but a particular use of XSTRING is invoked only after
125 testing that STRINGP (x) is true, making the test redundant. */ 125 testing that STRINGP (x) is true, making the test redundant. */
126
127extern int suppress_checking EXTERNALLY_VISIBLE; 126extern int suppress_checking EXTERNALLY_VISIBLE;
128 127
129#define CHECK(check,msg) (((check) || suppress_checking \ 128# define eassert(cond) \
130 ? (void) 0 \ 129 ((cond) || suppress_checking \
131 : die ((msg), __FILE__, __LINE__)), \ 130 ? (void) 0 \
132 0) 131 : die ("assertion failed: " # cond, __FILE__, __LINE__))
133#else
134
135/* Produce same side effects and result, but don't complain. */
136#define CHECK(check,msg) ((check),0)
137
138#endif
139
140/* Define an Emacs version of "assert", since some system ones are
141 flaky. */
142#ifndef ENABLE_CHECKING
143#define eassert(X) ((void) (0 && (X))) /* Check that X compiles. */
144#else /* ENABLE_CHECKING */
145#if defined (__GNUC__) && __GNUC__ >= 2 && defined (__STDC__)
146#define eassert(cond) CHECK (cond, "assertion failed: " #cond)
147#else
148#define eassert(cond) CHECK (cond, "assertion failed")
149#endif
150#endif /* ENABLE_CHECKING */ 132#endif /* ENABLE_CHECKING */
151 133
152/* Use the configure flag --enable-check-lisp-object-type to make 134/* Use the configure flag --enable-check-lisp-object-type to make
@@ -230,31 +212,18 @@ extern int suppress_checking EXTERNALLY_VISIBLE;
230 212
231/* Define the fundamental Lisp data structures. */ 213/* Define the fundamental Lisp data structures. */
232 214
233/* If USE_2_TAGBITS_FOR_INTS is defined, then Lisp integers use
234 2 tags, to give them one extra bit, thus extending their range from
235 e.g -2^28..2^28-1 to -2^29..2^29-1. */
236#define USE_2_TAGS_FOR_INTS
237
238/* This is the set of Lisp data types. */ 215/* This is the set of Lisp data types. */
239 216
240#if !defined USE_2_TAGS_FOR_INTS 217/* Lisp integers use 2 tags, to give them one extra bit, thus
241# define LISP_INT_TAG Lisp_Int 218 extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */
242# define case_Lisp_Int case Lisp_Int 219#define INTTYPEBITS (GCTYPEBITS - 1)
243# define LISP_STRING_TAG 4 220#define FIXNUM_BITS (VALBITS + 1)
244# define LISP_INT_TAG_P(x) ((x) == Lisp_Int) 221#define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1))
245#else 222#define LISP_INT_TAG Lisp_Int0
246# define LISP_INT_TAG Lisp_Int0 223#define case_Lisp_Int case Lisp_Int0: case Lisp_Int1
247# define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 224#define LISP_INT1_TAG (USE_LSB_TAG ? 1 << INTTYPEBITS : 1)
248# if USE_LSB_TAG 225#define LISP_STRING_TAG (5 - LISP_INT1_TAG)
249# define LISP_INT1_TAG 4 226#define LISP_INT_TAG_P(x) (((x) & ~LISP_INT1_TAG) == 0)
250# define LISP_STRING_TAG 1
251# define LISP_INT_TAG_P(x) (((x) & 3) == 0)
252# else
253# define LISP_INT1_TAG 1
254# define LISP_STRING_TAG 4
255# define LISP_INT_TAG_P(x) (((x) & 6) == 0)
256# endif
257#endif
258 227
259/* Stolen from GDB. The only known compiler that doesn't support 228/* Stolen from GDB. The only known compiler that doesn't support
260 enums in bitfields is MSVC. */ 229 enums in bitfields is MSVC. */
@@ -268,12 +237,8 @@ extern int suppress_checking EXTERNALLY_VISIBLE;
268enum Lisp_Type 237enum Lisp_Type
269 { 238 {
270 /* Integer. XINT (obj) is the integer value. */ 239 /* Integer. XINT (obj) is the integer value. */
271#ifdef USE_2_TAGS_FOR_INTS
272 Lisp_Int0 = 0, 240 Lisp_Int0 = 0,
273 Lisp_Int1 = LISP_INT1_TAG, 241 Lisp_Int1 = LISP_INT1_TAG,
274#else
275 Lisp_Int = 0,
276#endif
277 242
278 /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ 243 /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */
279 Lisp_Symbol = 2, 244 Lisp_Symbol = 2,
@@ -420,68 +385,50 @@ enum pvec_type
420 XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */ 385 XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */
421 386
422/* Return a perfect hash of the Lisp_Object representation. */ 387/* Return a perfect hash of the Lisp_Object representation. */
423#define XHASH(a) XLI(a) 388#define XHASH(a) XLI (a)
424 389
425#if USE_LSB_TAG 390#if USE_LSB_TAG
426 391
427#define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1) 392#define TYPEMASK ((1 << GCTYPEBITS) - 1)
428#define XTYPE(a) ((enum Lisp_Type) (XLI(a) & TYPEMASK)) 393#define XTYPE(a) ((enum Lisp_Type) (XLI (a) & TYPEMASK))
429#ifdef USE_2_TAGS_FOR_INTS 394#define XINT(a) (XLI (a) >> INTTYPEBITS)
430# define XINT(a) (((EMACS_INT) XLI(a)) >> (GCTYPEBITS - 1)) 395#define XUINT(a) ((EMACS_UINT) XLI (a) >> INTTYPEBITS)
431# define XUINT(a) (((EMACS_UINT) XLI(a)) >> (GCTYPEBITS - 1)) 396#define make_number(N) XIL ((EMACS_INT) (N) << INTTYPEBITS)
432# define make_number(N) XIL(((EMACS_INT) (N)) << (GCTYPEBITS - 1))
433#else
434# define XINT(a) (((EMACS_INT) XLI(a)) >> GCTYPEBITS)
435# define XUINT(a) (((EMACS_UINT) XLI(a)) >> GCTYPEBITS)
436# define make_number(N) XIL(((EMACS_INT) (N)) << GCTYPEBITS)
437#endif
438#define XSET(var, type, ptr) \ 397#define XSET(var, type, ptr) \
439 (eassert (XTYPE (XIL((intptr_t) (ptr))) == 0), /* Check alignment. */ \ 398 (eassert (XTYPE (XIL ((intptr_t) (ptr))) == 0), /* Check alignment. */ \
440 (var) = XIL((type) | (intptr_t) (ptr))) 399 (var) = XIL ((type) | (intptr_t) (ptr)))
441 400
442#define XPNTR(a) ((intptr_t) (XLI(a) & ~TYPEMASK)) 401#define XPNTR(a) ((intptr_t) (XLI (a) & ~TYPEMASK))
443#define XUNTAG(a, type) ((intptr_t) (XLI(a) - (type))) 402#define XUNTAG(a, type) ((intptr_t) (XLI (a) - (type)))
444 403
445#else /* not USE_LSB_TAG */ 404#else /* not USE_LSB_TAG */
446 405
447#define VALMASK VAL_MAX 406#define VALMASK VAL_MAX
448 407
449/* One need to override this if there must be high bits set in data space 408#define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS))
450 (doing the result of the below & ((1 << (GCTYPE + 1)) - 1) would work
451 on all machines, but would penalize machines which don't need it)
452 */
453#define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) XLI(a)) >> VALBITS))
454 409
455/* For integers known to be positive, XFASTINT provides fast retrieval 410/* For integers known to be positive, XFASTINT provides fast retrieval
456 and XSETFASTINT provides fast storage. This takes advantage of the 411 and XSETFASTINT provides fast storage. This takes advantage of the
457 fact that Lisp_Int is 0. */ 412 fact that Lisp integers have zero-bits in their tags. */
458#define XFASTINT(a) (XLI(a) + 0) 413#define XFASTINT(a) (XLI (a) + 0)
459#define XSETFASTINT(a, b) ((a) = XIL(b)) 414#define XSETFASTINT(a, b) ((a) = XIL (b))
460 415
461/* Extract the value of a Lisp_Object as a (un)signed integer. */ 416/* Extract the value of a Lisp_Object as a (un)signed integer. */
462 417
463#ifdef USE_2_TAGS_FOR_INTS 418#define XINT(a) (XLI (a) << INTTYPEBITS >> INTTYPEBITS)
464# define XINT(a) ((((EMACS_INT) XLI(a)) << (GCTYPEBITS - 1)) >> (GCTYPEBITS - 1)) 419#define XUINT(a) ((EMACS_UINT) (XLI (a) & INTMASK))
465# define XUINT(a) ((EMACS_UINT) (XLI(a) & (1 + (VALMASK << 1)))) 420#define make_number(N) XIL ((EMACS_INT) (N) & INTMASK)
466# define make_number(N) XIL((((EMACS_INT) (N)) & (1 + (VALMASK << 1))))
467#else
468# define XINT(a) ((((EMACS_INT) XLI(a)) << (BITS_PER_EMACS_INT - VALBITS)) \
469 >> (BITS_PER_EMACS_INT - VALBITS))
470# define XUINT(a) ((EMACS_UINT) (XLI(a) & VALMASK))
471# define make_number(N) \
472 XIL((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS)
473#endif
474 421
475#define XSET(var, type, ptr) \ 422#define XSET(var, type, ptr) \
476 ((var) = XIL((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ 423 ((var) = XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \
477 + ((intptr_t) (ptr) & VALMASK))) 424 + ((intptr_t) (ptr) & VALMASK)))
478 425
479#ifdef DATA_SEG_BITS 426#ifdef DATA_SEG_BITS
480/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers 427/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers
481 which were stored in a Lisp_Object */ 428 which were stored in a Lisp_Object */
482#define XPNTR(a) ((uintptr_t) ((XLI(a) & VALMASK)) | DATA_SEG_BITS)) 429#define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS))
483#else 430#else
484#define XPNTR(a) ((uintptr_t) (XLI(a) & VALMASK)) 431#define XPNTR(a) ((uintptr_t) (XLI (a) & VALMASK))
485#endif 432#endif
486 433
487#endif /* not USE_LSB_TAG */ 434#endif /* not USE_LSB_TAG */
@@ -503,19 +450,9 @@ enum pvec_type
503 450
504#define EQ(x, y) (XHASH (x) == XHASH (y)) 451#define EQ(x, y) (XHASH (x) == XHASH (y))
505 452
506/* Number of bits in a fixnum, including the sign bit. */
507#ifdef USE_2_TAGS_FOR_INTS
508# define FIXNUM_BITS (VALBITS + 1)
509#else
510# define FIXNUM_BITS VALBITS
511#endif
512
513/* Mask indicating the significant bits of a fixnum. */
514#define INTMASK (((EMACS_INT) 1 << FIXNUM_BITS) - 1)
515
516/* Largest and smallest representable fixnum values. These are the C 453/* Largest and smallest representable fixnum values. These are the C
517 values. */ 454 values. */
518#define MOST_POSITIVE_FIXNUM (INTMASK / 2) 455#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
519#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) 456#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
520 457
521/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is 458/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is
@@ -821,7 +758,7 @@ struct vectorlike_header
821 /* When the vector is allocated from a vector block, NBYTES is used 758 /* When the vector is allocated from a vector block, NBYTES is used
822 if the vector is not on a free list, and VECTOR is used otherwise. 759 if the vector is not on a free list, and VECTOR is used otherwise.
823 For large vector-like objects, BUFFER or VECTOR is used as a pointer 760 For large vector-like objects, BUFFER or VECTOR is used as a pointer
824 to the next vector-like object. It is generally a buffer or a 761 to the next vector-like object. It is generally a buffer or a
825 Lisp_Vector alias, so for convenience it is a union instead of a 762 Lisp_Vector alias, so for convenience it is a union instead of a
826 pointer: this way, one can write P->next.vector instead of ((struct 763 pointer: this way, one can write P->next.vector instead of ((struct
827 Lisp_Vector *) P->next). */ 764 Lisp_Vector *) P->next). */
diff --git a/src/lread.c b/src/lread.c
index 8a9088b8ed2..a6d77204cf8 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -28,8 +28,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include <setjmp.h> 28#include <setjmp.h>
29#include "lisp.h" 29#include "lisp.h"
30#include "intervals.h" 30#include "intervals.h"
31#include "buffer.h"
32#include "character.h" 31#include "character.h"
32#include "buffer.h"
33#include "charset.h" 33#include "charset.h"
34#include "coding.h" 34#include "coding.h"
35#include <epaths.h> 35#include <epaths.h>
diff --git a/src/macros.c b/src/macros.c
index 0db7e63d622..7c8bc4c13b8 100644
--- a/src/macros.c
+++ b/src/macros.c
@@ -23,6 +23,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23#include "lisp.h" 23#include "lisp.h"
24#include "macros.h" 24#include "macros.h"
25#include "commands.h" 25#include "commands.h"
26#include "character.h"
26#include "buffer.h" 27#include "buffer.h"
27#include "window.h" 28#include "window.h"
28#include "keyboard.h" 29#include "keyboard.h"
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 0b88f7cd06b..be9d4a3361c 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -676,6 +676,7 @@ $(BLD)/composite.$(O) : \
676$(BLD)/data.$(O) : \ 676$(BLD)/data.$(O) : \
677 $(SRC)/data.c \ 677 $(SRC)/data.c \
678 $(SRC)/buffer.h \ 678 $(SRC)/buffer.h \
679 $(SRC)/keymap.h \
679 $(SRC)/puresize.h \ 680 $(SRC)/puresize.h \
680 $(SRC)/syssignal.h \ 681 $(SRC)/syssignal.h \
681 $(GNU_LIB)/intprops.h \ 682 $(GNU_LIB)/intprops.h \
@@ -781,6 +782,7 @@ $(BLD)/emacs.$(O) : \
781 $(NT_INC)/sys/file.h \ 782 $(NT_INC)/sys/file.h \
782 $(NT_INC)/unistd.h \ 783 $(NT_INC)/unistd.h \
783 $(BLOCKINPUT_H) \ 784 $(BLOCKINPUT_H) \
785 $(CHARACTER_H) \
784 $(CONFIG_H) \ 786 $(CONFIG_H) \
785 $(FRAME_H) \ 787 $(FRAME_H) \
786 $(INTERVALS_H) \ 788 $(INTERVALS_H) \
@@ -920,6 +922,7 @@ $(BLD)/fringe.$(O) : \
920 $(SRC)/fringe.c \ 922 $(SRC)/fringe.c \
921 $(SRC)/buffer.h \ 923 $(SRC)/buffer.h \
922 $(BLOCKINPUT_H) \ 924 $(BLOCKINPUT_H) \
925 $(CHARACTER_H) \
923 $(CONFIG_H) \ 926 $(CONFIG_H) \
924 $(DISPEXTERN_H) \ 927 $(DISPEXTERN_H) \
925 $(FRAME_H) \ 928 $(FRAME_H) \
@@ -944,6 +947,7 @@ $(BLD)/xml.$(O) : \
944 $(SRC)/xml.c \ 947 $(SRC)/xml.c \
945 $(SRC)/buffer.h \ 948 $(SRC)/buffer.h \
946 $(SRC)/w32.h \ 949 $(SRC)/w32.h \
950 $(CHARACTER_H) \
947 $(CONFIG_H) \ 951 $(CONFIG_H) \
948 $(LISP_H) 952 $(LISP_H)
949 953
@@ -1002,6 +1006,7 @@ $(BLD)/intervals.$(O) : \
1002 $(SRC)/keymap.h \ 1006 $(SRC)/keymap.h \
1003 $(SRC)/puresize.h \ 1007 $(SRC)/puresize.h \
1004 $(GNU_LIB)/intprops.h \ 1008 $(GNU_LIB)/intprops.h \
1009 $(CHARACTER_H) \
1005 $(CONFIG_H) \ 1010 $(CONFIG_H) \
1006 $(INTERVALS_H) \ 1011 $(INTERVALS_H) \
1007 $(KEYBOARD_H) \ 1012 $(KEYBOARD_H) \
@@ -1081,6 +1086,7 @@ $(BLD)/macros.$(O) : \
1081 $(SRC)/buffer.h \ 1086 $(SRC)/buffer.h \
1082 $(SRC)/commands.h \ 1087 $(SRC)/commands.h \
1083 $(SRC)/macros.h \ 1088 $(SRC)/macros.h \
1089 $(CHARACTER_H) \
1084 $(CONFIG_H) \ 1090 $(CONFIG_H) \
1085 $(KEYBOARD_H) \ 1091 $(KEYBOARD_H) \
1086 $(LISP_H) \ 1092 $(LISP_H) \
@@ -1113,6 +1119,7 @@ $(BLD)/minibuf.$(O) : \
1113 $(SRC)/commands.h \ 1119 $(SRC)/commands.h \
1114 $(SRC)/keymap.h \ 1120 $(SRC)/keymap.h \
1115 $(SRC)/syntax.h \ 1121 $(SRC)/syntax.h \
1122 $(CHARACTER_H) \
1116 $(CONFIG_H) \ 1123 $(CONFIG_H) \
1117 $(DISPEXTERN_H) \ 1124 $(DISPEXTERN_H) \
1118 $(FRAME_H) \ 1125 $(FRAME_H) \
@@ -1258,7 +1265,6 @@ $(BLD)/regex.$(O) : \
1258 $(SRC)/category.h \ 1265 $(SRC)/category.h \
1259 $(SRC)/regex.h \ 1266 $(SRC)/regex.h \
1260 $(SRC)/syntax.h \ 1267 $(SRC)/syntax.h \
1261 $(NT_INC)/unistd.h \
1262 $(CHARACTER_H) \ 1268 $(CHARACTER_H) \
1263 $(CONFIG_H) \ 1269 $(CONFIG_H) \
1264 $(LISP_H) 1270 $(LISP_H)
@@ -1267,6 +1273,7 @@ $(BLD)/region-cache.$(O) : \
1267 $(SRC)/region-cache.c \ 1273 $(SRC)/region-cache.c \
1268 $(SRC)/buffer.h \ 1274 $(SRC)/buffer.h \
1269 $(SRC)/region-cache.h \ 1275 $(SRC)/region-cache.h \
1276 $(CHARACTER_H) \
1270 $(CONFIG_H) \ 1277 $(CONFIG_H) \
1271 $(LISP_H) 1278 $(LISP_H)
1272 1279
@@ -1389,6 +1396,7 @@ $(BLD)/terminal.$(O) : \
1389$(BLD)/textprop.$(O) : \ 1396$(BLD)/textprop.$(O) : \
1390 $(SRC)/textprop.c \ 1397 $(SRC)/textprop.c \
1391 $(SRC)/buffer.h \ 1398 $(SRC)/buffer.h \
1399 $(CHARACTER_H) \
1392 $(CONFIG_H) \ 1400 $(CONFIG_H) \
1393 $(INTERVALS_H) \ 1401 $(INTERVALS_H) \
1394 $(LISP_H) \ 1402 $(LISP_H) \
@@ -1404,6 +1412,7 @@ $(BLD)/undo.$(O) : \
1404 $(SRC)/undo.c \ 1412 $(SRC)/undo.c \
1405 $(SRC)/buffer.h \ 1413 $(SRC)/buffer.h \
1406 $(SRC)/commands.h \ 1414 $(SRC)/commands.h \
1415 $(CHARACTER_H) \
1407 $(CONFIG_H) \ 1416 $(CONFIG_H) \
1408 $(LISP_H) \ 1417 $(LISP_H) \
1409 $(WINDOW_H) 1418 $(WINDOW_H)
@@ -1429,6 +1438,7 @@ $(BLD)/window.$(O) : \
1429 $(SRC)/keymap.h \ 1438 $(SRC)/keymap.h \
1430 $(SRC)/termchar.h \ 1439 $(SRC)/termchar.h \
1431 $(BLOCKINPUT_H) \ 1440 $(BLOCKINPUT_H) \
1441 $(CHARACTER_H) \
1432 $(CONFIG_H) \ 1442 $(CONFIG_H) \
1433 $(DISPEXTERN_H) \ 1443 $(DISPEXTERN_H) \
1434 $(FRAME_H) \ 1444 $(FRAME_H) \
@@ -1518,6 +1528,7 @@ $(BLD)/w32menu.$(O) : \
1518 $(SRC)/keymap.h \ 1528 $(SRC)/keymap.h \
1519 $(SRC)/w32heap.h \ 1529 $(SRC)/w32heap.h \
1520 $(BLOCKINPUT_H) \ 1530 $(BLOCKINPUT_H) \
1531 $(CHARACTER_H) \
1521 $(CHARSET_H) \ 1532 $(CHARSET_H) \
1522 $(CODING_H) \ 1533 $(CODING_H) \
1523 $(CONFIG_H) \ 1534 $(CONFIG_H) \
diff --git a/src/marker.c b/src/marker.c
index 37953494459..2c09b8e19a2 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -20,8 +20,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20#include <config.h> 20#include <config.h>
21#include <setjmp.h> 21#include <setjmp.h>
22#include "lisp.h" 22#include "lisp.h"
23#include "buffer.h"
24#include "character.h" 23#include "character.h"
24#include "buffer.h"
25 25
26/* Record one cached position found recently by 26/* Record one cached position found recently by
27 buf_charpos_to_bytepos or buf_bytepos_to_charpos. */ 27 buf_charpos_to_bytepos or buf_bytepos_to_charpos. */
diff --git a/src/minibuf.c b/src/minibuf.c
index d921e80be48..bed9bb39d31 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 25
26#include "lisp.h" 26#include "lisp.h"
27#include "commands.h" 27#include "commands.h"
28#include "character.h"
28#include "buffer.h" 29#include "buffer.h"
29#include "dispextern.h" 30#include "dispextern.h"
30#include "keyboard.h" 31#include "keyboard.h"
diff --git a/src/nsfns.m b/src/nsfns.m
index 5cea73c39ca..113fff394c4 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -38,11 +38,11 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
38#include "blockinput.h" 38#include "blockinput.h"
39#include "nsterm.h" 39#include "nsterm.h"
40#include "window.h" 40#include "window.h"
41#include "character.h"
41#include "buffer.h" 42#include "buffer.h"
42#include "keyboard.h" 43#include "keyboard.h"
43#include "termhooks.h" 44#include "termhooks.h"
44#include "fontset.h" 45#include "fontset.h"
45#include "character.h"
46#include "font.h" 46#include "font.h"
47 47
48#if 0 48#if 0
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 4bfe0cc003a..1f86417b53a 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -28,6 +28,7 @@ Carbon version by Yamamoto Mitsuharu. */
28 28
29#include "lisp.h" 29#include "lisp.h"
30#include "window.h" 30#include "window.h"
31#include "character.h"
31#include "buffer.h" 32#include "buffer.h"
32#include "keymap.h" 33#include "keymap.h"
33#include "coding.h" 34#include "coding.h"
diff --git a/src/nsterm.m b/src/nsterm.m
index 8bd2bb283b2..dd4969a1e2e 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1155,14 +1155,14 @@ x_free_frame_resources (struct frame *f)
1155 hlinfo->mouse_face_mouse_frame = 0; 1155 hlinfo->mouse_face_mouse_frame = 0;
1156 } 1156 }
1157 1157
1158 xfree (f->output_data.ns);
1159
1160 if (f->output_data.ns->miniimage != nil) 1158 if (f->output_data.ns->miniimage != nil)
1161 [f->output_data.ns->miniimage release]; 1159 [f->output_data.ns->miniimage release];
1162 1160
1163 [[view window] close]; 1161 [[view window] close];
1164 [view release]; 1162 [view release];
1165 1163
1164 xfree (f->output_data.ns);
1165
1166 UNBLOCK_INPUT; 1166 UNBLOCK_INPUT;
1167} 1167}
1168 1168
@@ -2595,6 +2595,60 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2595 return n; 2595 return n;
2596} 2596}
2597 2597
2598/* --------------------------------------------------------------------
2599 Draw a wavy line under glyph string s. The wave fills wave_height
2600 pixels from y.
2601
2602 x wave_length = 3
2603 --
2604 y * * * * *
2605 |* * * * * * * * *
2606 wave_height = 3 | * * * *
2607 --------------------------------------------------------------------- */
2608
2609static void
2610ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x)
2611{
2612 int wave_height = 3, wave_length = 3;
2613 int y, dx, dy, odd, xmax;
2614 NSPoint a, b;
2615 NSRect waveClip;
2616
2617 dx = wave_length;
2618 dy = wave_height - 1;
2619 y = s->ybase + 1;
2620 xmax = x + width;
2621
2622 /* Find and set clipping rectangle */
2623 waveClip = NSMakeRect (x, y, width, wave_height);
2624 [[NSGraphicsContext currentContext] saveGraphicsState];
2625 NSRectClip (waveClip);
2626
2627 /* Draw the waves */
2628 a.x = x - ((int)(x) % dx);
2629 b.x = a.x + dx;
2630 odd = (int)(a.x/dx) % 2;
2631 a.y = b.y = y;
2632
2633 if (odd)
2634 a.y += dy;
2635 else
2636 b.y += dy;
2637
2638 while (a.x <= xmax)
2639 {
2640 [NSBezierPath strokeLineFromPoint:a toPoint:b];
2641 a.x = b.x, a.y = b.y;
2642 b.x += dx, b.y = y + odd*dy;
2643 odd = !odd;
2644 }
2645
2646 /* Restore previous clipping rectangle(s) */
2647 [[NSGraphicsContext currentContext] restoreGraphicsState];
2648}
2649
2650
2651
2598void 2652void
2599ns_draw_text_decoration (struct glyph_string *s, struct face *face, 2653ns_draw_text_decoration (struct glyph_string *s, struct face *face,
2600 NSColor *defaultCol, CGFloat width, CGFloat x) 2654 NSColor *defaultCol, CGFloat width, CGFloat x)
@@ -2608,63 +2662,75 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
2608 /* Do underline. */ 2662 /* Do underline. */
2609 if (face->underline_p) 2663 if (face->underline_p)
2610 { 2664 {
2611 NSRect r; 2665 if (s->face->underline_type == FACE_UNDER_WAVE)
2612 unsigned long thickness, position;
2613
2614 /* If the prev was underlined, match its appearance. */
2615 if (s->prev && s->prev->face->underline_p
2616 && s->prev->underline_thickness > 0)
2617 { 2666 {
2618 thickness = s->prev->underline_thickness; 2667 if (face->underline_defaulted_p)
2619 position = s->prev->underline_position; 2668 [defaultCol set];
2669 else
2670 [ns_lookup_indexed_color (face->underline_color, s->f) set];
2671
2672 ns_draw_underwave (s, width, x);
2620 } 2673 }
2621 else 2674 else if (s->face->underline_type == FACE_UNDER_LINE)
2622 { 2675 {
2623 struct font *font;
2624 unsigned long descent;
2625
2626 font=s->font;
2627 descent = s->y + s->height - s->ybase;
2628
2629 /* Use underline thickness of font, defaulting to 1. */
2630 thickness = (font && font->underline_thickness > 0)
2631 ? font->underline_thickness : 1;
2632
2633 /* Determine the offset of underlining from the baseline. */
2634 if (x_underline_at_descent_line)
2635 position = descent - thickness;
2636 else if (x_use_underline_position_properties
2637 && font && font->underline_position >= 0)
2638 position = font->underline_position;
2639 else if (font)
2640 position = lround (font->descent / 2);
2641 else
2642 position = underline_minimum_offset;
2643 2676
2644 position = max (position, underline_minimum_offset); 2677 NSRect r;
2678 unsigned long thickness, position;
2645 2679
2646 /* Ensure underlining is not cropped. */ 2680 /* If the prev was underlined, match its appearance. */
2647 if (descent <= position) 2681 if (s->prev && s->prev->face->underline_p
2682 && s->prev->underline_thickness > 0)
2648 { 2683 {
2649 position = descent - 1; 2684 thickness = s->prev->underline_thickness;
2650 thickness = 1; 2685 position = s->prev->underline_position;
2651 } 2686 }
2652 else if (descent < position + thickness) 2687 else
2653 thickness = 1; 2688 {
2654 } 2689 struct font *font;
2690 unsigned long descent;
2691
2692 font=s->font;
2693 descent = s->y + s->height - s->ybase;
2694
2695 /* Use underline thickness of font, defaulting to 1. */
2696 thickness = (font && font->underline_thickness > 0)
2697 ? font->underline_thickness : 1;
2698
2699 /* Determine the offset of underlining from the baseline. */
2700 if (x_underline_at_descent_line)
2701 position = descent - thickness;
2702 else if (x_use_underline_position_properties
2703 && font && font->underline_position >= 0)
2704 position = font->underline_position;
2705 else if (font)
2706 position = lround (font->descent / 2);
2707 else
2708 position = underline_minimum_offset;
2655 2709
2656 s->underline_thickness = thickness; 2710 position = max (position, underline_minimum_offset);
2657 s->underline_position = position;
2658 2711
2659 r = NSMakeRect (x, s->ybase + position, width, thickness); 2712 /* Ensure underlining is not cropped. */
2713 if (descent <= position)
2714 {
2715 position = descent - 1;
2716 thickness = 1;
2717 }
2718 else if (descent < position + thickness)
2719 thickness = 1;
2720 }
2660 2721
2661 if (face->underline_defaulted_p) 2722 s->underline_thickness = thickness;
2662 [defaultCol set]; 2723 s->underline_position = position;
2663 else 2724
2664 [ns_lookup_indexed_color (face->underline_color, s->f) set]; 2725 r = NSMakeRect (x, s->ybase + position, width, thickness);
2665 NSRectFill (r);
2666 }
2667 2726
2727 if (face->underline_defaulted_p)
2728 [defaultCol set];
2729 else
2730 [ns_lookup_indexed_color (face->underline_color, s->f) set];
2731 NSRectFill (r);
2732 }
2733 }
2668 /* Do overline. We follow other terms in using a thickness of 1 2734 /* Do overline. We follow other terms in using a thickness of 1
2669 and ignoring overline_margin. */ 2735 and ignoring overline_margin. */
2670 if (face->overline_p) 2736 if (face->overline_p)
diff --git a/src/print.c b/src/print.c
index 4284a19d4df..c282c64aa89 100644
--- a/src/print.c
+++ b/src/print.c
@@ -23,8 +23,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23#include <stdio.h> 23#include <stdio.h>
24#include <setjmp.h> 24#include <setjmp.h>
25#include "lisp.h" 25#include "lisp.h"
26#include "buffer.h"
27#include "character.h" 26#include "character.h"
27#include "buffer.h"
28#include "charset.h" 28#include "charset.h"
29#include "keyboard.h" 29#include "keyboard.h"
30#include "frame.h" 30#include "frame.h"
diff --git a/src/process.c b/src/process.c
index 4d59ff0d452..cb89cae99fe 100644
--- a/src/process.c
+++ b/src/process.c
@@ -93,8 +93,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
93#include "systty.h" 93#include "systty.h"
94 94
95#include "window.h" 95#include "window.h"
96#include "buffer.h"
97#include "character.h" 96#include "character.h"
97#include "buffer.h"
98#include "coding.h" 98#include "coding.h"
99#include "process.h" 99#include "process.h"
100#include "frame.h" 100#include "frame.h"
@@ -638,6 +638,7 @@ make_process (Lisp_Object name)
638 p->status = Qrun; 638 p->status = Qrun;
639 p->mark = Fmake_marker (); 639 p->mark = Fmake_marker ();
640 p->kill_without_query = 0; 640 p->kill_without_query = 0;
641 p->write_queue = Qnil;
641 642
642#ifdef ADAPTIVE_READ_BUFFERING 643#ifdef ADAPTIVE_READ_BUFFERING
643 p->adaptive_read_buffering = 0; 644 p->adaptive_read_buffering = 0;
@@ -5371,6 +5372,78 @@ send_process_trap (int ignore)
5371 longjmp (send_process_frame, 1); 5372 longjmp (send_process_frame, 1);
5372} 5373}
5373 5374
5375/* In send_process, when a write fails temporarily,
5376 wait_reading_process_output is called. It may execute user code,
5377 e.g. timers, that attempts to write new data to the same process.
5378 We must ensure that data is sent in the right order, and not
5379 interspersed half-completed with other writes (Bug#10815). This is
5380 handled by the write_queue element of struct process. It is a list
5381 with each entry having the form
5382
5383 (string . (offset . length))
5384
5385 where STRING is a lisp string, OFFSET is the offset into the
5386 string's byte sequence from which we should begin to send, and
5387 LENGTH is the number of bytes left to send. */
5388
5389/* Create a new entry in write_queue.
5390 INPUT_OBJ should be a buffer, string Qt, or Qnil.
5391 BUF is a pointer to the string sequence of the input_obj or a C
5392 string in case of Qt or Qnil. */
5393
5394static void
5395write_queue_push (struct Lisp_Process *p, Lisp_Object input_obj,
5396 const char *buf, ptrdiff_t len, int front)
5397{
5398 ptrdiff_t offset;
5399 Lisp_Object entry, obj;
5400
5401 if (STRINGP (input_obj))
5402 {
5403 offset = buf - SSDATA (input_obj);
5404 obj = input_obj;
5405 }
5406 else
5407 {
5408 offset = 0;
5409 obj = make_unibyte_string (buf, len);
5410 }
5411
5412 entry = Fcons (obj, Fcons (make_number (offset), make_number (len)));
5413
5414 if (front)
5415 p->write_queue = Fcons (entry, p->write_queue);
5416 else
5417 p->write_queue = nconc2 (p->write_queue, Fcons (entry, Qnil));
5418}
5419
5420/* Remove the first element in the write_queue of process P, put its
5421 contents in OBJ, BUF and LEN, and return non-zero. If the
5422 write_queue is empty, return zero. */
5423
5424static int
5425write_queue_pop (struct Lisp_Process *p, Lisp_Object *obj,
5426 const char **buf, ptrdiff_t *len)
5427{
5428 Lisp_Object entry, offset_length;
5429 ptrdiff_t offset;
5430
5431 if (NILP (p->write_queue))
5432 return 0;
5433
5434 entry = XCAR (p->write_queue);
5435 p->write_queue = XCDR (p->write_queue);
5436
5437 *obj = XCAR (entry);
5438 offset_length = XCDR (entry);
5439
5440 *len = XINT (XCDR (offset_length));
5441 offset = XINT (XCAR (offset_length));
5442 *buf = SSDATA (*obj) + offset;
5443
5444 return 1;
5445}
5446
5374/* Send some data to process PROC. 5447/* Send some data to process PROC.
5375 BUF is the beginning of the data; LEN is the number of characters. 5448 BUF is the beginning of the data; LEN is the number of characters.
5376 OBJECT is the Lisp object that the data comes from. If OBJECT is 5449 OBJECT is the Lisp object that the data comes from. If OBJECT is
@@ -5389,11 +5462,8 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5389 struct Lisp_Process *p = XPROCESS (proc); 5462 struct Lisp_Process *p = XPROCESS (proc);
5390 ssize_t rv; 5463 ssize_t rv;
5391 struct coding_system *coding; 5464 struct coding_system *coding;
5392 struct gcpro gcpro1;
5393 void (*volatile old_sigpipe) (int); 5465 void (*volatile old_sigpipe) (int);
5394 5466
5395 GCPRO1 (object);
5396
5397 if (p->raw_status_new) 5467 if (p->raw_status_new)
5398 update_status (p); 5468 update_status (p);
5399 if (! EQ (p->status, Qrun)) 5469 if (! EQ (p->status, Qrun))
@@ -5505,22 +5575,37 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5505 if (!setjmp (send_process_frame)) 5575 if (!setjmp (send_process_frame))
5506 { 5576 {
5507 p = XPROCESS (proc); /* Repair any setjmp clobbering. */ 5577 p = XPROCESS (proc); /* Repair any setjmp clobbering. */
5508
5509 process_sent_to = proc; 5578 process_sent_to = proc;
5510 while (len > 0) 5579
5580 /* If there is already data in the write_queue, put the new data
5581 in the back of queue. Otherwise, ignore it. */
5582 if (!NILP (p->write_queue))
5583 write_queue_push (p, object, buf, len, 0);
5584
5585 do /* while !NILP (p->write_queue) */
5511 { 5586 {
5512 ptrdiff_t this = len; 5587 ptrdiff_t cur_len = -1;
5588 const char *cur_buf;
5589 Lisp_Object cur_object;
5590
5591 /* If write_queue is empty, ignore it. */
5592 if (!write_queue_pop (p, &cur_object, &cur_buf, &cur_len))
5593 {
5594 cur_len = len;
5595 cur_buf = buf;
5596 cur_object = object;
5597 }
5513 5598
5514 /* Send this batch, using one or more write calls. */ 5599 while (cur_len > 0)
5515 while (this > 0)
5516 { 5600 {
5601 /* Send this batch, using one or more write calls. */
5517 ptrdiff_t written = 0; 5602 ptrdiff_t written = 0;
5518 int outfd = p->outfd; 5603 int outfd = p->outfd;
5519 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); 5604 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap);
5520#ifdef DATAGRAM_SOCKETS 5605#ifdef DATAGRAM_SOCKETS
5521 if (DATAGRAM_CHAN_P (outfd)) 5606 if (DATAGRAM_CHAN_P (outfd))
5522 { 5607 {
5523 rv = sendto (outfd, buf, this, 5608 rv = sendto (outfd, cur_buf, cur_len,
5524 0, datagram_address[outfd].sa, 5609 0, datagram_address[outfd].sa,
5525 datagram_address[outfd].len); 5610 datagram_address[outfd].len);
5526 if (0 <= rv) 5611 if (0 <= rv)
@@ -5537,10 +5622,10 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5537 { 5622 {
5538#ifdef HAVE_GNUTLS 5623#ifdef HAVE_GNUTLS
5539 if (p->gnutls_p) 5624 if (p->gnutls_p)
5540 written = emacs_gnutls_write (p, buf, this); 5625 written = emacs_gnutls_write (p, cur_buf, cur_len);
5541 else 5626 else
5542#endif 5627#endif
5543 written = emacs_write (outfd, buf, this); 5628 written = emacs_write (outfd, cur_buf, cur_len);
5544 rv = (written ? 0 : -1); 5629 rv = (written ? 0 : -1);
5545#ifdef ADAPTIVE_READ_BUFFERING 5630#ifdef ADAPTIVE_READ_BUFFERING
5546 if (p->read_output_delay > 0 5631 if (p->read_output_delay > 0
@@ -5568,8 +5653,6 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5568 that may allow the program 5653 that may allow the program
5569 to finish doing output and read more. */ 5654 to finish doing output and read more. */
5570 { 5655 {
5571 ptrdiff_t offset = 0;
5572
5573#ifdef BROKEN_PTY_READ_AFTER_EAGAIN 5656#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
5574 /* A gross hack to work around a bug in FreeBSD. 5657 /* A gross hack to work around a bug in FreeBSD.
5575 In the following sequence, read(2) returns 5658 In the following sequence, read(2) returns
@@ -5595,35 +5678,25 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5595 } 5678 }
5596#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ 5679#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
5597 5680
5598 /* Running filters might relocate buffers or strings. 5681 /* Put what we should have written in wait_queue. */
5599 Arrange to relocate BUF. */ 5682 write_queue_push (p, cur_object, cur_buf, cur_len, 1);
5600 if (BUFFERP (object))
5601 offset = BUF_PTR_BYTE_POS (XBUFFER (object),
5602 (unsigned char *) buf);
5603 else if (STRINGP (object))
5604 offset = buf - SSDATA (object);
5605
5606#ifdef EMACS_HAS_USECS 5683#ifdef EMACS_HAS_USECS
5607 wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0); 5684 wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0);
5608#else 5685#else
5609 wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0); 5686 wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0);
5610#endif 5687#endif
5611 5688 /* Reread queue, to see what is left. */
5612 if (BUFFERP (object)) 5689 break;
5613 buf = (char *) BUF_BYTE_ADDRESS (XBUFFER (object),
5614 offset);
5615 else if (STRINGP (object))
5616 buf = offset + SSDATA (object);
5617 } 5690 }
5618 else 5691 else
5619 /* This is a real error. */ 5692 /* This is a real error. */
5620 report_file_error ("writing to process", Fcons (proc, Qnil)); 5693 report_file_error ("writing to process", Fcons (proc, Qnil));
5621 } 5694 }
5622 buf += written; 5695 cur_buf += written;
5623 len -= written; 5696 cur_len -= written;
5624 this -= written;
5625 } 5697 }
5626 } 5698 }
5699 while (!NILP (p->write_queue));
5627 } 5700 }
5628 else 5701 else
5629 { 5702 {
@@ -5636,8 +5709,6 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5636 deactivate_process (proc); 5709 deactivate_process (proc);
5637 error ("SIGPIPE raised on process %s; closed it", SDATA (p->name)); 5710 error ("SIGPIPE raised on process %s; closed it", SDATA (p->name));
5638 } 5711 }
5639
5640 UNGCPRO;
5641} 5712}
5642 5713
5643DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region, 5714DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,
diff --git a/src/process.h b/src/process.h
index edb937893b0..ae4b6b61c94 100644
--- a/src/process.h
+++ b/src/process.h
@@ -77,6 +77,8 @@ struct Lisp_Process
77 Lisp_Object encode_coding_system; 77 Lisp_Object encode_coding_system;
78 /* Working buffer for encoding. */ 78 /* Working buffer for encoding. */
79 Lisp_Object encoding_buf; 79 Lisp_Object encoding_buf;
80 /* Queue for storing waiting writes */
81 Lisp_Object write_queue;
80 82
81#ifdef HAVE_GNUTLS 83#ifdef HAVE_GNUTLS
82 Lisp_Object gnutls_cred_type; 84 Lisp_Object gnutls_cred_type;
diff --git a/src/regex.c b/src/regex.c
index 0dd3a187898..7ef53c606c9 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -130,13 +130,13 @@
130 130
131# include <setjmp.h> 131# include <setjmp.h>
132# include "lisp.h" 132# include "lisp.h"
133# include "character.h"
133# include "buffer.h" 134# include "buffer.h"
134 135
135/* Make syntax table lookup grant data in gl_state. */ 136/* Make syntax table lookup grant data in gl_state. */
136# define SYNTAX_ENTRY_VIA_PROPERTY 137# define SYNTAX_ENTRY_VIA_PROPERTY
137 138
138# include "syntax.h" 139# include "syntax.h"
139# include "character.h"
140# include "category.h" 140# include "category.h"
141 141
142# ifdef malloc 142# ifdef malloc
diff --git a/src/region-cache.c b/src/region-cache.c
index 9f4e5921877..2642e824680 100644
--- a/src/region-cache.c
+++ b/src/region-cache.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include <setjmp.h> 24#include <setjmp.h>
25 25
26#include "lisp.h" 26#include "lisp.h"
27#include "character.h"
27#include "buffer.h" 28#include "buffer.h"
28#include "region-cache.h" 29#include "region-cache.h"
29 30
diff --git a/src/s/bsd-common.h b/src/s/bsd-common.h
index ce67dd7b9af..98391740653 100644
--- a/src/s/bsd-common.h
+++ b/src/s/bsd-common.h
@@ -23,9 +23,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 23
24/* We give these symbols the numeric values found in <sys/param.h> to 24/* We give these symbols the numeric values found in <sys/param.h> to
25 avoid warnings about redefined macros. */ 25 avoid warnings about redefined macros. */
26#ifndef BSD4_3 26
27#define BSD4_3 1 27/* Nothing in Emacs uses this any more.
28#endif /* BSD4_3 */ 28 ifndef BSD4_3
29 define BSD4_3 1
30 endif
31*/
29 32
30#ifndef BSD_SYSTEM 33#ifndef BSD_SYSTEM
31#define BSD_SYSTEM 43 34#define BSD_SYSTEM 43
diff --git a/src/s/template.h b/src/s/template.h
index d8f811dc8aa..e3557aa191b 100644
--- a/src/s/template.h
+++ b/src/s/template.h
@@ -27,7 +27,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
27/* #define USG */ 27/* #define USG */
28/* #define HPUX */ 28/* #define HPUX */
29/* #define BSD4_2 */ 29/* #define BSD4_2 */
30/* #define BSD4_3 */
31/* #define BSD_SYSTEM */ 30/* #define BSD_SYSTEM */
32 31
33/* Emacs can read input using SIGIO and buffering characters itself, 32/* Emacs can read input using SIGIO and buffering characters itself,
diff --git a/src/s/usg5-4-common.h b/src/s/usg5-4-common.h
index 1502228c0d8..2676e9e5943 100644
--- a/src/s/usg5-4-common.h
+++ b/src/s/usg5-4-common.h
@@ -24,7 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#define USG /* System III, System V, etc */ 24#define USG /* System III, System V, etc */
25 25
26#define USG5 26#define USG5
27#define USG5_4 27/* Nothing in Emacs use this any more. */
28/* #define USG5_4 */
28 29
29/* setjmp and longjmp can safely replace _setjmp and _longjmp, 30/* setjmp and longjmp can safely replace _setjmp and _longjmp,
30 but they will run slower. */ 31 but they will run slower. */
diff --git a/src/search.c b/src/search.c
index 99519b839ef..71ab60d9f85 100644
--- a/src/search.c
+++ b/src/search.c
@@ -24,8 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include "lisp.h" 24#include "lisp.h"
25#include "syntax.h" 25#include "syntax.h"
26#include "category.h" 26#include "category.h"
27#include "buffer.h"
28#include "character.h" 27#include "character.h"
28#include "buffer.h"
29#include "charset.h" 29#include "charset.h"
30#include "region-cache.h" 30#include "region-cache.h"
31#include "commands.h" 31#include "commands.h"
diff --git a/src/syntax.c b/src/syntax.c
index 71da13e7a66..0518a47f92d 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -25,8 +25,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25#include <setjmp.h> 25#include <setjmp.h>
26#include "lisp.h" 26#include "lisp.h"
27#include "commands.h" 27#include "commands.h"
28#include "buffer.h"
29#include "character.h" 28#include "character.h"
29#include "buffer.h"
30#include "keymap.h" 30#include "keymap.h"
31#include "regex.h" 31#include "regex.h"
32 32
diff --git a/src/term.c b/src/term.c
index 8ce2efc0929..3a41552c02e 100644
--- a/src/term.c
+++ b/src/term.c
@@ -32,8 +32,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "termchar.h" 32#include "termchar.h"
33#include "termopts.h" 33#include "termopts.h"
34#include "tparam.h" 34#include "tparam.h"
35#include "buffer.h"
36#include "character.h" 35#include "character.h"
36#include "buffer.h"
37#include "charset.h" 37#include "charset.h"
38#include "coding.h" 38#include "coding.h"
39#include "composite.h" 39#include "composite.h"
diff --git a/src/textprop.c b/src/textprop.c
index 83d07c56f28..afeb0339d5c 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20#include <setjmp.h> 20#include <setjmp.h>
21#include "lisp.h" 21#include "lisp.h"
22#include "intervals.h" 22#include "intervals.h"
23#include "character.h"
23#include "buffer.h" 24#include "buffer.h"
24#include "window.h" 25#include "window.h"
25 26
diff --git a/src/undo.c b/src/undo.c
index 9b763984d7f..1cb048690ba 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20#include <config.h> 20#include <config.h>
21#include <setjmp.h> 21#include <setjmp.h>
22#include "lisp.h" 22#include "lisp.h"
23#include "character.h"
23#include "buffer.h" 24#include "buffer.h"
24#include "commands.h" 25#include "commands.h"
25#include "window.h" 26#include "window.h"
diff --git a/src/unexsol.c b/src/unexsol.c
index ef1e34e6f0f..336f3b4faea 100644
--- a/src/unexsol.c
+++ b/src/unexsol.c
@@ -7,6 +7,7 @@
7#include <setjmp.h> 7#include <setjmp.h>
8 8
9#include "lisp.h" 9#include "lisp.h"
10#include "character.h"
10#include "buffer.h" 11#include "buffer.h"
11#include "charset.h" 12#include "charset.h"
12#include "coding.h" 13#include "coding.h"
diff --git a/src/w16select.c b/src/w16select.c
index 03f63bedf0d..270118358b4 100644
--- a/src/w16select.c
+++ b/src/w16select.c
@@ -36,8 +36,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
36#include "dispextern.h" /* frame.h seems to want this */ 36#include "dispextern.h" /* frame.h seems to want this */
37#include "frame.h" /* Need this to get the X window of selected_frame */ 37#include "frame.h" /* Need this to get the X window of selected_frame */
38#include "blockinput.h" 38#include "blockinput.h"
39#include "buffer.h"
40#include "character.h" 39#include "character.h"
40#include "buffer.h"
41#include "coding.h" 41#include "coding.h"
42#include "composite.h" 42#include "composite.h"
43 43
diff --git a/src/w32fns.c b/src/w32fns.c
index a8becea1b74..915114138d8 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -32,13 +32,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "w32term.h" 32#include "w32term.h"
33#include "frame.h" 33#include "frame.h"
34#include "window.h" 34#include "window.h"
35#include "character.h"
35#include "buffer.h" 36#include "buffer.h"
36#include "intervals.h" 37#include "intervals.h"
37#include "dispextern.h" 38#include "dispextern.h"
38#include "keyboard.h" 39#include "keyboard.h"
39#include "blockinput.h" 40#include "blockinput.h"
40#include "epaths.h" 41#include "epaths.h"
41#include "character.h"
42#include "charset.h" 42#include "charset.h"
43#include "coding.h" 43#include "coding.h"
44#include "ccl.h" 44#include "ccl.h"
diff --git a/src/w32menu.c b/src/w32menu.c
index f5f5c6656c4..b957da67567 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31#include "termhooks.h" 31#include "termhooks.h"
32#include "window.h" 32#include "window.h"
33#include "blockinput.h" 33#include "blockinput.h"
34#include "character.h"
34#include "buffer.h" 35#include "buffer.h"
35#include "charset.h" 36#include "charset.h"
36#include "coding.h" 37#include "coding.h"
diff --git a/src/w32term.c b/src/w32term.c
index 38120b77ac9..6a4b3ca4afb 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -313,6 +313,94 @@ w32_set_clip_rectangle (HDC hdc, RECT *rect)
313 SelectClipRgn (hdc, NULL); 313 SelectClipRgn (hdc, NULL);
314} 314}
315 315
316/* Restore clipping rectangle in S */
317static void
318w32_restore_glyph_string_clip (struct glyph_string *s)
319{
320 RECT *r = s->clip;
321 int n = s->num_clips;
322
323 if (n == 1)
324 w32_set_clip_rectangle (s->hdc, r);
325 else if (n > 1)
326 {
327 HRGN clip1 = CreateRectRgnIndirect (r);
328 HRGN clip2 = CreateRectRgnIndirect (r + 1);
329 if (CombineRgn (clip1, clip1, clip2, RGN_OR) != ERROR)
330 SelectClipRgn (s->hdc, clip1);
331 DeleteObject (clip1);
332 DeleteObject (clip2);
333 }
334}
335
336/*
337 Draw a wavy line under S. The wave fills wave_height pixels from y0.
338
339 x0 wave_length = 2
340 --
341 y0 * * * * *
342 |* * * * * * * * *
343 wave_height = 3 | * * * *
344
345*/
346
347void
348w32_draw_underwave (struct glyph_string *s, COLORREF color)
349{
350 int wave_height = 2, wave_length = 3;
351 int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
352 XRectangle wave_clip, string_clip, final_clip;
353 RECT w32_final_clip, w32_string_clip;
354 HPEN hp, oldhp;
355
356 dx = wave_length;
357 dy = wave_height - 1;
358 x0 = s->x;
359 y0 = s->ybase + 1;
360 width = s->width;
361 xmax = x0 + width;
362
363 /* Find and set clipping rectangle */
364
365 wave_clip = (XRectangle){ x0, y0, width, wave_height };
366 get_glyph_string_clip_rect (s, &w32_string_clip);
367 CONVERT_TO_XRECT (string_clip, w32_string_clip);
368
369 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
370 return;
371
372 hp = CreatePen (PS_SOLID, 0, color);
373 oldhp = SelectObject (s->hdc, hp);
374 CONVERT_FROM_XRECT (final_clip, w32_final_clip);
375 w32_set_clip_rectangle (s->hdc, &w32_final_clip);
376
377 /* Draw the waves */
378
379 x1 = x0 - (x0 % dx);
380 x2 = x1 + dx;
381 odd = (x1/dx) % 2;
382 y1 = y2 = y0;
383
384 if (odd)
385 y1 += dy;
386 else
387 y2 += dy;
388
389 MoveToEx (s->hdc, x1, y1, NULL);
390
391 while (x1 <= xmax)
392 {
393 LineTo (s->hdc, x2, y2);
394 x1 = x2, y1 = y2;
395 x2 += dx, y2 = y0 + odd*dy;
396 odd = !odd;
397 }
398
399 /* Restore previous pen and clipping rectangle(s) */
400 w32_restore_glyph_string_clip (s);
401 SelectObject (s->hdc, oldhp);
402 DeleteObject (hp);
403}
316 404
317/* Draw a hollow rectangle at the specified position. */ 405/* Draw a hollow rectangle at the specified position. */
318void 406void
@@ -2347,60 +2435,74 @@ x_draw_glyph_string (struct glyph_string *s)
2347 /* Draw underline. */ 2435 /* Draw underline. */
2348 if (s->face->underline_p) 2436 if (s->face->underline_p)
2349 { 2437 {
2350 unsigned long thickness, position; 2438 if (s->face->underline_type == FACE_UNDER_WAVE)
2351 int y;
2352
2353 if (s->prev && s->prev->face->underline_p)
2354 { 2439 {
2355 /* We use the same underline style as the previous one. */ 2440 COLORREF color;
2356 thickness = s->prev->underline_thickness; 2441
2357 position = s->prev->underline_position; 2442 if (s->face->underline_defaulted_p)
2443 color = s->gc->foreground;
2444 else
2445 color = s->face->underline_color;
2446
2447 w32_draw_underwave (s, color);
2358 } 2448 }
2359 else 2449 else if (s->face->underline_type == FACE_UNDER_LINE)
2360 { 2450 {
2361 /* Get the underline thickness. Default is 1 pixel. */ 2451 unsigned long thickness, position;
2362 if (s->font && s->font->underline_thickness > 0) 2452 int y;
2363 thickness = s->font->underline_thickness; 2453
2454 if (s->prev && s->prev->face->underline_p)
2455 {
2456 /* We use the same underline style as the previous one. */
2457 thickness = s->prev->underline_thickness;
2458 position = s->prev->underline_position;
2459 }
2364 else 2460 else
2365 thickness = 1; 2461 {
2366 if (x_underline_at_descent_line) 2462 /* Get the underline thickness. Default is 1 pixel. */
2367 position = (s->height - thickness) - (s->ybase - s->y); 2463 if (s->font && s->font->underline_thickness > 0)
2464 thickness = s->font->underline_thickness;
2465 else
2466 thickness = 1;
2467 if (x_underline_at_descent_line)
2468 position = (s->height - thickness) - (s->ybase - s->y);
2469 else
2470 {
2471 /* Get the underline position. This is the recommended
2472 vertical offset in pixels from the baseline to the top of
2473 the underline. This is a signed value according to the
2474 specs, and its default is
2475
2476 ROUND ((maximum_descent) / 2), with
2477 ROUND (x) = floor (x + 0.5) */
2478
2479 if (x_use_underline_position_properties
2480 && s->font && s->font->underline_position >= 0)
2481 position = s->font->underline_position;
2482 else if (s->font)
2483 position = (s->font->descent + 1) / 2;
2484 }
2485 position = max (position, underline_minimum_offset);
2486 }
2487 /* Check the sanity of thickness and position. We should
2488 avoid drawing underline out of the current line area. */
2489 if (s->y + s->height <= s->ybase + position)
2490 position = (s->height - 1) - (s->ybase - s->y);
2491 if (s->y + s->height < s->ybase + position + thickness)
2492 thickness = (s->y + s->height) - (s->ybase + position);
2493 s->underline_thickness = thickness;
2494 s->underline_position =position;
2495 y = s->ybase + position;
2496 if (s->face->underline_defaulted_p)
2497 {
2498 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2499 y, s->width, 1);
2500 }
2368 else 2501 else
2369 { 2502 {
2370 /* Get the underline position. This is the recommended 2503 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
2371 vertical offset in pixels from the baseline to the top of 2504 y, s->width, 1);
2372 the underline. This is a signed value according to the
2373 specs, and its default is
2374
2375 ROUND ((maximum_descent) / 2), with
2376 ROUND (x) = floor (x + 0.5) */
2377
2378 if (x_use_underline_position_properties
2379 && s->font && s->font->underline_position >= 0)
2380 position = s->font->underline_position;
2381 else if (s->font)
2382 position = (s->font->descent + 1) / 2;
2383 } 2505 }
2384 position = max (position, underline_minimum_offset);
2385 }
2386 /* Check the sanity of thickness and position. We should
2387 avoid drawing underline out of the current line area. */
2388 if (s->y + s->height <= s->ybase + position)
2389 position = (s->height - 1) - (s->ybase - s->y);
2390 if (s->y + s->height < s->ybase + position + thickness)
2391 thickness = (s->y + s->height) - (s->ybase + position);
2392 s->underline_thickness = thickness;
2393 s->underline_position =position;
2394 y = s->ybase + position;
2395 if (s->face->underline_defaulted_p)
2396 {
2397 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2398 y, s->width, 1);
2399 }
2400 else
2401 {
2402 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
2403 y, s->width, 1);
2404 } 2506 }
2405 } 2507 }
2406 /* Draw overline. */ 2508 /* Draw overline. */
diff --git a/src/window.c b/src/window.c
index 2a498c43d80..f1b19390cd0 100644
--- a/src/window.c
+++ b/src/window.c
@@ -23,6 +23,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23#include <setjmp.h> 23#include <setjmp.h>
24 24
25#include "lisp.h" 25#include "lisp.h"
26#include "character.h"
26#include "buffer.h" 27#include "buffer.h"
27#include "keyboard.h" 28#include "keyboard.h"
28#include "keymap.h" 29#include "keymap.h"
@@ -2568,7 +2569,6 @@ window-start value is reasonable when this function is called. */)
2568 Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta; 2569 Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
2569 ptrdiff_t startpos IF_LINT (= 0); 2570 ptrdiff_t startpos IF_LINT (= 0);
2570 int top IF_LINT (= 0), new_top, resize_failed; 2571 int top IF_LINT (= 0), new_top, resize_failed;
2571 Mouse_HLInfo *hlinfo;
2572 2572
2573 w = decode_any_window (window); 2573 w = decode_any_window (window);
2574 XSETWINDOW (window, w); 2574 XSETWINDOW (window, w);
@@ -2649,19 +2649,23 @@ window-start value is reasonable when this function is called. */)
2649 } 2649 }
2650 2650
2651 BLOCK_INPUT; 2651 BLOCK_INPUT;
2652 hlinfo = MOUSE_HL_INFO (f); 2652 if (!FRAME_INITIAL_P (f))
2653 /* We are going to free the glyph matrices of WINDOW, and with that
2654 we might lose any information about glyph rows that have some of
2655 their glyphs highlighted in mouse face. (These rows are marked
2656 with a non-zero mouse_face_p flag.) If WINDOW indeed has some
2657 glyphs highlighted in mouse face, signal to frame's up-to-date
2658 hook that mouse highlight was overwritten, so that it will
2659 arrange for redisplaying the highlight. */
2660 if (EQ (hlinfo->mouse_face_window, window))
2661 { 2653 {
2662 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; 2654 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
2663 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; 2655
2664 hlinfo->mouse_face_window = Qnil; 2656 /* We are going to free the glyph matrices of WINDOW, and with
2657 that we might lose any information about glyph rows that have
2658 some of their glyphs highlighted in mouse face. (These rows
2659 are marked with a non-zero mouse_face_p flag.) If WINDOW
2660 indeed has some glyphs highlighted in mouse face, signal to
2661 frame's up-to-date hook that mouse highlight was overwritten,
2662 so that it will arrange for redisplaying the highlight. */
2663 if (EQ (hlinfo->mouse_face_window, window))
2664 {
2665 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
2666 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
2667 hlinfo->mouse_face_window = Qnil;
2668 }
2665 } 2669 }
2666 free_window_matrices (r); 2670 free_window_matrices (r);
2667 2671
@@ -3905,7 +3909,6 @@ Signal an error when WINDOW is the only window on its frame. */)
3905 && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines))) 3909 && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
3906 /* We can delete WINDOW now. */ 3910 /* We can delete WINDOW now. */
3907 { 3911 {
3908 Mouse_HLInfo *hlinfo;
3909 3912
3910 /* Block input. */ 3913 /* Block input. */
3911 BLOCK_INPUT; 3914 BLOCK_INPUT;
@@ -3916,9 +3919,13 @@ Signal an error when WINDOW is the only window on its frame. */)
3916 3919
3917 /* If this window is referred to by the dpyinfo's mouse 3920 /* If this window is referred to by the dpyinfo's mouse
3918 highlight, invalidate that slot to be safe (Bug#9904). */ 3921 highlight, invalidate that slot to be safe (Bug#9904). */
3919 hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); 3922 if (!FRAME_INITIAL_P (f))
3920 if (EQ (hlinfo->mouse_face_window, window)) 3923 {
3921 hlinfo->mouse_face_window = Qnil; 3924 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
3925
3926 if (EQ (hlinfo->mouse_face_window, window))
3927 hlinfo->mouse_face_window = Qnil;
3928 }
3922 3929
3923 windows_or_buffers_changed++; 3930 windows_or_buffers_changed++;
3924 Vwindow_list = Qnil; 3931 Vwindow_list = Qnil;
diff --git a/src/xdisp.c b/src/xdisp.c
index 39059acdb85..1353b4e1184 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -281,8 +281,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
281#include "window.h" 281#include "window.h"
282#include "termchar.h" 282#include "termchar.h"
283#include "dispextern.h" 283#include "dispextern.h"
284#include "buffer.h"
285#include "character.h" 284#include "character.h"
285#include "buffer.h"
286#include "charset.h" 286#include "charset.h"
287#include "indent.h" 287#include "indent.h"
288#include "commands.h" 288#include "commands.h"
@@ -3696,7 +3696,8 @@ handle_face_prop (struct it *it)
3696 int i; 3696 int i;
3697 Lisp_Object from_overlay 3697 Lisp_Object from_overlay
3698 = (it->current.overlay_string_index >= 0 3698 = (it->current.overlay_string_index >= 0
3699 ? it->string_overlays[it->current.overlay_string_index] 3699 ? it->string_overlays[it->current.overlay_string_index
3700 % OVERLAY_STRING_CHUNK_SIZE]
3700 : Qnil); 3701 : Qnil);
3701 3702
3702 /* See if we got to this string directly or indirectly from 3703 /* See if we got to this string directly or indirectly from
@@ -3710,7 +3711,8 @@ handle_face_prop (struct it *it)
3710 { 3711 {
3711 if (it->stack[i].current.overlay_string_index >= 0) 3712 if (it->stack[i].current.overlay_string_index >= 0)
3712 from_overlay 3713 from_overlay
3713 = it->string_overlays[it->stack[i].current.overlay_string_index]; 3714 = it->string_overlays[it->stack[i].current.overlay_string_index
3715 % OVERLAY_STRING_CHUNK_SIZE];
3714 else if (! NILP (it->stack[i].from_overlay)) 3716 else if (! NILP (it->stack[i].from_overlay))
3715 from_overlay = it->stack[i].from_overlay; 3717 from_overlay = it->stack[i].from_overlay;
3716 3718
@@ -13376,6 +13378,12 @@ redisplay_internal (void)
13376 { 13378 {
13377 struct frame *f = XFRAME (frame); 13379 struct frame *f = XFRAME (frame);
13378 13380
13381 /* We don't have to do anything for unselected terminal
13382 frames. */
13383 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13384 && !EQ (FRAME_TTY (f)->top_frame, frame))
13385 continue;
13386
13379 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) 13387 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13380 { 13388 {
13381 if (! EQ (frame, selected_frame)) 13389 if (! EQ (frame, selected_frame))
@@ -13996,16 +14004,13 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
13996 break; 14004 break;
13997 } 14005 }
13998 /* See if we've found a better approximation to 14006 /* See if we've found a better approximation to
13999 POS_BEFORE or to POS_AFTER. Note that we want the 14007 POS_BEFORE or to POS_AFTER. */
14000 first (leftmost) glyph of all those that are the
14001 closest from below, and the last (rightmost) of all
14002 those from above. */
14003 if (0 > dpos && dpos > pos_before - pt_old) 14008 if (0 > dpos && dpos > pos_before - pt_old)
14004 { 14009 {
14005 pos_before = glyph->charpos; 14010 pos_before = glyph->charpos;
14006 glyph_before = glyph; 14011 glyph_before = glyph;
14007 } 14012 }
14008 else if (0 < dpos && dpos <= pos_after - pt_old) 14013 else if (0 < dpos && dpos < pos_after - pt_old)
14009 { 14014 {
14010 pos_after = glyph->charpos; 14015 pos_after = glyph->charpos;
14011 glyph_after = glyph; 14016 glyph_after = glyph;
@@ -14089,7 +14094,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
14089 pos_before = glyph->charpos; 14094 pos_before = glyph->charpos;
14090 glyph_before = glyph; 14095 glyph_before = glyph;
14091 } 14096 }
14092 else if (0 < dpos && dpos <= pos_after - pt_old) 14097 else if (0 < dpos && dpos < pos_after - pt_old)
14093 { 14098 {
14094 pos_after = glyph->charpos; 14099 pos_after = glyph->charpos;
14095 glyph_after = glyph; 14100 glyph_after = glyph;
@@ -14321,6 +14326,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
14321 the cursor is not on this line. */ 14326 the cursor is not on this line. */
14322 if (cursor == NULL 14327 if (cursor == NULL
14323 && (row->reversed_p ? glyph <= end : glyph >= end) 14328 && (row->reversed_p ? glyph <= end : glyph >= end)
14329 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14324 && STRINGP (end->object) 14330 && STRINGP (end->object)
14325 && row->continued_p) 14331 && row->continued_p)
14326 return 0; 14332 return 0;
@@ -14350,6 +14356,21 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
14350 compute_x: 14356 compute_x:
14351 if (cursor != NULL) 14357 if (cursor != NULL)
14352 glyph = cursor; 14358 glyph = cursor;
14359 else if (glyph == glyphs_end
14360 && pos_before == pos_after
14361 && STRINGP ((row->reversed_p
14362 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14363 : row->glyphs[TEXT_AREA])->object))
14364 {
14365 /* If all the glyphs of this row came from strings, put the
14366 cursor on the first glyph of the row. This avoids having the
14367 cursor outside of the text area in this very rare and hard
14368 use case. */
14369 glyph =
14370 row->reversed_p
14371 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14372 : row->glyphs[TEXT_AREA];
14373 }
14353 if (x < 0) 14374 if (x < 0)
14354 { 14375 {
14355 struct glyph *g; 14376 struct glyph *g;
diff --git a/src/xfaces.c b/src/xfaces.c
index 772d2646291..32d1499b85a 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -320,6 +320,7 @@ static Lisp_Object QCfontset;
320 320
321Lisp_Object Qnormal; 321Lisp_Object Qnormal;
322Lisp_Object Qbold; 322Lisp_Object Qbold;
323static Lisp_Object Qline, Qwave;
323static Lisp_Object Qultra_light, Qextra_light, Qlight; 324static Lisp_Object Qultra_light, Qextra_light, Qlight;
324static Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold; 325static Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
325static Lisp_Object Qoblique, Qreverse_oblique, Qreverse_italic; 326static Lisp_Object Qoblique, Qreverse_oblique, Qreverse_italic;
@@ -1894,7 +1895,8 @@ check_lface_attrs (Lisp_Object *attrs)
1894 xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX]) 1895 xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
1895 || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX]) 1896 || IGNORE_DEFFACE_P (attrs[LFACE_UNDERLINE_INDEX])
1896 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX]) 1897 || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
1897 || STRINGP (attrs[LFACE_UNDERLINE_INDEX])); 1898 || STRINGP (attrs[LFACE_UNDERLINE_INDEX])
1899 || CONSP (attrs[LFACE_UNDERLINE_INDEX]));
1898 xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) 1900 xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
1899 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX]) 1901 || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX])
1900 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX]) 1902 || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
@@ -2525,7 +2527,8 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
2525 { 2527 {
2526 if (EQ (value, Qt) 2528 if (EQ (value, Qt)
2527 || NILP (value) 2529 || NILP (value)
2528 || STRINGP (value)) 2530 || STRINGP (value)
2531 || CONSP (value))
2529 to[LFACE_UNDERLINE_INDEX] = value; 2532 to[LFACE_UNDERLINE_INDEX] = value;
2530 else 2533 else
2531 err = 1; 2534 err = 1;
@@ -2948,15 +2951,54 @@ FRAME 0 means change the face on all frames, and change the default
2948 } 2951 }
2949 else if (EQ (attr, QCunderline)) 2952 else if (EQ (attr, QCunderline))
2950 { 2953 {
2951 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) 2954 int valid_p = 0;
2952 if ((SYMBOLP (value) 2955
2953 && !EQ (value, Qt) 2956 if (UNSPECIFIEDP (value) || IGNORE_DEFFACE_P (value))
2954 && !EQ (value, Qnil)) 2957 valid_p = 1;
2955 /* Underline color. */ 2958 else if (NILP (value) || EQ (value, Qt))
2956 || (STRINGP (value) 2959 valid_p = 1;
2957 && SCHARS (value) == 0)) 2960 else if (STRINGP (value) && SCHARS (value) > 0)
2958 signal_error ("Invalid face underline", value); 2961 valid_p = 1;
2959 2962 else if (CONSP (value))
2963 {
2964 Lisp_Object key, val, list;
2965
2966 list = value;
2967 valid_p = 1;
2968
2969 while (!NILP (CAR_SAFE(list)))
2970 {
2971 key = CAR_SAFE (list);
2972 list = CDR_SAFE (list);
2973 val = CAR_SAFE (list);
2974 list = CDR_SAFE (list);
2975
2976 if(NILP (key) || NILP (val))
2977 {
2978 valid_p = 0;
2979 break;
2980 }
2981
2982 else if (EQ (key, QCcolor)
2983 && !(EQ (val, Qforeground_color)
2984 || (STRINGP (val) && SCHARS (val) > 0)))
2985 {
2986 valid_p = 0;
2987 break;
2988 }
2989
2990 else if (EQ (key, QCstyle)
2991 && !(EQ (val, Qline) || EQ (val, Qwave)))
2992 {
2993 valid_p = 0;
2994 break;
2995 }
2996 }
2997 }
2998
2999 if (!valid_p)
3000 signal_error ("Invalid face underline", value);
3001
2960 old_value = LFACE_UNDERLINE (lface); 3002 old_value = LFACE_UNDERLINE (lface);
2961 LFACE_UNDERLINE (lface) = value; 3003 LFACE_UNDERLINE (lface) = value;
2962 } 3004 }
@@ -5576,7 +5618,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
5576#ifdef HAVE_WINDOW_SYSTEM 5618#ifdef HAVE_WINDOW_SYSTEM
5577 struct face *default_face; 5619 struct face *default_face;
5578 struct frame *f; 5620 struct frame *f;
5579 Lisp_Object stipple, overline, strike_through, box; 5621 Lisp_Object stipple, underline, overline, strike_through, box;
5580 5622
5581 xassert (FRAME_WINDOW_P (cache->f)); 5623 xassert (FRAME_WINDOW_P (cache->f));
5582 5624
@@ -5709,29 +5751,76 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
5709 5751
5710 /* Text underline, overline, strike-through. */ 5752 /* Text underline, overline, strike-through. */
5711 5753
5712 if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt)) 5754 underline = attrs[LFACE_UNDERLINE_INDEX];
5755 if (EQ (underline, Qt))
5713 { 5756 {
5714 /* Use default color (same as foreground color). */ 5757 /* Use default color (same as foreground color). */
5715 face->underline_p = 1; 5758 face->underline_p = 1;
5759 face->underline_type = FACE_UNDER_LINE;
5716 face->underline_defaulted_p = 1; 5760 face->underline_defaulted_p = 1;
5717 face->underline_color = 0; 5761 face->underline_color = 0;
5718 } 5762 }
5719 else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX])) 5763 else if (STRINGP (underline))
5720 { 5764 {
5721 /* Use specified color. */ 5765 /* Use specified color. */
5722 face->underline_p = 1; 5766 face->underline_p = 1;
5767 face->underline_type = FACE_UNDER_LINE;
5723 face->underline_defaulted_p = 0; 5768 face->underline_defaulted_p = 0;
5724 face->underline_color 5769 face->underline_color
5725 = load_color (f, face, attrs[LFACE_UNDERLINE_INDEX], 5770 = load_color (f, face, underline,
5726 LFACE_UNDERLINE_INDEX); 5771 LFACE_UNDERLINE_INDEX);
5727 } 5772 }
5728 else if (NILP (attrs[LFACE_UNDERLINE_INDEX])) 5773 else if (NILP (underline))
5729 { 5774 {
5730 face->underline_p = 0; 5775 face->underline_p = 0;
5731 face->underline_defaulted_p = 0; 5776 face->underline_defaulted_p = 0;
5732 face->underline_color = 0; 5777 face->underline_color = 0;
5733 } 5778 }
5734 5779 else if (CONSP (underline))
5780 {
5781 /* `(:color COLOR :style STYLE)'.
5782 STYLE being one of `line' or `wave'. */
5783 face->underline_p = 1;
5784 face->underline_color = 0;
5785 face->underline_defaulted_p = 1;
5786 face->underline_type = FACE_UNDER_LINE;
5787
5788 while (CONSP (underline))
5789 {
5790 Lisp_Object keyword, value;
5791
5792 keyword = XCAR (underline);
5793 underline = XCDR (underline);
5794
5795 if (!CONSP (underline))
5796 break;
5797 value = XCAR (underline);
5798 underline = XCDR (underline);
5799
5800 if (EQ (keyword, QCcolor))
5801 {
5802 if (EQ (value, Qforeground_color))
5803 {
5804 face->underline_defaulted_p = 1;
5805 face->underline_color = 0;
5806 }
5807 else if (STRINGP (value))
5808 {
5809 face->underline_defaulted_p = 0;
5810 face->underline_color = load_color (f, face, value,
5811 LFACE_UNDERLINE_INDEX);
5812 }
5813 }
5814 else if (EQ (keyword, QCstyle))
5815 {
5816 if (EQ (value, Qline))
5817 face->underline_type = FACE_UNDER_LINE;
5818 else if (EQ (value, Qwave))
5819 face->underline_type = FACE_UNDER_WAVE;
5820 }
5821 }
5822 }
5823
5735 overline = attrs[LFACE_OVERLINE_INDEX]; 5824 overline = attrs[LFACE_OVERLINE_INDEX];
5736 if (STRINGP (overline)) 5825 if (STRINGP (overline))
5737 { 5826 {
@@ -6476,6 +6565,8 @@ syms_of_xfaces (void)
6476 DEFSYM (QCcolor, ":color"); 6565 DEFSYM (QCcolor, ":color");
6477 DEFSYM (QCline_width, ":line-width"); 6566 DEFSYM (QCline_width, ":line-width");
6478 DEFSYM (QCstyle, ":style"); 6567 DEFSYM (QCstyle, ":style");
6568 DEFSYM (Qline, "line");
6569 DEFSYM (Qwave, "wave");
6479 DEFSYM (Qreleased_button, "released-button"); 6570 DEFSYM (Qreleased_button, "released-button");
6480 DEFSYM (Qpressed_button, "pressed-button"); 6571 DEFSYM (Qpressed_button, "pressed-button");
6481 DEFSYM (Qnormal, "normal"); 6572 DEFSYM (Qnormal, "normal");
diff --git a/src/xfns.c b/src/xfns.c
index 43ccdfaef1a..d49f0ea1458 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -32,13 +32,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "xterm.h" 32#include "xterm.h"
33#include "frame.h" 33#include "frame.h"
34#include "window.h" 34#include "window.h"
35#include "character.h"
35#include "buffer.h" 36#include "buffer.h"
36#include "intervals.h" 37#include "intervals.h"
37#include "dispextern.h" 38#include "dispextern.h"
38#include "keyboard.h" 39#include "keyboard.h"
39#include "blockinput.h" 40#include "blockinput.h"
40#include <epaths.h> 41#include <epaths.h>
41#include "character.h"
42#include "charset.h" 42#include "charset.h"
43#include "coding.h" 43#include "coding.h"
44#include "fontset.h" 44#include "fontset.h"
diff --git a/src/xmenu.c b/src/xmenu.c
index 79ead5f598c..dc98b980278 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -47,6 +47,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
47#include "termhooks.h" 47#include "termhooks.h"
48#include "window.h" 48#include "window.h"
49#include "blockinput.h" 49#include "blockinput.h"
50#include "character.h"
50#include "buffer.h" 51#include "buffer.h"
51#include "charset.h" 52#include "charset.h"
52#include "coding.h" 53#include "coding.h"
diff --git a/src/xml.c b/src/xml.c
index e462a1adf57..7bc6130b8b1 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#include <libxml/HTMLparser.h> 26#include <libxml/HTMLparser.h>
27 27
28#include "lisp.h" 28#include "lisp.h"
29#include "character.h"
29#include "buffer.h" 30#include "buffer.h"
30 31
31 32
diff --git a/src/xselect.c b/src/xselect.c
index 48baeb32581..f1eda5d7c85 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -35,11 +35,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35#include "dispextern.h" /* frame.h seems to want this */ 35#include "dispextern.h" /* frame.h seems to want this */
36#include "frame.h" /* Need this to get the X window of selected_frame */ 36#include "frame.h" /* Need this to get the X window of selected_frame */
37#include "blockinput.h" 37#include "blockinput.h"
38#include "character.h"
38#include "buffer.h" 39#include "buffer.h"
39#include "process.h" 40#include "process.h"
40#include "termhooks.h" 41#include "termhooks.h"
41#include "keyboard.h" 42#include "keyboard.h"
42#include "character.h"
43 43
44#include <X11/Xproto.h> 44#include <X11/Xproto.h>
45 45
diff --git a/src/xterm.c b/src/xterm.c
index 442b6b1b934..17279f2e6ca 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2666,6 +2666,68 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
2666 s->background_filled_p = 1; 2666 s->background_filled_p = 1;
2667} 2667}
2668 2668
2669/*
2670 Draw a wavy line under S. The wave fills wave_height pixels from y0.
2671
2672 x0 wave_length = 2
2673 --
2674 y0 * * * * *
2675 |* * * * * * * * *
2676 wave_height = 3 | * * * *
2677
2678*/
2679
2680static void
2681x_draw_underwave (struct glyph_string *s)
2682{
2683 int wave_height = 2, wave_length = 3;
2684 int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
2685 XRectangle wave_clip, string_clip, final_clip;
2686
2687 dx = wave_length;
2688 dy = wave_height - 1;
2689 x0 = s->x;
2690 y0 = s->ybase + 1;
2691 width = s->width;
2692 xmax = x0 + width;
2693
2694 /* Find and set clipping rectangle */
2695
2696 wave_clip = (XRectangle){ x0, y0, width, wave_height };
2697 get_glyph_string_clip_rect (s, &string_clip);
2698
2699 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
2700 return;
2701
2702 XSetClipRectangles (s->display, s->gc, 0, 0, &final_clip, 1, Unsorted);
2703
2704 /* Draw the waves */
2705
2706 x1 = x0 - (x0 % dx);
2707 x2 = x1 + dx;
2708 odd = (x1/dx) % 2;
2709 y1 = y2 = y0;
2710
2711 if (odd)
2712 y1 += dy;
2713 else
2714 y2 += dy;
2715
2716 if (INT_MAX - dx < xmax)
2717 abort ();
2718
2719 while (x1 <= xmax)
2720 {
2721 XDrawLine (s->display, s->window, s->gc, x1, y1, x2, y2);
2722 x1 = x2, y1 = y2;
2723 x2 += dx, y2 = y0 + odd*dy;
2724 odd = !odd;
2725 }
2726
2727 /* Restore previous clipping rectangle(s) */
2728 XSetClipRectangles (s->display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
2729}
2730
2669 2731
2670/* Draw glyph string S. */ 2732/* Draw glyph string S. */
2671 2733
@@ -2774,68 +2836,83 @@ x_draw_glyph_string (struct glyph_string *s)
2774 { 2836 {
2775 /* Draw underline. */ 2837 /* Draw underline. */
2776 if (s->face->underline_p) 2838 if (s->face->underline_p)
2777 { 2839 {
2778 unsigned long thickness, position; 2840 if (s->face->underline_type == FACE_UNDER_WAVE)
2779 int y; 2841 {
2780 2842 if (s->face->underline_defaulted_p)
2781 if (s->prev && s->prev->face->underline_p) 2843 x_draw_underwave (s);
2782 { 2844 else
2783 /* We use the same underline style as the previous one. */ 2845 {
2784 thickness = s->prev->underline_thickness; 2846 XGCValues xgcv;
2785 position = s->prev->underline_position; 2847 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2786 } 2848 XSetForeground (s->display, s->gc, s->face->underline_color);
2787 else 2849 x_draw_underwave (s);
2788 { 2850 XSetForeground (s->display, s->gc, xgcv.foreground);
2789 /* Get the underline thickness. Default is 1 pixel. */ 2851 }
2790 if (s->font && s->font->underline_thickness > 0) 2852 }
2791 thickness = s->font->underline_thickness; 2853 else if (s->face->underline_type == FACE_UNDER_LINE)
2792 else 2854 {
2793 thickness = 1; 2855 unsigned long thickness, position;
2794 if (x_underline_at_descent_line) 2856 int y;
2795 position = (s->height - thickness) - (s->ybase - s->y);
2796 else
2797 {
2798 /* Get the underline position. This is the recommended
2799 vertical offset in pixels from the baseline to the top of
2800 the underline. This is a signed value according to the
2801 specs, and its default is
2802
2803 ROUND ((maximum descent) / 2), with
2804 ROUND(x) = floor (x + 0.5) */
2805
2806 if (x_use_underline_position_properties
2807 && s->font && s->font->underline_position >= 0)
2808 position = s->font->underline_position;
2809 else if (s->font)
2810 position = (s->font->descent + 1) / 2;
2811 else
2812 position = underline_minimum_offset;
2813 }
2814 position = max (position, underline_minimum_offset);
2815 }
2816 /* Check the sanity of thickness and position. We should
2817 avoid drawing underline out of the current line area. */
2818 if (s->y + s->height <= s->ybase + position)
2819 position = (s->height - 1) - (s->ybase - s->y);
2820 if (s->y + s->height < s->ybase + position + thickness)
2821 thickness = (s->y + s->height) - (s->ybase + position);
2822 s->underline_thickness = thickness;
2823 s->underline_position = position;
2824 y = s->ybase + position;
2825 if (s->face->underline_defaulted_p)
2826 XFillRectangle (s->display, s->window, s->gc,
2827 s->x, y, s->width, thickness);
2828 else
2829 {
2830 XGCValues xgcv;
2831 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2832 XSetForeground (s->display, s->gc, s->face->underline_color);
2833 XFillRectangle (s->display, s->window, s->gc,
2834 s->x, y, s->width, thickness);
2835 XSetForeground (s->display, s->gc, xgcv.foreground);
2836 }
2837 }
2838 2857
2858 if (s->prev && s->prev->face->underline_p)
2859 {
2860 /* We use the same underline style as the previous one. */
2861 thickness = s->prev->underline_thickness;
2862 position = s->prev->underline_position;
2863 }
2864 else
2865 {
2866 /* Get the underline thickness. Default is 1 pixel. */
2867 if (s->font && s->font->underline_thickness > 0)
2868 thickness = s->font->underline_thickness;
2869 else
2870 thickness = 1;
2871 if (x_underline_at_descent_line)
2872 position = (s->height - thickness) - (s->ybase - s->y);
2873 else
2874 {
2875 /* Get the underline position. This is the recommended
2876 vertical offset in pixels from the baseline to the top of
2877 the underline. This is a signed value according to the
2878 specs, and its default is
2879
2880 ROUND ((maximum descent) / 2), with
2881 ROUND(x) = floor (x + 0.5) */
2882
2883 if (x_use_underline_position_properties
2884 && s->font && s->font->underline_position >= 0)
2885 position = s->font->underline_position;
2886 else if (s->font)
2887 position = (s->font->descent + 1) / 2;
2888 else
2889 position = underline_minimum_offset;
2890 }
2891 position = max (position, underline_minimum_offset);
2892 }
2893 /* Check the sanity of thickness and position. We should
2894 avoid drawing underline out of the current line area. */
2895 if (s->y + s->height <= s->ybase + position)
2896 position = (s->height - 1) - (s->ybase - s->y);
2897 if (s->y + s->height < s->ybase + position + thickness)
2898 thickness = (s->y + s->height) - (s->ybase + position);
2899 s->underline_thickness = thickness;
2900 s->underline_position = position;
2901 y = s->ybase + position;
2902 if (s->face->underline_defaulted_p)
2903 XFillRectangle (s->display, s->window, s->gc,
2904 s->x, y, s->width, thickness);
2905 else
2906 {
2907 XGCValues xgcv;
2908 XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
2909 XSetForeground (s->display, s->gc, s->face->underline_color);
2910 XFillRectangle (s->display, s->window, s->gc,
2911 s->x, y, s->width, thickness);
2912 XSetForeground (s->display, s->gc, xgcv.foreground);
2913 }
2914 }
2915 }
2839 /* Draw overline. */ 2916 /* Draw overline. */
2840 if (s->face->overline_p) 2917 if (s->face->overline_p)
2841 { 2918 {