aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit28
-rw-r--r--src/ChangeLog239
-rw-r--r--src/Makefile.in2
-rw-r--r--src/atimer.c3
-rw-r--r--src/callproc.c5
-rw-r--r--src/casefiddle.c23
-rw-r--r--src/config.in9
-rw-r--r--src/dispnew.c2
-rw-r--r--src/emacs.c1
-rw-r--r--src/eval.c46
-rw-r--r--src/fileio.c51
-rw-r--r--src/fontset.c14
-rw-r--r--src/gtkutil.c137
-rw-r--r--src/gtkutil.h7
-rw-r--r--src/insdel.c118
-rw-r--r--src/keyboard.c91
-rw-r--r--src/keyboard.h1
-rw-r--r--src/lisp.h2
-rw-r--r--src/macfns.c38
-rw-r--r--src/process.c48
-rw-r--r--src/w32fns.c30
-rw-r--r--src/w32term.c4
-rw-r--r--src/window.c40
-rw-r--r--src/xdisp.c28
-rw-r--r--src/xfns.c91
-rw-r--r--src/xmenu.c30
-rw-r--r--src/xselect.c176
-rw-r--r--src/xterm.c85
-rw-r--r--src/xterm.h7
29 files changed, 974 insertions, 382 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index b7716f0e904..ad6be09ec46 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -70,6 +70,34 @@ Print the argument as an emacs s-expression
70Works only when an inferior emacs is executing. 70Works only when an inferior emacs is executing.
71end 71end
72 72
73# Print out current buffer point and boundaries
74define ppt
75 set $b = current_buffer
76 set $t = $b->text
77 printf "BUF PT: %d", $b->pt
78 if ($b->pt != $b->pt_byte)
79 printf "[%d]", $b->pt_byte
80 end
81 printf " of 1..%d", $t->z
82 if ($t->z != $t->z_byte)
83 printf "[%d]", $t->z_byte
84 end
85 if ($b->begv != 1 || $b->zv != $t->z)
86 printf " NARROW=%d..%d", $b->begv, $b->zv
87 if ($b->begv != $b->begv_byte || $b->zv != $b->zv_byte)
88 printf " [%d..%d]", $b->begv_byte, $b->zv_byte
89 end
90 end
91 printf " GAP: %d", $t->gpt
92 if ($t->gpt != $t->gpt_byte)
93 printf "[%d]", $t->gpt_byte
94 end
95 printf " SZ=%d\n", $t->gap_size
96end
97document ppt
98Print point, beg, end, narrow, and gap for current buffer.
99end
100
73define xtype 101define xtype
74 xgettype $ 102 xgettype $
75 output $type 103 output $type
diff --git a/src/ChangeLog b/src/ChangeLog
index 8479a0f94ce..a38c3f7baeb 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,206 @@
12004-11-05 Kim F. Storm <storm@cua.dk>
2
3 * fileio.c (Ffile_modes): Doc fix.
4 (auto_save_1): Check for Ffile_modes nil value.
5
62004-11-05 Kim F. Storm <storm@cua.dk>
7
8 * xselect.c (struct selection_event_queue, selection_queue)
9 (x_queue_selection_requests, x_queue_event)
10 (x_start_queuing_selection_requests)
11 (x_stop_queuing_selection_requests): Add new queue for selection
12 input events to replace previous XEvent queue in xterm.c.
13 (queue_selection_requests_unwind): Adapt to new queue.
14 (x_reply_selection_request): Adapt to new queue. Unexpect
15 wait_object in case of x errors (memory leak).
16 (x_handle_selection_request, x_handle_selection_clear): Make static.
17 (x_handle_selection_event): New function. May queue selection events.
18 (wait_for_property_change_unwind): Use save_value instead of cons.
19 Clear property_change_reply_object.
20 (wait_for_property_change): Abort if already waiting.
21 Use save_value instead of cons for unwind data.
22 (x_handle_property_notify): Skip events already arrived, but don't
23 free them, as "arrived" field is checked by wait_for_property_change,
24 and it will be freed by unwind or explicit unexpect_property_change.
25 (x_get_foreign_selection): Add to new queue.
26 (receive_incremental_selection): Don't unexpect wait_object when done
27 as it has already been freed by previous wait_for_property_change.
28
29 * xterm.h (x_start_queuing_selection_requests)
30 (x_stop_queuing_selection_requests, x_handle_selection_request)
31 (x_handle_selection_clear): Remove prototypes.
32 (x_handle_selection_event): Add prototype.
33
34 * xterm.c (handle_one_xevent): Don't queue X selection events
35 here, it may be too late if we start queuing after we have already
36 stored some selection events into the kbd buffer.
37 (struct selection_event_queue, queue, x_queue_selection_requests)
38 (x_queue_event, x_unqueue_events, x_start_queuing_selection_requests)
39 (x_stop_queuing_selection_requests): Remove/move to xselect.c.
40 (x_catch_errors_unwind): Block input around final XSync.
41
42 * keyboard.h (kbd_buffer_unget_event): Add prototype.
43
44 * keyboard.c (kbd_buffer_store_event_hold): Remove obsolete code.
45 (kbd_buffer_unget_event): New function.
46 (kbd_buffer_get_event, swallow_events): Combine SELECTION events
47 and use x_handle_selection_event.
48 (mark_kboards): Don't mark x and y of SELECTION_CLEAR_EVENT.
49
502004-11-05 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
51
52 * xselect.c (TRACE3): New debug macro.
53 (x_reply_selection_request): Use it.
54 (receive_incremental_selection): In call to TRACE0, the name of
55 a symbol is in xname.
56
572004-11-05 Kim F. Storm <storm@cua.dk>
58
59 * fontset.c (fontset_pattern_regexp): Use unsigned char.
60
612004-11-04 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
62
63 * fileio.c (Fnext_read_file_uses_dialog_p): New function.
64
65 * gtkutil.h: Declare use_old_gtk_file_dialog.
66
67 * gtkutil.c: Make use_old_gtk_file_dialog non-static.
68 (xg_initialize): Moved DEFVAR_BOOL for use_old_gtk_file_dialog ...
69 * xfns.c (syms_of_xfns): ... to here.
70
71 * gtkutil.c (xg_get_file_with_chooser): Expand DEFAULT_FILENAME if
72 it doesn't start with /.
73
742004-11-04 Kenichi Handa <handa@m17n.org>
75
76 * fontset.c (fontset_pattern_regexp): If '*' is preceded by '\',
77 treat it as a literal character.
78
792004-11-03 Kim F. Storm <storm@cua.dk>
80
81 * .gdbinit (ppt): New function.
82
832004-11-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
84
85 * xterm.c (x_window_to_scroll_bar): Only call
86 xg_get_scroll_id_for_window if toolkit scroll bars are used.
87
88 * gtkutil.c (xg_get_file_with_chooser): Use GTK_STOCK_OK instead
89 of save.
90
912004-11-02 Andreas Schwab <schwab@suse.de>
92
93 * window.c (Fscroll_right): Fix last change.
94
952004-11-02 Kim F. Storm <storm@cua.dk>
96
97 * Makefile.in (callproc.o): Depend on blockinput.h atimer.h systime.h.
98
992004-11-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
100
101 * callproc.c (Fcall_process): Block input around vfork.
102
1032004-11-02 Kim F. Storm <storm@cua.dk>
104
105 * eval.c (Fcalled_interactively_p): Rename from Fcall_interactive_p.
106 (syms_of_eval): Defsubr it.
107
1082004-11-02 Richard M. Stallman <rms@gnu.org>
109
110 * insdel.c (replace_range_2): New function.
111
112 * casefiddle.c (casify_region): Handle changes in byte-length
113 using replace_range_2.
114
115 * emacs.c (USAGE3): Delete --horizontal-scroll-bars, -hb.
116
117 * xdisp.c (back_to_previous_visible_line_start):
118 Subtract 1 from pos when checking previous newline for invisibility.
119
120 * window.c (window_scroll_pixel_based): Update preserve_y
121 for header line if any.
122 (Fscroll_left, Fscroll_right): Don't call interactive_p;
123 use a new second argument instead.
124
125 * eval.c (Fcall_interactive_p): New function.
126 (interactive_p): Don't test INTERACTIVE here.
127 (Finteractive_p): Doc fix.
128
129 * eval.c (Feval): Abort if INPUT_BLOCKED_P.
130
1312004-11-02 KOBAYASHI Yasuhiro <kobayays@otsukakj.co.jp>
132
133 * w32fns.c (w32_font_match): Use fast_string_match_ignore_case for
134 comparing font names.
135
1362004-11-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
137
138 * fileio.c (Fread_file_name): Pass Qt as fifth parameter to
139 Fx_file_dialog if only directories should be read.
140
141 * lisp.h: Fx_file_dialog takes 5 parameters.
142
143 * xfns.c (Fx_file_dialog): Both Motif and GTK version: Add
144 parameter only_dir_p.
145 In Motif version, don't put DEFAULT_FILENAME in filter part of the
146 dialog, just text field part. Do not add DEFAULT_FILENAME
147 to list of files if it isn't there.
148 In GTK version, pass only_dir_p parameter to xg_get_file_name.
149
150 * macfns.c (Fx_file_dialog): Add parameter only_dir_p. Check
151 only_dir_p instead of comparing prompt to "Dired". When using
152 a save dialog, add option kNavDontConfirmReplacement, change title
153 to "Enter name", change text for save button to "Ok".
154
155 * w32fns.c (Fx_file_dialog): Add parameter only_dir_p. Check
156 only_dir_p instead of comparing prompt to "Dired".
157
158 * gtkutil.c (xg_get_file_with_chooser)
159 (xg_get_file_with_selection): New functions, only defined ifdef
160 HAVE_GTK_FILE_CHOOSER_DIALOG_NEW and HAVE_GTK_FILE_SELECTION_NEW
161 respectively.
162 (xg_get_file_name): Add parameter only_dir_p.
163 Call xg_get_file_with_chooser or xg_get_file_with_selection
164 depending on HAVE_GTK_FILE* and the value of use_old_gtk_file_dialog.
165 (xg_initialize): New DEFVAR_BOOL use_old_gtk_file_dialog.
166
167 * gtkutil.h (xg_get_file_name): Add parameter only_dir_p.
168
169 * config.in: Rebuild (added HAVE_GTK_FILE_*).
170
1712004-11-01 Kim F. Storm <storm@cua.dk>
172
173 * process.c (connect_wait_mask, num_pending_connects): Only
174 declare and use them if NON_BLOCKING_CONNECT is defined.
175 (init_process): Initialize them if NON_BLOCKING_CONNECT defined.
176 (IF_NON_BLOCKING_CONNECT): New helper macro.
177 (wait_reading_process_output): Only declare and use local vars
178 Connecting and check_connect when NON_BLOCKING_CONNECT is defined.
179
1802004-11-01 Andy Petrusenco <Igrek@star-sw.com> (tiny change)
181
182 * w32term.c (x_scroll_run): Delete region objects after use.
183
1842004-10-31 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
185
186 * xmenu.c: Add prototypes for forward function declarations.
187 (popup_get_selection): Remove parameter do_timers, remove call to
188 timer_check.
189 (create_and_show_popup_menu, create_and_show_dialog): Remove
190 parameter do_timers from call to popup_get_selection.
191
192 * xdisp.c (update_tool_bar): Pass a copy of f->tool_bar_items to
193 tool_bar_items and assign the result to f->tool_bar_items if
194 not equal. Move BLOCK/UNBLOCK_INPUT from around call to
195 tool_bar_items to assignment of result.
196
197 * atimer.c (alarm_signal_handler): Do not call set_alarm if
198 pending_atmers is non-zero.
199
2002004-10-31 Kim F. Storm <storm@cua.dk>
201
202 * dispnew.c (margin_glyphs_to_reserve): Don't use ncols_scale_factor.
203
12004-10-28 Will <will@glozer.net> 2042004-10-28 Will <will@glozer.net>
2 205
3 * macterm.c: allow user to assign key modifiers to the Mac Option 206 * macterm.c: allow user to assign key modifiers to the Mac Option
@@ -387,7 +590,7 @@
387 compositions to encode. 590 compositions to encode.
388 (encode_coding_string): Likewise. Free composition data. 591 (encode_coding_string): Likewise. Free composition data.
389 592
3902004-09-30 Florian Weimer <fw@deneb.enyo.de> (tiny change) 5932004-09-30 Florian Weimer <fw@deneb.enyo.de>
391 594
392 * coding.c (code_convert_region): Free composition data. 595 * coding.c (code_convert_region): Free composition data.
393 596
@@ -961,7 +1164,7 @@
961 (Fsave_window_excursion, Fset_window_vscroll) 1164 (Fsave_window_excursion, Fset_window_vscroll)
962 (syms_of_window) <window-size-fixed>: Doc fixes. 1165 (syms_of_window) <window-size-fixed>: Doc fixes.
963 1166
9642004-07-19 KOBAYASHI Yasuhiro <kobayays@otsukakj.co.jp> (tiny change) 11672004-07-19 KOBAYASHI Yasuhiro <kobayays@otsukakj.co.jp>
965 1168
966 * w32fns.c (Fx_file_dialog): Use ENCODE_FILE instead of 1169 * w32fns.c (Fx_file_dialog): Use ENCODE_FILE instead of
967 ENCODE_SYSTEM for filenames. 1170 ENCODE_SYSTEM for filenames.
@@ -1020,7 +1223,7 @@
1020 1223
1021 * buffer.c (syms_of_buffer) <transient-mark-mode>: Doc fix. 1224 * buffer.c (syms_of_buffer) <transient-mark-mode>: Doc fix.
1022 1225
10232004-07-15 KOBAYASHI Yasuhiro <kobayays@otsukakj.co.jp> (tiny change) 12262004-07-15 KOBAYASHI Yasuhiro <kobayays@otsukakj.co.jp>
1024 1227
1025 * w32fns.c (Fx_file_dialog): Encode strings in system coding 1228 * w32fns.c (Fx_file_dialog): Encode strings in system coding
1026 system before passing them to OS functions for display. 1229 system before passing them to OS functions for display.
@@ -1684,7 +1887,7 @@
1684 before actually accepting connection in case it has already been 1887 before actually accepting connection in case it has already been
1685 accepted due to recursion. 1888 accepted due to recursion.
1686 1889
16872004-05-23 K,Ba(Broly L,Bu(Brentey <lorentey@elte.hu> (tiny change) 18902004-05-23 K,Ba(Broly L,Bu(Brentey <lorentey@elte.hu>
1688 1891
1689 * coding.c (Fset_safe_terminal_coding_system_internal): 1892 * coding.c (Fset_safe_terminal_coding_system_internal):
1690 Set suppress_error in safe_terminal_coding, not terminal_coding. 1893 Set suppress_error in safe_terminal_coding, not terminal_coding.
@@ -1998,7 +2201,7 @@
1998 * w32fns.c (Vw32_ansi_code_page): New Lisp variable. 2201 * w32fns.c (Vw32_ansi_code_page): New Lisp variable.
1999 (globals_of_w32fns): Set it. 2202 (globals_of_w32fns): Set it.
2000 2203
20012004-05-09 Piet van Oostrum <piet@cs.uu.nl> (tiny change) 22042004-05-09 Piet van Oostrum <piet@cs.uu.nl>
2002 2205
2003 * data.c (Fquo): Simplify. 2206 * data.c (Fquo): Simplify.
2004 2207
@@ -2047,7 +2250,7 @@
2047 2250
2048 * emacs.c (main) [VMS]: Fix var ref. 2251 * emacs.c (main) [VMS]: Fix var ref.
2049 2252
20502004-05-06 Romain Francoise <romain@orebokech.com> (tiny change) 22532004-05-06 Romain Francoise <romain@orebokech.com>
2051 2254
2052 * data.c (Fsetq_default): Fix docstring. 2255 * data.c (Fsetq_default): Fix docstring.
2053 2256
@@ -2087,7 +2290,7 @@
2087 2290
2088 * Makefile.in (region-cache.o): Depend on config.h. 2291 * Makefile.in (region-cache.o): Depend on config.h.
2089 2292
20902004-05-02 Romain Francoise <romain@orebokech.com> (tiny change) 22932004-05-02 Romain Francoise <romain@orebokech.com>
2091 2294
2092 * indent.c (compute_motion): Save vpos in prev_vpos when dealing 2295 * indent.c (compute_motion): Save vpos in prev_vpos when dealing
2093 with continuation lines, too. 2296 with continuation lines, too.
@@ -3330,7 +3533,7 @@
3330 entries that were used before we return. 3533 entries that were used before we return.
3331 (init_keyboard): Initialize read_avail_input_buf here. 3534 (init_keyboard): Initialize read_avail_input_buf here.
3332 3535
33332004-02-16 Jesper Harder <harder@ifa.au.dk> (tiny change) 35362004-02-16 Jesper Harder <harder@ifa.au.dk>
3334 3537
3335 * cmds.c (Fend_of_line): Doc fix. 3538 * cmds.c (Fend_of_line): Doc fix.
3336 3539
@@ -3998,7 +4201,7 @@
3998 to the definition of `signal' in the Elisp manual. 4201 to the definition of `signal' in the Elisp manual.
3999 * eval.c (Fsignal): Ditto. 4202 * eval.c (Fsignal): Ditto.
4000 4203
40012003-12-29 James Clark <jjc@jclark.com> (tiny change) 42042003-12-29 James Clark <jjc@jclark.com>
4002 4205
4003 * fns.c (internal_equal): Return t for two NaN arguments. 4206 * fns.c (internal_equal): Return t for two NaN arguments.
4004 4207
@@ -5058,7 +5261,7 @@
5058 * fileio.c (Fwrite_region): Fix conditional expression to issue 5261 * fileio.c (Fwrite_region): Fix conditional expression to issue
5059 the right message. 5262 the right message.
5060 5263
50612003-08-16 Juri Linkov <juri@jurta.org> (tiny change) 52642003-08-16 Juri Linkov <juri@jurta.org>
5062 5265
5063 * syntax.c (Fforward_word): Argument changed to optional. 5266 * syntax.c (Fforward_word): Argument changed to optional.
5064 Set default value to 1. 5267 Set default value to 1.
@@ -5117,7 +5320,7 @@
5117 * fns.c (Fclear_string): New function. 5320 * fns.c (Fclear_string): New function.
5118 (syms_of_fns): defsubr it. 5321 (syms_of_fns): defsubr it.
5119 5322
51202003-07-28 KOBAYASHI Yasuhiro <kobayays@otsukakj.co.jp> (tiny change) 53232003-07-28 KOBAYASHI Yasuhiro <kobayays@otsukakj.co.jp>
5121 5324
5122 * xfns.c (xic_set_preeditarea): Add the left fringe width to spot.x. 5325 * xfns.c (xic_set_preeditarea): Add the left fringe width to spot.x.
5123 5326
@@ -5345,7 +5548,7 @@
5345 5548
5346 * alloc.c (Fgarbage_collect): Doc fix. 5549 * alloc.c (Fgarbage_collect): Doc fix.
5347 5550
53482003-07-07 Nozomu Ando <nand@mac.com> (tiny change) 55512003-07-07 Nozomu Ando <nand@mac.com>
5349 5552
5350 * buffer.c (Fkill_buffer): Clear charpos cache if necessary. 5553 * buffer.c (Fkill_buffer): Clear charpos cache if necessary.
5351 5554
@@ -6555,7 +6758,7 @@
6555 * alloc.c (Fgarbage_collect): Cast pointers into specpdl 6758 * alloc.c (Fgarbage_collect): Cast pointers into specpdl
6556 to avoid GCC warning. 6759 to avoid GCC warning.
6557 6760
65582003-05-16 Ralph Schleicher <rs@nunatak.allgaeu.org> (tiny change) 67612003-05-16 Ralph Schleicher <rs@nunatak.allgaeu.org>
6559 6762
6560 * fileio.c (Fdelete_file): Handle symlinks pointing to directories. 6763 * fileio.c (Fdelete_file): Handle symlinks pointing to directories.
6561 6764
@@ -8278,7 +8481,7 @@
8278 (w32_init_class): Use it. 8481 (w32_init_class): Use it.
8279 (x_put_x_image): Declare all args. 8482 (x_put_x_image): Declare all args.
8280 8483
82812003-01-21 Richard Dawe <rich@phekda.freeserve.co.uk> (tiny change) 84842003-01-21 Richard Dawe <rich@phekda.freeserve.co.uk>
8282 8485
8283 * Makefile.in (ALL_CFLAGS): Include MYCPPFLAGS, not MYCPPFLAG. 8486 * Makefile.in (ALL_CFLAGS): Include MYCPPFLAGS, not MYCPPFLAG.
8284 8487
@@ -8650,7 +8853,7 @@
8650 in direct action cases for Qforward_char and Qbackward_char. 8853 in direct action cases for Qforward_char and Qbackward_char.
8651 Set already_adjusted so it won't be done twice. 8854 Set already_adjusted so it won't be done twice.
8652 8855
86532002-12-30 Richard Dawe <rich@phekda.freeserve.co.uk> (tiny change) 88562002-12-30 Richard Dawe <rich@phekda.freeserve.co.uk>
8654 8857
8655 * src/config.in (!HAVE_SIZE_T): Fix order of arguments in 8858 * src/config.in (!HAVE_SIZE_T): Fix order of arguments in
8656 type definition of size_t. 8859 type definition of size_t.
@@ -8748,7 +8951,7 @@
8748 * dired.c (file_name_completion): Fix that change. 8951 * dired.c (file_name_completion): Fix that change.
8749 Delete special quit-handling code; just use QUIT. 8952 Delete special quit-handling code; just use QUIT.
8750 8953
87512002-12-21 Tak Ota <Takaaki.Ota@am.sony.com> (tiny change) 89542002-12-21 Tak Ota <Takaaki.Ota@am.sony.com>
8752 8955
8753 * dired.c (file_name_completion): Close directory on error 8956 * dired.c (file_name_completion): Close directory on error
8754 just as in directory_files_internal. 8957 just as in directory_files_internal.
@@ -10088,8 +10291,8 @@
10088 10291
100892002-08-26 Kim F. Storm <storm@cua.dk> 102922002-08-26 Kim F. Storm <storm@cua.dk>
10090 10293
10091 * frame.c (make_terminal_frame) [CANNOT_DUMP]: Initialize foreground 10294 * frame.c (make_terminal_frame) [CANNOT_DUMP]: Initialize
10092 and background colors. From Joe Buehler (tiny change). 10295 foreground and background colors. From Joe Buehler.
10093 10296
100942002-08-26 Miles Bader <miles@gnu.org> 102972002-08-26 Miles Bader <miles@gnu.org>
10095 10298
diff --git a/src/Makefile.in b/src/Makefile.in
index 9d169cd4bdc..ebbc4f45d61 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1056,7 +1056,7 @@ callint.o: callint.c window.h commands.h buffer.h keymap.h \
1056 keyboard.h dispextern.h $(config_h) 1056 keyboard.h dispextern.h $(config_h)
1057callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \ 1057callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \
1058 process.h systty.h syssignal.h charset.h coding.h ccl.h msdos.h \ 1058 process.h systty.h syssignal.h charset.h coding.h ccl.h msdos.h \
1059 composite.h 1059 composite.h w32.h blockinput.h atimer.h systime.h
1060casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h \ 1060casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h \
1061 charset.h keymap.h $(config_h) 1061 charset.h keymap.h $(config_h)
1062casetab.o: casetab.c buffer.h $(config_h) 1062casetab.o: casetab.c buffer.h $(config_h)
diff --git a/src/atimer.c b/src/atimer.c
index 9ec0238ff28..7410cad0244 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -397,7 +397,8 @@ alarm_signal_handler (signo)
397 EMACS_GET_TIME (now); 397 EMACS_GET_TIME (now);
398 } 398 }
399 399
400 set_alarm (); 400 if (! pending_atimers)
401 set_alarm ();
401} 402}
402 403
403 404
diff --git a/src/callproc.c b/src/callproc.c
index 5d7447d94f2..e251fc65941 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -83,6 +83,7 @@ extern int errno;
83#include "process.h" 83#include "process.h"
84#include "syssignal.h" 84#include "syssignal.h"
85#include "systty.h" 85#include "systty.h"
86#include "blockinput.h"
86 87
87#ifdef MSDOS 88#ifdef MSDOS
88#include "msdos.h" 89#include "msdos.h"
@@ -624,6 +625,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
624 pid = child_setup (filefd, fd1, fd_error, (char **) new_argv, 625 pid = child_setup (filefd, fd1, fd_error, (char **) new_argv,
625 0, current_dir); 626 0, current_dir);
626#else /* not WINDOWSNT */ 627#else /* not WINDOWSNT */
628 BLOCK_INPUT;
629
627 pid = vfork (); 630 pid = vfork ();
628 631
629 if (pid == 0) 632 if (pid == 0)
@@ -641,6 +644,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
641 child_setup (filefd, fd1, fd_error, (char **) new_argv, 644 child_setup (filefd, fd1, fd_error, (char **) new_argv,
642 0, current_dir); 645 0, current_dir);
643 } 646 }
647
648 UNBLOCK_INPUT;
644#endif /* not WINDOWSNT */ 649#endif /* not WINDOWSNT */
645 650
646 /* The MSDOS case did this already. */ 651 /* The MSDOS case did this already. */
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 51fc6444f49..ae4888088bd 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -235,6 +235,10 @@ casify_region (flag, b, e)
235 else if (!UPPERCASEP (c) 235 else if (!UPPERCASEP (c)
236 && (!inword || flag != CASE_CAPITALIZE_UP)) 236 && (!inword || flag != CASE_CAPITALIZE_UP))
237 c = UPCASE1 (c); 237 c = UPCASE1 (c);
238 if (multibyte && c >= 0x80)
239 /* A multibyte result character can't be handled in this
240 simple loop. */
241 break;
238 FETCH_BYTE (i) = c; 242 FETCH_BYTE (i) = c;
239 if (c != c2) 243 if (c != c2)
240 changed = 1; 244 changed = 1;
@@ -272,22 +276,17 @@ casify_region (flag, b, e)
272 tolen = CHAR_STRING (c2, str), 276 tolen = CHAR_STRING (c2, str),
273 fromlen == tolen) 277 fromlen == tolen)
274 { 278 {
279 /* Length is unchanged. */
275 for (j = 0; j < tolen; ++j) 280 for (j = 0; j < tolen; ++j)
276 FETCH_BYTE (i + j) = str[j]; 281 FETCH_BYTE (i + j) = str[j];
277 } 282 }
278 else 283 else
279 { 284 /* Replace one character with the other,
280 error ("Can't casify letters that change length"); 285 keeping text properties the same. */
281#if 0 /* This is approximately what we'd like to be able to do here */ 286 replace_range_2 (start + 1, i + tolen,
282 if (tolen < fromlen) 287 start + 2, i + tolen + fromlen,
283 del_range_1 (i + tolen, i + fromlen, 0, 0); 288 str, 1, tolen,
284 else if (tolen > fromlen) 289 0);
285 {
286 TEMP_SET_PT (i + fromlen);
287 insert_1 (str + fromlen, tolen - fromlen, 1, 0, 0);
288 }
289#endif
290 }
291 } 290 }
292 if ((int) flag >= (int) CASE_CAPITALIZE) 291 if ((int) flag >= (int) CASE_CAPITALIZE)
293 inword = SYNTAX (c2) == Sword; 292 inword = SYNTAX (c2) == Sword;
diff --git a/src/config.in b/src/config.in
index a559a35885f..a2087b98b1f 100644
--- a/src/config.in
+++ b/src/config.in
@@ -217,6 +217,15 @@ Boston, MA 02111-1307, USA. */
217/* Define to 1 if using GTK. */ 217/* Define to 1 if using GTK. */
218#undef HAVE_GTK 218#undef HAVE_GTK
219 219
220/* Define to 1 if GTK has both file selection and chooser dialog. */
221#undef HAVE_GTK_FILE_BOTH
222
223/* Define to 1 if you have the `gtk_file_chooser_dialog_new' function. */
224#undef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW
225
226/* Define to 1 if you have the `gtk_file_selection_new' function. */
227#undef HAVE_GTK_FILE_SELECTION_NEW
228
220/* Define to 1 if GTK can handle more than one display. */ 229/* Define to 1 if GTK can handle more than one display. */
221#undef HAVE_GTK_MULTIDISPLAY 230#undef HAVE_GTK_MULTIDISPLAY
222 231
diff --git a/src/dispnew.c b/src/dispnew.c
index 070c9648d1d..a148f27a1ef 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -566,7 +566,7 @@ margin_glyphs_to_reserve (w, total_glyphs, margin)
566 int width = XFASTINT (w->total_cols); 566 int width = XFASTINT (w->total_cols);
567 double d = max (0, XFLOATINT (margin)); 567 double d = max (0, XFLOATINT (margin));
568 d = min (width / 2 - 1, d); 568 d = min (width / 2 - 1, d);
569 n = (int) ((double) total_glyphs / width * d) * w->ncols_scale_factor; 569 n = (int) ((double) total_glyphs / width * d);
570 } 570 }
571 else 571 else
572 n = 0; 572 n = 0;
diff --git a/src/emacs.c b/src/emacs.c
index 96e858d943a..ab60df39e27 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -306,7 +306,6 @@ Display options:\n\
306--fullscreen, -fs make first frame fullscreen\n\ 306--fullscreen, -fs make first frame fullscreen\n\
307--fullwidth, -fw make the first frame wide as the screen\n\ 307--fullwidth, -fw make the first frame wide as the screen\n\
308--geometry, -g GEOMETRY window geometry\n\ 308--geometry, -g GEOMETRY window geometry\n\
309--horizontal-scroll-bars, -hb enable horizontal scroll bars\n\
310--icon-type, -i use picture of gnu for Emacs icon\n\ 309--icon-type, -i use picture of gnu for Emacs icon\n\
311--iconic start Emacs in iconified state\n\ 310--iconic start Emacs in iconified state\n\
312--internal-border, -ib WIDTH width between text and main border\n\ 311--internal-border, -ib WIDTH width between text and main border\n\
diff --git a/src/eval.c b/src/eval.c
index ee74215b2ee..5fb35cee58b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -540,21 +540,45 @@ usage: (function ARG) */)
540 540
541 541
542DEFUN ("interactive-p", Finteractive_p, Sinteractive_p, 0, 0, 0, 542DEFUN ("interactive-p", Finteractive_p, Sinteractive_p, 0, 0, 0,
543 doc: /* Return t if function in which this appears was called interactively. 543 doc: /* Return t if the function was run directly by user input.
544This means that the function was called with call-interactively (which 544This means that the function was called with call-interactively (which
545includes being called as the binding of a key) 545includes being called as the binding of a key)
546and input is currently coming from the keyboard (not in keyboard macro). */) 546and input is currently coming from the keyboard (not in keyboard macro),
547and Emacs is not running in batch mode (`noninteractive' is nil).
548
549The only known proper use of `interactive-p' is in deciding whether to
550display a helpful message, or how to display it. If you're thinking
551of using it for any other purpose, it is quite likely that you're
552making a mistake. Think: what do you want to do when the command is
553called from a keyboard macro?
554
555If you want to test whether your function was called with
556`call-interactively', the way to do that is by adding an extra
557optional argument, and making the `interactive' spec specify non-nil
558unconditionally for that argument. (`p' is a good way to do this.) */)
547 () 559 ()
548{ 560{
549 return interactive_p (1) ? Qt : Qnil; 561 return (INTERACTIVE && interactive_p (1)) ? Qt : Qnil;
550} 562}
551 563
552 564
553/* Return 1 if function in which this appears was called 565DEFUN ("called-interactively-p", Fcalled_interactively_p, Scalled_interactively_p, 0, 0, 0,
554 interactively. This means that the function was called with 566 doc: /* Return t if the function using this was called with call-interactively.
555 call-interactively (which includes being called as the binding of 567This is used for implementing advice and other function-modifying
556 a key) and input is currently coming from the keyboard (not in 568features of Emacs.
557 keyboard macro). 569
570The cleanest way to test whether your function was called with
571`call-interactively', the way to do that is by adding an extra
572optional argument, and making the `interactive' spec specify non-nil
573unconditionally for that argument. (`p' is a good way to do this.) */)
574 ()
575{
576 return (INTERACTIVE && interactive_p (1)) ? Qt : Qnil;
577}
578
579
580/* Return 1 if function in which this appears was called using
581 call-interactively.
558 582
559 EXCLUDE_SUBRS_P non-zero means always return 0 if the function 583 EXCLUDE_SUBRS_P non-zero means always return 0 if the function
560 called is a built-in. */ 584 called is a built-in. */
@@ -566,9 +590,6 @@ interactive_p (exclude_subrs_p)
566 struct backtrace *btp; 590 struct backtrace *btp;
567 Lisp_Object fun; 591 Lisp_Object fun;
568 592
569 if (!INTERACTIVE)
570 return 0;
571
572 btp = backtrace_list; 593 btp = backtrace_list;
573 594
574 /* If this isn't a byte-compiled function, there may be a frame at 595 /* If this isn't a byte-compiled function, there may be a frame at
@@ -1975,7 +1996,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0,
1975 struct backtrace backtrace; 1996 struct backtrace backtrace;
1976 struct gcpro gcpro1, gcpro2, gcpro3; 1997 struct gcpro gcpro1, gcpro2, gcpro3;
1977 1998
1978 if (handling_signal) 1999 if (handling_signal || INPUT_BLOCKED_P)
1979 abort (); 2000 abort ();
1980 2001
1981 if (SYMBOLP (form)) 2002 if (SYMBOLP (form))
@@ -3449,6 +3470,7 @@ The value the function returns is not used. */);
3449 defsubr (&Scondition_case); 3470 defsubr (&Scondition_case);
3450 defsubr (&Ssignal); 3471 defsubr (&Ssignal);
3451 defsubr (&Sinteractive_p); 3472 defsubr (&Sinteractive_p);
3473 defsubr (&Scalled_interactively_p);
3452 defsubr (&Scommandp); 3474 defsubr (&Scommandp);
3453 defsubr (&Sautoload); 3475 defsubr (&Sautoload);
3454 defsubr (&Seval); 3476 defsubr (&Seval);
diff --git a/src/fileio.c b/src/fileio.c
index ece909ea8b3..587f36d537d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3368,7 +3368,8 @@ This is the sort of file that holds an ordinary stream of data bytes. */)
3368} 3368}
3369 3369
3370DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0, 3370DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
3371 doc: /* Return mode bits of file named FILENAME, as an integer. */) 3371 doc: /* Return mode bits of file named FILENAME, as an integer.
3372Return nil, if file does not exist or is not accessible. */)
3372 (filename) 3373 (filename)
3373 Lisp_Object filename; 3374 Lisp_Object filename;
3374{ 3375{
@@ -5714,17 +5715,21 @@ Lisp_Object
5714auto_save_1 () 5715auto_save_1 ()
5715{ 5716{
5716 struct stat st; 5717 struct stat st;
5718 Lisp_Object modes;
5719
5720 auto_save_mode_bits = 0666;
5717 5721
5718 /* Get visited file's mode to become the auto save file's mode. */ 5722 /* Get visited file's mode to become the auto save file's mode. */
5719 if (! NILP (current_buffer->filename) 5723 if (! NILP (current_buffer->filename))
5720 && stat (SDATA (current_buffer->filename), &st) >= 0) 5724 {
5721 /* But make sure we can overwrite it later! */ 5725 if (stat (SDATA (current_buffer->filename), &st) >= 0)
5722 auto_save_mode_bits = st.st_mode | 0600; 5726 /* But make sure we can overwrite it later! */
5723 else if (! NILP (current_buffer->filename)) 5727 auto_save_mode_bits = st.st_mode | 0600;
5724 /* Remote files don't cooperate with stat. */ 5728 else if ((modes = Ffile_modes (current_buffer->filename),
5725 auto_save_mode_bits = XINT (Ffile_modes (current_buffer->filename)) | 0600; 5729 INTEGERP (modes)))
5726 else 5730 /* Remote files don't cooperate with stat. */
5727 auto_save_mode_bits = 0666; 5731 auto_save_mode_bits = XINT (modes) | 0600;
5732 }
5728 5733
5729 return 5734 return
5730 Fwrite_region (Qnil, Qnil, 5735 Fwrite_region (Qnil, Qnil,
@@ -6176,6 +6181,23 @@ DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_inte
6176 return Ffile_exists_p (string); 6181 return Ffile_exists_p (string);
6177} 6182}
6178 6183
6184DEFUN ("next-read-file-uses-dialog-p", Fnext_read_file_uses_dialog_p,
6185 Snext_read_file_uses_dialog_p, 0, 0, 0,
6186 doc: /* Return t if a call to `read-file-name' will use a dialog.
6187The return value is only relevant for a call to `read-file-name' that happens
6188before any other event (mouse or keypress) is handeled. */)
6189 ()
6190{
6191#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (TARGET_API_MAC_CARBON)
6192 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
6193 && use_dialog_box
6194 && use_file_dialog
6195 && have_menus_p ())
6196 return Qt;
6197#endif
6198 return Qnil;
6199}
6200
6179DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0, 6201DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0,
6180 doc: /* Read file name, prompting with PROMPT and completing in directory DIR. 6202 doc: /* Read file name, prompting with PROMPT and completing in directory DIR.
6181Value is not expanded---you must call `expand-file-name' yourself. 6203Value is not expanded---you must call `expand-file-name' yourself.
@@ -6308,10 +6330,7 @@ and `read-file-name-function'. */)
6308 GCPRO2 (insdef, default_filename); 6330 GCPRO2 (insdef, default_filename);
6309 6331
6310#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (TARGET_API_MAC_CARBON) 6332#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (TARGET_API_MAC_CARBON)
6311 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 6333 if (! NILP (Fnext_read_file_uses_dialog_p ()))
6312 && use_dialog_box
6313 && use_file_dialog
6314 && have_menus_p ())
6315 { 6334 {
6316 /* If DIR contains a file name, split it. */ 6335 /* If DIR contains a file name, split it. */
6317 Lisp_Object file; 6336 Lisp_Object file;
@@ -6323,7 +6342,8 @@ and `read-file-name-function'. */)
6323 } 6342 }
6324 if (!NILP(default_filename)) 6343 if (!NILP(default_filename))
6325 default_filename = Fexpand_file_name (default_filename, dir); 6344 default_filename = Fexpand_file_name (default_filename, dir);
6326 val = Fx_file_dialog (prompt, dir, default_filename, mustmatch); 6345 val = Fx_file_dialog (prompt, dir, default_filename, mustmatch,
6346 EQ (predicate, Qfile_directory_p) ? Qt : Qnil);
6327 add_to_history = 1; 6347 add_to_history = 1;
6328 } 6348 }
6329 else 6349 else
@@ -6695,6 +6715,7 @@ a non-nil value. */);
6695 6715
6696 defsubr (&Sread_file_name_internal); 6716 defsubr (&Sread_file_name_internal);
6697 defsubr (&Sread_file_name); 6717 defsubr (&Sread_file_name);
6718 defsubr (&Snext_read_file_uses_dialog_p);
6698 6719
6699#ifdef unix 6720#ifdef unix
6700 defsubr (&Sunix_sync); 6721 defsubr (&Sunix_sync);
diff --git a/src/fontset.c b/src/fontset.c
index 0c50be2d21e..f370f2ae981 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -790,14 +790,14 @@ fontset_pattern_regexp (pattern)
790 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME)) 790 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
791 { 791 {
792 /* We must at first update the cached data. */ 792 /* We must at first update the cached data. */
793 char *regex, *p0, *p1; 793 unsigned char *regex, *p0, *p1;
794 int ndashes = 0, nstars = 0; 794 int ndashes = 0, nstars = 0;
795 795
796 for (p0 = SDATA (pattern); *p0; p0++) 796 for (p0 = SDATA (pattern); *p0; p0++)
797 { 797 {
798 if (*p0 == '-') 798 if (*p0 == '-')
799 ndashes++; 799 ndashes++;
800 else if (*p0 == '*') 800 else if (*p0 == '*' && p0 > SDATA (pattern) && p0[-1] != '\\')
801 nstars++; 801 nstars++;
802 } 802 }
803 803
@@ -805,14 +805,14 @@ fontset_pattern_regexp (pattern)
805 we convert "*" to "[^-]*" which is much faster in regular 805 we convert "*" to "[^-]*" which is much faster in regular
806 expression matching. */ 806 expression matching. */
807 if (ndashes < 14) 807 if (ndashes < 14)
808 p1 = regex = (char *) alloca (SBYTES (pattern) + 2 * nstars + 1); 808 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
809 else 809 else
810 p1 = regex = (char *) alloca (SBYTES (pattern) + 5 * nstars + 1); 810 p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
811 811
812 *p1++ = '^'; 812 *p1++ = '^';
813 for (p0 = (char *) SDATA (pattern); *p0; p0++) 813 for (p0 = SDATA (pattern); *p0; p0++)
814 { 814 {
815 if (*p0 == '*') 815 if (*p0 == '*' && p0 > SDATA (pattern) && p0[-1] != '\\')
816 { 816 {
817 if (ndashes < 14) 817 if (ndashes < 14)
818 *p1++ = '.'; 818 *p1++ = '.';
diff --git a/src/gtkutil.c b/src/gtkutil.c
index dc091c1a09b..f5f05709e48 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1118,6 +1118,10 @@ create_dialog (wv, select_cb, deactivate_cb)
1118} 1118}
1119 1119
1120 1120
1121
1122/***********************************************************************
1123 File dialog functions
1124 ***********************************************************************/
1121enum 1125enum
1122{ 1126{
1123 XG_FILE_NOT_DONE, 1127 XG_FILE_NOT_DONE,
@@ -1126,6 +1130,85 @@ enum
1126 XG_FILE_DESTROYED, 1130 XG_FILE_DESTROYED,
1127}; 1131};
1128 1132
1133#ifdef HAVE_GTK_FILE_BOTH
1134int use_old_gtk_file_dialog;
1135#endif
1136
1137
1138#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW
1139/* Read a file name from the user using a file chooser dialog.
1140 F is the current frame.
1141 PROMPT is a prompt to show to the user. May not be NULL.
1142 DEFAULT_FILENAME is a default selection to be displayed. May be NULL.
1143 If MUSTMATCH_P is non-zero, the returned file name must be an existing
1144 file.
1145
1146 Returns a file name or NULL if no file was selected.
1147 The returned string must be freed by the caller. */
1148
1149static char *
1150xg_get_file_with_chooser (f, prompt, default_filename, mustmatch_p, only_dir_p)
1151 FRAME_PTR f;
1152 char *prompt;
1153 char *default_filename;
1154 int mustmatch_p, only_dir_p;
1155{
1156 GtkWidget *filewin;
1157 GtkWindow *gwin = GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f));
1158
1159 char *fn = 0;
1160 GtkFileChooserAction action = (mustmatch_p ?
1161 GTK_FILE_CHOOSER_ACTION_OPEN :
1162 GTK_FILE_CHOOSER_ACTION_SAVE);
1163
1164 if (only_dir_p)
1165 action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
1166
1167 filewin = gtk_file_chooser_dialog_new (prompt, gwin, action,
1168 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1169 (mustmatch_p || only_dir_p ?
1170 GTK_STOCK_OPEN : GTK_STOCK_OK),
1171 GTK_RESPONSE_OK,
1172 NULL);
1173
1174 xg_set_screen (filewin, f);
1175 gtk_widget_set_name (filewin, "emacs-filedialog");
1176 gtk_window_set_transient_for (GTK_WINDOW (filewin), gwin);
1177 gtk_window_set_destroy_with_parent (GTK_WINDOW (filewin), TRUE);
1178
1179
1180 if (default_filename)
1181 {
1182 Lisp_Object file;
1183 struct gcpro gcpro1;
1184 GCPRO1 (file);
1185
1186 /* File chooser does not understand ~/... in the file name. It must be
1187 an absolute name starting with /. */
1188 if (default_filename[0] != '/')
1189 {
1190 file = Fexpand_file_name (build_string (default_filename), Qnil);
1191 default_filename = SDATA (file);
1192 }
1193
1194 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filewin),
1195 default_filename);
1196
1197 UNGCPRO;
1198 }
1199
1200 gtk_widget_show (filewin);
1201
1202 if (gtk_dialog_run (GTK_DIALOG (filewin)) == GTK_RESPONSE_OK)
1203 fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filewin));
1204
1205 gtk_widget_destroy (filewin);
1206
1207 return fn;
1208}
1209#endif /* HAVE_GTK_FILE_CHOOSER_DIALOG_NEW */
1210
1211#ifdef HAVE_GTK_FILE_SELECTION_NEW
1129/* Callback function invoked when the Ok button is pressed in 1212/* Callback function invoked when the Ok button is pressed in
1130 a file dialog. 1213 a file dialog.
1131 W is the file dialog widget, 1214 W is the file dialog widget,
@@ -1167,7 +1250,7 @@ xg_file_sel_destroy (w, arg)
1167 *(int*)arg = XG_FILE_DESTROYED; 1250 *(int*)arg = XG_FILE_DESTROYED;
1168} 1251}
1169 1252
1170/* Read a file name from the user using a file dialog. 1253/* Read a file name from the user using a file selection dialog.
1171 F is the current frame. 1254 F is the current frame.
1172 PROMPT is a prompt to show to the user. May not be NULL. 1255 PROMPT is a prompt to show to the user. May not be NULL.
1173 DEFAULT_FILENAME is a default selection to be displayed. May be NULL. 1256 DEFAULT_FILENAME is a default selection to be displayed. May be NULL.
@@ -1177,12 +1260,13 @@ xg_file_sel_destroy (w, arg)
1177 Returns a file name or NULL if no file was selected. 1260 Returns a file name or NULL if no file was selected.
1178 The returned string must be freed by the caller. */ 1261 The returned string must be freed by the caller. */
1179 1262
1180char * 1263static char *
1181xg_get_file_name (f, prompt, default_filename, mustmatch_p) 1264xg_get_file_with_selection (f, prompt, default_filename,
1265 mustmatch_p, only_dir_p)
1182 FRAME_PTR f; 1266 FRAME_PTR f;
1183 char *prompt; 1267 char *prompt;
1184 char *default_filename; 1268 char *default_filename;
1185 int mustmatch_p; 1269 int mustmatch_p, only_dir_p;
1186{ 1270{
1187 GtkWidget *filewin; 1271 GtkWidget *filewin;
1188 GtkFileSelection *filesel; 1272 GtkFileSelection *filesel;
@@ -1193,9 +1277,7 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p)
1193 filesel = GTK_FILE_SELECTION (filewin); 1277 filesel = GTK_FILE_SELECTION (filewin);
1194 1278
1195 xg_set_screen (filewin, f); 1279 xg_set_screen (filewin, f);
1196
1197 gtk_widget_set_name (filewin, "emacs-filedialog"); 1280 gtk_widget_set_name (filewin, "emacs-filedialog");
1198
1199 gtk_window_set_transient_for (GTK_WINDOW (filewin), 1281 gtk_window_set_transient_for (GTK_WINDOW (filewin),
1200 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f))); 1282 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
1201 gtk_window_set_destroy_with_parent (GTK_WINDOW (filewin), TRUE); 1283 gtk_window_set_destroy_with_parent (GTK_WINDOW (filewin), TRUE);
@@ -1237,6 +1319,49 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p)
1237 1319
1238 return fn; 1320 return fn;
1239} 1321}
1322#endif /* HAVE_GTK_FILE_SELECTION_NEW */
1323
1324/* Read a file name from the user using a file dialog, either the old
1325 file selection dialog, or the new file chooser dialog. Which to use
1326 depends on what the GTK version used has, and what the value of
1327 gtk-use-old-file-dialog.
1328 F is the current frame.
1329 PROMPT is a prompt to show to the user. May not be NULL.
1330 DEFAULT_FILENAME is a default selection to be displayed. May be NULL.
1331 If MUSTMATCH_P is non-zero, the returned file name must be an existing
1332 file.
1333
1334 Returns a file name or NULL if no file was selected.
1335 The returned string must be freed by the caller. */
1336
1337char *
1338xg_get_file_name (f, prompt, default_filename, mustmatch_p, only_dir_p)
1339 FRAME_PTR f;
1340 char *prompt;
1341 char *default_filename;
1342 int mustmatch_p, only_dir_p;
1343{
1344#ifdef HAVE_GTK_FILE_BOTH
1345 if (use_old_gtk_file_dialog)
1346 return xg_get_file_with_selection (f, prompt, default_filename,
1347 mustmatch_p, only_dir_p);
1348 return xg_get_file_with_chooser (f, prompt, default_filename,
1349 mustmatch_p, only_dir_p);
1350
1351#else /* not HAVE_GTK_FILE_BOTH */
1352
1353#ifdef HAVE_GTK_FILE_SELECTION_DIALOG_NEW
1354 return xg_get_file_with_selection (f, prompt, default_filename,
1355 mustmatch_p, only_dir_p);
1356#endif
1357#ifdef HAVE_GTK_FILE_CHOOSER_DIALOG_NEW
1358 return xg_get_file_with_chooser (f, prompt, default_filename,
1359 mustmatch_p, only_dir_p);
1360#endif
1361
1362#endif /* HAVE_GTK_FILE_BOTH */
1363 return 0;
1364}
1240 1365
1241 1366
1242/*********************************************************************** 1367/***********************************************************************
diff --git a/src/gtkutil.h b/src/gtkutil.h
index c0055f361cc..44e82885d7f 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -126,13 +126,18 @@ typedef struct _widget_value
126 struct _widget_value *free_list; 126 struct _widget_value *free_list;
127} widget_value; 127} widget_value;
128 128
129#ifdef HAVE_GTK_FILE_BOTH
130extern int use_old_gtk_file_dialog;
131#endif
132
129extern widget_value *malloc_widget_value P_ ((void)); 133extern widget_value *malloc_widget_value P_ ((void));
130extern void free_widget_value P_ ((widget_value *)); 134extern void free_widget_value P_ ((widget_value *));
131 135
132extern char *xg_get_file_name P_ ((FRAME_PTR f, 136extern char *xg_get_file_name P_ ((FRAME_PTR f,
133 char *prompt, 137 char *prompt,
134 char *default_filename, 138 char *default_filename,
135 int mustmatch_p)); 139 int mustmatch_p,
140 int only_dir_p));
136 141
137extern GtkWidget *xg_create_widget P_ ((char *type, 142extern GtkWidget *xg_create_widget P_ ((char *type,
138 char *name, 143 char *name,
diff --git a/src/insdel.c b/src/insdel.c
index ffe7006a45b..f5f56f0371f 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1464,7 +1464,7 @@ adjust_after_insert (from, from_byte, to, to_byte, newlen)
1464 Z -= len; Z_BYTE -= len_byte; 1464 Z -= len; Z_BYTE -= len_byte;
1465 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte); 1465 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1466} 1466}
1467 1467
1468/* Replace the text from character positions FROM to TO with NEW, 1468/* Replace the text from character positions FROM to TO with NEW,
1469 If PREPARE is nonzero, call prepare_to_modify_buffer. 1469 If PREPARE is nonzero, call prepare_to_modify_buffer.
1470 If INHERIT, the newly inserted text should inherit text properties 1470 If INHERIT, the newly inserted text should inherit text properties
@@ -1641,6 +1641,122 @@ replace_range (from, to, new, prepare, inherit, markers)
1641 update_compositions (from, GPT, CHECK_BORDER); 1641 update_compositions (from, GPT, CHECK_BORDER);
1642} 1642}
1643 1643
1644/* Replace the text from character positions FROM to TO with
1645 the text in INS of length INSCHARS.
1646 Keep the text properties that applied to the old characters
1647 (extending them to all the new chars if there are more new chars).
1648
1649 Note that this does not yet handle markers quite right.
1650
1651 If MARKERS is nonzero, relocate markers.
1652
1653 Unlike most functions at this level, never call
1654 prepare_to_modify_buffer and never call signal_after_change. */
1655
1656void
1657replace_range_2 (from, from_byte, to, to_byte, ins, inschars, insbytes, markers)
1658 int from, from_byte, to, to_byte;
1659 char *ins;
1660 int inschars, insbytes, markers;
1661{
1662 int nbytes_del, nchars_del;
1663 Lisp_Object temp;
1664
1665 CHECK_MARKERS ();
1666
1667 nchars_del = to - from;
1668 nbytes_del = to_byte - from_byte;
1669
1670 if (nbytes_del <= 0 && insbytes == 0)
1671 return;
1672
1673 /* Make sure point-max won't overflow after this insertion. */
1674 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1675 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1676 error ("Maximum buffer size exceeded");
1677
1678 /* Make sure the gap is somewhere in or next to what we are deleting. */
1679 if (from > GPT)
1680 gap_right (from, from_byte);
1681 if (to < GPT)
1682 gap_left (to, to_byte, 0);
1683
1684 GAP_SIZE += nbytes_del;
1685 ZV -= nchars_del;
1686 Z -= nchars_del;
1687 ZV_BYTE -= nbytes_del;
1688 Z_BYTE -= nbytes_del;
1689 GPT = from;
1690 GPT_BYTE = from_byte;
1691 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1692
1693 if (GPT_BYTE < GPT)
1694 abort ();
1695
1696 if (GPT - BEG < BEG_UNCHANGED)
1697 BEG_UNCHANGED = GPT - BEG;
1698 if (Z - GPT < END_UNCHANGED)
1699 END_UNCHANGED = Z - GPT;
1700
1701 if (GAP_SIZE < insbytes)
1702 make_gap (insbytes - GAP_SIZE);
1703
1704 /* Copy the replacement text into the buffer. */
1705 bcopy (ins, GPT_ADDR, insbytes);
1706
1707#ifdef BYTE_COMBINING_DEBUG
1708 /* We have copied text into the gap, but we have not marked
1709 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1710 here, for both the previous text and the following text.
1711 Meanwhile, GPT_ADDR does point to
1712 the text that has been stored by copy_text. */
1713 if (count_combining_before (GPT_ADDR, insbytes, from, from_byte)
1714 || count_combining_after (GPT_ADDR, insbytes, from, from_byte))
1715 abort ();
1716#endif
1717
1718 GAP_SIZE -= insbytes;
1719 GPT += inschars;
1720 ZV += inschars;
1721 Z += inschars;
1722 GPT_BYTE += insbytes;
1723 ZV_BYTE += insbytes;
1724 Z_BYTE += insbytes;
1725 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1726
1727 if (GPT_BYTE < GPT)
1728 abort ();
1729
1730 /* Adjust the overlay center as needed. This must be done after
1731 adjusting the markers that bound the overlays. */
1732 if (nchars_del != inschars)
1733 {
1734 adjust_overlays_for_insert (from, inschars);
1735 adjust_overlays_for_delete (from + inschars, nchars_del);
1736 }
1737
1738 /* Adjust markers for the deletion and the insertion. */
1739 if (markers
1740 && ! (nchars_del == 1 && inschars == 1))
1741 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1742 inschars, insbytes);
1743
1744 offset_intervals (current_buffer, from, inschars - nchars_del);
1745
1746 /* Relocate point as if it were a marker. */
1747 if (from < PT && nchars_del != inschars)
1748 adjust_point ((from + inschars - (PT < to ? PT : to)),
1749 (from_byte + insbytes
1750 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1751
1752 if (insbytes == 0)
1753 evaporate_overlays (from);
1754
1755 CHECK_MARKERS ();
1756
1757 MODIFF++;
1758}
1759
1644/* Delete characters in current buffer 1760/* Delete characters in current buffer
1645 from FROM up to (but not including) TO. 1761 from FROM up to (but not including) TO.
1646 If TO comes before FROM, we delete nothing. */ 1762 If TO comes before FROM, we delete nothing. */
diff --git a/src/keyboard.c b/src/keyboard.c
index 475479b66a3..35bfd1402c9 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3694,36 +3694,26 @@ kbd_buffer_store_event_hold (event, hold_quit)
3694 Discard the event if it would fill the last slot. */ 3694 Discard the event if it would fill the last slot. */
3695 if (kbd_fetch_ptr - 1 != kbd_store_ptr) 3695 if (kbd_fetch_ptr - 1 != kbd_store_ptr)
3696 { 3696 {
3697 *kbd_store_ptr = *event;
3698 ++kbd_store_ptr;
3699 }
3700}
3697 3701
3698#if 0 /* The SELECTION_REQUEST_EVENT case looks bogus, and it's error
3699 prone to assign individual members for other events, in case
3700 the input_event structure is changed. --2000-07-13, gerd. */
3701 struct input_event *sp = kbd_store_ptr;
3702 sp->kind = event->kind;
3703 if (event->kind == SELECTION_REQUEST_EVENT)
3704 {
3705 /* We must not use the ordinary copying code for this case,
3706 since `part' is an enum and copying it might not copy enough
3707 in this case. */
3708 bcopy (event, (char *) sp, sizeof (*event));
3709 }
3710 else
3711 3702
3712 { 3703/* Put an input event back in the head of the event queue. */
3713 sp->code = event->code;
3714 sp->part = event->part;
3715 sp->frame_or_window = event->frame_or_window;
3716 sp->arg = event->arg;
3717 sp->modifiers = event->modifiers;
3718 sp->x = event->x;
3719 sp->y = event->y;
3720 sp->timestamp = event->timestamp;
3721 }
3722#else
3723 *kbd_store_ptr = *event;
3724#endif
3725 3704
3726 ++kbd_store_ptr; 3705void
3706kbd_buffer_unget_event (event)
3707 register struct input_event *event;
3708{
3709 if (kbd_fetch_ptr == kbd_buffer)
3710 kbd_fetch_ptr = kbd_buffer + KBD_BUFFER_SIZE;
3711
3712 /* Don't let the very last slot in the buffer become full, */
3713 if (kbd_fetch_ptr - 1 != kbd_store_ptr)
3714 {
3715 --kbd_fetch_ptr;
3716 *kbd_fetch_ptr = *event;
3727 } 3717 }
3728} 3718}
3729 3719
@@ -3938,7 +3928,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
3938 /* These two kinds of events get special handling 3928 /* These two kinds of events get special handling
3939 and don't actually appear to the command loop. 3929 and don't actually appear to the command loop.
3940 We return nil for them. */ 3930 We return nil for them. */
3941 if (event->kind == SELECTION_REQUEST_EVENT) 3931 if (event->kind == SELECTION_REQUEST_EVENT
3932 || event->kind == SELECTION_CLEAR_EVENT)
3942 { 3933 {
3943#ifdef HAVE_X11 3934#ifdef HAVE_X11
3944 struct input_event copy; 3935 struct input_event copy;
@@ -3949,7 +3940,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
3949 copy = *event; 3940 copy = *event;
3950 kbd_fetch_ptr = event + 1; 3941 kbd_fetch_ptr = event + 1;
3951 input_pending = readable_events (0); 3942 input_pending = readable_events (0);
3952 x_handle_selection_request (&copy); 3943 x_handle_selection_event (&copy);
3953#else 3944#else
3954 /* We're getting selection request events, but we don't have 3945 /* We're getting selection request events, but we don't have
3955 a window system. */ 3946 a window system. */
@@ -3957,22 +3948,6 @@ kbd_buffer_get_event (kbp, used_mouse_menu)
3957#endif 3948#endif
3958 } 3949 }
3959 3950
3960 else if (event->kind == SELECTION_CLEAR_EVENT)
3961 {
3962#ifdef HAVE_X11
3963 struct input_event copy;
3964
3965 /* Remove it from the buffer before processing it. */
3966 copy = *event;
3967 kbd_fetch_ptr = event + 1;
3968 input_pending = readable_events (0);
3969 x_handle_selection_clear (&copy);
3970#else
3971 /* We're getting selection request events, but we don't have
3972 a window system. */
3973 abort ();
3974#endif
3975 }
3976#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS) 3951#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS)
3977 else if (event->kind == DELETE_WINDOW_EVENT) 3952 else if (event->kind == DELETE_WINDOW_EVENT)
3978 { 3953 {
@@ -4201,7 +4176,8 @@ swallow_events (do_display)
4201 4176
4202 /* These two kinds of events get special handling 4177 /* These two kinds of events get special handling
4203 and don't actually appear to the command loop. */ 4178 and don't actually appear to the command loop. */
4204 if (event->kind == SELECTION_REQUEST_EVENT) 4179 if (event->kind == SELECTION_REQUEST_EVENT
4180 || event->kind == SELECTION_CLEAR_EVENT)
4205 { 4181 {
4206#ifdef HAVE_X11 4182#ifdef HAVE_X11
4207 struct input_event copy; 4183 struct input_event copy;
@@ -4212,25 +4188,7 @@ swallow_events (do_display)
4212 copy = *event; 4188 copy = *event;
4213 kbd_fetch_ptr = event + 1; 4189 kbd_fetch_ptr = event + 1;
4214 input_pending = readable_events (0); 4190 input_pending = readable_events (0);
4215 x_handle_selection_request (&copy); 4191 x_handle_selection_event (&copy);
4216#else
4217 /* We're getting selection request events, but we don't have
4218 a window system. */
4219 abort ();
4220#endif
4221 }
4222
4223 else if (event->kind == SELECTION_CLEAR_EVENT)
4224 {
4225#ifdef HAVE_X11
4226 struct input_event copy;
4227
4228 /* Remove it from the buffer before processing it, */
4229 copy = *event;
4230
4231 kbd_fetch_ptr = event + 1;
4232 input_pending = readable_events (0);
4233 x_handle_selection_clear (&copy);
4234#else 4192#else
4235 /* We're getting selection request events, but we don't have 4193 /* We're getting selection request events, but we don't have
4236 a window system. */ 4194 a window system. */
@@ -11590,7 +11548,8 @@ mark_kboards ()
11590 { 11548 {
11591 if (event == kbd_buffer + KBD_BUFFER_SIZE) 11549 if (event == kbd_buffer + KBD_BUFFER_SIZE)
11592 event = kbd_buffer; 11550 event = kbd_buffer;
11593 if (event->kind != SELECTION_REQUEST_EVENT) 11551 if (event->kind != SELECTION_REQUEST_EVENT
11552 && event->kind != SELECTION_CLEAR_EVENT)
11594 { 11553 {
11595 mark_object (event->x); 11554 mark_object (event->x);
11596 mark_object (event->y); 11555 mark_object (event->y);
diff --git a/src/keyboard.h b/src/keyboard.h
index 3039f028bbb..8ff1543d92e 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -330,6 +330,7 @@ extern int lucid_event_type_list_p P_ ((Lisp_Object));
330extern void kbd_buffer_store_event P_ ((struct input_event *)); 330extern void kbd_buffer_store_event P_ ((struct input_event *));
331extern void kbd_buffer_store_event_hold P_ ((struct input_event *, 331extern void kbd_buffer_store_event_hold P_ ((struct input_event *,
332 struct input_event *)); 332 struct input_event *));
333extern void kbd_buffer_unget_event P_ ((struct input_event *));
333#ifdef POLL_FOR_INPUT 334#ifdef POLL_FOR_INPUT
334extern void poll_for_input_1 P_ ((void)); 335extern void poll_for_input_1 P_ ((void));
335#endif 336#endif
diff --git a/src/lisp.h b/src/lisp.h
index 55664cb8ca3..7b9b0427da6 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3123,7 +3123,7 @@ extern void syms_of_xfns P_ ((void));
3123#ifdef HAVE_WINDOW_SYSTEM 3123#ifdef HAVE_WINDOW_SYSTEM
3124/* Defined in xfns.c, w32fns.c, or macfns.c */ 3124/* Defined in xfns.c, w32fns.c, or macfns.c */
3125EXFUN (Fxw_display_color_p, 1); 3125EXFUN (Fxw_display_color_p, 1);
3126EXFUN (Fx_file_dialog, 4); 3126EXFUN (Fx_file_dialog, 5);
3127#endif /* HAVE_WINDOW_SYSTEM */ 3127#endif /* HAVE_WINDOW_SYSTEM */
3128 3128
3129/* Defined in xsmfns.c */ 3129/* Defined in xsmfns.c */
diff --git a/src/macfns.c b/src/macfns.c
index 88f975a65c8..401c7011fea 100644
--- a/src/macfns.c
+++ b/src/macfns.c
@@ -4216,22 +4216,23 @@ Value is t if tooltip was open, nil otherwise. */)
4216 4216
4217extern Lisp_Object Qfile_name_history; 4217extern Lisp_Object Qfile_name_history;
4218 4218
4219DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, 4219DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
4220 doc: /* Read file name, prompting with PROMPT in directory DIR. 4220 doc: /* Read file name, prompting with PROMPT in directory DIR.
4221Use a file selection dialog. 4221Use a file selection dialog.
4222Select DEFAULT-FILENAME in the dialog's file selection box, if 4222Select DEFAULT-FILENAME in the dialog's file selection box, if
4223specified. Ensure that file exists if MUSTMATCH is non-nil. */) 4223specified. Ensure that file exists if MUSTMATCH is non-nil.
4224 (prompt, dir, default_filename, mustmatch) 4224If ONLY-DIR-P is non-nil, the user can only select directories. */)
4225 Lisp_Object prompt, dir, default_filename, mustmatch; 4225 (prompt, dir, default_filename, mustmatch, only_dir_p)
4226 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
4226{ 4227{
4227 struct frame *f = SELECTED_FRAME (); 4228 struct frame *f = SELECTED_FRAME ();
4228 Lisp_Object file = Qnil; 4229 Lisp_Object file = Qnil;
4229 int count = SPECPDL_INDEX (); 4230 int count = SPECPDL_INDEX ();
4230 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 4231 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
4231 char filename[1001]; 4232 char filename[1001];
4232 int default_filter_index = 1; /* 1: All Files, 2: Directories only */ 4233 int default_filter_index = 1; /* 1: All Files, 2: Directories only */
4233 4234
4234 GCPRO5 (prompt, dir, default_filename, mustmatch, file); 4235 GCPRO6 (prompt, dir, default_filename, mustmatch, file, only_dir_p);
4235 CHECK_STRING (prompt); 4236 CHECK_STRING (prompt);
4236 CHECK_STRING (dir); 4237 CHECK_STRING (dir);
4237 4238
@@ -4245,7 +4246,8 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
4245 NavDialogRef dialogRef; 4246 NavDialogRef dialogRef;
4246 NavTypeListHandle fileTypes = NULL; 4247 NavTypeListHandle fileTypes = NULL;
4247 NavUserAction userAction; 4248 NavUserAction userAction;
4248 CFStringRef message=NULL, client=NULL, saveName = NULL; 4249 CFStringRef message=NULL, client=NULL, saveName = NULL, ok = NULL;
4250 CFStringRef title = NULL;
4249 4251
4250 BLOCK_INPUT; 4252 BLOCK_INPUT;
4251 /* No need for a callback function because we are modal */ 4253 /* No need for a callback function because we are modal */
@@ -4268,13 +4270,19 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
4268 options.clientName = client; 4270 options.clientName = client;
4269 */ 4271 */
4270 4272
4271 /* Do Dired hack copied from w32fns.c */ 4273 if (!NILP (only_dir_p))
4272 if (!NILP(prompt) && strncmp (SDATA(prompt), "Dired", 5) == 0)
4273 status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL, 4274 status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL,
4274 &dialogRef); 4275 &dialogRef);
4275 else if (NILP (mustmatch)) 4276 else if (NILP (mustmatch))
4276 { 4277 {
4277 /* This is a save dialog */ 4278 /* This is a save dialog */
4279 ok = CFStringCreateWithCString (NULL, "Ok", kCFStringEncodingUTF8);
4280 title = CFStringCreateWithCString (NULL, "Enter name",
4281 kCFStringEncodingUTF8);
4282 options.optionFlags |= kNavDontConfirmReplacement;
4283 options.actionButtonLabel = ok;
4284 options.windowTitle = title;
4285
4278 if (!NILP(default_filename)) 4286 if (!NILP(default_filename))
4279 { 4287 {
4280 saveName = CFStringCreateWithCString(NULL, SDATA(default_filename), 4288 saveName = CFStringCreateWithCString(NULL, SDATA(default_filename),
@@ -4282,20 +4290,10 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
4282 options.saveFileName = saveName; 4290 options.saveFileName = saveName;
4283 options.optionFlags |= kNavSelectDefaultLocation; 4291 options.optionFlags |= kNavSelectDefaultLocation;
4284 } 4292 }
4285 /* MAC_TODO: Find a better way to determine if this is a save
4286 or load dialog than comparing dir with default_filename */
4287 if (EQ(dir, default_filename))
4288 {
4289 status = NavCreateChooseFileDialog(&options, fileTypes,
4290 NULL, NULL, NULL, NULL,
4291 &dialogRef);
4292 }
4293 else {
4294 status = NavCreatePutFileDialog(&options, 4293 status = NavCreatePutFileDialog(&options,
4295 'TEXT', kNavGenericSignature, 4294 'TEXT', kNavGenericSignature,
4296 NULL, NULL, &dialogRef); 4295 NULL, NULL, &dialogRef);
4297 } 4296 }
4298 }
4299 else 4297 else
4300 { 4298 {
4301 /* This is an open dialog*/ 4299 /* This is an open dialog*/
@@ -4324,6 +4322,8 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
4324 if (saveName) CFRelease(saveName); 4322 if (saveName) CFRelease(saveName);
4325 if (client) CFRelease(client); 4323 if (client) CFRelease(client);
4326 if (message) CFRelease(message); 4324 if (message) CFRelease(message);
4325 if (ok) CFRelease(ok);
4326 if (title) CFRelease(title);
4327 4327
4328 if (status == noErr) { 4328 if (status == noErr) {
4329 userAction = NavDialogGetUserAction(dialogRef); 4329 userAction = NavDialogGetUserAction(dialogRef);
diff --git a/src/process.c b/src/process.c
index 9638c2875da..db6e85c0fb3 100644
--- a/src/process.c
+++ b/src/process.c
@@ -310,6 +310,7 @@ static SELECT_TYPE non_keyboard_wait_mask;
310 310
311static SELECT_TYPE non_process_wait_mask; 311static SELECT_TYPE non_process_wait_mask;
312 312
313#ifdef NON_BLOCKING_CONNECT
313/* Mask of bits indicating the descriptors that we wait for connect to 314/* Mask of bits indicating the descriptors that we wait for connect to
314 complete on. Once they complete, they are removed from this mask 315 complete on. Once they complete, they are removed from this mask
315 and added to the input_wait_mask and non_keyboard_wait_mask. */ 316 and added to the input_wait_mask and non_keyboard_wait_mask. */
@@ -319,6 +320,11 @@ static SELECT_TYPE connect_wait_mask;
319/* Number of bits set in connect_wait_mask. */ 320/* Number of bits set in connect_wait_mask. */
320static int num_pending_connects; 321static int num_pending_connects;
321 322
323#define IF_NON_BLOCKING_CONNECT(s) s
324#else
325#define IF_NON_BLOCKING_CONNECT(s)
326#endif
327
322/* The largest descriptor currently in use for a process object. */ 328/* The largest descriptor currently in use for a process object. */
323static int max_process_desc; 329static int max_process_desc;
324 330
@@ -3672,12 +3678,14 @@ deactivate_process (proc)
3672 chan_process[inchannel] = Qnil; 3678 chan_process[inchannel] = Qnil;
3673 FD_CLR (inchannel, &input_wait_mask); 3679 FD_CLR (inchannel, &input_wait_mask);
3674 FD_CLR (inchannel, &non_keyboard_wait_mask); 3680 FD_CLR (inchannel, &non_keyboard_wait_mask);
3681#ifdef NON_BLOCKING_CONNECT
3675 if (FD_ISSET (inchannel, &connect_wait_mask)) 3682 if (FD_ISSET (inchannel, &connect_wait_mask))
3676 { 3683 {
3677 FD_CLR (inchannel, &connect_wait_mask); 3684 FD_CLR (inchannel, &connect_wait_mask);
3678 if (--num_pending_connects < 0) 3685 if (--num_pending_connects < 0)
3679 abort (); 3686 abort ();
3680 } 3687 }
3688#endif
3681 if (inchannel == max_process_desc) 3689 if (inchannel == max_process_desc)
3682 { 3690 {
3683 int i; 3691 int i;
@@ -4038,8 +4046,11 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4038{ 4046{
4039 register int channel, nfds; 4047 register int channel, nfds;
4040 SELECT_TYPE Available; 4048 SELECT_TYPE Available;
4049#ifdef NON_BLOCKING_CONNECT
4041 SELECT_TYPE Connecting; 4050 SELECT_TYPE Connecting;
4042 int check_connect, check_delay, no_avail; 4051 int check_connect;
4052#endif
4053 int check_delay, no_avail;
4043 int xerrno; 4054 int xerrno;
4044 Lisp_Object proc; 4055 Lisp_Object proc;
4045 EMACS_TIME timeout, end_time; 4056 EMACS_TIME timeout, end_time;
@@ -4050,7 +4061,9 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4050 int saved_waiting_for_user_input_p = waiting_for_user_input_p; 4061 int saved_waiting_for_user_input_p = waiting_for_user_input_p;
4051 4062
4052 FD_ZERO (&Available); 4063 FD_ZERO (&Available);
4064#ifdef NON_BLOCKING_CONNECT
4053 FD_ZERO (&Connecting); 4065 FD_ZERO (&Connecting);
4066#endif
4054 4067
4055 /* If wait_proc is a process to watch, set wait_channel accordingly. */ 4068 /* If wait_proc is a process to watch, set wait_channel accordingly. */
4056 if (wait_proc != NULL) 4069 if (wait_proc != NULL)
@@ -4187,7 +4200,10 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4187 timeout to get our attention. */ 4200 timeout to get our attention. */
4188 if (update_tick != process_tick && do_display) 4201 if (update_tick != process_tick && do_display)
4189 { 4202 {
4190 SELECT_TYPE Atemp, Ctemp; 4203 SELECT_TYPE Atemp;
4204#ifdef NON_BLOCKING_CONNECT
4205 SELECT_TYPE Ctemp;
4206#endif
4191 4207
4192 Atemp = input_wait_mask; 4208 Atemp = input_wait_mask;
4193#if 0 4209#if 0
@@ -4199,11 +4215,16 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4199 */ 4215 */
4200 FD_CLR (0, &Atemp); 4216 FD_CLR (0, &Atemp);
4201#endif 4217#endif
4202 Ctemp = connect_wait_mask; 4218 IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
4219
4203 EMACS_SET_SECS_USECS (timeout, 0, 0); 4220 EMACS_SET_SECS_USECS (timeout, 0, 0);
4204 if ((select (max (max_process_desc, max_keyboard_desc) + 1, 4221 if ((select (max (max_process_desc, max_keyboard_desc) + 1,
4205 &Atemp, 4222 &Atemp,
4223#ifdef NON_BLOCKING_CONNECT
4206 (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0), 4224 (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
4225#else
4226 (SELECT_TYPE *)0,
4227#endif
4207 (SELECT_TYPE *)0, &timeout) 4228 (SELECT_TYPE *)0, &timeout)
4208 <= 0)) 4229 <= 0))
4209 { 4230 {
@@ -4263,12 +4284,14 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4263 if (XINT (wait_proc->infd) < 0) /* Terminated */ 4284 if (XINT (wait_proc->infd) < 0) /* Terminated */
4264 break; 4285 break;
4265 FD_SET (XINT (wait_proc->infd), &Available); 4286 FD_SET (XINT (wait_proc->infd), &Available);
4266 check_connect = check_delay = 0; 4287 check_delay = 0;
4288 IF_NON_BLOCKING_CONNECT (check_connect = 0);
4267 } 4289 }
4268 else if (!NILP (wait_for_cell)) 4290 else if (!NILP (wait_for_cell))
4269 { 4291 {
4270 Available = non_process_wait_mask; 4292 Available = non_process_wait_mask;
4271 check_connect = check_delay = 0; 4293 check_delay = 0;
4294 IF_NON_BLOCKING_CONNECT (check_connect = 0);
4272 } 4295 }
4273 else 4296 else
4274 { 4297 {
@@ -4276,7 +4299,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4276 Available = non_keyboard_wait_mask; 4299 Available = non_keyboard_wait_mask;
4277 else 4300 else
4278 Available = input_wait_mask; 4301 Available = input_wait_mask;
4279 check_connect = (num_pending_connects > 0); 4302 IF_NON_BLOCKING_CONNECT (check_connect = (num_pending_connects > 0));
4280 check_delay = wait_channel >= 0 ? 0 : process_output_delay_count; 4303 check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
4281 } 4304 }
4282 4305
@@ -4301,8 +4324,10 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4301 } 4324 }
4302 else 4325 else
4303 { 4326 {
4327#ifdef NON_BLOCKING_CONNECT
4304 if (check_connect) 4328 if (check_connect)
4305 Connecting = connect_wait_mask; 4329 Connecting = connect_wait_mask;
4330#endif
4306 4331
4307#ifdef ADAPTIVE_READ_BUFFERING 4332#ifdef ADAPTIVE_READ_BUFFERING
4308 if (process_output_skip && check_delay > 0) 4333 if (process_output_skip && check_delay > 0)
@@ -4333,7 +4358,11 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4333 4358
4334 nfds = select (max (max_process_desc, max_keyboard_desc) + 1, 4359 nfds = select (max (max_process_desc, max_keyboard_desc) + 1,
4335 &Available, 4360 &Available,
4361#ifdef NON_BLOCKING_CONNECT
4336 (check_connect ? &Connecting : (SELECT_TYPE *)0), 4362 (check_connect ? &Connecting : (SELECT_TYPE *)0),
4363#else
4364 (SELECT_TYPE *)0,
4365#endif
4337 (SELECT_TYPE *)0, &timeout); 4366 (SELECT_TYPE *)0, &timeout);
4338 } 4367 }
4339 4368
@@ -4389,7 +4418,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
4389 if (no_avail) 4418 if (no_avail)
4390 { 4419 {
4391 FD_ZERO (&Available); 4420 FD_ZERO (&Available);
4392 check_connect = 0; 4421 IF_NON_BLOCKING_CONNECT (check_connect = 0);
4393 } 4422 }
4394 4423
4395#if defined(sun) && !defined(USG5_4) 4424#if defined(sun) && !defined(USG5_4)
@@ -6620,6 +6649,11 @@ init_process ()
6620 FD_ZERO (&non_process_wait_mask); 6649 FD_ZERO (&non_process_wait_mask);
6621 max_process_desc = 0; 6650 max_process_desc = 0;
6622 6651
6652#ifdef NON_BLOCKING_CONNECT
6653 FD_ZERO (&connect_wait_mask);
6654 num_pending_connects = 0;
6655#endif
6656
6623#ifdef ADAPTIVE_READ_BUFFERING 6657#ifdef ADAPTIVE_READ_BUFFERING
6624 process_output_delay_count = 0; 6658 process_output_delay_count = 0;
6625 process_output_skip = 0; 6659 process_output_skip = 0;
diff --git a/src/w32fns.c b/src/w32fns.c
index 38faa7c3199..08780e05b1f 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -5607,14 +5607,12 @@ w32_font_match (fontname, pattern)
5607 char * fontname; 5607 char * fontname;
5608 char * pattern; 5608 char * pattern;
5609{ 5609{
5610 char *font_name_copy;
5611 char *ptr; 5610 char *ptr;
5612 Lisp_Object encoded_font_name; 5611 char *font_name_copy;
5613 char *regex = alloca (strlen (pattern) * 2 + 3); 5612 char *regex = alloca (strlen (pattern) * 2 + 3);
5614 5613
5615 /* Convert fontname to unibyte for match. */ 5614 font_name_copy = alloca (strlen (fontname) + 1);
5616 encoded_font_name = string_make_unibyte (build_string (fontname)); 5615 strcpy (font_name_copy, fontname);
5617 font_name_copy = SDATA (encoded_font_name);
5618 5616
5619 ptr = regex; 5617 ptr = regex;
5620 *ptr++ = '^'; 5618 *ptr++ = '^';
@@ -5652,8 +5650,8 @@ w32_font_match (fontname, pattern)
5652 return FALSE; 5650 return FALSE;
5653 } 5651 }
5654 5652
5655 return (fast_c_string_match_ignore_case (build_string (regex), 5653 return (fast_string_match_ignore_case (build_string (regex),
5656 font_name_copy) >= 0); 5654 build_string(font_name_copy)) >= 0);
5657} 5655}
5658 5656
5659/* Callback functions, and a structure holding info they need, for 5657/* Callback functions, and a structure holding info they need, for
@@ -7742,23 +7740,24 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
7742 return 0; 7740 return 0;
7743} 7741}
7744 7742
7745DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, 7743DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
7746 doc: /* Read file name, prompting with PROMPT in directory DIR. 7744 doc: /* Read file name, prompting with PROMPT in directory DIR.
7747Use a file selection dialog. 7745Use a file selection dialog.
7748Select DEFAULT-FILENAME in the dialog's file selection box, if 7746Select DEFAULT-FILENAME in the dialog's file selection box, if
7749specified. Ensure that file exists if MUSTMATCH is non-nil. */) 7747specified. Ensure that file exists if MUSTMATCH is non-nil.
7750 (prompt, dir, default_filename, mustmatch) 7748If ONLY-DIR-P is non-nil, the user can only select directories. */)
7751 Lisp_Object prompt, dir, default_filename, mustmatch; 7749 (prompt, dir, default_filename, mustmatch, only_dir_p)
7750 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
7752{ 7751{
7753 struct frame *f = SELECTED_FRAME (); 7752 struct frame *f = SELECTED_FRAME ();
7754 Lisp_Object file = Qnil; 7753 Lisp_Object file = Qnil;
7755 int count = SPECPDL_INDEX (); 7754 int count = SPECPDL_INDEX ();
7756 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 7755 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
7757 char filename[MAX_PATH + 1]; 7756 char filename[MAX_PATH + 1];
7758 char init_dir[MAX_PATH + 1]; 7757 char init_dir[MAX_PATH + 1];
7759 int default_filter_index = 1; /* 1: All Files, 2: Directories only */ 7758 int default_filter_index = 1; /* 1: All Files, 2: Directories only */
7760 7759
7761 GCPRO5 (prompt, dir, default_filename, mustmatch, file); 7760 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
7762 CHECK_STRING (prompt); 7761 CHECK_STRING (prompt);
7763 CHECK_STRING (dir); 7762 CHECK_STRING (dir);
7764 7763
@@ -7806,10 +7805,7 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */)
7806 file_details.lpstrInitialDir = init_dir; 7805 file_details.lpstrInitialDir = init_dir;
7807 file_details.lpstrTitle = SDATA (prompt); 7806 file_details.lpstrTitle = SDATA (prompt);
7808 7807
7809 /* If prompt starts with Dired, default to directories only. */ 7808 if (! NILP (only_dir_p))
7810 /* A bit hacky, but there doesn't seem to be a better way to
7811 DTRT for dired. */
7812 if (strncmp (file_details.lpstrTitle, "Dired", 5) == 0)
7813 default_filter_index = 2; 7809 default_filter_index = 2;
7814 7810
7815 file_details.nFilterIndex = default_filter_index; 7811 file_details.nFilterIndex = default_filter_index;
diff --git a/src/w32term.c b/src/w32term.c
index 8db94ceb759..aa9c0b96e92 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2763,9 +2763,13 @@ x_scroll_run (w, run)
2763 /* If the dirty region is not what we expected, redraw the entire frame. */ 2763 /* If the dirty region is not what we expected, redraw the entire frame. */
2764 if (!EqualRgn (combined, expect_dirty)) 2764 if (!EqualRgn (combined, expect_dirty))
2765 SET_FRAME_GARBAGED (f); 2765 SET_FRAME_GARBAGED (f);
2766
2767 DeleteObject (dirty);
2768 DeleteObject (combined);
2766 } 2769 }
2767 2770
2768 UNBLOCK_INPUT; 2771 UNBLOCK_INPUT;
2772 DeleteObject (expect_dirty);
2769} 2773}
2770 2774
2771 2775
diff --git a/src/window.c b/src/window.c
index 6b244ca5353..d9ac2eb62bd 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4627,17 +4627,25 @@ window_scroll_pixel_based (window, n, whole, noerror)
4627 w->force_start = Qt; 4627 w->force_start = Qt;
4628 } 4628 }
4629 4629
4630 /* The rest of this function uses current_y in a nonstandard way,
4631 not including the height of the header line if any. */
4630 it.current_y = it.vpos = 0; 4632 it.current_y = it.vpos = 0;
4631 4633
4632 /* Preserve the screen position if we must. */ 4634 /* Preserve the screen position if we should. */
4633 if (preserve_y >= 0) 4635 if (preserve_y >= 0)
4634 { 4636 {
4637 /* If we have a header line, take account of it. */
4638 if (WINDOW_WANTS_HEADER_LINE_P (w))
4639 preserve_y -= CURRENT_HEADER_LINE_HEIGHT (w);
4640
4635 move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y); 4641 move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y);
4636 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 4642 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
4637 } 4643 }
4638 else 4644 else
4639 { 4645 {
4640 /* Move PT out of scroll margins. */ 4646 /* Move PT out of scroll margins.
4647 This code wants current_y to be zero at the window start position
4648 even if there is a header line. */
4641 this_scroll_margin = max (0, scroll_margin); 4649 this_scroll_margin = max (0, scroll_margin);
4642 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->total_lines) / 4); 4650 this_scroll_margin = min (this_scroll_margin, XFASTINT (w->total_lines) / 4);
4643 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); 4651 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
@@ -4992,17 +5000,17 @@ specifies the window to scroll. This takes precedence over
4992 return Qnil; 5000 return Qnil;
4993} 5001}
4994 5002
4995DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 1, "P", 5003DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "P\np",
4996 doc: /* Scroll selected window display ARG columns left. 5004 doc: /* Scroll selected window display ARG columns left.
4997Default for ARG is window width minus 2. 5005Default for ARG is window width minus 2.
4998Value is the total amount of leftward horizontal scrolling in 5006Value is the total amount of leftward horizontal scrolling in
4999effect after the change. 5007effect after the change.
5000If `automatic-hscrolling' is non-nil, the argument ARG modifies 5008If SET_MINIMUM is non-nil, the new scroll amount becomes the
5001a lower bound for automatic scrolling, i.e. automatic scrolling 5009lower bound for automatic scrolling, i.e. automatic scrolling
5002will not scroll a window to a column less than the value returned 5010will not scroll a window to a column less than the value returned
5003by this function. */) 5011by this function. This happens in an interactive call. */)
5004 (arg) 5012 (arg, set_minimum)
5005 register Lisp_Object arg; 5013 register Lisp_Object arg, set_minimum;
5006{ 5014{
5007 Lisp_Object result; 5015 Lisp_Object result;
5008 int hscroll; 5016 int hscroll;
@@ -5016,23 +5024,23 @@ by this function. */)
5016 hscroll = XINT (w->hscroll) + XINT (arg); 5024 hscroll = XINT (w->hscroll) + XINT (arg);
5017 result = Fset_window_hscroll (selected_window, make_number (hscroll)); 5025 result = Fset_window_hscroll (selected_window, make_number (hscroll));
5018 5026
5019 if (interactive_p (0)) 5027 if (!NILP (set_minimum))
5020 w->min_hscroll = w->hscroll; 5028 w->min_hscroll = w->hscroll;
5021 5029
5022 return result; 5030 return result;
5023} 5031}
5024 5032
5025DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 1, "P", 5033DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 2, "P\np",
5026 doc: /* Scroll selected window display ARG columns right. 5034 doc: /* Scroll selected window display ARG columns right.
5027Default for ARG is window width minus 2. 5035Default for ARG is window width minus 2.
5028Value is the total amount of leftward horizontal scrolling in 5036Value is the total amount of leftward horizontal scrolling in
5029effect after the change. 5037effect after the change.
5030If `automatic-hscrolling' is non-nil, the argument ARG modifies 5038If SET_MINIMUM is non-nil, the new scroll amount becomes the
5031a lower bound for automatic scrolling, i.e. automatic scrolling 5039lower bound for automatic scrolling, i.e. automatic scrolling
5032will not scroll a window to a column less than the value returned 5040will not scroll a window to a column less than the value returned
5033by this function. */) 5041by this function. This happens in an interactive call. */)
5034 (arg) 5042 (arg, set_minimum)
5035 register Lisp_Object arg; 5043 register Lisp_Object arg, set_minimum;
5036{ 5044{
5037 Lisp_Object result; 5045 Lisp_Object result;
5038 int hscroll; 5046 int hscroll;
@@ -5046,7 +5054,7 @@ by this function. */)
5046 hscroll = XINT (w->hscroll) - XINT (arg); 5054 hscroll = XINT (w->hscroll) - XINT (arg);
5047 result = Fset_window_hscroll (selected_window, make_number (hscroll)); 5055 result = Fset_window_hscroll (selected_window, make_number (hscroll));
5048 5056
5049 if (interactive_p (0)) 5057 if (!NILP (set_minimum))
5050 w->min_hscroll = w->hscroll; 5058 w->min_hscroll = w->hscroll;
5051 5059
5052 return result; 5060 return result;
diff --git a/src/xdisp.c b/src/xdisp.c
index a5449c4db7c..4b0865aa4f0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4554,7 +4554,8 @@ back_to_previous_visible_line_start (it)
4554 { 4554 {
4555 Lisp_Object prop; 4555 Lisp_Object prop;
4556 4556
4557 prop = Fget_char_property (make_number (IT_CHARPOS (*it)), 4557 /* Check the newline before point for invisibility. */
4558 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4558 Qinvisible, it->window); 4559 Qinvisible, it->window);
4559 if (TEXT_PROP_MEANS_INVISIBLE (prop)) 4560 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4560 visible_p = 0; 4561 visible_p = 0;
@@ -8414,7 +8415,8 @@ update_tool_bar (f, save_match_data)
8414 { 8415 {
8415 struct buffer *prev = current_buffer; 8416 struct buffer *prev = current_buffer;
8416 int count = SPECPDL_INDEX (); 8417 int count = SPECPDL_INDEX ();
8417 Lisp_Object old_tool_bar; 8418 Lisp_Object new_tool_bar;
8419 int new_n_tool_bar;
8418 struct gcpro gcpro1; 8420 struct gcpro gcpro1;
8419 8421
8420 /* Set current_buffer to the buffer of the selected 8422 /* Set current_buffer to the buffer of the selected
@@ -8433,18 +8435,24 @@ update_tool_bar (f, save_match_data)
8433 specbind (Qoverriding_local_map, Qnil); 8435 specbind (Qoverriding_local_map, Qnil);
8434 } 8436 }
8435 8437
8436 old_tool_bar = f->tool_bar_items; 8438 GCPRO1 (new_tool_bar);
8437 GCPRO1 (old_tool_bar);
8438 8439
8439 /* Build desired tool-bar items from keymaps. */ 8440 /* Build desired tool-bar items from keymaps. */
8440 BLOCK_INPUT; 8441 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8441 f->tool_bar_items 8442 &new_n_tool_bar);
8442 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8443 UNBLOCK_INPUT;
8444 8443
8445 /* Redisplay the tool-bar if we changed it. */ 8444 /* Redisplay the tool-bar if we changed it. */
8446 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items))) 8445 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8447 w->update_mode_line = Qt; 8446 {
8447 /* Redisplay that happens asynchronously due to an expose event
8448 may access f->tool_bar_items. Make sure we update both
8449 variables within BLOCK_INPUT so no such event interrupts. */
8450 BLOCK_INPUT;
8451 f->tool_bar_items = new_tool_bar;
8452 f->n_tool_bar_items = new_n_tool_bar;
8453 w->update_mode_line = Qt;
8454 UNBLOCK_INPUT;
8455 }
8448 8456
8449 UNGCPRO; 8457 UNGCPRO;
8450 8458
diff --git a/src/xfns.c b/src/xfns.c
index b11779da185..cdce77f158f 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5130,27 +5130,26 @@ file_dialog_unmap_cb (widget, client_data, call_data)
5130} 5130}
5131 5131
5132 5132
5133DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, 5133DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5134 doc: /* Read file name, prompting with PROMPT in directory DIR. 5134 doc: /* Read file name, prompting with PROMPT in directory DIR.
5135Use a file selection dialog. 5135Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5136Select DEFAULT-FILENAME in the dialog's file selection box, if 5136selection box, if specified. If MUSTMATCH is non-nil, the returned file
5137specified. Don't let the user enter a file name in the file 5137or directory must exist. ONLY-DIR-P is ignored." */)
5138selection dialog's entry field, if MUSTMATCH is non-nil. */) 5138 (prompt, dir, default_filename, mustmatch, only_dir_p)
5139 (prompt, dir, default_filename, mustmatch) 5139 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5140 Lisp_Object prompt, dir, default_filename, mustmatch;
5141{ 5140{
5142 int result; 5141 int result;
5143 struct frame *f = SELECTED_FRAME (); 5142 struct frame *f = SELECTED_FRAME ();
5144 Lisp_Object file = Qnil; 5143 Lisp_Object file = Qnil;
5145 Widget dialog, text, list, help; 5144 Widget dialog, text, help;
5146 Arg al[10]; 5145 Arg al[10];
5147 int ac = 0; 5146 int ac = 0;
5148 extern XtAppContext Xt_app_con; 5147 extern XtAppContext Xt_app_con;
5149 XmString dir_xmstring, pattern_xmstring; 5148 XmString dir_xmstring, pattern_xmstring;
5150 int count = SPECPDL_INDEX (); 5149 int count = SPECPDL_INDEX ();
5151 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 5150 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5152 5151
5153 GCPRO5 (prompt, dir, default_filename, mustmatch, file); 5152 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5154 CHECK_STRING (prompt); 5153 CHECK_STRING (prompt);
5155 CHECK_STRING (dir); 5154 CHECK_STRING (dir);
5156 5155
@@ -5183,9 +5182,9 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
5183 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb, 5182 XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
5184 (XtPointer) &result); 5183 (XtPointer) &result);
5185 5184
5186 /* Disable the help button since we can't display help. */ 5185 /* Remove the help button since we can't display help. */
5187 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON); 5186 help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
5188 XtSetSensitive (help, False); 5187 XtUnmanageChild (help);
5189 5188
5190 /* Mark OK button as default. */ 5189 /* Mark OK button as default. */
5191 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON), 5190 XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
@@ -5207,30 +5206,30 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
5207 /* Manage the dialog, so that list boxes get filled. */ 5206 /* Manage the dialog, so that list boxes get filled. */
5208 XtManageChild (dialog); 5207 XtManageChild (dialog);
5209 5208
5210 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5211 must include the path for this to work. */
5212 list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5213 if (STRINGP (default_filename)) 5209 if (STRINGP (default_filename))
5214 { 5210 {
5215 XmString default_xmstring; 5211 XmString default_xmstring;
5216 int item_pos; 5212 Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
5213 Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
5217 5214
5218 default_xmstring 5215 XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
5219 = XmStringCreateLocalized (SDATA (default_filename)); 5216 XmTextFieldReplace (wtext, 0, last_pos,
5217 (SDATA (Ffile_name_nondirectory (default_filename))));
5220 5218
5221 if (!XmListItemExists (list, default_xmstring)) 5219 /* Select DEFAULT_FILENAME in the files list box. DEFAULT_FILENAME
5222 { 5220 must include the path for this to work. */
5223 /* Add a new item if DEFAULT_FILENAME is not in the list. */ 5221
5224 XmListAddItem (list, default_xmstring, 0); 5222 default_xmstring = XmStringCreateLocalized (SDATA (default_filename));
5225 item_pos = 0; 5223
5226 } 5224 if (XmListItemExists (list, default_xmstring))
5227 else 5225 {
5228 item_pos = XmListItemPos (list, default_xmstring); 5226 int item_pos = XmListItemPos (list, default_xmstring);
5229 XmStringFree (default_xmstring); 5227 /* Select the item and scroll it into view. */
5228 XmListSelectPos (list, item_pos, True);
5229 XmListSetPos (list, item_pos);
5230 }
5230 5231
5231 /* Select the item and scroll it into view. */ 5232 XmStringFree (default_xmstring);
5232 XmListSelectPos (list, item_pos, True);
5233 XmListSetPos (list, item_pos);
5234 } 5233 }
5235 5234
5236 /* Process events until the user presses Cancel or OK. */ 5235 /* Process events until the user presses Cancel or OK. */
@@ -5274,23 +5273,23 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */)
5274 5273
5275#ifdef USE_GTK 5274#ifdef USE_GTK
5276 5275
5277DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, 5276DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
5278 "Read file name, prompting with PROMPT in directory DIR.\n\ 5277 doc: /* Read file name, prompting with PROMPT in directory DIR.
5279Use a file selection dialog.\n\ 5278Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
5280Select DEFAULT-FILENAME in the dialog's file selection box, if\n\ 5279selection box, if specified. If MUSTMATCH is non-nil, the returned file
5281specified. Don't let the user enter a file name in the file\n\ 5280or directory must exist. If ONLY-DIR-P is non-nil, the user can only select
5282selection dialog's entry field, if MUSTMATCH is non-nil.") 5281directories. */)
5283 (prompt, dir, default_filename, mustmatch) 5282 (prompt, dir, default_filename, mustmatch, only_dir_p)
5284 Lisp_Object prompt, dir, default_filename, mustmatch; 5283 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
5285{ 5284{
5286 FRAME_PTR f = SELECTED_FRAME (); 5285 FRAME_PTR f = SELECTED_FRAME ();
5287 char *fn; 5286 char *fn;
5288 Lisp_Object file = Qnil; 5287 Lisp_Object file = Qnil;
5289 int count = specpdl_ptr - specpdl; 5288 int count = specpdl_ptr - specpdl;
5290 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 5289 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5291 char *cdef_file; 5290 char *cdef_file;
5292 5291
5293 GCPRO5 (prompt, dir, default_filename, mustmatch, file); 5292 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5294 CHECK_STRING (prompt); 5293 CHECK_STRING (prompt);
5295 CHECK_STRING (dir); 5294 CHECK_STRING (dir);
5296 5295
@@ -5304,7 +5303,9 @@ selection dialog's entry field, if MUSTMATCH is non-nil.")
5304 else 5303 else
5305 cdef_file = SDATA (dir); 5304 cdef_file = SDATA (dir);
5306 5305
5307 fn = xg_get_file_name (f, SDATA (prompt), cdef_file, ! NILP (mustmatch)); 5306 fn = xg_get_file_name (f, SDATA (prompt), cdef_file,
5307 ! NILP (mustmatch),
5308 ! NILP (only_dir_p));
5308 5309
5309 if (fn) 5310 if (fn)
5310 { 5311 {
@@ -5580,6 +5581,14 @@ Chinese, Japanese, and Korean. */);
5580 Fprovide (intern ("x-toolkit"), Qnil); 5581 Fprovide (intern ("x-toolkit"), Qnil);
5581 Fprovide (intern ("gtk"), Qnil); 5582 Fprovide (intern ("gtk"), Qnil);
5582 5583
5584#ifdef HAVE_GTK_FILE_BOTH
5585 DEFVAR_BOOL ("use-old-gtk-file-dialog", &use_old_gtk_file_dialog,
5586 doc: /* *Non-nil means that the old GTK file selection dialog is used.
5587If nil the new GTK file chooser is used instead. To turn off
5588all file dialogs set the variable `use-file-dialog'. */);
5589 use_old_gtk_file_dialog = 0;
5590#endif
5591
5583 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string, 5592 DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string,
5584 doc: /* Version info for GTK+. */); 5593 doc: /* Version info for GTK+. */);
5585 { 5594 {
diff --git a/src/xmenu.c b/src/xmenu.c
index 5c3d5804355..145e4f70b9c 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -110,11 +110,12 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
110extern Lisp_Object Qmenu_bar_update_hook; 110extern Lisp_Object Qmenu_bar_update_hook;
111 111
112#ifdef USE_X_TOOLKIT 112#ifdef USE_X_TOOLKIT
113extern void set_frame_menubar (); 113extern void set_frame_menubar P_ ((FRAME_PTR, int, int));
114extern XtAppContext Xt_app_con; 114extern XtAppContext Xt_app_con;
115 115
116static Lisp_Object xdialog_show (); 116static Lisp_Object xdialog_show P_ ((FRAME_PTR, int, Lisp_Object, char **));
117static void popup_get_selection (); 117static void popup_get_selection P_ ((XEvent *, struct x_display_info *,
118 LWLIB_ID, int));
118 119
119/* Define HAVE_BOXES if menus can handle radio and toggle buttons. */ 120/* Define HAVE_BOXES if menus can handle radio and toggle buttons. */
120 121
@@ -124,8 +125,8 @@ static void popup_get_selection ();
124#ifdef USE_GTK 125#ifdef USE_GTK
125#include "gtkutil.h" 126#include "gtkutil.h"
126#define HAVE_BOXES 1 127#define HAVE_BOXES 1
127extern void set_frame_menubar (); 128extern void set_frame_menubar P_ ((FRAME_PTR, int, int));
128static Lisp_Object xdialog_show (); 129static Lisp_Object xdialog_show P_ ((FRAME_PTR, int, Lisp_Object, char **));
129#endif 130#endif
130 131
131/* This is how to deal with multibyte text if HAVE_MULTILINGUAL_MENU 132/* This is how to deal with multibyte text if HAVE_MULTILINGUAL_MENU
@@ -156,7 +157,6 @@ static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
156static void list_of_panes P_ ((Lisp_Object)); 157static void list_of_panes P_ ((Lisp_Object));
157static void list_of_items P_ ((Lisp_Object)); 158static void list_of_items P_ ((Lisp_Object));
158 159
159extern EMACS_TIME timer_check P_ ((int));
160 160
161/* This holds a Lisp vector that holds the results of decoding 161/* This holds a Lisp vector that holds the results of decoding
162 the keymaps or alist-of-alists that specify a menu. 162 the keymaps or alist-of-alists that specify a menu.
@@ -1120,29 +1120,28 @@ on the left of the dialog box and all following items on the right.
1120 popped down (deactivated). This is used for x-popup-menu 1120 popped down (deactivated). This is used for x-popup-menu
1121 and x-popup-dialog; it is not used for the menu bar. 1121 and x-popup-dialog; it is not used for the menu bar.
1122 1122
1123 If DO_TIMERS is nonzero, run timers.
1124 If DOWN_ON_KEYPRESS is nonzero, pop down if a key is pressed. 1123 If DOWN_ON_KEYPRESS is nonzero, pop down if a key is pressed.
1125 1124
1125 This function used to have a DO_TIMERS argument which was
1126 1 in the dialog case, and caused it to run Lisp-level timers.
1127 That was unsafe so we removed it, but does anyone remember
1128 why menus and dialogs were treated differently?
1129
1126 NOTE: All calls to popup_get_selection should be protected 1130 NOTE: All calls to popup_get_selection should be protected
1127 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ 1131 with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */
1128 1132
1129#ifdef USE_X_TOOLKIT 1133#ifdef USE_X_TOOLKIT
1130static void 1134static void
1131popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress) 1135popup_get_selection (initial_event, dpyinfo, id, down_on_keypress)
1132 XEvent *initial_event; 1136 XEvent *initial_event;
1133 struct x_display_info *dpyinfo; 1137 struct x_display_info *dpyinfo;
1134 LWLIB_ID id; 1138 LWLIB_ID id;
1135 int do_timers;
1136 int down_on_keypress; 1139 int down_on_keypress;
1137{ 1140{
1138 XEvent event; 1141 XEvent event;
1139 1142
1140 while (popup_activated_flag) 1143 while (popup_activated_flag)
1141 { 1144 {
1142 /* If we have no events to run, consider timers. */
1143 if (do_timers && !XtAppPending (Xt_app_con))
1144 timer_check (1);
1145
1146 if (initial_event) 1145 if (initial_event)
1147 { 1146 {
1148 event = *initial_event; 1147 event = *initial_event;
@@ -2489,7 +2488,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2489 popup_activated_flag = 1; 2488 popup_activated_flag = 1;
2490 2489
2491 /* Process events that apply to the menu. */ 2490 /* Process events that apply to the menu. */
2492 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0, 0); 2491 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 0);
2493 2492
2494 /* fp turned off the following statement and wrote a comment 2493 /* fp turned off the following statement and wrote a comment
2495 that it is unnecessary--that the menu has already disappeared. 2494 that it is unnecessary--that the menu has already disappeared.
@@ -2883,8 +2882,7 @@ create_and_show_dialog (f, first_wv)
2883 Fcons (make_number (dialog_id >> (fact)), 2882 Fcons (make_number (dialog_id >> (fact)),
2884 make_number (dialog_id & ~(-1 << (fact))))); 2883 make_number (dialog_id & ~(-1 << (fact)))));
2885 2884
2886 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), 2885 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1);
2887 dialog_id, 1, 1);
2888 2886
2889 unbind_to (count, Qnil); 2887 unbind_to (count, Qnil);
2890 } 2888 }
diff --git a/src/xselect.c b/src/xselect.c
index 65cb584410e..06f4bfbd2a1 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */
32#include "buffer.h" 32#include "buffer.h"
33#include "process.h" 33#include "process.h"
34#include "termhooks.h" 34#include "termhooks.h"
35#include "keyboard.h"
35 36
36#include <X11/Xproto.h> 37#include <X11/Xproto.h>
37 38
@@ -85,10 +86,13 @@ static void initialize_cut_buffers P_ ((Display *, Window));
85 fprintf (stderr, "%d: " fmt "\n", getpid (), a0) 86 fprintf (stderr, "%d: " fmt "\n", getpid (), a0)
86#define TRACE2(fmt, a0, a1) \ 87#define TRACE2(fmt, a0, a1) \
87 fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1) 88 fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1)
89#define TRACE3(fmt, a0, a1, a2) \
90 fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1, a2)
88#else 91#else
89#define TRACE0(fmt) (void) 0 92#define TRACE0(fmt) (void) 0
90#define TRACE1(fmt, a0) (void) 0 93#define TRACE1(fmt, a0) (void) 0
91#define TRACE2(fmt, a0, a1) (void) 0 94#define TRACE2(fmt, a0, a1) (void) 0
95#define TRACE3(fmt, a0, a1) (void) 0
92#endif 96#endif
93 97
94 98
@@ -168,6 +172,86 @@ static void lisp_data_to_selection_data ();
168static Lisp_Object selection_data_to_lisp_data (); 172static Lisp_Object selection_data_to_lisp_data ();
169static Lisp_Object x_get_window_property_as_lisp_data (); 173static Lisp_Object x_get_window_property_as_lisp_data ();
170 174
175
176
177/* Define a queue to save up SelectionRequest events for later handling. */
178
179struct selection_event_queue
180 {
181 struct input_event event;
182 struct selection_event_queue *next;
183 };
184
185static struct selection_event_queue *selection_queue;
186
187/* Nonzero means queue up certain events--don't process them yet. */
188
189static int x_queue_selection_requests;
190
191/* Queue up an X event *EVENT, to be processed later. */
192
193static void
194x_queue_event (event)
195 struct input_event *event;
196{
197 struct selection_event_queue *queue_tmp;
198
199 /* Don't queue repeated requests */
200 for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
201 {
202 if (!bcmp (&queue_tmp->event, event, sizeof (*event)))
203 {
204 TRACE1 ("IGNORE DUP SELECTION EVENT %08x", (unsigned long)queue_tmp);
205 return;
206 }
207 }
208
209 queue_tmp
210 = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
211
212 if (queue_tmp != NULL)
213 {
214 TRACE1 ("QUEUE SELECTION EVENT %08x", (unsigned long)queue_tmp);
215 queue_tmp->event = *event;
216 queue_tmp->next = selection_queue;
217 selection_queue = queue_tmp;
218 }
219}
220
221/* Start queuing SelectionRequest events. */
222
223static void
224x_start_queuing_selection_requests ()
225{
226 if (x_queue_selection_requests)
227 abort ();
228
229 x_queue_selection_requests++;
230 TRACE1 ("x_start_queuing_selection_requests %d", x_queue_selection_requests);
231}
232
233/* Stop queuing SelectionRequest events. */
234
235static void
236x_stop_queuing_selection_requests ()
237{
238 TRACE1 ("x_stop_queuing_selection_requests %d", x_queue_selection_requests);
239 --x_queue_selection_requests;
240
241 /* Take all the queued events and put them back
242 so that they get processed afresh. */
243
244 while (selection_queue != NULL)
245 {
246 struct selection_event_queue *queue_tmp = selection_queue;
247 TRACE1 ("RESTORE SELECTION EVENT %08x", (unsigned long)queue_tmp);
248 kbd_buffer_unget_event (&queue_tmp->event);
249 selection_queue = queue_tmp->next;
250 xfree ((char *)queue_tmp);
251 }
252}
253
254
171/* This converts a Lisp symbol to a server Atom, avoiding a server 255/* This converts a Lisp symbol to a server Atom, avoiding a server
172 roundtrip whenever possible. */ 256 roundtrip whenever possible. */
173 257
@@ -564,13 +648,10 @@ static struct prop_location *property_change_reply_object;
564static struct prop_location *property_change_wait_list; 648static struct prop_location *property_change_wait_list;
565 649
566static Lisp_Object 650static Lisp_Object
567queue_selection_requests_unwind (frame) 651queue_selection_requests_unwind (tem)
568 Lisp_Object frame; 652 Lisp_Object tem;
569{ 653{
570 FRAME_PTR f = XFRAME (frame); 654 x_stop_queuing_selection_requests ();
571
572 if (! NILP (frame))
573 x_stop_queuing_selection_requests (FRAME_X_DISPLAY (f));
574 return Qnil; 655 return Qnil;
575} 656}
576 657
@@ -631,6 +712,17 @@ x_reply_selection_request (event, format, data, size, type)
631 BLOCK_INPUT; 712 BLOCK_INPUT;
632 count = x_catch_errors (display); 713 count = x_catch_errors (display);
633 714
715#ifdef TRACE_SELECTION
716 {
717 static int cnt;
718 char *sel = XGetAtomName (display, reply.selection);
719 char *tgt = XGetAtomName (display, reply.target);
720 TRACE3 ("%s, target %s (%d)", sel, tgt, ++cnt);
721 if (sel) XFree (sel);
722 if (tgt) XFree (tgt);
723 }
724#endif /* TRACE_SELECTION */
725
634 /* Store the data on the requested property. 726 /* Store the data on the requested property.
635 If the selection is large, only store the first N bytes of it. 727 If the selection is large, only store the first N bytes of it.
636 */ 728 */
@@ -658,10 +750,10 @@ x_reply_selection_request (event, format, data, size, type)
658 bother trying to queue them. */ 750 bother trying to queue them. */
659 if (!NILP (frame)) 751 if (!NILP (frame))
660 { 752 {
661 x_start_queuing_selection_requests (display); 753 x_start_queuing_selection_requests ();
662 754
663 record_unwind_protect (queue_selection_requests_unwind, 755 record_unwind_protect (queue_selection_requests_unwind,
664 frame); 756 Qnil);
665 } 757 }
666 758
667 if (x_window_to_frame (dpyinfo, window)) /* #### debug */ 759 if (x_window_to_frame (dpyinfo, window)) /* #### debug */
@@ -695,6 +787,8 @@ x_reply_selection_request (event, format, data, size, type)
695 XGetAtomName (display, reply.property)); 787 XGetAtomName (display, reply.property));
696 wait_for_property_change (wait_object); 788 wait_for_property_change (wait_object);
697 } 789 }
790 else
791 unexpect_property_change (wait_object);
698 792
699 TRACE0 ("Got ACK"); 793 TRACE0 ("Got ACK");
700 while (bytes_remaining) 794 while (bytes_remaining)
@@ -768,7 +862,7 @@ x_reply_selection_request (event, format, data, size, type)
768/* Handle a SelectionRequest event EVENT. 862/* Handle a SelectionRequest event EVENT.
769 This is called from keyboard.c when such an event is found in the queue. */ 863 This is called from keyboard.c when such an event is found in the queue. */
770 864
771void 865static void
772x_handle_selection_request (event) 866x_handle_selection_request (event)
773 struct input_event *event; 867 struct input_event *event;
774{ 868{
@@ -783,6 +877,8 @@ x_handle_selection_request (event)
783 struct x_display_info *dpyinfo 877 struct x_display_info *dpyinfo
784 = x_display_info_for_display (SELECTION_EVENT_DISPLAY (event)); 878 = x_display_info_for_display (SELECTION_EVENT_DISPLAY (event));
785 879
880 TRACE0 ("x_handle_selection_request");
881
786 local_selection_data = Qnil; 882 local_selection_data = Qnil;
787 target_symbol = Qnil; 883 target_symbol = Qnil;
788 converted_selection = Qnil; 884 converted_selection = Qnil;
@@ -877,7 +973,7 @@ x_handle_selection_request (event)
877 client cleared out our previously asserted selection. 973 client cleared out our previously asserted selection.
878 This is called from keyboard.c when such an event is found in the queue. */ 974 This is called from keyboard.c when such an event is found in the queue. */
879 975
880void 976static void
881x_handle_selection_clear (event) 977x_handle_selection_clear (event)
882 struct input_event *event; 978 struct input_event *event;
883{ 979{
@@ -890,6 +986,8 @@ x_handle_selection_clear (event)
890 struct x_display_info *dpyinfo = x_display_info_for_display (display); 986 struct x_display_info *dpyinfo = x_display_info_for_display (display);
891 struct x_display_info *t_dpyinfo; 987 struct x_display_info *t_dpyinfo;
892 988
989 TRACE0 ("x_handle_selection_clear");
990
893 /* If the new selection owner is also Emacs, 991 /* If the new selection owner is also Emacs,
894 don't clear the new selection. */ 992 don't clear the new selection. */
895 BLOCK_INPUT; 993 BLOCK_INPUT;
@@ -958,6 +1056,24 @@ x_handle_selection_clear (event)
958 } 1056 }
959} 1057}
960 1058
1059void
1060x_handle_selection_event (event)
1061 struct input_event *event;
1062{
1063 TRACE0 ("x_handle_selection_event");
1064
1065 if (event->kind == SELECTION_REQUEST_EVENT)
1066 {
1067 if (x_queue_selection_requests)
1068 x_queue_event (event);
1069 else
1070 x_handle_selection_request (event);
1071 }
1072 else
1073 x_handle_selection_clear (event);
1074}
1075
1076
961/* Clear all selections that were made from frame F. 1077/* Clear all selections that were made from frame F.
962 We do this when about to delete a frame. */ 1078 We do this when about to delete a frame. */
963 1079
@@ -1088,12 +1204,14 @@ unexpect_property_change (location)
1088/* Remove the property change expectation element for IDENTIFIER. */ 1204/* Remove the property change expectation element for IDENTIFIER. */
1089 1205
1090static Lisp_Object 1206static Lisp_Object
1091wait_for_property_change_unwind (identifierval) 1207wait_for_property_change_unwind (loc)
1092 Lisp_Object identifierval; 1208 Lisp_Object loc;
1093{ 1209{
1094 unexpect_property_change ((struct prop_location *) 1210 struct prop_location *location = XSAVE_VALUE (loc)->pointer;
1095 (XFASTINT (XCAR (identifierval)) << 16 1211
1096 | XFASTINT (XCDR (identifierval)))); 1212 unexpect_property_change (location);
1213 if (location == property_change_reply_object)
1214 property_change_reply_object = 0;
1097 return Qnil; 1215 return Qnil;
1098} 1216}
1099 1217
@@ -1106,18 +1224,17 @@ wait_for_property_change (location)
1106{ 1224{
1107 int secs, usecs; 1225 int secs, usecs;
1108 int count = SPECPDL_INDEX (); 1226 int count = SPECPDL_INDEX ();
1109 Lisp_Object tem;
1110 1227
1111 tem = Fcons (Qnil, Qnil); 1228 if (property_change_reply_object)
1112 XSETCARFASTINT (tem, (EMACS_UINT)location >> 16); 1229 abort ();
1113 XSETCDRFASTINT (tem, (EMACS_UINT)location & 0xffff);
1114 1230
1115 /* Make sure to do unexpect_property_change if we quit or err. */ 1231 /* Make sure to do unexpect_property_change if we quit or err. */
1116 record_unwind_protect (wait_for_property_change_unwind, tem); 1232 record_unwind_protect (wait_for_property_change_unwind,
1233 make_save_value (location, 0));
1117 1234
1118 XSETCAR (property_change_reply, Qnil); 1235 XSETCAR (property_change_reply, Qnil);
1119
1120 property_change_reply_object = location; 1236 property_change_reply_object = location;
1237
1121 /* If the event we are waiting for arrives beyond here, it will set 1238 /* If the event we are waiting for arrives beyond here, it will set
1122 property_change_reply, because property_change_reply_object says so. */ 1239 property_change_reply, because property_change_reply_object says so. */
1123 if (! location->arrived) 1240 if (! location->arrived)
@@ -1148,7 +1265,8 @@ x_handle_property_notify (event)
1148 1265
1149 while (rest) 1266 while (rest)
1150 { 1267 {
1151 if (rest->property == event->atom 1268 if (!rest->arrived
1269 && rest->property == event->atom
1152 && rest->window == event->window 1270 && rest->window == event->window
1153 && rest->display == event->display 1271 && rest->display == event->display
1154 && rest->desired_state == event->state) 1272 && rest->desired_state == event->state)
@@ -1164,11 +1282,6 @@ x_handle_property_notify (event)
1164 if (rest == property_change_reply_object) 1282 if (rest == property_change_reply_object)
1165 XSETCAR (property_change_reply, Qt); 1283 XSETCAR (property_change_reply, Qt);
1166 1284
1167 if (prev)
1168 prev->next = rest->next;
1169 else
1170 property_change_wait_list = rest->next;
1171 xfree (rest);
1172 return; 1285 return;
1173 } 1286 }
1174 1287
@@ -1303,10 +1416,10 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
1303 bother trying to queue them. */ 1416 bother trying to queue them. */
1304 if (!NILP (frame)) 1417 if (!NILP (frame))
1305 { 1418 {
1306 x_start_queuing_selection_requests (display); 1419 x_start_queuing_selection_requests ();
1307 1420
1308 record_unwind_protect (queue_selection_requests_unwind, 1421 record_unwind_protect (queue_selection_requests_unwind,
1309 frame); 1422 Qnil);
1310 } 1423 }
1311 UNBLOCK_INPUT; 1424 UNBLOCK_INPUT;
1312 1425
@@ -1462,10 +1575,10 @@ receive_incremental_selection (display, window, property, target_type,
1462 BLOCK_INPUT; 1575 BLOCK_INPUT;
1463 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask); 1576 XSelectInput (display, window, STANDARD_EVENT_SET | PropertyChangeMask);
1464 TRACE1 (" Delete property %s", 1577 TRACE1 (" Delete property %s",
1465 XSYMBOL (x_atom_to_symbol (display, property))->name->data); 1578 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
1466 XDeleteProperty (display, window, property); 1579 XDeleteProperty (display, window, property);
1467 TRACE1 (" Expect new value of property %s", 1580 TRACE1 (" Expect new value of property %s",
1468 XSYMBOL (x_atom_to_symbol (display, property))->name->data); 1581 SDATA (SYMBOL_NAME (x_atom_to_symbol (display, property))));
1469 wait_object = expect_property_change (display, window, property, 1582 wait_object = expect_property_change (display, window, property,
1470 PropertyNewValue); 1583 PropertyNewValue);
1471 XFlush (display); 1584 XFlush (display);
@@ -1495,7 +1608,6 @@ receive_incremental_selection (display, window, property, target_type,
1495 1608
1496 if (! waiting_for_other_props_on_window (display, window)) 1609 if (! waiting_for_other_props_on_window (display, window))
1497 XSelectInput (display, window, STANDARD_EVENT_SET); 1610 XSelectInput (display, window, STANDARD_EVENT_SET);
1498 unexpect_property_change (wait_object);
1499 /* Use xfree, not XFree, because x_get_window_property 1611 /* Use xfree, not XFree, because x_get_window_property
1500 calls xmalloc itself. */ 1612 calls xmalloc itself. */
1501 if (tmp_data) xfree (tmp_data); 1613 if (tmp_data) xfree (tmp_data);
diff --git a/src/xterm.c b/src/xterm.c
index 492e8d00b52..a1fd1d5dcc2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3922,9 +3922,9 @@ x_window_to_scroll_bar (display, window_id)
3922{ 3922{
3923 Lisp_Object tail; 3923 Lisp_Object tail;
3924 3924
3925#ifdef USE_GTK 3925#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3926 window_id = (Window) xg_get_scroll_id_for_window (display, window_id); 3926 window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
3927#endif /* USE_GTK */ 3927#endif /* USE_GTK && USE_TOOLKIT_SCROLL_BARS */
3928 3928
3929 for (tail = Vframe_list; 3929 for (tail = Vframe_list;
3930 XGCTYPE (tail) == Lisp_Cons; 3930 XGCTYPE (tail) == Lisp_Cons;
@@ -5579,73 +5579,6 @@ x_scroll_bar_clear (f)
5579} 5579}
5580 5580
5581 5581
5582/* Define a queue to save up SelectionRequest events for later handling. */
5583
5584struct selection_event_queue
5585 {
5586 XEvent event;
5587 struct selection_event_queue *next;
5588 };
5589
5590static struct selection_event_queue *queue;
5591
5592/* Nonzero means queue up certain events--don't process them yet. */
5593
5594static int x_queue_selection_requests;
5595
5596/* Queue up an X event *EVENT, to be processed later. */
5597
5598static void
5599x_queue_event (f, event)
5600 FRAME_PTR f;
5601 XEvent *event;
5602{
5603 struct selection_event_queue *queue_tmp
5604 = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
5605
5606 if (queue_tmp != NULL)
5607 {
5608 queue_tmp->event = *event;
5609 queue_tmp->next = queue;
5610 queue = queue_tmp;
5611 }
5612}
5613
5614/* Take all the queued events and put them back
5615 so that they get processed afresh. */
5616
5617static void
5618x_unqueue_events (display)
5619 Display *display;
5620{
5621 while (queue != NULL)
5622 {
5623 struct selection_event_queue *queue_tmp = queue;
5624 XPutBackEvent (display, &queue_tmp->event);
5625 queue = queue_tmp->next;
5626 xfree ((char *)queue_tmp);
5627 }
5628}
5629
5630/* Start queuing SelectionRequest events. */
5631
5632void
5633x_start_queuing_selection_requests (display)
5634 Display *display;
5635{
5636 x_queue_selection_requests++;
5637}
5638
5639/* Stop queuing SelectionRequest events. */
5640
5641void
5642x_stop_queuing_selection_requests (display)
5643 Display *display;
5644{
5645 x_queue_selection_requests--;
5646 x_unqueue_events (display);
5647}
5648
5649/* The main X event-reading loop - XTread_socket. */ 5582/* The main X event-reading loop - XTread_socket. */
5650 5583
5651#if 0 5584#if 0
@@ -6023,11 +5956,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6023 if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner)) 5956 if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
6024 goto OTHER; 5957 goto OTHER;
6025#endif /* USE_X_TOOLKIT */ 5958#endif /* USE_X_TOOLKIT */
6026 if (x_queue_selection_requests) 5959 {
6027 x_queue_event (x_window_to_frame (dpyinfo, event.xselectionrequest.owner),
6028 &event);
6029 else
6030 {
6031 XSelectionRequestEvent *eventp 5960 XSelectionRequestEvent *eventp
6032 = (XSelectionRequestEvent *) &event; 5961 = (XSelectionRequestEvent *) &event;
6033 5962
@@ -6039,7 +5968,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
6039 SELECTION_EVENT_PROPERTY (&inev) = eventp->property; 5968 SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
6040 SELECTION_EVENT_TIME (&inev) = eventp->time; 5969 SELECTION_EVENT_TIME (&inev) = eventp->time;
6041 inev.frame_or_window = Qnil; 5970 inev.frame_or_window = Qnil;
6042 } 5971 }
6043 break; 5972 break;
6044 5973
6045 case PropertyNotify: 5974 case PropertyNotify:
@@ -7623,7 +7552,11 @@ x_catch_errors_unwind (old_val)
7623 /* The display may have been closed before this function is called. 7552 /* The display may have been closed before this function is called.
7624 Check if it is still open before calling XSync. */ 7553 Check if it is still open before calling XSync. */
7625 if (x_display_info_for_display (dpy) != 0) 7554 if (x_display_info_for_display (dpy) != 0)
7626 XSync (dpy, False); 7555 {
7556 BLOCK_INPUT;
7557 XSync (dpy, False);
7558 UNBLOCK_INPUT;
7559 }
7627 7560
7628 x_error_message_string = XCDR (old_val); 7561 x_error_message_string = XCDR (old_val);
7629 return Qnil; 7562 return Qnil;
diff --git a/src/xterm.h b/src/xterm.h
index eebe4f10878..23f0e43d149 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -52,7 +52,7 @@ typedef GtkWidget *xt_or_gtk_widget;
52#undef XSync 52#undef XSync
53#define XSync(d, b) do { gdk_window_process_all_updates (); \ 53#define XSync(d, b) do { gdk_window_process_all_updates (); \
54 XSync (d, b); } while (0) 54 XSync (d, b); } while (0)
55 55
56 56
57#endif /* USE_GTK */ 57#endif /* USE_GTK */
58 58
@@ -976,8 +976,6 @@ int x_alloc_nearest_color P_ ((struct frame *, Colormap, XColor *));
976 976
977extern void cancel_mouse_face P_ ((struct frame *)); 977extern void cancel_mouse_face P_ ((struct frame *));
978extern void x_scroll_bar_clear P_ ((struct frame *)); 978extern void x_scroll_bar_clear P_ ((struct frame *));
979extern void x_start_queuing_selection_requests P_ ((Display *));
980extern void x_stop_queuing_selection_requests P_ ((Display *));
981extern int x_text_icon P_ ((struct frame *, char *)); 979extern int x_text_icon P_ ((struct frame *, char *));
982extern int x_bitmap_icon P_ ((struct frame *, Lisp_Object)); 980extern int x_bitmap_icon P_ ((struct frame *, Lisp_Object));
983extern int x_catch_errors P_ ((Display *)); 981extern int x_catch_errors P_ ((Display *));
@@ -1013,8 +1011,7 @@ extern int x_dispatch_event P_ ((XEvent *, Display *));
1013 1011
1014extern void x_handle_property_notify P_ ((XPropertyEvent *)); 1012extern void x_handle_property_notify P_ ((XPropertyEvent *));
1015extern void x_handle_selection_notify P_ ((XSelectionEvent *)); 1013extern void x_handle_selection_notify P_ ((XSelectionEvent *));
1016extern void x_handle_selection_request P_ ((struct input_event *)); 1014extern void x_handle_selection_event P_ ((struct input_event *));
1017extern void x_handle_selection_clear P_ ((struct input_event *));
1018extern void x_clear_frame_selections P_ ((struct frame *)); 1015extern void x_clear_frame_selections P_ ((struct frame *));
1019 1016
1020extern int x_handle_dnd_message P_ ((struct frame *, 1017extern int x_handle_dnd_message P_ ((struct frame *,