aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey2004-12-23 16:43:51 +0000
committerKaroly Lorentey2004-12-23 16:43:51 +0000
commit17d51b68fb4e7da4f18eff72c589b7ffc4f9c22c (patch)
treef490c1ccdbd43077ea77f953bc59ca94c2fe810c /src
parent4b89585ee70a1f64543a5851f07cf7e2d89c5c62 (diff)
parent55f4edbcd246d8ea1715687a7aeeb3afe35c0345 (diff)
downloademacs-17d51b68fb4e7da4f18eff72c589b7ffc4f9c22c.tar.gz
emacs-17d51b68fb4e7da4f18eff72c589b7ffc4f9c22c.zip
Merged in changes from CVS trunk.
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-726 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-727 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-728 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-729 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-730 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-731 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-732 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-733 Update from CVS: man/calc.texi: Fix some TeX definitions. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-734 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-735 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-736 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-737 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-738 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-739 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-740 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-741 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-742 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-743 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-744 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-745 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-746 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-75 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-76 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-77 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-277
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog166
-rw-r--r--src/alloc.c109
-rw-r--r--src/atimer.c2
-rw-r--r--src/data.c1
-rw-r--r--src/dispnew.c4
-rw-r--r--src/emacs.c25
-rw-r--r--src/eval.c7
-rw-r--r--src/fileio.c16
-rw-r--r--src/floatfns.c1
-rw-r--r--src/indent.c5
-rw-r--r--src/keyboard.c66
-rw-r--r--src/lisp.h11
-rw-r--r--src/macterm.c102
-rw-r--r--src/minibuf.c30
-rw-r--r--src/process.c3
-rw-r--r--src/regex.c4
-rw-r--r--src/syntax.c6
-rw-r--r--src/sysdep.c1
-rw-r--r--src/syssignal.h27
-rw-r--r--src/term.c2
-rw-r--r--src/undo.c156
-rw-r--r--src/w32term.c30
-rw-r--r--src/xdisp.c22
-rw-r--r--src/xselect.c2
-rw-r--r--src/xterm.c31
25 files changed, 577 insertions, 252 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 38a079989be..8d09c5bfd2f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,159 @@
12004-12-22 Richard M. Stallman <rms@gnu.org>
2
3 * emacs.c (main): If batch mode, set Vundo_outer_limit to nil.
4
5 * lisp.h (Vundo_outer_limit): Fix decl.
6
7 * undo.c (Vundo_outer_limit): Replaces undo_outer_limit.
8 Uses changed.
9 (syms_of_undo): Initialize appropriately.
10 (truncate_undo_list): If it's nil, there's no limit.
11
122004-12-22 Kenichi Handa <handa@m17n.org>
13
14 * xselect.c (Fx_get_cut_buffer_internal): Return a unibyte string.
15
162004-12-21 Richard M. Stallman <rms@gnu.org>
17
18 * eval.c (unwind_to_catch): Clear immediate_quit.
19
20 * xdisp.c (get_next_display_element): Display codes 8a0 and 8ad
21 specially as `\ ' and `\-'.
22
23 * keyboard.c (kbd_buffer_store_event_hold):
24 In the code for while-no-input, handle immediate_quit.
25
26 * alloc.c (Fgarbage_collect): Update call to truncate_undo_list.
27 Call that at the very start.
28 (undo_limit, undo_strong_limit, undo_outer_limit): Moved to undo.c.
29 (syms_of_alloc): Don't define undo-limit,
30 undo-strong-limit and undo-outer-limit here.
31
32 * undo.c (truncate_undo_list): Return void.
33 Take just one argument, the buffer.
34 Make it current, and inhibit recursive GC.
35 Access and update the undo list directly; return void.
36 Refer to the undo...limit variables directly.
37 Test undo_outer_limit only after counting the whole current command.
38 When it's exceeded, call the function in undo-outer-limit-function.
39 (undo_limit, undo_strong_limit, undo_outer_limit): From alloc.c.
40 (Vundo_outer_limit_function): New variable.
41 (syms_of_undo): Define undo-limit, undo-strong-limit
42 and undo-outer-limit here, and undo-outer-limit-function.
43 Doc fixes.
44
45 * lisp.h (truncate_undo_list): Update decl.
46
472004-12-21 Piet van Oostrum <piet@cs.uu.nl>
48
49 * fileio.c (Fread_file_name): Delete duplicates in
50 file-name-history when history_delete_duplicates is true.
51
522004-12-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
53
54 * macterm.c (mac_do_list_fonts): Fix memory leak
55
562004-12-20 Richard M. Stallman <rms@gnu.org>
57
58 * regex.c (re_match_2_internal) <symend, wordend>:
59 Fix calls to UPDATE_SYNTAX_TABLE_FORWARD.
60
612004-12-18 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
62
63 * macterm.c (endif, x_font_name_to_mac_font_name): Use
64 maccentraleurroman instead of maccentraleuropean
65 (mac_c_string_match, mac_do_list_fonts): Speed up font search by
66 quickly finding a specific font without needing regexps.
67
682004-12-15 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
69
70 * syssignal.h: Declare main_thread.
71 (SIGNAL_THREAD_CHECK): New macro.
72
73 * keyboard.c (input_available_signal): Move thread checking code
74 to macro SIGNAL_THREAD_CHECK and call that macro.
75 (interrupt_signal): Call SIGNAL_THREAD_CHECK.
76
77 * alloc.c (uninterrupt_malloc): Move main_thread to emacs.c.
78
79 * emacs.c: Define main_thread.
80 (main): Initialize main_thread.
81 (handle_USR1_signal, handle_USR2_signal, fatal_error_signal)
82 (memory_warning_signal): Call SIGNAL_THREAD_CHECK.
83
84 * floatfns.c (float_error): Call SIGNAL_THREAD_CHECK.
85
86 * dispnew.c (window_change_signal): Call SIGNAL_THREAD_CHECK.
87
88 * sysdep.c (select_alarm): Call SIGNAL_THREAD_CHECK.
89
90 * process.c (send_process_trap, sigchld_handler): Call
91 SIGNAL_THREAD_CHECK.
92
93 * data.c (arith_error): Call SIGNAL_THREAD_CHECK.
94
95 * atimer.c (alarm_signal_handler): Call SIGNAL_THREAD_CHECK.
96
97 * xterm.c (xg_scroll_callback): Update XG_LAST_SB_DATA before
98 returning when xg_ignore_gtk_scrollbar is true.
99
1002004-12-14 Kim F. Storm <storm@cua.dk>
101
102 * keyboard.c (read_char): Save and restore echo_string when
103 handling input method.
104
1052004-12-13 Richard M. Stallman <rms@gnu.org>
106
107 * eval.c (syms_of_eval) <quit-flag>: Doc fix.
108
109 * keyboard.c (Vthrow_on_input): New variable.
110 (syms_of_keyboard): Defvar and initialize it.
111 (kbd_buffer_store_event_hold): Handle Vthrow_on_input.
112
113 * lisp.h (QUIT): Check for Vthrow_on_input.
114 (Vthrow_on_input): Declare it.
115
1162004-12-13 Kim F. Storm <storm@cua.dk>
117
118 * xdisp.c (set_iterator_to_next): Reset stop_charpos after display
119 vector.
120
1212004-12-12 Richard M. Stallman <rms@gnu.org>
122
123 * indent.c (Fvertical_motion): Call move_it_by_lines even if LINES = 0.
124
125 * minibuf.c (Fall_completions): Add var `zero' and use it in loop.
126 (Ftry_completion): Really use outer `zero'; eliminate inner one.
127
1282004-12-12 Kenichi Handa <handa@m17n.org>
129
130 * term.c (encode_terminal_code): Fix previous change.
131
1322004-12-11 Stefan Monnier <monnier@iro.umontreal.ca>
133
134 * keyboard.c (handle_async_input): Remove pthread mutex handling.
135 (input_available_signal): Move pthread thingy to !SYNC_INPUT branch.
136
137 * syntax.c (Fforward_word): Avoid non-idempotent side-effects
138 in macro arguments.
139
140 * minibuf.c (Ftry_completion, Fall_completions): Don't use
141 XFASTINT blindly.
142
143 * emacs.c (main, Fdump_emacs): Don't touch malloc hooks if SYNC_INPUT.
144
1452004-12-11 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
146
147 * w32term.c (x_calc_absolute_position): Remove calculation of
148 difference between inner and outer window. Don't subtract difference
149 for left and top calculations.
150
151 * xterm.c (x_calc_absolute_position): Don't subtract outer_pixel_diff
152 for left and top calculations. Remove call to x_real_positions.
153 [Bug report by Drew Adams in November]
154 (x_check_expected_move): Do not set change_gravity to 1 when calling
155 x_set_offset.
156
12004-12-08 Richard M. Stallman <rms@gnu.org> 1572004-12-08 Richard M. Stallman <rms@gnu.org>
2 158
3 * xdisp.c (get_next_display_element): Use `escape-glyph' for 159 * xdisp.c (get_next_display_element): Use `escape-glyph' for
@@ -17,8 +173,8 @@
17 * emacs.c (Fdump_emacs): Add ! defined (SYSTEM_MALLOC) around 173 * emacs.c (Fdump_emacs): Add ! defined (SYSTEM_MALLOC) around
18 reset_malloc_hooks. 174 reset_malloc_hooks.
19 175
20 * keyboard.c (handle_async_input, input_available_signal): Add 176 * keyboard.c (handle_async_input, input_available_signal):
21 ! defined (SYSTEM_MALLOC) around thread code. 177 Add ! defined (SYSTEM_MALLOC) around thread code.
22 178
23 * alloc.c: Add comment about the reason for (UN)BLOCK_INPUT_ALLOC. 179 * alloc.c: Add comment about the reason for (UN)BLOCK_INPUT_ALLOC.
24 180
@@ -56,12 +212,11 @@
56 * emacs.c (Fdump_emacs): Call reset_malloc_hooks. 212 * emacs.c (Fdump_emacs): Call reset_malloc_hooks.
57 213
58 * keyboard.c: Conditionally include pthread.h 214 * keyboard.c: Conditionally include pthread.h
59 (handle_async_inpu, input_available_signalt): If not in the main 215 (handle_async_input, input_available_signalt): If not in the main
60 thread, block signal, send signal to main thread and return. 216 thread, block signal, send signal to main thread and return.
61 217
62 * gtkutil.c (xg_get_file_with_chooser): Handle local files only. 218 * gtkutil.c (xg_get_file_with_chooser): Handle local files only.
63 Set current folder in file chooser if default_filename is a 219 Set current folder in file chooser if default_filename is a directory.
64 directory.
65 220
662004-12-05 Stefan Monnier <monnier@iro.umontreal.ca> 2212004-12-05 Stefan Monnier <monnier@iro.umontreal.ca>
67 222
@@ -92,6 +247,7 @@
92 * eval.c (Fcalled_interactively_p): Don't check INTERACTIVE. 247 * eval.c (Fcalled_interactively_p): Don't check INTERACTIVE.
93 (interactive_p): Skip Scalled_interactively_p frames 248 (interactive_p): Skip Scalled_interactively_p frames
94 like Sinteractive_p frames. 249 like Sinteractive_p frames.
250 (unwind_to_catch): Clear handling_signal.
95 251
96 * data.c (Fmake_variable_buffer_local): Doc fix. 252 * data.c (Fmake_variable_buffer_local): Doc fix.
97 (Fmake_local_variable): Doc fix. 253 (Fmake_local_variable): Doc fix.
diff --git a/src/alloc.c b/src/alloc.c
index 4cf5de46d21..7a6a1344d6c 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -99,7 +99,7 @@ extern __malloc_size_t __malloc_extra_blocks;
99 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_* 99 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
100 functions below are called from malloc, there is a chance that one 100 functions below are called from malloc, there is a chance that one
101 of these threads preempts the Emacs main thread and the hook variables 101 of these threads preempts the Emacs main thread and the hook variables
102 end up in a inconsistent state. So we have a mutex to prevent that (note 102 end up in an inconsistent state. So we have a mutex to prevent that (note
103 that the backend handles concurrent access to malloc within its own threads 103 that the backend handles concurrent access to malloc within its own threads
104 but Emacs code running in the main thread is not included in that control). 104 but Emacs code running in the main thread is not included in that control).
105 105
@@ -109,7 +109,6 @@ extern __malloc_size_t __malloc_extra_blocks;
109 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */ 109 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */
110 110
111static pthread_mutex_t alloc_mutex; 111static pthread_mutex_t alloc_mutex;
112pthread_t main_thread;
113 112
114#define BLOCK_INPUT_ALLOC \ 113#define BLOCK_INPUT_ALLOC \
115 do \ 114 do \
@@ -201,12 +200,6 @@ extern
201#endif /* VIRT_ADDR_VARIES */ 200#endif /* VIRT_ADDR_VARIES */
202int malloc_sbrk_unused; 201int malloc_sbrk_unused;
203 202
204/* Two limits controlling how much undo information to keep. */
205
206EMACS_INT undo_limit;
207EMACS_INT undo_strong_limit;
208EMACS_INT undo_outer_limit;
209
210/* Number of live and free conses etc. */ 203/* Number of live and free conses etc. */
211 204
212static int total_conses, total_markers, total_symbols, total_vector_size; 205static int total_conses, total_markers, total_symbols, total_vector_size;
@@ -1311,8 +1304,6 @@ uninterrupt_malloc ()
1311 pthread_mutexattr_init (&attr); 1304 pthread_mutexattr_init (&attr);
1312 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 1305 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
1313 pthread_mutex_init (&alloc_mutex, &attr); 1306 pthread_mutex_init (&alloc_mutex, &attr);
1314
1315 main_thread = pthread_self ();
1316#endif /* HAVE_GTK_AND_PTHREAD */ 1307#endif /* HAVE_GTK_AND_PTHREAD */
1317 1308
1318 if (__free_hook != emacs_blocked_free) 1309 if (__free_hook != emacs_blocked_free)
@@ -4648,13 +4639,48 @@ returns nil, because real GC can't be done. */)
4648 if (abort_on_gc) 4639 if (abort_on_gc)
4649 abort (); 4640 abort ();
4650 4641
4651 EMACS_GET_TIME (t1);
4652
4653 /* Can't GC if pure storage overflowed because we can't determine 4642 /* Can't GC if pure storage overflowed because we can't determine
4654 if something is a pure object or not. */ 4643 if something is a pure object or not. */
4655 if (pure_bytes_used_before_overflow) 4644 if (pure_bytes_used_before_overflow)
4656 return Qnil; 4645 return Qnil;
4657 4646
4647 /* Don't keep undo information around forever.
4648 Do this early on, so it is no problem if the user quits. */
4649 {
4650 register struct buffer *nextb = all_buffers;
4651
4652 while (nextb)
4653 {
4654 /* If a buffer's undo list is Qt, that means that undo is
4655 turned off in that buffer. Calling truncate_undo_list on
4656 Qt tends to return NULL, which effectively turns undo back on.
4657 So don't call truncate_undo_list if undo_list is Qt. */
4658 if (! EQ (nextb->undo_list, Qt))
4659 truncate_undo_list (nextb);
4660
4661 /* Shrink buffer gaps, but skip indirect and dead buffers. */
4662 if (nextb->base_buffer == 0 && !NILP (nextb->name))
4663 {
4664 /* If a buffer's gap size is more than 10% of the buffer
4665 size, or larger than 2000 bytes, then shrink it
4666 accordingly. Keep a minimum size of 20 bytes. */
4667 int size = min (2000, max (20, (nextb->text->z_byte / 10)));
4668
4669 if (nextb->text->gap_size > size)
4670 {
4671 struct buffer *save_current = current_buffer;
4672 current_buffer = nextb;
4673 make_gap (-(nextb->text->gap_size - size));
4674 current_buffer = save_current;
4675 }
4676 }
4677
4678 nextb = nextb->next;
4679 }
4680 }
4681
4682 EMACS_GET_TIME (t1);
4683
4658 /* In case user calls debug_print during GC, 4684 /* In case user calls debug_print during GC,
4659 don't let that cause a recursive GC. */ 4685 don't let that cause a recursive GC. */
4660 consing_since_gc = 0; 4686 consing_since_gc = 0;
@@ -4693,42 +4719,6 @@ returns nil, because real GC can't be done. */)
4693 4719
4694 shrink_regexp_cache (); 4720 shrink_regexp_cache ();
4695 4721
4696 /* Don't keep undo information around forever. */
4697 {
4698 register struct buffer *nextb = all_buffers;
4699
4700 while (nextb)
4701 {
4702 /* If a buffer's undo list is Qt, that means that undo is
4703 turned off in that buffer. Calling truncate_undo_list on
4704 Qt tends to return NULL, which effectively turns undo back on.
4705 So don't call truncate_undo_list if undo_list is Qt. */
4706 if (! EQ (nextb->undo_list, Qt))
4707 nextb->undo_list
4708 = truncate_undo_list (nextb->undo_list, undo_limit,
4709 undo_strong_limit, undo_outer_limit);
4710
4711 /* Shrink buffer gaps, but skip indirect and dead buffers. */
4712 if (nextb->base_buffer == 0 && !NILP (nextb->name))
4713 {
4714 /* If a buffer's gap size is more than 10% of the buffer
4715 size, or larger than 2000 bytes, then shrink it
4716 accordingly. Keep a minimum size of 20 bytes. */
4717 int size = min (2000, max (20, (nextb->text->z_byte / 10)));
4718
4719 if (nextb->text->gap_size > size)
4720 {
4721 struct buffer *save_current = current_buffer;
4722 current_buffer = nextb;
4723 make_gap (-(nextb->text->gap_size - size));
4724 current_buffer = save_current;
4725 }
4726 }
4727
4728 nextb = nextb->next;
4729 }
4730 }
4731
4732 gc_in_progress = 1; 4722 gc_in_progress = 1;
4733 4723
4734 /* clear_marks (); */ 4724 /* clear_marks (); */
@@ -6004,29 +5994,6 @@ prevent garbage collection during a part of the program. */);
6004 doc: /* Non-nil means loading Lisp code in order to dump an executable. 5994 doc: /* Non-nil means loading Lisp code in order to dump an executable.
6005This means that certain objects should be allocated in shared (pure) space. */); 5995This means that certain objects should be allocated in shared (pure) space. */);
6006 5996
6007 DEFVAR_INT ("undo-limit", &undo_limit,
6008 doc: /* Keep no more undo information once it exceeds this size.
6009This limit is applied when garbage collection happens.
6010The size is counted as the number of bytes occupied,
6011which includes both saved text and other data. */);
6012 undo_limit = 20000;
6013
6014 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit,
6015 doc: /* Don't keep more than this much size of undo information.
6016A previous command which pushes the undo list past this size
6017is entirely forgotten when GC happens.
6018The size is counted as the number of bytes occupied,
6019which includes both saved text and other data. */);
6020 undo_strong_limit = 30000;
6021
6022 DEFVAR_INT ("undo-outer-limit", &undo_outer_limit,
6023 doc: /* Don't keep more than this much size of undo information.
6024If the current command has produced more than this much undo information,
6025GC discards it. This is a last-ditch limit to prevent memory overflow.
6026The size is counted as the number of bytes occupied,
6027which includes both saved text and other data. */);
6028 undo_outer_limit = 300000;
6029
6030 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, 5997 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages,
6031 doc: /* Non-nil means display messages at start and end of garbage collection. */); 5998 doc: /* Non-nil means display messages at start and end of garbage collection. */);
6032 garbage_collection_messages = 0; 5999 garbage_collection_messages = 0;
diff --git a/src/atimer.c b/src/atimer.c
index 7410cad0244..ff5b8faaf36 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -364,6 +364,8 @@ alarm_signal_handler (signo)
364{ 364{
365 EMACS_TIME now; 365 EMACS_TIME now;
366 366
367 SIGNAL_THREAD_CHECK (signo);
368
367 EMACS_GET_TIME (now); 369 EMACS_GET_TIME (now);
368 pending_atimers = 0; 370 pending_atimers = 0;
369 371
diff --git a/src/data.c b/src/data.c
index afbca80181d..811619b58b3 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3366,6 +3366,7 @@ arith_error (signo)
3366 sigsetmask (SIGEMPTYMASK); 3366 sigsetmask (SIGEMPTYMASK);
3367#endif /* not BSD4_1 */ 3367#endif /* not BSD4_1 */
3368 3368
3369 SIGNAL_THREAD_CHECK (signo);
3369 Fsignal (Qarith_error, Qnil); 3370 Fsignal (Qarith_error, Qnil);
3370} 3371}
3371 3372
diff --git a/src/dispnew.c b/src/dispnew.c
index f2fac47a7c2..6813cda5a71 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -6005,6 +6005,9 @@ window_change_signal (signalnum) /* If we don't have an argument, */
6005 6005
6006 struct tty_display_info *tty; 6006 struct tty_display_info *tty;
6007 6007
6008 signal (SIGWINCH, window_change_signal);
6009 SIGNAL_THREAD_CHECK (signalnum);
6010
6008 /* The frame size change obviously applies to a single 6011 /* The frame size change obviously applies to a single
6009 termcap-controlled terminal, but we can't decide which. 6012 termcap-controlled terminal, but we can't decide which.
6010 Therefore, we resize the frames corresponding to each tty. 6013 Therefore, we resize the frames corresponding to each tty.
@@ -6028,7 +6031,6 @@ window_change_signal (signalnum) /* If we don't have an argument, */
6028 } 6031 }
6029 } 6032 }
6030 6033
6031 signal (SIGWINCH, window_change_signal);
6032 errno = old_errno; 6034 errno = old_errno;
6033} 6035}
6034#endif /* SIGWINCH */ 6036#endif /* SIGWINCH */
diff --git a/src/emacs.c b/src/emacs.c
index fb7c573836a..b16ea78b9b8 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -343,6 +343,14 @@ int fatal_error_in_progress;
343 343
344void (*fatal_error_signal_hook) P_ ((void)); 344void (*fatal_error_signal_hook) P_ ((void));
345 345
346#ifdef HAVE_GTK_AND_PTHREAD
347/* When compiled with GTK and running under Gnome, multiple threads meay be
348 created. Keep track of our main thread to make sure signals are delivered
349 to it (see syssignal.h). */
350
351pthread_t main_thread;
352#endif
353
346 354
347#ifdef SIGUSR1 355#ifdef SIGUSR1
348SIGTYPE 356SIGTYPE
@@ -351,6 +359,7 @@ handle_USR1_signal (sig)
351{ 359{
352 struct input_event buf; 360 struct input_event buf;
353 361
362 SIGNAL_THREAD_CHECK (sig);
354 bzero (&buf, sizeof buf); 363 bzero (&buf, sizeof buf);
355 buf.kind = USER_SIGNAL_EVENT; 364 buf.kind = USER_SIGNAL_EVENT;
356 buf.frame_or_window = selected_frame; 365 buf.frame_or_window = selected_frame;
@@ -366,6 +375,7 @@ handle_USR2_signal (sig)
366{ 375{
367 struct input_event buf; 376 struct input_event buf;
368 377
378 SIGNAL_THREAD_CHECK (sig);
369 bzero (&buf, sizeof buf); 379 bzero (&buf, sizeof buf);
370 buf.kind = USER_SIGNAL_EVENT; 380 buf.kind = USER_SIGNAL_EVENT;
371 buf.code = 1; 381 buf.code = 1;
@@ -380,6 +390,7 @@ SIGTYPE
380fatal_error_signal (sig) 390fatal_error_signal (sig)
381 int sig; 391 int sig;
382{ 392{
393 SIGNAL_THREAD_CHECK (sig);
383 fatal_error_code = sig; 394 fatal_error_code = sig;
384 signal (sig, SIG_DFL); 395 signal (sig, SIG_DFL);
385 396
@@ -419,6 +430,7 @@ memory_warning_signal (sig)
419 int sig; 430 int sig;
420{ 431{
421 signal (sig, memory_warning_signal); 432 signal (sig, memory_warning_signal);
433 SIGNAL_THREAD_CHECK (sig);
422 434
423 malloc_warning ("Operating system warns that virtual memory is running low.\n"); 435 malloc_warning ("Operating system warns that virtual memory is running low.\n");
424 436
@@ -1024,10 +1036,16 @@ main (argc, argv
1024 Also call realloc and free for consistency. */ 1036 Also call realloc and free for consistency. */
1025 free (realloc (malloc (4), 4)); 1037 free (realloc (malloc (4), 4));
1026 1038
1039# ifndef SYNC_INPUT
1027 /* Arrange to disable interrupt input inside malloc etc. */ 1040 /* Arrange to disable interrupt input inside malloc etc. */
1028 uninterrupt_malloc (); 1041 uninterrupt_malloc ();
1042# endif /* not SYNC_INPUT */
1029#endif /* not SYSTEM_MALLOC */ 1043#endif /* not SYSTEM_MALLOC */
1030 1044
1045#ifdef HAVE_GTK_AND_PTHREAD
1046 main_thread = pthread_self ();
1047#endif /* HAVE_GTK_AND_PTHREAD */
1048
1031#if defined (MSDOS) || defined (WINDOWSNT) 1049#if defined (MSDOS) || defined (WINDOWSNT)
1032 /* We do all file input/output as binary files. When we need to translate 1050 /* We do all file input/output as binary files. When we need to translate
1033 newlines, we do that manually. */ 1051 newlines, we do that manually. */
@@ -1116,7 +1134,10 @@ main (argc, argv
1116 /* Handle the -batch switch, which means don't do interactive display. */ 1134 /* Handle the -batch switch, which means don't do interactive display. */
1117 noninteractive = 0; 1135 noninteractive = 0;
1118 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args)) 1136 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
1119 noninteractive = 1; 1137 {
1138 noninteractive = 1;
1139 Vundo_outer_limit = Qnil;
1140 }
1120 if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args)) 1141 if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args))
1121 { 1142 {
1122 noninteractive = 1; /* Set batch mode. */ 1143 noninteractive = 1; /* Set batch mode. */
@@ -2237,7 +2258,7 @@ You must run Emacs in batch mode in order to dump it. */)
2237 memory_warnings (my_edata, malloc_warning); 2258 memory_warnings (my_edata, malloc_warning);
2238#endif /* not WINDOWSNT */ 2259#endif /* not WINDOWSNT */
2239#endif 2260#endif
2240#if ! defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) 2261#if !defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) && !defined SYNC_INPUT
2241 /* Pthread may call malloc before main, and then we will get an endless 2262 /* Pthread may call malloc before main, and then we will get an endless
2242 loop, because pthread_self (see alloc.c) calls malloc the first time 2263 loop, because pthread_self (see alloc.c) calls malloc the first time
2243 it is called on some systems. */ 2264 it is called on some systems. */
diff --git a/src/eval.c b/src/eval.c
index 0eb519fbfca..df528e3da80 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1178,6 +1178,7 @@ unwind_to_catch (catch, value)
1178 set_poll_suppress_count (catch->poll_suppress_count); 1178 set_poll_suppress_count (catch->poll_suppress_count);
1179 interrupt_input_blocked = catch->interrupt_input_blocked; 1179 interrupt_input_blocked = catch->interrupt_input_blocked;
1180 handling_signal = 0; 1180 handling_signal = 0;
1181 immediate_quit = 0;
1181 1182
1182 do 1183 do
1183 { 1184 {
@@ -3331,7 +3332,11 @@ Emacs could overflow the real C stack, and crash. */);
3331 3332
3332 DEFVAR_LISP ("quit-flag", &Vquit_flag, 3333 DEFVAR_LISP ("quit-flag", &Vquit_flag,
3333 doc: /* Non-nil causes `eval' to abort, unless `inhibit-quit' is non-nil. 3334 doc: /* Non-nil causes `eval' to abort, unless `inhibit-quit' is non-nil.
3334Typing C-g sets `quit-flag' non-nil, regardless of `inhibit-quit'. */); 3335If the value is t, that means do an ordinary quit.
3336If the value equals `throw-on-input', that means quit by throwing
3337to the tag specified in `throw-on-input'; it's for handling `while-no-input'.
3338Typing C-g sets `quit-flag' to t, regardless of `inhibit-quit',
3339but `inhibit-quit' non-nil prevents anything from taking notice of that. */);
3335 Vquit_flag = Qnil; 3340 Vquit_flag = Qnil;
3336 3341
3337 DEFVAR_LISP ("inhibit-quit", &Vinhibit_quit, 3342 DEFVAR_LISP ("inhibit-quit", &Vinhibit_quit,
diff --git a/src/fileio.c b/src/fileio.c
index 587f36d537d..195cff2bc8c 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -230,6 +230,8 @@ extern int minibuf_level;
230 230
231extern int minibuffer_auto_raise; 231extern int minibuffer_auto_raise;
232 232
233extern int history_delete_duplicates;
234
233/* These variables describe handlers that have "already" had a chance 235/* These variables describe handlers that have "already" had a chance
234 to handle the current operation. 236 to handle the current operation.
235 237
@@ -6385,7 +6387,13 @@ and `read-file-name-function'. */)
6385 if (replace_in_history) 6387 if (replace_in_history)
6386 /* Replace what Fcompleting_read added to the history 6388 /* Replace what Fcompleting_read added to the history
6387 with what we will actually return. */ 6389 with what we will actually return. */
6388 XSETCAR (Fsymbol_value (Qfile_name_history), double_dollars (val)); 6390 {
6391 Lisp_Object val1 = double_dollars (val);
6392 tem = Fsymbol_value (Qfile_name_history);
6393 if (history_delete_duplicates)
6394 XSETCDR (tem, Fdelete (val1, XCDR(tem)));
6395 XSETCAR (tem, val1);
6396 }
6389 else if (add_to_history) 6397 else if (add_to_history)
6390 { 6398 {
6391 /* Add the value to the history--but not if it matches 6399 /* Add the value to the history--but not if it matches
@@ -6393,8 +6401,10 @@ and `read-file-name-function'. */)
6393 Lisp_Object val1 = double_dollars (val); 6401 Lisp_Object val1 = double_dollars (val);
6394 tem = Fsymbol_value (Qfile_name_history); 6402 tem = Fsymbol_value (Qfile_name_history);
6395 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1))) 6403 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1)))
6396 Fset (Qfile_name_history, 6404 {
6397 Fcons (val1, tem)); 6405 if (history_delete_duplicates) tem = Fdelete (val1, tem);
6406 Fset (Qfile_name_history, Fcons (val1, tem));
6407 }
6398 } 6408 }
6399 6409
6400 return val; 6410 return val;
diff --git a/src/floatfns.c b/src/floatfns.c
index 61879eabe39..8cd08106ef2 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -981,6 +981,7 @@ float_error (signo)
981 signal (SIGILL, float_error); 981 signal (SIGILL, float_error);
982#endif /* BSD_SYSTEM */ 982#endif /* BSD_SYSTEM */
983 983
984 SIGNAL_THREAD_CHECK (signo);
984 in_float = 0; 985 in_float = 0;
985 986
986 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil)); 987 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil));
diff --git a/src/indent.c b/src/indent.c
index 4efb5445f7e..7cfe53d80bb 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2094,8 +2094,9 @@ whether or not it is currently displayed in some window. */)
2094 move_it_by_lines (&it, -1, 0); 2094 move_it_by_lines (&it, -1, 0);
2095 2095
2096 it.vpos = 0; 2096 it.vpos = 0;
2097 if (XINT (lines) != 0) 2097 /* Do this even if LINES is 0, so that we move back
2098 move_it_by_lines (&it, XINT (lines), 0); 2098 to the beginning of the current line as we ought. */
2099 move_it_by_lines (&it, XINT (lines), 0);
2099 2100
2100 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 2101 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2101 } 2102 }
diff --git a/src/keyboard.c b/src/keyboard.c
index 052ef2d38b7..122a8e6b025 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3038,6 +3038,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
3038 /* Save the echo status. */ 3038 /* Save the echo status. */
3039 int saved_immediate_echo = current_kboard->immediate_echo; 3039 int saved_immediate_echo = current_kboard->immediate_echo;
3040 struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause; 3040 struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
3041 Lisp_Object saved_echo_string = current_kboard->echo_string;
3041 int saved_echo_after_prompt = current_kboard->echo_after_prompt; 3042 int saved_echo_after_prompt = current_kboard->echo_after_prompt;
3042 3043
3043#if 0 3044#if 0
@@ -3092,6 +3093,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
3092 3093
3093 cancel_echoing (); 3094 cancel_echoing ();
3094 ok_to_echo_at_next_pause = saved_ok_to_echo; 3095 ok_to_echo_at_next_pause = saved_ok_to_echo;
3096 current_kboard->echo_string = saved_echo_string;
3095 current_kboard->echo_after_prompt = saved_echo_after_prompt; 3097 current_kboard->echo_after_prompt = saved_echo_after_prompt;
3096 if (saved_immediate_echo) 3098 if (saved_immediate_echo)
3097 echo_now (); 3099 echo_now ();
@@ -3574,6 +3576,9 @@ event_to_kboard (event)
3574} 3576}
3575#endif 3577#endif
3576 3578
3579
3580Lisp_Object Vthrow_on_input;
3581
3577/* Store an event obtained at interrupt level into kbd_buffer, fifo */ 3582/* Store an event obtained at interrupt level into kbd_buffer, fifo */
3578 3583
3579void 3584void
@@ -3699,6 +3704,24 @@ kbd_buffer_store_event_hold (event, hold_quit)
3699 *kbd_store_ptr = *event; 3704 *kbd_store_ptr = *event;
3700 ++kbd_store_ptr; 3705 ++kbd_store_ptr;
3701 } 3706 }
3707
3708 /* If we're inside while-no-input, and this event qualifies
3709 as input, set quit-flag to cause an interrupt. */
3710 if (!NILP (Vthrow_on_input)
3711 && event->kind != FOCUS_IN_EVENT
3712 && event->kind != HELP_EVENT
3713 && event->kind != DEICONIFY_EVENT)
3714 {
3715 Vquit_flag = Vthrow_on_input;
3716 /* If we're inside a function that wants immediate quits,
3717 do it now. */
3718 if (immediate_quit && NILP (Vinhibit_quit))
3719 {
3720 immediate_quit = 0;
3721 sigfree ();
3722 QUIT;
3723 }
3724 }
3702} 3725}
3703 3726
3704 3727
@@ -6849,24 +6872,6 @@ handle_async_input ()
6849#ifdef BSD4_1 6872#ifdef BSD4_1
6850 extern int select_alarmed; 6873 extern int select_alarmed;
6851#endif 6874#endif
6852#if ! defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD)
6853 extern pthread_t main_thread;
6854 if (pthread_self () != main_thread)
6855 {
6856 /* POSIX says any thread can receive the signal. On GNU/Linux that is
6857 not true, but for other systems (FreeBSD at least) it is. So direct
6858 the signal to the correct thread and block it from this thread. */
6859#ifdef SIGIO
6860 sigset_t new_mask;
6861
6862 sigemptyset (&new_mask);
6863 sigaddset (&new_mask, SIGIO);
6864 pthread_sigmask (SIG_BLOCK, &new_mask, 0);
6865 pthread_kill (main_thread, SIGIO);
6866#endif
6867 return;
6868 }
6869#endif
6870 6875
6871 interrupt_input_pending = 0; 6876 interrupt_input_pending = 0;
6872 6877
@@ -6895,22 +6900,6 @@ input_available_signal (signo)
6895{ 6900{
6896 /* Must preserve main program's value of errno. */ 6901 /* Must preserve main program's value of errno. */
6897 int old_errno = errno; 6902 int old_errno = errno;
6898#if ! defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD)
6899 extern pthread_t main_thread;
6900 if (pthread_self () != main_thread)
6901 {
6902 /* POSIX says any thread can receive the signal. On GNU/Linux that is
6903 not true, but for other systems (FreeBSD at least) it is. So direct
6904 the signal to the correct thread and block it from this thread. */
6905 sigset_t new_mask;
6906
6907 sigemptyset (&new_mask);
6908 sigaddset (&new_mask, SIGIO);
6909 pthread_sigmask (SIG_BLOCK, &new_mask, 0);
6910 pthread_kill (main_thread, SIGIO);
6911 return;
6912 }
6913#endif /* HAVE_GTK_AND_PTHREAD */
6914#if defined (USG) && !defined (POSIX_SIGNALS) 6903#if defined (USG) && !defined (POSIX_SIGNALS)
6915 /* USG systems forget handlers when they are used; 6904 /* USG systems forget handlers when they are used;
6916 must reestablish each time */ 6905 must reestablish each time */
@@ -6927,6 +6916,8 @@ input_available_signal (signo)
6927#ifdef SYNC_INPUT 6916#ifdef SYNC_INPUT
6928 interrupt_input_pending = 1; 6917 interrupt_input_pending = 1;
6929#else 6918#else
6919
6920 SIGNAL_THREAD_CHECK (signo);
6930 handle_async_input (); 6921 handle_async_input ();
6931#endif 6922#endif
6932 6923
@@ -10379,6 +10370,7 @@ handle_interrupt ()
10379 char c; 10370 char c;
10380 struct frame *sf = SELECTED_FRAME (); 10371 struct frame *sf = SELECTED_FRAME ();
10381 10372
10373 SIGNAL_THREAD_CHECK (signalnum);
10382 cancel_echoing (); 10374 cancel_echoing ();
10383 10375
10384 /* XXX This code needs to be revised for multi-tty support. */ 10376 /* XXX This code needs to be revised for multi-tty support. */
@@ -11525,6 +11517,12 @@ Used during Emacs' startup. */);
11525 doc: /* *How long to display an echo-area message when the minibuffer is active. 11517 doc: /* *How long to display an echo-area message when the minibuffer is active.
11526If the value is not a number, such messages don't time out. */); 11518If the value is not a number, such messages don't time out. */);
11527 Vminibuffer_message_timeout = make_number (2); 11519 Vminibuffer_message_timeout = make_number (2);
11520
11521 DEFVAR_LISP ("throw-on-input", &Vthrow_on_input,
11522 doc: /* If non-nil, any keyboard input throws to this symbol.
11523The value of that variable is passed to `quit-flag' and later causes a
11524peculiar kind of quitting. */);
11525 Vthrow_on_input = Qnil;
11528} 11526}
11529 11527
11530void 11528void
diff --git a/src/lisp.h b/src/lisp.h
index 8be6b910a5e..59ce03435f5 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1768,11 +1768,15 @@ extern char *stack_bottom;
1768#ifdef SYNC_INPUT 1768#ifdef SYNC_INPUT
1769extern void handle_async_input P_ ((void)); 1769extern void handle_async_input P_ ((void));
1770extern int interrupt_input_pending; 1770extern int interrupt_input_pending;
1771
1771#define QUIT \ 1772#define QUIT \
1772 do { \ 1773 do { \
1773 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \ 1774 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
1774 { \ 1775 { \
1776 Lisp_Object flag = Vquit_flag; \
1775 Vquit_flag = Qnil; \ 1777 Vquit_flag = Qnil; \
1778 if (EQ (Vthrow_on_input, flag)) \
1779 Fthrow (Vthrow_on_input, Qnil); \
1776 Fsignal (Qquit, Qnil); \ 1780 Fsignal (Qquit, Qnil); \
1777 } \ 1781 } \
1778 else if (interrupt_input_pending) \ 1782 else if (interrupt_input_pending) \
@@ -1785,7 +1789,10 @@ extern int interrupt_input_pending;
1785 do { \ 1789 do { \
1786 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \ 1790 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
1787 { \ 1791 { \
1792 Lisp_Object flag = Vquit_flag; \
1788 Vquit_flag = Qnil; \ 1793 Vquit_flag = Qnil; \
1794 if (EQ (Vthrow_on_input, flag)) \
1795 Fthrow (Vthrow_on_input, Qnil); \
1789 Fsignal (Qquit, Qnil); \ 1796 Fsignal (Qquit, Qnil); \
1790 } \ 1797 } \
1791 } while (0) 1798 } while (0)
@@ -2876,6 +2883,7 @@ extern struct kboard *echo_kboard;
2876extern void cancel_echoing P_ ((void)); 2883extern void cancel_echoing P_ ((void));
2877extern Lisp_Object Qdisabled, QCfilter; 2884extern Lisp_Object Qdisabled, QCfilter;
2878extern Lisp_Object Vtty_erase_char, Vhelp_form, Vtop_level; 2885extern Lisp_Object Vtty_erase_char, Vhelp_form, Vtop_level;
2886extern Lisp_Object Vthrow_on_input;
2879extern int input_pending; 2887extern int input_pending;
2880EXFUN (Fdiscard_input, 0); 2888EXFUN (Fdiscard_input, 0);
2881EXFUN (Frecursive_edit, 0); 2889EXFUN (Frecursive_edit, 0);
@@ -3041,7 +3049,7 @@ extern void syms_of_macros P_ ((void));
3041/* defined in undo.c */ 3049/* defined in undo.c */
3042extern Lisp_Object Qinhibit_read_only; 3050extern Lisp_Object Qinhibit_read_only;
3043EXFUN (Fundo_boundary, 0); 3051EXFUN (Fundo_boundary, 0);
3044extern Lisp_Object truncate_undo_list P_ ((Lisp_Object, int, int, int)); 3052extern void truncate_undo_list P_ ((struct buffer *));
3045extern void record_marker_adjustment P_ ((Lisp_Object, int)); 3053extern void record_marker_adjustment P_ ((Lisp_Object, int));
3046extern void record_insert P_ ((int, int)); 3054extern void record_insert P_ ((int, int));
3047extern void record_delete P_ ((int, Lisp_Object)); 3055extern void record_delete P_ ((int, Lisp_Object));
@@ -3050,6 +3058,7 @@ extern void record_change P_ ((int, int));
3050extern void record_property_change P_ ((int, int, Lisp_Object, Lisp_Object, 3058extern void record_property_change P_ ((int, int, Lisp_Object, Lisp_Object,
3051 Lisp_Object)); 3059 Lisp_Object));
3052extern void syms_of_undo P_ ((void)); 3060extern void syms_of_undo P_ ((void));
3061extern Lisp_Object Vundo_outer_limit;
3053 3062
3054/* defined in textprop.c */ 3063/* defined in textprop.c */
3055extern Lisp_Object Qfont, Qmouse_face; 3064extern Lisp_Object Qfont, Qmouse_face;
diff --git a/src/macterm.c b/src/macterm.c
index b0a7edeb516..da3dcb15ee8 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -5976,7 +5976,7 @@ mac_to_x_fontname (name, size, style, scriptcode, encoding_base)
5976 strcpy(cs, "mac-cyrillic"); 5976 strcpy(cs, "mac-cyrillic");
5977 break; 5977 break;
5978 case kTextEncodingMacCentralEurRoman: 5978 case kTextEncodingMacCentralEurRoman:
5979 strcpy(cs, "mac-centraleuropean"); 5979 strcpy(cs, "mac-centraleurroman");
5980 break; 5980 break;
5981 case kTextEncodingMacSymbol: 5981 case kTextEncodingMacSymbol:
5982 case kTextEncodingMacDingbats: 5982 case kTextEncodingMacDingbats:
@@ -6034,7 +6034,7 @@ x_font_name_to_mac_font_name (char *xf, char *mf)
6034 coding_system = Qeuc_kr; 6034 coding_system = Qeuc_kr;
6035 else if (strcmp (cs, "mac-roman") == 0 6035 else if (strcmp (cs, "mac-roman") == 0
6036 || strcmp (cs, "mac-cyrillic") == 0 6036 || strcmp (cs, "mac-cyrillic") == 0
6037 || strcmp (cs, "mac-centraleuropean") == 0 6037 || strcmp (cs, "mac-centraleurroman") == 0
6038 || strcmp (cs, "adobe-fontspecific") == 0) 6038 || strcmp (cs, "adobe-fontspecific") == 0)
6039 strcpy (mf, family); 6039 strcpy (mf, family);
6040 else 6040 else
@@ -6276,6 +6276,28 @@ static int xlfd_scalable_fields[] =
6276 }; 6276 };
6277 6277
6278static Lisp_Object 6278static Lisp_Object
6279mac_c_string_match (regexp, string, nonspecial, exact)
6280 Lisp_Object regexp;
6281 const char *string, *nonspecial;
6282 int exact;
6283{
6284 if (exact)
6285 {
6286 if (strcmp (string, nonspecial) == 0)
6287 return build_string (string);
6288 }
6289 else if (strstr (string, nonspecial))
6290 {
6291 Lisp_Object str = build_string (string);
6292
6293 if (fast_string_match (regexp, str) >= 0)
6294 return str;
6295 }
6296
6297 return Qnil;
6298}
6299
6300static Lisp_Object
6279mac_do_list_fonts (pattern, maxnames) 6301mac_do_list_fonts (pattern, maxnames)
6280 char *pattern; 6302 char *pattern;
6281 int maxnames; 6303 int maxnames;
@@ -6286,6 +6308,8 @@ mac_do_list_fonts (pattern, maxnames)
6286 char scaled[256]; 6308 char scaled[256];
6287 char *ptr; 6309 char *ptr;
6288 int scl_val[XLFD_SCL_LAST], *field, *val; 6310 int scl_val[XLFD_SCL_LAST], *field, *val;
6311 char *longest_start, *cur_start, *nonspecial;
6312 int longest_len, cur_len, exact;
6289 6313
6290 for (i = 0; i < XLFD_SCL_LAST; i++) 6314 for (i = 0; i < XLFD_SCL_LAST; i++)
6291 scl_val[i] = -1; 6315 scl_val[i] = -1;
@@ -6343,34 +6367,66 @@ mac_do_list_fonts (pattern, maxnames)
6343 ptr = regex; 6367 ptr = regex;
6344 *ptr++ = '^'; 6368 *ptr++ = '^';
6345 6369
6346 /* Turn pattern into a regexp and do a regexp match. */ 6370 longest_start = cur_start = ptr;
6371 longest_len = cur_len = 0;
6372 exact = 1;
6373
6374 /* Turn pattern into a regexp and do a regexp match. Also find the
6375 longest substring containing no special characters. */
6347 for (; *pattern; pattern++) 6376 for (; *pattern; pattern++)
6348 { 6377 {
6349 if (*pattern == '?') 6378 if (*pattern == '?' || *pattern == '*')
6350 *ptr++ = '.'; 6379 {
6351 else if (*pattern == '*') 6380 if (cur_len > longest_len)
6352 { 6381 {
6353 *ptr++ = '.'; 6382 longest_start = cur_start;
6354 *ptr++ = '*'; 6383 longest_len = cur_len;
6355 } 6384 }
6385 cur_len = 0;
6386 exact = 0;
6387
6388 if (*pattern == '?')
6389 *ptr++ = '.';
6390 else /* if (*pattern == '*') */
6391 {
6392 *ptr++ = '.';
6393 *ptr++ = '*';
6394 }
6395 }
6356 else 6396 else
6357 *ptr++ = tolower (*pattern); 6397 {
6398 if (cur_len == 0)
6399 cur_start = ptr;
6400 cur_len++;
6401
6402 *ptr++ = tolower (*pattern);
6403 }
6358 } 6404 }
6405
6406 if (cur_len > longest_len)
6407 {
6408 longest_start = cur_start;
6409 longest_len = cur_len;
6410 }
6411
6359 *ptr = '$'; 6412 *ptr = '$';
6360 *(ptr + 1) = '\0'; 6413 *(ptr + 1) = '\0';
6361 6414
6415 nonspecial = xmalloc (longest_len + 1);
6416 strncpy (nonspecial, longest_start, longest_len);
6417 nonspecial[longest_len] = '\0';
6418
6362 pattern_regex = build_string (regex); 6419 pattern_regex = build_string (regex);
6363 6420
6364 for (i = 0; i < font_name_count; i++) 6421 for (i = 0; i < font_name_count; i++)
6365 { 6422 {
6366 fontname = build_string (font_name_table[i]); 6423 fontname = mac_c_string_match (pattern_regex, font_name_table[i],
6367 if (fast_string_match (pattern_regex, fontname) >= 0) 6424 nonspecial, exact);
6425 if (!NILP (fontname))
6368 { 6426 {
6369 font_list = Fcons (fontname, font_list); 6427 font_list = Fcons (fontname, font_list);
6370 6428 if (exact || maxnames > 0 && ++n_fonts >= maxnames)
6371 n_fonts++; 6429 break;
6372 if (maxnames > 0 && n_fonts >= maxnames)
6373 break;
6374 } 6430 }
6375 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0 6431 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
6376 && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-"))) 6432 && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-")))
@@ -6384,17 +6440,19 @@ mac_do_list_fonts (pattern, maxnames)
6384 scl_val[XLFD_SCL_POINT_SIZE], 6440 scl_val[XLFD_SCL_POINT_SIZE],
6385 scl_val[XLFD_SCL_AVGWIDTH], 6441 scl_val[XLFD_SCL_AVGWIDTH],
6386 ptr + sizeof ("-0-0-75-75-m-0-") - 1); 6442 ptr + sizeof ("-0-0-75-75-m-0-") - 1);
6387 fontname = build_string (scaled); 6443 fontname = mac_c_string_match (pattern_regex, scaled,
6388 if (fast_string_match (pattern_regex, fontname) >= 0) 6444 nonspecial, exact);
6445 if (!NILP (fontname))
6389 { 6446 {
6390 font_list = Fcons (fontname, font_list); 6447 font_list = Fcons (fontname, font_list);
6391 6448 if (exact || maxnames > 0 && ++n_fonts >= maxnames)
6392 n_fonts++;
6393 if (maxnames > 0 && n_fonts >= maxnames)
6394 break; 6449 break;
6395 } 6450 }
6396 } 6451 }
6397 } 6452 }
6453
6454 xfree (nonspecial);
6455
6398 return font_list; 6456 return font_list;
6399} 6457}
6400 6458
diff --git a/src/minibuf.c b/src/minibuf.c
index 375fa3622b3..463c083cb5e 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1232,6 +1232,7 @@ is used to further constrain the set of candidates. */)
1232 return call3 (alist, string, predicate, Qnil); 1232 return call3 (alist, string, predicate, Qnil);
1233 1233
1234 bestmatch = bucket = Qnil; 1234 bestmatch = bucket = Qnil;
1235 zero = make_number (0);
1235 1236
1236 /* If ALIST is not a list, set TAIL just for gc pro. */ 1237 /* If ALIST is not a list, set TAIL just for gc pro. */
1237 tail = alist; 1238 tail = alist;
@@ -1258,7 +1259,7 @@ is used to further constrain the set of candidates. */)
1258 } 1259 }
1259 else if (type == 2) 1260 else if (type == 2)
1260 { 1261 {
1261 if (XFASTINT (bucket) != 0) 1262 if (!EQ (bucket, zero))
1262 { 1263 {
1263 elt = bucket; 1264 elt = bucket;
1264 eltstring = Fsymbol_name (elt); 1265 eltstring = Fsymbol_name (elt);
@@ -1290,16 +1291,14 @@ is used to further constrain the set of candidates. */)
1290 1291
1291 if (STRINGP (eltstring) 1292 if (STRINGP (eltstring)
1292 && SCHARS (string) <= SCHARS (eltstring) 1293 && SCHARS (string) <= SCHARS (eltstring)
1293 && (tem = Fcompare_strings (eltstring, make_number (0), 1294 && (tem = Fcompare_strings (eltstring, zero,
1294 make_number (SCHARS (string)), 1295 make_number (SCHARS (string)),
1295 string, make_number (0), Qnil, 1296 string, zero, Qnil,
1296 completion_ignore_case ? Qt : Qnil), 1297 completion_ignore_case ? Qt : Qnil),
1297 EQ (Qt, tem))) 1298 EQ (Qt, tem)))
1298 { 1299 {
1299 /* Yes. */ 1300 /* Yes. */
1300 Lisp_Object regexps; 1301 Lisp_Object regexps;
1301 Lisp_Object zero;
1302 XSETFASTINT (zero, 0);
1303 1302
1304 /* Ignore this element if it fails to match all the regexps. */ 1303 /* Ignore this element if it fails to match all the regexps. */
1305 { 1304 {
@@ -1353,9 +1352,9 @@ is used to further constrain the set of candidates. */)
1353 else 1352 else
1354 { 1353 {
1355 compare = min (bestmatchsize, SCHARS (eltstring)); 1354 compare = min (bestmatchsize, SCHARS (eltstring));
1356 tem = Fcompare_strings (bestmatch, make_number (0), 1355 tem = Fcompare_strings (bestmatch, zero,
1357 make_number (compare), 1356 make_number (compare),
1358 eltstring, make_number (0), 1357 eltstring, zero,
1359 make_number (compare), 1358 make_number (compare),
1360 completion_ignore_case ? Qt : Qnil); 1359 completion_ignore_case ? Qt : Qnil);
1361 if (EQ (tem, Qt)) 1360 if (EQ (tem, Qt))
@@ -1386,15 +1385,15 @@ is used to further constrain the set of candidates. */)
1386 ((matchsize == SCHARS (eltstring)) 1385 ((matchsize == SCHARS (eltstring))
1387 == 1386 ==
1388 (matchsize == SCHARS (bestmatch)) 1387 (matchsize == SCHARS (bestmatch))
1389 && (tem = Fcompare_strings (eltstring, make_number (0), 1388 && (tem = Fcompare_strings (eltstring, zero,
1390 make_number (SCHARS (string)), 1389 make_number (SCHARS (string)),
1391 string, make_number (0), 1390 string, zero,
1392 Qnil, 1391 Qnil,
1393 Qnil), 1392 Qnil),
1394 EQ (Qt, tem)) 1393 EQ (Qt, tem))
1395 && (tem = Fcompare_strings (bestmatch, make_number (0), 1394 && (tem = Fcompare_strings (bestmatch, zero,
1396 make_number (SCHARS (string)), 1395 make_number (SCHARS (string)),
1397 string, make_number (0), 1396 string, zero,
1398 Qnil, 1397 Qnil,
1399 Qnil), 1398 Qnil),
1400 ! EQ (Qt, tem)))) 1399 ! EQ (Qt, tem))))
@@ -1481,13 +1480,14 @@ are ignored unless STRING itself starts with a space. */)
1481 || NILP (XCAR (alist)))); 1480 || NILP (XCAR (alist))));
1482 int index = 0, obsize = 0; 1481 int index = 0, obsize = 0;
1483 int bindcount = -1; 1482 int bindcount = -1;
1484 Lisp_Object bucket, tem; 1483 Lisp_Object bucket, tem, zero;
1485 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 1484 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1486 1485
1487 CHECK_STRING (string); 1486 CHECK_STRING (string);
1488 if (type == 0) 1487 if (type == 0)
1489 return call3 (alist, string, predicate, Qt); 1488 return call3 (alist, string, predicate, Qt);
1490 allmatches = bucket = Qnil; 1489 allmatches = bucket = Qnil;
1490 zero = make_number (0);
1491 1491
1492 /* If ALIST is not a list, set TAIL just for gc pro. */ 1492 /* If ALIST is not a list, set TAIL just for gc pro. */
1493 tail = alist; 1493 tail = alist;
@@ -1514,7 +1514,7 @@ are ignored unless STRING itself starts with a space. */)
1514 } 1514 }
1515 else if (type == 2) 1515 else if (type == 2)
1516 { 1516 {
1517 if (XFASTINT (bucket) != 0) 1517 if (!EQ (bucket, zero))
1518 { 1518 {
1519 elt = bucket; 1519 elt = bucket;
1520 eltstring = Fsymbol_name (elt); 1520 eltstring = Fsymbol_name (elt);
@@ -1552,9 +1552,9 @@ are ignored unless STRING itself starts with a space. */)
1552 && SREF (string, 0) == ' ') 1552 && SREF (string, 0) == ' ')
1553 || SREF (eltstring, 0) != ' ' 1553 || SREF (eltstring, 0) != ' '
1554 || NILP (hide_spaces)) 1554 || NILP (hide_spaces))
1555 && (tem = Fcompare_strings (eltstring, make_number (0), 1555 && (tem = Fcompare_strings (eltstring, zero,
1556 make_number (SCHARS (string)), 1556 make_number (SCHARS (string)),
1557 string, make_number (0), 1557 string, zero,
1558 make_number (SCHARS (string)), 1558 make_number (SCHARS (string)),
1559 completion_ignore_case ? Qt : Qnil), 1559 completion_ignore_case ? Qt : Qnil),
1560 EQ (Qt, tem))) 1560 EQ (Qt, tem)))
diff --git a/src/process.c b/src/process.c
index 65dec1457b0..646b9aed6a8 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5104,6 +5104,7 @@ Lisp_Object process_sent_to;
5104SIGTYPE 5104SIGTYPE
5105send_process_trap () 5105send_process_trap ()
5106{ 5106{
5107 SIGNAL_THREAD_CHECK (SIGPIPE);
5107#ifdef BSD4_1 5108#ifdef BSD4_1
5108 sigrelse (SIGPIPE); 5109 sigrelse (SIGPIPE);
5109 sigrelse (SIGALRM); 5110 sigrelse (SIGALRM);
@@ -6146,6 +6147,8 @@ sigchld_handler (signo)
6146 register struct Lisp_Process *p; 6147 register struct Lisp_Process *p;
6147 extern EMACS_TIME *input_available_clear_time; 6148 extern EMACS_TIME *input_available_clear_time;
6148 6149
6150 SIGNAL_THREAD_CHECK (signo);
6151
6149#ifdef BSD4_1 6152#ifdef BSD4_1
6150 extern int sigheld; 6153 extern int sigheld;
6151 sigheld |= sigbit (SIGCHLD); 6154 sigheld |= sigbit (SIGCHLD);
diff --git a/src/regex.c b/src/regex.c
index 1009c837dcf..a223f170765 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -5860,7 +5860,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
5860 PREFETCH_NOLIMIT (); 5860 PREFETCH_NOLIMIT ();
5861 c2 = RE_STRING_CHAR (d, dend - d); 5861 c2 = RE_STRING_CHAR (d, dend - d);
5862#ifdef emacs 5862#ifdef emacs
5863 UPDATE_SYNTAX_TABLE_FORWARD (charpos); 5863 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
5864#endif 5864#endif
5865 s2 = SYNTAX (c2); 5865 s2 = SYNTAX (c2);
5866 5866
@@ -5947,7 +5947,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
5947 PREFETCH_NOLIMIT (); 5947 PREFETCH_NOLIMIT ();
5948 c2 = RE_STRING_CHAR (d, dend - d); 5948 c2 = RE_STRING_CHAR (d, dend - d);
5949#ifdef emacs 5949#ifdef emacs
5950 UPDATE_SYNTAX_TABLE_FORWARD (charpos); 5950 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
5951#endif 5951#endif
5952 s2 = SYNTAX (c2); 5952 s2 = SYNTAX (c2);
5953 5953
diff --git a/src/syntax.c b/src/syntax.c
index 8bfa62b49fc..fa34c2433c1 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1295,6 +1295,7 @@ and the function returns nil. Field boundaries are not noticed if
1295 (arg) 1295 (arg)
1296 Lisp_Object arg; 1296 Lisp_Object arg;
1297{ 1297{
1298 Lisp_Object tmp;
1298 int orig_val, val; 1299 int orig_val, val;
1299 1300
1300 if (NILP (arg)) 1301 if (NILP (arg))
@@ -1307,8 +1308,9 @@ and the function returns nil. Field boundaries are not noticed if
1307 val = XINT (arg) > 0 ? ZV : BEGV; 1308 val = XINT (arg) > 0 ? ZV : BEGV;
1308 1309
1309 /* Avoid jumping out of an input field. */ 1310 /* Avoid jumping out of an input field. */
1310 val = XFASTINT (Fconstrain_to_field (make_number (val), make_number (PT), 1311 tmp = Fconstrain_to_field (make_number (val), make_number (PT),
1311 Qt, Qnil, Qnil)); 1312 Qt, Qnil, Qnil);
1313 val = XFASTINT (tmp);
1312 1314
1313 SET_PT (val); 1315 SET_PT (val);
1314 return val == orig_val ? Qt : Qnil; 1316 return val == orig_val ? Qt : Qnil;
diff --git a/src/sysdep.c b/src/sysdep.c
index fb7b9275fc7..55b333bfbc9 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2567,6 +2567,7 @@ select_alarm ()
2567#else /* not BSD4_1 */ 2567#else /* not BSD4_1 */
2568 signal (SIGALRM, SIG_IGN); 2568 signal (SIGALRM, SIG_IGN);
2569#endif /* not BSD4_1 */ 2569#endif /* not BSD4_1 */
2570 SIGNAL_THREAD_CHECK (SIGALRM);
2570 if (read_alarm_should_throw) 2571 if (read_alarm_should_throw)
2571 longjmp (read_alarm_throw, 1); 2572 longjmp (read_alarm_throw, 1);
2572} 2573}
diff --git a/src/syssignal.h b/src/syssignal.h
index 8d58325c02c..ab61d111398 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -20,6 +20,11 @@ Boston, MA 02111-1307, USA. */
20 20
21extern void init_signals P_ ((void)); 21extern void init_signals P_ ((void));
22 22
23#ifdef HAVE_GTK_AND_PTHREAD
24#include <pthread.h>
25extern pthread_t main_thread;
26#endif
27
23#ifdef POSIX_SIGNALS 28#ifdef POSIX_SIGNALS
24 29
25/* Don't #include <signal.h>. That header should always be #included 30/* Don't #include <signal.h>. That header should always be #included
@@ -199,5 +204,27 @@ extern SIGMASKTYPE sigprocmask_set;
199char *strsignal (); 204char *strsignal ();
200#endif 205#endif
201 206
207#ifdef HAVE_GTK_AND_PTHREAD
208#define SIGNAL_THREAD_CHECK(signo) \
209 do { \
210 if (pthread_self () != main_thread) \
211 { \
212 /* POSIX says any thread can receive the signal. On GNU/Linux \
213 that is not true, but for other systems (FreeBSD at least) \
214 it is. So direct the signal to the correct thread and block \
215 it from this thread. */ \
216 sigset_t new_mask; \
217 \
218 sigemptyset (&new_mask); \
219 sigaddset (&new_mask, signo); \
220 pthread_sigmask (SIG_BLOCK, &new_mask, 0); \
221 pthread_kill (main_thread, signo); \
222 return; \
223 } \
224 } while (0)
225
226#else /* not HAVE_GTK_AND_PTHREAD */
227#define SIGNAL_THREAD_CHECK(signo)
228#endif /* not HAVE_GTK_AND_PTHREAD */
202/* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152 229/* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152
203 (do not change this comment) */ 230 (do not change this comment) */
diff --git a/src/term.c b/src/term.c
index cf79ea43531..fc60b993ea4 100644
--- a/src/term.c
+++ b/src/term.c
@@ -640,11 +640,11 @@ encode_terminal_code (src, src_len, coding)
640 required = MAX_MULTIBYTE_LENGTH * src_len; 640 required = MAX_MULTIBYTE_LENGTH * src_len;
641 if (encode_terminal_bufsize < required) 641 if (encode_terminal_bufsize < required)
642 { 642 {
643 encode_terminal_bufsize = required;
644 if (encode_terminal_bufsize == 0) 643 if (encode_terminal_bufsize == 0)
645 encode_terminal_buf = xmalloc (required); 644 encode_terminal_buf = xmalloc (required);
646 else 645 else
647 encode_terminal_buf = xrealloc (encode_terminal_buf, required); 646 encode_terminal_buf = xrealloc (encode_terminal_buf, required);
647 encode_terminal_bufsize = required;
648 } 648 }
649 649
650 buf = encode_terminal_buf; 650 buf = encode_terminal_buf;
diff --git a/src/undo.c b/src/undo.c
index 9fdc46a3b13..df4b8d08cd6 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -24,6 +24,17 @@ Boston, MA 02111-1307, USA. */
24#include "buffer.h" 24#include "buffer.h"
25#include "commands.h" 25#include "commands.h"
26 26
27/* Limits controlling how much undo information to keep. */
28
29EMACS_INT undo_limit;
30EMACS_INT undo_strong_limit;
31
32Lisp_Object Vundo_outer_limit;
33
34/* Function to call when undo_outer_limit is exceeded. */
35
36Lisp_Object Vundo_outer_limit_function;
37
27/* Last buffer for which undo information was recorded. */ 38/* Last buffer for which undo information was recorded. */
28Lisp_Object last_undo_buffer; 39Lisp_Object last_undo_buffer;
29 40
@@ -291,31 +302,35 @@ but another undo command will undo to the previous boundary. */)
291} 302}
292 303
293/* At garbage collection time, make an undo list shorter at the end, 304/* At garbage collection time, make an undo list shorter at the end,
294 returning the truncated list. 305 returning the truncated list. How this is done depends on the
295 MINSIZE, MAXSIZE and LIMITSIZE are the limits on size allowed, 306 variables undo-limit, undo-strong-limit and undo-outer-limit.
296 as described below. 307 In some cases this works by calling undo-outer-limit-function. */
297 In practice, these are the values of undo-limit, 308
298 undo-strong-limit, and undo-outer-limit. */ 309void
299 310truncate_undo_list (b)
300Lisp_Object 311 struct buffer *b;
301truncate_undo_list (list, minsize, maxsize, limitsize)
302 Lisp_Object list;
303 int minsize, maxsize, limitsize;
304{ 312{
313 Lisp_Object list;
305 Lisp_Object prev, next, last_boundary; 314 Lisp_Object prev, next, last_boundary;
306 int size_so_far = 0; 315 int size_so_far = 0;
307 316
317 /* Make sure that calling undo-outer-limit-function
318 won't cause another GC. */
319 int count = inhibit_garbage_collection ();
320
321 /* Make the buffer current to get its local values of variables such
322 as undo_limit. Also so that Vundo_outer_limit_function can
323 tell which buffer to operate on. */
324 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
325 set_buffer_internal (b);
326
327 list = b->undo_list;
328
308 prev = Qnil; 329 prev = Qnil;
309 next = list; 330 next = list;
310 last_boundary = Qnil; 331 last_boundary = Qnil;
311 332
312 /* Always preserve at least the most recent undo record 333 /* If the first element is an undo boundary, skip past it. */
313 unless it is really horribly big.
314 If the first element is an undo boundary, skip past it.
315
316 Skip, skip, skip the undo, skip, skip, skip the undo,
317 Skip, skip, skip the undo, skip to the undo bound'ry.
318 (Get it? "Skip to my Loo?") */
319 if (CONSP (next) && NILP (XCAR (next))) 334 if (CONSP (next) && NILP (XCAR (next)))
320 { 335 {
321 /* Add in the space occupied by this element and its chain link. */ 336 /* Add in the space occupied by this element and its chain link. */
@@ -326,6 +341,12 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
326 next = XCDR (next); 341 next = XCDR (next);
327 } 342 }
328 343
344 /* Always preserve at least the most recent undo record
345 unless it is really horribly big.
346
347 Skip, skip, skip the undo, skip, skip, skip the undo,
348 Skip, skip, skip the undo, skip to the undo bound'ry. */
349
329 while (CONSP (next) && ! NILP (XCAR (next))) 350 while (CONSP (next) && ! NILP (XCAR (next)))
330 { 351 {
331 Lisp_Object elt; 352 Lisp_Object elt;
@@ -341,35 +362,53 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
341 + SCHARS (XCAR (elt))); 362 + SCHARS (XCAR (elt)));
342 } 363 }
343 364
344 /* If we reach LIMITSIZE before the first boundary,
345 we're heading for memory full, so truncate the list to nothing. */
346 if (size_so_far > limitsize)
347 return Qnil;
348
349 /* Advance to next element. */ 365 /* Advance to next element. */
350 prev = next; 366 prev = next;
351 next = XCDR (next); 367 next = XCDR (next);
352 } 368 }
353 369
370 /* If by the first boundary we have already passed undo_outer_limit,
371 we're heading for memory full, so offer to clear out the list. */
372 if (INTEGERP (Vundo_outer_limit)
373 && size_so_far > XINT (Vundo_outer_limit)
374 && !NILP (Vundo_outer_limit_function))
375 {
376 Lisp_Object temp = last_undo_buffer;
377
378 /* Normally the function this calls is undo-outer-limit-truncate. */
379 if (! NILP (call1 (Vundo_outer_limit_function,
380 make_number (size_so_far))))
381 {
382 /* The function is responsible for making
383 any desired changes in buffer-undo-list. */
384 unbind_to (count, Qnil);
385 return;
386 }
387 /* That function probably used the minibuffer, and if so, that
388 changed last_undo_buffer. Change it back so that we don't
389 force next change to make an undo boundary here. */
390 last_undo_buffer = temp;
391 }
392
354 if (CONSP (next)) 393 if (CONSP (next))
355 last_boundary = prev; 394 last_boundary = prev;
356 395
357 /* Keep more if it fits. */ 396 /* Keep additional undo data, if it fits in the limits. */
358 while (CONSP (next)) 397 while (CONSP (next))
359 { 398 {
360 Lisp_Object elt; 399 Lisp_Object elt;
361 elt = XCAR (next); 400 elt = XCAR (next);
362 401
363 /* When we get to a boundary, decide whether to truncate 402 /* When we get to a boundary, decide whether to truncate
364 either before or after it. The lower threshold, MINSIZE, 403 either before or after it. The lower threshold, undo_limit,
365 tells us to truncate after it. If its size pushes past 404 tells us to truncate after it. If its size pushes past
366 the higher threshold MAXSIZE as well, we truncate before it. */ 405 the higher threshold undo_strong_limit, we truncate before it. */
367 if (NILP (elt)) 406 if (NILP (elt))
368 { 407 {
369 if (size_so_far > maxsize) 408 if (size_so_far > undo_strong_limit)
370 break; 409 break;
371 last_boundary = prev; 410 last_boundary = prev;
372 if (size_so_far > minsize) 411 if (size_so_far > undo_limit)
373 break; 412 break;
374 } 413 }
375 414
@@ -390,16 +429,15 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
390 429
391 /* If we scanned the whole list, it is short enough; don't change it. */ 430 /* If we scanned the whole list, it is short enough; don't change it. */
392 if (NILP (next)) 431 if (NILP (next))
393 return list; 432 ;
394
395 /* Truncate at the boundary where we decided to truncate. */ 433 /* Truncate at the boundary where we decided to truncate. */
396 if (!NILP (last_boundary)) 434 else if (!NILP (last_boundary))
397 { 435 XSETCDR (last_boundary, Qnil);
398 XSETCDR (last_boundary, Qnil); 436 /* There's nothing we decided to keep, so clear it out. */
399 return list;
400 }
401 else 437 else
402 return Qnil; 438 b->undo_list = Qnil;
439
440 unbind_to (count, Qnil);
403} 441}
404 442
405DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0, 443DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
@@ -563,6 +601,54 @@ syms_of_undo ()
563 601
564 defsubr (&Sprimitive_undo); 602 defsubr (&Sprimitive_undo);
565 defsubr (&Sundo_boundary); 603 defsubr (&Sundo_boundary);
604
605 DEFVAR_INT ("undo-limit", &undo_limit,
606 doc: /* Keep no more undo information once it exceeds this size.
607This limit is applied when garbage collection happens.
608When a previous command increases the total undo list size past this
609value, the earlier commands that came before it are forgotten.
610
611The size is counted as the number of bytes occupied,
612which includes both saved text and other data. */);
613 undo_limit = 20000;
614
615 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit,
616 doc: /* Don't keep more than this much size of undo information.
617This limit is applied when garbage collection happens.
618When a previous command increases the total undo list size past this
619value, that command and the earlier commands that came before it are forgotten.
620However, the most recent buffer-modifying command's undo info
621is never discarded for this reason.
622
623The size is counted as the number of bytes occupied,
624which includes both saved text and other data. */);
625 undo_strong_limit = 30000;
626
627 DEFVAR_LISP ("undo-outer-limit", &Vundo_outer_limit,
628 doc: /* Outer limit on size of undo information for one command.
629At garbage collection time, if the current command has produced
630more than this much undo information, it asks you whether to delete
631the information. This is a last-ditch limit to prevent memory overflow.
632
633The size is counted as the number of bytes occupied,
634which includes both saved text and other data.
635
636In fact, this calls the function which is the value of
637`undo-outer-limit-function' with one argument, the size.
638The text above describes the behavior of the function
639that variable usually specifies. */);
640 Vundo_outer_limit = make_number (300000);
641
642 DEFVAR_LISP ("undo-outer-limit-function", &Vundo_outer_limit_function,
643 doc: /* Function to call when an undo list exceeds `undo-outer-limit'.
644This function is called with one argument, the current undo list size
645for the most recent command (since the last undo boundary).
646If the function returns t, that means truncation has been fully handled.
647If it returns nil, the other forms of truncation are done.
648
649Garbage collection is inhibited around the call to this function,
650so it must make sure not to do a lot of consing. */);
651 Vundo_outer_limit_function = Qnil;
566} 652}
567 653
568/* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a 654/* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a
diff --git a/src/w32term.c b/src/w32term.c
index 0f6e9f67a66..e02019f45b9 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5374,47 +5374,17 @@ void
5374x_calc_absolute_position (f) 5374x_calc_absolute_position (f)
5375 struct frame *f; 5375 struct frame *f;
5376{ 5376{
5377 POINT pt;
5378 int flags = f->size_hint_flags; 5377 int flags = f->size_hint_flags;
5379 5378
5380 pt.x = pt.y = 0;
5381
5382 /* Find the position of the outside upper-left corner of
5383 the inner window, with respect to the outer window.
5384 But do this only if we will need the results. */
5385 if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
5386 {
5387 BLOCK_INPUT;
5388 MapWindowPoints (FRAME_W32_WINDOW (f),
5389 f->output_data.w32->parent_desc,
5390 &pt, 1);
5391 UNBLOCK_INPUT;
5392 }
5393
5394 {
5395 RECT rt;
5396 rt.left = rt.right = rt.top = rt.bottom = 0;
5397
5398 BLOCK_INPUT;
5399 AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
5400 FRAME_EXTERNAL_MENU_BAR (f));
5401 UNBLOCK_INPUT;
5402
5403 pt.x += (rt.right - rt.left);
5404 pt.y += (rt.bottom - rt.top);
5405 }
5406
5407 /* Treat negative positions as relative to the leftmost bottommost 5379 /* Treat negative positions as relative to the leftmost bottommost
5408 position that fits on the screen. */ 5380 position that fits on the screen. */
5409 if (flags & XNegative) 5381 if (flags & XNegative)
5410 f->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width 5382 f->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
5411 - 2 * f->border_width - pt.x
5412 - FRAME_PIXEL_WIDTH (f) 5383 - FRAME_PIXEL_WIDTH (f)
5413 + f->left_pos); 5384 + f->left_pos);
5414 5385
5415 if (flags & YNegative) 5386 if (flags & YNegative)
5416 f->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height 5387 f->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
5417 - 2 * f->border_width - pt.y
5418 - FRAME_PIXEL_HEIGHT (f) 5388 - FRAME_PIXEL_HEIGHT (f)
5419 + f->top_pos); 5389 + f->top_pos);
5420 /* The left_pos and top_pos 5390 /* The left_pos and top_pos
diff --git a/src/xdisp.c b/src/xdisp.c
index c58e8088141..b0a8f953c9c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4914,7 +4914,9 @@ get_next_display_element (it)
4914 || (it->multibyte_p 4914 || (it->multibyte_p
4915 ? ((it->c >= 127 4915 ? ((it->c >= 127
4916 && it->len == 1) 4916 && it->len == 1)
4917 || !CHAR_PRINTABLE_P (it->c)) 4917 || !CHAR_PRINTABLE_P (it->c)
4918 || it->c == 0x8ad
4919 || it->c == 0x8a0)
4918 : (it->c >= 127 4920 : (it->c >= 127
4919 && (!unibyte_display_via_language_environment 4921 && (!unibyte_display_via_language_environment
4920 || it->c == unibyte_char_to_multibyte (it->c))))) 4922 || it->c == unibyte_char_to_multibyte (it->c)))))
@@ -4957,6 +4959,21 @@ get_next_display_element (it)
4957 XSETINT (it->ctl_chars[1], g); 4959 XSETINT (it->ctl_chars[1], g);
4958 ctl_len = 2; 4960 ctl_len = 2;
4959 } 4961 }
4962 else if (it->c == 0x8a0 || it->c == 0x8ad)
4963 {
4964 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4965 if (it->dp
4966 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4967 && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (it->dp))))
4968 g = XINT (DISP_ESCAPE_GLYPH (it->dp));
4969 else
4970 g = FAST_MAKE_GLYPH ('\\', face_id);
4971 XSETINT (it->ctl_chars[0], g);
4972
4973 g = FAST_MAKE_GLYPH (it->c == 0x8ad ? '-' : ' ', face_id);
4974 XSETINT (it->ctl_chars[1], g);
4975 ctl_len = 2;
4976 }
4960 else 4977 else
4961 { 4978 {
4962 unsigned char str[MAX_MULTIBYTE_LENGTH]; 4979 unsigned char str[MAX_MULTIBYTE_LENGTH];
@@ -5139,6 +5156,9 @@ set_iterator_to_next (it, reseat_p)
5139 it->dpvec = NULL; 5156 it->dpvec = NULL;
5140 it->current.dpvec_index = -1; 5157 it->current.dpvec_index = -1;
5141 5158
5159 /* Recheck faces after display vector */
5160 it->stop_charpos = 0;
5161
5142 /* Skip over characters which were displayed via IT->dpvec. */ 5162 /* Skip over characters which were displayed via IT->dpvec. */
5143 if (it->dpvec_char_len < 0) 5163 if (it->dpvec_char_len < 0)
5144 reseat_at_next_visible_line_start (it, 1); 5164 reseat_at_next_visible_line_start (it, 1);
diff --git a/src/xselect.c b/src/xselect.c
index cd059e81979..1a033f1d973 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2348,7 +2348,7 @@ DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
2348 Fcons (x_atom_to_symbol (display, type), 2348 Fcons (x_atom_to_symbol (display, type),
2349 Fcons (make_number (format), Qnil)))); 2349 Fcons (make_number (format), Qnil))));
2350 2350
2351 ret = (bytes ? make_string ((char *) data, bytes) : Qnil); 2351 ret = (bytes ? make_unibyte_string ((char *) data, bytes) : Qnil);
2352 /* Use xfree, not XFree, because x_get_window_property 2352 /* Use xfree, not XFree, because x_get_window_property
2353 calls xmalloc itself. */ 2353 calls xmalloc itself. */
2354 xfree (data); 2354 xfree (data);
diff --git a/src/xterm.c b/src/xterm.c
index 480ee1c624a..51feed59ac4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -4286,8 +4286,6 @@ xg_scroll_callback (widget, data)
4286 int part = -1, whole = 0, portion = 0; 4286 int part = -1, whole = 0, portion = 0;
4287 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget)); 4287 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget));
4288 4288
4289 if (xg_ignore_gtk_scrollbar) return;
4290
4291 position = gtk_adjustment_get_value (adj); 4289 position = gtk_adjustment_get_value (adj);
4292 4290
4293 p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA); 4291 p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
@@ -4301,6 +4299,8 @@ xg_scroll_callback (widget, data)
4301 previous = *p; 4299 previous = *p;
4302 *p = position; 4300 *p = position;
4303 4301
4302 if (xg_ignore_gtk_scrollbar) return;
4303
4304 diff = (int) (position - previous); 4304 diff = (int) (position - previous);
4305 4305
4306 if (diff == (int) adj->step_increment) 4306 if (diff == (int) adj->step_increment)
@@ -4332,7 +4332,7 @@ xg_scroll_callback (widget, data)
4332 } 4332 }
4333 4333
4334 if (part >= 0) 4334 if (part >= 0)
4335 { 4335 {
4336 window_being_scrolled = bar->window; 4336 window_being_scrolled = bar->window;
4337 last_scroll_bar_part = part; 4337 last_scroll_bar_part = part;
4338 x_send_scroll_bar_event (bar->window, part, portion, whole); 4338 x_send_scroll_bar_event (bar->window, part, portion, whole);
@@ -8155,20 +8155,11 @@ x_calc_absolute_position (f)
8155 if (! ((flags & XNegative) || (flags & YNegative))) 8155 if (! ((flags & XNegative) || (flags & YNegative)))
8156 return; 8156 return;
8157 8157
8158 /* Find the offsets of the outside upper-left corner of
8159 the inner window, with respect to the outer window.
8160 But do this only if we will need the results. */
8161 if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
8162 /* This is to get *_pixels_outer_diff. */
8163 x_real_positions (f, &win_x, &win_y);
8164
8165 /* Treat negative positions as relative to the leftmost bottommost 8158 /* Treat negative positions as relative to the leftmost bottommost
8166 position that fits on the screen. */ 8159 position that fits on the screen. */
8167 if (flags & XNegative) 8160 if (flags & XNegative)
8168 f->left_pos = (FRAME_X_DISPLAY_INFO (f)->width 8161 f->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
8169 - 2 * FRAME_X_OUTPUT (f)->x_pixels_outer_diff 8162 - FRAME_PIXEL_WIDTH (f) + f->left_pos);
8170 - FRAME_PIXEL_WIDTH (f)
8171 + f->left_pos);
8172 8163
8173 { 8164 {
8174 int height = FRAME_PIXEL_HEIGHT (f); 8165 int height = FRAME_PIXEL_HEIGHT (f);
@@ -8190,15 +8181,7 @@ x_calc_absolute_position (f)
8190#endif 8181#endif
8191 8182
8192 if (flags & YNegative) 8183 if (flags & YNegative)
8193 f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height 8184 f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height - height + f->top_pos);
8194 - FRAME_X_OUTPUT (f)->y_pixels_outer_diff
8195
8196 /* Assume the window manager decorations are the same size on
8197 three sides, i.e. left, right and bottom. This is to
8198 compensate for the bottom part. */
8199 - FRAME_X_OUTPUT (f)->x_pixels_outer_diff
8200 - height
8201 + f->top_pos);
8202 } 8185 }
8203 8186
8204 /* The left_pos and top_pos 8187 /* The left_pos and top_pos
@@ -8314,7 +8297,9 @@ x_check_expected_move (f)
8314 FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos; 8297 FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos;
8315 FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos; 8298 FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos;
8316 8299
8317 x_set_offset (f, expect_left, expect_top, 1); 8300 f->left_pos = expect_left;
8301 f->top_pos = expect_top;
8302 x_set_offset (f, expect_left, expect_top, 0);
8318 } 8303 }
8319 else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN) 8304 else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
8320 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B; 8305 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;