aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Tromey2013-01-16 11:48:32 -0700
committerTom Tromey2013-01-16 11:48:32 -0700
commit6f4de085f065e11f4df3195d47479f28f5ef08ba (patch)
tree1211a00f1afc86c2b73624897993db02a4852943 /src
parente078a23febca14bc919c5806670479c395e3253e (diff)
parentffe04adc88e546c406f9b050238fb98a7243c7a0 (diff)
downloademacs-6f4de085f065e11f4df3195d47479f28f5ef08ba.tar.gz
emacs-6f4de085f065e11f4df3195d47479f28f5ef08ba.zip
merge from trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog258
-rw-r--r--src/alloc.c117
-rw-r--r--src/buffer.c104
-rw-r--r--src/buffer.h11
-rw-r--r--src/coding.c9
-rw-r--r--src/data.c10
-rw-r--r--src/dired.c2
-rw-r--r--src/editfns.c61
-rw-r--r--src/emacs.c19
-rw-r--r--src/eval.c3
-rw-r--r--src/fileio.c39
-rw-r--r--src/font.c2
-rw-r--r--src/ftfont.c22
-rw-r--r--src/gtkutil.c23
-rw-r--r--src/indent.c4
-rw-r--r--src/insdel.c45
-rw-r--r--src/keyboard.c152
-rw-r--r--src/keymap.c16
-rw-r--r--src/lisp.h74
-rw-r--r--src/lread.c2
-rw-r--r--src/nsfns.m8
-rw-r--r--src/nsfont.m35
-rw-r--r--src/nsmenu.m3
-rw-r--r--src/nsterm.h4
-rw-r--r--src/nsterm.m2
-rw-r--r--src/print.c73
-rw-r--r--src/sysdep.c45
-rw-r--r--src/term.c31
-rw-r--r--src/undo.c212
-rw-r--r--src/w32.c2
-rw-r--r--src/w32term.c2
-rw-r--r--src/window.c5
-rw-r--r--src/xfaces.c2
-rw-r--r--src/xfns.c3
-rw-r--r--src/xmenu.c20
-rw-r--r--src/xml.c17
-rw-r--r--src/xselect.c2
-rw-r--r--src/xterm.c43
38 files changed, 833 insertions, 649 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c0c85c15ee9..115b8d42915 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,9 +1,249 @@
12013-01-15 Paul Eggert <eggert@cs.ucla.edu>
2
3 * alloc.c (free_save_value): Now static.
4
52013-01-15 Dmitry Antipov <dmantipov@yandex.ru>
6
7 * keymap.c (map_keymap_internal): Use format_save_value.
8 (map_keymap_char_table_item): Adjust accordingly.
9 * fileio.c (non_regular_fd, non_regular_inserted)
10 (non_regular_nbytes): Remove.
11 (Finsert_file_contents): Convert trytry to ptrdiff_t. Use
12 format_save_value to pass parameters to read_non_regular.
13 (read_non_regular): Use XSAVE_ macros to extract parameters.
14 Adjust comment.
15 * xmenu.c (xmenu_show) [!USE_X_TOOLKIT && !USE_GTK]: Use
16 format_save_value.
17 (pop_down_menu) [!USE_X_TOOLKIT && !USE_GTK]: Adjust user.
18
192013-01-15 Dmitry Antipov <dmantipov@yandex.ru>
20
21 * lisp.h (XSAVE_POINTER, XSAVE_INTEGER): Change to allow
22 extraction from any Lisp_Save_Value slot. Add type checking.
23 * alloc.c, dired.c, editfns.c, fileio.c, ftfont.c, gtkutil.c:
24 * keymap.c, lread.c, nsterm.h, nsmenu.c, xfns.c, xmenu.c:
25 * xselect.c: All users changed.
26
272013-01-15 Dmitry Antipov <dmantipov@yandex.ru>
28
29 Some convenient bits to deal with Lisp_Save_Values.
30 * lisp.h (XSAVE_OBJECT): New macro to extract saved objects.
31 (allocate_misc): Remove prototype.
32 (format_save_value): New prototype.
33 * alloc.c (allocate_misc): Revert back to static.
34 (format_save_value): New function to build Lisp_Save_Value
35 object with the specified internal structure.
36 (make_save_value): Reimplement using format_save_value.
37 * editfns.c (save_excursion_save): Use format_save_value.
38 (save_excursion_restore): Use XSAVE_OBJECT.
39
402013-01-14 Paul Eggert <eggert@cs.ucla.edu>
41
42 Avoid needless casts with XSAVE_POINTER.
43 * alloc.c (mark_object) [GC_MARK_STACK]:
44 * dired.c (directory_files_internal_unwind):
45 * fileio.c (do_auto_save_unwind):
46 * gtkutil.c (pop_down_dialog):
47 * keymap.c (map_keymap_char_table_item):
48 * lread.c (load_unwind):
49 * nsmenu.m (pop_down_menu):
50 * print.c (print_object) [GC_MARK_STACK]:
51 * xfns.c (clean_up_file_dialog):
52 * xmenu.c (cleanup_widget_value_tree):
53 Omit casts between XSAVE_POINTER and a pointer type.
54
552013-01-14 Dmitry Antipov <dmantipov@yandex.ru>
56
57 Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE.
58 * eval.c (eval_sub): Protect `form' from being GCed before its
59 car and cdr becomes protected with the backtrace entry.
60
612013-01-14 Dmitry Antipov <dmantipov@yandex.ru>
62
63 Make Lisp_Save_Value more versatile storage for up to four objects.
64 * lisp.h (toplevel): Enumeration to describe types of saved objects.
65 (struct Lisp_Save_Value): New layout. Adjust comments.
66 (XSAVE_POINTER): New macro.
67 (XSAVE_INTEGER): Likewise.
68 (allocate_misc): Add prototype.
69 (free_misc): Likewise.
70 * alloc.c (allocate_misc): Now global.
71 (free_misc): Likewise. Adjust comment.
72 (make_save_value): Use new Lisp_Save_Value layout. Adjust comment.
73 (free_save_value): Likewise.
74 (mark_object): Likewise.
75 * editfns.c (save_excursion_save): Pack everything within
76 Lisp_Save_Value and so avoid xmalloc.
77 (save_excursion_restore): Adjust to match new layout. Use free_misc
78 because we do not allocate extra memory any more. Add eassert.
79 * print.c (print_object): New code to print Lisp_Save_Value. Do not
80 rely on valid_lisp_object_p if !GC_MARK_STACK. Adjust comments.
81 * dired.c, fileio.c, font.c, ftfont.c, gtkutil.c, keymap.c,
82 * lread.c, nsmenu.m, nsterm.h, xfns.c, xmenu.c, xselect.c:
83 Use XSAVE_POINTER and XSAVE_INTEGER where appropriate.
84
852013-01-13 Jan Djärv <jan.h.d@swipnet.se>
86
87 * nsfont.m (LCD_SMOOTHING_MARGIN): New define.
88 (nsfont_draw): Remove disabling of LCD smoothing.
89 (ns_glyph_metrics): Add LCD_SMOOTHING_MARGIN to bearings to fix
90 Bug#11484 with LCD smoothing on.
91
922013-01-13 Paul Eggert <eggert@cs.ucla.edu>
93
94 Fix SIGDANGER handlers, for AIX (Bug#13408).
95 * sysdep.c.c (handle_danger_signal, deliver_danger_signal) [SIGDANGER]:
96 Move handlers here from emacs.c; they were out of place.
97
982013-01-11 Jan Djärv <jan.h.d@swipnet.se>
99
100 * xterm.c (syms_of_xterm): Adjust documentation for
101 scroll-bar-adjust-thumb-portion.
102
1032012-12-31 Adam Sjøgren <asjo@koldfront.dk> (tiny change)
104
105 * xterm.c (scroll-bar-adjust-thumb-portion): New variable to
106 determine whether scroll bar thumb size should be adjusted or
107 not. Use variable for MOTIF.
108
109 * gtkutil.c (scroll-bar-adjust-thumb-portion): Use variable for
110 GTK.
111
1122013-01-13 Jan Djärv <jan.h.d@swipnet.se>
113
114 * nsterm.m (keyDown:): Set processingCompose to NO if an emacs key
115 event is generated.
116 (doCommandBySelector:): Set processingCompose to NO.
117
118 * nsfont.m (ns_findfonts): Add block/unblock_input calls.
119 Remove check for fkeys count > zero, block/unblock fixes the real bug.
120 (nsfont_list_family): Add block/unblock_input calls.
121 (nsfont_open): Move block_input earlier. Add unblock_input before early
122 return.
123 (nsfont_draw): Add block/unblock_input calls.
124
1252013-01-12 Dmitry Antipov <dmantipov@yandex.ru>
126
127 * indent.c (Fvertical_motion): Remove now-incorrect GCPROs
128 for old_charpos and old_bytepos.
129
1302013-01-12 Paul Eggert <eggert@cs.ucla.edu>
131
132 Fix bug with set-time-zone-rule and LOCALTIME_CACHE (Bug#13415).
133 * editfns.c (set_time_zone_rule) [LOCALTIME_CACHE]:
134 Clear tzvalbuf_in_environ if this workaround is in effect.
135 Problem and fix reported by Kazuhiro Ito.
136
1372013-01-11 Aaron S. Hawley <Aaron.Hawley@vtinfo.com>
138
139 * insdel.c (Fcombine_after_change_execute, syms_of_insdel): Fix
140 ambiguous doc string cross-reference(s).
141
142 * keyboard.c (Fcommand_execute, syms_of_keyboard): Fix ambiguous
143 doc string cross-reference(s).
144
145 * window.c (Fwindow_point, syms_of_window): Fix ambiguous doc
146 string cross-reference(s).
147
1482013-01-11 Dmitry Antipov <dmantipov@yandex.ru>
149
150 Avoid unnecessary byte position calculation for the gap movement.
151 Since all users of move_gap do CHAR_TO_BYTE for other purposes
152 anyway, all of them should use move_gap_both instead.
153 * lisp.h (move_gap): Remove prototype.
154 * insdel.c (move_gap): Remove.
155 (move_gap_both): Add eassert.
156 * editfns.c (Ftranspose_regions): Tweak to use move_gap_both.
157 * xml.c (parse_region): Likewise.
158
1592013-01-11 Paul Eggert <eggert@cs.ucla.edu>
160
161 emacsclient -t should not suspend Emacs server (Bug#13387)
162 * lisp.h, sysdep.c (block_tty_out_signal, unblock_tty_out_signal):
163 New functions.
164 * term.c (init_tty): Use them instead of rolling our own code.
165 * sysdep.c (tcsetpgrp_without_stopping): Likewise. Here, this
166 switches from 'signal' to 'pthread_sigmask', which is safer in
167 multithreaded applications.
168 * term.c (Fresume_tty): Don't bother dissociating if O_IGNORE_CTTY,
169 which has already arranged for that.
170 (dissociate_if_controlling_tty): If setsid fails, fall back on TIOCNOTTY.
171 This is the main part of the bug fix.
172
1732013-01-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> (tiny change)
174
175 * gtkutil.c (xg_initialize): Add ifdef HAVE_FREETYPE around
176 x_last_font_name (Bug#13403).
177
1782013-01-10 Dmitry Antipov <dmantipov@yandex.ru>
179
180 Omit buffer_slot_type_mismatch and use generic predicates to enforce
181 the type of per-buffer values where appropriate.
182 * lisp.h (struct Lisp_Buffer_Objfwd): Rename slottype member to
183 predicate, which is how it's really used now. Adjust comment.
184 * buffer.h (buffer_slot_type_mismatch): Remove prototype.
185 * buffer.c (buffer_slot_type_mismatch): Remove.
186 (DEFVAR_PER_BUFFER, defvar_per_buffer): Rename type argument to
187 predicate. Adjust comment.
188 (syms_of_buffer): Use Qsymbolp for major-mode. Use Qintegerp for
189 fill-column, left-margin, tab-width, buffer-saved-size,
190 left-margin-width, right-margin-width, left-fringe-width,
191 right-fringe-width, scroll-bar-width and buffer-display-count.
192 Use Qstringp for default-directory, buffer-file-name,
193 buffer-file-truename and buffer-auto-save-file-name. Use Qfloatp for
194 scroll-up-aggressively and scroll-down-aggressively. Use Qnumberp for
195 line-spacing.
196 * data.c (store_symval_forwarding): Adjust to call the predicate.
197
1982013-01-09 Juanma Barranquero <lekktu@gmail.com>
199
200 * w32.c (get_name_and_id, acl_set_file):
201 * w32term.c (w32fullscreen_hook): Remove unused local variables.
202
2032013-01-09 Dmitry Antipov <dmantipov@yandex.ru>
204
205 * lisp.h (make_gap_1): New prototype.
206 * buffer.h (GAP_BYTES_DFL, GAP_BYTES_MIN): New macros for the special
207 gap size values.
208 * editfns.c (Fbuffer_size): Rename from Fbufsize to fit the common
209 naming convention.
210 (syms_of_editfns): Adjust defsubr. Drop commented-out obsolete code.
211 * insdel.c (make_gap_larger): Use GAP_BYTES_DFL. Adjust comment.
212 (make_gap_smaller): Use GAP_BYTES_MIN. Adjust comment.
213 (make_gap_1): New function to adjust the gap of any buffer.
214 * coding.c (coding_alloc_by_making_gap): Use it.
215 * buffer.c (compact_buffer): Likewise. Use BUF_Z_BYTE, BUF_GAP_SIZE,
216 GAP_BYTES_DFL and GAP_BYTES_MIN. Adjust comment.
217
2182013-01-08 Juri Linkov <juri@jurta.org>
219
220 * xfaces.c (tty_supports_face_attributes_p): Return 0 for the case
221 of (supports :underline (:style wave)). (Bug#13000)
222
2232013-01-08 Aaron S. Hawley <aaron.s.hawley@gmail.com>
224
225 * undo.c (Fprimitive_undo): Move to simple.el.
226 (syms_of_undo): Remove declarations for Sprimitive_undo.
227
2282013-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
229
230 * keyboard.c (echo_add_key): Rename from echo_add_char.
231
2322013-01-06 Chong Yidong <cyd@gnu.org>
233
234 * keyboard.c (echo_add_char): New function, factored out from
235 echo_char. Don't add a space if the previous echo string was
236 empty (Bug#13255).
237 (echo_char): Use it.
238 (read_key_sequence): When echoing mock input, ensure that the
239 trailing dash is properly added.
240
12013-01-05 Eli Zaretskii <eliz@gnu.org> 2412013-01-05 Eli Zaretskii <eliz@gnu.org>
2 242
3 * xdisp.c (dump_glyph): Align glyph data better. Use "pD" instead 243 * xdisp.c (dump_glyph): Align glyph data better. Use "pD" instead
4 of a non-portable "t" to print ptrdiff_t values. Allow up to 9 244 of a non-portable "t" to print ptrdiff_t values. Allow up to 9
5 digits for buffer positions, before misalignment starts. Display 245 digits for buffer positions, before misalignment starts.
6 "0" for integer "object" field. 246 Display "0" for integer "object" field.
7 (dump_glyph_row): Adapt the header line to changes in dump_glyph. 247 (dump_glyph_row): Adapt the header line to changes in dump_glyph.
8 Display the newline glyph more unambiguously. 248 Display the newline glyph more unambiguously.
9 249
@@ -44,8 +284,8 @@
442012-12-31 Eli Zaretskii <eliz@gnu.org> 2842012-12-31 Eli Zaretskii <eliz@gnu.org>
45 285
46 * w32.c (unsetenv): Set up the string passed to _putenv 286 * w32.c (unsetenv): Set up the string passed to _putenv
47 correctly. See 287 correctly.
48 http://lists.gnu.org/archive/html/emacs-devel/2012-12/msg00863.html 288 See http://lists.gnu.org/archive/html/emacs-devel/2012-12/msg00863.html
49 for the bug this caused. 289 for the bug this caused.
50 290
512012-12-30 Paul Eggert <eggert@cs.ucla.edu> 2912012-12-30 Paul Eggert <eggert@cs.ucla.edu>
@@ -117,8 +357,8 @@
117 357
1182012-12-27 Eli Zaretskii <eliz@gnu.org> 3582012-12-27 Eli Zaretskii <eliz@gnu.org>
119 359
120 * fileio.c (file_name_as_directory, directory_file_name): Accept 360 * fileio.c (file_name_as_directory, directory_file_name):
121 an additional argument MULTIBYTE to indicate whether the input C 361 Accept an additional argument MULTIBYTE to indicate whether the input C
122 came from a multibyte or a unibyte Lisp string; all callers 362 came from a multibyte or a unibyte Lisp string; all callers
123 adjusted. Don't assume the input string is always multibyte. 363 adjusted. Don't assume the input string is always multibyte.
124 (Bug#13262) 364 (Bug#13262)
@@ -202,8 +442,8 @@
202 * w32.c (sys_close): Do not call delete_child on a subprocess 442 * w32.c (sys_close): Do not call delete_child on a subprocess
203 whose handle is not yet closed. Instead, set its file descriptor 443 whose handle is not yet closed. Instead, set its file descriptor
204 to a negative value, so that reap_subprocess will call 444 to a negative value, so that reap_subprocess will call
205 delete_child on that subprocess when its SIGCHLD arrives. This 445 delete_child on that subprocess when its SIGCHLD arrives.
206 avoids closing handles used for communications between sys_select 446 This avoids closing handles used for communications between sys_select
207 and reader_thread, which doesn't give sys_select a chance to 447 and reader_thread, which doesn't give sys_select a chance to
208 notice that the process exited and invoke the SIGCHLD handler for 448 notice that the process exited and invoke the SIGCHLD handler for
209 it. 449 it.
@@ -1642,7 +1882,7 @@
1642 * image.c (xpm_make_color_table_h): Fix compiler error because 1882 * image.c (xpm_make_color_table_h): Fix compiler error because
1643 make_hash_table changed. 1883 make_hash_table changed.
1644 1884
16452012-11-08 Thomas Kappler <tkappler@gmail.com> (tiny change) 18852012-11-08 Thomas Kappler <tkappler@gmail.com> (tiny change)
1646 1886
1647 * nsfont.m (ns_findfonts): Handle empty matchingDescs (Bug#11541). 1887 * nsfont.m (ns_findfonts): Handle empty matchingDescs (Bug#11541).
1648 1888
diff --git a/src/alloc.c b/src/alloc.c
index c2b2a4c1ed7..b7c17fbd6fb 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -209,6 +209,7 @@ Lisp_Object Qchar_table_extra_slots;
209 209
210static Lisp_Object Qpost_gc_hook; 210static Lisp_Object Qpost_gc_hook;
211 211
212static void free_save_value (Lisp_Object);
212static void mark_terminals (void); 213static void mark_terminals (void);
213static void gc_sweep (void); 214static void gc_sweep (void);
214static Lisp_Object make_pure_vector (ptrdiff_t); 215static Lisp_Object make_pure_vector (ptrdiff_t);
@@ -219,7 +220,6 @@ static void refill_memory_reserve (void);
219#endif 220#endif
220static void compact_small_strings (void); 221static void compact_small_strings (void);
221static void free_large_strings (void); 222static void free_large_strings (void);
222static void free_misc (Lisp_Object);
223extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; 223extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE;
224 224
225/* When scanning the C stack for live Lisp objects, Emacs keeps track of 225/* When scanning the C stack for live Lisp objects, Emacs keeps track of
@@ -3337,9 +3337,9 @@ allocate_misc (enum Lisp_Misc_Type type)
3337 return val; 3337 return val;
3338} 3338}
3339 3339
3340/* Free a Lisp_Misc object */ 3340/* Free a Lisp_Misc object. */
3341 3341
3342static void 3342void
3343free_misc (Lisp_Object misc) 3343free_misc (Lisp_Object misc)
3344{ 3344{
3345 XMISCTYPE (misc) = Lisp_Misc_Free; 3345 XMISCTYPE (misc) = Lisp_Misc_Free;
@@ -3349,34 +3349,77 @@ free_misc (Lisp_Object misc)
3349 total_free_markers++; 3349 total_free_markers++;
3350} 3350}
3351 3351
3352/* Return a Lisp_Misc_Save_Value object containing POINTER and 3352/* Return a Lisp_Save_Value object with the data saved according to
3353 INTEGER. This is used to package C values to call record_unwind_protect. 3353 FMT. Format specifiers are `i' for an integer, `p' for a pointer
3354 The unwind function can get the C values back using XSAVE_VALUE. */ 3354 and `o' for Lisp_Object. Up to 4 objects can be specified. */
3355 3355
3356Lisp_Object 3356Lisp_Object
3357make_save_value (void *pointer, ptrdiff_t integer) 3357format_save_value (const char *fmt, ...)
3358{ 3358{
3359 register Lisp_Object val; 3359 va_list ap;
3360 register struct Lisp_Save_Value *p; 3360 int len = strlen (fmt);
3361 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3362 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3363
3364 eassert (0 < len && len < 5);
3365 va_start (ap, fmt);
3366
3367#define INITX(index) \
3368 do { \
3369 if (len <= index) \
3370 p->type ## index = SAVE_UNUSED; \
3371 else \
3372 { \
3373 if (fmt[index] == 'i') \
3374 { \
3375 p->type ## index = SAVE_INTEGER; \
3376 p->data[index].integer = va_arg (ap, ptrdiff_t); \
3377 } \
3378 else if (fmt[index] == 'p') \
3379 { \
3380 p->type ## index = SAVE_POINTER; \
3381 p->data[index].pointer = va_arg (ap, void *); \
3382 } \
3383 else if (fmt[index] == 'o') \
3384 { \
3385 p->type ## index = SAVE_OBJECT; \
3386 p->data[index].object = va_arg (ap, Lisp_Object); \
3387 } \
3388 else \
3389 emacs_abort (); \
3390 } \
3391 } while (0)
3392
3393 INITX (0);
3394 INITX (1);
3395 INITX (2);
3396 INITX (3);
3361 3397
3362 val = allocate_misc (Lisp_Misc_Save_Value); 3398#undef INITX
3363 p = XSAVE_VALUE (val); 3399
3364 p->pointer = pointer; 3400 va_end (ap);
3365 p->integer = integer; 3401 p->area = 0;
3366 p->dogc = 0;
3367 return val; 3402 return val;
3368} 3403}
3369 3404
3370/* Free a Lisp_Misc_Save_Value object. */ 3405/* Return a Lisp_Save_Value object containing POINTER and INTEGER.
3406 Most code should use this to package C integers and pointers
3407 to call record_unwind_protect. The unwind function can get the
3408 C values back using XSAVE_POINTER and XSAVE_INTEGER. */
3371 3409
3372void 3410Lisp_Object
3373free_save_value (Lisp_Object save) 3411make_save_value (void *pointer, ptrdiff_t integer)
3374{ 3412{
3375 register struct Lisp_Save_Value *p = XSAVE_VALUE (save); 3413 return format_save_value ("pi", pointer, integer);
3414}
3415
3416/* Free a Lisp_Save_Value object. Do not use this function
3417 if SAVE contains pointer other than returned by xmalloc. */
3376 3418
3377 p->dogc = 0; 3419static void
3378 xfree (p->pointer); 3420free_save_value (Lisp_Object save)
3379 p->pointer = NULL; 3421{
3422 xfree (XSAVE_POINTER (save, 0));
3380 free_misc (save); 3423 free_misc (save);
3381} 3424}
3382 3425
@@ -4444,11 +4487,6 @@ mark_memory (void *start, void *end)
4444 } 4487 }
4445} 4488}
4446 4489
4447/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in
4448 the GCC system configuration. In gcc 3.2, the only systems for
4449 which this is so are i386-sco5 non-ELF, i386-sysv3 (maybe included
4450 by others?) and ns32k-pc532-min. */
4451
4452#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS 4490#if !defined GC_SAVE_REGISTERS_ON_STACK && !defined GC_SETJMP_WORKS
4453 4491
4454static bool setjmp_tested_p; 4492static bool setjmp_tested_p;
@@ -5913,20 +5951,33 @@ mark_object (Lisp_Object arg)
5913 5951
5914 case Lisp_Misc_Save_Value: 5952 case Lisp_Misc_Save_Value:
5915 XMISCANY (obj)->gcmarkbit = 1; 5953 XMISCANY (obj)->gcmarkbit = 1;
5916#if GC_MARK_STACK
5917 { 5954 {
5918 register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); 5955 register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
5919 /* If DOGC is set, POINTER is the address of a memory 5956 /* If `area' is nonzero, `data[0].pointer' is the address
5920 area containing INTEGER potential Lisp_Objects. */ 5957 of a memory area containing `data[1].integer' potential
5921 if (ptr->dogc) 5958 Lisp_Objects. */
5959#if GC_MARK_STACK
5960 if (ptr->area)
5922 { 5961 {
5923 Lisp_Object *p = (Lisp_Object *) ptr->pointer; 5962 Lisp_Object *p = ptr->data[0].pointer;
5924 ptrdiff_t nelt; 5963 ptrdiff_t nelt;
5925 for (nelt = ptr->integer; nelt > 0; nelt--, p++) 5964 for (nelt = ptr->data[1].integer; nelt > 0; nelt--, p++)
5926 mark_maybe_object (*p); 5965 mark_maybe_object (*p);
5927 } 5966 }
5967 else
5968#endif /* GC_MARK_STACK */
5969 {
5970 /* Find Lisp_Objects in `data[N]' slots and mark them. */
5971 if (ptr->type0 == SAVE_OBJECT)
5972 mark_object (ptr->data[0].object);
5973 if (ptr->type1 == SAVE_OBJECT)
5974 mark_object (ptr->data[1].object);
5975 if (ptr->type2 == SAVE_OBJECT)
5976 mark_object (ptr->data[2].object);
5977 if (ptr->type3 == SAVE_OBJECT)
5978 mark_object (ptr->data[3].object);
5979 }
5928 } 5980 }
5929#endif
5930 break; 5981 break;
5931 5982
5932 case Lisp_Misc_Overlay: 5983 case Lisp_Misc_Overlay:
diff --git a/src/buffer.c b/src/buffer.c
index 61b457e4558..a06868ec6c3 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1680,17 +1680,13 @@ compact_buffer (struct buffer *buffer)
1680 if (!buffer->text->inhibit_shrinking) 1680 if (!buffer->text->inhibit_shrinking)
1681 { 1681 {
1682 /* If a buffer's gap size is more than 10% of the buffer 1682 /* If a buffer's gap size is more than 10% of the buffer
1683 size, or larger than 2000 bytes, then shrink it 1683 size, or larger than GAP_BYTES_DFL bytes, then shrink it
1684 accordingly. Keep a minimum size of 20 bytes. */ 1684 accordingly. Keep a minimum size of GAP_BYTES_MIN bytes. */
1685 int size = min (2000, max (20, (buffer->text->z_byte / 10))); 1685 ptrdiff_t size = clip_to_bounds (GAP_BYTES_MIN,
1686 1686 BUF_Z_BYTE (buffer) / 10,
1687 if (buffer->text->gap_size > size) 1687 GAP_BYTES_DFL);
1688 { 1688 if (BUF_GAP_SIZE (buffer) > size)
1689 struct buffer *save_current = current_buffer; 1689 make_gap_1 (buffer, -(BUF_GAP_SIZE (buffer) - size));
1690 current_buffer = buffer;
1691 make_gap (-(buffer->text->gap_size - size));
1692 current_buffer = save_current;
1693 }
1694 } 1690 }
1695 BUF_COMPACT (buffer) = BUF_MODIFF (buffer); 1691 BUF_COMPACT (buffer) = BUF_MODIFF (buffer);
1696 } 1692 }
@@ -4578,27 +4574,7 @@ evaporate_overlays (ptrdiff_t pos)
4578 for (; CONSP (hit_list); hit_list = XCDR (hit_list)) 4574 for (; CONSP (hit_list); hit_list = XCDR (hit_list))
4579 Fdelete_overlay (XCAR (hit_list)); 4575 Fdelete_overlay (XCAR (hit_list));
4580} 4576}
4581
4582/* Somebody has tried to store a value with an unacceptable type
4583 in the slot with offset OFFSET. */
4584
4585void
4586buffer_slot_type_mismatch (Lisp_Object newval, int type)
4587{
4588 Lisp_Object predicate;
4589
4590 switch (type)
4591 {
4592 case_Lisp_Int: predicate = Qintegerp; break;
4593 case Lisp_String: predicate = Qstringp; break;
4594 case Lisp_Symbol: predicate = Qsymbolp; break;
4595 default: emacs_abort ();
4596 }
4597
4598 wrong_type_argument (predicate, newval);
4599}
4600 4577
4601
4602/*********************************************************************** 4578/***********************************************************************
4603 Allocation with mmap 4579 Allocation with mmap
4604 ***********************************************************************/ 4580 ***********************************************************************/
@@ -5372,25 +5348,23 @@ init_buffer (void)
5372 free (pwd); 5348 free (pwd);
5373} 5349}
5374 5350
5375/* Similar to defvar_lisp but define a variable whose value is the Lisp 5351/* Similar to defvar_lisp but define a variable whose value is the
5376 Object stored in the current buffer. address is the address of the slot 5352 Lisp_Object stored in the current buffer. LNAME is the Lisp-level
5377 in the buffer that is current now. */ 5353 variable name. VNAME is the name of the buffer slot. PREDICATE
5378 5354 is nil for a general Lisp variable. If PREDICATE is non-nil, then
5379/* TYPE is nil for a general Lisp variable. 5355 only Lisp values that satisfies the PREDICATE are allowed (except
5380 An integer specifies a type; then only Lisp values 5356 that nil is allowed too). DOC is a dummy where you write the doc
5381 with that type code are allowed (except that nil is allowed too). 5357 string as a comment. */
5382 LNAME is the Lisp-level variable name. 5358
5383 VNAME is the name of the buffer slot. 5359#define DEFVAR_PER_BUFFER(lname, vname, predicate, doc) \
5384 DOC is a dummy where you write the doc string as a comment. */ 5360 do { \
5385#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ 5361 static struct Lisp_Buffer_Objfwd bo_fwd; \
5386 do { \ 5362 defvar_per_buffer (&bo_fwd, lname, vname, predicate); \
5387 static struct Lisp_Buffer_Objfwd bo_fwd; \
5388 defvar_per_buffer (&bo_fwd, lname, vname, type); \
5389 } while (0) 5363 } while (0)
5390 5364
5391static void 5365static void
5392defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, 5366defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5393 Lisp_Object *address, Lisp_Object type) 5367 Lisp_Object *address, Lisp_Object predicate)
5394{ 5368{
5395 struct Lisp_Symbol *sym; 5369 struct Lisp_Symbol *sym;
5396 int offset; 5370 int offset;
@@ -5400,7 +5374,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5400 5374
5401 bo_fwd->type = Lisp_Fwd_Buffer_Obj; 5375 bo_fwd->type = Lisp_Fwd_Buffer_Obj;
5402 bo_fwd->offset = offset; 5376 bo_fwd->offset = offset;
5403 bo_fwd->slottype = type; 5377 bo_fwd->predicate = predicate;
5404 sym->declared_special = 1; 5378 sym->declared_special = 1;
5405 sym->redirect = SYMBOL_FORWARDED; 5379 sym->redirect = SYMBOL_FORWARDED;
5406 { 5380 {
@@ -5663,7 +5637,7 @@ Decimal digits after the % specify field width to which to pad. */);
5663 doc: /* Value of `major-mode' for new buffers. */); 5637 doc: /* Value of `major-mode' for new buffers. */);
5664 5638
5665 DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode), 5639 DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode),
5666 make_number (Lisp_Symbol), 5640 Qsymbolp,
5667 doc: /* Symbol for current buffer's major mode. 5641 doc: /* Symbol for current buffer's major mode.
5668The default value (normally `fundamental-mode') affects new buffers. 5642The default value (normally `fundamental-mode') affects new buffers.
5669A value of nil means to use the current buffer's major mode, provided 5643A value of nil means to use the current buffer's major mode, provided
@@ -5694,17 +5668,17 @@ Use the command `abbrev-mode' to change this variable. */);
5694 doc: /* Non-nil if searches and matches should ignore case. */); 5668 doc: /* Non-nil if searches and matches should ignore case. */);
5695 5669
5696 DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column), 5670 DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column),
5697 make_number (Lisp_Int0), 5671 Qintegerp,
5698 doc: /* Column beyond which automatic line-wrapping should happen. 5672 doc: /* Column beyond which automatic line-wrapping should happen.
5699Interactively, you can set the buffer local value using \\[set-fill-column]. */); 5673Interactively, you can set the buffer local value using \\[set-fill-column]. */);
5700 5674
5701 DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin), 5675 DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin),
5702 make_number (Lisp_Int0), 5676 Qintegerp,
5703 doc: /* Column for the default `indent-line-function' to indent to. 5677 doc: /* Column for the default `indent-line-function' to indent to.
5704Linefeed indents to this column in Fundamental mode. */); 5678Linefeed indents to this column in Fundamental mode. */);
5705 5679
5706 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width), 5680 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
5707 make_number (Lisp_Int0), 5681 Qintegerp,
5708 doc: /* Distance between tab stops (for display of tab characters), in columns. 5682 doc: /* Distance between tab stops (for display of tab characters), in columns.
5709This should be an integer greater than zero. */); 5683This should be an integer greater than zero. */);
5710 5684
@@ -5789,7 +5763,7 @@ visual lines rather than logical lines. See the documentation of
5789`visual-line-mode'. */); 5763`visual-line-mode'. */);
5790 5764
5791 DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), 5765 DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory),
5792 make_number (Lisp_String), 5766 Qstringp,
5793 doc: /* Name of default directory of current buffer. Should end with slash. 5767 doc: /* Name of default directory of current buffer. Should end with slash.
5794To interactively change the default directory, use command `cd'. */); 5768To interactively change the default directory, use command `cd'. */);
5795 5769
@@ -5802,18 +5776,18 @@ NOTE: This variable is not a hook;
5802its value may not be a list of functions. */); 5776its value may not be a list of functions. */);
5803 5777
5804 DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename), 5778 DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename),
5805 make_number (Lisp_String), 5779 Qstringp,
5806 doc: /* Name of file visited in current buffer, or nil if not visiting a file. */); 5780 doc: /* Name of file visited in current buffer, or nil if not visiting a file. */);
5807 5781
5808 DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename), 5782 DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename),
5809 make_number (Lisp_String), 5783 Qstringp,
5810 doc: /* Abbreviated truename of file visited in current buffer, or nil if none. 5784 doc: /* Abbreviated truename of file visited in current buffer, or nil if none.
5811The truename of a file is calculated by `file-truename' 5785The truename of a file is calculated by `file-truename'
5812and then abbreviated with `abbreviate-file-name'. */); 5786and then abbreviated with `abbreviate-file-name'. */);
5813 5787
5814 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name", 5788 DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
5815 &BVAR (current_buffer, auto_save_file_name), 5789 &BVAR (current_buffer, auto_save_file_name),
5816 make_number (Lisp_String), 5790 Qstringp,
5817 doc: /* Name of file for auto-saving current buffer. 5791 doc: /* Name of file for auto-saving current buffer.
5818If it is nil, that means don't auto-save this buffer. */); 5792If it is nil, that means don't auto-save this buffer. */);
5819 5793
@@ -5825,7 +5799,7 @@ If it is nil, that means don't auto-save this buffer. */);
5825Backing up is done before the first time the file is saved. */); 5799Backing up is done before the first time the file is saved. */);
5826 5800
5827 DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length), 5801 DEFVAR_PER_BUFFER ("buffer-saved-size", &BVAR (current_buffer, save_length),
5828 make_number (Lisp_Int0), 5802 Qintegerp,
5829 doc: /* Length of current buffer when last read in, saved or auto-saved. 5803 doc: /* Length of current buffer when last read in, saved or auto-saved.
58300 initially. 58040 initially.
5831-1 means auto-saving turned off until next real save. 5805-1 means auto-saving turned off until next real save.
@@ -5895,23 +5869,23 @@ In addition, a char-table has six extra slots to control the display of:
5895See also the functions `display-table-slot' and `set-display-table-slot'. */); 5869See also the functions `display-table-slot' and `set-display-table-slot'. */);
5896 5870
5897 DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols), 5871 DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols),
5898 Qnil, 5872 Qintegerp,
5899 doc: /* Width of left marginal area for display of a buffer. 5873 doc: /* Width of left marginal area for display of a buffer.
5900A value of nil means no marginal area. */); 5874A value of nil means no marginal area. */);
5901 5875
5902 DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols), 5876 DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols),
5903 Qnil, 5877 Qintegerp,
5904 doc: /* Width of right marginal area for display of a buffer. 5878 doc: /* Width of right marginal area for display of a buffer.
5905A value of nil means no marginal area. */); 5879A value of nil means no marginal area. */);
5906 5880
5907 DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width), 5881 DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width),
5908 Qnil, 5882 Qintegerp,
5909 doc: /* Width of this buffer's left fringe (in pixels). 5883 doc: /* Width of this buffer's left fringe (in pixels).
5910A value of 0 means no left fringe is shown in this buffer's window. 5884A value of 0 means no left fringe is shown in this buffer's window.
5911A value of nil means to use the left fringe width from the window's frame. */); 5885A value of nil means to use the left fringe width from the window's frame. */);
5912 5886
5913 DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width), 5887 DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width),
5914 Qnil, 5888 Qintegerp,
5915 doc: /* Width of this buffer's right fringe (in pixels). 5889 doc: /* Width of this buffer's right fringe (in pixels).
5916A value of 0 means no right fringe is shown in this buffer's window. 5890A value of 0 means no right fringe is shown in this buffer's window.
5917A value of nil means to use the right fringe width from the window's frame. */); 5891A value of nil means to use the right fringe width from the window's frame. */);
@@ -5922,7 +5896,7 @@ A value of nil means to use the right fringe width from the window's frame. */)
5922A value of nil means to display fringes between margins and buffer text. */); 5896A value of nil means to display fringes between margins and buffer text. */);
5923 5897
5924 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width), 5898 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
5925 Qnil, 5899 Qintegerp,
5926 doc: /* Width of this buffer's scroll bars in pixels. 5900 doc: /* Width of this buffer's scroll bars in pixels.
5927A value of nil means to use the scroll bar width from the window's frame. */); 5901A value of nil means to use the scroll bar width from the window's frame. */);
5928 5902
@@ -6002,7 +5976,7 @@ BITMAP is the corresponding fringe bitmap shown for the logical
6002cursor type. */); 5976cursor type. */);
6003 5977
6004 DEFVAR_PER_BUFFER ("scroll-up-aggressively", 5978 DEFVAR_PER_BUFFER ("scroll-up-aggressively",
6005 &BVAR (current_buffer, scroll_up_aggressively), Qnil, 5979 &BVAR (current_buffer, scroll_up_aggressively), Qfloatp,
6006 doc: /* How far to scroll windows upward. 5980 doc: /* How far to scroll windows upward.
6007If you move point off the bottom, the window scrolls automatically. 5981If you move point off the bottom, the window scrolls automatically.
6008This variable controls how far it scrolls. The value nil, the default, 5982This variable controls how far it scrolls. The value nil, the default,
@@ -6015,7 +5989,7 @@ window scrolls by a full window height. Meaningful values are
6015between 0.0 and 1.0, inclusive. */); 5989between 0.0 and 1.0, inclusive. */);
6016 5990
6017 DEFVAR_PER_BUFFER ("scroll-down-aggressively", 5991 DEFVAR_PER_BUFFER ("scroll-down-aggressively",
6018 &BVAR (current_buffer, scroll_down_aggressively), Qnil, 5992 &BVAR (current_buffer, scroll_down_aggressively), Qfloatp,
6019 doc: /* How far to scroll windows downward. 5993 doc: /* How far to scroll windows downward.
6020If you move point off the top, the window scrolls automatically. 5994If you move point off the top, the window scrolls automatically.
6021This variable controls how far it scrolls. The value nil, the default, 5995This variable controls how far it scrolls. The value nil, the default,
@@ -6169,7 +6143,7 @@ then characters with property value PROP are invisible,
6169and they have an ellipsis as well if ELLIPSIS is non-nil. */); 6143and they have an ellipsis as well if ELLIPSIS is non-nil. */);
6170 6144
6171 DEFVAR_PER_BUFFER ("buffer-display-count", 6145 DEFVAR_PER_BUFFER ("buffer-display-count",
6172 &BVAR (current_buffer, display_count), Qnil, 6146 &BVAR (current_buffer, display_count), Qintegerp,
6173 doc: /* A number incremented each time this buffer is displayed in a window. 6147 doc: /* A number incremented each time this buffer is displayed in a window.
6174The function `set-window-buffer' increments it. */); 6148The function `set-window-buffer' increments it. */);
6175 6149
@@ -6228,7 +6202,7 @@ cursor's appearance is instead controlled by the variable
6228`cursor-in-non-selected-windows'. */); 6202`cursor-in-non-selected-windows'. */);
6229 6203
6230 DEFVAR_PER_BUFFER ("line-spacing", 6204 DEFVAR_PER_BUFFER ("line-spacing",
6231 &BVAR (current_buffer, extra_line_spacing), Qnil, 6205 &BVAR (current_buffer, extra_line_spacing), Qnumberp,
6232 doc: /* Additional space to put between lines when displaying a buffer. 6206 doc: /* Additional space to put between lines when displaying a buffer.
6233The space is measured in pixels, and put below lines on graphic displays, 6207The space is measured in pixels, and put below lines on graphic displays,
6234see `display-graphic-p'. 6208see `display-graphic-p'.
diff --git a/src/buffer.h b/src/buffer.h
index 4bf2b4c2a0b..c0b0e227725 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -320,6 +320,16 @@ while (0)
320#define BUF_BYTES_MAX \ 320#define BUF_BYTES_MAX \
321 (ptrdiff_t) min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX)) 321 (ptrdiff_t) min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX))
322 322
323/* Maximum gap size after compact_buffer, in bytes. Also
324 used in make_gap_larger to get some extra reserved space. */
325
326#define GAP_BYTES_DFL 2000
327
328/* Minimum gap size after compact_buffer, in bytes. Also
329 used in make_gap_smaller to avoid too small gap size. */
330
331#define GAP_BYTES_MIN 20
332
323/* Return the address of byte position N in current buffer. */ 333/* Return the address of byte position N in current buffer. */
324 334
325#define BYTE_POS_ADDR(n) \ 335#define BYTE_POS_ADDR(n) \
@@ -1064,7 +1074,6 @@ extern void set_buffer_internal_1 (struct buffer *);
1064extern void set_buffer_temp (struct buffer *); 1074extern void set_buffer_temp (struct buffer *);
1065extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object); 1075extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object);
1066extern void record_buffer (Lisp_Object); 1076extern void record_buffer (Lisp_Object);
1067extern _Noreturn void buffer_slot_type_mismatch (Lisp_Object, int);
1068extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t); 1077extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t);
1069extern void mmap_set_vars (bool); 1078extern void mmap_set_vars (bool);
1070 1079
diff --git a/src/coding.c b/src/coding.c
index 5285a906823..a9bf9032a69 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -1049,14 +1049,7 @@ coding_alloc_by_making_gap (struct coding_system *coding,
1049 GPT -= gap_head_used, GPT_BYTE -= gap_head_used; 1049 GPT -= gap_head_used, GPT_BYTE -= gap_head_used;
1050 } 1050 }
1051 else 1051 else
1052 { 1052 make_gap_1 (XBUFFER (coding->dst_object), bytes);
1053 Lisp_Object this_buffer;
1054
1055 this_buffer = Fcurrent_buffer ();
1056 set_buffer_internal (XBUFFER (coding->dst_object));
1057 make_gap (bytes);
1058 set_buffer_internal (XBUFFER (this_buffer));
1059 }
1060} 1053}
1061 1054
1062 1055
diff --git a/src/data.c b/src/data.c
index e9f3a2cff3f..8a66cbe9197 100644
--- a/src/data.c
+++ b/src/data.c
@@ -951,13 +951,11 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
951 case Lisp_Fwd_Buffer_Obj: 951 case Lisp_Fwd_Buffer_Obj:
952 { 952 {
953 int offset = XBUFFER_OBJFWD (valcontents)->offset; 953 int offset = XBUFFER_OBJFWD (valcontents)->offset;
954 Lisp_Object type = XBUFFER_OBJFWD (valcontents)->slottype; 954 Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate;
955 955
956 if (!(NILP (type) || NILP (newval) 956 if (!NILP (predicate) && !NILP (newval)
957 || (XINT (type) == Lisp_Int0 957 && NILP (call1 (predicate, newval)))
958 ? INTEGERP (newval) 958 wrong_type_argument (predicate, newval);
959 : XTYPE (newval) == XINT (type))))
960 buffer_slot_type_mismatch (newval, XINT (type));
961 959
962 if (buf == NULL) 960 if (buf == NULL)
963 buf = current_buffer; 961 buf = current_buffer;
diff --git a/src/dired.c b/src/dired.c
index b4dc702112e..3dca9d24f67 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -78,7 +78,7 @@ directory_files_internal_w32_unwind (Lisp_Object arg)
78static Lisp_Object 78static Lisp_Object
79directory_files_internal_unwind (Lisp_Object dh) 79directory_files_internal_unwind (Lisp_Object dh)
80{ 80{
81 DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer; 81 DIR *d = XSAVE_POINTER (dh, 0);
82 block_input (); 82 block_input ();
83 closedir (d); 83 closedir (d);
84 unblock_input (); 84 unblock_input ();
diff --git a/src/editfns.c b/src/editfns.c
index df0dad0669d..8910b66e4d3 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -833,21 +833,17 @@ This function does not move point. */)
833Lisp_Object 833Lisp_Object
834save_excursion_save (void) 834save_excursion_save (void)
835{ 835{
836 Lisp_Object save, *data = xmalloc (word_size * 4); 836 return format_save_value
837 837 ("oooo",
838 data[0] = Fpoint_marker (); 838 Fpoint_marker (),
839 /* Do not copy the mark if it points to nowhere. */ 839 /* Do not copy the mark if it points to nowhere. */
840 data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer 840 (XMARKER (BVAR (current_buffer, mark))->buffer
841 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) 841 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
842 : Qnil); 842 : Qnil),
843 /* Selected window if current buffer is shown in it, nil otherwise. */ 843 /* Selected window if current buffer is shown in it, nil otherwise. */
844 data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) 844 ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
845 ? selected_window : Qnil); 845 ? selected_window : Qnil),
846 data[3] = BVAR (current_buffer, mark_active); 846 BVAR (current_buffer, mark_active));
847
848 save = make_save_value (data, 4);
849 XSAVE_VALUE (save)->dogc = 1;
850 return save;
851} 847}
852 848
853/* Restore saved buffer before leaving `save-excursion' special form. */ 849/* Restore saved buffer before leaving `save-excursion' special form. */
@@ -855,10 +851,10 @@ save_excursion_save (void)
855Lisp_Object 851Lisp_Object
856save_excursion_restore (Lisp_Object info) 852save_excursion_restore (Lisp_Object info)
857{ 853{
858 Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer; 854 Lisp_Object tem, tem1, omark, nmark;
859 struct gcpro gcpro1, gcpro2, gcpro3; 855 struct gcpro gcpro1, gcpro2, gcpro3;
860 856
861 tem = Fmarker_buffer (data[0]); 857 tem = Fmarker_buffer (XSAVE_OBJECT (info, 0));
862 /* If we're unwinding to top level, saved buffer may be deleted. This 858 /* If we're unwinding to top level, saved buffer may be deleted. This
863 means that all of its markers are unchained and so tem is nil. */ 859 means that all of its markers are unchained and so tem is nil. */
864 if (NILP (tem)) 860 if (NILP (tem))
@@ -870,12 +866,12 @@ save_excursion_restore (Lisp_Object info)
870 Fset_buffer (tem); 866 Fset_buffer (tem);
871 867
872 /* Point marker. */ 868 /* Point marker. */
873 tem = data[0]; 869 tem = XSAVE_OBJECT (info, 0);
874 Fgoto_char (tem); 870 Fgoto_char (tem);
875 unchain_marker (XMARKER (tem)); 871 unchain_marker (XMARKER (tem));
876 872
877 /* Mark marker. */ 873 /* Mark marker. */
878 tem = data[1]; 874 tem = XSAVE_OBJECT (info, 1);
879 omark = Fmarker_position (BVAR (current_buffer, mark)); 875 omark = Fmarker_position (BVAR (current_buffer, mark));
880 if (NILP (tem)) 876 if (NILP (tem))
881 unchain_marker (XMARKER (BVAR (current_buffer, mark))); 877 unchain_marker (XMARKER (BVAR (current_buffer, mark)));
@@ -887,7 +883,7 @@ save_excursion_restore (Lisp_Object info)
887 } 883 }
888 884
889 /* Mark active. */ 885 /* Mark active. */
890 tem = data[3]; 886 tem = XSAVE_OBJECT (info, 3);
891 tem1 = BVAR (current_buffer, mark_active); 887 tem1 = BVAR (current_buffer, mark_active);
892 bset_mark_active (current_buffer, tem); 888 bset_mark_active (current_buffer, tem);
893 889
@@ -911,7 +907,7 @@ save_excursion_restore (Lisp_Object info)
911 /* If buffer was visible in a window, and a different window was 907 /* If buffer was visible in a window, and a different window was
912 selected, and the old selected window is still showing this 908 selected, and the old selected window is still showing this
913 buffer, restore point in that window. */ 909 buffer, restore point in that window. */
914 tem = data[2]; 910 tem = XSAVE_OBJECT (info, 2);
915 if (WINDOWP (tem) 911 if (WINDOWP (tem)
916 && !EQ (tem, selected_window) 912 && !EQ (tem, selected_window)
917 && (tem1 = XWINDOW (tem)->buffer, 913 && (tem1 = XWINDOW (tem)->buffer,
@@ -925,7 +921,7 @@ save_excursion_restore (Lisp_Object info)
925 921
926 out: 922 out:
927 923
928 free_save_value (info); 924 free_misc (info);
929 return Qnil; 925 return Qnil;
930} 926}
931 927
@@ -968,7 +964,7 @@ usage: (save-current-buffer &rest BODY) */)
968 return unbind_to (count, Fprogn (args)); 964 return unbind_to (count, Fprogn (args));
969} 965}
970 966
971DEFUN ("buffer-size", Fbufsize, Sbufsize, 0, 1, 0, 967DEFUN ("buffer-size", Fbuffer_size, Sbuffer_size, 0, 1, 0,
972 doc: /* Return the number of characters in the current buffer. 968 doc: /* Return the number of characters in the current buffer.
973If BUFFER, return the number of characters in that buffer instead. */) 969If BUFFER, return the number of characters in that buffer instead. */)
974 (Lisp_Object buffer) 970 (Lisp_Object buffer)
@@ -2188,6 +2184,7 @@ set_time_zone_rule (const char *tzstring)
2188 xputenv (set_time_zone_rule_tz[1]); 2184 xputenv (set_time_zone_rule_tz[1]);
2189 } 2185 }
2190 tzset (); 2186 tzset ();
2187 tzvalbuf_in_environ = 0;
2191#endif 2188#endif
2192 2189
2193 if (!tzstring) 2190 if (!tzstring)
@@ -4257,7 +4254,7 @@ usage: (format STRING &rest OBJECTS) */)
4257 memcpy (buf, initial_buffer, used); 4254 memcpy (buf, initial_buffer, used);
4258 } 4255 }
4259 else 4256 else
4260 XSAVE_VALUE (buf_save_value)->pointer = buf = xrealloc (buf, bufsize); 4257 XSAVE_POINTER (buf_save_value, 0) = buf = xrealloc (buf, bufsize);
4261 4258
4262 p = buf + used; 4259 p = buf + used;
4263 } 4260 }
@@ -4522,7 +4519,7 @@ Transposing beyond buffer boundaries is an error. */)
4522 (Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers) 4519 (Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers)
4523{ 4520{
4524 register ptrdiff_t start1, end1, start2, end2; 4521 register ptrdiff_t start1, end1, start2, end2;
4525 ptrdiff_t start1_byte, start2_byte, len1_byte, len2_byte; 4522 ptrdiff_t start1_byte, start2_byte, len1_byte, len2_byte, end2_byte;
4526 ptrdiff_t gap, len1, len_mid, len2; 4523 ptrdiff_t gap, len1, len_mid, len2;
4527 unsigned char *start1_addr, *start2_addr, *temp; 4524 unsigned char *start1_addr, *start2_addr, *temp;
4528 4525
@@ -4583,20 +4580,22 @@ Transposing beyond buffer boundaries is an error. */)
4583 the gap the minimum distance to get it out of the way, and then 4580 the gap the minimum distance to get it out of the way, and then
4584 deal with an unbroken array. */ 4581 deal with an unbroken array. */
4585 4582
4583 start1_byte = CHAR_TO_BYTE (start1);
4584 end2_byte = CHAR_TO_BYTE (end2);
4585
4586 /* Make sure the gap won't interfere, by moving it out of the text 4586 /* Make sure the gap won't interfere, by moving it out of the text
4587 we will operate on. */ 4587 we will operate on. */
4588 if (start1 < gap && gap < end2) 4588 if (start1 < gap && gap < end2)
4589 { 4589 {
4590 if (gap - start1 < end2 - gap) 4590 if (gap - start1 < end2 - gap)
4591 move_gap (start1); 4591 move_gap_both (start1, start1_byte);
4592 else 4592 else
4593 move_gap (end2); 4593 move_gap_both (end2, end2_byte);
4594 } 4594 }
4595 4595
4596 start1_byte = CHAR_TO_BYTE (start1);
4597 start2_byte = CHAR_TO_BYTE (start2); 4596 start2_byte = CHAR_TO_BYTE (start2);
4598 len1_byte = CHAR_TO_BYTE (end1) - start1_byte; 4597 len1_byte = CHAR_TO_BYTE (end1) - start1_byte;
4599 len2_byte = CHAR_TO_BYTE (end2) - start2_byte; 4598 len2_byte = end2_byte - start2_byte;
4600 4599
4601#ifdef BYTE_COMBINING_DEBUG 4600#ifdef BYTE_COMBINING_DEBUG
4602 if (end1 == start2) 4601 if (end1 == start2)
@@ -4883,12 +4882,10 @@ functions if all the text being accessed has this property. */);
4883 defsubr (&Sline_beginning_position); 4882 defsubr (&Sline_beginning_position);
4884 defsubr (&Sline_end_position); 4883 defsubr (&Sline_end_position);
4885 4884
4886/* defsubr (&Smark); */
4887/* defsubr (&Sset_mark); */
4888 defsubr (&Ssave_excursion); 4885 defsubr (&Ssave_excursion);
4889 defsubr (&Ssave_current_buffer); 4886 defsubr (&Ssave_current_buffer);
4890 4887
4891 defsubr (&Sbufsize); 4888 defsubr (&Sbuffer_size);
4892 defsubr (&Spoint_max); 4889 defsubr (&Spoint_max);
4893 defsubr (&Spoint_min); 4890 defsubr (&Spoint_min);
4894 defsubr (&Spoint_min_marker); 4891 defsubr (&Spoint_min_marker);
diff --git a/src/emacs.c b/src/emacs.c
index 57de81f05b0..1848c71a22f 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -340,25 +340,6 @@ terminate_due_to_signal (int sig, int backtrace_limit)
340 /* This shouldn't be executed, but it prevents a warning. */ 340 /* This shouldn't be executed, but it prevents a warning. */
341 exit (1); 341 exit (1);
342} 342}
343
344#ifdef SIGDANGER
345
346/* Handler for SIGDANGER. */
347static void
348handle_danger_signal (int sig)
349{
350 malloc_warning ("Operating system warns that virtual memory is running low.\n");
351
352 /* It might be unsafe to call do_auto_save now. */
353 force_auto_save_soon ();
354}
355
356static void
357deliver_danger_signal (int sig)
358{
359 deliver_process_signal (sig, handle_danger_signal);
360}
361#endif
362 343
363/* Code for dealing with Lisp access to the Unix command line. */ 344/* Code for dealing with Lisp access to the Unix command line. */
364 345
diff --git a/src/eval.c b/src/eval.c
index f88567f14cb..18031236c7d 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1950,7 +1950,10 @@ eval_sub (Lisp_Object form)
1950 return form; 1950 return form;
1951 1951
1952 QUIT; 1952 QUIT;
1953
1954 GCPRO1 (form);
1953 maybe_gc (); 1955 maybe_gc ();
1956 UNGCPRO;
1954 1957
1955 if (++lisp_eval_depth > max_lisp_eval_depth) 1958 if (++lisp_eval_depth > max_lisp_eval_depth)
1956 { 1959 {
diff --git a/src/fileio.c b/src/fileio.c
index 5e9b36ee44a..87d945c1e5e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3408,30 +3408,22 @@ decide_coding_unwind (Lisp_Object unwind_data)
3408 return Qnil; 3408 return Qnil;
3409} 3409}
3410 3410
3411 3411/* Read from a non-regular file. STATE is a Lisp_Save_Value
3412/* Used to pass values from insert-file-contents to read_non_regular. */ 3412 object where slot 0 is the file descriptor, slot 1 specifies
3413 3413 an offset to put the read bytes, and slot 2 is the maximum
3414static int non_regular_fd; 3414 amount of bytes to read. Value is the number of bytes read. */
3415static ptrdiff_t non_regular_inserted;
3416static int non_regular_nbytes;
3417
3418
3419/* Read from a non-regular file.
3420 Read non_regular_nbytes bytes max from non_regular_fd.
3421 Non_regular_inserted specifies where to put the read bytes.
3422 Value is the number of bytes read. */
3423 3415
3424static Lisp_Object 3416static Lisp_Object
3425read_non_regular (Lisp_Object ignore) 3417read_non_regular (Lisp_Object state)
3426{ 3418{
3427 int nbytes; 3419 int nbytes;
3428 3420
3429 immediate_quit = 1; 3421 immediate_quit = 1;
3430 QUIT; 3422 QUIT;
3431 nbytes = emacs_read (non_regular_fd, 3423 nbytes = emacs_read (XSAVE_INTEGER (state, 0),
3432 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE 3424 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
3433 + non_regular_inserted), 3425 + XSAVE_INTEGER (state, 1)),
3434 non_regular_nbytes); 3426 XSAVE_INTEGER (state, 2));
3435 immediate_quit = 0; 3427 immediate_quit = 0;
3436 return make_number (nbytes); 3428 return make_number (nbytes);
3437} 3429}
@@ -4238,7 +4230,7 @@ by calling `format-decode', which see. */)
4238 while (how_much < total) 4230 while (how_much < total)
4239 { 4231 {
4240 /* try is reserved in some compilers (Microsoft C) */ 4232 /* try is reserved in some compilers (Microsoft C) */
4241 int trytry = min (total - how_much, READ_BUF_SIZE); 4233 ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE);
4242 ptrdiff_t this; 4234 ptrdiff_t this;
4243 4235
4244 if (not_regular) 4236 if (not_regular)
@@ -4255,12 +4247,11 @@ by calling `format-decode', which see. */)
4255 /* Read from the file, capturing `quit'. When an 4247 /* Read from the file, capturing `quit'. When an
4256 error occurs, end the loop, and arrange for a quit 4248 error occurs, end the loop, and arrange for a quit
4257 to be signaled after decoding the text we read. */ 4249 to be signaled after decoding the text we read. */
4258 non_regular_fd = fd; 4250 nbytes = internal_condition_case_1
4259 non_regular_inserted = inserted; 4251 (read_non_regular,
4260 non_regular_nbytes = trytry; 4252 format_save_value ("iii", (ptrdiff_t) fd, inserted, trytry),
4261 nbytes = internal_condition_case_1 (read_non_regular, 4253 Qerror, read_non_regular_quit);
4262 Qnil, Qerror, 4254
4263 read_non_regular_quit);
4264 if (NILP (nbytes)) 4255 if (NILP (nbytes))
4265 { 4256 {
4266 read_quit = 1; 4257 read_quit = 1;
@@ -5507,7 +5498,7 @@ static Lisp_Object
5507do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */ 5498do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */
5508 5499
5509{ 5500{
5510 FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer; 5501 FILE *stream = XSAVE_POINTER (arg, 0);
5511 auto_saving = 0; 5502 auto_saving = 0;
5512 if (stream != NULL) 5503 if (stream != NULL)
5513 { 5504 {
diff --git a/src/font.c b/src/font.c
index a3a41006f9b..89931f6ec76 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1857,7 +1857,7 @@ otf_open (Lisp_Object file)
1857 OTF *otf; 1857 OTF *otf;
1858 1858
1859 if (! NILP (val)) 1859 if (! NILP (val))
1860 otf = XSAVE_VALUE (XCDR (val))->pointer; 1860 otf = XSAVE_POINTER (XCDR (val), 0);
1861 else 1861 else
1862 { 1862 {
1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; 1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
diff --git a/src/ftfont.c b/src/ftfont.c
index 1ada95d377c..5bf91832c7c 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -393,16 +393,14 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
393 cache_data = xmalloc (sizeof *cache_data); 393 cache_data = xmalloc (sizeof *cache_data);
394 cache_data->ft_face = NULL; 394 cache_data->ft_face = NULL;
395 cache_data->fc_charset = NULL; 395 cache_data->fc_charset = NULL;
396 val = make_save_value (NULL, 0); 396 val = make_save_value (cache_data, 0);
397 XSAVE_VALUE (val)->integer = 0;
398 XSAVE_VALUE (val)->pointer = cache_data;
399 cache = Fcons (Qnil, val); 397 cache = Fcons (Qnil, val);
400 Fputhash (key, cache, ft_face_cache); 398 Fputhash (key, cache, ft_face_cache);
401 } 399 }
402 else 400 else
403 { 401 {
404 val = XCDR (cache); 402 val = XCDR (cache);
405 cache_data = XSAVE_VALUE (val)->pointer; 403 cache_data = XSAVE_POINTER (val, 0);
406 } 404 }
407 405
408 if (cache_for == FTFONT_CACHE_FOR_ENTITY) 406 if (cache_for == FTFONT_CACHE_FOR_ENTITY)
@@ -468,7 +466,7 @@ ftfont_get_fc_charset (Lisp_Object entity)
468 466
469 cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET); 467 cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET);
470 val = XCDR (cache); 468 val = XCDR (cache);
471 cache_data = XSAVE_VALUE (val)->pointer; 469 cache_data = XSAVE_POINTER (val, 0);
472 return cache_data->fc_charset; 470 return cache_data->fc_charset;
473} 471}
474 472
@@ -1200,9 +1198,9 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
1200 filename = XCAR (val); 1198 filename = XCAR (val);
1201 idx = XCDR (val); 1199 idx = XCDR (val);
1202 val = XCDR (cache); 1200 val = XCDR (cache);
1203 cache_data = XSAVE_VALUE (XCDR (cache))->pointer; 1201 cache_data = XSAVE_POINTER (XCDR (cache), 0);
1204 ft_face = cache_data->ft_face; 1202 ft_face = cache_data->ft_face;
1205 if (XSAVE_VALUE (val)->integer > 0) 1203 if (XSAVE_INTEGER (val, 1) > 0)
1206 { 1204 {
1207 /* FT_Face in this cache is already used by the different size. */ 1205 /* FT_Face in this cache is already used by the different size. */
1208 if (FT_New_Size (ft_face, &ft_size) != 0) 1206 if (FT_New_Size (ft_face, &ft_size) != 0)
@@ -1213,13 +1211,13 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
1213 return Qnil; 1211 return Qnil;
1214 } 1212 }
1215 } 1213 }
1216 XSAVE_VALUE (val)->integer++; 1214 XSAVE_INTEGER (val, 1)++;
1217 size = XINT (AREF (entity, FONT_SIZE_INDEX)); 1215 size = XINT (AREF (entity, FONT_SIZE_INDEX));
1218 if (size == 0) 1216 if (size == 0)
1219 size = pixel_size; 1217 size = pixel_size;
1220 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) 1218 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0)
1221 { 1219 {
1222 if (XSAVE_VALUE (val)->integer == 0) 1220 if (XSAVE_INTEGER (val, 1) == 0)
1223 FT_Done_Face (ft_face); 1221 FT_Done_Face (ft_face);
1224 return Qnil; 1222 return Qnil;
1225 } 1223 }
@@ -1328,10 +1326,10 @@ ftfont_close (FRAME_PTR f, struct font *font)
1328 cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE); 1326 cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE);
1329 eassert (CONSP (cache)); 1327 eassert (CONSP (cache));
1330 val = XCDR (cache); 1328 val = XCDR (cache);
1331 (XSAVE_VALUE (val)->integer)--; 1329 XSAVE_INTEGER (val, 1)--;
1332 if (XSAVE_VALUE (val)->integer == 0) 1330 if (XSAVE_INTEGER (val, 1) == 0)
1333 { 1331 {
1334 struct ftfont_cache_data *cache_data = XSAVE_VALUE (val)->pointer; 1332 struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0);
1335 1333
1336 FT_Done_Face (cache_data->ft_face); 1334 FT_Done_Face (cache_data->ft_face);
1337#ifdef HAVE_LIBOTF 1335#ifdef HAVE_LIBOTF
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 95ac04b8ff0..f045deacd33 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1650,8 +1650,7 @@ xg_dialog_response_cb (GtkDialog *w,
1650static Lisp_Object 1650static Lisp_Object
1651pop_down_dialog (Lisp_Object arg) 1651pop_down_dialog (Lisp_Object arg)
1652{ 1652{
1653 struct Lisp_Save_Value *p = XSAVE_VALUE (arg); 1653 struct xg_dialog_data *dd = XSAVE_POINTER (arg, 0);
1654 struct xg_dialog_data *dd = (struct xg_dialog_data *) p->pointer;
1655 1654
1656 block_input (); 1655 block_input ();
1657 if (dd->w) gtk_widget_destroy (dd->w); 1656 if (dd->w) gtk_widget_destroy (dd->w);
@@ -3795,13 +3794,17 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
3795 3794
3796 adj = gtk_range_get_adjustment (GTK_RANGE (wscroll)); 3795 adj = gtk_range_get_adjustment (GTK_RANGE (wscroll));
3797 3796
3798 /* We do the same as for MOTIF in xterm.c, assume 30 chars per line 3797 if (scroll_bar_adjust_thumb_portion_p)
3799 rather than the real portion value. This makes the thumb less likely 3798 {
3800 to resize and that looks better. */ 3799 /* We do the same as for MOTIF in xterm.c, use 30 chars per
3801 portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30; 3800 line rather than the real portion value. This makes the
3802 /* When the thumb is at the bottom, position == whole. 3801 thumb less likely to resize and that looks better. */
3803 So we need to increase `whole' to make space for the thumb. */ 3802 portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
3804 whole += portion; 3803
3804 /* When the thumb is at the bottom, position == whole.
3805 So we need to increase `whole' to make space for the thumb. */
3806 whole += portion;
3807 }
3805 3808
3806 if (whole <= 0) 3809 if (whole <= 0)
3807 top = 0, shown = 1; 3810 top = 0, shown = 1;
@@ -5041,7 +5044,9 @@ xg_initialize (void)
5041 "cancel", 0); 5044 "cancel", 0);
5042 update_theme_scrollbar_width (); 5045 update_theme_scrollbar_width ();
5043 5046
5047#ifdef HAVE_FREETYPE
5044 x_last_font_name = NULL; 5048 x_last_font_name = NULL;
5049#endif
5045} 5050}
5046 5051
5047#endif /* USE_GTK */ 5052#endif /* USE_GTK */
diff --git a/src/indent.c b/src/indent.c
index 4a30c00dd27..45b6afbd395 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1970,7 +1970,7 @@ whether or not it is currently displayed in some window. */)
1970 struct window *w; 1970 struct window *w;
1971 Lisp_Object old_buffer; 1971 Lisp_Object old_buffer;
1972 EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0); 1972 EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0);
1973 struct gcpro gcpro1, gcpro2, gcpro3; 1973 struct gcpro gcpro1;
1974 Lisp_Object lcols = Qnil; 1974 Lisp_Object lcols = Qnil;
1975 double cols IF_LINT (= 0); 1975 double cols IF_LINT (= 0);
1976 void *itdata = NULL; 1976 void *itdata = NULL;
@@ -1987,7 +1987,7 @@ whether or not it is currently displayed in some window. */)
1987 w = decode_live_window (window); 1987 w = decode_live_window (window);
1988 1988
1989 old_buffer = Qnil; 1989 old_buffer = Qnil;
1990 GCPRO3 (old_buffer, old_charpos, old_bytepos); 1990 GCPRO1 (old_buffer);
1991 if (XBUFFER (w->buffer) != current_buffer) 1991 if (XBUFFER (w->buffer) != current_buffer)
1992 { 1992 {
1993 /* Set the window's buffer temporarily to the current buffer. */ 1993 /* Set the window's buffer temporarily to the current buffer. */
diff --git a/src/insdel.c b/src/insdel.c
index 52a017a62a2..303247816ca 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -84,21 +84,14 @@ check_markers (void)
84 84
85#endif /* MARKER_DEBUG */ 85#endif /* MARKER_DEBUG */
86 86
87/* Move gap to position CHARPOS.
88 Note that this can quit! */
89
90void
91move_gap (ptrdiff_t charpos)
92{
93 move_gap_both (charpos, CHAR_TO_BYTE (charpos));
94}
95
96/* Move gap to byte position BYTEPOS, which is also char position CHARPOS. 87/* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
97 Note that this can quit! */ 88 Note that this can quit! */
98 89
99void 90void
100move_gap_both (ptrdiff_t charpos, ptrdiff_t bytepos) 91move_gap_both (ptrdiff_t charpos, ptrdiff_t bytepos)
101{ 92{
93 eassert (charpos == BYTE_TO_CHAR (bytepos)
94 && bytepos == CHAR_TO_BYTE (charpos));
102 if (bytepos < GPT_BYTE) 95 if (bytepos < GPT_BYTE)
103 gap_left (charpos, bytepos, 0); 96 gap_left (charpos, bytepos, 0);
104 else if (bytepos > GPT_BYTE) 97 else if (bytepos > GPT_BYTE)
@@ -388,14 +381,13 @@ make_gap_larger (ptrdiff_t nbytes_added)
388 ptrdiff_t real_gap_loc_byte; 381 ptrdiff_t real_gap_loc_byte;
389 ptrdiff_t old_gap_size; 382 ptrdiff_t old_gap_size;
390 ptrdiff_t current_size = Z_BYTE - BEG_BYTE + GAP_SIZE; 383 ptrdiff_t current_size = Z_BYTE - BEG_BYTE + GAP_SIZE;
391 enum { enough_for_a_while = 2000 };
392 384
393 if (BUF_BYTES_MAX - current_size < nbytes_added) 385 if (BUF_BYTES_MAX - current_size < nbytes_added)
394 buffer_overflow (); 386 buffer_overflow ();
395 387
396 /* If we have to get more space, get enough to last a while; 388 /* If we have to get more space, get enough to last a while;
397 but do not exceed the maximum buffer size. */ 389 but do not exceed the maximum buffer size. */
398 nbytes_added = min (nbytes_added + enough_for_a_while, 390 nbytes_added = min (nbytes_added + GAP_BYTES_DFL,
399 BUF_BYTES_MAX - current_size); 391 BUF_BYTES_MAX - current_size);
400 392
401 enlarge_buffer_text (current_buffer, nbytes_added); 393 enlarge_buffer_text (current_buffer, nbytes_added);
@@ -413,8 +405,7 @@ make_gap_larger (ptrdiff_t nbytes_added)
413 GPT_BYTE = Z_BYTE + GAP_SIZE; 405 GPT_BYTE = Z_BYTE + GAP_SIZE;
414 GAP_SIZE = nbytes_added; 406 GAP_SIZE = nbytes_added;
415 407
416 /* Move the new gap down to be consecutive with the end of the old one. 408 /* Move the new gap down to be consecutive with the end of the old one. */
417 This adjusts the markers properly too. */
418 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1); 409 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
419 410
420 /* Now combine the two into one large gap. */ 411 /* Now combine the two into one large gap. */
@@ -443,9 +434,9 @@ make_gap_smaller (ptrdiff_t nbytes_removed)
443 ptrdiff_t real_beg_unchanged; 434 ptrdiff_t real_beg_unchanged;
444 ptrdiff_t new_gap_size; 435 ptrdiff_t new_gap_size;
445 436
446 /* Make sure the gap is at least 20 bytes. */ 437 /* Make sure the gap is at least GAP_BYTES_MIN bytes. */
447 if (GAP_SIZE - nbytes_removed < 20) 438 if (GAP_SIZE - nbytes_removed < GAP_BYTES_MIN)
448 nbytes_removed = GAP_SIZE - 20; 439 nbytes_removed = GAP_SIZE - GAP_BYTES_MIN;
449 440
450 /* Prevent quitting in move_gap. */ 441 /* Prevent quitting in move_gap. */
451 tem = Vinhibit_quit; 442 tem = Vinhibit_quit;
@@ -468,8 +459,7 @@ make_gap_smaller (ptrdiff_t nbytes_removed)
468 Z_BYTE += new_gap_size; 459 Z_BYTE += new_gap_size;
469 GAP_SIZE = nbytes_removed; 460 GAP_SIZE = nbytes_removed;
470 461
471 /* Move the unwanted pretend gap to the end of the buffer. This 462 /* Move the unwanted pretend gap to the end of the buffer. */
472 adjusts the markers properly too. */
473 gap_right (Z, Z_BYTE); 463 gap_right (Z, Z_BYTE);
474 464
475 enlarge_buffer_text (current_buffer, -nbytes_removed); 465 enlarge_buffer_text (current_buffer, -nbytes_removed);
@@ -500,7 +490,20 @@ make_gap (ptrdiff_t nbytes_added)
500 make_gap_smaller (-nbytes_added); 490 make_gap_smaller (-nbytes_added);
501#endif 491#endif
502} 492}
503 493
494/* Add NBYTES to B's gap. It's enough to temporarily
495 fake current_buffer and avoid real switch to B. */
496
497void
498make_gap_1 (struct buffer *b, ptrdiff_t nbytes)
499{
500 struct buffer *oldb = current_buffer;
501
502 current_buffer = b;
503 make_gap (nbytes);
504 current_buffer = oldb;
505}
506
504/* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR. 507/* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
505 FROM_MULTIBYTE says whether the incoming text is multibyte. 508 FROM_MULTIBYTE says whether the incoming text is multibyte.
506 TO_MULTIBYTE says whether to store the text as multibyte. 509 TO_MULTIBYTE says whether to store the text as multibyte.
@@ -2081,7 +2084,7 @@ Fcombine_after_change_execute_1 (Lisp_Object val)
2081 2084
2082DEFUN ("combine-after-change-execute", Fcombine_after_change_execute, 2085DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2083 Scombine_after_change_execute, 0, 0, 0, 2086 Scombine_after_change_execute, 0, 0, 0,
2084 doc: /* This function is for use internally in `combine-after-change-calls'. */) 2087 doc: /* This function is for use internally in the function `combine-after-change-calls'. */)
2085 (void) 2088 (void)
2086{ 2089{
2087 ptrdiff_t count = SPECPDL_INDEX (); 2090 ptrdiff_t count = SPECPDL_INDEX ();
@@ -2173,7 +2176,7 @@ syms_of_insdel (void)
2173 combine_after_change_buffer = Qnil; 2176 combine_after_change_buffer = Qnil;
2174 2177
2175 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls, 2178 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls,
2176 doc: /* Used internally by the `combine-after-change-calls' macro. */); 2179 doc: /* Used internally by the function `combine-after-change-calls' macro. */);
2177 Vcombine_after_change_calls = Qnil; 2180 Vcombine_after_change_calls = Qnil;
2178 2181
2179 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks, 2182 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks,
diff --git a/src/keyboard.c b/src/keyboard.c
index 8edd705135f..7594a4f72fc 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -497,97 +497,103 @@ kset_system_key_syms (struct kboard *kb, Lisp_Object val)
497} 497}
498 498
499 499
500/* Add C to the echo string, if echoing is going on. 500/* Add C to the echo string, without echoing it immediately. C can be
501 C can be a character, which is printed prettily ("M-C-x" and all that 501 a character, which is pretty-printed, or a symbol, whose name is
502 jazz), or a symbol, whose name is printed. */ 502 printed. */
503 503
504static void 504static void
505echo_char (Lisp_Object c) 505echo_add_key (Lisp_Object c)
506{ 506{
507 if (current_kboard->immediate_echo) 507 int size = KEY_DESCRIPTION_SIZE + 100;
508 { 508 char *buffer = alloca (size);
509 int size = KEY_DESCRIPTION_SIZE + 100; 509 char *ptr = buffer;
510 char *buffer = alloca (size); 510 Lisp_Object echo_string;
511 char *ptr = buffer;
512 Lisp_Object echo_string;
513 511
514 echo_string = KVAR (current_kboard, echo_string); 512 echo_string = KVAR (current_kboard, echo_string);
515 513
516 /* If someone has passed us a composite event, use its head symbol. */ 514 /* If someone has passed us a composite event, use its head symbol. */
517 c = EVENT_HEAD (c); 515 c = EVENT_HEAD (c);
518 516
519 if (INTEGERP (c)) 517 if (INTEGERP (c))
518 ptr = push_key_description (XINT (c), ptr);
519 else if (SYMBOLP (c))
520 {
521 Lisp_Object name = SYMBOL_NAME (c);
522 int nbytes = SBYTES (name);
523
524 if (size - (ptr - buffer) < nbytes)
520 { 525 {
521 ptr = push_key_description (XINT (c), ptr); 526 int offset = ptr - buffer;
527 size = max (2 * size, size + nbytes);
528 buffer = alloca (size);
529 ptr = buffer + offset;
522 } 530 }
523 else if (SYMBOLP (c))
524 {
525 Lisp_Object name = SYMBOL_NAME (c);
526 int nbytes = SBYTES (name);
527 531
528 if (size - (ptr - buffer) < nbytes) 532 ptr += copy_text (SDATA (name), (unsigned char *) ptr, nbytes,
529 { 533 STRING_MULTIBYTE (name), 1);
530 int offset = ptr - buffer; 534 }
531 size = max (2 * size, size + nbytes);
532 buffer = alloca (size);
533 ptr = buffer + offset;
534 }
535 535
536 ptr += copy_text (SDATA (name), (unsigned char *) ptr, nbytes, 536 if ((NILP (echo_string) || SCHARS (echo_string) == 0)
537 STRING_MULTIBYTE (name), 1); 537 && help_char_p (c))
538 } 538 {
539 const char *text = " (Type ? for further options)";
540 int len = strlen (text);
539 541
540 if ((NILP (echo_string) || SCHARS (echo_string) == 0) 542 if (size - (ptr - buffer) < len)
541 && help_char_p (c))
542 { 543 {
543 const char *text = " (Type ? for further options)"; 544 int offset = ptr - buffer;
544 int len = strlen (text); 545 size += len;
545 546 buffer = alloca (size);
546 if (size - (ptr - buffer) < len) 547 ptr = buffer + offset;
547 {
548 int offset = ptr - buffer;
549 size += len;
550 buffer = alloca (size);
551 ptr = buffer + offset;
552 }
553
554 memcpy (ptr, text, len);
555 ptr += len;
556 } 548 }
557 549
558 /* Replace a dash from echo_dash with a space, otherwise 550 memcpy (ptr, text, len);
559 add a space at the end as a separator between keys. */ 551 ptr += len;
560 if (STRINGP (echo_string) 552 }
561 && SCHARS (echo_string) > 1)
562 {
563 Lisp_Object last_char, prev_char, idx;
564 553
565 idx = make_number (SCHARS (echo_string) - 2); 554 /* Replace a dash from echo_dash with a space, otherwise add a space
566 prev_char = Faref (echo_string, idx); 555 at the end as a separator between keys. */
556 if (STRINGP (echo_string) && SCHARS (echo_string) > 1)
557 {
558 Lisp_Object last_char, prev_char, idx;
567 559
568 idx = make_number (SCHARS (echo_string) - 1); 560 idx = make_number (SCHARS (echo_string) - 2);
569 last_char = Faref (echo_string, idx); 561 prev_char = Faref (echo_string, idx);
570 562
571 /* We test PREV_CHAR to make sure this isn't the echoing 563 idx = make_number (SCHARS (echo_string) - 1);
572 of a minus-sign. */ 564 last_char = Faref (echo_string, idx);
573 if (XINT (last_char) == '-' && XINT (prev_char) != ' ') 565
574 Faset (echo_string, idx, make_number (' ')); 566 /* We test PREV_CHAR to make sure this isn't the echoing of a
575 else 567 minus-sign. */
576 echo_string = concat2 (echo_string, build_string (" ")); 568 if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
577 } 569 Faset (echo_string, idx, make_number (' '));
578 else if (STRINGP (echo_string)) 570 else
579 echo_string = concat2 (echo_string, build_string (" ")); 571 echo_string = concat2 (echo_string, build_string (" "));
572 }
573 else if (STRINGP (echo_string) && SCHARS (echo_string) > 0)
574 echo_string = concat2 (echo_string, build_string (" "));
580 575
581 kset_echo_string 576 kset_echo_string
582 (current_kboard, 577 (current_kboard,
583 concat2 (echo_string, make_string (buffer, ptr - buffer))); 578 concat2 (echo_string, make_string (buffer, ptr - buffer)));
579}
580
581/* Add C to the echo string, if echoing is going on. C can be a
582 character or a symbol. */
584 583
584static void
585echo_char (Lisp_Object c)
586{
587 if (current_kboard->immediate_echo)
588 {
589 echo_add_key (c);
585 echo_now (); 590 echo_now ();
586 } 591 }
587} 592}
588 593
589/* Temporarily add a dash to the end of the echo string if it's not 594/* Temporarily add a dash to the end of the echo string if it's not
590 empty, so that it serves as a mini-prompt for the very next character. */ 595 empty, so that it serves as a mini-prompt for the very next
596 character. */
591 597
592static void 598static void
593echo_dash (void) 599echo_dash (void)
@@ -9218,8 +9224,12 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9218 key = keybuf[t]; 9224 key = keybuf[t];
9219 add_command_key (key); 9225 add_command_key (key);
9220 if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes)) 9226 if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
9221 && NILP (Fzerop (Vecho_keystrokes))) 9227 && NILP (Fzerop (Vecho_keystrokes))
9222 echo_char (key); 9228 && current_kboard->immediate_echo)
9229 {
9230 echo_add_key (key);
9231 echo_dash ();
9232 }
9223 } 9233 }
9224 9234
9225 /* If not, we should actually read a character. */ 9235 /* If not, we should actually read a character. */
@@ -10160,7 +10170,7 @@ DEFUN ("command-execute", Fcommand_execute, Scommand_execute, 1, 4, 0,
10160 doc: /* Execute CMD as an editor command. 10170 doc: /* Execute CMD as an editor command.
10161CMD must be a symbol that satisfies the `commandp' predicate. 10171CMD must be a symbol that satisfies the `commandp' predicate.
10162Optional second arg RECORD-FLAG non-nil 10172Optional second arg RECORD-FLAG non-nil
10163means unconditionally put this command in `command-history'. 10173means unconditionally put this command in the variable `command-history'.
10164Otherwise, that is done only if an arg is read using the minibuffer. 10174Otherwise, that is done only if an arg is read using the minibuffer.
10165The argument KEYS specifies the value to use instead of (this-command-keys) 10175The argument KEYS specifies the value to use instead of (this-command-keys)
10166when reading the arguments; if it is nil, (this-command-keys) is used. 10176when reading the arguments; if it is nil, (this-command-keys) is used.
@@ -12045,8 +12055,8 @@ This takes effect only when Transient Mark mode is enabled. */);
12045 Vsaved_region_selection, 12055 Vsaved_region_selection,
12046 doc: /* Contents of active region prior to buffer modification. 12056 doc: /* Contents of active region prior to buffer modification.
12047If `select-active-regions' is non-nil, Emacs sets this to the 12057If `select-active-regions' is non-nil, Emacs sets this to the
12048text in the region before modifying the buffer. The next 12058text in the region before modifying the buffer. The next call to
12049`deactivate-mark' call uses this to set the window selection. */); 12059the function `deactivate-mark' uses this to set the window selection. */);
12050 Vsaved_region_selection = Qnil; 12060 Vsaved_region_selection = Qnil;
12051 12061
12052 DEFVAR_LISP ("selection-inhibit-update-commands", 12062 DEFVAR_LISP ("selection-inhibit-update-commands",
diff --git a/src/keymap.c b/src/keymap.c
index d1ddd55a358..a9266120e86 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -565,15 +565,13 @@ map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val)
565{ 565{
566 if (!NILP (val)) 566 if (!NILP (val))
567 { 567 {
568 map_keymap_function_t fun 568 map_keymap_function_t fun = XSAVE_POINTER (args, 0);
569 = (map_keymap_function_t) XSAVE_VALUE (XCAR (args))->pointer;
570 args = XCDR (args);
571 /* If the key is a range, make a copy since map_char_table modifies 569 /* If the key is a range, make a copy since map_char_table modifies
572 it in place. */ 570 it in place. */
573 if (CONSP (key)) 571 if (CONSP (key))
574 key = Fcons (XCAR (key), XCDR (key)); 572 key = Fcons (XCAR (key), XCDR (key));
575 map_keymap_item (fun, XCDR (args), key, val, 573 map_keymap_item (fun, XSAVE_OBJECT (args, 2), key,
576 XSAVE_VALUE (XCAR (args))->pointer); 574 val, XSAVE_POINTER (args, 1));
577 } 575 }
578} 576}
579 577
@@ -611,12 +609,8 @@ map_keymap_internal (Lisp_Object map,
611 } 609 }
612 } 610 }
613 else if (CHAR_TABLE_P (binding)) 611 else if (CHAR_TABLE_P (binding))
614 { 612 map_char_table (map_keymap_char_table_item, Qnil, binding,
615 map_char_table (map_keymap_char_table_item, Qnil, binding, 613 format_save_value ("ppo", fun, data, args));
616 Fcons (make_save_value ((void *) fun, 0),
617 Fcons (make_save_value (data, 0),
618 args)));
619 }
620 } 614 }
621 UNGCPRO; 615 UNGCPRO;
622 return tail; 616 return tail;
diff --git a/src/lisp.h b/src/lisp.h
index e96c9664743..9cebdef2b20 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1389,20 +1389,60 @@ struct Lisp_Overlay
1389 Lisp_Object plist; 1389 Lisp_Object plist;
1390 }; 1390 };
1391 1391
1392/* Hold a C pointer for later use. 1392/* Types of data which may be saved in a Lisp_Save_Value. */
1393 This type of object is used in the arg to record_unwind_protect. */ 1393
1394enum
1395 {
1396 SAVE_UNUSED,
1397 SAVE_INTEGER,
1398 SAVE_POINTER,
1399 SAVE_OBJECT
1400 };
1401
1402/* Special object used to hold a different values for later use. */
1403
1394struct Lisp_Save_Value 1404struct Lisp_Save_Value
1395 { 1405 {
1396 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ 1406 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */
1397 unsigned gcmarkbit : 1; 1407 unsigned gcmarkbit : 1;
1398 int spacer : 14; 1408 int spacer : 6;
1399 /* If DOGC is set, POINTER is the address of a memory 1409 /* If `area' is nonzero, `data[0].pointer' is the address of a memory area
1400 area containing INTEGER potential Lisp_Objects. */ 1410 containing `data[1].integer' potential Lisp_Objects. The rest of `data'
1401 unsigned int dogc : 1; 1411 fields are unused. */
1402 void *pointer; 1412 unsigned area : 1;
1403 ptrdiff_t integer; 1413 /* If `area' is zero, `data[N]' may hold different objects which type is
1414 encoded in `typeN' fields as described by the anonymous enum above.
1415 E.g. if `type0' is SAVE_INTEGER, `data[0].integer' is in use. */
1416 unsigned type0 : 2;
1417 unsigned type1 : 2;
1418 unsigned type2 : 2;
1419 unsigned type3 : 2;
1420 union {
1421 void *pointer;
1422 ptrdiff_t integer;
1423 Lisp_Object object;
1424 } data[4];
1404 }; 1425 };
1405 1426
1427/* Macro to set and extract Nth saved pointer. Type
1428 checking is ugly because it's used as an lvalue. */
1429
1430#define XSAVE_POINTER(obj, n) \
1431 XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
1432 ## n == SAVE_POINTER), n)].pointer
1433
1434/* Likewise for the saved integer. */
1435
1436#define XSAVE_INTEGER(obj, n) \
1437 XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
1438 ## n == SAVE_INTEGER), n)].integer
1439
1440/* Macro to extract Nth saved object. This is never used as
1441 an lvalue, so we can do more convenient type checking. */
1442
1443#define XSAVE_OBJECT(obj, n) \
1444 (eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT), \
1445 XSAVE_VALUE (obj)->data[n].object)
1406 1446
1407/* A miscellaneous object, when it's on the free list. */ 1447/* A miscellaneous object, when it's on the free list. */
1408struct Lisp_Free 1448struct Lisp_Free
@@ -1461,7 +1501,8 @@ struct Lisp_Buffer_Objfwd
1461 { 1501 {
1462 enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Buffer_Obj */ 1502 enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Buffer_Obj */
1463 int offset; 1503 int offset;
1464 Lisp_Object slottype; /* Qnil, Lisp_Int, Lisp_Symbol, or Lisp_String. */ 1504 /* One of Qnil, Qintegerp, Qsymbolp, Qstringp, Qfloatp or Qnumberp. */
1505 Lisp_Object predicate;
1465 }; 1506 };
1466 1507
1467/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when 1508/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
@@ -2231,8 +2272,12 @@ struct gcpro
2231 2 Mark the stack, and check that everything GCPRO'd is 2272 2 Mark the stack, and check that everything GCPRO'd is
2232 marked. 2273 marked.
2233 3 Mark using GCPRO's, mark stack last, and count how many 2274 3 Mark using GCPRO's, mark stack last, and count how many
2234 dead objects are kept alive. */ 2275 dead objects are kept alive.
2235 2276
2277 Formerly, method 0 was used. Currently, method 1 is used unless
2278 otherwise specified by hand when building, e.g.,
2279 "make CPPFLAGS='-DGC_MARK_STACK=GC_USE_GCPROS_AS_BEFORE'".
2280 Methods 2 and 3 are present mainly to debug the transition from 0 to 1. */
2236 2281
2237#define GC_USE_GCPROS_AS_BEFORE 0 2282#define GC_USE_GCPROS_AS_BEFORE 0
2238#define GC_MAKE_GCPROS_NOOPS 1 2283#define GC_MAKE_GCPROS_NOOPS 1
@@ -2788,10 +2833,10 @@ extern void syms_of_image (void);
2788 2833
2789/* Defined in insdel.c. */ 2834/* Defined in insdel.c. */
2790extern Lisp_Object Qinhibit_modification_hooks; 2835extern Lisp_Object Qinhibit_modification_hooks;
2791extern void move_gap (ptrdiff_t);
2792extern void move_gap_both (ptrdiff_t, ptrdiff_t); 2836extern void move_gap_both (ptrdiff_t, ptrdiff_t);
2793extern _Noreturn void buffer_overflow (void); 2837extern _Noreturn void buffer_overflow (void);
2794extern void make_gap (ptrdiff_t); 2838extern void make_gap (ptrdiff_t);
2839extern void make_gap_1 (struct buffer *, ptrdiff_t);
2795extern ptrdiff_t copy_text (const unsigned char *, unsigned char *, 2840extern ptrdiff_t copy_text (const unsigned char *, unsigned char *,
2796 ptrdiff_t, bool, bool); 2841 ptrdiff_t, bool, bool);
2797extern int count_combining_before (const unsigned char *, 2842extern int count_combining_before (const unsigned char *,
@@ -2902,6 +2947,7 @@ extern void memory_warnings (void *, void (*warnfun) (const char *));
2902 2947
2903/* Defined in alloc.c. */ 2948/* Defined in alloc.c. */
2904extern void check_pure_size (void); 2949extern void check_pure_size (void);
2950extern void free_misc (Lisp_Object);
2905extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); 2951extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
2906extern void malloc_warning (const char *); 2952extern void malloc_warning (const char *);
2907extern _Noreturn void memory_full (size_t); 2953extern _Noreturn void memory_full (size_t);
@@ -2989,8 +3035,8 @@ extern bool abort_on_gc;
2989extern Lisp_Object make_float (double); 3035extern Lisp_Object make_float (double);
2990extern void display_malloc_warning (void); 3036extern void display_malloc_warning (void);
2991extern ptrdiff_t inhibit_garbage_collection (void); 3037extern ptrdiff_t inhibit_garbage_collection (void);
3038extern Lisp_Object format_save_value (const char *, ...);
2992extern Lisp_Object make_save_value (void *, ptrdiff_t); 3039extern Lisp_Object make_save_value (void *, ptrdiff_t);
2993extern void free_save_value (Lisp_Object);
2994extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 3040extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
2995extern void free_marker (Lisp_Object); 3041extern void free_marker (Lisp_Object);
2996extern void free_cons (struct Lisp_Cons *); 3042extern void free_cons (struct Lisp_Cons *);
@@ -3479,6 +3525,8 @@ extern void init_sigio (int);
3479extern void sys_subshell (void); 3525extern void sys_subshell (void);
3480extern void sys_suspend (void); 3526extern void sys_suspend (void);
3481extern void discard_tty_input (void); 3527extern void discard_tty_input (void);
3528extern void block_tty_out_signal (void);
3529extern void unblock_tty_out_signal (void);
3482extern void init_sys_modes (struct tty_display_info *); 3530extern void init_sys_modes (struct tty_display_info *);
3483extern void reset_sys_modes (struct tty_display_info *); 3531extern void reset_sys_modes (struct tty_display_info *);
3484extern void init_all_sys_modes (void); 3532extern void init_all_sys_modes (void);
@@ -3707,7 +3755,7 @@ extern void *record_xmalloc (size_t);
3707 Lisp_Object arg_; \ 3755 Lisp_Object arg_; \
3708 buf = xmalloc ((nelt) * word_size); \ 3756 buf = xmalloc ((nelt) * word_size); \
3709 arg_ = make_save_value (buf, nelt); \ 3757 arg_ = make_save_value (buf, nelt); \
3710 XSAVE_VALUE (arg_)->dogc = 1; \ 3758 XSAVE_VALUE (arg_)->area = 1; \
3711 sa_must_free = 1; \ 3759 sa_must_free = 1; \
3712 record_unwind_protect (safe_alloca_unwind, arg_); \ 3760 record_unwind_protect (safe_alloca_unwind, arg_); \
3713 } \ 3761 } \
diff --git a/src/lread.c b/src/lread.c
index 2b96dc16359..a01cf099b49 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1357,7 +1357,7 @@ Return t if the file exists and loads successfully. */)
1357static Lisp_Object 1357static Lisp_Object
1358load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */ 1358load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */
1359{ 1359{
1360 FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer; 1360 FILE *stream = XSAVE_POINTER (arg, 0);
1361 if (stream != NULL) 1361 if (stream != NULL)
1362 { 1362 {
1363 block_input (); 1363 block_input ();
diff --git a/src/nsfns.m b/src/nsfns.m
index 1750eb62cdf..fac61d2ab53 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1503,12 +1503,12 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1503 [panel setDelegate: fileDelegate]; 1503 [panel setDelegate: fileDelegate];
1504 1504
1505 panelOK = 0; 1505 panelOK = 0;
1506 if (! NILP (dir_only_p)) 1506 if (! NILP (dir_only_p))
1507 { 1507 {
1508 [panel setCanChooseDirectories: YES]; 1508 [panel setCanChooseDirectories: YES];
1509 [panel setCanChooseFiles: NO]; 1509 [panel setCanChooseFiles: NO];
1510 } 1510 }
1511 1511
1512 block_input (); 1512 block_input ();
1513#if defined (NS_IMPL_COCOA) && \ 1513#if defined (NS_IMPL_COCOA) && \
1514 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 1514 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
@@ -1519,7 +1519,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1519 [panel setNameFieldStringValue: [initS lastPathComponent]]; 1519 [panel setNameFieldStringValue: [initS lastPathComponent]];
1520 else 1520 else
1521 [panel setNameFieldStringValue: @""]; 1521 [panel setNameFieldStringValue: @""];
1522 1522
1523 ret = [panel runModal]; 1523 ret = [panel runModal];
1524#else 1524#else
1525 if (NILP (mustmatch) && NILP (dir_only_p)) 1525 if (NILP (mustmatch) && NILP (dir_only_p))
@@ -2147,7 +2147,7 @@ In case the execution fails, an error is signaled. */)
2147 [NSApp postEvent: nxev atStart: NO]; 2147 [NSApp postEvent: nxev atStart: NO];
2148 2148
2149 // If there are other events, the event loop may exit. Keep running 2149 // If there are other events, the event loop may exit. Keep running
2150 // until the script has been handeled. */ 2150 // until the script has been handled. */
2151 while (! NILP (as_script)) 2151 while (! NILP (as_script))
2152 [NSApp run]; 2152 [NSApp run];
2153 2153
diff --git a/src/nsfont.m b/src/nsfont.m
index c0bea2e225c..5039f0c9013 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -44,6 +44,7 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu)
44#endif 44#endif
45 45
46#define NSFONT_TRACE 0 46#define NSFONT_TRACE 0
47#define LCD_SMOOTHING_MARGIN 2
47 48
48extern Lisp_Object Qns; 49extern Lisp_Object Qns;
49extern Lisp_Object Qnormal, Qbold, Qitalic; 50extern Lisp_Object Qnormal, Qbold, Qitalic;
@@ -546,6 +547,7 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
546 NSSet *cFamilies; 547 NSSet *cFamilies;
547 BOOL foundItal = NO; 548 BOOL foundItal = NO;
548 549
550 block_input ();
549 if (NSFONT_TRACE) 551 if (NSFONT_TRACE)
550 { 552 {
551 fprintf (stderr, "nsfont: %s for fontspec:\n ", 553 fprintf (stderr, "nsfont: %s for fontspec:\n ",
@@ -560,10 +562,7 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
560 if (isMatch) 562 if (isMatch)
561 [fkeys removeObject: NSFontFamilyAttribute]; 563 [fkeys removeObject: NSFontFamilyAttribute];
562 564
563 if ([fkeys count] > 0) 565 matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
564 matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
565 else
566 matchingDescs = [NSMutableArray array];
567 566
568 if (NSFONT_TRACE) 567 if (NSFONT_TRACE)
569 NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc, 568 NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc,
@@ -598,6 +597,8 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
598 [s1 release]; 597 [s1 release];
599 } 598 }
600 599
600 unblock_input ();
601
601 /* Return something if was a match and nothing found. */ 602 /* Return something if was a match and nothing found. */
602 if (isMatch) 603 if (isMatch)
603 return ns_fallback_entity (); 604 return ns_fallback_entity ();
@@ -701,10 +702,12 @@ static Lisp_Object
701nsfont_list_family (Lisp_Object frame) 702nsfont_list_family (Lisp_Object frame)
702{ 703{
703 Lisp_Object list = Qnil; 704 Lisp_Object list = Qnil;
704 NSEnumerator *families = 705 NSEnumerator *families;
705 [[[NSFontManager sharedFontManager] availableFontFamilies]
706 objectEnumerator];
707 NSString *family; 706 NSString *family;
707
708 block_input ();
709 families = [[[NSFontManager sharedFontManager] availableFontFamilies]
710 objectEnumerator];
708 while ((family = [families nextObject])) 711 while ((family = [families nextObject]))
709 list = Fcons (intern ([family UTF8String]), list); 712 list = Fcons (intern ([family UTF8String]), list);
710 /* FIXME: escape the name? */ 713 /* FIXME: escape the name? */
@@ -713,6 +716,7 @@ nsfont_list_family (Lisp_Object frame)
713 fprintf (stderr, "nsfont: list families returning %"pI"d entries\n", 716 fprintf (stderr, "nsfont: list families returning %"pI"d entries\n",
714 XINT (Flength (list))); 717 XINT (Flength (list)));
715 718
719 unblock_input ();
716 return list; 720 return list;
717} 721}
718 722
@@ -735,6 +739,8 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
735 Lisp_Object font_object; 739 Lisp_Object font_object;
736 int fixLeopardBug; 740 int fixLeopardBug;
737 741
742 block_input ();
743
738 if (NSFONT_TRACE) 744 if (NSFONT_TRACE)
739 { 745 {
740 fprintf (stderr, "nsfont: open size %d of fontentity:\n ", pixel_size); 746 fprintf (stderr, "nsfont: open size %d of fontentity:\n ", pixel_size);
@@ -794,13 +800,14 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
794 font_info = (struct nsfont_info *) XFONT_OBJECT (font_object); 800 font_info = (struct nsfont_info *) XFONT_OBJECT (font_object);
795 font = (struct font *) font_info; 801 font = (struct font *) font_info;
796 if (!font) 802 if (!font)
797 return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */ 803 {
804 unblock_input ();
805 return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */
806 }
798 807
799 font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs); 808 font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
800 font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics); 809 font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics);
801 810
802 block_input ();
803
804 /* for metrics */ 811 /* for metrics */
805#ifdef NS_IMPL_COCOA 812#ifdef NS_IMPL_COCOA
806 sfont = [nsfont screenFontWithRenderingMode: 813 sfont = [nsfont screenFontWithRenderingMode:
@@ -1051,6 +1058,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1051 char isComposite = s->first_glyph->type == COMPOSITE_GLYPH; 1058 char isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
1052 int end = isComposite ? s->cmp_to : s->nchars; 1059 int end = isComposite ? s->cmp_to : s->nchars;
1053 1060
1061 block_input ();
1054 /* Select face based on input flags */ 1062 /* Select face based on input flags */
1055 switch (ns_tmp_flags) 1063 switch (ns_tmp_flags)
1056 { 1064 {
@@ -1240,7 +1248,6 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1240 else 1248 else
1241 CGContextSetShouldAntialias (gcontext, 1); 1249 CGContextSetShouldAntialias (gcontext, 1);
1242 1250
1243 CGContextSetShouldSmoothFonts (gcontext, NO);
1244 CGContextSetTextMatrix (gcontext, fliptf); 1251 CGContextSetTextMatrix (gcontext, fliptf);
1245 1252
1246 if (bgCol != nil) 1253 if (bgCol != nil)
@@ -1273,6 +1280,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1273 /* Draw underline, overline, strike-through. */ 1280 /* Draw underline, overline, strike-through. */
1274 ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x); 1281 ns_draw_text_decoration (s, face, col, r.size.width, r.origin.x);
1275 1282
1283 unblock_input ();
1276 return to-from; 1284 return to-from;
1277} 1285}
1278 1286
@@ -1406,11 +1414,12 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
1406 1414
1407 lb = r.origin.x; 1415 lb = r.origin.x;
1408 rb = r.size.width - w; 1416 rb = r.size.width - w;
1417 // Add to bearing for LCD smoothing. We don't know if it is there.
1409 if (lb < 0) 1418 if (lb < 0)
1410 metrics->lbearing = round (lb); 1419 metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN);
1411 if (font_info->ital) 1420 if (font_info->ital)
1412 rb += 0.22 * font_info->height; 1421 rb += 0.22 * font_info->height;
1413 metrics->rbearing = lrint (w + rb); 1422 metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN);
1414 1423
1415 metrics->descent = r.origin.y < 0 ? -r.origin.y : 0; 1424 metrics->descent = r.origin.y < 0 ? -r.origin.y : 0;
1416 /*lrint (hshrink * [sfont ascender] + expand * hd/2); */ 1425 /*lrint (hshrink * [sfont ascender] + expand * hd/2); */
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 39797d414f0..b0369e76a27 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1347,8 +1347,7 @@ struct Popdown_data
1347static Lisp_Object 1347static Lisp_Object
1348pop_down_menu (Lisp_Object arg) 1348pop_down_menu (Lisp_Object arg)
1349{ 1349{
1350 struct Lisp_Save_Value *p = XSAVE_VALUE (arg); 1350 struct Popdown_data *unwind_data = XSAVE_POINTER (arg, 0);
1351 struct Popdown_data *unwind_data = (struct Popdown_data *) p->pointer;
1352 1351
1353 block_input (); 1352 block_input ();
1354 if (popup_activated_flag) 1353 if (popup_activated_flag)
diff --git a/src/nsterm.h b/src/nsterm.h
index e58b8493c94..0cf4aa60d08 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -675,9 +675,9 @@ struct x_output
675#define FRAME_FONT(f) ((f)->output_data.ns->font) 675#define FRAME_FONT(f) ((f)->output_data.ns->font)
676 676
677#ifdef __OBJC__ 677#ifdef __OBJC__
678#define XNS_SCROLL_BAR(vec) ((id) XSAVE_VALUE (vec)->pointer) 678#define XNS_SCROLL_BAR(vec) ((id) XSAVE_POINTER (vec, 0))
679#else 679#else
680#define XNS_SCROLL_BAR(vec) XSAVE_VALUE (vec)->pointer 680#define XNS_SCROLL_BAR(vec) XSAVE_POINTER (vec, 0)
681#endif 681#endif
682 682
683/* Compute pixel size for vertical scroll bars */ 683/* Compute pixel size for vertical scroll bars */
diff --git a/src/nsterm.m b/src/nsterm.m
index 0fd062b7f17..48efac3f70b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4981,6 +4981,7 @@ not_in_argv (NSString *arg)
4981 4981
4982 emacs_event->code = code; 4982 emacs_event->code = code;
4983 EV_TRAILER (theEvent); 4983 EV_TRAILER (theEvent);
4984 processingCompose = NO;
4984 return; 4985 return;
4985 } 4986 }
4986 } 4987 }
@@ -5171,6 +5172,7 @@ not_in_argv (NSString *arg)
5171 if (NS_KEYLOG) 5172 if (NS_KEYLOG)
5172 NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector)); 5173 NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector));
5173 5174
5175 processingCompose = NO;
5174 if (aSelector == @selector (deleteBackward:)) 5176 if (aSelector == @selector (deleteBackward:))
5175 { 5177 {
5176 /* happens when user backspaces over an ongoing composition: 5178 /* happens when user backspaces over an ongoing composition:
diff --git a/src/print.c b/src/print.c
index 2ffe7def396..62009e17686 100644
--- a/src/print.c
+++ b/src/print.c
@@ -2063,8 +2063,9 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
2063 PRINTCHAR ('>'); 2063 PRINTCHAR ('>');
2064 break; 2064 break;
2065 2065
2066 /* Remaining cases shouldn't happen in normal usage, but let's print 2066 /* Remaining cases shouldn't happen in normal usage, but let's
2067 them anyway for the benefit of the debugger. */ 2067 print them anyway for the benefit of the debugger. */
2068
2068 case Lisp_Misc_Free: 2069 case Lisp_Misc_Free:
2069 strout ("#<misc free cell>", -1, -1, printcharfun); 2070 strout ("#<misc free cell>", -1, -1, printcharfun);
2070 break; 2071 break;
@@ -2075,20 +2076,28 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
2075 struct Lisp_Save_Value *v = XSAVE_VALUE (obj); 2076 struct Lisp_Save_Value *v = XSAVE_VALUE (obj);
2076 2077
2077 strout ("#<save-value ", -1, -1, printcharfun); 2078 strout ("#<save-value ", -1, -1, printcharfun);
2078 if (v->dogc) 2079
2080 if (v->area)
2079 { 2081 {
2080 int lim = min (v->integer, 8); 2082 ptrdiff_t amount = v->data[1].integer;
2081 2083
2082 /* Try to print up to 8 objects we have saved. Although 2084#if GC_MARK_STACK
2083 valid_lisp_object_p is slow, this shouldn't be a real 2085
2084 bottleneck because such a saved values are quite rare. */ 2086 /* If GC_MARK_STACK, valid_lisp_object_p is quite reliable,
2087 and so we try to print up to 8 objects we have saved.
2088 Although valid_lisp_object_p is slow, this shouldn't be
2089 a real bottleneck because we do not use this code under
2090 normal circumstances. */
2085 2091
2086 i = sprintf (buf, "with %"pD"d objects", v->integer); 2092 int limit = min (amount, 8);
2093 Lisp_Object *area = v->data[0].pointer;
2094
2095 i = sprintf (buf, "with %"pD"d objects", amount);
2087 strout (buf, i, i, printcharfun); 2096 strout (buf, i, i, printcharfun);
2088 2097
2089 for (i = 0; i < lim; i++) 2098 for (i = 0; i < limit; i++)
2090 { 2099 {
2091 Lisp_Object maybe = ((Lisp_Object *) v->pointer)[i]; 2100 Lisp_Object maybe = area[i];
2092 2101
2093 if (valid_lisp_object_p (maybe) > 0) 2102 if (valid_lisp_object_p (maybe) > 0)
2094 { 2103 {
@@ -2098,13 +2107,49 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
2098 else 2107 else
2099 strout (" <invalid>", -1, -1, printcharfun); 2108 strout (" <invalid>", -1, -1, printcharfun);
2100 } 2109 }
2101 if (i == lim && i < v->integer) 2110 if (i == limit && i < amount)
2102 strout (" ...", 4, 4, printcharfun); 2111 strout (" ...", 4, 4, printcharfun);
2112
2113#else /* not GC_MARK_STACK */
2114
2115 /* If !GC_MARK_STACK, we have no reliable way to find
2116 whether Lisp_Object pointers points to an initialized
2117 objects, and so we do not ever trying to print them. */
2118
2119 i = sprintf (buf, "with %"pD"d objects", amount);
2120 strout (buf, i, i, printcharfun);
2121
2122#endif /* GC_MARK_STACK */
2103 } 2123 }
2104 else 2124 else
2105 { 2125 {
2106 i = sprintf (buf, "ptr=%p int=%"pD"d", v->pointer, v->integer); 2126 /* Print each `data[N]' slot according to its type. */
2107 strout (buf, i, i, printcharfun); 2127
2128#define PRINTX(index) \
2129 do { \
2130 i = 0; \
2131 if (v->type ## index == SAVE_UNUSED) \
2132 i = sprintf (buf, "<unused>"); \
2133 else if (v->type ## index == SAVE_INTEGER) \
2134 i = sprintf (buf, "<integer %"pD"d>", v->data[index].integer); \
2135 else if (v->type ## index == SAVE_POINTER) \
2136 i = sprintf (buf, "<pointer %p>", v->data[index].pointer); \
2137 else /* SAVE_OBJECT */ \
2138 print_object (v->data[index].object, printcharfun, escapeflag); \
2139 if (i) \
2140 strout (buf, i, i, printcharfun); \
2141 } while (0)
2142
2143 PRINTX (0);
2144 PRINTCHAR (' ');
2145 PRINTX (1);
2146 PRINTCHAR (' ');
2147 PRINTX (2);
2148 PRINTCHAR (' ');
2149 PRINTX (3);
2150
2151#undef PRINTX
2152
2108 } 2153 }
2109 PRINTCHAR ('>'); 2154 PRINTCHAR ('>');
2110 } 2155 }
diff --git a/src/sysdep.c b/src/sysdep.c
index 049eb85afe5..0e9a6826005 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -714,6 +714,27 @@ init_foreground_group (void)
714 inherited_pgroup = getpid () == pgrp ? 0 : pgrp; 714 inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
715} 715}
716 716
717/* Block and unblock SIGTTOU. */
718
719void
720block_tty_out_signal (void)
721{
722#ifdef SIGTTOU
723 sigset_t blocked;
724 sigemptyset (&blocked);
725 sigaddset (&blocked, SIGTTOU);
726 pthread_sigmask (SIG_BLOCK, &blocked, 0);
727#endif
728}
729
730void
731unblock_tty_out_signal (void)
732{
733#ifdef SIGTTOU
734 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
735#endif
736}
737
717/* Safely set a controlling terminal FD's process group to PGID. 738/* Safely set a controlling terminal FD's process group to PGID.
718 If we are not in the foreground already, POSIX requires tcsetpgrp 739 If we are not in the foreground already, POSIX requires tcsetpgrp
719 to deliver a SIGTTOU signal, which would stop us. This is an 740 to deliver a SIGTTOU signal, which would stop us. This is an
@@ -725,11 +746,10 @@ static void
725tcsetpgrp_without_stopping (int fd, pid_t pgid) 746tcsetpgrp_without_stopping (int fd, pid_t pgid)
726{ 747{
727#ifdef SIGTTOU 748#ifdef SIGTTOU
728 signal_handler_t handler;
729 block_input (); 749 block_input ();
730 handler = signal (SIGTTOU, SIG_IGN); 750 block_tty_out_signal ();
731 tcsetpgrp (fd, pgid); 751 tcsetpgrp (fd, pgid);
732 signal (SIGTTOU, handler); 752 unblock_tty_out_signal ();
733 unblock_input (); 753 unblock_input ();
734#endif 754#endif
735} 755}
@@ -1658,6 +1678,25 @@ deliver_arith_signal (int sig)
1658 deliver_thread_signal (sig, handle_arith_signal); 1678 deliver_thread_signal (sig, handle_arith_signal);
1659} 1679}
1660 1680
1681#ifdef SIGDANGER
1682
1683/* Handler for SIGDANGER. */
1684static void
1685handle_danger_signal (int sig)
1686{
1687 malloc_warning ("Operating system warns that virtual memory is running low.\n");
1688
1689 /* It might be unsafe to call do_auto_save now. */
1690 force_auto_save_soon ();
1691}
1692
1693static void
1694deliver_danger_signal (int sig)
1695{
1696 deliver_process_signal (sig, handle_danger_signal);
1697}
1698#endif
1699
1661/* Treat SIG as a terminating signal, unless it is already ignored and 1700/* Treat SIG as a terminating signal, unless it is already ignored and
1662 we are in --batch mode. Among other things, this makes nohup work. */ 1701 we are in --batch mode. Among other things, this makes nohup work. */
1663static void 1702static void
diff --git a/src/term.c b/src/term.c
index d76562bb4db..f66a0bddc33 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2423,7 +2423,7 @@ frame's terminal). */)
2423 if (fd == -1) 2423 if (fd == -1)
2424 error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno)); 2424 error ("Can not reopen tty device %s: %s", t->display_info.tty->name, strerror (errno));
2425 2425
2426 if (strcmp (t->display_info.tty->name, DEV_TTY)) 2426 if (!O_IGNORE_CTTY && strcmp (t->display_info.tty->name, DEV_TTY) != 0)
2427 dissociate_if_controlling_tty (fd); 2427 dissociate_if_controlling_tty (fd);
2428 2428
2429 t->display_info.tty->output = fdopen (fd, "w+"); 2429 t->display_info.tty->output = fdopen (fd, "w+");
@@ -2903,13 +2903,23 @@ set_tty_hooks (struct terminal *terminal)
2903 terminal->delete_terminal_hook = &delete_tty; 2903 terminal->delete_terminal_hook = &delete_tty;
2904} 2904}
2905 2905
2906/* Drop the controlling terminal if fd is the same device. */ 2906/* If FD is the controlling terminal, drop it. */
2907static void 2907static void
2908dissociate_if_controlling_tty (int fd) 2908dissociate_if_controlling_tty (int fd)
2909{ 2909{
2910 pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ 2910 /* If tcgetpgrp succeeds, fd is the controlling terminal,
2911 if (0 <= pgid) 2911 so dissociate it by invoking setsid. */
2912 setsid (); 2912 if (0 <= tcgetpgrp (fd) && setsid () < 0)
2913 {
2914#ifdef TIOCNOTTY
2915 /* setsid failed, presumably because Emacs is already a process
2916 group leader. Fall back on the obsolescent way to dissociate
2917 a controlling tty. */
2918 block_tty_out_signal ();
2919 ioctl (fd, TIOCNOTTY, 0);
2920 unblock_tty_out_signal ();
2921#endif
2922 }
2913} 2923}
2914 2924
2915/* Create a termcap display on the tty device with the given name and 2925/* Create a termcap display on the tty device with the given name and
@@ -3030,14 +3040,9 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3030 3040
3031 /* On some systems, tgetent tries to access the controlling 3041 /* On some systems, tgetent tries to access the controlling
3032 terminal. */ 3042 terminal. */
3033 { 3043 block_tty_out_signal ();
3034 sigset_t blocked; 3044 status = tgetent (tty->termcap_term_buffer, terminal_type);
3035 sigemptyset (&blocked); 3045 unblock_tty_out_signal ();
3036 sigaddset (&blocked, SIGTTOU);
3037 pthread_sigmask (SIG_BLOCK, &blocked, 0);
3038 status = tgetent (tty->termcap_term_buffer, terminal_type);
3039 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
3040 }
3041 3046
3042 if (status < 0) 3047 if (status < 0)
3043 { 3048 {
diff --git a/src/undo.c b/src/undo.c
index 2626fd4ccfe..63edc8e9b8d 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -452,217 +452,6 @@ user_error (const char *msg)
452} 452}
453 453
454 454
455DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
456 doc: /* Undo N records from the front of the list LIST.
457Return what remains of the list. */)
458 (Lisp_Object n, Lisp_Object list)
459{
460 struct gcpro gcpro1, gcpro2;
461 Lisp_Object next;
462 ptrdiff_t count = SPECPDL_INDEX ();
463 register EMACS_INT arg;
464 Lisp_Object oldlist;
465 int did_apply = 0;
466
467#if 0 /* This is a good feature, but would make undo-start
468 unable to do what is expected. */
469 Lisp_Object tem;
470
471 /* If the head of the list is a boundary, it is the boundary
472 preceding this command. Get rid of it and don't count it. */
473 tem = Fcar (list);
474 if (NILP (tem))
475 list = Fcdr (list);
476#endif
477
478 CHECK_NUMBER (n);
479 arg = XINT (n);
480 next = Qnil;
481 GCPRO2 (next, list);
482 /* I don't think we need to gcpro oldlist, as we use it only
483 to check for EQ. ++kfs */
484
485 /* In a writable buffer, enable undoing read-only text that is so
486 because of text properties. */
487 if (NILP (BVAR (current_buffer, read_only)))
488 specbind (Qinhibit_read_only, Qt);
489
490 /* Don't let `intangible' properties interfere with undo. */
491 specbind (Qinhibit_point_motion_hooks, Qt);
492
493 oldlist = BVAR (current_buffer, undo_list);
494
495 while (arg > 0)
496 {
497 while (CONSP (list))
498 {
499 next = XCAR (list);
500 list = XCDR (list);
501 /* Exit inner loop at undo boundary. */
502 if (NILP (next))
503 break;
504 /* Handle an integer by setting point to that value. */
505 if (INTEGERP (next))
506 SET_PT (clip_to_bounds (BEGV, XINT (next), ZV));
507 else if (CONSP (next))
508 {
509 Lisp_Object car, cdr;
510
511 car = XCAR (next);
512 cdr = XCDR (next);
513 if (EQ (car, Qt))
514 {
515 /* Element (t . TIME) records previous modtime.
516 Preserve any flag of NONEXISTENT_MODTIME_NSECS or
517 UNKNOWN_MODTIME_NSECS. */
518 struct buffer *base_buffer = current_buffer;
519 EMACS_TIME mod_time;
520
521 if (CONSP (cdr)
522 && CONSP (XCDR (cdr))
523 && CONSP (XCDR (XCDR (cdr)))
524 && CONSP (XCDR (XCDR (XCDR (cdr))))
525 && INTEGERP (XCAR (XCDR (XCDR (XCDR (cdr)))))
526 && XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) < 0)
527 mod_time =
528 (make_emacs_time
529 (0, XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000));
530 else
531 mod_time = lisp_time_argument (cdr);
532
533 if (current_buffer->base_buffer)
534 base_buffer = current_buffer->base_buffer;
535
536 /* If this records an obsolete save
537 (not matching the actual disk file)
538 then don't mark unmodified. */
539 if (EMACS_TIME_NE (mod_time, base_buffer->modtime))
540 continue;
541#ifdef CLASH_DETECTION
542 Funlock_buffer ();
543#endif /* CLASH_DETECTION */
544 Fset_buffer_modified_p (Qnil);
545 }
546 else if (EQ (car, Qnil))
547 {
548 /* Element (nil PROP VAL BEG . END) is property change. */
549 Lisp_Object beg, end, prop, val;
550
551 prop = Fcar (cdr);
552 cdr = Fcdr (cdr);
553 val = Fcar (cdr);
554 cdr = Fcdr (cdr);
555 beg = Fcar (cdr);
556 end = Fcdr (cdr);
557
558 if (XINT (beg) < BEGV || XINT (end) > ZV)
559 user_error ("Changes to be undone are outside visible portion of buffer");
560 Fput_text_property (beg, end, prop, val, Qnil);
561 }
562 else if (INTEGERP (car) && INTEGERP (cdr))
563 {
564 /* Element (BEG . END) means range was inserted. */
565
566 if (XINT (car) < BEGV
567 || XINT (cdr) > ZV)
568 user_error ("Changes to be undone are outside visible portion of buffer");
569 /* Set point first thing, so that undoing this undo
570 does not send point back to where it is now. */
571 Fgoto_char (car);
572 Fdelete_region (car, cdr);
573 }
574 else if (EQ (car, Qapply))
575 {
576 /* Element (apply FUN . ARGS) means call FUN to undo. */
577 struct buffer *save_buffer = current_buffer;
578
579 car = Fcar (cdr);
580 cdr = Fcdr (cdr);
581 if (INTEGERP (car))
582 {
583 /* Long format: (apply DELTA START END FUN . ARGS). */
584 Lisp_Object delta = car;
585 Lisp_Object start = Fcar (cdr);
586 Lisp_Object end = Fcar (Fcdr (cdr));
587 Lisp_Object start_mark = Fcopy_marker (start, Qnil);
588 Lisp_Object end_mark = Fcopy_marker (end, Qt);
589
590 cdr = Fcdr (Fcdr (cdr));
591 apply1 (Fcar (cdr), Fcdr (cdr));
592
593 /* Check that the function did what the entry said it
594 would do. */
595 if (!EQ (start, Fmarker_position (start_mark))
596 || (XINT (delta) + XINT (end)
597 != marker_position (end_mark)))
598 error ("Changes to be undone by function different than announced");
599 Fset_marker (start_mark, Qnil, Qnil);
600 Fset_marker (end_mark, Qnil, Qnil);
601 }
602 else
603 apply1 (car, cdr);
604
605 if (save_buffer != current_buffer)
606 error ("Undo function switched buffer");
607 did_apply = 1;
608 }
609 else if (STRINGP (car) && INTEGERP (cdr))
610 {
611 /* Element (STRING . POS) means STRING was deleted. */
612 Lisp_Object membuf;
613 EMACS_INT pos = XINT (cdr);
614
615 membuf = car;
616 if (pos < 0)
617 {
618 if (-pos < BEGV || -pos > ZV)
619 user_error ("Changes to be undone are outside visible portion of buffer");
620 SET_PT (-pos);
621 Finsert (1, &membuf);
622 }
623 else
624 {
625 if (pos < BEGV || pos > ZV)
626 user_error ("Changes to be undone are outside visible portion of buffer");
627 SET_PT (pos);
628
629 /* Now that we record marker adjustments
630 (caused by deletion) for undo,
631 we should always insert after markers,
632 so that undoing the marker adjustments
633 put the markers back in the right place. */
634 Finsert (1, &membuf);
635 SET_PT (pos);
636 }
637 }
638 else if (MARKERP (car) && INTEGERP (cdr))
639 {
640 /* (MARKER . INTEGER) means a marker MARKER
641 was adjusted by INTEGER. */
642 if (XMARKER (car)->buffer)
643 Fset_marker (car,
644 make_number (marker_position (car) - XINT (cdr)),
645 Fmarker_buffer (car));
646 }
647 }
648 }
649 arg--;
650 }
651
652
653 /* Make sure an apply entry produces at least one undo entry,
654 so the test in `undo' for continuing an undo series
655 will work right. */
656 if (did_apply
657 && EQ (oldlist, BVAR (current_buffer, undo_list)))
658 bset_undo_list
659 (current_buffer,
660 Fcons (list3 (Qapply, Qcdr, Qnil), BVAR (current_buffer, undo_list)));
661
662 UNGCPRO;
663 return unbind_to (count, list);
664}
665
666void 455void
667syms_of_undo (void) 456syms_of_undo (void)
668{ 457{
@@ -675,7 +464,6 @@ syms_of_undo (void)
675 last_undo_buffer = NULL; 464 last_undo_buffer = NULL;
676 last_boundary_buffer = NULL; 465 last_boundary_buffer = NULL;
677 466
678 defsubr (&Sprimitive_undo);
679 defsubr (&Sundo_boundary); 467 defsubr (&Sundo_boundary);
680 468
681 DEFVAR_INT ("undo-limit", undo_limit, 469 DEFVAR_INT ("undo-limit", undo_limit,
diff --git a/src/w32.c b/src/w32.c
index 55581a17de5..812003e96c0 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -3648,7 +3648,6 @@ static int
3648get_name_and_id (PSECURITY_DESCRIPTOR psd, unsigned *id, char *nm, int what) 3648get_name_and_id (PSECURITY_DESCRIPTOR psd, unsigned *id, char *nm, int what)
3649{ 3649{
3650 PSID sid = NULL; 3650 PSID sid = NULL;
3651 char machine[MAX_COMPUTERNAME_LENGTH+1];
3652 BOOL dflt; 3651 BOOL dflt;
3653 SID_NAME_USE ignore; 3652 SID_NAME_USE ignore;
3654 char name[UNLEN+1]; 3653 char name[UNLEN+1];
@@ -4800,7 +4799,6 @@ acl_set_file (const char *fname, acl_type_t type, acl_t acl)
4800{ 4799{
4801 TOKEN_PRIVILEGES old1, old2; 4800 TOKEN_PRIVILEGES old1, old2;
4802 DWORD err; 4801 DWORD err;
4803 BOOL res;
4804 int st = 0, retval = -1; 4802 int st = 0, retval = -1;
4805 SECURITY_INFORMATION flags = 0; 4803 SECURITY_INFORMATION flags = 0;
4806 PSID psid; 4804 PSID psid;
diff --git a/src/w32term.c b/src/w32term.c
index 36ae4d7797f..16c7bd415a5 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5652,7 +5652,7 @@ x_check_fullscreen (struct frame *f)
5652static void 5652static void
5653w32fullscreen_hook (FRAME_PTR f) 5653w32fullscreen_hook (FRAME_PTR f)
5654{ 5654{
5655 static int normal_width, normal_height, normal_top, normal_left; 5655 static int normal_width, normal_height;
5656 5656
5657 if (f->async_visible) 5657 if (f->async_visible)
5658 { 5658 {
diff --git a/src/window.c b/src/window.c
index 71d8eb7f778..32a6759f9f4 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1436,7 +1436,7 @@ window were selected.
1436 1436
1437Note that, when WINDOW is selected, the value returned is the same as 1437Note that, when WINDOW is selected, the value returned is the same as
1438that returned by `point' for WINDOW's buffer. It would be more strictly 1438that returned by `point' for WINDOW's buffer. It would be more strictly
1439correct to return the `top-level' value of `point', outside of any 1439correct to return the top-level value of `point', outside of any
1440`save-excursion' forms. But that is hard to define. */) 1440`save-excursion' forms. But that is hard to define. */)
1441 (Lisp_Object window) 1441 (Lisp_Object window)
1442{ 1442{
@@ -6793,7 +6793,8 @@ same combination.
6793 6793
6794Other values are reserved for future use. 6794Other values are reserved for future use.
6795 6795
6796This variable takes no effect if `window-combination-limit' is non-nil. */); 6796This variable takes no effect if the variable `window-combination-limit' is
6797non-nil. */);
6797 Vwindow_combination_resize = Qnil; 6798 Vwindow_combination_resize = Qnil;
6798 6799
6799 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit, 6800 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
diff --git a/src/xfaces.c b/src/xfaces.c
index ed2895c014c..43535b9ea0c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4877,6 +4877,8 @@ tty_supports_face_attributes_p (struct frame *f,
4877 { 4877 {
4878 if (STRINGP (val)) 4878 if (STRINGP (val))
4879 return 0; /* ttys can't use colored underlines */ 4879 return 0; /* ttys can't use colored underlines */
4880 else if (EQ (CAR_SAFE (val), QCstyle) && EQ (CAR_SAFE (CDR_SAFE (val)), Qwave))
4881 return 0; /* ttys can't use wave underlines */
4880 else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX])) 4882 else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
4881 return 0; /* same as default */ 4883 return 0; /* same as default */
4882 else 4884 else
diff --git a/src/xfns.c b/src/xfns.c
index 315d5093716..65148d1c9e1 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5292,8 +5292,7 @@ file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5292static Lisp_Object 5292static Lisp_Object
5293clean_up_file_dialog (Lisp_Object arg) 5293clean_up_file_dialog (Lisp_Object arg)
5294{ 5294{
5295 struct Lisp_Save_Value *p = XSAVE_VALUE (arg); 5295 Widget dialog = XSAVE_POINTER (arg, 0);
5296 Widget dialog = (Widget) p->pointer;
5297 5296
5298 /* Clean up. */ 5297 /* Clean up. */
5299 block_input (); 5298 block_input ();
diff --git a/src/xmenu.c b/src/xmenu.c
index 3d76070c336..7f6914d26ac 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1411,11 +1411,9 @@ popup_selection_callback (GtkWidget *widget, gpointer client_data)
1411static Lisp_Object 1411static Lisp_Object
1412pop_down_menu (Lisp_Object arg) 1412pop_down_menu (Lisp_Object arg)
1413{ 1413{
1414 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
1415
1416 popup_activated_flag = 0; 1414 popup_activated_flag = 0;
1417 block_input (); 1415 block_input ();
1418 gtk_widget_destroy (GTK_WIDGET (p->pointer)); 1416 gtk_widget_destroy (GTK_WIDGET (XSAVE_POINTER (arg, 0)));
1419 unblock_input (); 1417 unblock_input ();
1420 return Qnil; 1418 return Qnil;
1421} 1419}
@@ -1612,11 +1610,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
1612static Lisp_Object 1610static Lisp_Object
1613cleanup_widget_value_tree (Lisp_Object arg) 1611cleanup_widget_value_tree (Lisp_Object arg)
1614{ 1612{
1615 struct Lisp_Save_Value *p = XSAVE_VALUE (arg); 1613 free_menubar_widget_value_tree (XSAVE_POINTER (arg, 0));
1616 widget_value *wv = p->pointer;
1617
1618 free_menubar_widget_value_tree (wv);
1619
1620 return Qnil; 1614 return Qnil;
1621} 1615}
1622 1616
@@ -2242,11 +2236,8 @@ menu_help_callback (char const *help_string, int pane, int item)
2242static Lisp_Object 2236static Lisp_Object
2243pop_down_menu (Lisp_Object arg) 2237pop_down_menu (Lisp_Object arg)
2244{ 2238{
2245 struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg)); 2239 FRAME_PTR f = XSAVE_POINTER (arg, 0);
2246 struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg)); 2240 XMenu *menu = XSAVE_POINTER (arg, 1);
2247
2248 FRAME_PTR f = p1->pointer;
2249 XMenu *menu = p2->pointer;
2250 2241
2251 block_input (); 2242 block_input ();
2252#ifndef MSDOS 2243#ifndef MSDOS
@@ -2488,8 +2479,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
2488#endif 2479#endif
2489 2480
2490 record_unwind_protect (pop_down_menu, 2481 record_unwind_protect (pop_down_menu,
2491 Fcons (make_save_value (f, 0), 2482 format_save_value ("pp", f, menu));
2492 make_save_value (menu, 0)));
2493 2483
2494 /* Help display under X won't work because XMenuActivate contains 2484 /* Help display under X won't work because XMenuActivate contains
2495 a loop that doesn't give Emacs a chance to process it. */ 2485 a loop that doesn't give Emacs a chance to process it. */
diff --git a/src/xml.c b/src/xml.c
index 5939c58a564..5a52b0c2a1e 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -180,8 +180,7 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
180 xmlDoc *doc; 180 xmlDoc *doc;
181 Lisp_Object result = Qnil; 181 Lisp_Object result = Qnil;
182 const char *burl = ""; 182 const char *burl = "";
183 ptrdiff_t bytes; 183 ptrdiff_t istart, iend, istart_byte, iend_byte;
184 ptrdiff_t istart, iend;
185 184
186 fn_xmlCheckVersion (LIBXML_VERSION); 185 fn_xmlCheckVersion (LIBXML_VERSION);
187 186
@@ -189,9 +188,11 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
189 188
190 istart = XINT (start); 189 istart = XINT (start);
191 iend = XINT (end); 190 iend = XINT (end);
191 istart_byte = CHAR_TO_BYTE (istart);
192 iend_byte = CHAR_TO_BYTE (iend);
192 193
193 if (istart < GPT && GPT < iend) 194 if (istart < GPT && GPT < iend)
194 move_gap (iend); 195 move_gap_both (iend, iend_byte);
195 196
196 if (! NILP (base_url)) 197 if (! NILP (base_url))
197 { 198 {
@@ -199,17 +200,15 @@ parse_region (Lisp_Object start, Lisp_Object end, Lisp_Object base_url, int html
199 burl = SSDATA (base_url); 200 burl = SSDATA (base_url);
200 } 201 }
201 202
202 bytes = CHAR_TO_BYTE (iend) - CHAR_TO_BYTE (istart);
203
204 if (htmlp) 203 if (htmlp)
205 doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), 204 doc = fn_htmlReadMemory ((char *) BYTE_POS_ADDR (istart_byte),
206 bytes, burl, "utf-8", 205 iend_byte - istart_byte, burl, "utf-8",
207 HTML_PARSE_RECOVER|HTML_PARSE_NONET| 206 HTML_PARSE_RECOVER|HTML_PARSE_NONET|
208 HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR| 207 HTML_PARSE_NOWARNING|HTML_PARSE_NOERROR|
209 HTML_PARSE_NOBLANKS); 208 HTML_PARSE_NOBLANKS);
210 else 209 else
211 doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (CHAR_TO_BYTE (istart)), 210 doc = fn_xmlReadMemory ((char *) BYTE_POS_ADDR (istart_byte),
212 bytes, burl, "utf-8", 211 iend_byte - istart_byte, burl, "utf-8",
213 XML_PARSE_NONET|XML_PARSE_NOWARNING| 212 XML_PARSE_NONET|XML_PARSE_NOWARNING|
214 XML_PARSE_NOBLANKS |XML_PARSE_NOERROR); 213 XML_PARSE_NOBLANKS |XML_PARSE_NOERROR);
215 214
diff --git a/src/xselect.c b/src/xselect.c
index f43efab827b..b7cdf70ff77 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1120,7 +1120,7 @@ unexpect_property_change (struct prop_location *location)
1120static Lisp_Object 1120static Lisp_Object
1121wait_for_property_change_unwind (Lisp_Object loc) 1121wait_for_property_change_unwind (Lisp_Object loc)
1122{ 1122{
1123 struct prop_location *location = XSAVE_VALUE (loc)->pointer; 1123 struct prop_location *location = XSAVE_POINTER (loc, 0);
1124 1124
1125 unexpect_property_change (location); 1125 unexpect_property_change (location);
1126 if (location == property_change_reply_object) 1126 if (location == property_change_reply_object)
diff --git a/src/xterm.c b/src/xterm.c
index f63f10566f6..26d40859ed3 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -4802,21 +4802,24 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
4802 4802
4803#ifdef USE_MOTIF 4803#ifdef USE_MOTIF
4804 4804
4805 /* We use an estimate of 30 chars per line rather than the real 4805 if (scroll_bar_adjust_thumb_portion_p)
4806 `portion' value. This has the disadvantage that the thumb size 4806 {
4807 is not very representative, but it makes our life a lot easier. 4807 /* We use an estimate of 30 chars per line rather than the real
4808 Otherwise, we have to constantly adjust the thumb size, which 4808 `portion' value. This has the disadvantage that the thumb size
4809 we can't always do quickly enough: while dragging, the size of 4809 is not very representative, but it makes our life a lot easier.
4810 the thumb might prevent the user from dragging the thumb all the 4810 Otherwise, we have to constantly adjust the thumb size, which
4811 way to the end. but Motif and some versions of Xaw3d don't allow 4811 we can't always do quickly enough: while dragging, the size of
4812 updating the thumb size while dragging. Also, even if we can update 4812 the thumb might prevent the user from dragging the thumb all the
4813 its size, the update will often happen too late. 4813 way to the end. but Motif and some versions of Xaw3d don't allow
4814 If you don't believe it, check out revision 1.650 of xterm.c to see 4814 updating the thumb size while dragging. Also, even if we can update
4815 what hoops we were going through and the still poor behavior we got. */ 4815 its size, the update will often happen too late.
4816 portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30; 4816 If you don't believe it, check out revision 1.650 of xterm.c to see
4817 /* When the thumb is at the bottom, position == whole. 4817 what hoops we were going through and the still poor behavior we got. */
4818 So we need to increase `whole' to make space for the thumb. */ 4818 portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
4819 whole += portion; 4819 /* When the thumb is at the bottom, position == whole.
4820 So we need to increase `whole' to make space for the thumb. */
4821 whole += portion;
4822 }
4820 4823
4821 if (whole <= 0) 4824 if (whole <= 0)
4822 top = 0, shown = 1; 4825 top = 0, shown = 1;
@@ -10784,6 +10787,16 @@ With MS Windows or Nextstep, the value is t. */);
10784 Vx_toolkit_scroll_bars = Qnil; 10787 Vx_toolkit_scroll_bars = Qnil;
10785#endif 10788#endif
10786 10789
10790 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
10791 scroll_bar_adjust_thumb_portion_p,
10792 doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
10793Non-nil means adjust the thumb in the scroll bar so it can be dragged downwards
10794even if the end of the buffer is shown (i.e. overscrolling).
10795Set to nil if you want the thumb to be at the bottom when the end of the buffer
10796is shown. Also, the thumb fills the whole scroll bar when the entire buffer
10797is visible. In this case you can not overscroll. */);
10798 scroll_bar_adjust_thumb_portion_p = 1;
10799
10787 staticpro (&last_mouse_motion_frame); 10800 staticpro (&last_mouse_motion_frame);
10788 last_mouse_motion_frame = Qnil; 10801 last_mouse_motion_frame = Qnil;
10789 10802