aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit49
-rw-r--r--src/ChangeLog557
-rw-r--r--src/alloc.c193
-rw-r--r--src/buffer.c44
-rw-r--r--src/buffer.h31
-rw-r--r--src/callproc.c10
-rw-r--r--src/category.c4
-rw-r--r--src/composite.c4
-rw-r--r--src/conf_post.h15
-rw-r--r--src/data.c70
-rw-r--r--src/dispnew.c126
-rw-r--r--src/doc.c35
-rw-r--r--src/emacs.c29
-rw-r--r--src/eval.c21
-rw-r--r--src/fileio.c10
-rw-r--r--src/fns.c178
-rw-r--r--src/font.c51
-rw-r--r--src/fontset.c9
-rw-r--r--src/frame.c345
-rw-r--r--src/frame.h16
-rw-r--r--src/fringe.c6
-rw-r--r--src/image.c4
-rw-r--r--src/indent.c15
-rw-r--r--src/keyboard.c31
-rw-r--r--src/lisp.h212
-rw-r--r--src/lisp.mk6
-rw-r--r--src/lread.c2
-rw-r--r--src/makefile.w32-in5
-rw-r--r--src/msdos.c19
-rw-r--r--src/nsfns.m1
-rw-r--r--src/nsfont.m15
-rw-r--r--src/nsterm.m26
-rw-r--r--src/print.c8
-rw-r--r--src/process.c215
-rw-r--r--src/process.h3
-rw-r--r--src/profiler.c91
-rw-r--r--src/ralloc.c34
-rw-r--r--src/regex.c2
-rw-r--r--src/sysdep.c4
-rw-r--r--src/systty.h21
-rw-r--r--src/term.c36
-rw-r--r--src/termhooks.h30
-rw-r--r--src/terminal.c9
-rw-r--r--src/w32fns.c135
-rw-r--r--src/w32proc.c14
-rw-r--r--src/w32term.c13
-rw-r--r--src/w32term.h11
-rw-r--r--src/widget.c28
-rw-r--r--src/window.c239
-rw-r--r--src/window.h9
-rw-r--r--src/xdisp.c127
-rw-r--r--src/xfaces.c130
-rw-r--r--src/xfns.c60
-rw-r--r--src/xmenu.c5
-rw-r--r--src/xselect.c21
-rw-r--r--src/xterm.c57
-rw-r--r--src/xterm.h6
57 files changed, 1894 insertions, 1553 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index 952d7392a4c..fa580cc99bf 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -650,19 +650,52 @@ If the first type printed is Lisp_Vector or Lisp_Misc,
650a second line gives the more precise type. 650a second line gives the more precise type.
651end 651end
652 652
653define pvectype
654 set $size = ((struct Lisp_Vector *) $arg0)->header.size
655 if ($size & PSEUDOVECTOR_FLAG)
656 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
657 else
658 output PVEC_NORMAL_VECTOR
659 end
660 echo \n
661end
662document pvectype
663Print the subtype of vectorlike object.
664Takes one argument, a pointer to an object.
665end
666
653define xvectype 667define xvectype
654 xgetptr $ 668 xgetptr $
655 set $size = ((struct Lisp_Vector *) $ptr)->header.size 669 pvectype $ptr
670end
671document xvectype
672Print the subtype of vectorlike object.
673This command assumes that $ is a Lisp_Object.
674end
675
676define pvecsize
677 set $size = ((struct Lisp_Vector *) $arg0)->header.size
656 if ($size & PSEUDOVECTOR_FLAG) 678 if ($size & PSEUDOVECTOR_FLAG)
657 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_SIZE_BITS) 679 output ($size & PSEUDOVECTOR_SIZE_MASK)
680 echo \n
681 output (($size & PSEUDOVECTOR_REST_MASK) >> PSEUDOVECTOR_SIZE_BITS)
658 else 682 else
659 output $size & ~ARRAY_MARK_FLAG 683 output ($size & ~ARRAY_MARK_FLAG)
660 end 684 end
661 echo \n 685 echo \n
662end 686end
663document xvectype 687document pvecsize
664Print the size or vector subtype of $. 688Print the size of vectorlike object.
665This command assumes that $ is a vector or pseudovector. 689Takes one argument, a pointer to an object.
690end
691
692define xvecsize
693 xgetptr $
694 pvecsize $ptr
695end
696document xvecsize
697Print the size of $
698This command assumes that $ is a Lisp_Object.
666end 699end
667 700
668define xmisctype 701define xmisctype
@@ -996,7 +1029,7 @@ define xpr
996 if $type == Lisp_Vectorlike 1029 if $type == Lisp_Vectorlike
997 set $size = ((struct Lisp_Vector *) $ptr)->header.size 1030 set $size = ((struct Lisp_Vector *) $ptr)->header.size
998 if ($size & PSEUDOVECTOR_FLAG) 1031 if ($size & PSEUDOVECTOR_FLAG)
999 set $vec = (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_SIZE_BITS) 1032 set $vec = (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
1000 if $vec == PVEC_NORMAL_VECTOR 1033 if $vec == PVEC_NORMAL_VECTOR
1001 xvector 1034 xvector
1002 end 1035 end
@@ -1132,7 +1165,7 @@ define xbacktrace
1132 xgetptr ($bt->function) 1165 xgetptr ($bt->function)
1133 set $size = ((struct Lisp_Vector *) $ptr)->header.size 1166 set $size = ((struct Lisp_Vector *) $ptr)->header.size
1134 if ($size & PSEUDOVECTOR_FLAG) 1167 if ($size & PSEUDOVECTOR_FLAG)
1135 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_SIZE_BITS) 1168 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
1136 else 1169 else
1137 output $size & ~ARRAY_MARK_FLAG 1170 output $size & ~ARRAY_MARK_FLAG
1138 end 1171 end
diff --git a/src/ChangeLog b/src/ChangeLog
index 87f669c5c6e..e3be3f9149d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,554 @@
12012-11-13 Dmitry Antipov <dmantipov@yandex.ru>
2
3 Omit glyphs initialization at startup.
4 * dispnew.c (glyphs_initialized_initially_p): Remove.
5 (adjust_frame_glyphs_initially): Likewise. Adjust users.
6 (Fredraw_frame): Move actual code from here...
7 (redraw_frame): ...to here. Add eassert. Adjust comment.
8 (Fredraw_display): Use redraw_frame.
9 * xdisp.c (clear_garbaged_frames): Likewise.
10
112012-11-13 Eli Zaretskii <eliz@gnu.org>
12
13 * xdisp.c (decode_mode_spec): Limit the value of WIDTH argument
14 passed to pint2str and pint2hrstr to be at most the size of the
15 frame's decode_mode_spec_buffer. This avoids crashes with very
16 large values of FIELD_WIDTH argument to decode_mode_spec.
17 (Bug#12867)
18
192012-11-13 Paul Eggert <eggert@cs.ucla.edu>
20
21 Fix a race with verify-visited-file-modtime (Bug#12863).
22 Since at least 1991 Emacs has ignored an mtime difference of no
23 more than one second, but my guess is that this was to work around
24 file system bugs that were fixed long ago. Since the race is
25 causing problems now, let's remove that code.
26 * fileio.c (Fverify_visited_file_modtime): Do not accept a file
27 whose time stamp is off by no more than a second. Insist that the
28 file time stamps match exactly.
29
302012-11-12 Dmitry Antipov <dmantipov@yandex.ru>
31
32 * frame.h (struct frame): Convert external_tool_bar member to
33 1-bit unsigned bitfield.
34 * termhooks.h (struct terminal): Remove mouse_moved member since
35 all users are long dead. Adjust comment on mouse_position_hook.
36
372012-11-12 Dmitry Antipov <dmantipov@yandex.ru>
38
39 Simplify by using FOR_EACH_FRAME here and there.
40 * frame.c (next_frame, prev_frame, other_visible_frames)
41 (delete_frame, visible-frame-list): Use FOR_EACH_FRAME.
42 * w32term.c (x_window_to_scroll_bar): Likewise.
43 * window.c (window_list): Likewise.
44 * xdisp.c (x_consider_frame_title): Likewise.
45 * xfaces.c ( Fdisplay_supports_face_attributes_p): Likewise.
46 * xfns.c (x_window_to_frame, x_any_window_to_frame)
47 (x_menubar_window_to_frame, x_top_window_to_frame): Likewise.
48 * xmenu.c (menubar_id_to_frame): Likewise.
49 * xselect.c (frame_for_x_selection): Likewise.
50 * xterm.c (x_frame_of_widget, x_window_to_scroll_bar)
51 (x_window_to_menu_bar): Likewise.
52 * w32fns.c (x_window_to_frame): Likewise. Adjust comment.
53
542012-11-12 Paul Eggert <eggert@cs.ucla.edu>
55
56 * data.c (Qdefalias_fset_function): Now static.
57
58 Another tweak to vectorlike_header change.
59 * alloc.c (struct Lisp_Vectorlike_Free, NEXT_IN_FREE_LIST):
60 Remove, and replace all uses with ...
61 (next_in_free_list, set_next_in_free_list):
62 New functions, which respect C's aliasing rules better.
63
642012-11-11 Paul Eggert <eggert@cs.ucla.edu>
65
66 * window.c (list4i): Rename from 'quad'. All uses changed.
67 Needed because <sys/types.h> defines 'quad' on Solaris 10.
68
692012-11-11 Juanma Barranquero <lekktu@gmail.com>
70
71 * xdisp.c (start_hourglass) [HAVE_NTGUI]: Add block to silence
72 warning about mixing declarations and code in ISO C90.
73
742012-11-10 Martin Rudalics <rudalics@gmx.at>
75
76 * window.c (Fsplit_window_internal): Set combination limit of
77 new parent window to t iff Vwindow_combination_limit is t;
78 fixing a regression introduced with the change from 2012-09-22.
79 (Fset_window_combination_limit): Fix doc-string.
80
812012-11-10 Eli Zaretskii <eliz@gnu.org>
82
83 * xdisp.c (try_scrolling): Fix correction of aggressive-scroll
84 amount when the scroll margins are too large. When scrolling
85 backwards in the buffer, give up if cannot reach point or the
86 scroll margin within a reasonable number of screen lines. Fixes
87 point position in window under scroll-up/down-aggressively when
88 point is positioned many lines beyond the window top/bottom.
89 (Bug#12811)
90
91 * ralloc.c (relinquish): If real_morecore fails to return memory
92 to the system, don't crash; instead, leave the last heap
93 unchanged and return. (Bug#12774)
94
952012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
96
97 * lisp.h (AUTOLOADP): New macro.
98 * eval.c (Fautoload): Don't attach to loadhist, call Fdefalias instead.
99 * data.c (Ffset): Remove special ad-advice-info handling.
100 (Fdefalias): Handle autoload definitions and new Qdefalias_fset_function.
101 (Fsubr_arity): CSE.
102 (Finteractive_form): Simplify.
103 (Fquo): Don't insist on having at least 2 arguments.
104 (Qdefalias_fset_function): New var.
105
1062012-11-09 Jan Djärv <jan.h.d@swipnet.se>
107
108 * image.c (xpm_make_color_table_h): Change to hashtest_equal.
109
110 * nsfont.m (Qcondensed, Qexpanded): New variables.
111 (ns_descriptor_to_entity): Restore Qcondensed, Qexpanded setting.
112 (syms_of_nsfont): Defsym Qcondensed, Qexpanded.
113
1142012-11-09 Dmitry Antipov <dmantipov@yandex.ru>
115
116 Fix recently introduced crash on MS-Windows (Bug#12839).
117 * w32term.h (struct scroll_bar): Use convenient header.
118 (SCROLL_BAR_VEC_SIZE): Remove.
119 * w32term.c (x_scroll_bar_create): Use VECSIZE.
120
1212012-11-09 Dmitry Antipov <dmantipov@yandex.ru>
122
123 Tweak last vectorlike_header change.
124 * alloc.c (struct Lisp_Vectorlike_Free): Special type to represent
125 vectorlike object on the free list. This is introduced to avoid
126 some (but not all) pointer casting and aliasing problems, see
127 http://lists.gnu.org/archive/html/emacs-devel/2012-11/msg00105.html.
128 * .gdbinit (pvectype, pvecsize): New commands to examine vectorlike
129 objects.
130 (xvectype, xvecsize): Use them to examine Lisp_Object values.
131
1322012-11-09 Jan Djärv <jan.h.d@swipnet.se>
133
134 * nsfont.m (ns_descriptor_to_entity): Qcondensed and Qexpanded has
135 been removed, so remove them here also.
136
1372012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
138
139 * doc.c (Fdocumentation): Handle new property
140 dynamic-docstring-function to replace the old ad-advice-info.
141
1422012-11-09 Paul Eggert <eggert@cs.ucla.edu>
143
144 * fns.c (Qeql, hashtest_eq): Now static.
145
1462012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
147
148 * lisp.h (XHASH): Redefine to be imperfect and fit in a Lisp int.
149 * fns.c (hashfn_eq, hashfn_eql, sxhash):
150 * profiler.c (hashfn_profiler): Don't use XUINT on non-integers.
151 * buffer.c (compare_overlays): Use XLI rather than XHASH.
152
1532012-11-08 Paul Eggert <eggert@cs.ucla.edu>
154
155 Use same hash function for hashfn_profiler as for hash_string etc.
156 * fns.c (SXHASH_COMBINE): Remove. All uses replaced by sxhash_combine.
157 * lisp.h (sxhash_combine): New inline function, with the contents
158 of the old SXHASH_COMBINE.
159 * profiler.c (hashfn_profiler): Use it, instead of having a
160 special hash function containing a comparison that always yields 1.
161
1622012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
163
164 * xfaces.c (Qultra_light, Qreverse_oblique, Qreverse_italic)
165 (Qultra_condensed, Qextra_condensed, Qcondensed, Qsemi_condensed)
166 (Qsemi_expanded, Qextra_expanded, Qexpanded, Qultra_expanded):
167 Remove unused vars.
168
1692012-11-08 Jan Djärv <jan.h.d@swipnet.se>
170
171 * image.c (xpm_make_color_table_h): Fix compiler error because
172 make_hash_table changed.
173
1742012-11-08 Thomas Kappler <tkappler@gmail.com> (tiny change)
175
176 * nsfont.m (ns_findfonts): Handle empty matchingDescs (Bug#11541).
177
1782012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
179
180 Use ad-hoc comparison function for the profiler's hash-tables.
181 * profiler.c (Qprofiler_backtrace_equal, hashtest_profiler): New vars.
182 (make_log): Use them.
183 (handle_profiler_signal): Don't inhibit quit any longer since we don't
184 call Fequal any more.
185 (Ffunction_equal): New function.
186 (cmpfn_profiler, hashfn_profiler): New functions.
187 (syms_of_profiler): Initialize them.
188 * lisp.h (struct hash_table_test): New struct.
189 (struct Lisp_Hash_Table): Use it.
190 * alloc.c (mark_object): Mark hash_table_test fields of hash tables.
191 * fns.c (make_hash_table): Take a struct to describe the test.
192 (cmpfn_eql, cmpfn_equal, cmpfn_user_defined, hashfn_eq, hashfn_eql)
193 (hashfn_equal, hashfn_user_defined): Adjust to new calling convention.
194 (hash_lookup, hash_remove_from_table): Move assertion checking of
195 hashfn result here. Check hash-equality before calling cmpfn.
196 (Fmake_hash_table): Adjust call to make_hash_table.
197 (hashtest_eq, hashtest_eql, hashtest_equal): New structs.
198 (syms_of_fns): Initialize them.
199 * emacs.c (main): Move syms_of_fns earlier.
200 * xterm.c (syms_of_xterm):
201 * category.c (hash_get_category_set): Adjust call to make_hash_table.
202 * print.c (print_object): Adjust to new hash-table struct.
203 * composite.c (composition_gstring_put_cache): Adjust to new hashfn.
204
2052012-11-08 Eli Zaretskii <eliz@gnu.org>
206
207 * w32fns.c (modifier_set): Fix handling of Scroll Lock when the
208 value of w32-scroll-lock-modifier is neither nil nor one of the
209 known key modifiers. (Bug#12806)
210
2112012-11-08 Dmitry Antipov <dmantipov@yandex.ru>
212
213 Shrink struct vectorlike_header to the only size field.
214 * lisp.h (enum pvec_type): Avoid explicit enum member values.
215 Adjust comment.
216 (enum More_Lisp_Bits): Change PSEUDOVECTOR_SIZE_BITS and
217 PVEC_TYPE_MASK to arrange new bitfield in the vector header.
218 (PSEUDOVECTOR_REST_BITS, PSEUDOVECTOR_REST_MASK): New members.
219 (PSEUDOVECTOR_AREA_BITS): New member used to extract subtype
220 information from the vector header. Adjust comment.
221 (XSETPVECTYPE, XSETPVECTYPESIZE, XSETTYPED_PSEUDOVECTOR)
222 (PSEUDOVECTOR_TYPEP, DEFUN): Adjust to match new vector header
223 layout.
224 (XSETSUBR, SUBRP): Adjust to match new Lisp_Subr layout.
225 (struct vectorlike_header): Remove next member. Adjust comment.
226 (struct Lisp_Subr): Add convenient header. Adjust comment.
227 (allocate_pseudovector): Adjust prototype.
228 * alloc.c (mark_glyph_matrix, mark_face_cache, allocate_string)
229 (sweep_string, lisp_malloc): Remove useless prototypes.
230 (enum mem_type): Adjust comment.
231 (NEXT_IN_FREE_LIST): New macro.
232 (SETUP_ON_FREE_LIST): Adjust XSETPVECTYPESIZE usage.
233 (Fmake_bool_vector): Likewise.
234 (struct large_vector): New type to represent allocation unit for
235 the vectors with the memory footprint more than VBLOOCK_BYTES_MAX.
236 (large_vectors): Change type to struct large_vector.
237 (allocate_vector_from_block): Simplify.
238 (PSEUDOVECTOR_NBYTES): Replace with...
239 (vector_nbytes): ...new function. Adjust users.
240 (sweep_vectors): Adjust processing of large vectors.
241 (allocate_vectorlike): Likewise.
242 (allocate_pseudovector): Change type of 3rd arg to enum pvec_type.
243 Add easserts. Adjust XSETPVECTYPESIZE usage.
244 (allocate_buffer): Use BUFFER_PVEC_INIT.
245 (live_vector_p): Adjust to match large vector.
246 * buffer.c (init_buffer_once): Use BUFFER_PVEC_INIT.
247 * buffer.h (struct buffer): Add next member.
248 (BUFFER_LISP_SIZE, BUFFER_REST_SIZE, BUFFER_PVEC_INIT):
249 New macros.
250 (FOR_EACH_BUFFER): Adjust to match struct buffer change.
251 * fns.c (internal_equal): Adjust to match enum pvec_type change.
252 (copy_hash_table): Adjust to match vector header change.
253 * lread.c (defsubr): Use XSETPVECTYPE.
254 * .gdbinit (xpr, xbacktrace): Adjust to match vector header change.
255 (xvectype): Likewise. Print PVEC_NORMAL_VECTOR for regular vectors.
256 (xvecsize): New command.
257
2582012-11-08 Dmitry Antipov <dmantipov@yandex.ru>
259
260 * keyboard.c (event_to_kboard): Do not dereference
261 frame_or_window field of SELECTION_REQUEST_EVENT
262 and SELECTION_CLEAR_EVENT events (Bug#12814).
263 * xterm.h (struct selection_input_event): Adjust comment.
264
2652012-11-07 Eli Zaretskii <eliz@gnu.org>
266
267 * w32fns.c (modifier_set): Don't report modifiers from toggle key,
268 such as Scroll Lock, if the respective keys are treated as
269 function keys, not as modifiers. This avoids destroying non-ASCII
270 keyboard input when Scroll Lock is toggled ON. (Bug#12806)
271
2722012-11-07 Dmitry Antipov <dmantipov@yandex.ru>
273
274 * xfns.c (Fx_wm_set_size_hint): Use check_x_frame. Adjust docstring.
275
2762012-11-06 Paul Eggert <eggert@cs.ucla.edu>
277
278 Restore some duplicate definitions (Bug#12814).
279 This undoes part of the 2012-11-03 changes. Some people build
280 with plain -g rather than with -g3, and they need the duplicate
281 definitions for .gdbinit to work; see <http://bugs.gnu.org/12814#26>.
282 * lisp.h (GCTYPEBITS, ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG, VALMASK):
283 Define as macros, as well as as enums or as constants.
284
2852012-11-06 Jan Djärv <jan.h.d@swipnet.se>
286
287 * nsterm.m (convert_ns_to_X_keysym, keyDown:): Add NSNumericPadKeyMask
288 to keypad keys (Bug#12816).
289
2902012-11-06 Paul Eggert <eggert@cs.ucla.edu>
291
292 Minor adjustments of recently-changed frame functions.
293 * buffer.c (Fbuffer_list): Omit CHECK_FRAME, since arg is already
294 known to be a frame (we're in the FRAMEP branch).
295 * lisp.h (Qframep): Remove decl. frame.h declares this.
296 * window.c (quad): Args are of type EMACS_INT, not ptrdiff_t,
297 since they're meant for Lisp fixnum values.
298
2992012-11-06 Dmitry Antipov <dmantipov@yandex.ru>
300
301 * window.c (Fwindow_combination_limit): Revert to the only
302 required argument and adjust docstring as suggested in
303 http://lists.gnu.org/archive/html/emacs-diffs/2012-11/msg01082.html
304 by Martin Rudalics <rudalics@gmx.at>.
305
3062012-11-06 Dmitry Antipov <dmantipov@yandex.ru>
307
308 Widely used frame validity and checking functions.
309 * frame.h (decode_live_frame, decode_any_frame): Add prototypes.
310 * frame.c (decode_live_frame, decode_any_frame): New functions.
311 (delete_frame, Fredirect_frame_focus, Fframe_parameters)
312 (Fframe_parameter, Fframe_char_height, Fframe_char_width)
313 (Fframe_pixel_height, Fframe_pixel_width, Ftool_bar_pixel_width)
314 (Fframe_pointer_visible_p): Use decode_any_frame.
315 (Fmake_frame_visible, Fmake_frame_invisible, Ficonify_frame)
316 (Fraise_frame, Flower_frame, Fmodify_frame_parameters)
317 (Fset_frame_height, Fset_frame_width): Use decode_live_frame.
318 (Fframe_focus): Likewise. Allow zero number of arguments.
319 Adjust docstring.
320 (frame_buffer_list, frame_buffer_predicate): Remove.
321 * lisp.h (frame_buffer_predicate): Remove prototype.
322 * buffer.c (Fother_buffer): Use decode_any_frame.
323 * xdisp.c (Ftool_bar_lines_needed): Likewise.
324 * xfaces.c (Fcolor_gray_p, Fcolor_supported_p): Likewise.
325 * font.c (Ffont_face_attributes, Ffont_family_list, Fopen_font)
326 (Fclose_font, Ffont_info): Use decode_live_frame.
327 * fontset.c (check_fontset_name): Likewise.
328 * terminal.c (Fframe_terminal): Likewise.
329 * w32fns.c (check_x_frame): Likewise.
330 * window.c (Fminibuffer_window, Fwindow_at)
331 (Fcurrent_window_configuration): Likewise.
332 (Frun_window_configuration_change_hook, Fwindow_resize_apply):
333 Likewise. Allow zero number of arguments. Adjust docstring.
334 * dispnew.c (Fredraw_frame): Likewise.
335 * xfaces.c (frame_or_selected_frame): Remove.
336 (Fx_list_fonts, Finternal_get_lisp_face_attribute, Fface_font)
337 (Finternal_lisp_face_equal_p, Finternal_lisp_face_empty_p)
338 (Fframe_face_alist): Use decode_live_frame.
339 * xfns.c (check_x_frame): Likewise.
340
3412012-11-06 Dmitry Antipov <dmantipov@yandex.ru>
342
343 * window.c (quad): New function.
344 (Fwindow_edges, Fwindow_pixel_edges, Fwindow_inside_edges)
345 (Fwindow_absolute_pixel_edges, Fwindow_inside_absolute_pixel_edges)
346 (Fwindow_inside_pixel_edges, Fpos_visible_in_window_p)
347 (Fwindow_line_height): Use it.
348 (Fwindow_fringes): Use list3.
349 (Fwindow_scroll_bars): Use list4.
350 (Fwindow_frame, Fwindow_top_child, Fwindow_left_child)
351 (Fwindow_combination_limit): Allow zero number of arguments.
352
3532012-11-05 Eli Zaretskii <eliz@gnu.org>
354
355 * makefile.w32-in ($(BLD)/w32fns.$(O)): Depend on $(NT_INC)/unistd.h.
356
357 * w32fns.c: Include unistd.h, to avoid compiler warnings on Cygwin.
358 (emacs_abort) [CYGWIN]: Don't call _open_osfhandle; instead, use
359 file descriptor 2 for standard error. (Bug#12805)
360
3612012-11-05 Chong Yidong <cyd@gnu.org>
362
363 * process.c (wait_reading_process_output): Revert previous change.
364
3652012-11-05 Paul Eggert <eggert@cs.ucla.edu>
366
367 Assume at least POSIX.1-1988 for getpgrp, setpgid, setsid (Bug#12800).
368 This removes code that has been obsolete since around 1990.
369 * callproc.c (Fcall_process):
370 * emacs.c (main):
371 * process.c (create_process):
372 * term.c (dissociate_if_controlling_tty):
373 Assume setsid exists.
374 * callproc.c (child_setup): Assume setpgid exists and behaves as
375 per POSIX.1-1988 or later.
376 * conf_post.h (setpgid) [!HAVE_SETPGID]: Remove.
377 * emacs.c (shut_down_emacs):
378 * sysdep.c (sys_suspend, init_foreground_group):
379 Assume getpgrp behaves as per POSIX.1-1998 or later.
380 * msdos.c (setpgrp): Remove.
381 (tcgetpgrp, setpgid, setsid): New functions.
382 * systty.h (EMACS_GETPGRP): Remove. All callers now use getpgrp.
383 * term.c (no_controlling_tty): Remove; unused.
384 * w32proc.c (setpgrp): Remove.
385 (setsid, tcgetpgrp): New functions.
386
387 Simplify by assuming __fpending.
388 * dispnew.c: Include <fpending.h>, not <stdio_ext.h>.
389 (update_frame_1): Use __fpending, not PENDING_OUTPUT_COUNT.
390 Do not assume that __fpending's result fits in int.
391
3922012-11-04 Paul Eggert <eggert@cs.ucla.edu>
393
394 Remove EMACS_OUTQSIZE+sleep hack.
395 * dispnew.c (update_frame_1): Remove hack for terminals slower
396 than 2400 bps, which throttled Emacs by having it sleep.
397 This code hasn't worked since at least 2007, when the multi-tty stuff
398 was added, and anyway those old terminals are long dead.
399 * systty.h (EMACS_OUTQSIZE): Remove; unused. The macro isn't used even
400 without the dispnew.c change, as dispnew.c doesn't include systty.h.
401
402 Fix data-loss with --version (Bug#9574).
403 * emacs.c (close_output_streams): Use strerror, not emacs_strerror,
404 as we can't assume that emacs_strerror is initialized, and strerror
405 is good enough here.
406 (main): Invoke atexit earlier, to catch earlier instances of
407 sending data to stdout and exiting, e.g., "emacs --version >/dev/full".
408
4092012-11-04 Michael Marchionna <tralfaz@pacbell.net>
410
411 * nsterm.m: Add NSClearLineFunctionKey and keypad keys (Bug#8680).
412 (keyDown): Remap keypad keys to X11 virtual key codes.
413
4142012-11-03 Paul Eggert <eggert@cs.ucla.edu>
415
416 Fix data-loss with --batch (Bug#9574).
417 * emacs.c: Include <close-stream.h>.
418 (close_output_streams): New function.
419 (main): Pass it to atexit, so that Emacs closes stdout and stderr
420 and handles errors appropriately.
421 (Fkill_emacs): Don't worry about flushing, as close_output_stream
422 does that now.
423
424 Fix a race condition that causes Emacs to mess up glib (Bug#8855).
425 The symptom is a diagnostic "GLib-WARNING **: In call to
426 g_spawn_sync(), exit status of a child process was requested but
427 SIGCHLD action was set to SIG_IGN and ECHILD was received by
428 waitpid(), so exit status can't be returned." The diagnostic
429 is partly wrong, as the SIGCHLD action is not set to SIG_IGN.
430 The real bug is a race condition between Emacs and glib: Emacs
431 does a waitpid (-1, ...) and reaps glib's subprocess by mistake,
432 so that glib can't find it. Work around the bug by invoking
433 waitpid only on subprocesses that Emacs itself creates.
434 * process.c (create_process, record_child_status_change):
435 Don't use special value -1 in pid field, as the caller now must
436 know the pid rather than having the callee infer it.
437 The inference was sometimes incorrect anyway, due to another race.
438 (create_process): Set new 'alive' member if child is created.
439 (process_status_retrieved): New function.
440 (record_child_status_change): Use it.
441 Accept negative 1st argument, which means to wait for the
442 processes that Emacs already knows about. Move special-case code
443 for DOS_NT (which lacks WNOHANG) here, from caller. Keep track of
444 processes that have already been waited for, by testing and
445 clearing new 'alive' member.
446 (CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change
447 now does this internally.
448 (handle_child_signal): Let record_child_status_change do all
449 the work, since we do not want to reap all exited child processes,
450 only the child processes that Emacs itself created.
451 * process.h (Lisp_Process): New boolean member 'alive'.
452
453 Omit duplicate definitions no longer needed with gcc -g3.
454 * lisp.h (GCTYPEBITS, GCALIGNMENT, ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG)
455 (VALMASK, MOST_POSITIVE_FIXNUM, MOST_NEGATIVE_FIXNUM):
456 Define only as macros. There's no longer any need to also define
457 these symbols as enums or as constants, since we now assume
458 gcc -g3 when debugging.
459
4602012-11-03 Eli Zaretskii <eliz@gnu.org>
461
462 * lisp.mk: Adjust comments to the fact that term/internal is now
463 loaded from loadup.el.
464
465 * msdos.c (msdos_abort): Rename from emacs_abort, and make static.
466 (msdos_fatal_signal): New function.
467 (XMenuActivate): Adjust the call to kbd_buffer_events_waiting to
468 its argument list.
469
470 * conf_post.h (_GL_EXECINFO_INLINE) [MSDOS]: Define to "inline"
471 for GCC versions before 4.
472 (emacs_raise): Define to call msdos_fatal_signal.
473
474 * xdisp.c (init_from_display_pos): Fix initialization of the bidi
475 iterator when starting in the middle of a display or overlay
476 string. (Bug#12745)
477
4782012-11-03 Chong Yidong <cyd@gnu.org>
479
480 * process.c (wait_reading_process_output): Clean up the last
481 change.
482
4832012-11-03 Jim Paris <jim@jtan.com> (tiny change)
484
485 * process.c (wait_reading_process_output): Avoid a race condition
486 with SIGIO delivery (Bug#11536).
487
4882012-11-03 Chong Yidong <cyd@gnu.org>
489
490 * buffer.c (cursor_type): Untabify docstring.
491
4922012-11-03 Dmitry Antipov <dmantipov@yandex.ru>
493
494 * frame.h (struct frame): Drop can_have_scroll_bars member
495 which is meaningless for a long time. Adjust comments.
496 (FRAME_CAN_HAVE_SCROLL_BARS): Remove.
497 * frame.c, nsfns.m, term.c, w32fns.c, xfns.c: Adjust users.
498
4992012-11-03 Dmitry Antipov <dmantipov@yandex.ru>
500
501 * window.c (decode_next_window_args): Update window arg after
502 calling decode_live_window and so fix crash reported at
503 http://lists.gnu.org/archive/html/emacs-devel/2012-11/msg00035.html
504 by Juanma Barranquero <lekktu@gmail.com>.
505 (Fwindow_body_width, Fwindow_body_height): Simplify a bit.
506 * font.c (Ffont_at): Likewise.
507
5082012-11-01 Jan Djärv <jan.h.d@swipnet.se>
509
510 * widget.c (resize_cb): New function.
511 (EmacsFrameRealize): Add resize_cb as event handler (Bug#12733).
512 (EmacsFrameResize): Check if all is up to date before changing frame
513 size.
514
5152012-11-02 Eli Zaretskii <eliz@gnu.org>
516
517 Implement backtrace output for fatal errors on MS-Windows.
518 * w32fns.c (CaptureStackBackTrace_proc): New typedef.
519 (BACKTRACE_LIMIT_MAX): New macro.
520 (w32_backtrace): New function.
521 (emacs_abort): Use w32_backtrace when the user chooses not to
522 attach a debugger. Update the text of the abort dialog.
523
5242012-11-02 Dmitry Antipov <dmantipov@yandex.ru>
525
526 Window-related stuff cleanup here and there.
527 * dispnew.c (Finternal_show_cursor, Finternal_show_cursor_p):
528 Use decode_any_window.
529 * fringe.c (Ffringe_bitmaps_at_pos): Likewise.
530 * xdisp.c (Fformat_mode_line): Likewise.
531 * font.c (Ffont_at): Use decode_live_window.
532 * indent.c (Fcompute_motion, Fvertical_motion): Likewise.
533 * window.c (decode_next_window_args): Likewise.
534 (decode_any_window): Remove static.
535 * window.h (decode_any_window): Add prototype.
536 * lisp.h (CHECK_VALID_WINDOW, CHECK_LIVE_WINDOW): Move from here...
537 * window.h: ...to here, redefine via WINDOW_VALID_P and WINDOW_LIVE_P,
538 respectively.
539
5402012-11-02 Dmitry Antipov <dmantipov@yandex.ru>
541
542 Remove pad from struct input_event.
543 * termhooks.h (struct input_event): Remove padding field.
544 Adjust comment.
545 * keyboard.c (event_to_kboard): Simplify because frame_or_window
546 member is never cons for a long time. Adjust comment.
547 (mark_kboards): Adjust because SELECTION_REQUEST_EVENT and
548 SELECTION_CLEAR_EVENT has no Lisp_Objects to mark. Add comment.
549 * xterm.c (handle_one_xevent): Do not initialize frame_or_window
550 field of SELECTION_REQUEST_EVENT and SELECTION_CLEAR_EVENT.
551
12012-11-01 Eli Zaretskii <eliz@gnu.org> 5522012-11-01 Eli Zaretskii <eliz@gnu.org>
2 553
3 * w32proc.c (getpgrp, setpgid): New functions. (Bug#12776) 554 * w32proc.c (getpgrp, setpgid): New functions. (Bug#12776)
@@ -44,8 +595,8 @@
44 595
452012-10-29 Daniel Colascione <dancol@dancol.org> 5962012-10-29 Daniel Colascione <dancol@dancol.org>
46 597
47 * cygw32.h, cygw32.c (Qutf_16le, from_unicode, to_unicode): In 598 * cygw32.h, cygw32.c (Qutf_16le, from_unicode, to_unicode):
48 preparation for fixing bug#12739, move these functions from 599 In preparation for fixing bug#12739, move these functions from
49 here... 600 here...
50 601
51 * coding.h, coding.c: ... to here, and compile them only when 602 * coding.h, coding.c: ... to here, and compile them only when
@@ -628,7 +1179,7 @@
628 now a supported configuration. 1179 now a supported configuration.
629 1180
630 * Makefile.in: consolidate image variables into LIBIMAGE; add 1181 * Makefile.in: consolidate image variables into LIBIMAGE; add
631 W32_OBJ and W32_LIBS. Compile new files. 1182 W32_OBJ and W32_LIBS. Compile new files.
632 1183
633 * conf_post.h: 1184 * conf_post.h:
634 (_DebPrint) declare tracing facility for W32 debugging. We need 1185 (_DebPrint) declare tracing facility for W32 debugging. We need
diff --git a/src/alloc.c b/src/alloc.c
index 5bb528c64ab..a66a752f5dc 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -216,23 +216,19 @@ static Lisp_Object Qpost_gc_hook;
216static void mark_terminals (void); 216static void mark_terminals (void);
217static void gc_sweep (void); 217static void gc_sweep (void);
218static Lisp_Object make_pure_vector (ptrdiff_t); 218static Lisp_Object make_pure_vector (ptrdiff_t);
219static void mark_glyph_matrix (struct glyph_matrix *);
220static void mark_face_cache (struct face_cache *);
221static void mark_buffer (struct buffer *); 219static void mark_buffer (struct buffer *);
222 220
223#if !defined REL_ALLOC || defined SYSTEM_MALLOC 221#if !defined REL_ALLOC || defined SYSTEM_MALLOC
224static void refill_memory_reserve (void); 222static void refill_memory_reserve (void);
225#endif 223#endif
226static struct Lisp_String *allocate_string (void);
227static void compact_small_strings (void); 224static void compact_small_strings (void);
228static void free_large_strings (void); 225static void free_large_strings (void);
229static void sweep_strings (void);
230static void free_misc (Lisp_Object); 226static void free_misc (Lisp_Object);
231extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; 227extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE;
232 228
233/* When scanning the C stack for live Lisp objects, Emacs keeps track 229/* When scanning the C stack for live Lisp objects, Emacs keeps track of
234 of what memory allocated via lisp_malloc is intended for what 230 what memory allocated via lisp_malloc and lisp_align_malloc is intended
235 purpose. This enumeration specifies the type of memory. */ 231 for what purpose. This enumeration specifies the type of memory. */
236 232
237enum mem_type 233enum mem_type
238{ 234{
@@ -243,10 +239,9 @@ enum mem_type
243 MEM_TYPE_MISC, 239 MEM_TYPE_MISC,
244 MEM_TYPE_SYMBOL, 240 MEM_TYPE_SYMBOL,
245 MEM_TYPE_FLOAT, 241 MEM_TYPE_FLOAT,
246 /* We used to keep separate mem_types for subtypes of vectors such as 242 /* Since all non-bool pseudovectors are small enough to be
247 process, hash_table, frame, terminal, and window, but we never made 243 allocated from vector blocks, this memory type denotes
248 use of the distinction, so it only caused source-code complexity 244 large regular vectors and large bool pseudovectors. */
249 and runtime slowdown. Minor but pointless. */
250 MEM_TYPE_VECTORLIKE, 245 MEM_TYPE_VECTORLIKE,
251 /* Special type to denote vector blocks. */ 246 /* Special type to denote vector blocks. */
252 MEM_TYPE_VECTOR_BLOCK, 247 MEM_TYPE_VECTOR_BLOCK,
@@ -254,9 +249,6 @@ enum mem_type
254 MEM_TYPE_SPARE 249 MEM_TYPE_SPARE
255}; 250};
256 251
257static void *lisp_malloc (size_t, enum mem_type);
258
259
260#if GC_MARK_STACK || defined GC_MALLOC_CHECK 252#if GC_MARK_STACK || defined GC_MALLOC_CHECK
261 253
262#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 254#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
@@ -2040,7 +2032,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2040 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil); 2032 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil);
2041 2033
2042 /* No Lisp_Object to trace in there. */ 2034 /* No Lisp_Object to trace in there. */
2043 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0); 2035 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2044 2036
2045 p = XBOOL_VECTOR (val); 2037 p = XBOOL_VECTOR (val);
2046 p->size = XFASTINT (length); 2038 p->size = XFASTINT (length);
@@ -2619,19 +2611,54 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2619 2611
2620#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) 2612#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
2621 2613
2614/* Get and set the next field in block-allocated vectorlike objects on
2615 the free list. Doing it this way respects C's aliasing rules.
2616 We could instead make 'contents' a union, but that would mean
2617 changes everywhere that the code uses 'contents'. */
2618static struct Lisp_Vector *
2619next_in_free_list (struct Lisp_Vector *v)
2620{
2621 intptr_t i = XLI (v->contents[0]);
2622 return (struct Lisp_Vector *) i;
2623}
2624static void
2625set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
2626{
2627 v->contents[0] = XIL ((intptr_t) next);
2628}
2629
2622/* Common shortcut to setup vector on a free list. */ 2630/* Common shortcut to setup vector on a free list. */
2623 2631
2624#define SETUP_ON_FREE_LIST(v, nbytes, index) \ 2632#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \
2625 do { \ 2633 do { \
2626 XSETPVECTYPESIZE (v, PVEC_FREE, nbytes); \ 2634 (tmp) = ((nbytes - header_size) / word_size); \
2627 eassert ((nbytes) % roundup_size == 0); \ 2635 XSETPVECTYPESIZE (v, PVEC_FREE, 0, (tmp)); \
2628 (index) = VINDEX (nbytes); \ 2636 eassert ((nbytes) % roundup_size == 0); \
2629 eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ 2637 (tmp) = VINDEX (nbytes); \
2630 (v)->header.next.vector = vector_free_lists[index]; \ 2638 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
2631 vector_free_lists[index] = (v); \ 2639 set_next_in_free_list (v, vector_free_lists[tmp]); \
2632 total_free_vector_slots += (nbytes) / word_size; \ 2640 vector_free_lists[tmp] = (v); \
2641 total_free_vector_slots += (nbytes) / word_size; \
2633 } while (0) 2642 } while (0)
2634 2643
2644/* This internal type is used to maintain the list of large vectors
2645 which are allocated at their own, e.g. outside of vector blocks. */
2646
2647struct large_vector
2648{
2649 union {
2650 struct large_vector *vector;
2651#if USE_LSB_TAG
2652 /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */
2653 unsigned char c[vroundup (sizeof (struct large_vector *))];
2654#endif
2655 } next;
2656 struct Lisp_Vector v;
2657};
2658
2659/* This internal type is used to maintain an underlying storage
2660 for small vectors. */
2661
2635struct vector_block 2662struct vector_block
2636{ 2663{
2637 char data[VECTOR_BLOCK_BYTES]; 2664 char data[VECTOR_BLOCK_BYTES];
@@ -2649,7 +2676,7 @@ static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX];
2649 2676
2650/* Singly-linked list of large vectors. */ 2677/* Singly-linked list of large vectors. */
2651 2678
2652static struct Lisp_Vector *large_vectors; 2679static struct large_vector *large_vectors;
2653 2680
2654/* The only vector with 0 slots, allocated from pure space. */ 2681/* The only vector with 0 slots, allocated from pure space. */
2655 2682
@@ -2693,7 +2720,7 @@ init_vectors (void)
2693static struct Lisp_Vector * 2720static struct Lisp_Vector *
2694allocate_vector_from_block (size_t nbytes) 2721allocate_vector_from_block (size_t nbytes)
2695{ 2722{
2696 struct Lisp_Vector *vector, *rest; 2723 struct Lisp_Vector *vector;
2697 struct vector_block *block; 2724 struct vector_block *block;
2698 size_t index, restbytes; 2725 size_t index, restbytes;
2699 2726
@@ -2706,8 +2733,7 @@ allocate_vector_from_block (size_t nbytes)
2706 if (vector_free_lists[index]) 2733 if (vector_free_lists[index])
2707 { 2734 {
2708 vector = vector_free_lists[index]; 2735 vector = vector_free_lists[index];
2709 vector_free_lists[index] = vector->header.next.vector; 2736 vector_free_lists[index] = next_in_free_list (vector);
2710 vector->header.next.nbytes = nbytes;
2711 total_free_vector_slots -= nbytes / word_size; 2737 total_free_vector_slots -= nbytes / word_size;
2712 return vector; 2738 return vector;
2713 } 2739 }
@@ -2721,16 +2747,14 @@ allocate_vector_from_block (size_t nbytes)
2721 { 2747 {
2722 /* This vector is larger than requested. */ 2748 /* This vector is larger than requested. */
2723 vector = vector_free_lists[index]; 2749 vector = vector_free_lists[index];
2724 vector_free_lists[index] = vector->header.next.vector; 2750 vector_free_lists[index] = next_in_free_list (vector);
2725 vector->header.next.nbytes = nbytes;
2726 total_free_vector_slots -= nbytes / word_size; 2751 total_free_vector_slots -= nbytes / word_size;
2727 2752
2728 /* Excess bytes are used for the smaller vector, 2753 /* Excess bytes are used for the smaller vector,
2729 which should be set on an appropriate free list. */ 2754 which should be set on an appropriate free list. */
2730 restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; 2755 restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes;
2731 eassert (restbytes % roundup_size == 0); 2756 eassert (restbytes % roundup_size == 0);
2732 rest = ADVANCE (vector, nbytes); 2757 SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index);
2733 SETUP_ON_FREE_LIST (rest, restbytes, index);
2734 return vector; 2758 return vector;
2735 } 2759 }
2736 2760
@@ -2739,7 +2763,6 @@ allocate_vector_from_block (size_t nbytes)
2739 2763
2740 /* New vector will be at the beginning of this block. */ 2764 /* New vector will be at the beginning of this block. */
2741 vector = (struct Lisp_Vector *) block->data; 2765 vector = (struct Lisp_Vector *) block->data;
2742 vector->header.next.nbytes = nbytes;
2743 2766
2744 /* If the rest of space from this block is large enough 2767 /* If the rest of space from this block is large enough
2745 for one-slot vector at least, set up it on a free list. */ 2768 for one-slot vector at least, set up it on a free list. */
@@ -2747,11 +2770,10 @@ allocate_vector_from_block (size_t nbytes)
2747 if (restbytes >= VBLOCK_BYTES_MIN) 2770 if (restbytes >= VBLOCK_BYTES_MIN)
2748 { 2771 {
2749 eassert (restbytes % roundup_size == 0); 2772 eassert (restbytes % roundup_size == 0);
2750 rest = ADVANCE (vector, nbytes); 2773 SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index);
2751 SETUP_ON_FREE_LIST (rest, restbytes, index);
2752 } 2774 }
2753 return vector; 2775 return vector;
2754 } 2776}
2755 2777
2756/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ 2778/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */
2757 2779
@@ -2759,15 +2781,30 @@ allocate_vector_from_block (size_t nbytes)
2759 ((char *) (vector) <= (block)->data \ 2781 ((char *) (vector) <= (block)->data \
2760 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) 2782 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN)
2761 2783
2762/* Number of bytes used by vector-block-allocated object. This is the only 2784/* Return the memory footprint of V in bytes. */
2763 place where we actually use the `nbytes' field of the vector-header.
2764 I.e. we could get rid of the `nbytes' field by computing it based on the
2765 vector-type. */
2766 2785
2767#define PSEUDOVECTOR_NBYTES(vector) \ 2786static ptrdiff_t
2768 (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \ 2787vector_nbytes (struct Lisp_Vector *v)
2769 ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \ 2788{
2770 : vector->header.next.nbytes) 2789 ptrdiff_t size = v->header.size & ~ARRAY_MARK_FLAG;
2790
2791 if (size & PSEUDOVECTOR_FLAG)
2792 {
2793 if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR))
2794 size = (bool_header_size
2795 + (((struct Lisp_Bool_Vector *) v)->size
2796 + BOOL_VECTOR_BITS_PER_CHAR - 1)
2797 / BOOL_VECTOR_BITS_PER_CHAR);
2798 else
2799 size = (header_size
2800 + ((size & PSEUDOVECTOR_SIZE_MASK)
2801 + ((size & PSEUDOVECTOR_REST_MASK)
2802 >> PSEUDOVECTOR_SIZE_BITS)) * word_size);
2803 }
2804 else
2805 size = header_size + size * word_size;
2806 return vroundup (size);
2807}
2771 2808
2772/* Reclaim space used by unmarked vectors. */ 2809/* Reclaim space used by unmarked vectors. */
2773 2810
@@ -2775,7 +2812,8 @@ static void
2775sweep_vectors (void) 2812sweep_vectors (void)
2776{ 2813{
2777 struct vector_block *block = vector_blocks, **bprev = &vector_blocks; 2814 struct vector_block *block = vector_blocks, **bprev = &vector_blocks;
2778 struct Lisp_Vector *vector, *next, **vprev = &large_vectors; 2815 struct large_vector *lv, **lvprev = &large_vectors;
2816 struct Lisp_Vector *vector, *next;
2779 2817
2780 total_vectors = total_vector_slots = total_free_vector_slots = 0; 2818 total_vectors = total_vector_slots = total_free_vector_slots = 0;
2781 memset (vector_free_lists, 0, sizeof (vector_free_lists)); 2819 memset (vector_free_lists, 0, sizeof (vector_free_lists));
@@ -2785,6 +2823,7 @@ sweep_vectors (void)
2785 for (block = vector_blocks; block; block = *bprev) 2823 for (block = vector_blocks; block; block = *bprev)
2786 { 2824 {
2787 bool free_this_block = 0; 2825 bool free_this_block = 0;
2826 ptrdiff_t nbytes;
2788 2827
2789 for (vector = (struct Lisp_Vector *) block->data; 2828 for (vector = (struct Lisp_Vector *) block->data;
2790 VECTOR_IN_BLOCK (vector, block); vector = next) 2829 VECTOR_IN_BLOCK (vector, block); vector = next)
@@ -2793,14 +2832,16 @@ sweep_vectors (void)
2793 { 2832 {
2794 VECTOR_UNMARK (vector); 2833 VECTOR_UNMARK (vector);
2795 total_vectors++; 2834 total_vectors++;
2796 total_vector_slots += vector->header.next.nbytes / word_size; 2835 nbytes = vector_nbytes (vector);
2797 next = ADVANCE (vector, vector->header.next.nbytes); 2836 total_vector_slots += nbytes / word_size;
2837 next = ADVANCE (vector, nbytes);
2798 } 2838 }
2799 else 2839 else
2800 { 2840 {
2801 ptrdiff_t nbytes = PSEUDOVECTOR_NBYTES (vector); 2841 ptrdiff_t total_bytes;
2802 ptrdiff_t total_bytes = nbytes;
2803 2842
2843 nbytes = vector_nbytes (vector);
2844 total_bytes = nbytes;
2804 next = ADVANCE (vector, nbytes); 2845 next = ADVANCE (vector, nbytes);
2805 2846
2806 /* While NEXT is not marked, try to coalesce with VECTOR, 2847 /* While NEXT is not marked, try to coalesce with VECTOR,
@@ -2810,7 +2851,7 @@ sweep_vectors (void)
2810 { 2851 {
2811 if (VECTOR_MARKED_P (next)) 2852 if (VECTOR_MARKED_P (next))
2812 break; 2853 break;
2813 nbytes = PSEUDOVECTOR_NBYTES (next); 2854 nbytes = vector_nbytes (next);
2814 total_bytes += nbytes; 2855 total_bytes += nbytes;
2815 next = ADVANCE (next, nbytes); 2856 next = ADVANCE (next, nbytes);
2816 } 2857 }
@@ -2844,8 +2885,9 @@ sweep_vectors (void)
2844 2885
2845 /* Sweep large vectors. */ 2886 /* Sweep large vectors. */
2846 2887
2847 for (vector = large_vectors; vector; vector = *vprev) 2888 for (lv = large_vectors; lv; lv = *lvprev)
2848 { 2889 {
2890 vector = &lv->v;
2849 if (VECTOR_MARKED_P (vector)) 2891 if (VECTOR_MARKED_P (vector))
2850 { 2892 {
2851 VECTOR_UNMARK (vector); 2893 VECTOR_UNMARK (vector);
@@ -2867,12 +2909,12 @@ sweep_vectors (void)
2867 else 2909 else
2868 total_vector_slots 2910 total_vector_slots
2869 += header_size / word_size + vector->header.size; 2911 += header_size / word_size + vector->header.size;
2870 vprev = &vector->header.next.vector; 2912 lvprev = &lv->next.vector;
2871 } 2913 }
2872 else 2914 else
2873 { 2915 {
2874 *vprev = vector->header.next.vector; 2916 *lvprev = lv->next.vector;
2875 lisp_free (vector); 2917 lisp_free (lv);
2876 } 2918 }
2877 } 2919 }
2878} 2920}
@@ -2904,9 +2946,12 @@ allocate_vectorlike (ptrdiff_t len)
2904 p = allocate_vector_from_block (vroundup (nbytes)); 2946 p = allocate_vector_from_block (vroundup (nbytes));
2905 else 2947 else
2906 { 2948 {
2907 p = lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); 2949 struct large_vector *lv
2908 p->header.next.vector = large_vectors; 2950 = lisp_malloc (sizeof (*lv) + (len - 1) * word_size,
2909 large_vectors = p; 2951 MEM_TYPE_VECTORLIKE);
2952 lv->next.vector = large_vectors;
2953 large_vectors = lv;
2954 p = &lv->v;
2910 } 2955 }
2911 2956
2912#ifdef DOUG_LEA_MALLOC 2957#ifdef DOUG_LEA_MALLOC
@@ -2943,16 +2988,21 @@ allocate_vector (EMACS_INT len)
2943/* Allocate other vector-like structures. */ 2988/* Allocate other vector-like structures. */
2944 2989
2945struct Lisp_Vector * 2990struct Lisp_Vector *
2946allocate_pseudovector (int memlen, int lisplen, int tag) 2991allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
2947{ 2992{
2948 struct Lisp_Vector *v = allocate_vectorlike (memlen); 2993 struct Lisp_Vector *v = allocate_vectorlike (memlen);
2949 int i; 2994 int i;
2950 2995
2996 /* Catch bogus values. */
2997 eassert (tag <= PVEC_FONT);
2998 eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1);
2999 eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3000
2951 /* Only the first lisplen slots will be traced normally by the GC. */ 3001 /* Only the first lisplen slots will be traced normally by the GC. */
2952 for (i = 0; i < lisplen; ++i) 3002 for (i = 0; i < lisplen; ++i)
2953 v->contents[i] = Qnil; 3003 v->contents[i] = Qnil;
2954 3004
2955 XSETPVECTYPESIZE (v, tag, lisplen); 3005 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
2956 return v; 3006 return v;
2957} 3007}
2958 3008
@@ -2961,10 +3011,9 @@ allocate_buffer (void)
2961{ 3011{
2962 struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER); 3012 struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER);
2963 3013
2964 XSETPVECTYPESIZE (b, PVEC_BUFFER, (offsetof (struct buffer, own_text) 3014 BUFFER_PVEC_INIT (b);
2965 - header_size) / word_size);
2966 /* Put B on the chain of all buffers including killed ones. */ 3015 /* Put B on the chain of all buffers including killed ones. */
2967 b->header.next.buffer = all_buffers; 3016 b->next = all_buffers;
2968 all_buffers = b; 3017 all_buffers = b;
2969 /* Note that the rest fields of B are not initialized. */ 3018 /* Note that the rest fields of B are not initialized. */
2970 return b; 3019 return b;
@@ -4068,16 +4117,15 @@ live_vector_p (struct mem_node *m, void *p)
4068 while (VECTOR_IN_BLOCK (vector, block) 4117 while (VECTOR_IN_BLOCK (vector, block)
4069 && vector <= (struct Lisp_Vector *) p) 4118 && vector <= (struct Lisp_Vector *) p)
4070 { 4119 {
4071 if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) 4120 if (!PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) && vector == p)
4072 vector = ADVANCE (vector, (vector->header.size
4073 & PSEUDOVECTOR_SIZE_MASK));
4074 else if (vector == p)
4075 return 1; 4121 return 1;
4076 else 4122 else
4077 vector = ADVANCE (vector, vector->header.next.nbytes); 4123 vector = ADVANCE (vector, vector_nbytes (vector));
4078 } 4124 }
4079 } 4125 }
4080 else if (m->type == MEM_TYPE_VECTORLIKE && p == m->start) 4126 else if (m->type == MEM_TYPE_VECTORLIKE
4127 && (char *) p == ((char *) m->start
4128 + offsetof (struct large_vector, v)))
4081 /* This memory node corresponds to a large vector. */ 4129 /* This memory node corresponds to a large vector. */
4082 return 1; 4130 return 1;
4083 return 0; 4131 return 0;
@@ -5687,7 +5735,7 @@ mark_object (Lisp_Object arg)
5687 5735
5688 if (ptr->header.size & PSEUDOVECTOR_FLAG) 5736 if (ptr->header.size & PSEUDOVECTOR_FLAG)
5689 pvectype = ((ptr->header.size & PVEC_TYPE_MASK) 5737 pvectype = ((ptr->header.size & PVEC_TYPE_MASK)
5690 >> PSEUDOVECTOR_SIZE_BITS); 5738 >> PSEUDOVECTOR_AREA_BITS);
5691 else 5739 else
5692 pvectype = PVEC_NORMAL_VECTOR; 5740 pvectype = PVEC_NORMAL_VECTOR;
5693 5741
@@ -5766,6 +5814,9 @@ mark_object (Lisp_Object arg)
5766 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; 5814 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr;
5767 5815
5768 mark_vectorlike (ptr); 5816 mark_vectorlike (ptr);
5817 mark_object (h->test.name);
5818 mark_object (h->test.user_hash_function);
5819 mark_object (h->test.user_cmp_function);
5769 /* If hash table is not weak, mark all keys and values. 5820 /* If hash table is not weak, mark all keys and values.
5770 For weak tables, mark only the vector. */ 5821 For weak tables, mark only the vector. */
5771 if (NILP (h->weak)) 5822 if (NILP (h->weak))
@@ -6317,7 +6368,7 @@ gc_sweep (void)
6317 for (buffer = all_buffers; buffer; buffer = *bprev) 6368 for (buffer = all_buffers; buffer; buffer = *bprev)
6318 if (!VECTOR_MARKED_P (buffer)) 6369 if (!VECTOR_MARKED_P (buffer))
6319 { 6370 {
6320 *bprev = buffer->header.next.buffer; 6371 *bprev = buffer->next;
6321 lisp_free (buffer); 6372 lisp_free (buffer);
6322 } 6373 }
6323 else 6374 else
@@ -6326,7 +6377,7 @@ gc_sweep (void)
6326 /* Do not use buffer_(set|get)_intervals here. */ 6377 /* Do not use buffer_(set|get)_intervals here. */
6327 buffer->text->intervals = balance_intervals (buffer->text->intervals); 6378 buffer->text->intervals = balance_intervals (buffer->text->intervals);
6328 total_buffers++; 6379 total_buffers++;
6329 bprev = &buffer->header.next.buffer; 6380 bprev = &buffer->next;
6330 } 6381 }
6331 } 6382 }
6332 6383
diff --git a/src/buffer.c b/src/buffer.c
index 0b3dde27968..619a729a859 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -406,7 +406,6 @@ followed by the rest of the buffers. */)
406 Lisp_Object framelist, prevlist, tail; 406 Lisp_Object framelist, prevlist, tail;
407 Lisp_Object args[3]; 407 Lisp_Object args[3];
408 408
409 CHECK_FRAME (frame);
410 framelist = Fcopy_sequence (XFRAME (frame)->buffer_list); 409 framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
411 prevlist = Fnreverse (Fcopy_sequence 410 prevlist = Fnreverse (Fcopy_sequence
412 (XFRAME (frame)->buried_buffer_list)); 411 (XFRAME (frame)->buried_buffer_list));
@@ -1543,17 +1542,11 @@ list first, followed by the list of all buffers. If no other buffer
1543exists, return the buffer `*scratch*' (creating it if necessary). */) 1542exists, return the buffer `*scratch*' (creating it if necessary). */)
1544 (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame) 1543 (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
1545{ 1544{
1546 Lisp_Object tail, buf, pred; 1545 struct frame *f = decode_any_frame (frame);
1547 Lisp_Object notsogood = Qnil; 1546 Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate;
1547 Lisp_Object buf, notsogood = Qnil;
1548 1548
1549 if (NILP (frame))
1550 frame = selected_frame;
1551
1552 CHECK_FRAME (frame);
1553
1554 pred = frame_buffer_predicate (frame);
1555 /* Consider buffers that have been seen in the frame first. */ 1549 /* Consider buffers that have been seen in the frame first. */
1556 tail = XFRAME (frame)->buffer_list;
1557 for (; CONSP (tail); tail = XCDR (tail)) 1550 for (; CONSP (tail); tail = XCDR (tail))
1558 { 1551 {
1559 buf = XCAR (tail); 1552 buf = XCAR (tail);
@@ -2109,7 +2102,7 @@ set_buffer_internal_1 (register struct buffer *b)
2109 return; 2102 return;
2110 2103
2111 BUFFER_CHECK_INDIRECTION (b); 2104 BUFFER_CHECK_INDIRECTION (b);
2112 2105
2113 old_buf = current_buffer; 2106 old_buf = current_buffer;
2114 current_buffer = b; 2107 current_buffer = b;
2115 last_known_column_point = -1; /* invalidate indentation cache */ 2108 last_known_column_point = -1; /* invalidate indentation cache */
@@ -3139,8 +3132,8 @@ compare_overlays (const void *v1, const void *v2)
3139 between "equal" overlays. The result can still change between 3132 between "equal" overlays. The result can still change between
3140 invocations of Emacs, but it won't change in the middle of 3133 invocations of Emacs, but it won't change in the middle of
3141 `find_field' (bug#6830). */ 3134 `find_field' (bug#6830). */
3142 if (XHASH (s1->overlay) != XHASH (s2->overlay)) 3135 if (!EQ (s1->overlay, s2->overlay))
3143 return XHASH (s1->overlay) < XHASH (s2->overlay) ? -1 : 1; 3136 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3144 return 0; 3137 return 0;
3145} 3138}
3146 3139
@@ -5112,11 +5105,6 @@ void
5112init_buffer_once (void) 5105init_buffer_once (void)
5113{ 5106{
5114 int idx; 5107 int idx;
5115 /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make
5116 sure that this is still correct. Otherwise, mark_vectorlike may not
5117 trace all Lisp_Objects in buffer_defaults and buffer_local_symbols. */
5118 const int pvecsize
5119 = (offsetof (struct buffer, own_text) - header_size) / word_size;
5120 5108
5121 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags); 5109 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
5122 5110
@@ -5139,8 +5127,8 @@ init_buffer_once (void)
5139 /* This is not strictly necessary, but let's make them initialized. */ 5127 /* This is not strictly necessary, but let's make them initialized. */
5140 bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*")); 5128 bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*"));
5141 bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*")); 5129 bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*"));
5142 XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize); 5130 BUFFER_PVEC_INIT (&buffer_defaults);
5143 XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, pvecsize); 5131 BUFFER_PVEC_INIT (&buffer_local_symbols);
5144 5132
5145 /* Set up the default values of various buffer slots. */ 5133 /* Set up the default values of various buffer slots. */
5146 /* Must do these before making the first buffer! */ 5134 /* Must do these before making the first buffer! */
@@ -6210,15 +6198,15 @@ is a member of the list. */);
6210 doc: /* Cursor to use when this buffer is in the selected window. 6198 doc: /* Cursor to use when this buffer is in the selected window.
6211Values are interpreted as follows: 6199Values are interpreted as follows:
6212 6200
6213 t use the cursor specified for the frame 6201 t use the cursor specified for the frame
6214 nil don't display a cursor 6202 nil don't display a cursor
6215 box display a filled box cursor 6203 box display a filled box cursor
6216 hollow display a hollow box cursor 6204 hollow display a hollow box cursor
6217 bar display a vertical bar cursor with default width 6205 bar display a vertical bar cursor with default width
6218 (bar . WIDTH) display a vertical bar cursor with width WIDTH 6206 (bar . WIDTH) display a vertical bar cursor with width WIDTH
6219 hbar display a horizontal bar cursor with default height 6207 hbar display a horizontal bar cursor with default height
6220 (hbar . HEIGHT) display a horizontal bar cursor with height HEIGHT 6208 (hbar . HEIGHT) display a horizontal bar cursor with height HEIGHT
6221 ANYTHING ELSE display a hollow box cursor 6209 ANYTHING ELSE display a hollow box cursor
6222 6210
6223When the buffer is displayed in a non-selected window, the 6211When the buffer is displayed in a non-selected window, the
6224cursor's appearance is instead controlled by the variable 6212cursor's appearance is instead controlled by the variable
diff --git a/src/buffer.h b/src/buffer.h
index 9e0e9eef0b1..fbbbf1b8434 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -482,11 +482,6 @@ struct buffer_text
482 482
483struct buffer 483struct buffer
484{ 484{
485 /* HEADER.NEXT is the next buffer, in chain of all buffers, including killed
486 buffers. This chain, starting from all_buffers, is used only for garbage
487 collection, in order to collect killed buffers properly. Note that large
488 vectors and large pseudo-vector objects are all on another chain starting
489 from large_vectors. */
490 struct vectorlike_header header; 485 struct vectorlike_header header;
491 486
492 /* The name of this buffer. */ 487 /* The name of this buffer. */
@@ -750,6 +745,9 @@ struct buffer
750 In an indirect buffer, this is the own_text field of another buffer. */ 745 In an indirect buffer, this is the own_text field of another buffer. */
751 struct buffer_text *text; 746 struct buffer_text *text;
752 747
748 /* Next buffer, in chain of all buffers, including killed ones. */
749 struct buffer *next;
750
753 /* Char position of point in buffer. */ 751 /* Char position of point in buffer. */
754 ptrdiff_t pt; 752 ptrdiff_t pt;
755 753
@@ -959,6 +957,27 @@ bset_width_table (struct buffer *b, Lisp_Object val)
959 b->INTERNAL_FIELD (width_table) = val; 957 b->INTERNAL_FIELD (width_table) = val;
960} 958}
961 959
960/* Number of Lisp_Objects at the beginning of struct buffer.
961 If you add, remove, or reorder Lisp_Objects within buffer
962 structure, make sure that this is still correct. */
963
964#define BUFFER_LISP_SIZE \
965 ((offsetof (struct buffer, own_text) - header_size) / word_size)
966
967/* Size of the struct buffer part beyond leading Lisp_Objects, in word_size
968 units. Rounding is needed for --with-wide-int configuration. */
969
970#define BUFFER_REST_SIZE \
971 ((((sizeof (struct buffer) - offsetof (struct buffer, own_text)) \
972 + (word_size - 1)) & ~(word_size - 1)) / word_size)
973
974/* Initialize the pseudovector header of buffer object. BUFFER_LISP_SIZE
975 is required for GC, but BUFFER_REST_SIZE is set up just to be consistent
976 with other pseudovectors. */
977
978#define BUFFER_PVEC_INIT(b) \
979 XSETPVECTYPESIZE (b, PVEC_BUFFER, BUFFER_LISP_SIZE, BUFFER_REST_SIZE)
980
962/* Convenient check whether buffer B is live. */ 981/* Convenient check whether buffer B is live. */
963 982
964#define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name))) 983#define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name)))
@@ -986,7 +1005,7 @@ extern struct buffer *all_buffers;
986/* Used to iterate over the chain above. */ 1005/* Used to iterate over the chain above. */
987 1006
988#define FOR_EACH_BUFFER(b) \ 1007#define FOR_EACH_BUFFER(b) \
989 for ((b) = all_buffers; (b); (b) = (b)->header.next.buffer) 1008 for ((b) = all_buffers; (b); (b) = (b)->next)
990 1009
991/* This points to the current buffer. */ 1010/* This points to the current buffer. */
992 1011
diff --git a/src/callproc.c b/src/callproc.c
index c236f22fc86..c7bbe36e605 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -612,11 +612,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
612 if (fd[0] >= 0) 612 if (fd[0] >= 0)
613 emacs_close (fd[0]); 613 emacs_close (fd[0]);
614 614
615#ifdef HAVE_SETSID
616 setsid (); 615 setsid ();
617#else
618 setpgid (0, 0);
619#endif
620 616
621 /* Emacs ignores SIGPIPE, but the child should not. */ 617 /* Emacs ignores SIGPIPE, but the child should not. */
622 signal (SIGPIPE, SIG_DFL); 618 signal (SIGPIPE, SIG_DFL);
@@ -1286,11 +1282,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1286 if (err != in && err != out) 1282 if (err != in && err != out)
1287 emacs_close (err); 1283 emacs_close (err);
1288 1284
1289#if defined HAVE_SETPGID || ! (defined USG && defined SETPGRP_RELEASES_CTTY) 1285 setpgid (0, 0);
1290 setpgid (pid, pid);
1291#endif
1292
1293 /* setpgrp_of_tty is incorrect here; it uses input_fd. */
1294 tcsetpgrp (0, pid); 1286 tcsetpgrp (0, pid);
1295 1287
1296 /* execvp does not accept an environment arg so the only way 1288 /* execvp does not accept an environment arg so the only way
diff --git a/src/category.c b/src/category.c
index fe02303f679..31cc90bca68 100644
--- a/src/category.c
+++ b/src/category.c
@@ -78,10 +78,10 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set)
78 if (NILP (XCHAR_TABLE (table)->extras[1])) 78 if (NILP (XCHAR_TABLE (table)->extras[1]))
79 set_char_table_extras 79 set_char_table_extras
80 (table, 1, 80 (table, 1,
81 make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), 81 make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
82 make_float (DEFAULT_REHASH_SIZE), 82 make_float (DEFAULT_REHASH_SIZE),
83 make_float (DEFAULT_REHASH_THRESHOLD), 83 make_float (DEFAULT_REHASH_THRESHOLD),
84 Qnil, Qnil, Qnil)); 84 Qnil));
85 h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]); 85 h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]);
86 i = hash_lookup (h, category_set, &hash); 86 i = hash_lookup (h, category_set, &hash);
87 if (i >= 0) 87 if (i >= 0)
diff --git a/src/composite.c b/src/composite.c
index 6c603fab3fc..bcde0a4c9e6 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -676,7 +676,7 @@ composition_gstring_put_cache (Lisp_Object gstring, ptrdiff_t len)
676 ptrdiff_t i; 676 ptrdiff_t i;
677 677
678 header = LGSTRING_HEADER (gstring); 678 header = LGSTRING_HEADER (gstring);
679 hash = h->hashfn (h, header); 679 hash = h->test.hashfn (&h->test, header);
680 if (len < 0) 680 if (len < 0)
681 { 681 {
682 ptrdiff_t j, glyph_len = LGSTRING_GLYPH_LEN (gstring); 682 ptrdiff_t j, glyph_len = LGSTRING_GLYPH_LEN (gstring);
@@ -1382,7 +1382,7 @@ composition_update_it (struct composition_it *cmp_it, ptrdiff_t charpos, ptrdiff
1382 } 1382 }
1383 else 1383 else
1384 { 1384 {
1385 /* automatic composition */ 1385 /* Automatic composition. */
1386 Lisp_Object gstring = composition_gstring_from_id (cmp_it->id); 1386 Lisp_Object gstring = composition_gstring_from_id (cmp_it->id);
1387 Lisp_Object glyph; 1387 Lisp_Object glyph;
1388 ptrdiff_t from; 1388 ptrdiff_t from;
diff --git a/src/conf_post.h b/src/conf_post.h
index 6056821d4a7..66390ddf103 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -110,15 +110,16 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */
110#else 110#else
111# define lstat stat 111# define lstat stat
112#endif 112#endif
113/* The "portable" definition of _GL_INLINE on config.h does not work
114 with DJGPP GCC 3.4.4: it causes unresolved externals in sysdep.c,
115 although lib/execinfo.h is included and the inline functions there
116 are visible. */
117#if __GNUC__ < 4
118# define _GL_EXECINFO_INLINE inline
119#endif
113/* End of gnulib-related stuff. */ 120/* End of gnulib-related stuff. */
114 121
115#ifndef HAVE_SETPGID 122#define emacs_raise(sig) msdos_fatal_signal (sig)
116# ifdef USG
117# define setpgid(pid, pgid) setpgrp ()
118# else
119# define setpgid(pid, pgid) setpgrp (pid, pgid)
120# endif
121#endif
122 123
123/* Define one of these for easier conditionals. */ 124/* Define one of these for easier conditionals. */
124#ifdef HAVE_X_WINDOWS 125#ifdef HAVE_X_WINDOWS
diff --git a/src/data.c b/src/data.c
index abcdd4dca0d..09899400b68 100644
--- a/src/data.c
+++ b/src/data.c
@@ -81,6 +81,7 @@ Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
81static Lisp_Object Qdefun; 81static Lisp_Object Qdefun;
82 82
83Lisp_Object Qinteractive_form; 83Lisp_Object Qinteractive_form;
84static Lisp_Object Qdefalias_fset_function;
84 85
85static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); 86static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *);
86 87
@@ -444,7 +445,7 @@ DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
444} 445}
445 446
446 447
447/* Extract and set components of lists */ 448/* Extract and set components of lists. */
448 449
449DEFUN ("car", Fcar, Scar, 1, 1, 0, 450DEFUN ("car", Fcar, Scar, 1, 1, 0,
450 doc: /* Return the car of LIST. If arg is nil, return nil. 451 doc: /* Return the car of LIST. If arg is nil, return nil.
@@ -608,27 +609,18 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
608 (register Lisp_Object symbol, Lisp_Object definition) 609 (register Lisp_Object symbol, Lisp_Object definition)
609{ 610{
610 register Lisp_Object function; 611 register Lisp_Object function;
611
612 CHECK_SYMBOL (symbol); 612 CHECK_SYMBOL (symbol);
613 if (NILP (symbol) || EQ (symbol, Qt))
614 xsignal1 (Qsetting_constant, symbol);
615 613
616 function = XSYMBOL (symbol)->function; 614 function = XSYMBOL (symbol)->function;
617 615
618 if (!NILP (Vautoload_queue) && !EQ (function, Qunbound)) 616 if (!NILP (Vautoload_queue) && !EQ (function, Qunbound))
619 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); 617 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue);
620 618
621 if (CONSP (function) && EQ (XCAR (function), Qautoload)) 619 if (AUTOLOADP (function))
622 Fput (symbol, Qautoload, XCDR (function)); 620 Fput (symbol, Qautoload, XCDR (function));
623 621
624 set_symbol_function (symbol, definition); 622 set_symbol_function (symbol, definition);
625 /* Handle automatic advice activation. */ 623
626 if (CONSP (XSYMBOL (symbol)->plist)
627 && !NILP (Fget (symbol, Qad_advice_info)))
628 {
629 call2 (Qad_activate_internal, symbol, Qnil);
630 definition = XSYMBOL (symbol)->function;
631 }
632 return definition; 624 return definition;
633} 625}
634 626
@@ -642,15 +634,32 @@ The return value is undefined. */)
642 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) 634 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring)
643{ 635{
644 CHECK_SYMBOL (symbol); 636 CHECK_SYMBOL (symbol);
645 if (CONSP (XSYMBOL (symbol)->function)
646 && EQ (XCAR (XSYMBOL (symbol)->function), Qautoload))
647 LOADHIST_ATTACH (Fcons (Qt, symbol));
648 if (!NILP (Vpurify_flag) 637 if (!NILP (Vpurify_flag)
649 /* If `definition' is a keymap, immutable (and copying) is wrong. */ 638 /* If `definition' is a keymap, immutable (and copying) is wrong. */
650 && !KEYMAPP (definition)) 639 && !KEYMAPP (definition))
651 definition = Fpurecopy (definition); 640 definition = Fpurecopy (definition);
652 definition = Ffset (symbol, definition); 641
653 LOADHIST_ATTACH (Fcons (Qdefun, symbol)); 642 {
643 bool autoload = AUTOLOADP (definition);
644 if (NILP (Vpurify_flag) || !autoload)
645 { /* Only add autoload entries after dumping, because the ones before are
646 not useful and else we get loads of them from the loaddefs.el. */
647
648 if (AUTOLOADP (XSYMBOL (symbol)->function))
649 /* Remember that the function was already an autoload. */
650 LOADHIST_ATTACH (Fcons (Qt, symbol));
651 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
652 }
653 }
654
655 { /* Handle automatic advice activation. */
656 Lisp_Object hook = Fget (symbol, Qdefalias_fset_function);
657 if (!NILP (hook))
658 call2 (hook, symbol, definition);
659 else
660 Ffset (symbol, definition);
661 }
662
654 if (!NILP (docstring)) 663 if (!NILP (docstring))
655 Fput (symbol, Qfunction_documentation, docstring); 664 Fput (symbol, Qfunction_documentation, docstring);
656 /* We used to return `definition', but now that `defun' and `defmacro' expand 665 /* We used to return `definition', but now that `defun' and `defmacro' expand
@@ -680,12 +689,10 @@ function with `&rest' args, or `unevalled' for a special form. */)
680 CHECK_SUBR (subr); 689 CHECK_SUBR (subr);
681 minargs = XSUBR (subr)->min_args; 690 minargs = XSUBR (subr)->min_args;
682 maxargs = XSUBR (subr)->max_args; 691 maxargs = XSUBR (subr)->max_args;
683 if (maxargs == MANY) 692 return Fcons (make_number (minargs),
684 return Fcons (make_number (minargs), Qmany); 693 maxargs == MANY ? Qmany
685 else if (maxargs == UNEVALLED) 694 : maxargs == UNEVALLED ? Qunevalled
686 return Fcons (make_number (minargs), Qunevalled); 695 : make_number (maxargs));
687 else
688 return Fcons (make_number (minargs), make_number (maxargs));
689} 696}
690 697
691DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0, 698DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0,
@@ -711,7 +718,7 @@ Value, if non-nil, is a list \(interactive SPEC). */)
711 return Qnil; 718 return Qnil;
712 719
713 /* Use an `interactive-form' property if present, analogous to the 720 /* Use an `interactive-form' property if present, analogous to the
714 function-documentation property. */ 721 function-documentation property. */
715 fun = cmd; 722 fun = cmd;
716 while (SYMBOLP (fun)) 723 while (SYMBOLP (fun))
717 { 724 {
@@ -735,6 +742,8 @@ Value, if non-nil, is a list \(interactive SPEC). */)
735 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE) 742 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE)
736 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE)); 743 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE));
737 } 744 }
745 else if (AUTOLOADP (fun))
746 return Finteractive_form (Fautoload_do_load (fun, cmd, Qnil));
738 else if (CONSP (fun)) 747 else if (CONSP (fun))
739 { 748 {
740 Lisp_Object funcar = XCAR (fun); 749 Lisp_Object funcar = XCAR (fun);
@@ -742,14 +751,6 @@ Value, if non-nil, is a list \(interactive SPEC). */)
742 return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); 751 return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun))));
743 else if (EQ (funcar, Qlambda)) 752 else if (EQ (funcar, Qlambda))
744 return Fassq (Qinteractive, Fcdr (XCDR (fun))); 753 return Fassq (Qinteractive, Fcdr (XCDR (fun)));
745 else if (EQ (funcar, Qautoload))
746 {
747 struct gcpro gcpro1;
748 GCPRO1 (cmd);
749 Fautoload_do_load (fun, cmd, Qnil);
750 UNGCPRO;
751 return Finteractive_form (cmd);
752 }
753 } 754 }
754 return Qnil; 755 return Qnil;
755} 756}
@@ -2695,10 +2696,10 @@ usage: (* &rest NUMBERS-OR-MARKERS) */)
2695 return arith_driver (Amult, nargs, args); 2696 return arith_driver (Amult, nargs, args);
2696} 2697}
2697 2698
2698DEFUN ("/", Fquo, Squo, 2, MANY, 0, 2699DEFUN ("/", Fquo, Squo, 1, MANY, 0,
2699 doc: /* Return first argument divided by all the remaining arguments. 2700 doc: /* Return first argument divided by all the remaining arguments.
2700The arguments must be numbers or markers. 2701The arguments must be numbers or markers.
2701usage: (/ DIVIDEND DIVISOR &rest DIVISORS) */) 2702usage: (/ DIVIDEND &rest DIVISORS) */)
2702 (ptrdiff_t nargs, Lisp_Object *args) 2703 (ptrdiff_t nargs, Lisp_Object *args)
2703{ 2704{
2704 ptrdiff_t argnum; 2705 ptrdiff_t argnum;
@@ -3063,6 +3064,7 @@ syms_of_data (void)
3063 DEFSYM (Qfont_object, "font-object"); 3064 DEFSYM (Qfont_object, "font-object");
3064 3065
3065 DEFSYM (Qinteractive_form, "interactive-form"); 3066 DEFSYM (Qinteractive_form, "interactive-form");
3067 DEFSYM (Qdefalias_fset_function, "defalias-fset-function");
3066 3068
3067 defsubr (&Sindirect_variable); 3069 defsubr (&Sindirect_variable);
3068 defsubr (&Sinteractive_form); 3070 defsubr (&Sinteractive_form);
diff --git a/src/dispnew.c b/src/dispnew.c
index 9f0e22fcdcb..675c06c22e9 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -53,9 +53,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
53#include "systime.h" 53#include "systime.h"
54#include <errno.h> 54#include <errno.h>
55 55
56#ifdef DISPNEW_NEEDS_STDIO_EXT 56#include <fpending.h>
57#include <stdio_ext.h>
58#endif
59 57
60#if defined (HAVE_TERM_H) && defined (GNU_LINUX) 58#if defined (HAVE_TERM_H) && defined (GNU_LINUX)
61#include <term.h> /* for tgetent */ 59#include <term.h> /* for tgetent */
@@ -143,10 +141,6 @@ struct frame *last_nonminibuf_frame;
143 141
144static bool delayed_size_change; 142static bool delayed_size_change;
145 143
146/* 1 means glyph initialization has been completed at startup. */
147
148static bool glyphs_initialized_initially_p;
149
150/* Updated window if != 0. Set by update_window. */ 144/* Updated window if != 0. Set by update_window. */
151 145
152struct window *updated_window; 146struct window *updated_window;
@@ -1852,43 +1846,6 @@ adjust_glyphs (struct frame *f)
1852 unblock_input (); 1846 unblock_input ();
1853} 1847}
1854 1848
1855
1856/* Adjust frame glyphs when Emacs is initialized.
1857
1858 To be called from init_display.
1859
1860 We need a glyph matrix because redraw will happen soon.
1861 Unfortunately, window sizes on selected_frame are not yet set to
1862 meaningful values. I believe we can assume that there are only two
1863 windows on the frame---the mini-buffer and the root window. Frame
1864 height and width seem to be correct so far. So, set the sizes of
1865 windows to estimated values. */
1866
1867static void
1868adjust_frame_glyphs_initially (void)
1869{
1870 struct frame *sf = SELECTED_FRAME ();
1871 struct window *root = XWINDOW (sf->root_window);
1872 struct window *mini = XWINDOW (root->next);
1873 int frame_lines = FRAME_LINES (sf);
1874 int frame_cols = FRAME_COLS (sf);
1875 int top_margin = FRAME_TOP_MARGIN (sf);
1876
1877 /* Do it for the root window. */
1878 wset_top_line (root, make_number (top_margin));
1879 wset_total_lines (root, make_number (frame_lines - 1 - top_margin));
1880 wset_total_cols (root, make_number (frame_cols));
1881
1882 /* Do it for the mini-buffer window. */
1883 wset_top_line (mini, make_number (frame_lines - 1));
1884 wset_total_lines (mini, make_number (1));
1885 wset_total_cols (mini, make_number (frame_cols));
1886
1887 adjust_frame_glyphs (sf);
1888 glyphs_initialized_initially_p = 1;
1889}
1890
1891
1892/* Allocate/reallocate glyph matrices of a single frame F. */ 1849/* Allocate/reallocate glyph matrices of a single frame F. */
1893 1850
1894static void 1851static void
@@ -3073,21 +3030,13 @@ window_to_frame_hpos (struct window *w, int hpos)
3073 Redrawing Frames 3030 Redrawing Frames
3074 **********************************************************************/ 3031 **********************************************************************/
3075 3032
3076DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0, 3033/* Redraw frame F. */
3077 doc: /* Clear frame FRAME and output again what is supposed to appear on it. */)
3078 (Lisp_Object frame)
3079{
3080 struct frame *f;
3081
3082 CHECK_LIVE_FRAME (frame);
3083 f = XFRAME (frame);
3084
3085 /* Ignore redraw requests, if frame has no glyphs yet.
3086 (Implementation note: It still has to be checked why we are
3087 called so early here). */
3088 if (!glyphs_initialized_initially_p)
3089 return Qnil;
3090 3034
3035void
3036redraw_frame (struct frame *f)
3037{
3038 /* Error if F has no glyphs. */
3039 eassert (f->glyphs_initialized_p);
3091 update_begin (f); 3040 update_begin (f);
3092#ifdef MSDOS 3041#ifdef MSDOS
3093 if (FRAME_MSDOS_P (f)) 3042 if (FRAME_MSDOS_P (f))
@@ -3104,22 +3053,17 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
3104 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); 3053 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3105 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1); 3054 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
3106 f->garbaged = 0; 3055 f->garbaged = 0;
3107 return Qnil;
3108} 3056}
3109 3057
3110 3058DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0,
3111/* Redraw frame F. This is nothing more than a call to the Lisp 3059 doc: /* Clear frame FRAME and output again what is supposed to appear on it.
3112 function redraw-frame. */ 3060If FRAME is omitted or nil, the selected frame is used. */)
3113 3061 (Lisp_Object frame)
3114void
3115redraw_frame (struct frame *f)
3116{ 3062{
3117 Lisp_Object frame; 3063 redraw_frame (decode_live_frame (frame));
3118 XSETFRAME (frame, f); 3064 return Qnil;
3119 Fredraw_frame (frame);
3120} 3065}
3121 3066
3122
3123DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "", 3067DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3124 doc: /* Clear and redisplay all visible frames. */) 3068 doc: /* Clear and redisplay all visible frames. */)
3125 (void) 3069 (void)
@@ -3128,7 +3072,7 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3128 3072
3129 FOR_EACH_FRAME (tail, frame) 3073 FOR_EACH_FRAME (tail, frame)
3130 if (FRAME_VISIBLE_P (XFRAME (frame))) 3074 if (FRAME_VISIBLE_P (XFRAME (frame)))
3131 Fredraw_frame (frame); 3075 redraw_frame (XFRAME (frame));
3132 3076
3133 return Qnil; 3077 return Qnil;
3134} 3078}
@@ -4647,24 +4591,10 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
4647 FILE *display_output = FRAME_TTY (f)->output; 4591 FILE *display_output = FRAME_TTY (f)->output;
4648 if (display_output) 4592 if (display_output)
4649 { 4593 {
4650 int outq = PENDING_OUTPUT_COUNT (display_output); 4594 ptrdiff_t outq = __fpending (display_output);
4651 if (outq > 900 4595 if (outq > 900
4652 || (outq > 20 && ((i - 1) % preempt_count == 0))) 4596 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4653 { 4597 fflush (display_output);
4654 fflush (display_output);
4655 if (preempt_count == 1)
4656 {
4657#ifdef EMACS_OUTQSIZE
4658 if (EMACS_OUTQSIZE (0, &outq) < 0)
4659 /* Probably not a tty. Ignore the error and reset
4660 the outq count. */
4661 outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output));
4662#endif
4663 outq *= 10;
4664 if (baud_rate <= outq && baud_rate > 0)
4665 sleep (outq / baud_rate);
4666 }
4667 }
4668 } 4598 }
4669 } 4599 }
4670 4600
@@ -6226,7 +6156,6 @@ init_display (void)
6226 So call tgetent. */ 6156 So call tgetent. */
6227 { char b[2044]; tgetent (b, "xterm");} 6157 { char b[2044]; tgetent (b, "xterm");}
6228#endif 6158#endif
6229 adjust_frame_glyphs_initially ();
6230 return; 6159 return;
6231 } 6160 }
6232#endif /* HAVE_X_WINDOWS */ 6161#endif /* HAVE_X_WINDOWS */
@@ -6236,7 +6165,6 @@ init_display (void)
6236 { 6165 {
6237 Vinitial_window_system = Qw32; 6166 Vinitial_window_system = Qw32;
6238 Vwindow_system_version = make_number (1); 6167 Vwindow_system_version = make_number (1);
6239 adjust_frame_glyphs_initially ();
6240 return; 6168 return;
6241 } 6169 }
6242#endif /* HAVE_NTGUI */ 6170#endif /* HAVE_NTGUI */
@@ -6250,7 +6178,6 @@ init_display (void)
6250 { 6178 {
6251 Vinitial_window_system = Qns; 6179 Vinitial_window_system = Qns;
6252 Vwindow_system_version = make_number (10); 6180 Vwindow_system_version = make_number (10);
6253 adjust_frame_glyphs_initially ();
6254 return; 6181 return;
6255 } 6182 }
6256#endif 6183#endif
@@ -6340,7 +6267,6 @@ init_display (void)
6340 fatal ("screen size %dx%d too big", width, height); 6267 fatal ("screen size %dx%d too big", width, height);
6341 } 6268 }
6342 6269
6343 adjust_frame_glyphs_initially ();
6344 calculate_costs (XFRAME (selected_frame)); 6270 calculate_costs (XFRAME (selected_frame));
6345 6271
6346 /* Set up faces of the initial terminal frame of a dumped Emacs. */ 6272 /* Set up faces of the initial terminal frame of a dumped Emacs. */
@@ -6375,15 +6301,7 @@ don't show a cursor. */)
6375 /* Don't change cursor state while redisplaying. This could confuse 6301 /* Don't change cursor state while redisplaying. This could confuse
6376 output routines. */ 6302 output routines. */
6377 if (!redisplaying_p) 6303 if (!redisplaying_p)
6378 { 6304 decode_any_window (window)->cursor_off_p = NILP (show);
6379 if (NILP (window))
6380 window = selected_window;
6381 else
6382 CHECK_WINDOW (window);
6383
6384 XWINDOW (window)->cursor_off_p = NILP (show);
6385 }
6386
6387 return Qnil; 6305 return Qnil;
6388} 6306}
6389 6307
@@ -6394,15 +6312,7 @@ DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
6394WINDOW nil or omitted means report on the selected window. */) 6312WINDOW nil or omitted means report on the selected window. */)
6395 (Lisp_Object window) 6313 (Lisp_Object window)
6396{ 6314{
6397 struct window *w; 6315 return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
6398
6399 if (NILP (window))
6400 window = selected_window;
6401 else
6402 CHECK_WINDOW (window);
6403
6404 w = XWINDOW (window);
6405 return w->cursor_off_p ? Qnil : Qt;
6406} 6316}
6407 6317
6408DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame, 6318DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
diff --git a/src/doc.c b/src/doc.c
index 9ead1addfba..1d3d1e64442 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -21,7 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22 22
23#include <sys/types.h> 23#include <sys/types.h>
24#include <sys/file.h> /* Must be after sys/types.h for USG*/ 24#include <sys/file.h> /* Must be after sys/types.h for USG. */
25#include <fcntl.h> 25#include <fcntl.h>
26#include <unistd.h> 26#include <unistd.h>
27 27
@@ -42,7 +42,7 @@ static ptrdiff_t get_doc_string_buffer_size;
42 42
43static unsigned char *read_bytecode_pointer; 43static unsigned char *read_bytecode_pointer;
44 44
45/* readchar in lread.c calls back here to fetch the next byte. 45/* `readchar' in lread.c calls back here to fetch the next byte.
46 If UNREADFLAG is 1, we unread a byte. */ 46 If UNREADFLAG is 1, we unread a byte. */
47 47
48int 48int
@@ -338,15 +338,9 @@ string is passed through `substitute-command-keys'. */)
338 338
339 doc = Qnil; 339 doc = Qnil;
340 340
341 if (SYMBOLP (function))
342 {
343 Lisp_Object tem = Fget (function, Qfunction_documentation);
344 if (!NILP (tem))
345 return Fdocumentation_property (function, Qfunction_documentation,
346 raw);
347 }
348
349 fun = Findirect_function (function, Qnil); 341 fun = Findirect_function (function, Qnil);
342 if (CONSP (fun) && EQ (XCAR (fun), Qmacro))
343 fun = XCDR (fun);
350 if (SUBRP (fun)) 344 if (SUBRP (fun))
351 { 345 {
352 if (XSUBR (fun)->doc == 0) 346 if (XSUBR (fun)->doc == 0)
@@ -400,8 +394,6 @@ string is passed through `substitute-command-keys'. */)
400 else 394 else
401 return Qnil; 395 return Qnil;
402 } 396 }
403 else if (EQ (funcar, Qmacro))
404 return Fdocumentation (Fcdr (fun), raw);
405 else 397 else
406 goto oops; 398 goto oops;
407 } 399 }
@@ -411,16 +403,19 @@ string is passed through `substitute-command-keys'. */)
411 xsignal1 (Qinvalid_function, fun); 403 xsignal1 (Qinvalid_function, fun);
412 } 404 }
413 405
414 /* Check for an advised function. Its doc string 406 /* Check for a dynamic docstring. These come with
415 has an `ad-advice-info' text property. */ 407 a dynamic-docstring-function text property. */
416 if (STRINGP (doc)) 408 if (STRINGP (doc))
417 { 409 {
418 Lisp_Object innerfunc; 410 Lisp_Object func
419 innerfunc = Fget_text_property (make_number (0), 411 = Fget_text_property (make_number (0),
420 intern ("ad-advice-info"), 412 intern ("dynamic-docstring-function"),
421 doc); 413 doc);
422 if (! NILP (innerfunc)) 414 if (!NILP (func))
423 doc = call1 (intern ("ad-make-advised-docstring"), innerfunc); 415 /* Pass both `doc' and `function' since `function' can be needed, and
416 finding `doc' can be annoying: calling `documentation' is not an
417 option because it would infloop. */
418 doc = call2 (func, doc, function);
424 } 419 }
425 420
426 /* If DOC is 0, it's typically because of a dumped file missing 421 /* If DOC is 0, it's typically because of a dumped file missing
@@ -528,6 +523,8 @@ store_function_docstring (Lisp_Object obj, ptrdiff_t offset)
528 { 523 {
529 tem = Fcdr (Fcdr (fun)); 524 tem = Fcdr (Fcdr (fun));
530 if (CONSP (tem) && INTEGERP (XCAR (tem))) 525 if (CONSP (tem) && INTEGERP (XCAR (tem)))
526 /* FIXME: This modifies typically pure hash-cons'd data, so its
527 correctness is quite delicate. */
531 XSETCAR (tem, make_number (offset)); 528 XSETCAR (tem, make_number (offset));
532 } 529 }
533 else if (EQ (tem, Qmacro)) 530 else if (EQ (tem, Qmacro))
diff --git a/src/emacs.c b/src/emacs.c
index 0004af359d2..1afc7c189df 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
27#include <sys/file.h> 27#include <sys/file.h>
28#include <unistd.h> 28#include <unistd.h>
29 29
30#include <close-stream.h>
30#include <ignore-value.h> 31#include <ignore-value.h>
31 32
32#include "lisp.h" 33#include "lisp.h"
@@ -675,6 +676,22 @@ void (*__malloc_initialize_hook) (void) EXTERNALLY_VISIBLE = malloc_initialize_h
675 676
676#endif /* DOUG_LEA_MALLOC */ 677#endif /* DOUG_LEA_MALLOC */
677 678
679/* Close standard output and standard error, reporting any write
680 errors as best we can. This is intended for use with atexit. */
681static void
682close_output_streams (void)
683{
684 if (close_stream (stdout) != 0)
685 {
686 fprintf (stderr, "Write error to standard output: %s\n",
687 strerror (errno));
688 fflush (stderr);
689 _exit (EXIT_FAILURE);
690 }
691
692 if (close_stream (stderr) != 0)
693 _exit (EXIT_FAILURE);
694}
678 695
679/* ARGSUSED */ 696/* ARGSUSED */
680int 697int
@@ -731,6 +748,8 @@ main (int argc, char **argv)
731 unexec_init_emacs_zone (); 748 unexec_init_emacs_zone ();
732#endif 749#endif
733 750
751 atexit (close_output_streams);
752
734 sort_args (argc, argv); 753 sort_args (argc, argv);
735 argc = 0; 754 argc = 0;
736 while (argv[argc]) argc++; 755 while (argv[argc]) argc++;
@@ -1082,9 +1101,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1082 that it is not accessible to programs started from .emacs. */ 1101 that it is not accessible to programs started from .emacs. */
1083 fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC); 1102 fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC);
1084 1103
1085#ifdef HAVE_SETSID
1086 setsid (); 1104 setsid ();
1087#endif
1088#else /* DOS_NT */ 1105#else /* DOS_NT */
1089 fprintf (stderr, "This platform does not support the -daemon flag.\n"); 1106 fprintf (stderr, "This platform does not support the -daemon flag.\n");
1090 exit (1); 1107 exit (1);
@@ -1137,6 +1154,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1137 1154
1138 /* Called before syms_of_fileio, because it sets up Qerror_condition. */ 1155 /* Called before syms_of_fileio, because it sets up Qerror_condition. */
1139 syms_of_data (); 1156 syms_of_data ();
1157 syms_of_fns (); /* Before syms_of_charset which uses hashtables. */
1140 syms_of_fileio (); 1158 syms_of_fileio ();
1141 /* Before syms_of_coding to initialize Vgc_cons_threshold. */ 1159 /* Before syms_of_coding to initialize Vgc_cons_threshold. */
1142 syms_of_alloc (); 1160 syms_of_alloc ();
@@ -1148,7 +1166,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1148 1166
1149 init_window_once (); /* Init the window system. */ 1167 init_window_once (); /* Init the window system. */
1150#ifdef HAVE_WINDOW_SYSTEM 1168#ifdef HAVE_WINDOW_SYSTEM
1151 init_fringe_once (); /* Swap bitmaps if necessary. */ 1169 init_fringe_once (); /* Swap bitmaps if necessary. */
1152#endif /* HAVE_WINDOW_SYSTEM */ 1170#endif /* HAVE_WINDOW_SYSTEM */
1153 } 1171 }
1154 1172
@@ -1332,7 +1350,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1332 syms_of_lread (); 1350 syms_of_lread ();
1333 syms_of_print (); 1351 syms_of_print ();
1334 syms_of_eval (); 1352 syms_of_eval ();
1335 syms_of_fns ();
1336 syms_of_floatfns (); 1353 syms_of_floatfns ();
1337 1354
1338 syms_of_buffer (); 1355 syms_of_buffer ();
@@ -1869,8 +1886,6 @@ all of which are called before Emacs is actually killed. */)
1869 exit_code = (XINT (arg) < 0 1886 exit_code = (XINT (arg) < 0
1870 ? XINT (arg) | INT_MIN 1887 ? XINT (arg) | INT_MIN
1871 : XINT (arg) & INT_MAX); 1888 : XINT (arg) & INT_MAX);
1872 else if (noninteractive && (fflush (stdout) || ferror (stdout)))
1873 exit_code = EXIT_FAILURE;
1874 else 1889 else
1875 exit_code = EXIT_SUCCESS; 1890 exit_code = EXIT_SUCCESS;
1876 exit (exit_code); 1891 exit (exit_code);
@@ -1900,7 +1915,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
1900 /* If we are controlling the terminal, reset terminal modes. */ 1915 /* If we are controlling the terminal, reset terminal modes. */
1901#ifndef DOS_NT 1916#ifndef DOS_NT
1902 { 1917 {
1903 pid_t pgrp = EMACS_GETPGRP (0); 1918 pid_t pgrp = getpgrp ();
1904 pid_t tpgrp = tcgetpgrp (0); 1919 pid_t tpgrp = tcgetpgrp (0);
1905 if ((tpgrp != -1) && tpgrp == pgrp) 1920 if ((tpgrp != -1) && tpgrp == pgrp)
1906 { 1921 {
diff --git a/src/eval.c b/src/eval.c
index 975204da017..dcd48cb7250 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1876,26 +1876,19 @@ this does nothing and returns nil. */)
1876 CHECK_STRING (file); 1876 CHECK_STRING (file);
1877 1877
1878 /* If function is defined and not as an autoload, don't override. */ 1878 /* If function is defined and not as an autoload, don't override. */
1879 if ((CONSP (XSYMBOL (function)->function) 1879 if (!EQ (XSYMBOL (function)->function, Qunbound)
1880 && EQ (XCAR (XSYMBOL (function)->function), Qautoload))) 1880 && !AUTOLOADP (XSYMBOL (function)->function))
1881 /* Remember that the function was already an autoload. */
1882 LOADHIST_ATTACH (Fcons (Qt, function));
1883 else if (!EQ (XSYMBOL (function)->function, Qunbound))
1884 return Qnil; 1881 return Qnil;
1885 1882
1886 if (NILP (Vpurify_flag)) 1883 if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0)))
1887 /* Only add entries after dumping, because the ones before are
1888 not useful and else we get loads of them from the loaddefs.el. */
1889 LOADHIST_ATTACH (Fcons (Qautoload, function));
1890 else if (EQ (docstring, make_number (0)))
1891 /* `read1' in lread.c has found the docstring starting with "\ 1884 /* `read1' in lread.c has found the docstring starting with "\
1892 and assumed the docstring will be provided by Snarf-documentation, so it 1885 and assumed the docstring will be provided by Snarf-documentation, so it
1893 passed us 0 instead. But that leads to accidental sharing in purecopy's 1886 passed us 0 instead. But that leads to accidental sharing in purecopy's
1894 hash-consing, so we use a (hopefully) unique integer instead. */ 1887 hash-consing, so we use a (hopefully) unique integer instead. */
1895 docstring = make_number (XUNTAG (function, Lisp_Symbol)); 1888 docstring = make_number (XHASH (function));
1896 return Ffset (function, 1889 return Fdefalias (function,
1897 Fpurecopy (list5 (Qautoload, file, docstring, 1890 list5 (Qautoload, file, docstring, interactive, type),
1898 interactive, type))); 1891 Qnil);
1899} 1892}
1900 1893
1901Lisp_Object 1894Lisp_Object
diff --git a/src/fileio.c b/src/fileio.c
index d47d7dd9e0b..b9541e78838 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5076,7 +5076,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5076 struct stat st; 5076 struct stat st;
5077 Lisp_Object handler; 5077 Lisp_Object handler;
5078 Lisp_Object filename; 5078 Lisp_Object filename;
5079 EMACS_TIME mtime, diff; 5079 EMACS_TIME mtime;
5080 5080
5081 if (NILP (buf)) 5081 if (NILP (buf))
5082 b = current_buffer; 5082 b = current_buffer;
@@ -5101,13 +5101,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5101 mtime = (stat (SSDATA (filename), &st) == 0 5101 mtime = (stat (SSDATA (filename), &st) == 0
5102 ? get_stat_mtime (&st) 5102 ? get_stat_mtime (&st)
5103 : time_error_value (errno)); 5103 : time_error_value (errno));
5104 if ((EMACS_TIME_EQ (mtime, b->modtime) 5104 if (EMACS_TIME_EQ (mtime, b->modtime)
5105 /* If both exist, accept them if they are off by one second. */
5106 || (EMACS_TIME_VALID_P (mtime) && EMACS_TIME_VALID_P (b->modtime)
5107 && ((diff = (EMACS_TIME_LT (mtime, b->modtime)
5108 ? sub_emacs_time (b->modtime, mtime)
5109 : sub_emacs_time (mtime, b->modtime))),
5110 EMACS_TIME_LE (diff, make_emacs_time (1, 0)))))
5111 && (st.st_size == b->modtime_size 5105 && (st.st_size == b->modtime_size
5112 || b->modtime_size < 0)) 5106 || b->modtime_size < 0))
5113 return Qt; 5107 return Qt;
diff --git a/src/fns.c b/src/fns.c
index b1ba5ce9509..7c2222e9805 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2014,7 +2014,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
2014 d1 = extract_float (o1); 2014 d1 = extract_float (o1);
2015 d2 = extract_float (o2); 2015 d2 = extract_float (o2);
2016 /* If d is a NaN, then d != d. Two NaNs should be `equal' even 2016 /* If d is a NaN, then d != d. Two NaNs should be `equal' even
2017 though they are not =. */ 2017 though they are not =. */
2018 return d1 == d2 || (d1 != d1 && d2 != d2); 2018 return d1 == d2 || (d1 != d1 && d2 != d2);
2019 } 2019 }
2020 2020
@@ -2076,9 +2076,8 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
2076 are sensible to compare, so eliminate the others now. */ 2076 are sensible to compare, so eliminate the others now. */
2077 if (size & PSEUDOVECTOR_FLAG) 2077 if (size & PSEUDOVECTOR_FLAG)
2078 { 2078 {
2079 if (!(size & ((PVEC_COMPILED | PVEC_CHAR_TABLE 2079 if (((size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
2080 | PVEC_SUB_CHAR_TABLE | PVEC_FONT) 2080 < PVEC_COMPILED)
2081 << PSEUDOVECTOR_SIZE_BITS)))
2082 return 0; 2081 return 0;
2083 size &= PSEUDOVECTOR_SIZE_MASK; 2082 size &= PSEUDOVECTOR_SIZE_MASK;
2084 } 2083 }
@@ -3332,8 +3331,8 @@ static struct Lisp_Hash_Table *weak_hash_tables;
3332 3331
3333/* Various symbols. */ 3332/* Various symbols. */
3334 3333
3335static Lisp_Object Qhash_table_p, Qkey, Qvalue; 3334static Lisp_Object Qhash_table_p, Qkey, Qvalue, Qeql;
3336Lisp_Object Qeq, Qeql, Qequal; 3335Lisp_Object Qeq, Qequal;
3337Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness; 3336Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
3338static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value; 3337static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
3339 3338
@@ -3425,14 +3424,17 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
3425 Low-level Functions 3424 Low-level Functions
3426 ***********************************************************************/ 3425 ***********************************************************************/
3427 3426
3427static struct hash_table_test hashtest_eq;
3428struct hash_table_test hashtest_eql, hashtest_equal;
3429
3428/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code 3430/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
3429 HASH2 in hash table H using `eql'. Value is true if KEY1 and 3431 HASH2 in hash table H using `eql'. Value is true if KEY1 and
3430 KEY2 are the same. */ 3432 KEY2 are the same. */
3431 3433
3432static bool 3434static bool
3433cmpfn_eql (struct Lisp_Hash_Table *h, 3435cmpfn_eql (struct hash_table_test *ht,
3434 Lisp_Object key1, EMACS_UINT hash1, 3436 Lisp_Object key1,
3435 Lisp_Object key2, EMACS_UINT hash2) 3437 Lisp_Object key2)
3436{ 3438{
3437 return (FLOATP (key1) 3439 return (FLOATP (key1)
3438 && FLOATP (key2) 3440 && FLOATP (key2)
@@ -3445,11 +3447,11 @@ cmpfn_eql (struct Lisp_Hash_Table *h,
3445 KEY2 are the same. */ 3447 KEY2 are the same. */
3446 3448
3447static bool 3449static bool
3448cmpfn_equal (struct Lisp_Hash_Table *h, 3450cmpfn_equal (struct hash_table_test *ht,
3449 Lisp_Object key1, EMACS_UINT hash1, 3451 Lisp_Object key1,
3450 Lisp_Object key2, EMACS_UINT hash2) 3452 Lisp_Object key2)
3451{ 3453{
3452 return hash1 == hash2 && !NILP (Fequal (key1, key2)); 3454 return !NILP (Fequal (key1, key2));
3453} 3455}
3454 3456
3455 3457
@@ -3458,21 +3460,16 @@ cmpfn_equal (struct Lisp_Hash_Table *h,
3458 if KEY1 and KEY2 are the same. */ 3460 if KEY1 and KEY2 are the same. */
3459 3461
3460static bool 3462static bool
3461cmpfn_user_defined (struct Lisp_Hash_Table *h, 3463cmpfn_user_defined (struct hash_table_test *ht,
3462 Lisp_Object key1, EMACS_UINT hash1, 3464 Lisp_Object key1,
3463 Lisp_Object key2, EMACS_UINT hash2) 3465 Lisp_Object key2)
3464{ 3466{
3465 if (hash1 == hash2) 3467 Lisp_Object args[3];
3466 {
3467 Lisp_Object args[3];
3468 3468
3469 args[0] = h->user_cmp_function; 3469 args[0] = ht->user_cmp_function;
3470 args[1] = key1; 3470 args[1] = key1;
3471 args[2] = key2; 3471 args[2] = key2;
3472 return !NILP (Ffuncall (3, args)); 3472 return !NILP (Ffuncall (3, args));
3473 }
3474 else
3475 return 0;
3476} 3473}
3477 3474
3478 3475
@@ -3481,54 +3478,48 @@ cmpfn_user_defined (struct Lisp_Hash_Table *h,
3481 in a Lisp integer. */ 3478 in a Lisp integer. */
3482 3479
3483static EMACS_UINT 3480static EMACS_UINT
3484hashfn_eq (struct Lisp_Hash_Table *h, Lisp_Object key) 3481hashfn_eq (struct hash_table_test *ht, Lisp_Object key)
3485{ 3482{
3486 EMACS_UINT hash = XUINT (key) ^ XTYPE (key); 3483 EMACS_UINT hash = XHASH (key) ^ XTYPE (key);
3487 eassert ((hash & ~INTMASK) == 0);
3488 return hash; 3484 return hash;
3489} 3485}
3490 3486
3491
3492/* Value is a hash code for KEY for use in hash table H which uses 3487/* Value is a hash code for KEY for use in hash table H which uses
3493 `eql' to compare keys. The hash code returned is guaranteed to fit 3488 `eql' to compare keys. The hash code returned is guaranteed to fit
3494 in a Lisp integer. */ 3489 in a Lisp integer. */
3495 3490
3496static EMACS_UINT 3491static EMACS_UINT
3497hashfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key) 3492hashfn_eql (struct hash_table_test *ht, Lisp_Object key)
3498{ 3493{
3499 EMACS_UINT hash; 3494 EMACS_UINT hash;
3500 if (FLOATP (key)) 3495 if (FLOATP (key))
3501 hash = sxhash (key, 0); 3496 hash = sxhash (key, 0);
3502 else 3497 else
3503 hash = XUINT (key) ^ XTYPE (key); 3498 hash = XHASH (key) ^ XTYPE (key);
3504 eassert ((hash & ~INTMASK) == 0);
3505 return hash; 3499 return hash;
3506} 3500}
3507 3501
3508
3509/* Value is a hash code for KEY for use in hash table H which uses 3502/* Value is a hash code for KEY for use in hash table H which uses
3510 `equal' to compare keys. The hash code returned is guaranteed to fit 3503 `equal' to compare keys. The hash code returned is guaranteed to fit
3511 in a Lisp integer. */ 3504 in a Lisp integer. */
3512 3505
3513static EMACS_UINT 3506static EMACS_UINT
3514hashfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key) 3507hashfn_equal (struct hash_table_test *ht, Lisp_Object key)
3515{ 3508{
3516 EMACS_UINT hash = sxhash (key, 0); 3509 EMACS_UINT hash = sxhash (key, 0);
3517 eassert ((hash & ~INTMASK) == 0);
3518 return hash; 3510 return hash;
3519} 3511}
3520 3512
3521
3522/* Value is a hash code for KEY for use in hash table H which uses as 3513/* Value is a hash code for KEY for use in hash table H which uses as
3523 user-defined function to compare keys. The hash code returned is 3514 user-defined function to compare keys. The hash code returned is
3524 guaranteed to fit in a Lisp integer. */ 3515 guaranteed to fit in a Lisp integer. */
3525 3516
3526static EMACS_UINT 3517static EMACS_UINT
3527hashfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key) 3518hashfn_user_defined (struct hash_table_test *ht, Lisp_Object key)
3528{ 3519{
3529 Lisp_Object args[2], hash; 3520 Lisp_Object args[2], hash;
3530 3521
3531 args[0] = h->user_hash_function; 3522 args[0] = ht->user_hash_function;
3532 args[1] = key; 3523 args[1] = key;
3533 hash = Ffuncall (2, args); 3524 hash = Ffuncall (2, args);
3534 if (!INTEGERP (hash)) 3525 if (!INTEGERP (hash))
@@ -3564,9 +3555,9 @@ hashfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key)
3564 one of the symbols `key', `value', `key-or-value', or `key-and-value'. */ 3555 one of the symbols `key', `value', `key-or-value', or `key-and-value'. */
3565 3556
3566Lisp_Object 3557Lisp_Object
3567make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size, 3558make_hash_table (struct hash_table_test test,
3568 Lisp_Object rehash_threshold, Lisp_Object weak, 3559 Lisp_Object size, Lisp_Object rehash_size,
3569 Lisp_Object user_test, Lisp_Object user_hash) 3560 Lisp_Object rehash_threshold, Lisp_Object weak)
3570{ 3561{
3571 struct Lisp_Hash_Table *h; 3562 struct Lisp_Hash_Table *h;
3572 Lisp_Object table; 3563 Lisp_Object table;
@@ -3575,7 +3566,7 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size,
3575 double index_float; 3566 double index_float;
3576 3567
3577 /* Preconditions. */ 3568 /* Preconditions. */
3578 eassert (SYMBOLP (test)); 3569 eassert (SYMBOLP (test.name));
3579 eassert (INTEGERP (size) && XINT (size) >= 0); 3570 eassert (INTEGERP (size) && XINT (size) >= 0);
3580 eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0) 3571 eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
3581 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size))); 3572 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
@@ -3599,29 +3590,6 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size,
3599 3590
3600 /* Initialize hash table slots. */ 3591 /* Initialize hash table slots. */
3601 h->test = test; 3592 h->test = test;
3602 if (EQ (test, Qeql))
3603 {
3604 h->cmpfn = cmpfn_eql;
3605 h->hashfn = hashfn_eql;
3606 }
3607 else if (EQ (test, Qeq))
3608 {
3609 h->cmpfn = NULL;
3610 h->hashfn = hashfn_eq;
3611 }
3612 else if (EQ (test, Qequal))
3613 {
3614 h->cmpfn = cmpfn_equal;
3615 h->hashfn = hashfn_equal;
3616 }
3617 else
3618 {
3619 h->user_cmp_function = user_test;
3620 h->user_hash_function = user_hash;
3621 h->cmpfn = cmpfn_user_defined;
3622 h->hashfn = hashfn_user_defined;
3623 }
3624
3625 h->weak = weak; 3593 h->weak = weak;
3626 h->rehash_threshold = rehash_threshold; 3594 h->rehash_threshold = rehash_threshold;
3627 h->rehash_size = rehash_size; 3595 h->rehash_size = rehash_size;
@@ -3661,12 +3629,9 @@ copy_hash_table (struct Lisp_Hash_Table *h1)
3661{ 3629{
3662 Lisp_Object table; 3630 Lisp_Object table;
3663 struct Lisp_Hash_Table *h2; 3631 struct Lisp_Hash_Table *h2;
3664 struct Lisp_Vector *next;
3665 3632
3666 h2 = allocate_hash_table (); 3633 h2 = allocate_hash_table ();
3667 next = h2->header.next.vector;
3668 *h2 = *h1; 3634 *h2 = *h1;
3669 h2->header.next.vector = next;
3670 h2->key_and_value = Fcopy_sequence (h1->key_and_value); 3635 h2->key_and_value = Fcopy_sequence (h1->key_and_value);
3671 h2->hash = Fcopy_sequence (h1->hash); 3636 h2->hash = Fcopy_sequence (h1->hash);
3672 h2->next = Fcopy_sequence (h1->next); 3637 h2->next = Fcopy_sequence (h1->next);
@@ -3780,7 +3745,8 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
3780 ptrdiff_t start_of_bucket; 3745 ptrdiff_t start_of_bucket;
3781 Lisp_Object idx; 3746 Lisp_Object idx;
3782 3747
3783 hash_code = h->hashfn (h, key); 3748 hash_code = h->test.hashfn (&h->test, key);
3749 eassert ((hash_code & ~INTMASK) == 0);
3784 if (hash) 3750 if (hash)
3785 *hash = hash_code; 3751 *hash = hash_code;
3786 3752
@@ -3792,9 +3758,9 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
3792 { 3758 {
3793 ptrdiff_t i = XFASTINT (idx); 3759 ptrdiff_t i = XFASTINT (idx);
3794 if (EQ (key, HASH_KEY (h, i)) 3760 if (EQ (key, HASH_KEY (h, i))
3795 || (h->cmpfn 3761 || (h->test.cmpfn
3796 && h->cmpfn (h, key, hash_code, 3762 && hash_code == XUINT (HASH_HASH (h, i))
3797 HASH_KEY (h, i), XUINT (HASH_HASH (h, i))))) 3763 && h->test.cmpfn (&h->test, key, HASH_KEY (h, i))))
3798 break; 3764 break;
3799 idx = HASH_NEXT (h, i); 3765 idx = HASH_NEXT (h, i);
3800 } 3766 }
@@ -3845,7 +3811,8 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
3845 ptrdiff_t start_of_bucket; 3811 ptrdiff_t start_of_bucket;
3846 Lisp_Object idx, prev; 3812 Lisp_Object idx, prev;
3847 3813
3848 hash_code = h->hashfn (h, key); 3814 hash_code = h->test.hashfn (&h->test, key);
3815 eassert ((hash_code & ~INTMASK) == 0);
3849 start_of_bucket = hash_code % ASIZE (h->index); 3816 start_of_bucket = hash_code % ASIZE (h->index);
3850 idx = HASH_INDEX (h, start_of_bucket); 3817 idx = HASH_INDEX (h, start_of_bucket);
3851 prev = Qnil; 3818 prev = Qnil;
@@ -3856,9 +3823,9 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
3856 ptrdiff_t i = XFASTINT (idx); 3823 ptrdiff_t i = XFASTINT (idx);
3857 3824
3858 if (EQ (key, HASH_KEY (h, i)) 3825 if (EQ (key, HASH_KEY (h, i))
3859 || (h->cmpfn 3826 || (h->test.cmpfn
3860 && h->cmpfn (h, key, hash_code, 3827 && hash_code == XUINT (HASH_HASH (h, i))
3861 HASH_KEY (h, i), XUINT (HASH_HASH (h, i))))) 3828 && h->test.cmpfn (&h->test, key, HASH_KEY (h, i))))
3862 { 3829 {
3863 /* Take entry out of collision chain. */ 3830 /* Take entry out of collision chain. */
3864 if (NILP (prev)) 3831 if (NILP (prev))
@@ -4070,13 +4037,6 @@ sweep_weak_hash_tables (void)
4070 4037
4071#define SXHASH_MAX_LEN 7 4038#define SXHASH_MAX_LEN 7
4072 4039
4073/* Combine two integers X and Y for hashing. The result might not fit
4074 into a Lisp integer. */
4075
4076#define SXHASH_COMBINE(X, Y) \
4077 ((((EMACS_UINT) (X) << 4) + ((EMACS_UINT) (X) >> (BITS_PER_EMACS_INT - 4))) \
4078 + (EMACS_UINT) (Y))
4079
4080/* Hash X, returning a value that fits into a Lisp integer. */ 4040/* Hash X, returning a value that fits into a Lisp integer. */
4081#define SXHASH_REDUCE(X) \ 4041#define SXHASH_REDUCE(X) \
4082 ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK) 4042 ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
@@ -4095,7 +4055,7 @@ hash_string (char const *ptr, ptrdiff_t len)
4095 while (p != end) 4055 while (p != end)
4096 { 4056 {
4097 c = *p++; 4057 c = *p++;
4098 hash = SXHASH_COMBINE (hash, c); 4058 hash = sxhash_combine (hash, c);
4099 } 4059 }
4100 4060
4101 return hash; 4061 return hash;
@@ -4129,7 +4089,7 @@ sxhash_float (double val)
4129 u.val = val; 4089 u.val = val;
4130 memset (&u.val + 1, 0, sizeof u - sizeof u.val); 4090 memset (&u.val + 1, 0, sizeof u - sizeof u.val);
4131 for (i = 0; i < WORDS_PER_DOUBLE; i++) 4091 for (i = 0; i < WORDS_PER_DOUBLE; i++)
4132 hash = SXHASH_COMBINE (hash, u.word[i]); 4092 hash = sxhash_combine (hash, u.word[i]);
4133 return SXHASH_REDUCE (hash); 4093 return SXHASH_REDUCE (hash);
4134} 4094}
4135 4095
@@ -4148,13 +4108,13 @@ sxhash_list (Lisp_Object list, int depth)
4148 list = XCDR (list), ++i) 4108 list = XCDR (list), ++i)
4149 { 4109 {
4150 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1); 4110 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1);
4151 hash = SXHASH_COMBINE (hash, hash2); 4111 hash = sxhash_combine (hash, hash2);
4152 } 4112 }
4153 4113
4154 if (!NILP (list)) 4114 if (!NILP (list))
4155 { 4115 {
4156 EMACS_UINT hash2 = sxhash (list, depth + 1); 4116 EMACS_UINT hash2 = sxhash (list, depth + 1);
4157 hash = SXHASH_COMBINE (hash, hash2); 4117 hash = sxhash_combine (hash, hash2);
4158 } 4118 }
4159 4119
4160 return SXHASH_REDUCE (hash); 4120 return SXHASH_REDUCE (hash);
@@ -4174,7 +4134,7 @@ sxhash_vector (Lisp_Object vec, int depth)
4174 for (i = 0; i < n; ++i) 4134 for (i = 0; i < n; ++i)
4175 { 4135 {
4176 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1); 4136 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1);
4177 hash = SXHASH_COMBINE (hash, hash2); 4137 hash = sxhash_combine (hash, hash2);
4178 } 4138 }
4179 4139
4180 return SXHASH_REDUCE (hash); 4140 return SXHASH_REDUCE (hash);
@@ -4190,7 +4150,7 @@ sxhash_bool_vector (Lisp_Object vec)
4190 4150
4191 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size); 4151 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size);
4192 for (i = 0; i < n; ++i) 4152 for (i = 0; i < n; ++i)
4193 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]); 4153 hash = sxhash_combine (hash, XBOOL_VECTOR (vec)->data[i]);
4194 4154
4195 return SXHASH_REDUCE (hash); 4155 return SXHASH_REDUCE (hash);
4196} 4156}
@@ -4214,7 +4174,7 @@ sxhash (Lisp_Object obj, int depth)
4214 break; 4174 break;
4215 4175
4216 case Lisp_Misc: 4176 case Lisp_Misc:
4217 hash = XUINT (obj); 4177 hash = XHASH (obj);
4218 break; 4178 break;
4219 4179
4220 case Lisp_Symbol: 4180 case Lisp_Symbol:
@@ -4238,7 +4198,7 @@ sxhash (Lisp_Object obj, int depth)
4238 else 4198 else
4239 /* Others are `equal' if they are `eq', so let's take their 4199 /* Others are `equal' if they are `eq', so let's take their
4240 address as hash. */ 4200 address as hash. */
4241 hash = XUINT (obj); 4201 hash = XHASH (obj);
4242 break; 4202 break;
4243 4203
4244 case Lisp_Cons: 4204 case Lisp_Cons:
@@ -4307,7 +4267,7 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4307 (ptrdiff_t nargs, Lisp_Object *args) 4267 (ptrdiff_t nargs, Lisp_Object *args)
4308{ 4268{
4309 Lisp_Object test, size, rehash_size, rehash_threshold, weak; 4269 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
4310 Lisp_Object user_test, user_hash; 4270 struct hash_table_test testdesc;
4311 char *used; 4271 char *used;
4312 ptrdiff_t i; 4272 ptrdiff_t i;
4313 4273
@@ -4319,7 +4279,13 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4319 /* See if there's a `:test TEST' among the arguments. */ 4279 /* See if there's a `:test TEST' among the arguments. */
4320 i = get_key_arg (QCtest, nargs, args, used); 4280 i = get_key_arg (QCtest, nargs, args, used);
4321 test = i ? args[i] : Qeql; 4281 test = i ? args[i] : Qeql;
4322 if (!EQ (test, Qeq) && !EQ (test, Qeql) && !EQ (test, Qequal)) 4282 if (EQ (test, Qeq))
4283 testdesc = hashtest_eq;
4284 else if (EQ (test, Qeql))
4285 testdesc = hashtest_eql;
4286 else if (EQ (test, Qequal))
4287 testdesc = hashtest_equal;
4288 else
4323 { 4289 {
4324 /* See if it is a user-defined test. */ 4290 /* See if it is a user-defined test. */
4325 Lisp_Object prop; 4291 Lisp_Object prop;
@@ -4327,11 +4293,12 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4327 prop = Fget (test, Qhash_table_test); 4293 prop = Fget (test, Qhash_table_test);
4328 if (!CONSP (prop) || !CONSP (XCDR (prop))) 4294 if (!CONSP (prop) || !CONSP (XCDR (prop)))
4329 signal_error ("Invalid hash table test", test); 4295 signal_error ("Invalid hash table test", test);
4330 user_test = XCAR (prop); 4296 testdesc.name = test;
4331 user_hash = XCAR (XCDR (prop)); 4297 testdesc.user_cmp_function = XCAR (prop);
4298 testdesc.user_hash_function = XCAR (XCDR (prop));
4299 testdesc.hashfn = hashfn_user_defined;
4300 testdesc.cmpfn = cmpfn_user_defined;
4332 } 4301 }
4333 else
4334 user_test = user_hash = Qnil;
4335 4302
4336 /* See if there's a `:size SIZE' argument. */ 4303 /* See if there's a `:size SIZE' argument. */
4337 i = get_key_arg (QCsize, nargs, args, used); 4304 i = get_key_arg (QCsize, nargs, args, used);
@@ -4373,8 +4340,7 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4373 if (!used[i]) 4340 if (!used[i])
4374 signal_error ("Invalid argument list", args[i]); 4341 signal_error ("Invalid argument list", args[i]);
4375 4342
4376 return make_hash_table (test, size, rehash_size, rehash_threshold, weak, 4343 return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak);
4377 user_test, user_hash);
4378} 4344}
4379 4345
4380 4346
@@ -4428,7 +4394,7 @@ DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0,
4428 doc: /* Return the test TABLE uses. */) 4394 doc: /* Return the test TABLE uses. */)
4429 (Lisp_Object table) 4395 (Lisp_Object table)
4430{ 4396{
4431 return check_hash_table (table)->test; 4397 return check_hash_table (table)->test.name;
4432} 4398}
4433 4399
4434 4400
@@ -4992,4 +4958,14 @@ this variable. */);
4992 defsubr (&Smd5); 4958 defsubr (&Smd5);
4993 defsubr (&Ssecure_hash); 4959 defsubr (&Ssecure_hash);
4994 defsubr (&Slocale_info); 4960 defsubr (&Slocale_info);
4961
4962 {
4963 struct hash_table_test
4964 eq = { Qeq, Qnil, Qnil, NULL, hashfn_eq },
4965 eql = { Qeql, Qnil, Qnil, cmpfn_eql, hashfn_eql },
4966 equal = { Qequal, Qnil, Qnil, cmpfn_equal, hashfn_equal };
4967 hashtest_eq = eq;
4968 hashtest_eql = eql;
4969 hashtest_equal = equal;
4970 }
4995} 4971}
diff --git a/src/font.c b/src/font.c
index e79ce5d80bc..41dbfd7a757 100644
--- a/src/font.c
+++ b/src/font.c
@@ -3993,16 +3993,11 @@ The optional argument FRAME specifies the frame that the face attributes
3993are to be displayed on. If omitted, the selected frame is used. */) 3993are to be displayed on. If omitted, the selected frame is used. */)
3994 (Lisp_Object font, Lisp_Object frame) 3994 (Lisp_Object font, Lisp_Object frame)
3995{ 3995{
3996 struct frame *f; 3996 struct frame *f = decode_live_frame (frame);
3997 Lisp_Object plist[10]; 3997 Lisp_Object plist[10];
3998 Lisp_Object val; 3998 Lisp_Object val;
3999 int n = 0; 3999 int n = 0;
4000 4000
4001 if (NILP (frame))
4002 frame = selected_frame;
4003 CHECK_LIVE_FRAME (frame);
4004 f = XFRAME (frame);
4005
4006 if (STRINGP (font)) 4001 if (STRINGP (font))
4007 { 4002 {
4008 int fontset = fs_query_fontset (font, 0); 4003 int fontset = fs_query_fontset (font, 0);
@@ -4152,18 +4147,15 @@ how close they are to PREFER. */)
4152 4147
4153DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0, 4148DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0,
4154 doc: /* List available font families on the current frame. 4149 doc: /* List available font families on the current frame.
4155Optional argument FRAME, if non-nil, specifies the target frame. */) 4150If FRAME is omitted or nil, the selected frame is used. */)
4156 (Lisp_Object frame) 4151 (Lisp_Object frame)
4157{ 4152{
4158 FRAME_PTR f; 4153 struct frame *f = decode_live_frame (frame);
4159 struct font_driver_list *driver_list; 4154 struct font_driver_list *driver_list;
4160 Lisp_Object list; 4155 Lisp_Object list = Qnil;
4156
4157 XSETFRAME (frame, f);
4161 4158
4162 if (NILP (frame))
4163 frame = selected_frame;
4164 CHECK_LIVE_FRAME (frame);
4165 f = XFRAME (frame);
4166 list = Qnil;
4167 for (driver_list = f->font_driver_list; driver_list; 4159 for (driver_list = f->font_driver_list; driver_list;
4168 driver_list = driver_list->next) 4160 driver_list = driver_list->next)
4169 if (driver_list->driver->list_family) 4161 if (driver_list->driver->list_family)
@@ -4531,11 +4523,9 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
4531 (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame) 4523 (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame)
4532{ 4524{
4533 EMACS_INT isize; 4525 EMACS_INT isize;
4526 struct frame *f = decode_live_frame (frame);
4534 4527
4535 CHECK_FONT_ENTITY (font_entity); 4528 CHECK_FONT_ENTITY (font_entity);
4536 if (NILP (frame))
4537 frame = selected_frame;
4538 CHECK_LIVE_FRAME (frame);
4539 4529
4540 if (NILP (size)) 4530 if (NILP (size))
4541 isize = XINT (AREF (font_entity, FONT_SIZE_INDEX)); 4531 isize = XINT (AREF (font_entity, FONT_SIZE_INDEX));
@@ -4543,7 +4533,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
4543 { 4533 {
4544 CHECK_NUMBER_OR_FLOAT (size); 4534 CHECK_NUMBER_OR_FLOAT (size);
4545 if (FLOATP (size)) 4535 if (FLOATP (size))
4546 isize = POINT_TO_PIXEL (XFLOAT_DATA (size), XFRAME (frame)->resy); 4536 isize = POINT_TO_PIXEL (XFLOAT_DATA (size), f->resy);
4547 else 4537 else
4548 isize = XINT (size); 4538 isize = XINT (size);
4549 if (! (INT_MIN <= isize && isize <= INT_MAX)) 4539 if (! (INT_MIN <= isize && isize <= INT_MAX))
@@ -4551,7 +4541,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
4551 if (isize == 0) 4541 if (isize == 0)
4552 isize = 120; 4542 isize = 120;
4553 } 4543 }
4554 return font_open_entity (XFRAME (frame), font_entity, isize); 4544 return font_open_entity (f, font_entity, isize);
4555} 4545}
4556 4546
4557DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0, 4547DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0,
@@ -4559,10 +4549,7 @@ DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0,
4559 (Lisp_Object font_object, Lisp_Object frame) 4549 (Lisp_Object font_object, Lisp_Object frame)
4560{ 4550{
4561 CHECK_FONT_OBJECT (font_object); 4551 CHECK_FONT_OBJECT (font_object);
4562 if (NILP (frame)) 4552 font_close_object (decode_live_frame (frame), font_object);
4563 frame = selected_frame;
4564 CHECK_LIVE_FRAME (frame);
4565 font_close_object (XFRAME (frame), font_object);
4566 return Qnil; 4553 return Qnil;
4567} 4554}
4568 4555
@@ -4765,13 +4752,8 @@ Optional third arg STRING, if non-nil, is a string containing the target
4765character at index specified by POSITION. */) 4752character at index specified by POSITION. */)
4766 (Lisp_Object position, Lisp_Object window, Lisp_Object string) 4753 (Lisp_Object position, Lisp_Object window, Lisp_Object string)
4767{ 4754{
4768 struct window *w; 4755 struct window *w = decode_live_window (window);
4769 ptrdiff_t pos;
4770 4756
4771 if (NILP (window))
4772 window = selected_window;
4773 CHECK_LIVE_WINDOW (window);
4774 w = XWINDOW (window);
4775 if (NILP (string)) 4757 if (NILP (string))
4776 { 4758 {
4777 if (XBUFFER (w->buffer) != current_buffer) 4759 if (XBUFFER (w->buffer) != current_buffer)
@@ -4779,7 +4761,6 @@ character at index specified by POSITION. */)
4779 CHECK_NUMBER_COERCE_MARKER (position); 4761 CHECK_NUMBER_COERCE_MARKER (position);
4780 if (! (BEGV <= XINT (position) && XINT (position) < ZV)) 4762 if (! (BEGV <= XINT (position) && XINT (position) < ZV))
4781 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); 4763 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
4782 pos = XINT (position);
4783 } 4764 }
4784 else 4765 else
4785 { 4766 {
@@ -4787,10 +4768,9 @@ character at index specified by POSITION. */)
4787 CHECK_STRING (string); 4768 CHECK_STRING (string);
4788 if (! (0 <= XINT (position) && XINT (position) < SCHARS (string))) 4769 if (! (0 <= XINT (position) && XINT (position) < SCHARS (string)))
4789 args_out_of_range (string, position); 4770 args_out_of_range (string, position);
4790 pos = XINT (position);
4791 } 4771 }
4792 4772
4793 return font_at (-1, pos, NULL, w, string); 4773 return font_at (-1, XINT (position), NULL, w, string);
4794} 4774}
4795 4775
4796#if 0 4776#if 0
@@ -4854,7 +4834,7 @@ where
4854If the named font is not yet loaded, return nil. */) 4834If the named font is not yet loaded, return nil. */)
4855 (Lisp_Object name, Lisp_Object frame) 4835 (Lisp_Object name, Lisp_Object frame)
4856{ 4836{
4857 FRAME_PTR f; 4837 struct frame *f;
4858 struct font *font; 4838 struct font *font;
4859 Lisp_Object info; 4839 Lisp_Object info;
4860 Lisp_Object font_object; 4840 Lisp_Object font_object;
@@ -4863,10 +4843,7 @@ If the named font is not yet loaded, return nil. */)
4863 4843
4864 if (! FONTP (name)) 4844 if (! FONTP (name))
4865 CHECK_STRING (name); 4845 CHECK_STRING (name);
4866 if (NILP (frame)) 4846 f = decode_live_frame (frame);
4867 frame = selected_frame;
4868 CHECK_LIVE_FRAME (frame);
4869 f = XFRAME (frame);
4870 4847
4871 if (STRINGP (name)) 4848 if (STRINGP (name))
4872 { 4849 {
diff --git a/src/fontset.c b/src/fontset.c
index da745b31ca1..b76a216bac2 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -1326,17 +1326,14 @@ static Lisp_Object
1326check_fontset_name (Lisp_Object name, Lisp_Object *frame) 1326check_fontset_name (Lisp_Object name, Lisp_Object *frame)
1327{ 1327{
1328 int id; 1328 int id;
1329 struct frame *f = decode_live_frame (*frame);
1329 1330
1330 if (NILP (*frame)) 1331 XSETFRAME (*frame, f);
1331 *frame = selected_frame;
1332 CHECK_LIVE_FRAME (*frame);
1333 1332
1334 if (EQ (name, Qt)) 1333 if (EQ (name, Qt))
1335 return Vdefault_fontset; 1334 return Vdefault_fontset;
1336 if (NILP (name)) 1335 if (NILP (name))
1337 { 1336 id = FRAME_FONTSET (f);
1338 id = FRAME_FONTSET (XFRAME (*frame));
1339 }
1340 else 1337 else
1341 { 1338 {
1342 CHECK_STRING (name); 1339 CHECK_STRING (name);
diff --git a/src/frame.c b/src/frame.c
index 79893abf826..d580bf7f148 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -131,7 +131,24 @@ fset_minibuffer_window (struct frame *f, Lisp_Object val)
131 f->minibuffer_window = val; 131 f->minibuffer_window = val;
132} 132}
133 133
134 134struct frame *
135decode_live_frame (register Lisp_Object frame)
136{
137 if (NILP (frame))
138 frame = selected_frame;
139 CHECK_LIVE_FRAME (frame);
140 return XFRAME (frame);
141}
142
143struct frame *
144decode_any_frame (register Lisp_Object frame)
145{
146 if (NILP (frame))
147 frame = selected_frame;
148 CHECK_FRAME (frame);
149 return XFRAME (frame);
150}
151
135static void 152static void
136set_menu_bar_lines_1 (Lisp_Object window, int n) 153set_menu_bar_lines_1 (Lisp_Object window, int n)
137{ 154{
@@ -502,7 +519,6 @@ make_initial_frame (void)
502 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR; 519 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
503 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR; 520 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
504 521
505 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
506 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; 522 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
507 523
508 /* The default value of menu-bar-mode is t. */ 524 /* The default value of menu-bar-mode is t. */
@@ -551,7 +567,6 @@ make_terminal_frame (struct terminal *terminal)
551 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR; 567 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
552#endif /* not MSDOS */ 568#endif /* not MSDOS */
553 569
554 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
555 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; 570 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
556 FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1; 571 FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1;
557 572
@@ -891,7 +906,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
891static Lisp_Object 906static Lisp_Object
892next_frame (Lisp_Object frame, Lisp_Object minibuf) 907next_frame (Lisp_Object frame, Lisp_Object minibuf)
893{ 908{
894 Lisp_Object tail; 909 Lisp_Object f, tail;
895 int passed = 0; 910 int passed = 0;
896 911
897 /* There must always be at least one frame in Vframe_list. */ 912 /* There must always be at least one frame in Vframe_list. */
@@ -903,12 +918,8 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
903 CHECK_LIVE_FRAME (frame); 918 CHECK_LIVE_FRAME (frame);
904 919
905 while (1) 920 while (1)
906 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 921 FOR_EACH_FRAME (tail, f)
907 { 922 {
908 Lisp_Object f;
909
910 f = XCAR (tail);
911
912 if (passed 923 if (passed
913 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame)) 924 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
914 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) 925 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
@@ -969,22 +980,13 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
969static Lisp_Object 980static Lisp_Object
970prev_frame (Lisp_Object frame, Lisp_Object minibuf) 981prev_frame (Lisp_Object frame, Lisp_Object minibuf)
971{ 982{
972 Lisp_Object tail; 983 Lisp_Object f, tail, prev = Qnil;
973 Lisp_Object prev;
974 984
975 /* There must always be at least one frame in Vframe_list. */ 985 /* There must always be at least one frame in Vframe_list. */
976 if (! CONSP (Vframe_list)) 986 eassert (CONSP (Vframe_list));
977 emacs_abort ();
978 987
979 prev = Qnil; 988 FOR_EACH_FRAME (tail, f)
980 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
981 { 989 {
982 Lisp_Object f;
983
984 f = XCAR (tail);
985 if (!FRAMEP (f))
986 emacs_abort ();
987
988 if (EQ (frame, f) && !NILP (prev)) 990 if (EQ (frame, f) && !NILP (prev))
989 return prev; 991 return prev;
990 992
@@ -1085,11 +1087,10 @@ Otherwise, include all frames. */)
1085static int 1087static int
1086other_visible_frames (FRAME_PTR f) 1088other_visible_frames (FRAME_PTR f)
1087{ 1089{
1088 Lisp_Object frames; 1090 Lisp_Object frames, this;
1089 1091
1090 for (frames = Vframe_list; CONSP (frames); frames = XCDR (frames)) 1092 FOR_EACH_FRAME (frames, this)
1091 { 1093 {
1092 Lisp_Object this = XCAR (frames);
1093 if (f == XFRAME (this)) 1094 if (f == XFRAME (this))
1094 continue; 1095 continue;
1095 1096
@@ -1120,23 +1121,12 @@ other_visible_frames (FRAME_PTR f)
1120Lisp_Object 1121Lisp_Object
1121delete_frame (Lisp_Object frame, Lisp_Object force) 1122delete_frame (Lisp_Object frame, Lisp_Object force)
1122{ 1123{
1123 struct frame *f; 1124 struct frame *f = decode_any_frame (frame);
1124 struct frame *sf = SELECTED_FRAME (); 1125 struct frame *sf = SELECTED_FRAME ();
1125 struct kboard *kb; 1126 struct kboard *kb;
1126 1127
1127 int minibuffer_selected, is_tooltip_frame; 1128 int minibuffer_selected, is_tooltip_frame;
1128 1129
1129 if (EQ (frame, Qnil))
1130 {
1131 f = sf;
1132 XSETFRAME (frame, f);
1133 }
1134 else
1135 {
1136 CHECK_FRAME (frame);
1137 f = XFRAME (frame);
1138 }
1139
1140 if (! FRAME_LIVE_P (f)) 1130 if (! FRAME_LIVE_P (f))
1141 return Qnil; 1131 return Qnil;
1142 1132
@@ -1148,19 +1138,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1148 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp)) 1138 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1149 error ("Attempt to delete the only frame"); 1139 error ("Attempt to delete the only frame");
1150 1140
1141 XSETFRAME (frame, f);
1142
1151 /* Does this frame have a minibuffer, and is it the surrogate 1143 /* Does this frame have a minibuffer, and is it the surrogate
1152 minibuffer for any other frame? */ 1144 minibuffer for any other frame? */
1153 if (FRAME_HAS_MINIBUF_P (XFRAME (frame))) 1145 if (FRAME_HAS_MINIBUF_P (f))
1154 { 1146 {
1155 Lisp_Object frames; 1147 Lisp_Object frames, this;
1156 1148
1157 for (frames = Vframe_list; 1149 FOR_EACH_FRAME (frames, this)
1158 CONSP (frames);
1159 frames = XCDR (frames))
1160 { 1150 {
1161 Lisp_Object this;
1162 this = XCAR (frames);
1163
1164 if (! EQ (this, frame) 1151 if (! EQ (this, frame)
1165 && EQ (frame, 1152 && EQ (frame,
1166 WINDOW_FRAME (XWINDOW 1153 WINDOW_FRAME (XWINDOW
@@ -1353,15 +1340,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1353 another one. */ 1340 another one. */
1354 if (f == last_nonminibuf_frame) 1341 if (f == last_nonminibuf_frame)
1355 { 1342 {
1356 Lisp_Object frames; 1343 Lisp_Object frames, this;
1357 1344
1358 last_nonminibuf_frame = 0; 1345 last_nonminibuf_frame = 0;
1359 1346
1360 for (frames = Vframe_list; 1347 FOR_EACH_FRAME (frames, this)
1361 CONSP (frames);
1362 frames = XCDR (frames))
1363 { 1348 {
1364 f = XFRAME (XCAR (frames)); 1349 f = XFRAME (this);
1365 if (!FRAME_MINIBUF_ONLY_P (f)) 1350 if (!FRAME_MINIBUF_ONLY_P (f))
1366 { 1351 {
1367 last_nonminibuf_frame = f; 1352 last_nonminibuf_frame = f;
@@ -1374,27 +1359,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1374 single-kboard state if we're in it for this kboard. */ 1359 single-kboard state if we're in it for this kboard. */
1375 if (kb != NULL) 1360 if (kb != NULL)
1376 { 1361 {
1377 Lisp_Object frames; 1362 Lisp_Object frames, this;
1378 /* Some frame we found on the same kboard, or nil if there are none. */ 1363 /* Some frame we found on the same kboard, or nil if there are none. */
1379 Lisp_Object frame_on_same_kboard; 1364 Lisp_Object frame_on_same_kboard = Qnil;
1380
1381 frame_on_same_kboard = Qnil;
1382
1383 for (frames = Vframe_list;
1384 CONSP (frames);
1385 frames = XCDR (frames))
1386 {
1387 Lisp_Object this;
1388 struct frame *f1;
1389 1365
1390 this = XCAR (frames); 1366 FOR_EACH_FRAME (frames, this)
1391 if (!FRAMEP (this)) 1367 if (kb == FRAME_KBOARD (XFRAME (this)))
1392 emacs_abort (); 1368 frame_on_same_kboard = this;
1393 f1 = XFRAME (this);
1394
1395 if (kb == FRAME_KBOARD (f1))
1396 frame_on_same_kboard = this;
1397 }
1398 1369
1399 if (NILP (frame_on_same_kboard)) 1370 if (NILP (frame_on_same_kboard))
1400 not_single_kboard_state (kb); 1371 not_single_kboard_state (kb);
@@ -1406,27 +1377,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1406 frames with other windows. */ 1377 frames with other windows. */
1407 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame))) 1378 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
1408 { 1379 {
1409 Lisp_Object frames; 1380 Lisp_Object frames, this;
1410 1381
1411 /* The last frame we saw with a minibuffer, minibuffer-only or not. */ 1382 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1412 Lisp_Object frame_with_minibuf; 1383 Lisp_Object frame_with_minibuf = Qnil;
1413 /* Some frame we found on the same kboard, or nil if there are none. */ 1384 /* Some frame we found on the same kboard, or nil if there are none. */
1414 Lisp_Object frame_on_same_kboard; 1385 Lisp_Object frame_on_same_kboard = Qnil;
1415 1386
1416 frame_on_same_kboard = Qnil; 1387 FOR_EACH_FRAME (frames, this)
1417 frame_with_minibuf = Qnil;
1418
1419 for (frames = Vframe_list;
1420 CONSP (frames);
1421 frames = XCDR (frames))
1422 { 1388 {
1423 Lisp_Object this; 1389 struct frame *f1 = XFRAME (this);
1424 struct frame *f1;
1425
1426 this = XCAR (frames);
1427 if (!FRAMEP (this))
1428 emacs_abort ();
1429 f1 = XFRAME (this);
1430 1390
1431 /* Consider only frames on the same kboard 1391 /* Consider only frames on the same kboard
1432 and only those with minibuffers. */ 1392 and only those with minibuffers. */
@@ -1665,25 +1625,23 @@ DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1665If omitted, FRAME defaults to the currently selected frame. */) 1625If omitted, FRAME defaults to the currently selected frame. */)
1666 (Lisp_Object frame) 1626 (Lisp_Object frame)
1667{ 1627{
1668 if (NILP (frame)) 1628 struct frame *f = decode_live_frame (frame);
1669 frame = selected_frame;
1670
1671 CHECK_LIVE_FRAME (frame);
1672 1629
1673 /* I think this should be done with a hook. */ 1630 /* I think this should be done with a hook. */
1674#ifdef HAVE_WINDOW_SYSTEM 1631#ifdef HAVE_WINDOW_SYSTEM
1675 if (FRAME_WINDOW_P (XFRAME (frame))) 1632 if (FRAME_WINDOW_P (f))
1676 { 1633 {
1677 FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); 1634 FRAME_SAMPLE_VISIBILITY (f);
1678 x_make_frame_visible (XFRAME (frame)); 1635 x_make_frame_visible (f);
1679 } 1636 }
1680#endif 1637#endif
1681 1638
1682 make_frame_visible_1 (XFRAME (frame)->root_window); 1639 make_frame_visible_1 (f->root_window);
1683 1640
1684 /* Make menu bar update for the Buffers and Frames menus. */ 1641 /* Make menu bar update for the Buffers and Frames menus. */
1685 windows_or_buffers_changed++; 1642 windows_or_buffers_changed++;
1686 1643
1644 XSETFRAME (frame, f);
1687 return frame; 1645 return frame;
1688} 1646}
1689 1647
@@ -1724,16 +1682,13 @@ always considered visible, whether or not they are currently being
1724displayed in the terminal. */) 1682displayed in the terminal. */)
1725 (Lisp_Object frame, Lisp_Object force) 1683 (Lisp_Object frame, Lisp_Object force)
1726{ 1684{
1727 if (NILP (frame)) 1685 struct frame *f = decode_live_frame (frame);
1728 frame = selected_frame;
1729
1730 CHECK_LIVE_FRAME (frame);
1731 1686
1732 if (NILP (force) && !other_visible_frames (XFRAME (frame))) 1687 if (NILP (force) && !other_visible_frames (f))
1733 error ("Attempt to make invisible the sole visible or iconified frame"); 1688 error ("Attempt to make invisible the sole visible or iconified frame");
1734 1689
1735 /* Don't allow minibuf_window to remain on a deleted frame. */ 1690 /* Don't allow minibuf_window to remain on a deleted frame. */
1736 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) 1691 if (EQ (f->minibuffer_window, minibuf_window))
1737 { 1692 {
1738 struct frame *sf = XFRAME (selected_frame); 1693 struct frame *sf = XFRAME (selected_frame);
1739 /* Use set_window_buffer instead of Fset_window_buffer (see 1694 /* Use set_window_buffer instead of Fset_window_buffer (see
@@ -1745,8 +1700,8 @@ displayed in the terminal. */)
1745 1700
1746 /* I think this should be done with a hook. */ 1701 /* I think this should be done with a hook. */
1747#ifdef HAVE_WINDOW_SYSTEM 1702#ifdef HAVE_WINDOW_SYSTEM
1748 if (FRAME_WINDOW_P (XFRAME (frame))) 1703 if (FRAME_WINDOW_P (f))
1749 x_make_frame_invisible (XFRAME (frame)); 1704 x_make_frame_invisible (f);
1750#endif 1705#endif
1751 1706
1752 /* Make menu bar update for the Buffers and Frames menus. */ 1707 /* Make menu bar update for the Buffers and Frames menus. */
@@ -1761,19 +1716,10 @@ DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1761If omitted, FRAME defaults to the currently selected frame. */) 1716If omitted, FRAME defaults to the currently selected frame. */)
1762 (Lisp_Object frame) 1717 (Lisp_Object frame)
1763{ 1718{
1764 if (NILP (frame)) 1719 struct frame *f = decode_live_frame (frame);
1765 frame = selected_frame;
1766
1767 CHECK_LIVE_FRAME (frame);
1768
1769#if 0 /* This isn't logically necessary, and it can do GC. */
1770 /* Don't let the frame remain selected. */
1771 if (EQ (frame, selected_frame))
1772 Fhandle_switch_frame (next_frame (frame, Qt));
1773#endif
1774 1720
1775 /* Don't allow minibuf_window to remain on an iconified frame. */ 1721 /* Don't allow minibuf_window to remain on an iconified frame. */
1776 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) 1722 if (EQ (f->minibuffer_window, minibuf_window))
1777 { 1723 {
1778 struct frame *sf = XFRAME (selected_frame); 1724 struct frame *sf = XFRAME (selected_frame);
1779 /* Use set_window_buffer instead of Fset_window_buffer (see 1725 /* Use set_window_buffer instead of Fset_window_buffer (see
@@ -1785,8 +1731,8 @@ If omitted, FRAME defaults to the currently selected frame. */)
1785 1731
1786 /* I think this should be done with a hook. */ 1732 /* I think this should be done with a hook. */
1787#ifdef HAVE_WINDOW_SYSTEM 1733#ifdef HAVE_WINDOW_SYSTEM
1788 if (FRAME_WINDOW_P (XFRAME (frame))) 1734 if (FRAME_WINDOW_P (f))
1789 x_iconify_frame (XFRAME (frame)); 1735 x_iconify_frame (f);
1790#endif 1736#endif
1791 1737
1792 /* Make menu bar update for the Buffers and Frames menus. */ 1738 /* Make menu bar update for the Buffers and Frames menus. */
@@ -1824,20 +1770,12 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1824 doc: /* Return a list of all frames now \"visible\" (being updated). */) 1770 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1825 (void) 1771 (void)
1826{ 1772{
1827 Lisp_Object tail, frame; 1773 Lisp_Object tail, frame, value = Qnil;
1828 struct frame *f; 1774
1829 Lisp_Object value; 1775 FOR_EACH_FRAME (tail, frame)
1776 if (FRAME_VISIBLE_P (XFRAME (frame)))
1777 value = Fcons (frame, value);
1830 1778
1831 value = Qnil;
1832 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1833 {
1834 frame = XCAR (tail);
1835 if (!FRAMEP (frame))
1836 continue;
1837 f = XFRAME (frame);
1838 if (FRAME_VISIBLE_P (f))
1839 value = Fcons (frame, value);
1840 }
1841 return value; 1779 return value;
1842} 1780}
1843 1781
@@ -1850,13 +1788,9 @@ If Emacs is displaying on an ordinary terminal or some other device which
1850doesn't support multiple overlapping frames, this function selects FRAME. */) 1788doesn't support multiple overlapping frames, this function selects FRAME. */)
1851 (Lisp_Object frame) 1789 (Lisp_Object frame)
1852{ 1790{
1853 struct frame *f; 1791 struct frame *f = decode_live_frame (frame);
1854 if (NILP (frame))
1855 frame = selected_frame;
1856
1857 CHECK_LIVE_FRAME (frame);
1858 1792
1859 f = XFRAME (frame); 1793 XSETFRAME (frame, f);
1860 1794
1861 if (FRAME_TERMCAP_P (f)) 1795 if (FRAME_TERMCAP_P (f))
1862 /* On a text terminal select FRAME. */ 1796 /* On a text terminal select FRAME. */
@@ -1879,14 +1813,7 @@ If Emacs is displaying on an ordinary terminal or some other device which
1879doesn't support multiple overlapping frames, this function does nothing. */) 1813doesn't support multiple overlapping frames, this function does nothing. */)
1880 (Lisp_Object frame) 1814 (Lisp_Object frame)
1881{ 1815{
1882 struct frame *f; 1816 struct frame *f = decode_live_frame (frame);
1883
1884 if (NILP (frame))
1885 frame = selected_frame;
1886
1887 CHECK_LIVE_FRAME (frame);
1888
1889 f = XFRAME (frame);
1890 1817
1891 if (FRAME_TERMINAL (f)->frame_raise_lower_hook) 1818 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1892 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0); 1819 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
@@ -1922,18 +1849,14 @@ is affected by `select-frame', while the latter is not.
1922The redirection lasts until `redirect-frame-focus' is called to change it. */) 1849The redirection lasts until `redirect-frame-focus' is called to change it. */)
1923 (Lisp_Object frame, Lisp_Object focus_frame) 1850 (Lisp_Object frame, Lisp_Object focus_frame)
1924{ 1851{
1925 struct frame *f;
1926
1927 /* Note that we don't check for a live frame here. It's reasonable 1852 /* Note that we don't check for a live frame here. It's reasonable
1928 to redirect the focus of a frame you're about to delete, if you 1853 to redirect the focus of a frame you're about to delete, if you
1929 know what other frame should receive those keystrokes. */ 1854 know what other frame should receive those keystrokes. */
1930 CHECK_FRAME (frame); 1855 struct frame *f = decode_any_frame (frame);
1931 1856
1932 if (! NILP (focus_frame)) 1857 if (! NILP (focus_frame))
1933 CHECK_LIVE_FRAME (focus_frame); 1858 CHECK_LIVE_FRAME (focus_frame);
1934 1859
1935 f = XFRAME (frame);
1936
1937 fset_focus_frame (f, focus_frame); 1860 fset_focus_frame (f, focus_frame);
1938 1861
1939 if (FRAME_TERMINAL (f)->frame_rehighlight_hook) 1862 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
@@ -1943,15 +1866,14 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */)
1943} 1866}
1944 1867
1945 1868
1946DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0, 1869DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 0, 1, 0,
1947 doc: /* Return the frame to which FRAME's keystrokes are currently being sent. 1870 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
1948This returns nil if FRAME's focus is not redirected. 1871If FRAME is omitted or nil, the selected frame is used.
1872Return nil if FRAME's focus is not redirected.
1949See `redirect-frame-focus'. */) 1873See `redirect-frame-focus'. */)
1950 (Lisp_Object frame) 1874 (Lisp_Object frame)
1951{ 1875{
1952 CHECK_LIVE_FRAME (frame); 1876 return FRAME_FOCUS_FRAME (decode_live_frame (frame));
1953
1954 return FRAME_FOCUS_FRAME (XFRAME (frame));
1955} 1877}
1956 1878
1957 1879
@@ -1974,22 +1896,6 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
1974} 1896}
1975#endif 1897#endif
1976 1898
1977/* Return the buffer-predicate of the selected frame. */
1978
1979Lisp_Object
1980frame_buffer_predicate (Lisp_Object frame)
1981{
1982 return XFRAME (frame)->buffer_predicate;
1983}
1984
1985/* Return the buffer-list of the selected frame. */
1986
1987static Lisp_Object
1988frame_buffer_list (Lisp_Object frame)
1989{
1990 return XFRAME (frame)->buffer_list;
1991}
1992
1993/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */ 1899/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
1994 1900
1995void 1901void
@@ -2168,20 +2074,14 @@ DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2168 doc: /* Return the parameters-alist of frame FRAME. 2074 doc: /* Return the parameters-alist of frame FRAME.
2169It is a list of elements of the form (PARM . VALUE), where PARM is a symbol. 2075It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2170The meaningful PARMs depend on the kind of frame. 2076The meaningful PARMs depend on the kind of frame.
2171If FRAME is omitted, return information on the currently selected frame. */) 2077If FRAME is omitted or nil, return information on the currently selected frame. */)
2172 (Lisp_Object frame) 2078 (Lisp_Object frame)
2173{ 2079{
2174 Lisp_Object alist; 2080 Lisp_Object alist;
2175 FRAME_PTR f; 2081 struct frame *f = decode_any_frame (frame);
2176 int height, width; 2082 int height, width;
2177 struct gcpro gcpro1; 2083 struct gcpro gcpro1;
2178 2084
2179 if (NILP (frame))
2180 frame = selected_frame;
2181
2182 CHECK_FRAME (frame);
2183 f = XFRAME (frame);
2184
2185 if (!FRAME_LIVE_P (f)) 2085 if (!FRAME_LIVE_P (f))
2186 return Qnil; 2086 return Qnil;
2187 2087
@@ -2242,9 +2142,8 @@ If FRAME is omitted, return information on the currently selected frame. */)
2242 : FRAME_MINIBUF_ONLY_P (f) ? Qonly 2142 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2243 : FRAME_MINIBUF_WINDOW (f))); 2143 : FRAME_MINIBUF_WINDOW (f)));
2244 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil)); 2144 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2245 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame)); 2145 store_in_alist (&alist, Qbuffer_list, f->buffer_list);
2246 store_in_alist (&alist, Qburied_buffer_list, 2146 store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
2247 XFRAME (frame)->buried_buffer_list);
2248 2147
2249 /* I think this should be done with a hook. */ 2148 /* I think this should be done with a hook. */
2250#ifdef HAVE_WINDOW_SYSTEM 2149#ifdef HAVE_WINDOW_SYSTEM
@@ -2269,17 +2168,12 @@ DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2269If FRAME is nil, describe the currently selected frame. */) 2168If FRAME is nil, describe the currently selected frame. */)
2270 (Lisp_Object frame, Lisp_Object parameter) 2169 (Lisp_Object frame, Lisp_Object parameter)
2271{ 2170{
2272 struct frame *f; 2171 struct frame *f = decode_any_frame (frame);
2273 Lisp_Object value; 2172 Lisp_Object value = Qnil;
2274 2173
2275 if (NILP (frame))
2276 frame = selected_frame;
2277 else
2278 CHECK_FRAME (frame);
2279 CHECK_SYMBOL (parameter); 2174 CHECK_SYMBOL (parameter);
2280 2175
2281 f = XFRAME (frame); 2176 XSETFRAME (frame, f);
2282 value = Qnil;
2283 2177
2284 if (FRAME_LIVE_P (f)) 2178 if (FRAME_LIVE_P (f))
2285 { 2179 {
@@ -2359,14 +2253,9 @@ Note that this functionality is obsolete as of Emacs 22.2, and its
2359use is not recommended. Explicitly check for a frame-parameter instead. */) 2253use is not recommended. Explicitly check for a frame-parameter instead. */)
2360 (Lisp_Object frame, Lisp_Object alist) 2254 (Lisp_Object frame, Lisp_Object alist)
2361{ 2255{
2362 FRAME_PTR f; 2256 struct frame *f = decode_live_frame (frame);
2363 register Lisp_Object tail, prop, val; 2257 register Lisp_Object tail, prop, val;
2364 2258
2365 if (EQ (frame, Qnil))
2366 frame = selected_frame;
2367 CHECK_LIVE_FRAME (frame);
2368 f = XFRAME (frame);
2369
2370 /* I think this should be done with a hook. */ 2259 /* I think this should be done with a hook. */
2371#ifdef HAVE_WINDOW_SYSTEM 2260#ifdef HAVE_WINDOW_SYSTEM
2372 if (FRAME_WINDOW_P (f)) 2261 if (FRAME_WINDOW_P (f))
@@ -2421,18 +2310,13 @@ use is not recommended. Explicitly check for a frame-parameter instead. */)
2421DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height, 2310DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2422 0, 1, 0, 2311 0, 1, 0,
2423 doc: /* Height in pixels of a line in the font in frame FRAME. 2312 doc: /* Height in pixels of a line in the font in frame FRAME.
2424If FRAME is omitted, the selected frame is used. 2313If FRAME is omitted or nil, the selected frame is used.
2425For a terminal frame, the value is always 1. */) 2314For a terminal frame, the value is always 1. */)
2426 (Lisp_Object frame) 2315 (Lisp_Object frame)
2427{ 2316{
2428 struct frame *f;
2429
2430 if (NILP (frame))
2431 frame = selected_frame;
2432 CHECK_FRAME (frame);
2433 f = XFRAME (frame);
2434
2435#ifdef HAVE_WINDOW_SYSTEM 2317#ifdef HAVE_WINDOW_SYSTEM
2318 struct frame *f = decode_any_frame (frame);
2319
2436 if (FRAME_WINDOW_P (f)) 2320 if (FRAME_WINDOW_P (f))
2437 return make_number (x_char_height (f)); 2321 return make_number (x_char_height (f));
2438 else 2322 else
@@ -2444,19 +2328,14 @@ For a terminal frame, the value is always 1. */)
2444DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width, 2328DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2445 0, 1, 0, 2329 0, 1, 0,
2446 doc: /* Width in pixels of characters in the font in frame FRAME. 2330 doc: /* Width in pixels of characters in the font in frame FRAME.
2447If FRAME is omitted, the selected frame is used. 2331If FRAME is omitted or nil, the selected frame is used.
2448On a graphical screen, the width is the standard width of the default font. 2332On a graphical screen, the width is the standard width of the default font.
2449For a terminal screen, the value is always 1. */) 2333For a terminal screen, the value is always 1. */)
2450 (Lisp_Object frame) 2334 (Lisp_Object frame)
2451{ 2335{
2452 struct frame *f;
2453
2454 if (NILP (frame))
2455 frame = selected_frame;
2456 CHECK_FRAME (frame);
2457 f = XFRAME (frame);
2458
2459#ifdef HAVE_WINDOW_SYSTEM 2336#ifdef HAVE_WINDOW_SYSTEM
2337 struct frame *f = decode_any_frame (frame);
2338
2460 if (FRAME_WINDOW_P (f)) 2339 if (FRAME_WINDOW_P (f))
2461 return make_number (x_char_width (f)); 2340 return make_number (x_char_width (f));
2462 else 2341 else
@@ -2467,7 +2346,7 @@ For a terminal screen, the value is always 1. */)
2467DEFUN ("frame-pixel-height", Fframe_pixel_height, 2346DEFUN ("frame-pixel-height", Fframe_pixel_height,
2468 Sframe_pixel_height, 0, 1, 0, 2347 Sframe_pixel_height, 0, 1, 0,
2469 doc: /* Return a FRAME's height in pixels. 2348 doc: /* Return a FRAME's height in pixels.
2470If FRAME is omitted, the selected frame is used. The exact value 2349If FRAME is omitted or nil, the selected frame is used. The exact value
2471of the result depends on the window-system and toolkit in use: 2350of the result depends on the window-system and toolkit in use:
2472 2351
2473In the Gtk+ version of Emacs, it includes only any window (including 2352In the Gtk+ version of Emacs, it includes only any window (including
@@ -2482,12 +2361,7 @@ result is really in characters rather than pixels (i.e., is identical
2482to `frame-height'). */) 2361to `frame-height'). */)
2483 (Lisp_Object frame) 2362 (Lisp_Object frame)
2484{ 2363{
2485 struct frame *f; 2364 struct frame *f = decode_any_frame (frame);
2486
2487 if (NILP (frame))
2488 frame = selected_frame;
2489 CHECK_FRAME (frame);
2490 f = XFRAME (frame);
2491 2365
2492#ifdef HAVE_WINDOW_SYSTEM 2366#ifdef HAVE_WINDOW_SYSTEM
2493 if (FRAME_WINDOW_P (f)) 2367 if (FRAME_WINDOW_P (f))
@@ -2501,15 +2375,10 @@ DEFUN ("frame-pixel-width", Fframe_pixel_width,
2501 Sframe_pixel_width, 0, 1, 0, 2375 Sframe_pixel_width, 0, 1, 0,
2502 doc: /* Return FRAME's width in pixels. 2376 doc: /* Return FRAME's width in pixels.
2503For a terminal frame, the result really gives the width in characters. 2377For a terminal frame, the result really gives the width in characters.
2504If FRAME is omitted, the selected frame is used. */) 2378If FRAME is omitted or nil, the selected frame is used. */)
2505 (Lisp_Object frame) 2379 (Lisp_Object frame)
2506{ 2380{
2507 struct frame *f; 2381 struct frame *f = decode_any_frame (frame);
2508
2509 if (NILP (frame))
2510 frame = selected_frame;
2511 CHECK_FRAME (frame);
2512 f = XFRAME (frame);
2513 2382
2514#ifdef HAVE_WINDOW_SYSTEM 2383#ifdef HAVE_WINDOW_SYSTEM
2515 if (FRAME_WINDOW_P (f)) 2384 if (FRAME_WINDOW_P (f))
@@ -2523,17 +2392,15 @@ DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
2523 Stool_bar_pixel_width, 0, 1, 0, 2392 Stool_bar_pixel_width, 0, 1, 0,
2524 doc: /* Return width in pixels of FRAME's tool bar. 2393 doc: /* Return width in pixels of FRAME's tool bar.
2525The result is greater than zero only when the tool bar is on the left 2394The result is greater than zero only when the tool bar is on the left
2526or right side of FRAME. If FRAME is omitted, the selected frame is 2395or right side of FRAME. If FRAME is omitted or nil, the selected frame
2527used. */) 2396is used. */)
2528 (Lisp_Object frame) 2397 (Lisp_Object frame)
2529{ 2398{
2530 if (NILP (frame))
2531 frame = selected_frame;
2532 CHECK_FRAME (frame);
2533
2534#ifdef FRAME_TOOLBAR_WIDTH 2399#ifdef FRAME_TOOLBAR_WIDTH
2535 if (FRAME_WINDOW_P (XFRAME (frame))) 2400 struct frame *f = decode_any_frame (frame);
2536 return make_number (FRAME_TOOLBAR_WIDTH (XFRAME (frame))); 2401
2402 if (FRAME_WINDOW_P (f))
2403 return make_number (FRAME_TOOLBAR_WIDTH (f));
2537#endif 2404#endif
2538 return make_number (0); 2405 return make_number (0);
2539} 2406}
@@ -2544,13 +2411,9 @@ Optional third arg non-nil means that redisplay should use LINES lines
2544but that the idea of the actual height of the frame should not be changed. */) 2411but that the idea of the actual height of the frame should not be changed. */)
2545 (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend) 2412 (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
2546{ 2413{
2547 register struct frame *f; 2414 register struct frame *f = decode_live_frame (frame);
2548 2415
2549 CHECK_TYPE_RANGED_INTEGER (int, lines); 2416 CHECK_TYPE_RANGED_INTEGER (int, lines);
2550 if (NILP (frame))
2551 frame = selected_frame;
2552 CHECK_LIVE_FRAME (frame);
2553 f = XFRAME (frame);
2554 2417
2555 /* I think this should be done with a hook. */ 2418 /* I think this should be done with a hook. */
2556#ifdef HAVE_WINDOW_SYSTEM 2419#ifdef HAVE_WINDOW_SYSTEM
@@ -2572,12 +2435,9 @@ Optional third arg non-nil means that redisplay should use COLS columns
2572but that the idea of the actual width of the frame should not be changed. */) 2435but that the idea of the actual width of the frame should not be changed. */)
2573 (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend) 2436 (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
2574{ 2437{
2575 register struct frame *f; 2438 register struct frame *f = decode_live_frame (frame);
2439
2576 CHECK_TYPE_RANGED_INTEGER (int, cols); 2440 CHECK_TYPE_RANGED_INTEGER (int, cols);
2577 if (NILP (frame))
2578 frame = selected_frame;
2579 CHECK_LIVE_FRAME (frame);
2580 f = XFRAME (frame);
2581 2441
2582 /* I think this should be done with a hook. */ 2442 /* I think this should be done with a hook. */
2583#ifdef HAVE_WINDOW_SYSTEM 2443#ifdef HAVE_WINDOW_SYSTEM
@@ -4294,12 +4154,7 @@ Otherwise it returns nil. FRAME omitted or nil means the
4294selected frame. This is useful when `make-pointer-invisible' is set. */) 4154selected frame. This is useful when `make-pointer-invisible' is set. */)
4295 (Lisp_Object frame) 4155 (Lisp_Object frame)
4296{ 4156{
4297 if (NILP (frame)) 4157 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
4298 frame = selected_frame;
4299
4300 CHECK_FRAME (frame);
4301
4302 return (XFRAME (frame)->pointer_invisible ? Qnil : Qt);
4303} 4158}
4304 4159
4305 4160
diff --git a/src/frame.h b/src/frame.h
index f8c3d99fedd..35cbc44becc 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -237,7 +237,7 @@ struct frame
237 237
238#if defined (USE_GTK) || defined (HAVE_NS) 238#if defined (USE_GTK) || defined (HAVE_NS)
239 /* Nonzero means using a tool bar that comes from the toolkit. */ 239 /* Nonzero means using a tool bar that comes from the toolkit. */
240 int external_tool_bar; 240 unsigned external_tool_bar : 1;
241#endif 241#endif
242 242
243 /* Margin at the top of the frame. Used to display the tool-bar. */ 243 /* Margin at the top of the frame. Used to display the tool-bar. */
@@ -409,10 +409,6 @@ struct frame
409 show no modeline for that window. */ 409 show no modeline for that window. */
410 unsigned wants_modeline : 1; 410 unsigned wants_modeline : 1;
411 411
412 /* Non-zero if the hardware device this frame is displaying on can
413 support scroll bars. */
414 char can_have_scroll_bars;
415
416 /* Non-0 means raise this frame to the top of the heap when selected. */ 412 /* Non-0 means raise this frame to the top of the heap when selected. */
417 unsigned auto_raise : 1; 413 unsigned auto_raise : 1;
418 414
@@ -438,8 +434,7 @@ struct frame
438 /* Nonzero means that the pointer is invisible. */ 434 /* Nonzero means that the pointer is invisible. */
439 unsigned pointer_invisible :1; 435 unsigned pointer_invisible :1;
440 436
441 /* If can_have_scroll_bars is non-zero, this is non-zero if we should 437 /* Nonzero if we should actually display the scroll bars on this frame. */
442 actually display them on this frame. */
443 enum vertical_scroll_bar_type vertical_scroll_bar_type; 438 enum vertical_scroll_bar_type vertical_scroll_bar_type;
444 439
445 /* What kind of text cursor should we draw in the future? 440 /* What kind of text cursor should we draw in the future?
@@ -767,11 +762,6 @@ typedef struct frame *FRAME_PTR;
767#define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos 762#define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos
768#define FRAME_FOCUS_FRAME(f) f->focus_frame 763#define FRAME_FOCUS_FRAME(f) f->focus_frame
769 764
770/* Nonzero if frame F supports scroll bars.
771 If this is zero, then it is impossible to enable scroll bars
772 on frame F. */
773#define FRAME_CAN_HAVE_SCROLL_BARS(f) ((f)->can_have_scroll_bars)
774
775/* This frame slot says whether scroll bars are currently enabled for frame F, 765/* This frame slot says whether scroll bars are currently enabled for frame F,
776 and which side they are on. */ 766 and which side they are on. */
777#define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((f)->vertical_scroll_bar_type) 767#define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((f)->vertical_scroll_bar_type)
@@ -953,6 +943,8 @@ extern Lisp_Object Qnoelisp;
953extern struct frame *last_nonminibuf_frame; 943extern struct frame *last_nonminibuf_frame;
954 944
955extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); 945extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
946extern struct frame *decode_live_frame (Lisp_Object);
947extern struct frame *decode_any_frame (Lisp_Object);
956extern struct frame *make_initial_frame (void); 948extern struct frame *make_initial_frame (void);
957extern struct frame *make_frame (int); 949extern struct frame *make_frame (int);
958#ifdef HAVE_WINDOW_SYSTEM 950#ifdef HAVE_WINDOW_SYSTEM
diff --git a/src/fringe.c b/src/fringe.c
index d788503e91e..a126292e1ff 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1731,10 +1731,8 @@ Return nil if POS is not visible in WINDOW. */)
1731 struct glyph_row *row; 1731 struct glyph_row *row;
1732 ptrdiff_t textpos; 1732 ptrdiff_t textpos;
1733 1733
1734 if (NILP (window)) 1734 w = decode_any_window (window);
1735 window = selected_window; 1735 XSETWINDOW (window, w);
1736 CHECK_WINDOW (window);
1737 w = XWINDOW (window);
1738 1736
1739 if (!NILP (pos)) 1737 if (!NILP (pos))
1740 { 1738 {
diff --git a/src/image.c b/src/image.c
index 538ae2b7772..07db6cece1f 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3731,10 +3731,10 @@ xpm_make_color_table_h (void (**put_func) (Lisp_Object,
3731{ 3731{
3732 *put_func = xpm_put_color_table_h; 3732 *put_func = xpm_put_color_table_h;
3733 *get_func = xpm_get_color_table_h; 3733 *get_func = xpm_get_color_table_h;
3734 return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), 3734 return make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
3735 make_float (DEFAULT_REHASH_SIZE), 3735 make_float (DEFAULT_REHASH_SIZE),
3736 make_float (DEFAULT_REHASH_THRESHOLD), 3736 make_float (DEFAULT_REHASH_THRESHOLD),
3737 Qnil, Qnil, Qnil); 3737 Qnil);
3738} 3738}
3739 3739
3740static void 3740static void
diff --git a/src/indent.c b/src/indent.c
index bbc944d2518..eee96061e25 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1764,11 +1764,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */)
1764 else 1764 else
1765 hscroll = tab_offset = 0; 1765 hscroll = tab_offset = 0;
1766 1766
1767 if (NILP (window)) 1767 w = decode_live_window (window);
1768 window = Fselected_window ();
1769 else
1770 CHECK_LIVE_WINDOW (window);
1771 w = XWINDOW (window);
1772 1768
1773 if (XINT (from) < BEGV || XINT (from) > ZV) 1769 if (XINT (from) < BEGV || XINT (from) > ZV)
1774 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV)); 1770 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
@@ -1790,8 +1786,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */)
1790 1)) 1786 1))
1791 : XINT (XCAR (topos))), 1787 : XINT (XCAR (topos))),
1792 (NILP (width) ? -1 : XINT (width)), 1788 (NILP (width) ? -1 : XINT (width)),
1793 hscroll, tab_offset, 1789 hscroll, tab_offset, w);
1794 XWINDOW (window));
1795 1790
1796 XSETFASTINT (bufpos, pos->bufpos); 1791 XSETFASTINT (bufpos, pos->bufpos);
1797 XSETINT (hpos, pos->hpos); 1792 XSETINT (hpos, pos->hpos);
@@ -1988,11 +1983,7 @@ whether or not it is currently displayed in some window. */)
1988 } 1983 }
1989 1984
1990 CHECK_NUMBER (lines); 1985 CHECK_NUMBER (lines);
1991 if (! NILP (window)) 1986 w = decode_live_window (window);
1992 CHECK_WINDOW (window);
1993 else
1994 window = selected_window;
1995 w = XWINDOW (window);
1996 1987
1997 old_buffer = Qnil; 1988 old_buffer = Qnil;
1998 GCPRO3 (old_buffer, old_charpos, old_bytepos); 1989 GCPRO3 (old_buffer, old_charpos, old_bytepos);
diff --git a/src/keyboard.c b/src/keyboard.c
index 0029304ea8e..98c1cc0b78b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3419,20 +3419,20 @@ int stop_character EXTERNALLY_VISIBLE;
3419static KBOARD * 3419static KBOARD *
3420event_to_kboard (struct input_event *event) 3420event_to_kboard (struct input_event *event)
3421{ 3421{
3422 Lisp_Object frame; 3422 /* Not applicable for these special events. */
3423 frame = event->frame_or_window; 3423 if (event->kind == SELECTION_REQUEST_EVENT
3424 if (CONSP (frame)) 3424 || event->kind == SELECTION_CLEAR_EVENT)
3425 frame = XCAR (frame); 3425 return NULL;
3426 else if (WINDOWP (frame))
3427 frame = WINDOW_FRAME (XWINDOW (frame));
3428
3429 /* There are still some events that don't set this field.
3430 For now, just ignore the problem.
3431 Also ignore dead frames here. */
3432 if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame)))
3433 return 0;
3434 else 3426 else
3435 return FRAME_KBOARD (XFRAME (frame)); 3427 {
3428 Lisp_Object obj = event->frame_or_window;
3429 /* There are some events that set this field to nil or string. */
3430 if (WINDOWP (obj))
3431 obj = WINDOW_FRAME (XWINDOW (obj));
3432 /* Also ignore dead frames here. */
3433 return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj)))
3434 ? FRAME_KBOARD (XFRAME (obj)) : NULL);
3435 }
3436} 3436}
3437 3437
3438#ifdef subprocesses 3438#ifdef subprocesses
@@ -12189,14 +12189,15 @@ mark_kboards (void)
12189 { 12189 {
12190 if (event == kbd_buffer + KBD_BUFFER_SIZE) 12190 if (event == kbd_buffer + KBD_BUFFER_SIZE)
12191 event = kbd_buffer; 12191 event = kbd_buffer;
12192 /* These two special event types has no Lisp_Objects to mark. */
12192 if (event->kind != SELECTION_REQUEST_EVENT 12193 if (event->kind != SELECTION_REQUEST_EVENT
12193 && event->kind != SELECTION_CLEAR_EVENT) 12194 && event->kind != SELECTION_CLEAR_EVENT)
12194 { 12195 {
12195 mark_object (event->x); 12196 mark_object (event->x);
12196 mark_object (event->y); 12197 mark_object (event->y);
12198 mark_object (event->frame_or_window);
12199 mark_object (event->arg);
12197 } 12200 }
12198 mark_object (event->frame_or_window);
12199 mark_object (event->arg);
12200 } 12201 }
12201 } 12202 }
12202} 12203}
diff --git a/src/lisp.h b/src/lisp.h
index 7746b4e313e..c909287b7cd 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -160,11 +160,9 @@ enum Lisp_Bits
160#define GCTYPEBITS 3 160#define GCTYPEBITS 3
161 GCTYPEBITS, 161 GCTYPEBITS,
162 162
163 /* 2**GCTYPEBITS. This must also be a macro that expands to a 163 /* 2**GCTYPEBITS. This must be a macro that expands to a literal
164 literal integer constant, for MSVC. */ 164 integer constant, for MSVC. */
165 GCALIGNMENT =
166#define GCALIGNMENT 8 165#define GCALIGNMENT 8
167 GCALIGNMENT,
168 166
169 /* Number of bits in a Lisp_Object value, not counting the tag. */ 167 /* Number of bits in a Lisp_Object value, not counting the tag. */
170 VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS, 168 VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS,
@@ -410,14 +408,11 @@ enum pvec_type
410 PVEC_WINDOW_CONFIGURATION, 408 PVEC_WINDOW_CONFIGURATION,
411 PVEC_SUBR, 409 PVEC_SUBR,
412 PVEC_OTHER, 410 PVEC_OTHER,
413 /* These last 4 are special because we OR them in fns.c:internal_equal, 411 /* These should be last, check internal_equal to see why. */
414 so they have to use a disjoint bit pattern: 412 PVEC_COMPILED,
415 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE 413 PVEC_CHAR_TABLE,
416 | PVEC_SUB_CHAR_TABLE | PVEC_FONT))) */ 414 PVEC_SUB_CHAR_TABLE,
417 PVEC_COMPILED = 0x10, 415 PVEC_FONT /* Should be last because it's used for range checking. */
418 PVEC_CHAR_TABLE = 0x20,
419 PVEC_SUB_CHAR_TABLE = 0x30,
420 PVEC_FONT = 0x40
421}; 416};
422 417
423/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers 418/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers
@@ -437,9 +432,18 @@ enum More_Lisp_Bits
437 only the number of Lisp_Object fields (that need to be traced by GC). 432 only the number of Lisp_Object fields (that need to be traced by GC).
438 The distinction is used, e.g., by Lisp_Process, which places extra 433 The distinction is used, e.g., by Lisp_Process, which places extra
439 non-Lisp_Object fields at the end of the structure. */ 434 non-Lisp_Object fields at the end of the structure. */
440 PSEUDOVECTOR_SIZE_BITS = 16, 435 PSEUDOVECTOR_SIZE_BITS = 12,
441 PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, 436 PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
442 PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS, 437
438 /* To calculate the memory footprint of the pseudovector, it's useful
439 to store the size of non-Lisp area in word_size units here. */
440 PSEUDOVECTOR_REST_BITS = 12,
441 PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
442 << PSEUDOVECTOR_SIZE_BITS),
443
444 /* Used to extract pseudovector subtype information. */
445 PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
446 PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS,
443 447
444 /* Number of bits to put in each character in the internal representation 448 /* Number of bits to put in each character in the internal representation
445 of bool vectors. This should not vary across implementations. */ 449 of bool vectors. This should not vary across implementations. */
@@ -450,9 +454,6 @@ enum More_Lisp_Bits
450 For example, if tem is a Lisp_Object whose type is Lisp_Cons, 454 For example, if tem is a Lisp_Object whose type is Lisp_Cons,
451 XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */ 455 XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */
452 456
453/* Return a perfect hash of the Lisp_Object representation. */
454#define XHASH(a) XLI (a)
455
456#if USE_LSB_TAG 457#if USE_LSB_TAG
457 458
458enum lsb_bits 459enum lsb_bits
@@ -505,6 +506,11 @@ static EMACS_INT const VALMASK
505 506
506#endif /* not USE_LSB_TAG */ 507#endif /* not USE_LSB_TAG */
507 508
509/* Return a (Lisp-integer sized) hash of the Lisp_Object value. Happens to be
510 like XUINT right now, but XUINT should only be applied to objects we know
511 are integers. */
512#define XHASH(a) XUINT (a)
513
508/* For integers known to be positive, XFASTINT sometimes provides 514/* For integers known to be positive, XFASTINT sometimes provides
509 faster retrieval and XSETFASTINT provides faster storage. 515 faster retrieval and XSETFASTINT provides faster storage.
510 If not, fallback on the non-accelerated path. */ 516 If not, fallback on the non-accelerated path. */
@@ -520,17 +526,12 @@ static EMACS_INT const VALMASK
520# define XUNTAG(a, type) XPNTR (a) 526# define XUNTAG(a, type) XPNTR (a)
521#endif 527#endif
522 528
523#define EQ(x, y) (XHASH (x) == XHASH (y)) 529#define EQ(x, y) (XLI (x) == XLI (y))
524 530
525/* Largest and smallest representable fixnum values. These are the C 531/* Largest and smallest representable fixnum values. These are the C
526 values. They are macros for use in static initializers, and 532 values. They are macros for use in static initializers. */
527 constants for visibility to GDB. */
528static EMACS_INT const MOST_POSITIVE_FIXNUM =
529#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) 533#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
530 MOST_POSITIVE_FIXNUM;
531static EMACS_INT const MOST_NEGATIVE_FIXNUM =
532#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) 534#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
533 MOST_NEGATIVE_FIXNUM;
534 535
535/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is 536/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is
536 written this way so that it also works if I is of unsigned 537 written this way so that it also works if I is of unsigned
@@ -615,13 +616,13 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
615 616
616/* Pseudovector types. */ 617/* Pseudovector types. */
617 618
618#define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE (v, header.size, code) 619#define XSETPVECTYPE(v, code) \
619#define XSETTYPED_PVECTYPE(v, size_member, code) \ 620 ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
620 ((v)->size_member |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS)) 621#define XSETPVECTYPESIZE(v, code, lispsize, restsize) \
621#define XSETPVECTYPESIZE(v, code, sizeval) \
622 ((v)->header.size = (PSEUDOVECTOR_FLAG \ 622 ((v)->header.size = (PSEUDOVECTOR_FLAG \
623 | ((code) << PSEUDOVECTOR_SIZE_BITS) \ 623 | ((code) << PSEUDOVECTOR_AREA_BITS) \
624 | (sizeval))) 624 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \
625 | (lispsize)))
625 626
626/* The cast to struct vectorlike_header * avoids aliasing issues. */ 627/* The cast to struct vectorlike_header * avoids aliasing issues. */
627#define XSETPSEUDOVECTOR(a, b, code) \ 628#define XSETPSEUDOVECTOR(a, b, code) \
@@ -633,16 +634,14 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
633#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \ 634#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \
634 (XSETVECTOR (a, b), \ 635 (XSETVECTOR (a, b), \
635 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 636 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
636 == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_SIZE_BITS)))) 637 == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
637 638
638#define XSETWINDOW_CONFIGURATION(a, b) \ 639#define XSETWINDOW_CONFIGURATION(a, b) \
639 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)) 640 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION))
640#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) 641#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS))
641#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) 642#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW))
642#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) 643#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL))
643/* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */ 644#define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR))
644#define XSETSUBR(a, b) \
645 XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR)
646#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) 645#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
647#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) 646#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
648#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) 647#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
@@ -809,7 +808,7 @@ struct Lisp_String
809 }; 808 };
810 809
811/* Header of vector-like objects. This documents the layout constraints on 810/* Header of vector-like objects. This documents the layout constraints on
812 vectors and pseudovectors other than struct Lisp_Subr. It also prevents 811 vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents
813 compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR 812 compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR
814 and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *, 813 and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *,
815 because when two such pointers potentially alias, a compiler won't 814 because when two such pointers potentially alias, a compiler won't
@@ -817,43 +816,26 @@ struct Lisp_String
817 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */ 816 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */
818struct vectorlike_header 817struct vectorlike_header
819 { 818 {
820 /* This field contains various pieces of information: 819 /* The only field contains various pieces of information:
821 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. 820 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
822 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain 821 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
823 vector (0) or a pseudovector (1). 822 vector (0) or a pseudovector (1).
824 - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number 823 - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
825 of slots) of the vector. 824 of slots) of the vector.
826 - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into 825 - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:
827 a "pvec type" tag held in PVEC_TYPE_MASK and a size held in the lowest 826 - a) pseudovector subtype held in PVEC_TYPE_MASK field;
828 PSEUDOVECTOR_SIZE_BITS. That size normally indicates the number of 827 - b) number of Lisp_Objects slots at the beginning of the object
829 Lisp_Object slots at the beginning of the object that need to be 828 held in PSEUDOVECTOR_SIZE_MASK field. These objects are always
830 traced by the GC, tho some types use it slightly differently. 829 traced by the GC;
831 - E.g. if the pvec type is PVEC_FREE it means this is an unallocated 830 - c) size of the rest fields held in PSEUDOVECTOR_REST_MASK and
832 vector on a free-list and PSEUDOVECTOR_SIZE_BITS indicates its size 831 measured in word_size units. Rest fields may also include
833 in bytes. */ 832 Lisp_Objects, but these objects usually needs some special treatment
833 during GC.
834 There are some exceptions. For PVEC_FREE, b) is always zero. For
835 PVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero.
836 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,
837 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */
834 ptrdiff_t size; 838 ptrdiff_t size;
835
836 /* When the vector is allocated from a vector block, NBYTES is used
837 if the vector is not on a free list, and VECTOR is used otherwise.
838 For large vector-like objects, BUFFER or VECTOR is used as a pointer
839 to the next vector-like object. It is generally a buffer or a
840 Lisp_Vector alias, so for convenience it is a union instead of a
841 pointer: this way, one can write P->next.vector instead of ((struct
842 Lisp_Vector *) P->next). */
843 union {
844 /* This is only needed for small vectors that are not free because the
845 `size' field only gives us the number of Lisp_Object slots, whereas we
846 need to know the total size, including non-Lisp_Object data.
847 FIXME: figure out a way to store this info elsewhere so we can
848 finally get rid of this extra word of overhead. */
849 ptrdiff_t nbytes;
850 struct buffer *buffer;
851 /* FIXME: This can be removed: For large vectors, this field could be
852 placed *before* the vector itself. And for small vectors on a free
853 list, this field could be stored in the vector's bytes, since the
854 empty vector is handled specially anyway. */
855 struct Lisp_Vector *vector;
856 } next;
857 }; 839 };
858 840
859/* Regular vector is just a header plus array of Lisp_Objects. */ 841/* Regular vector is just a header plus array of Lisp_Objects. */
@@ -1027,15 +1009,11 @@ struct Lisp_Sub_Char_Table
1027 1009
1028/* This structure describes a built-in function. 1010/* This structure describes a built-in function.
1029 It is generated by the DEFUN macro only. 1011 It is generated by the DEFUN macro only.
1030 defsubr makes it into a Lisp object. 1012 defsubr makes it into a Lisp object. */
1031
1032 This type is treated in most respects as a pseudovector,
1033 but since we never dynamically allocate or free them,
1034 we don't need a struct vectorlike_header and its 'next' field. */
1035 1013
1036struct Lisp_Subr 1014struct Lisp_Subr
1037 { 1015 {
1038 ptrdiff_t size; 1016 struct vectorlike_header header;
1039 union { 1017 union {
1040 Lisp_Object (*a0) (void); 1018 Lisp_Object (*a0) (void);
1041 Lisp_Object (*a1) (Lisp_Object); 1019 Lisp_Object (*a1) (Lisp_Object);
@@ -1183,14 +1161,29 @@ struct Lisp_Symbol
1183 1161
1184/* The structure of a Lisp hash table. */ 1162/* The structure of a Lisp hash table. */
1185 1163
1164struct hash_table_test
1165{
1166 /* Name of the function used to compare keys. */
1167 Lisp_Object name;
1168
1169 /* User-supplied hash function, or nil. */
1170 Lisp_Object user_hash_function;
1171
1172 /* User-supplied key comparison function, or nil. */
1173 Lisp_Object user_cmp_function;
1174
1175 /* C function to compare two keys. */
1176 bool (*cmpfn) (struct hash_table_test *t, Lisp_Object, Lisp_Object);
1177
1178 /* C function to compute hash code. */
1179 EMACS_UINT (*hashfn) (struct hash_table_test *t, Lisp_Object);
1180};
1181
1186struct Lisp_Hash_Table 1182struct Lisp_Hash_Table
1187{ 1183{
1188 /* This is for Lisp; the hash table code does not refer to it. */ 1184 /* This is for Lisp; the hash table code does not refer to it. */
1189 struct vectorlike_header header; 1185 struct vectorlike_header header;
1190 1186
1191 /* Function used to compare keys. */
1192 Lisp_Object test;
1193
1194 /* Nil if table is non-weak. Otherwise a symbol describing the 1187 /* Nil if table is non-weak. Otherwise a symbol describing the
1195 weakness of the table. */ 1188 weakness of the table. */
1196 Lisp_Object weak; 1189 Lisp_Object weak;
@@ -1221,12 +1214,6 @@ struct Lisp_Hash_Table
1221 hash table size to reduce collisions. */ 1214 hash table size to reduce collisions. */
1222 Lisp_Object index; 1215 Lisp_Object index;
1223 1216
1224 /* User-supplied hash function, or nil. */
1225 Lisp_Object user_hash_function;
1226
1227 /* User-supplied key comparison function, or nil. */
1228 Lisp_Object user_cmp_function;
1229
1230 /* Only the fields above are traced normally by the GC. The ones below 1217 /* Only the fields above are traced normally by the GC. The ones below
1231 `count' are special and are either ignored by the GC or traced in 1218 `count' are special and are either ignored by the GC or traced in
1232 a special way (e.g. because of weakness). */ 1219 a special way (e.g. because of weakness). */
@@ -1239,17 +1226,12 @@ struct Lisp_Hash_Table
1239 This is gc_marked specially if the table is weak. */ 1226 This is gc_marked specially if the table is weak. */
1240 Lisp_Object key_and_value; 1227 Lisp_Object key_and_value;
1241 1228
1229 /* The comparison and hash functions. */
1230 struct hash_table_test test;
1231
1242 /* Next weak hash table if this is a weak hash table. The head 1232 /* Next weak hash table if this is a weak hash table. The head
1243 of the list is in weak_hash_tables. */ 1233 of the list is in weak_hash_tables. */
1244 struct Lisp_Hash_Table *next_weak; 1234 struct Lisp_Hash_Table *next_weak;
1245
1246 /* C function to compare two keys. */
1247 bool (*cmpfn) (struct Lisp_Hash_Table *,
1248 Lisp_Object, EMACS_UINT,
1249 Lisp_Object, EMACS_UINT);
1250
1251 /* C function to compute hash code. */
1252 EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object);
1253}; 1235};
1254 1236
1255 1237
@@ -1304,6 +1286,15 @@ static double const DEFAULT_REHASH_THRESHOLD = 0.8;
1304 1286
1305static double const DEFAULT_REHASH_SIZE = 1.5; 1287static double const DEFAULT_REHASH_SIZE = 1.5;
1306 1288
1289/* Combine two integers X and Y for hashing. The result might not fit
1290 into a Lisp integer. */
1291
1292LISP_INLINE EMACS_UINT
1293sxhash_combine (EMACS_UINT x, EMACS_UINT y)
1294{
1295 return (x << 4) + (x >> (BITS_PER_EMACS_INT - 4)) + y;
1296}
1297
1307/* These structures are used for various misc types. */ 1298/* These structures are used for various misc types. */
1308 1299
1309struct Lisp_Misc_Any /* Supertype of all Misc types. */ 1300struct Lisp_Misc_Any /* Supertype of all Misc types. */
@@ -1703,6 +1694,8 @@ typedef struct {
1703#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) 1694#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
1704#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) 1695#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
1705 1696
1697#define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x)))
1698
1706#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) 1699#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int)
1707#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) 1700#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool)
1708#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) 1701#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj)
@@ -1716,7 +1709,7 @@ typedef struct {
1716 1709
1717#define PSEUDOVECTOR_TYPEP(v, code) \ 1710#define PSEUDOVECTOR_TYPEP(v, code) \
1718 (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 1711 (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
1719 == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS))) 1712 == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS)))
1720 1713
1721/* True if object X, with internal type struct T *, is a pseudovector whose 1714/* True if object X, with internal type struct T *, is a pseudovector whose
1722 code is CODE. */ 1715 code is CODE. */
@@ -1729,8 +1722,7 @@ typedef struct {
1729#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) 1722#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS)
1730#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) 1723#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW)
1731#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) 1724#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL)
1732/* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ 1725#define SUBRP(x) PSEUDOVECTORP (x, PVEC_SUBR)
1733#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR)
1734#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) 1726#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED)
1735#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) 1727#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)
1736#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) 1728#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE)
@@ -1791,20 +1783,6 @@ typedef struct {
1791#define CHECK_WINDOW_CONFIGURATION(x) \ 1783#define CHECK_WINDOW_CONFIGURATION(x) \
1792 CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x) 1784 CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x)
1793 1785
1794/* A window of any sort, leaf or interior, is "valid" if one of its
1795 buffer, vchild, or hchild members is non-nil. */
1796#define CHECK_VALID_WINDOW(x) \
1797 CHECK_TYPE (WINDOWP (x) \
1798 && (!NILP (XWINDOW (x)->buffer) \
1799 || !NILP (XWINDOW (x)->vchild) \
1800 || !NILP (XWINDOW (x)->hchild)), \
1801 Qwindow_valid_p, x)
1802
1803/* A window is "live" if and only if it shows a buffer. */
1804#define CHECK_LIVE_WINDOW(x) \
1805 CHECK_TYPE (WINDOWP (x) && !NILP (XWINDOW (x)->buffer), \
1806 Qwindow_live_p, x)
1807
1808#define CHECK_PROCESS(x) \ 1786#define CHECK_PROCESS(x) \
1809 CHECK_TYPE (PROCESSP (x), Qprocessp, x) 1787 CHECK_TYPE (PROCESSP (x), Qprocessp, x)
1810 1788
@@ -1919,8 +1897,8 @@ typedef struct {
1919#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1897#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1920 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1898 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1921 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ 1899 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \
1922 { (PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS) \ 1900 { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \
1923 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \ 1901 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \
1924 { (Lisp_Object (__cdecl *)(void))fnname }, \ 1902 { (Lisp_Object (__cdecl *)(void))fnname }, \
1925 minargs, maxargs, lname, intspec, 0}; \ 1903 minargs, maxargs, lname, intspec, 0}; \
1926 Lisp_Object fnname 1904 Lisp_Object fnname
@@ -1928,8 +1906,8 @@ typedef struct {
1928#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1906#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1929 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1907 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1930 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ 1908 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \
1931 { PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS, \ 1909 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
1932 { .a ## maxargs = fnname }, \ 1910 { .a ## maxargs = fnname }, \
1933 minargs, maxargs, lname, intspec, 0}; \ 1911 minargs, maxargs, lname, intspec, 0}; \
1934 Lisp_Object fnname 1912 Lisp_Object fnname
1935#endif 1913#endif
@@ -2658,9 +2636,6 @@ extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
2658 2636
2659EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST; 2637EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST;
2660 2638
2661/* Defined in frame.c. */
2662extern Lisp_Object Qframep;
2663
2664/* Defined in data.c. */ 2639/* Defined in data.c. */
2665extern Lisp_Object indirect_function (Lisp_Object); 2640extern Lisp_Object indirect_function (Lisp_Object);
2666extern Lisp_Object find_symbol_value (Lisp_Object); 2641extern Lisp_Object find_symbol_value (Lisp_Object);
@@ -2746,15 +2721,15 @@ extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
2746extern void sweep_weak_hash_tables (void); 2721extern void sweep_weak_hash_tables (void);
2747extern Lisp_Object Qcursor_in_echo_area; 2722extern Lisp_Object Qcursor_in_echo_area;
2748extern Lisp_Object Qstring_lessp; 2723extern Lisp_Object Qstring_lessp;
2749extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql; 2724extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq;
2750EMACS_UINT hash_string (char const *, ptrdiff_t); 2725EMACS_UINT hash_string (char const *, ptrdiff_t);
2751EMACS_UINT sxhash (Lisp_Object, int); 2726EMACS_UINT sxhash (Lisp_Object, int);
2752Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, 2727Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object,
2753 Lisp_Object, Lisp_Object, Lisp_Object, 2728 Lisp_Object, Lisp_Object);
2754 Lisp_Object);
2755ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); 2729ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
2756ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, 2730ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
2757 EMACS_UINT); 2731 EMACS_UINT);
2732extern struct hash_table_test hashtest_eql, hashtest_equal;
2758 2733
2759extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, 2734extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,
2760 ptrdiff_t, ptrdiff_t); 2735 ptrdiff_t, ptrdiff_t);
@@ -2976,7 +2951,7 @@ extern void make_byte_code (struct Lisp_Vector *);
2976extern Lisp_Object Qautomatic_gc; 2951extern Lisp_Object Qautomatic_gc;
2977extern Lisp_Object Qchar_table_extra_slots; 2952extern Lisp_Object Qchar_table_extra_slots;
2978extern struct Lisp_Vector *allocate_vector (EMACS_INT); 2953extern struct Lisp_Vector *allocate_vector (EMACS_INT);
2979extern struct Lisp_Vector *allocate_pseudovector (int memlen, int lisplen, int tag); 2954extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type);
2980#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ 2955#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \
2981 ((typ*) \ 2956 ((typ*) \
2982 allocate_pseudovector \ 2957 allocate_pseudovector \
@@ -3328,7 +3303,6 @@ extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
3328#if HAVE_NS 3303#if HAVE_NS
3329extern Lisp_Object get_frame_param (struct frame *, Lisp_Object); 3304extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
3330#endif 3305#endif
3331extern Lisp_Object frame_buffer_predicate (Lisp_Object);
3332extern void frames_discard_buffer (Lisp_Object); 3306extern void frames_discard_buffer (Lisp_Object);
3333extern void syms_of_frame (void); 3307extern void syms_of_frame (void);
3334 3308
diff --git a/src/lisp.mk b/src/lisp.mk
index 1f459d4d5f1..8c2710110e3 100644
--- a/src/lisp.mk
+++ b/src/lisp.mk
@@ -34,9 +34,9 @@
34## that does not have an explicit .el extension, but beware of any 34## that does not have an explicit .el extension, but beware of any
35## no-byte-compile ones. 35## no-byte-compile ones.
36 36
37## Confusingly, term/internal is not in loadup, but is unconditionally 37## Confusingly, international/cp51932 and international/eucjp-ms are
38## loaded by pc-win, which is. Ditto for international/cp51932 and 38## unconditionally loaded from language/japanese, instead of being
39## international/eucjp-ms, loaded from language/japanese. 39## loaded directly from loadup.el; FIXME.
40 40
41## Note that this list should not include lisp files which might not 41## Note that this list should not include lisp files which might not
42## be present, like site-load.el and site-init.el; this makefile 42## be present, like site-load.el and site-init.el; this makefile
diff --git a/src/lread.c b/src/lread.c
index 94744620279..3a82e0057e2 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3981,7 +3981,7 @@ defsubr (struct Lisp_Subr *sname)
3981{ 3981{
3982 Lisp_Object sym, tem; 3982 Lisp_Object sym, tem;
3983 sym = intern_c_string (sname->symbol_name); 3983 sym = intern_c_string (sname->symbol_name);
3984 XSETTYPED_PVECTYPE (sname, size, PVEC_SUBR); 3984 XSETPVECTYPE (sname, PVEC_SUBR);
3985 XSETSUBR (tem, sname); 3985 XSETSUBR (tem, sname);
3986 set_symbol_function (sym, tem); 3986 set_symbol_function (sym, tem);
3987} 3987}
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 7cb6667c7ea..50e5e2ec4df 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -1476,8 +1476,8 @@ $(BLD)/unexw32.$(O) : \
1476 $(SRC)/w32.h \ 1476 $(SRC)/w32.h \
1477 $(SRC)/w32common.h \ 1477 $(SRC)/w32common.h \
1478 $(SRC)/w32heap.h \ 1478 $(SRC)/w32heap.h \
1479 $(LISP_H) \ 1479 $(CONFIG_H) \
1480 $(CONFIG_H) 1480 $(LISP_H)
1481 1481
1482$(BLD)/vm-limit.$(O) : \ 1482$(BLD)/vm-limit.$(O) : \
1483 $(SRC)/vm-limit.c \ 1483 $(SRC)/vm-limit.c \
@@ -1565,6 +1565,7 @@ $(BLD)/w32fns.$(O) : \
1565 $(SRC)/w32.h \ 1565 $(SRC)/w32.h \
1566 $(SRC)/w32common.h \ 1566 $(SRC)/w32common.h \
1567 $(SRC)/w32heap.h \ 1567 $(SRC)/w32heap.h \
1568 $(NT_INC)/unistd.h \
1568 $(BUFFER_H) \ 1569 $(BUFFER_H) \
1569 $(CCL_H) \ 1570 $(CCL_H) \
1570 $(CHARACTER_H) \ 1571 $(CHARACTER_H) \
diff --git a/src/msdos.c b/src/msdos.c
index bac6b977fdf..dd05a8b2c5d 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -3305,7 +3305,7 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
3305 Emacs will process them after we return and surprise the user. */ 3305 Emacs will process them after we return and surprise the user. */
3306 discard_mouse_events (); 3306 discard_mouse_events ();
3307 mouse_clear_clicks (); 3307 mouse_clear_clicks ();
3308 if (!kbd_buffer_events_waiting (1)) 3308 if (!kbd_buffer_events_waiting ())
3309 clear_input_pending (); 3309 clear_input_pending ();
3310 /* Allow mouse events generation by dos_rawgetc. */ 3310 /* Allow mouse events generation by dos_rawgetc. */
3311 mouse_preempted--; 3311 mouse_preempted--;
@@ -3927,8 +3927,10 @@ croak (char *badfunc)
3927/* 3927/*
3928 * A few unimplemented functions that we silently ignore. 3928 * A few unimplemented functions that we silently ignore.
3929 */ 3929 */
3930int setpgrp (void) {return 0; } 3930pid_t tcgetpgrp (int fd) { return 0; }
3931int setpgid (int pid, int pgid) { return 0; }
3931int setpriority (int x, int y, int z) { return 0; } 3932int setpriority (int x, int y, int z) { return 0; }
3933pid_t setsid (void) { return 0; }
3932 3934
3933#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4 3935#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4
3934ssize_t 3936ssize_t
@@ -4214,8 +4216,8 @@ init_gettimeofday (void)
4214} 4216}
4215#endif 4217#endif
4216 4218
4217void 4219static void
4218emacs_abort (void) 4220msdos_abort (void)
4219{ 4221{
4220 dos_ttcooked (); 4222 dos_ttcooked ();
4221 ScreenSetCursor (10, 0); 4223 ScreenSetCursor (10, 0);
@@ -4233,6 +4235,15 @@ emacs_abort (void)
4233} 4235}
4234 4236
4235void 4237void
4238msdos_fatal_signal (int sig)
4239{
4240 if (sig == SIGABRT)
4241 msdos_abort ();
4242 else
4243 raise (sig);
4244}
4245
4246void
4236syms_of_msdos (void) 4247syms_of_msdos (void)
4237{ 4248{
4238 recent_doskeys = Fmake_vector (make_number (NUM_RECENT_DOSKEYS), Qnil); 4249 recent_doskeys = Fmake_vector (make_number (NUM_RECENT_DOSKEYS), Qnil);
diff --git a/src/nsfns.m b/src/nsfns.m
index 7a22ac547c3..e8bf696e7f5 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1175,7 +1175,6 @@ This function is an internal primitive--use `make-frame' instead. */)
1175 f = make_frame (1); 1175 f = make_frame (1);
1176 1176
1177 XSETFRAME (frame, f); 1177 XSETFRAME (frame, f);
1178 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
1179 1178
1180 f->terminal = dpyinfo->terminal; 1179 f->terminal = dpyinfo->terminal;
1181 1180
diff --git a/src/nsfont.m b/src/nsfont.m
index 4f29d1d54a9..2ba38b7570e 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -46,8 +46,9 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu)
46#define NSFONT_TRACE 0 46#define NSFONT_TRACE 0
47 47
48extern Lisp_Object Qns; 48extern Lisp_Object Qns;
49extern Lisp_Object Qnormal, Qbold, Qitalic, Qcondensed, Qexpanded; 49extern Lisp_Object Qnormal, Qbold, Qitalic;
50static Lisp_Object Qapple, Qroman, Qmedium; 50static Lisp_Object Qapple, Qroman, Qmedium;
51static Lisp_Object Qcondensed, Qexpanded;
51extern Lisp_Object Qappend; 52extern Lisp_Object Qappend;
52extern float ns_antialias_threshold; 53extern float ns_antialias_threshold;
53extern int ns_tmp_flags; 54extern int ns_tmp_flags;
@@ -201,8 +202,8 @@ ns_descriptor_to_entity (NSFontDescriptor *desc,
201 make_number (100 + 100 202 make_number (100 + 100
202 * ns_attribute_fvalue (desc, NSFontSlantTrait)));*/ 203 * ns_attribute_fvalue (desc, NSFontSlantTrait)));*/
203 FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX, 204 FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
204 traits & NSFontCondensedTrait ? Qcondensed : 205 traits & NSFontCondensedTrait ? Qcondensed :
205 traits & NSFontExpandedTrait ? Qexpanded : Qnormal); 206 traits & NSFontExpandedTrait ? Qexpanded : Qnormal);
206/* FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX, 207/* FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
207 make_number (100 + 100 208 make_number (100 + 100
208 * ns_attribute_fvalue (desc, NSFontWidthTrait)));*/ 209 * ns_attribute_fvalue (desc, NSFontWidthTrait)));*/
@@ -559,7 +560,11 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
559 if (isMatch) 560 if (isMatch)
560 [fkeys removeObject: NSFontFamilyAttribute]; 561 [fkeys removeObject: NSFontFamilyAttribute];
561 562
562 matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys]; 563 if ([fkeys count] > 0)
564 matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
565 else
566 matchingDescs = [NSMutableArray array];
567
563 if (NSFONT_TRACE) 568 if (NSFONT_TRACE)
564 NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc, 569 NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc,
565 [matchingDescs count]); 570 [matchingDescs count]);
@@ -1507,6 +1512,8 @@ syms_of_nsfont (void)
1507{ 1512{
1508 nsfont_driver.type = Qns; 1513 nsfont_driver.type = Qns;
1509 register_font_driver (&nsfont_driver, NULL); 1514 register_font_driver (&nsfont_driver, NULL);
1515 DEFSYM (Qcondensed, "condensed");
1516 DEFSYM (Qexpanded, "expanded");
1510 DEFSYM (Qapple, "apple"); 1517 DEFSYM (Qapple, "apple");
1511 DEFSYM (Qroman, "roman"); 1518 DEFSYM (Qroman, "roman");
1512 DEFSYM (Qmedium, "medium"); 1519 DEFSYM (Qmedium, "medium");
diff --git a/src/nsterm.m b/src/nsterm.m
index 9b2e544c75b..7ba1608268b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -100,6 +100,7 @@ static unsigned convert_ns_to_X_keysym[] =
100 NSBeginFunctionKey, 0x58, 100 NSBeginFunctionKey, 0x58,
101 NSSelectFunctionKey, 0x60, 101 NSSelectFunctionKey, 0x60,
102 NSPrintFunctionKey, 0x61, 102 NSPrintFunctionKey, 0x61,
103 NSClearLineFunctionKey, 0x0B,
103 NSExecuteFunctionKey, 0x62, 104 NSExecuteFunctionKey, 0x62,
104 NSInsertFunctionKey, 0x63, 105 NSInsertFunctionKey, 0x63,
105 NSUndoFunctionKey, 0x65, 106 NSUndoFunctionKey, 0x65,
@@ -144,6 +145,23 @@ static unsigned convert_ns_to_X_keysym[] =
144 NSNewlineCharacter, 0x0D, 145 NSNewlineCharacter, 0x0D,
145 NSEnterCharacter, 0x8D, 146 NSEnterCharacter, 0x8D,
146 147
148 0x41|NSNumericPadKeyMask, 0xAE, /* KP_Decimal */
149 0x43|NSNumericPadKeyMask, 0xAA, /* KP_Multiply */
150 0x45|NSNumericPadKeyMask, 0xAB, /* KP_Add */
151 0x4B|NSNumericPadKeyMask, 0xAF, /* KP_Divide */
152 0x4E|NSNumericPadKeyMask, 0xAD, /* KP_Subtract */
153 0x51|NSNumericPadKeyMask, 0xBD, /* KP_Equal */
154 0x52|NSNumericPadKeyMask, 0xB0, /* KP_0 */
155 0x53|NSNumericPadKeyMask, 0xB1, /* KP_1 */
156 0x54|NSNumericPadKeyMask, 0xB2, /* KP_2 */
157 0x55|NSNumericPadKeyMask, 0xB3, /* KP_3 */
158 0x56|NSNumericPadKeyMask, 0xB4, /* KP_4 */
159 0x57|NSNumericPadKeyMask, 0xB5, /* KP_5 */
160 0x58|NSNumericPadKeyMask, 0xB6, /* KP_6 */
161 0x59|NSNumericPadKeyMask, 0xB7, /* KP_7 */
162 0x5B|NSNumericPadKeyMask, 0xB8, /* KP_8 */
163 0x5C|NSNumericPadKeyMask, 0xB9, /* KP_9 */
164
147 0x1B, 0x1B /* escape */ 165 0x1B, 0x1B /* escape */
148}; 166};
149 167
@@ -4754,12 +4772,12 @@ not_in_argv (NSString *arg)
4754 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe); 4772 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
4755 int code; 4773 int code;
4756 unsigned fnKeysym = 0; 4774 unsigned fnKeysym = 0;
4757 int flags;
4758 static NSMutableArray *nsEvArray; 4775 static NSMutableArray *nsEvArray;
4759#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 4776#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
4760 static BOOL firstTime = YES; 4777 static BOOL firstTime = YES;
4761#endif 4778#endif
4762 int left_is_none; 4779 int left_is_none;
4780 unsigned int flags = [theEvent modifierFlags];
4763 4781
4764 NSTRACE (keyDown); 4782 NSTRACE (keyDown);
4765 4783
@@ -4810,7 +4828,10 @@ not_in_argv (NSString *arg)
4810 /* (Carbon way: [theEvent keyCode]) */ 4828 /* (Carbon way: [theEvent keyCode]) */
4811 4829
4812 /* is it a "function key"? */ 4830 /* is it a "function key"? */
4813 fnKeysym = ns_convert_key (code); 4831 fnKeysym = (code < 0x00ff && (flags&NSNumericPadKeyMask))
4832 ? ns_convert_key ([theEvent keyCode] | NSNumericPadKeyMask)
4833 : ns_convert_key (code);
4834
4814 if (fnKeysym) 4835 if (fnKeysym)
4815 { 4836 {
4816 /* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace', 4837 /* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace',
@@ -4823,7 +4844,6 @@ not_in_argv (NSString *arg)
4823 4844
4824 /* are there modifiers? */ 4845 /* are there modifiers? */
4825 emacs_event->modifiers = 0; 4846 emacs_event->modifiers = 0;
4826 flags = [theEvent modifierFlags];
4827 4847
4828 if (flags & NSHelpKeyMask) 4848 if (flags & NSHelpKeyMask)
4829 emacs_event->modifiers |= hyper_modifier; 4849 emacs_event->modifiers |= hyper_modifier;
diff --git a/src/print.c b/src/print.c
index ccf0e8ed7cc..bf86be5622e 100644
--- a/src/print.c
+++ b/src/print.c
@@ -798,7 +798,7 @@ safe_debug_print (Lisp_Object arg)
798 else 798 else
799 fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n", 799 fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n",
800 !valid ? "INVALID" : "SOME", 800 !valid ? "INVALID" : "SOME",
801 XHASH (arg)); 801 XLI (arg));
802} 802}
803 803
804 804
@@ -1815,14 +1815,14 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1815#endif 1815#endif
1816 /* Implement a readable output, e.g.: 1816 /* Implement a readable output, e.g.:
1817 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ 1817 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */
1818 /* Always print the size. */ 1818 /* Always print the size. */
1819 len = sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); 1819 len = sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next));
1820 strout (buf, len, len, printcharfun); 1820 strout (buf, len, len, printcharfun);
1821 1821
1822 if (!NILP (h->test)) 1822 if (!NILP (h->test.name))
1823 { 1823 {
1824 strout (" test ", -1, -1, printcharfun); 1824 strout (" test ", -1, -1, printcharfun);
1825 print_object (h->test, printcharfun, escapeflag); 1825 print_object (h->test.name, printcharfun, escapeflag);
1826 } 1826 }
1827 1827
1828 if (!NILP (h->weak)) 1828 if (!NILP (h->weak))
diff --git a/src/process.c b/src/process.c
index 77e99ead01f..43f0239d301 100644
--- a/src/process.c
+++ b/src/process.c
@@ -130,6 +130,10 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
130 EMACS_TIME *, void *); 130 EMACS_TIME *, void *);
131#endif 131#endif
132 132
133/* This is for DOS_NT ports. FIXME: Remove this old portability cruft
134 by having DOS_NT ports implement waitpid instead of wait. Nowadays
135 POSIXish hosts all define waitpid, WNOHANG, and WUNTRACED, as these
136 have been standard since POSIX.1-1988. */
133#ifndef WNOHANG 137#ifndef WNOHANG
134# undef waitpid 138# undef waitpid
135# define waitpid(pid, status, options) wait (status) 139# define waitpid(pid, status, options) wait (status)
@@ -795,9 +799,8 @@ get_process (register Lisp_Object name)
795#ifdef SIGCHLD 799#ifdef SIGCHLD
796/* Fdelete_process promises to immediately forget about the process, but in 800/* Fdelete_process promises to immediately forget about the process, but in
797 reality, Emacs needs to remember those processes until they have been 801 reality, Emacs needs to remember those processes until they have been
798 treated by the SIGCHLD handler; otherwise this handler would consider the 802 treated by the SIGCHLD handler and waitpid has been invoked on them;
799 process as being synchronous and say that the synchronous process is 803 otherwise they might fill up the kernel's process table. */
800 dead. */
801static Lisp_Object deleted_pid_list; 804static Lisp_Object deleted_pid_list;
802#endif 805#endif
803 806
@@ -1704,16 +1707,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1704 if (inchannel > max_process_desc) 1707 if (inchannel > max_process_desc)
1705 max_process_desc = inchannel; 1708 max_process_desc = inchannel;
1706 1709
1707 /* Until we store the proper pid, enable the SIGCHLD handler 1710 /* This may signal an error. */
1708 to recognize an unknown pid as standing for this process.
1709 It is very important not to let this `marker' value stay
1710 in the table after this function has returned; if it does
1711 it might cause call-process to hang and subsequent asynchronous
1712 processes to get their return values scrambled. */
1713 XPROCESS (process)->pid = -1;
1714
1715 /* This must be called after the above line because it may signal an
1716 error. */
1717 setup_process_coding_systems (process); 1711 setup_process_coding_systems (process);
1718 1712
1719 encoded_current_dir = ENCODE_FILE (current_dir); 1713 encoded_current_dir = ENCODE_FILE (current_dir);
@@ -1745,7 +1739,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1745 /* Make the pty be the controlling terminal of the process. */ 1739 /* Make the pty be the controlling terminal of the process. */
1746#ifdef HAVE_PTYS 1740#ifdef HAVE_PTYS
1747 /* First, disconnect its current controlling terminal. */ 1741 /* First, disconnect its current controlling terminal. */
1748#ifdef HAVE_SETSID
1749 /* We tried doing setsid only if pty_flag, but it caused 1742 /* We tried doing setsid only if pty_flag, but it caused
1750 process_set_signal to fail on SGI when using a pipe. */ 1743 process_set_signal to fail on SGI when using a pipe. */
1751 setsid (); 1744 setsid ();
@@ -1758,12 +1751,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1758 ioctl (xforkin, TIOCSCTTY, 0); 1751 ioctl (xforkin, TIOCSCTTY, 0);
1759#endif 1752#endif
1760 } 1753 }
1761#else /* not HAVE_SETSID */
1762 /* It's very important to call setpgid here and no time
1763 afterwards. Otherwise, we lose our controlling tty which
1764 is set when we open the pty. */
1765 setpgid (0, 0);
1766#endif /* not HAVE_SETSID */
1767#if defined (LDISC1) 1754#if defined (LDISC1)
1768 if (pty_flag && xforkin >= 0) 1755 if (pty_flag && xforkin >= 0)
1769 { 1756 {
@@ -1796,22 +1783,15 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1796 ioctl (j, TIOCNOTTY, 0); 1783 ioctl (j, TIOCNOTTY, 0);
1797 emacs_close (j); 1784 emacs_close (j);
1798 } 1785 }
1799#ifndef USG
1800 /* In order to get a controlling terminal on some versions
1801 of BSD, it is necessary to put the process in pgrp 0
1802 before it opens the terminal. */
1803 setpgid (0, 0);
1804#endif
1805 } 1786 }
1806#endif /* TIOCNOTTY */ 1787#endif /* TIOCNOTTY */
1807 1788
1808#if !defined (DONT_REOPEN_PTY) 1789#if !defined (DONT_REOPEN_PTY)
1809/*** There is a suggestion that this ought to be a 1790/*** There is a suggestion that this ought to be a
1810 conditional on TIOCSPGRP, 1791 conditional on TIOCSPGRP, or !defined TIOCSCTTY.
1811 or !(defined (HAVE_SETSID) && defined (TIOCSCTTY)).
1812 Trying the latter gave the wrong results on Debian GNU/Linux 1.1; 1792 Trying the latter gave the wrong results on Debian GNU/Linux 1.1;
1813 that system does seem to need this code, even though 1793 that system does seem to need this code, even though
1814 both HAVE_SETSID and TIOCSCTTY are defined. */ 1794 both TIOCSCTTY is defined. */
1815 /* Now close the pty (if we had it open) and reopen it. 1795 /* Now close the pty (if we had it open) and reopen it.
1816 This makes the pty the controlling terminal of the subprocess. */ 1796 This makes the pty the controlling terminal of the subprocess. */
1817 if (pty_flag) 1797 if (pty_flag)
@@ -1880,6 +1860,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1880#endif 1860#endif
1881 1861
1882 XPROCESS (process)->pid = pid; 1862 XPROCESS (process)->pid = pid;
1863 if (0 <= pid)
1864 XPROCESS (process)->alive = 1;
1883 1865
1884 /* Stop blocking signals in the parent. */ 1866 /* Stop blocking signals in the parent. */
1885#ifdef SIGCHLD 1867#ifdef SIGCHLD
@@ -4437,7 +4419,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4437 if (EMACS_TIME_LT (timer_delay, timeout)) 4419 if (EMACS_TIME_LT (timer_delay, timeout))
4438 { 4420 {
4439 timeout = timer_delay; 4421 timeout = timer_delay;
4440 timeout_reduced_for_timers = 1; 4422 timeout_reduced_for_timers = 1;
4441 } 4423 }
4442 } 4424 }
4443 else 4425 else
@@ -6273,9 +6255,35 @@ process has been transmitted to the serial port. */)
6273 return process; 6255 return process;
6274} 6256}
6275 6257
6276/* On receipt of a signal that a child status has changed, loop asking 6258/* If the status of the process DESIRED has changed, return true and
6277 about children with changed statuses until the system says there 6259 set *STATUS to its exit status; otherwise, return false.
6278 are no more. 6260 If HAVE is nonnegative, assume that HAVE = waitpid (HAVE, STATUS, ...)
6261 has already been invoked, and do not invoke waitpid again. */
6262
6263static bool
6264process_status_retrieved (pid_t desired, pid_t have, int *status)
6265{
6266 if (have < 0)
6267 {
6268 /* Invoke waitpid only with a known process ID; do not invoke
6269 waitpid with a nonpositive argument. Otherwise, Emacs might
6270 reap an unwanted process by mistake. For example, invoking
6271 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
6272 so that another thread running glib won't find them. */
6273 do
6274 have = waitpid (desired, status, WNOHANG | WUNTRACED);
6275 while (have < 0 && errno == EINTR);
6276 }
6277
6278 return have == desired;
6279}
6280
6281/* If PID is nonnegative, the child process PID with wait status W has
6282 changed its status; record this and return true.
6283
6284 If PID is negative, ignore W, and look for known child processes
6285 of Emacs whose status have changed. For each one found, record its new
6286 status.
6279 6287
6280 All we do is change the status; we do not run sentinels or print 6288 All we do is change the status; we do not run sentinels or print
6281 notifications. That is saved for the next time keyboard input is 6289 notifications. That is saved for the next time keyboard input is
@@ -6298,13 +6306,23 @@ process has been transmitted to the serial port. */)
6298 ** Malloc WARNING: This should never call malloc either directly or 6306 ** Malloc WARNING: This should never call malloc either directly or
6299 indirectly; if it does, that is a bug */ 6307 indirectly; if it does, that is a bug */
6300 6308
6301/* Record the changed status of the child process PID with wait status W. */
6302void 6309void
6303record_child_status_change (pid_t pid, int w) 6310record_child_status_change (pid_t pid, int w)
6304{ 6311{
6305#ifdef SIGCHLD 6312#ifdef SIGCHLD
6306 Lisp_Object proc; 6313
6307 struct Lisp_Process *p; 6314# ifdef WNOHANG
6315 /* On POSIXish hosts, record at most one child only if we already
6316 know one child that has exited. */
6317 bool record_at_most_one_child = 0 <= pid;
6318# else
6319 /* On DOS_NT (the only porting target that lacks WNOHANG),
6320 record the status of at most one child process, since the SIGCHLD
6321 handler must return right away. If any more processes want to
6322 signal us, we will get another signal. */
6323 bool record_at_most_one_child = 1;
6324# endif
6325
6308 Lisp_Object tail; 6326 Lisp_Object tail;
6309 6327
6310 /* Find the process that signaled us, and record its status. */ 6328 /* Find the process that signaled us, and record its status. */
@@ -6312,68 +6330,69 @@ record_child_status_change (pid_t pid, int w)
6312 /* The process can have been deleted by Fdelete_process. */ 6330 /* The process can have been deleted by Fdelete_process. */
6313 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) 6331 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail))
6314 { 6332 {
6333 bool all_pids_are_fixnums
6334 = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t)
6335 && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM);
6315 Lisp_Object xpid = XCAR (tail); 6336 Lisp_Object xpid = XCAR (tail);
6316 if ((INTEGERP (xpid) && pid == XINT (xpid)) 6337 if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid))
6317 || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid)))
6318 { 6338 {
6319 XSETCAR (tail, Qnil); 6339 pid_t deleted_pid;
6320 return; 6340 if (INTEGERP (xpid))
6341 deleted_pid = XINT (xpid);
6342 else
6343 deleted_pid = XFLOAT_DATA (xpid);
6344 if (process_status_retrieved (deleted_pid, pid, &w))
6345 {
6346 XSETCAR (tail, Qnil);
6347 if (record_at_most_one_child)
6348 return;
6349 }
6321 } 6350 }
6322 } 6351 }
6323 6352
6324 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ 6353 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
6325 p = 0;
6326 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6354 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6327 { 6355 {
6328 proc = XCDR (XCAR (tail)); 6356 Lisp_Object proc = XCDR (XCAR (tail));
6329 p = XPROCESS (proc); 6357 struct Lisp_Process *p = XPROCESS (proc);
6330 if (EQ (p->type, Qreal) && p->pid == pid) 6358 if (p->alive && process_status_retrieved (p->pid, pid, &w))
6331 break; 6359 {
6332 p = 0; 6360 /* Change the status of the process that was found. */
6333 } 6361 p->tick = ++process_tick;
6334 6362 p->raw_status = w;
6335 /* Look for an asynchronous process whose pid hasn't been filled 6363 p->raw_status_new = 1;
6336 in yet. */
6337 if (! p)
6338 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6339 {
6340 proc = XCDR (XCAR (tail));
6341 p = XPROCESS (proc);
6342 if (p->pid == -1)
6343 break;
6344 p = 0;
6345 }
6346 6364
6347 /* Change the status of the process that was found. */ 6365 /* If process has terminated, stop waiting for its output. */
6348 if (p) 6366 if (WIFSIGNALED (w) || WIFEXITED (w))
6349 { 6367 {
6350 int clear_desc_flag = 0; 6368 int clear_desc_flag = 0;
6369 p->alive = 0;
6370 if (p->infd >= 0)
6371 clear_desc_flag = 1;
6351 6372
6352 p->tick = ++process_tick; 6373 /* clear_desc_flag avoids a compiler bug in Microsoft C. */
6353 p->raw_status = w; 6374 if (clear_desc_flag)
6354 p->raw_status_new = 1; 6375 {
6376 FD_CLR (p->infd, &input_wait_mask);
6377 FD_CLR (p->infd, &non_keyboard_wait_mask);
6378 }
6379 }
6355 6380
6356 /* If process has terminated, stop waiting for its output. */ 6381 /* Tell wait_reading_process_output that it needs to wake up and
6357 if ((WIFSIGNALED (w) || WIFEXITED (w)) 6382 look around. */
6358 && p->infd >= 0) 6383 if (input_available_clear_time)
6359 clear_desc_flag = 1; 6384 *input_available_clear_time = make_emacs_time (0, 0);
6360 6385
6361 /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ 6386 if (record_at_most_one_child)
6362 if (clear_desc_flag) 6387 return;
6363 {
6364 FD_CLR (p->infd, &input_wait_mask);
6365 FD_CLR (p->infd, &non_keyboard_wait_mask);
6366 } 6388 }
6367
6368 /* Tell wait_reading_process_output that it needs to wake up and
6369 look around. */
6370 if (input_available_clear_time)
6371 *input_available_clear_time = make_emacs_time (0, 0);
6372 } 6389 }
6373 /* There was no asynchronous process found for that pid: we have 6390
6374 a synchronous process. */ 6391 if (0 <= pid)
6375 else
6376 { 6392 {
6393 /* The caller successfully waited for a pid but no asynchronous
6394 process was found for it, so this is a synchronous process. */
6395
6377 synch_process_alive = 0; 6396 synch_process_alive = 0;
6378 6397
6379 /* Report the status of the synchronous process. */ 6398 /* Report the status of the synchronous process. */
@@ -6392,38 +6411,10 @@ record_child_status_change (pid_t pid, int w)
6392 6411
6393#ifdef SIGCHLD 6412#ifdef SIGCHLD
6394 6413
6395/* On some systems, the SIGCHLD handler must return right away. If
6396 any more processes want to signal us, we will get another signal.
6397 Otherwise, loop around to use up all the processes that have
6398 something to tell us. */
6399#if (defined WINDOWSNT \
6400 || (defined USG && !defined GNU_LINUX \
6401 && !(defined HPUX && defined WNOHANG)))
6402enum { CAN_HANDLE_MULTIPLE_CHILDREN = 0 };
6403#else
6404enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 };
6405#endif
6406
6407static void 6414static void
6408handle_child_signal (int sig) 6415handle_child_signal (int sig)
6409{ 6416{
6410 do 6417 record_child_status_change (-1, 0);
6411 {
6412 pid_t pid;
6413 int status;
6414
6415 do
6416 pid = waitpid (-1, &status, WNOHANG | WUNTRACED);
6417 while (pid < 0 && errno == EINTR);
6418
6419 /* PID == 0 means no processes found, PID == -1 means a real failure.
6420 Either way, we have done all our job. */
6421 if (pid <= 0)
6422 break;
6423
6424 record_child_status_change (pid, status);
6425 }
6426 while (CAN_HANDLE_MULTIPLE_CHILDREN);
6427} 6418}
6428 6419
6429static void 6420static void
diff --git a/src/process.h b/src/process.h
index ce3d2e702cc..74d1a124060 100644
--- a/src/process.h
+++ b/src/process.h
@@ -142,6 +142,9 @@ struct Lisp_Process
142 /* Flag to set coding-system of the process buffer from the 142 /* Flag to set coding-system of the process buffer from the
143 coding_system used to decode process output. */ 143 coding_system used to decode process output. */
144 unsigned int inherit_coding_system_flag : 1; 144 unsigned int inherit_coding_system_flag : 1;
145 /* Whether the process is alive, i.e., can be waited for. Running
146 processes can be waited for, but exited and fake processes cannot. */
147 unsigned int alive : 1;
145 /* Record the process status in the raw form in which it comes from `wait'. 148 /* Record the process status in the raw form in which it comes from `wait'.
146 This is to avoid consing in a signal handler. The `raw_status_new' 149 This is to avoid consing in a signal handler. The `raw_status_new'
147 flag indicates that `raw_status' contains a new status that still 150 flag indicates that `raw_status' contains a new status that still
diff --git a/src/profiler.c b/src/profiler.c
index 51580710f28..3d8f7243d2f 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -35,6 +35,9 @@ saturated_add (EMACS_INT a, EMACS_INT b)
35 35
36typedef struct Lisp_Hash_Table log_t; 36typedef struct Lisp_Hash_Table log_t;
37 37
38static Lisp_Object Qprofiler_backtrace_equal;
39static struct hash_table_test hashtest_profiler;
40
38static Lisp_Object 41static Lisp_Object
39make_log (int heap_size, int max_stack_depth) 42make_log (int heap_size, int max_stack_depth)
40{ 43{
@@ -42,10 +45,11 @@ make_log (int heap_size, int max_stack_depth)
42 a special way. This is OK as long as the object is not exposed 45 a special way. This is OK as long as the object is not exposed
43 to Elisp, i.e. until it is returned by *-profiler-log, after which 46 to Elisp, i.e. until it is returned by *-profiler-log, after which
44 it can't be used any more. */ 47 it can't be used any more. */
45 Lisp_Object log = make_hash_table (Qequal, make_number (heap_size), 48 Lisp_Object log = make_hash_table (hashtest_profiler,
49 make_number (heap_size),
46 make_float (DEFAULT_REHASH_SIZE), 50 make_float (DEFAULT_REHASH_SIZE),
47 make_float (DEFAULT_REHASH_THRESHOLD), 51 make_float (DEFAULT_REHASH_THRESHOLD),
48 Qnil, Qnil, Qnil); 52 Qnil);
49 struct Lisp_Hash_Table *h = XHASH_TABLE (log); 53 struct Lisp_Hash_Table *h = XHASH_TABLE (log);
50 54
51 /* What is special about our hash-tables is that the keys are pre-filled 55 /* What is special about our hash-tables is that the keys are pre-filled
@@ -238,8 +242,6 @@ handle_profiler_signal (int signal)
238 cpu_gc_count = saturated_add (cpu_gc_count, 1); 242 cpu_gc_count = saturated_add (cpu_gc_count, 1);
239 else 243 else
240 { 244 {
241 Lisp_Object oquit;
242 bool saved_pending_signals;
243 EMACS_INT count = 1; 245 EMACS_INT count = 1;
244#ifdef HAVE_ITIMERSPEC 246#ifdef HAVE_ITIMERSPEC
245 if (profiler_timer_ok) 247 if (profiler_timer_ok)
@@ -249,19 +251,8 @@ handle_profiler_signal (int signal)
249 count += overruns; 251 count += overruns;
250 } 252 }
251#endif 253#endif
252 /* record_backtrace uses hash functions that call Fequal, which
253 uses QUIT, which can call malloc, which can cause disaster in
254 a signal handler. So inhibit QUIT. */
255 oquit = Vinhibit_quit;
256 saved_pending_signals = pending_signals;
257 Vinhibit_quit = Qt;
258 pending_signals = 0;
259
260 eassert (HASH_TABLE_P (cpu_log)); 254 eassert (HASH_TABLE_P (cpu_log));
261 record_backtrace (XHASH_TABLE (cpu_log), count); 255 record_backtrace (XHASH_TABLE (cpu_log), count);
262
263 Vinhibit_quit = oquit;
264 pending_signals = saved_pending_signals;
265 } 256 }
266} 257}
267 258
@@ -515,6 +506,66 @@ malloc_probe (size_t size)
515 record_backtrace (XHASH_TABLE (memory_log), min (size, MOST_POSITIVE_FIXNUM)); 506 record_backtrace (XHASH_TABLE (memory_log), min (size, MOST_POSITIVE_FIXNUM));
516} 507}
517 508
509DEFUN ("function-equal", Ffunction_equal, Sfunction_equal, 2, 2, 0,
510 doc: /* Return non-nil if F1 and F2 come from the same source.
511Used to determine if different closures are just different instances of
512the same lambda expression, or are really unrelated function. */)
513 (Lisp_Object f1, Lisp_Object f2)
514{
515 bool res;
516 if (EQ (f1, f2))
517 res = true;
518 else if (COMPILEDP (f1) && COMPILEDP (f2))
519 res = EQ (AREF (f1, COMPILED_BYTECODE), AREF (f2, COMPILED_BYTECODE));
520 else if (CONSP (f1) && CONSP (f2) && CONSP (XCDR (f1)) && CONSP (XCDR (f2))
521 && EQ (Qclosure, XCAR (f1))
522 && EQ (Qclosure, XCAR (f2)))
523 res = EQ (XCDR (XCDR (f1)), XCDR (XCDR (f2)));
524 else
525 res = false;
526 return res ? Qt : Qnil;
527}
528
529static bool
530cmpfn_profiler (struct hash_table_test *t,
531 Lisp_Object bt1, Lisp_Object bt2)
532{
533 if (VECTORP (bt1) && VECTORP (bt2))
534 {
535 ptrdiff_t i, l = ASIZE (bt1);
536 if (l != ASIZE (bt2))
537 return false;
538 for (i = 0; i < l; i++)
539 if (NILP (Ffunction_equal (AREF (bt1, i), AREF (bt2, i))))
540 return false;
541 return true;
542 }
543 else
544 return EQ (bt1, bt2);
545}
546
547static EMACS_UINT
548hashfn_profiler (struct hash_table_test *ht, Lisp_Object bt)
549{
550 if (VECTORP (bt))
551 {
552 EMACS_UINT hash = 0;
553 ptrdiff_t i, l = ASIZE (bt);
554 for (i = 0; i < l; i++)
555 {
556 Lisp_Object f = AREF (bt, i);
557 EMACS_UINT hash1
558 = (COMPILEDP (f) ? XHASH (AREF (f, COMPILED_BYTECODE))
559 : (CONSP (f) && CONSP (XCDR (f)) && EQ (Qclosure, XCAR (f)))
560 ? XHASH (XCDR (XCDR (f))) : XHASH (f));
561 hash = sxhash_combine (hash, hash1);
562 }
563 return (hash & INTMASK);
564 }
565 else
566 return XHASH (bt);
567}
568
518void 569void
519syms_of_profiler (void) 570syms_of_profiler (void)
520{ 571{
@@ -527,6 +578,16 @@ If the log gets full, some of the least-seen call-stacks will be evicted
527to make room for new entries. */); 578to make room for new entries. */);
528 profiler_log_size = 10000; 579 profiler_log_size = 10000;
529 580
581 DEFSYM (Qprofiler_backtrace_equal, "profiler-backtrace-equal");
582 {
583 struct hash_table_test test
584 = { Qprofiler_backtrace_equal, Qnil, Qnil,
585 cmpfn_profiler, hashfn_profiler };
586 hashtest_profiler = test;
587 }
588
589 defsubr (&Sfunction_equal);
590
530#ifdef PROFILER_CPU_SUPPORT 591#ifdef PROFILER_CPU_SUPPORT
531 profiler_cpu_running = NOT_RUNNING; 592 profiler_cpu_running = NOT_RUNNING;
532 cpu_log = Qnil; 593 cpu_log = Qnil;
diff --git a/src/ralloc.c b/src/ralloc.c
index 11897411930..e5bf76b0e6d 100644
--- a/src/ralloc.c
+++ b/src/ralloc.c
@@ -327,6 +327,8 @@ relinquish (void)
327 327
328 if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess) 328 if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess)
329 { 329 {
330 heap_ptr lh_prev;
331
330 /* This heap should have no blocs in it. If it does, we 332 /* This heap should have no blocs in it. If it does, we
331 cannot return it to the system. */ 333 cannot return it to the system. */
332 if (last_heap->first_bloc != NIL_BLOC 334 if (last_heap->first_bloc != NIL_BLOC
@@ -335,28 +337,26 @@ relinquish (void)
335 337
336 /* Return the last heap, with its header, to the system. */ 338 /* Return the last heap, with its header, to the system. */
337 excess = (char *)last_heap->end - (char *)last_heap->start; 339 excess = (char *)last_heap->end - (char *)last_heap->start;
338 last_heap = last_heap->prev; 340 lh_prev = last_heap->prev;
339 last_heap->next = NIL_HEAP; 341 /* If the system doesn't want that much memory back, leave
342 last_heap unaltered to reflect that. This can occur if
343 break_value is still within the original data segment. */
344 if ((*real_morecore) (- excess) != 0)
345 {
346 last_heap = lh_prev;
347 last_heap->next = NIL_HEAP;
348 }
340 } 349 }
341 else 350 else
342 { 351 {
343 excess = (char *) last_heap->end 352 excess = (char *) last_heap->end
344 - (char *) ROUNDUP ((char *)last_heap->end - excess); 353 - (char *) ROUNDUP ((char *)last_heap->end - excess);
345 last_heap->end = (char *) last_heap->end - excess; 354 /* If the system doesn't want that much memory back, leave
346 } 355 the end of the last heap unchanged to reflect that. This
347 356 can occur if break_value is still within the original
348 if ((*real_morecore) (- excess) == 0) 357 data segment. */
349 { 358 if ((*real_morecore) (- excess) != 0)
350 /* If the system didn't want that much memory back, adjust 359 last_heap->end = (char *) last_heap->end - excess;
351 the end of the last heap to reflect that. This can occur
352 if break_value is still within the original data segment. */
353 last_heap->end = (char *) last_heap->end + excess;
354 /* Make sure that the result of the adjustment is accurate.
355 It should be, for the else clause above; the other case,
356 which returns the entire last heap to the system, seems
357 unlikely to trigger this mode of failure. */
358 if (last_heap->end != (*real_morecore) (0))
359 emacs_abort ();
360 } 360 }
361 } 361 }
362} 362}
diff --git a/src/regex.c b/src/regex.c
index 7443eff3977..1473551e6cc 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -28,7 +28,7 @@
28 rather than at run-time, so that re_match can be reentrant. 28 rather than at run-time, so that re_match can be reentrant.
29*/ 29*/
30 30
31/* AIX requires this to be the first thing in the file. */ 31/* AIX requires this to be the first thing in the file. */
32#if defined _AIX && !defined REGEX_MALLOC 32#if defined _AIX && !defined REGEX_MALLOC
33 #pragma alloca 33 #pragma alloca
34#endif 34#endif
diff --git a/src/sysdep.c b/src/sysdep.c
index 63eac5d9e09..aa9d0f38c3c 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -452,7 +452,7 @@ sys_suspend (void)
452#if defined (SIGTSTP) && !defined (MSDOS) 452#if defined (SIGTSTP) && !defined (MSDOS)
453 453
454 { 454 {
455 pid_t pgrp = EMACS_GETPGRP (0); 455 pid_t pgrp = getpgrp ();
456 EMACS_KILLPG (pgrp, SIGTSTP); 456 EMACS_KILLPG (pgrp, SIGTSTP);
457 } 457 }
458 458
@@ -709,7 +709,7 @@ static pid_t inherited_pgroup;
709void 709void
710init_foreground_group (void) 710init_foreground_group (void)
711{ 711{
712 pid_t pgrp = EMACS_GETPGRP (0); 712 pid_t pgrp = getpgrp ();
713 inherited_pgroup = getpid () == pgrp ? 0 : pgrp; 713 inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
714} 714}
715 715
diff --git a/src/systty.h b/src/systty.h
index b7f36c6c259..80bcaedf740 100644
--- a/src/systty.h
+++ b/src/systty.h
@@ -52,27 +52,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
52#endif /* not CDEL */ 52#endif /* not CDEL */
53#endif /* not _POSIX_VDISABLE */ 53#endif /* not _POSIX_VDISABLE */
54 54
55/* Get the number of characters queued for output. */
56
57/* EMACS_OUTQSIZE(FD, int *SIZE) stores the number of characters
58 queued for output to the terminal FD in *SIZE, if FD is a tty.
59 Returns -1 if there was an error (i.e. FD is not a tty), 0
60 otherwise. */
61#ifdef TIOCOUTQ
62#define EMACS_OUTQSIZE(fd, size) (ioctl ((fd), TIOCOUTQ, (size)))
63#endif
64
65
66/* Manipulate a terminal's current process group. */
67
68/* EMACS_GETPGRP (arg) returns the process group of the process. */
69
70#if defined (GETPGRP_VOID)
71# define EMACS_GETPGRP(x) getpgrp()
72#else /* !GETPGRP_VOID */
73# define EMACS_GETPGRP(x) getpgrp(x)
74#endif /* !GETPGRP_VOID */
75
76/* Manipulate a TTY's input/output processing parameters. */ 55/* Manipulate a TTY's input/output processing parameters. */
77 56
78/* struct emacs_tty is a structure used to hold the current tty 57/* struct emacs_tty is a structure used to hold the current tty
diff --git a/src/term.c b/src/term.c
index 74b02b0af27..578c701858f 100644
--- a/src/term.c
+++ b/src/term.c
@@ -133,10 +133,6 @@ enum no_color_bit
133 133
134static int max_frame_cols; 134static int max_frame_cols;
135 135
136/* Non-zero if we have dropped our controlling tty and therefore
137 should not open a frame on stdout. */
138static int no_controlling_tty;
139
140 136
141 137
142#ifdef HAVE_GPM 138#ifdef HAVE_GPM
@@ -2918,36 +2914,9 @@ set_tty_hooks (struct terminal *terminal)
2918static void 2914static void
2919dissociate_if_controlling_tty (int fd) 2915dissociate_if_controlling_tty (int fd)
2920{ 2916{
2921#ifndef DOS_NT
2922 pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ 2917 pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */
2923 if (pgid != -1) 2918 if (0 <= pgid)
2924 { 2919 setsid ();
2925#if defined (USG5)
2926 setpgrp ();
2927 no_controlling_tty = 1;
2928#elif defined (CYGWIN)
2929 setsid ();
2930 no_controlling_tty = 1;
2931#else
2932#ifdef TIOCNOTTY /* Try BSD ioctls. */
2933 sigset_t blocked;
2934 sigemptyset (&blocked);
2935 sigaddset (&blocked, SIGTTOU);
2936 pthread_sigmask (SIG_BLOCK, &blocked, 0);
2937 fd = emacs_open (DEV_TTY, O_RDWR, 0);
2938 if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
2939 {
2940 no_controlling_tty = 1;
2941 }
2942 if (fd != -1)
2943 emacs_close (fd);
2944 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
2945#else
2946# error "Unknown system."
2947#endif /* ! TIOCNOTTY */
2948#endif /* ! USG */
2949 }
2950#endif /* !DOS_NT */
2951} 2920}
2952 2921
2953/* Create a termcap display on the tty device with the given name and 2922/* Create a termcap display on the tty device with the given name and
@@ -3235,7 +3204,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3235 FrameCols (tty) = FRAME_COLS (f); 3204 FrameCols (tty) = FRAME_COLS (f);
3236 tty->specified_window = FRAME_LINES (f); 3205 tty->specified_window = FRAME_LINES (f);
3237 3206
3238 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
3239 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; 3207 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
3240 terminal->char_ins_del_ok = 1; 3208 terminal->char_ins_del_ok = 1;
3241 baud_rate = 19200; 3209 baud_rate = 19200;
diff --git a/src/termhooks.h b/src/termhooks.h
index bac86423a4b..d1ee7138d67 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -243,16 +243,8 @@ struct input_event
243 Lisp_Object x, y; 243 Lisp_Object x, y;
244 Time timestamp; 244 Time timestamp;
245 245
246 /* This is padding just to put the frame_or_window field 246 /* This field is copied into a vector while the event is in
247 past the size of struct selection_input_event. */ 247 the queue, so that garbage collections won't kill it. */
248 int *padding[2];
249
250 /* This field is copied into a vector while the event is in the queue,
251 so that garbage collections won't kill it. */
252 /* In a menu_bar_event, this is a cons cell whose car is the frame
253 and whose cdr is the Lisp object that is the event's value. */
254 /* This field is last so that struct selection_input_event
255 does not overlap with it. */
256 Lisp_Object frame_or_window; 248 Lisp_Object frame_or_window;
257 249
258 /* Additional event argument. This is used for TOOL_BAR_EVENTs and 250 /* Additional event argument. This is used for TOOL_BAR_EVENTs and
@@ -423,14 +415,6 @@ struct terminal
423 int memory_below_frame; /* Terminal remembers lines scrolled 415 int memory_below_frame; /* Terminal remembers lines scrolled
424 off bottom */ 416 off bottom */
425 417
426#if 0 /* These are not used anywhere. */
427 /* EMACS_INT baud_rate; */ /* Output speed in baud */
428 int min_padding_speed; /* Speed below which no padding necessary. */
429 int dont_calculate_costs; /* Nonzero means don't bother computing
430 various cost tables; we won't use them. */
431#endif
432
433
434 /* Window-based redisplay interface for this device (0 for tty 418 /* Window-based redisplay interface for this device (0 for tty
435 devices). */ 419 devices). */
436 struct redisplay_interface *rif; 420 struct redisplay_interface *rif;
@@ -478,10 +462,7 @@ struct terminal
478 Otherwise, set *bar_window to Qnil, and *x and *y to the column and 462 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
479 row of the character cell the mouse is over. 463 row of the character cell the mouse is over.
480 464
481 Set *time to the time the mouse was at the returned position. 465 Set *time to the time the mouse was at the returned position. */
482
483 This should clear mouse_moved until the next motion
484 event arrives. */
485 void (*mouse_position_hook) (struct frame **f, int, 466 void (*mouse_position_hook) (struct frame **f, int,
486 Lisp_Object *bar_window, 467 Lisp_Object *bar_window,
487 enum scroll_bar_part *part, 468 enum scroll_bar_part *part,
@@ -489,11 +470,6 @@ struct terminal
489 Lisp_Object *y, 470 Lisp_Object *y,
490 Time *); 471 Time *);
491 472
492 /* The window system handling code should set this if the mouse has
493 moved since the last call to the mouse_position_hook. Calling that
494 hook should clear this. */
495 int mouse_moved;
496
497 /* When a frame's focus redirection is changed, this hook tells the 473 /* When a frame's focus redirection is changed, this hook tells the
498 window system code to re-decide where to put the highlight. Under 474 window system code to re-decide where to put the highlight. Under
499 X, this means that Emacs lies about where the focus is. */ 475 X, this means that Emacs lies about where the focus is. */
diff --git a/src/terminal.c b/src/terminal.c
index 2c0c60e7345..854ca61f19c 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -360,14 +360,7 @@ If FRAME is nil, the selected frame is used.
360The terminal device is represented by its integer identifier. */) 360The terminal device is represented by its integer identifier. */)
361 (Lisp_Object frame) 361 (Lisp_Object frame)
362{ 362{
363 struct terminal *t; 363 struct terminal *t = FRAME_TERMINAL (decode_live_frame (frame));
364
365 if (NILP (frame))
366 frame = selected_frame;
367
368 CHECK_LIVE_FRAME (frame);
369
370 t = FRAME_TERMINAL (XFRAME (frame));
371 364
372 if (!t) 365 if (!t)
373 return Qnil; 366 return Qnil;
diff --git a/src/w32fns.c b/src/w32fns.c
index 210eaf1a188..6458054013f 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -26,6 +26,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#include <limits.h> 26#include <limits.h>
27#include <errno.h> 27#include <errno.h>
28#include <math.h> 28#include <math.h>
29#include <fcntl.h>
30#include <unistd.h>
29 31
30#include "lisp.h" 32#include "lisp.h"
31#include "w32term.h" 33#include "w32term.h"
@@ -262,12 +264,8 @@ have_menus_p (void)
262FRAME_PTR 264FRAME_PTR
263check_x_frame (Lisp_Object frame) 265check_x_frame (Lisp_Object frame)
264{ 266{
265 FRAME_PTR f; 267 struct frame *f = decode_live_frame (frame);
266 268
267 if (NILP (frame))
268 frame = selected_frame;
269 CHECK_LIVE_FRAME (frame);
270 f = XFRAME (frame);
271 if (! FRAME_W32_P (f)) 269 if (! FRAME_W32_P (f))
272 error ("Non-W32 frame used"); 270 error ("Non-W32 frame used");
273 return f; 271 return f;
@@ -306,19 +304,14 @@ check_x_display_info (Lisp_Object frame)
306/* Return the Emacs frame-object corresponding to an w32 window. 304/* Return the Emacs frame-object corresponding to an w32 window.
307 It could be the frame's main window or an icon window. */ 305 It could be the frame's main window or an icon window. */
308 306
309/* This function can be called during GC, so use GC_xxx type test macros. */
310
311struct frame * 307struct frame *
312x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc) 308x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
313{ 309{
314 Lisp_Object tail, frame; 310 Lisp_Object tail, frame;
315 struct frame *f; 311 struct frame *f;
316 312
317 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 313 FOR_EACH_FRAME (tail, frame)
318 { 314 {
319 frame = XCAR (tail);
320 if (!FRAMEP (frame))
321 continue;
322 f = XFRAME (frame); 315 f = XFRAME (frame);
323 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo) 316 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
324 continue; 317 continue;
@@ -2087,8 +2080,35 @@ sync_modifiers (void)
2087static int 2080static int
2088modifier_set (int vkey) 2081modifier_set (int vkey)
2089{ 2082{
2090 if (vkey == VK_CAPITAL || vkey == VK_SCROLL) 2083 /* Warning: The fact that VK_NUMLOCK is not treated as the other 2
2091 return (GetKeyState (vkey) & 0x1); 2084 toggle keys is not an omission! If you want to add it, you will
2085 have to make changes in the default sub-case of the WM_KEYDOWN
2086 switch, because if the NUMLOCK modifier is set, the code there
2087 will directly convert any key that looks like an ASCII letter,
2088 and also downcase those that look like upper-case ASCII. */
2089 if (vkey == VK_CAPITAL)
2090 {
2091 if (NILP (Vw32_enable_caps_lock))
2092 return 0;
2093 else
2094 return (GetKeyState (vkey) & 0x1);
2095 }
2096 if (vkey == VK_SCROLL)
2097 {
2098 if (NILP (Vw32_scroll_lock_modifier)
2099 /* w32-scroll-lock-modifier can be any non-nil value that is
2100 not one of the modifiers, in which case it shall be ignored. */
2101 || !( EQ (Vw32_scroll_lock_modifier, Qhyper)
2102 || EQ (Vw32_scroll_lock_modifier, Qsuper)
2103 || EQ (Vw32_scroll_lock_modifier, Qmeta)
2104 || EQ (Vw32_scroll_lock_modifier, Qalt)
2105 || EQ (Vw32_scroll_lock_modifier, Qcontrol)
2106 || EQ (Vw32_scroll_lock_modifier, Qshift)))
2107 return 0;
2108 else
2109 return (GetKeyState (vkey) & 0x1);
2110 }
2111
2092 if (!modifiers_recorded) 2112 if (!modifiers_recorded)
2093 return (GetKeyState (vkey) & 0x8000); 2113 return (GetKeyState (vkey) & 0x8000);
2094 2114
@@ -4286,9 +4306,6 @@ This function is an internal primitive--use `make-frame' instead. */)
4286 4306
4287 XSETFRAME (frame, f); 4307 XSETFRAME (frame, f);
4288 4308
4289 /* Note that Windows does support scroll bars. */
4290 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
4291
4292 /* By default, make scrollbars the system standard width. */ 4309 /* By default, make scrollbars the system standard width. */
4293 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL); 4310 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
4294 4311
@@ -5389,7 +5406,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5389 Finsert (1, &text); 5406 Finsert (1, &text);
5390 set_buffer_internal_1 (old_buffer); 5407 set_buffer_internal_1 (old_buffer);
5391 5408
5392 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
5393 record_unwind_protect (unwind_create_tip_frame, frame); 5409 record_unwind_protect (unwind_create_tip_frame, frame);
5394 5410
5395 /* By setting the output method, we're essentially saying that 5411 /* By setting the output method, we're essentially saying that
@@ -7700,6 +7716,30 @@ globals_of_w32fns (void)
7700 syms_of_w32uniscribe (); 7716 syms_of_w32uniscribe ();
7701} 7717}
7702 7718
7719typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *,
7720 PULONG);
7721
7722#define BACKTRACE_LIMIT_MAX 62
7723
7724int
7725w32_backtrace (void **buffer, int limit)
7726{
7727 static CaptureStackBackTrace_proc s_pfn_CaptureStackBackTrace = NULL;
7728 HMODULE hm_kernel32 = NULL;
7729
7730 if (!s_pfn_CaptureStackBackTrace)
7731 {
7732 hm_kernel32 = LoadLibrary ("Kernel32.dll");
7733 s_pfn_CaptureStackBackTrace =
7734 (CaptureStackBackTrace_proc) GetProcAddress (hm_kernel32,
7735 "RtlCaptureStackBackTrace");
7736 }
7737 if (s_pfn_CaptureStackBackTrace)
7738 return s_pfn_CaptureStackBackTrace (0, min (BACKTRACE_LIMIT_MAX, limit),
7739 buffer, NULL);
7740 return 0;
7741}
7742
7703void 7743void
7704emacs_abort (void) 7744emacs_abort (void)
7705{ 7745{
@@ -7707,7 +7747,10 @@ emacs_abort (void)
7707 button = MessageBox (NULL, 7747 button = MessageBox (NULL,
7708 "A fatal error has occurred!\n\n" 7748 "A fatal error has occurred!\n\n"
7709 "Would you like to attach a debugger?\n\n" 7749 "Would you like to attach a debugger?\n\n"
7710 "Select YES to debug, NO to abort Emacs" 7750 "Select:\n"
7751 "YES -- to debug Emacs, or\n"
7752 "NO -- to abort Emacs and produce a backtrace\n"
7753 " (emacs_backtrace.txt in current directory)."
7711#if __GNUC__ 7754#if __GNUC__
7712 "\n\n(type \"gdb -p <emacs-PID>\" and\n" 7755 "\n\n(type \"gdb -p <emacs-PID>\" and\n"
7713 "\"continue\" inside GDB before clicking YES.)" 7756 "\"continue\" inside GDB before clicking YES.)"
@@ -7722,7 +7765,59 @@ emacs_abort (void)
7722 exit (2); /* tell the compiler we will never return */ 7765 exit (2); /* tell the compiler we will never return */
7723 case IDNO: 7766 case IDNO:
7724 default: 7767 default:
7725 abort (); 7768 {
7726 break; 7769 void *stack[BACKTRACE_LIMIT_MAX + 1];
7770 int i = w32_backtrace (stack, BACKTRACE_LIMIT_MAX + 1);
7771
7772 if (i)
7773 {
7774#ifdef CYGWIN
7775 int stderr_fd = 2;
7776#else
7777 HANDLE errout = GetStdHandle (STD_ERROR_HANDLE);
7778 int stderr_fd = -1;
7779#endif
7780 int errfile_fd = -1;
7781 int j;
7782
7783#ifndef CYGWIN
7784 if (errout && errout != INVALID_HANDLE_VALUE)
7785 stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND | O_BINARY);
7786#endif
7787 if (stderr_fd >= 0)
7788 write (stderr_fd, "\r\nBacktrace:\r\n", 14);
7789 errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
7790 if (errfile_fd >= 0)
7791 {
7792 lseek (errfile_fd, 0L, SEEK_END);
7793 write (errfile_fd, "\r\nBacktrace:\r\n", 14);
7794 }
7795
7796 for (j = 0; j < i; j++)
7797 {
7798 char buf[INT_BUFSIZE_BOUND (void *)];
7799
7800 /* stack[] gives the return addresses, whereas we want
7801 the address of the call, so decrease each address
7802 by approximate size of 1 CALL instruction. */
7803 sprintf (buf, "0x%p\r\n", stack[j] - sizeof(void *));
7804 if (stderr_fd >= 0)
7805 write (stderr_fd, buf, strlen (buf));
7806 if (errfile_fd >= 0)
7807 write (errfile_fd, buf, strlen (buf));
7808 }
7809 if (i == BACKTRACE_LIMIT_MAX)
7810 {
7811 if (stderr_fd >= 0)
7812 write (stderr_fd, "...\r\n", 5);
7813 if (errfile_fd >= 0)
7814 write (errfile_fd, "...\r\n", 5);
7815 }
7816 if (errfile_fd >= 0)
7817 close (errfile_fd);
7818 }
7819 abort ();
7820 break;
7821 }
7727 } 7822 }
7728} 7823}
diff --git a/src/w32proc.c b/src/w32proc.c
index 73013a3b013..e074ece020d 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -230,14 +230,14 @@ sigismember (const sigset_t *set, int signo)
230 return (*set & (1U << signo)) != 0; 230 return (*set & (1U << signo)) != 0;
231} 231}
232 232
233int 233pid_t
234setpgrp (int pid, int gid) 234getpgrp (void)
235{ 235{
236 return 0; 236 return getpid ();
237} 237}
238 238
239pid_t 239pid_t
240getpgrp (void) 240tcgetpgrp (int fd)
241{ 241{
242 return getpid (); 242 return getpid ();
243} 243}
@@ -248,6 +248,12 @@ setpgid (pid_t pid, pid_t pgid)
248 return 0; 248 return 0;
249} 249}
250 250
251pid_t
252setsid (void)
253{
254 return getpid ();
255}
256
251/* Emulations of interval timers. 257/* Emulations of interval timers.
252 258
253 Limitations: only ITIMER_REAL and ITIMER_PROF are supported. 259 Limitations: only ITIMER_REAL and ITIMER_PROF are supported.
diff --git a/src/w32term.c b/src/w32term.c
index 3ebd849ec31..e53fa5e7756 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3555,16 +3555,11 @@ w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
3555static struct scroll_bar * 3555static struct scroll_bar *
3556x_window_to_scroll_bar (Window window_id) 3556x_window_to_scroll_bar (Window window_id)
3557{ 3557{
3558 Lisp_Object tail; 3558 Lisp_Object tail, frame;
3559 3559
3560 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 3560 FOR_EACH_FRAME (tail, frame)
3561 { 3561 {
3562 Lisp_Object frame, bar, condemned; 3562 Lisp_Object bar, condemned;
3563
3564 frame = XCAR (tail);
3565 /* All elements of Vframe_list should be frames. */
3566 if (! FRAMEP (frame))
3567 emacs_abort ();
3568 3563
3569 /* Scan this frame's scroll bar list for a scroll bar with the 3564 /* Scan this frame's scroll bar list for a scroll bar with the
3570 right window ID. */ 3565 right window ID. */
@@ -3744,7 +3739,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
3744 HWND hwnd; 3739 HWND hwnd;
3745 SCROLLINFO si; 3740 SCROLLINFO si;
3746 struct scroll_bar *bar 3741 struct scroll_bar *bar
3747 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil)); 3742 = XSCROLL_BAR (Fmake_vector (make_number (VECSIZE (struct scroll_bar)), Qnil));
3748 Lisp_Object barobj; 3743 Lisp_Object barobj;
3749 3744
3750 block_input (); 3745 block_input ();
diff --git a/src/w32term.h b/src/w32term.h
index 14b3d1ffc42..98186a7d363 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -415,9 +415,8 @@ extern struct w32_output w32term_display;
415 415
416struct scroll_bar { 416struct scroll_bar {
417 417
418 /* These fields are shared by all vectors. */ 418 /* This field is shared by all vectors. */
419 EMACS_INT size_from_Lisp_Vector_struct; 419 struct vectorlike_header header;
420 struct Lisp_Vector *next_from_Lisp_Vector_struct;
421 420
422 /* The window we're a scroll bar for. */ 421 /* The window we're a scroll bar for. */
423 Lisp_Object window; 422 Lisp_Object window;
@@ -460,12 +459,6 @@ struct scroll_bar {
460 Lisp_Object fringe_extended_p; 459 Lisp_Object fringe_extended_p;
461}; 460};
462 461
463/* The number of elements a vector holding a struct scroll_bar needs. */
464#define SCROLL_BAR_VEC_SIZE \
465 ((sizeof (struct scroll_bar) \
466 - sizeof (EMACS_INT) - sizeof (struct Lisp_Vector *)) \
467 / word_size)
468
469/* Turning a lisp vector value into a pointer to a struct scroll_bar. */ 462/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
470#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec)) 463#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
471 464
diff --git a/src/widget.c b/src/widget.c
index 1f472c6231c..b4f7335c652 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -650,6 +650,16 @@ EmacsFrameInitialize (Widget request, Widget new, ArgList dum1, Cardinal *dum2)
650 set_frame_size (ew); 650 set_frame_size (ew);
651} 651}
652 652
653static void
654resize_cb (Widget widget,
655 XtPointer closure,
656 XEvent* event,
657 Boolean* continue_to_dispatch)
658{
659 EmacsFrame ew = (EmacsFrame) widget;
660 EmacsFrameResize (widget);
661}
662
653 663
654static void 664static void
655EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs) 665EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs)
@@ -665,6 +675,9 @@ EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs
665 *mask |= CWEventMask; 675 *mask |= CWEventMask;
666 XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask, 676 XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
667 attrs); 677 attrs);
678 /* Some ConfigureNotify events does not end up in EmacsFrameResize so
679 make sure we get them all. Seen with xfcwm4 for example. */
680 XtAddRawEventHandler (widget, StructureNotifyMask, False, resize_cb, NULL);
668 update_wm_hints (ew); 681 update_wm_hints (ew);
669} 682}
670 683
@@ -691,15 +704,22 @@ EmacsFrameResize (Widget widget)
691{ 704{
692 EmacsFrame ew = (EmacsFrame)widget; 705 EmacsFrame ew = (EmacsFrame)widget;
693 struct frame *f = ew->emacs_frame.frame; 706 struct frame *f = ew->emacs_frame.frame;
707 struct x_output *x = f->output_data.x;
694 int columns; 708 int columns;
695 int rows; 709 int rows;
696 710
697 pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows); 711 pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows);
698 change_frame_size (f, rows, columns, 0, 1, 0); 712 if (columns != FRAME_COLS (f)
699 update_wm_hints (ew); 713 || rows != FRAME_LINES (f)
700 update_various_frame_slots (ew); 714 || ew->core.width != FRAME_PIXEL_WIDTH (f)
715 || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f))
716 {
717 change_frame_size (f, rows, columns, 0, 1, 0);
718 update_wm_hints (ew);
719 update_various_frame_slots (ew);
701 720
702 cancel_mouse_face (f); 721 cancel_mouse_face (f);
722 }
703} 723}
704 724
705static Boolean 725static Boolean
diff --git a/src/window.c b/src/window.c
index dfcabda59b9..9f3474fcd53 100644
--- a/src/window.c
+++ b/src/window.c
@@ -244,7 +244,7 @@ decode_live_window (register Lisp_Object window)
244 return XWINDOW (window); 244 return XWINDOW (window);
245} 245}
246 246
247static struct window * 247struct window *
248decode_any_window (register Lisp_Object window) 248decode_any_window (register Lisp_Object window)
249{ 249{
250 struct window *w; 250 struct window *w;
@@ -270,6 +270,15 @@ decode_valid_window (register Lisp_Object window)
270 return w; 270 return w;
271} 271}
272 272
273/* Build a frequently used 4-integer (X Y W H) list. */
274
275static Lisp_Object
276list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h)
277{
278 return list4 (make_number (x), make_number (y),
279 make_number (w), make_number (h));
280}
281
273DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, 282DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
274 doc: /* Return t if OBJECT is a window and nil otherwise. */) 283 doc: /* Return t if OBJECT is a window and nil otherwise. */)
275 (Lisp_Object object) 284 (Lisp_Object object)
@@ -296,7 +305,7 @@ Internal windows and deleted windows are not live. */)
296} 305}
297 306
298/* Frames and windows. */ 307/* Frames and windows. */
299DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0, 308DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 0, 1, 0,
300 doc: /* Return the frame that window WINDOW is on. 309 doc: /* Return the frame that window WINDOW is on.
301WINDOW must be a valid window and defaults to the selected one. */) 310WINDOW must be a valid window and defaults to the selected one. */)
302 (Lisp_Object window) 311 (Lisp_Object window)
@@ -331,10 +340,7 @@ DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
331If FRAME is omitted or nil, it defaults to the selected frame. */) 340If FRAME is omitted or nil, it defaults to the selected frame. */)
332 (Lisp_Object frame) 341 (Lisp_Object frame)
333{ 342{
334 if (NILP (frame)) 343 return FRAME_MINIBUF_WINDOW (decode_live_frame (frame));
335 frame = selected_frame;
336 CHECK_LIVE_FRAME (frame);
337 return FRAME_MINIBUF_WINDOW (XFRAME (frame));
338} 344}
339 345
340DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, 346DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p,
@@ -556,7 +562,7 @@ Return nil for a window with no parent (e.g. a root window). */)
556 return decode_valid_window (window)->parent; 562 return decode_valid_window (window)->parent;
557} 563}
558 564
559DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 1, 1, 0, 565DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 0, 1, 0,
560 doc: /* Return the topmost child window of window WINDOW. 566 doc: /* Return the topmost child window of window WINDOW.
561WINDOW must be a valid window and defaults to the selected one. 567WINDOW must be a valid window and defaults to the selected one.
562Return nil if WINDOW is a live window (live windows have no children). 568Return nil if WINDOW is a live window (live windows have no children).
@@ -564,11 +570,10 @@ Return nil if WINDOW is an internal window whose children form a
564horizontal combination. */) 570horizontal combination. */)
565 (Lisp_Object window) 571 (Lisp_Object window)
566{ 572{
567 CHECK_WINDOW (window);
568 return decode_valid_window (window)->vchild; 573 return decode_valid_window (window)->vchild;
569} 574}
570 575
571DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 1, 1, 0, 576DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
572 doc: /* Return the leftmost child window of window WINDOW. 577 doc: /* Return the leftmost child window of window WINDOW.
573WINDOW must be a valid window and defaults to the selected one. 578WINDOW must be a valid window and defaults to the selected one.
574Return nil if WINDOW is a live window (live windows have no children). 579Return nil if WINDOW is a live window (live windows have no children).
@@ -576,7 +581,6 @@ Return nil if WINDOW is an internal window whose children form a
576vertical combination. */) 581vertical combination. */)
577 (Lisp_Object window) 582 (Lisp_Object window)
578{ 583{
579 CHECK_WINDOW (window);
580 return decode_valid_window (window)->hchild; 584 return decode_valid_window (window)->hchild;
581} 585}
582 586
@@ -600,22 +604,27 @@ Return nil if WINDOW has no previous sibling. */)
600 604
601DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0, 605DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
602 doc: /* Return combination limit of window WINDOW. 606 doc: /* Return combination limit of window WINDOW.
603WINDOW must be a valid window and defaults to the selected one.
604If the return value is nil, child windows of WINDOW can be recombined with 607If the return value is nil, child windows of WINDOW can be recombined with
605WINDOW's siblings. A return value of t means that child windows of 608WINDOW's siblings. A return value of t means that child windows of
606WINDOW are never \(re-)combined with WINDOW's siblings. */) 609WINDOW are never \(re-)combined with WINDOW's siblings.
610
611WINDOW must be a valid window. The return value is meaningful for
612internal windows only. */)
607 (Lisp_Object window) 613 (Lisp_Object window)
608{ 614{
609 return decode_valid_window (window)->combination_limit; 615 CHECK_VALID_WINDOW (window);
616 return XWINDOW (window)->combination_limit;
610} 617}
611 618
612DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0, 619DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
613 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT. 620 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
614WINDOW must be a valid window and defaults to the selected one.
615If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's 621If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
616siblings. LIMIT t means that child windows of WINDOW are never 622siblings. LIMIT t means that child windows of WINDOW are never
617\(re-)combined with WINDOW's siblings. Other values are reserved for 623\(re-)combined with WINDOW's siblings. Other values are reserved for
618future use. */) 624future use.
625
626WINDOW must be a valid window. Setting the combination limit is
627meaningful for internal windows only. */)
619 (Lisp_Object window, Lisp_Object limit) 628 (Lisp_Object window, Lisp_Object limit)
620{ 629{
621 wset_combination_limit (decode_valid_window (window), limit); 630 wset_combination_limit (decode_valid_window (window), limit);
@@ -774,8 +783,7 @@ area is only partially visible, that counts as a whole line; to
774exclude partially-visible lines, use `window-text-height'. */) 783exclude partially-visible lines, use `window-text-height'. */)
775 (Lisp_Object window) 784 (Lisp_Object window)
776{ 785{
777 struct window *w = decode_live_window (window); 786 return make_number (window_body_lines (decode_live_window (window)));
778 return make_number (window_body_lines (w));
779} 787}
780 788
781DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0, 789DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0,
@@ -787,8 +795,7 @@ marginal areas, or scroll bars. On a graphical display, the width is
787expressed as an integer multiple of the default character width. */) 795expressed as an integer multiple of the default character width. */)
788 (Lisp_Object window) 796 (Lisp_Object window)
789{ 797{
790 struct window *w = decode_live_window (window); 798 return make_number (window_body_cols (decode_live_window (window)));
791 return make_number (window_body_cols (w));
792} 799}
793 800
794DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 801DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
@@ -831,10 +838,8 @@ Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
831window so that the location of point moves off-window. */) 838window so that the location of point moves off-window. */)
832 (Lisp_Object window, Lisp_Object ncol) 839 (Lisp_Object window, Lisp_Object ncol)
833{ 840{
834 struct window *w = decode_live_window (window);
835
836 CHECK_NUMBER (ncol); 841 CHECK_NUMBER (ncol);
837 return set_window_hscroll (w, XINT (ncol)); 842 return set_window_hscroll (decode_live_window (window), XINT (ncol));
838} 843}
839 844
840DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger, 845DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
@@ -879,11 +884,8 @@ header line, and/or mode line. For the edges of just the text area, use
879{ 884{
880 register struct window *w = decode_valid_window (window); 885 register struct window *w = decode_valid_window (window);
881 886
882 return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w)), 887 return list4i (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w),
883 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w)), 888 WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w));
884 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w)),
885 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w)),
886 Qnil))));
887} 889}
888 890
889DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0, 891DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0,
@@ -902,11 +904,8 @@ of just the text area, use `window-inside-pixel-edges'. */)
902{ 904{
903 register struct window *w = decode_valid_window (window); 905 register struct window *w = decode_valid_window (window);
904 906
905 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w)), 907 return list4i (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w),
906 Fcons (make_number (WINDOW_TOP_EDGE_Y (w)), 908 WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w));
907 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w)),
908 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w)),
909 Qnil))));
910} 909}
911 910
912static void 911static void
@@ -948,13 +947,13 @@ of just the text area, use `window-inside-absolute-pixel-edges'. */)
948{ 947{
949 register struct window *w = decode_valid_window (window); 948 register struct window *w = decode_valid_window (window);
950 int add_x, add_y; 949 int add_x, add_y;
950
951 calc_absolute_offset (w, &add_x, &add_y); 951 calc_absolute_offset (w, &add_x, &add_y);
952 952
953 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w) + add_x), 953 return list4i (WINDOW_LEFT_EDGE_X (w) + add_x,
954 Fcons (make_number (WINDOW_TOP_EDGE_Y (w) + add_y), 954 WINDOW_TOP_EDGE_Y (w) + add_y,
955 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w) + add_x), 955 WINDOW_RIGHT_EDGE_X (w) + add_x,
956 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w) + add_y), 956 WINDOW_BOTTOM_EDGE_Y (w) + add_y);
957 Qnil))));
958} 957}
959 958
960DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0, 959DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0,
@@ -973,16 +972,16 @@ display margins, fringes, header line, and/or mode line. */)
973{ 972{
974 register struct window *w = decode_live_window (window); 973 register struct window *w = decode_live_window (window);
975 974
976 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w) 975 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
977 + WINDOW_LEFT_MARGIN_COLS (w) 976 + WINDOW_LEFT_MARGIN_COLS (w)
978 + WINDOW_LEFT_FRINGE_COLS (w)), 977 + WINDOW_LEFT_FRINGE_COLS (w)),
979 make_number (WINDOW_TOP_EDGE_LINE (w) 978 (WINDOW_TOP_EDGE_LINE (w)
980 + WINDOW_HEADER_LINE_LINES (w)), 979 + WINDOW_HEADER_LINE_LINES (w)),
981 make_number (WINDOW_BOX_RIGHT_EDGE_COL (w) 980 (WINDOW_BOX_RIGHT_EDGE_COL (w)
982 - WINDOW_RIGHT_MARGIN_COLS (w) 981 - WINDOW_RIGHT_MARGIN_COLS (w)
983 - WINDOW_RIGHT_FRINGE_COLS (w)), 982 - WINDOW_RIGHT_FRINGE_COLS (w)),
984 make_number (WINDOW_BOTTOM_EDGE_LINE (w) 983 (WINDOW_BOTTOM_EDGE_LINE (w)
985 - WINDOW_MODE_LINE_LINES (w))); 984 - WINDOW_MODE_LINE_LINES (w)));
986} 985}
987 986
988DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0, 987DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0,
@@ -1000,16 +999,16 @@ display margins, fringes, header line, and/or mode line. */)
1000{ 999{
1001 register struct window *w = decode_live_window (window); 1000 register struct window *w = decode_live_window (window);
1002 1001
1003 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w) 1002 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
1004 + WINDOW_LEFT_MARGIN_WIDTH (w) 1003 + WINDOW_LEFT_MARGIN_WIDTH (w)
1005 + WINDOW_LEFT_FRINGE_WIDTH (w)), 1004 + WINDOW_LEFT_FRINGE_WIDTH (w)),
1006 make_number (WINDOW_TOP_EDGE_Y (w) 1005 (WINDOW_TOP_EDGE_Y (w)
1007 + WINDOW_HEADER_LINE_HEIGHT (w)), 1006 + WINDOW_HEADER_LINE_HEIGHT (w)),
1008 make_number (WINDOW_BOX_RIGHT_EDGE_X (w) 1007 (WINDOW_BOX_RIGHT_EDGE_X (w)
1009 - WINDOW_RIGHT_MARGIN_WIDTH (w) 1008 - WINDOW_RIGHT_MARGIN_WIDTH (w)
1010 - WINDOW_RIGHT_FRINGE_WIDTH (w)), 1009 - WINDOW_RIGHT_FRINGE_WIDTH (w)),
1011 make_number (WINDOW_BOTTOM_EDGE_Y (w) 1010 (WINDOW_BOTTOM_EDGE_Y (w)
1012 - WINDOW_MODE_LINE_HEIGHT (w))); 1011 - WINDOW_MODE_LINE_HEIGHT (w)));
1013} 1012}
1014 1013
1015DEFUN ("window-inside-absolute-pixel-edges", 1014DEFUN ("window-inside-absolute-pixel-edges",
@@ -1029,18 +1028,19 @@ display margins, fringes, header line, and/or mode line. */)
1029{ 1028{
1030 register struct window *w = decode_live_window (window); 1029 register struct window *w = decode_live_window (window);
1031 int add_x, add_y; 1030 int add_x, add_y;
1031
1032 calc_absolute_offset (w, &add_x, &add_y); 1032 calc_absolute_offset (w, &add_x, &add_y);
1033 1033
1034 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w) 1034 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
1035 + WINDOW_LEFT_MARGIN_WIDTH (w) 1035 + WINDOW_LEFT_MARGIN_WIDTH (w)
1036 + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x), 1036 + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
1037 make_number (WINDOW_TOP_EDGE_Y (w) 1037 (WINDOW_TOP_EDGE_Y (w)
1038 + WINDOW_HEADER_LINE_HEIGHT (w) + add_y), 1038 + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
1039 make_number (WINDOW_BOX_RIGHT_EDGE_X (w) 1039 (WINDOW_BOX_RIGHT_EDGE_X (w)
1040 - WINDOW_RIGHT_MARGIN_WIDTH (w) 1040 - WINDOW_RIGHT_MARGIN_WIDTH (w)
1041 - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x), 1041 - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
1042 make_number (WINDOW_BOTTOM_EDGE_Y (w) 1042 (WINDOW_BOTTOM_EDGE_Y (w)
1043 - WINDOW_MODE_LINE_HEIGHT (w) + add_y)); 1043 - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
1044} 1044}
1045 1045
1046/* Test if the character at column X, row Y is within window W. 1046/* Test if the character at column X, row Y is within window W.
@@ -1373,12 +1373,7 @@ The top left corner of the frame is considered to be row 0,
1373column 0. */) 1373column 0. */)
1374 (Lisp_Object x, Lisp_Object y, Lisp_Object frame) 1374 (Lisp_Object x, Lisp_Object y, Lisp_Object frame)
1375{ 1375{
1376 struct frame *f; 1376 struct frame *f = decode_live_frame (frame);
1377
1378 if (NILP (frame))
1379 frame = selected_frame;
1380 CHECK_LIVE_FRAME (frame);
1381 f = XFRAME (frame);
1382 1377
1383 /* Check that arguments are integers or floats. */ 1378 /* Check that arguments are integers or floats. */
1384 CHECK_NUMBER_OR_FLOAT (x); 1379 CHECK_NUMBER_OR_FLOAT (x);
@@ -1626,8 +1621,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
1626 { 1621 {
1627 Lisp_Object part = Qnil; 1622 Lisp_Object part = Qnil;
1628 if (!fully_p) 1623 if (!fully_p)
1629 part = list4 (make_number (rtop), make_number (rbot), 1624 part = list4i (rtop, rbot, rowh, vpos);
1630 make_number (rowh), make_number (vpos));
1631 in_window = Fcons (make_number (x), 1625 in_window = Fcons (make_number (x),
1632 Fcons (make_number (y), part)); 1626 Fcons (make_number (y), part));
1633 } 1627 }
@@ -1693,23 +1687,19 @@ Return nil if window display is not up-to-date. In that case, use
1693 if (!WINDOW_WANTS_HEADER_LINE_P (w)) 1687 if (!WINDOW_WANTS_HEADER_LINE_P (w))
1694 return Qnil; 1688 return Qnil;
1695 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); 1689 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
1696 if (!row->enabled_p) 1690 return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
1697 return Qnil;
1698 return list4 (make_number (row->height),
1699 make_number (0), make_number (0),
1700 make_number (0));
1701 } 1691 }
1702 1692
1703 if (EQ (line, Qmode_line)) 1693 if (EQ (line, Qmode_line))
1704 { 1694 {
1705 row = MATRIX_MODE_LINE_ROW (w->current_matrix); 1695 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
1706 if (!row->enabled_p) 1696 return (row->enabled_p ?
1707 return Qnil; 1697 list4i (row->height,
1708 return list4 (make_number (row->height), 1698 0, /* not accurate */
1709 make_number (0), /* not accurate */ 1699 (WINDOW_HEADER_LINE_HEIGHT (w)
1710 make_number (WINDOW_HEADER_LINE_HEIGHT (w) 1700 + window_text_bottom_y (w)),
1711 + window_text_bottom_y (w)), 1701 0)
1712 make_number (0)); 1702 : Qnil);
1713 } 1703 }
1714 1704
1715 CHECK_NUMBER (line); 1705 CHECK_NUMBER (line);
@@ -1738,10 +1728,7 @@ Return nil if window display is not up-to-date. In that case, use
1738 1728
1739 found_row: 1729 found_row:
1740 crop = max (0, (row->y + row->height) - max_y); 1730 crop = max (0, (row->y + row->height) - max_y);
1741 return list4 (make_number (row->height + min (0, row->y) - crop), 1731 return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
1742 make_number (i),
1743 make_number (row->y),
1744 make_number (crop));
1745} 1732}
1746 1733
1747DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p, 1734DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
@@ -2146,10 +2133,10 @@ window_list (void)
2146{ 2133{
2147 if (!CONSP (Vwindow_list)) 2134 if (!CONSP (Vwindow_list))
2148 { 2135 {
2149 Lisp_Object tail; 2136 Lisp_Object tail, frame;
2150 2137
2151 Vwindow_list = Qnil; 2138 Vwindow_list = Qnil;
2152 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 2139 FOR_EACH_FRAME (tail, frame)
2153 { 2140 {
2154 Lisp_Object args[2]; 2141 Lisp_Object args[2];
2155 2142
@@ -2157,7 +2144,7 @@ window_list (void)
2157 new windows at the front of args[1], which means we 2144 new windows at the front of args[1], which means we
2158 have to reverse this list at the end. */ 2145 have to reverse this list at the end. */
2159 args[1] = Qnil; 2146 args[1] = Qnil;
2160 foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1]); 2147 foreach_window (XFRAME (frame), add_window_to_list, &args[1]);
2161 args[0] = Vwindow_list; 2148 args[0] = Vwindow_list;
2162 args[1] = Fnreverse (args[1]); 2149 args[1] = Fnreverse (args[1]);
2163 Vwindow_list = Fnconc (2, args); 2150 Vwindow_list = Fnconc (2, args);
@@ -2252,11 +2239,9 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
2252static void 2239static void
2253decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) 2240decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames)
2254{ 2241{
2255 if (NILP (*window)) 2242 struct window *w = decode_live_window (*window);
2256 *window = selected_window;
2257 else
2258 CHECK_LIVE_WINDOW (*window);
2259 2243
2244 XSETWINDOW (*window, w);
2260 /* MINIBUF nil may or may not include minibuffers. Decide if it 2245 /* MINIBUF nil may or may not include minibuffers. Decide if it
2261 does. */ 2246 does. */
2262 if (NILP (*minibuf)) 2247 if (NILP (*minibuf))
@@ -2272,7 +2257,7 @@ decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object
2272 if (NILP (*all_frames)) 2257 if (NILP (*all_frames))
2273 *all_frames 2258 *all_frames
2274 = (!EQ (*minibuf, Qlambda) 2259 = (!EQ (*minibuf, Qlambda)
2275 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window)->frame)) 2260 ? FRAME_MINIBUF_WINDOW (XFRAME (w->frame))
2276 : Qnil); 2261 : Qnil);
2277 else if (EQ (*all_frames, Qvisible)) 2262 else if (EQ (*all_frames, Qvisible))
2278 ; 2263 ;
@@ -3122,12 +3107,12 @@ run_window_configuration_change_hook (struct frame *f)
3122} 3107}
3123 3108
3124DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook, 3109DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
3125 Srun_window_configuration_change_hook, 1, 1, 0, 3110 Srun_window_configuration_change_hook, 0, 1, 0,
3126 doc: /* Run `window-configuration-change-hook' for FRAME. */) 3111 doc: /* Run `window-configuration-change-hook' for FRAME.
3112If FRAME is omitted or nil, it defaults to the selected frame. */)
3127 (Lisp_Object frame) 3113 (Lisp_Object frame)
3128{ 3114{
3129 CHECK_LIVE_FRAME (frame); 3115 run_window_configuration_change_hook (decode_live_frame (frame));
3130 run_window_configuration_change_hook (XFRAME (frame));
3131 return Qnil; 3116 return Qnil;
3132} 3117}
3133 3118
@@ -3654,10 +3639,12 @@ window_resize_apply (struct window *w, int horflag)
3654} 3639}
3655 3640
3656 3641
3657DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 1, 2, 0, 3642DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
3658 doc: /* Apply requested size values for window-tree of FRAME. 3643 doc: /* Apply requested size values for window-tree of FRAME.
3659Optional argument HORIZONTAL omitted or nil means apply requested height 3644If FRAME is omitted or nil, it defaults to the selected frame.
3660values. HORIZONTAL non-nil means apply requested width values. 3645
3646Optional argument HORIZONTAL omitted or nil means apply requested
3647height values. HORIZONTAL non-nil means apply requested width values.
3661 3648
3662This function checks whether the requested values sum up to a valid 3649This function checks whether the requested values sum up to a valid
3663window layout, recursively assigns the new sizes of all child windows 3650window layout, recursively assigns the new sizes of all child windows
@@ -3668,17 +3655,10 @@ Note: This function does not check any of `window-fixed-size-p',
3668be applied on the Elisp level. */) 3655be applied on the Elisp level. */)
3669 (Lisp_Object frame, Lisp_Object horizontal) 3656 (Lisp_Object frame, Lisp_Object horizontal)
3670{ 3657{
3671 struct frame *f; 3658 struct frame *f = decode_live_frame (frame);
3672 struct window *r; 3659 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
3673 int horflag = !NILP (horizontal); 3660 int horflag = !NILP (horizontal);
3674 3661
3675 if (NILP (frame))
3676 frame = selected_frame;
3677 CHECK_LIVE_FRAME (frame);
3678
3679 f = XFRAME (frame);
3680 r = XWINDOW (FRAME_ROOT_WINDOW (f));
3681
3682 if (!window_resize_check (r, horflag) 3662 if (!window_resize_check (r, horflag)
3683 || ! EQ (r->new_total, 3663 || ! EQ (r->new_total,
3684 (horflag ? r->total_cols : r->total_lines))) 3664 (horflag ? r->total_cols : r->total_lines)))
@@ -3892,9 +3872,10 @@ set correctly. See the code of `split-window' for how this is done. */)
3892 3872
3893 make_parent_window (old, horflag); 3873 make_parent_window (old, horflag);
3894 p = XWINDOW (o->parent); 3874 p = XWINDOW (o->parent);
3895 /* Store t in the new parent's combination_limit slot to avoid 3875 if (EQ (Vwindow_combination_limit, Qt))
3896 that its children get merged into another window. */ 3876 /* Store t in the new parent's combination_limit slot to avoid
3897 wset_combination_limit (p, Qt); 3877 that its children get merged into another window. */
3878 wset_combination_limit (p, Qt);
3898 /* These get applied below. */ 3879 /* These get applied below. */
3899 wset_new_total (p, horflag ? o->total_cols : o->total_lines); 3880 wset_new_total (p, horflag ? o->total_cols : o->total_lines);
3900 wset_new_normal (p, new_normal); 3881 wset_new_normal (p, new_normal);
@@ -6161,12 +6142,7 @@ saved by this function. */)
6161 register int n_windows; 6142 register int n_windows;
6162 register struct save_window_data *data; 6143 register struct save_window_data *data;
6163 register int i; 6144 register int i;
6164 FRAME_PTR f; 6145 struct frame *f = decode_live_frame (frame);
6165
6166 if (NILP (frame))
6167 frame = selected_frame;
6168 CHECK_LIVE_FRAME (frame);
6169 f = XFRAME (frame);
6170 6146
6171 n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); 6147 n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
6172 data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols, 6148 data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols,
@@ -6319,10 +6295,9 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6319{ 6295{
6320 struct window *w = decode_live_window (window); 6296 struct window *w = decode_live_window (window);
6321 6297
6322 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w)), 6298 return list3 (make_number (WINDOW_LEFT_FRINGE_WIDTH (w)),
6323 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w)), 6299 make_number (WINDOW_RIGHT_FRINGE_WIDTH (w)),
6324 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 6300 WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ? Qt : Qnil);
6325 ? Qt : Qnil), Qnil)));
6326} 6301}
6327 6302
6328 6303
@@ -6391,12 +6366,12 @@ value. */)
6391 (Lisp_Object window) 6366 (Lisp_Object window)
6392{ 6367{
6393 struct window *w = decode_live_window (window); 6368 struct window *w = decode_live_window (window);
6394 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) 6369
6370 return list4 (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
6395 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) 6371 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
6396 : WINDOW_SCROLL_BAR_AREA_WIDTH (w))), 6372 : WINDOW_SCROLL_BAR_AREA_WIDTH (w))),
6397 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w)), 6373 make_number (WINDOW_SCROLL_BAR_COLS (w)),
6398 Fcons (w->vertical_scroll_bar_type, 6374 w->vertical_scroll_bar_type, Qnil);
6399 Fcons (Qnil, Qnil))));
6400} 6375}
6401 6376
6402 6377
diff --git a/src/window.h b/src/window.h
index 115b361194c..2a12226c0aa 100644
--- a/src/window.h
+++ b/src/window.h
@@ -970,17 +970,26 @@ struct glyph *get_phys_cursor_glyph (struct window *w);
970 || !NILP (XWINDOW (WINDOW)->vchild) \ 970 || !NILP (XWINDOW (WINDOW)->vchild) \
971 || !NILP (XWINDOW (WINDOW)->hchild))) 971 || !NILP (XWINDOW (WINDOW)->hchild)))
972 972
973/* A window of any sort, leaf or interior, is "valid" if one
974 of its buffer, vchild, or hchild members is non-nil. */
975#define CHECK_VALID_WINDOW(WINDOW) \
976 CHECK_TYPE (WINDOW_VALID_P (WINDOW), Qwindow_valid_p, WINDOW)
973 977
974/* Value is non-zero if WINDOW is a live window. */ 978/* Value is non-zero if WINDOW is a live window. */
975#define WINDOW_LIVE_P(WINDOW) \ 979#define WINDOW_LIVE_P(WINDOW) \
976 (WINDOWP (WINDOW) && !NILP (XWINDOW (WINDOW)->buffer)) 980 (WINDOWP (WINDOW) && !NILP (XWINDOW (WINDOW)->buffer))
977 981
982/* A window is "live" if and only if it shows a buffer. */
983#define CHECK_LIVE_WINDOW(WINDOW) \
984 CHECK_TYPE (WINDOW_LIVE_P (WINDOW), Qwindow_live_p, WINDOW)
985
978/* These used to be in lisp.h. */ 986/* These used to be in lisp.h. */
979 987
980extern Lisp_Object Qwindowp, Qwindow_live_p; 988extern Lisp_Object Qwindowp, Qwindow_live_p;
981extern Lisp_Object Vwindow_list; 989extern Lisp_Object Vwindow_list;
982 990
983extern struct window *decode_live_window (Lisp_Object); 991extern struct window *decode_live_window (Lisp_Object);
992extern struct window *decode_any_window (Lisp_Object);
984extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool); 993extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool);
985extern void mark_window_cursors_off (struct window *); 994extern void mark_window_cursors_off (struct window *);
986extern int window_internal_height (struct window *); 995extern int window_internal_height (struct window *);
diff --git a/src/xdisp.c b/src/xdisp.c
index b3b08edcd0a..a74628db392 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -928,6 +928,7 @@ static enum move_it_result
928 move_it_in_display_line_to (struct it *, ptrdiff_t, int, 928 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
929 enum move_operation_enum); 929 enum move_operation_enum);
930void move_it_vertically_backward (struct it *, int); 930void move_it_vertically_backward (struct it *, int);
931static void get_visually_first_element (struct it *);
931static void init_to_row_start (struct it *, struct window *, 932static void init_to_row_start (struct it *, struct window *,
932 struct glyph_row *); 933 struct glyph_row *);
933static int init_to_row_end (struct it *, struct window *, 934static int init_to_row_end (struct it *, struct window *,
@@ -3113,6 +3114,40 @@ init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3113 eassert (STRINGP (it->string)); 3114 eassert (STRINGP (it->string));
3114 it->current.string_pos = pos->string_pos; 3115 it->current.string_pos = pos->string_pos;
3115 it->method = GET_FROM_STRING; 3116 it->method = GET_FROM_STRING;
3117 it->end_charpos = SCHARS (it->string);
3118 /* Set up the bidi iterator for this overlay string. */
3119 if (it->bidi_p)
3120 {
3121 it->bidi_it.string.lstring = it->string;
3122 it->bidi_it.string.s = NULL;
3123 it->bidi_it.string.schars = SCHARS (it->string);
3124 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3125 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3126 it->bidi_it.string.unibyte = !it->multibyte_p;
3127 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3128 FRAME_WINDOW_P (it->f), &it->bidi_it);
3129
3130 /* Synchronize the state of the bidi iterator with
3131 pos->string_pos. For any string position other than
3132 zero, this will be done automagically when we resume
3133 iteration over the string and get_visually_first_element
3134 is called. But if string_pos is zero, and the string is
3135 to be reordered for display, we need to resync manually,
3136 since it could be that the iteration state recorded in
3137 pos ended at string_pos of 0 moving backwards in string. */
3138 if (CHARPOS (pos->string_pos) == 0)
3139 {
3140 get_visually_first_element (it);
3141 if (IT_STRING_CHARPOS (*it) != 0)
3142 do {
3143 /* Paranoia. */
3144 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3145 bidi_move_to_visually_next (&it->bidi_it);
3146 } while (it->bidi_it.charpos != 0);
3147 }
3148 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3149 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3150 }
3116 } 3151 }
3117 3152
3118 if (CHARPOS (pos->string_pos) >= 0) 3153 if (CHARPOS (pos->string_pos) >= 0)
@@ -3122,6 +3157,9 @@ init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3122 IT should already be filled with that string. */ 3157 IT should already be filled with that string. */
3123 it->current.string_pos = pos->string_pos; 3158 it->current.string_pos = pos->string_pos;
3124 eassert (STRINGP (it->string)); 3159 eassert (STRINGP (it->string));
3160 if (it->bidi_p)
3161 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3162 FRAME_WINDOW_P (it->f), &it->bidi_it);
3125 } 3163 }
3126 3164
3127 /* Restore position in display vector translations, control 3165 /* Restore position in display vector translations, control
@@ -10731,7 +10769,7 @@ clear_garbaged_frames (void)
10731 { 10769 {
10732 if (f->resized_p) 10770 if (f->resized_p)
10733 { 10771 {
10734 Fredraw_frame (frame); 10772 redraw_frame (f);
10735 f->force_flush_display_p = 1; 10773 f->force_flush_display_p = 1;
10736 } 10774 }
10737 clear_current_matrices (f); 10775 clear_current_matrices (f);
@@ -11058,17 +11096,15 @@ x_consider_frame_title (Lisp_Object frame)
11058 || f->explicit_name) 11096 || f->explicit_name)
11059 { 11097 {
11060 /* Do we have more than one visible frame on this X display? */ 11098 /* Do we have more than one visible frame on this X display? */
11061 Lisp_Object tail; 11099 Lisp_Object tail, other_frame, fmt;
11062 Lisp_Object fmt;
11063 ptrdiff_t title_start; 11100 ptrdiff_t title_start;
11064 char *title; 11101 char *title;
11065 ptrdiff_t len; 11102 ptrdiff_t len;
11066 struct it it; 11103 struct it it;
11067 ptrdiff_t count = SPECPDL_INDEX (); 11104 ptrdiff_t count = SPECPDL_INDEX ();
11068 11105
11069 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 11106 FOR_EACH_FRAME (tail, other_frame)
11070 { 11107 {
11071 Lisp_Object other_frame = XCAR (tail);
11072 struct frame *tf = XFRAME (other_frame); 11108 struct frame *tf = XFRAME (other_frame);
11073 11109
11074 if (tf != f 11110 if (tf != f
@@ -11878,19 +11914,14 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
11878 11914
11879DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed, 11915DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11880 0, 1, 0, 11916 0, 1, 0,
11881 doc: /* Return the number of lines occupied by the tool bar of FRAME. */) 11917 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11918If FRAME is nil or omitted, use the selected frame. */)
11882 (Lisp_Object frame) 11919 (Lisp_Object frame)
11883{ 11920{
11884 struct frame *f; 11921 struct frame *f = decode_any_frame (frame);
11885 struct window *w; 11922 struct window *w;
11886 int nlines = 0; 11923 int nlines = 0;
11887 11924
11888 if (NILP (frame))
11889 frame = selected_frame;
11890 else
11891 CHECK_FRAME (frame);
11892 f = XFRAME (frame);
11893
11894 if (WINDOWP (f->tool_bar_window) 11925 if (WINDOWP (f->tool_bar_window)
11895 && (w = XWINDOW (f->tool_bar_window), 11926 && (w = XWINDOW (f->tool_bar_window),
11896 WINDOW_TOTAL_LINES (w) > 0)) 11927 WINDOW_TOTAL_LINES (w) > 0))
@@ -14753,13 +14784,18 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14753 if (NUMBERP (aggressive)) 14784 if (NUMBERP (aggressive))
14754 { 14785 {
14755 double float_amount = XFLOATINT (aggressive) * height; 14786 double float_amount = XFLOATINT (aggressive) * height;
14756 amount_to_scroll = float_amount; 14787 int aggressive_scroll = float_amount;
14757 if (amount_to_scroll == 0 && float_amount > 0) 14788 if (aggressive_scroll == 0 && float_amount > 0)
14758 amount_to_scroll = 1; 14789 aggressive_scroll = 1;
14759 /* Don't let point enter the scroll margin near top of 14790 /* Don't let point enter the scroll margin near top of
14760 the window. */ 14791 the window. This could happen if the value of
14761 if (amount_to_scroll > height - 2*this_scroll_margin + dy) 14792 scroll_up_aggressively is too large and there are
14762 amount_to_scroll = height - 2*this_scroll_margin + dy; 14793 non-zero margins, because scroll_up_aggressively
14794 means put point that fraction of window height
14795 _from_the_bottom_margin_. */
14796 if (aggressive_scroll + 2*this_scroll_margin > height)
14797 aggressive_scroll = height - 2*this_scroll_margin;
14798 amount_to_scroll = dy + aggressive_scroll;
14763 } 14799 }
14764 } 14800 }
14765 14801
@@ -14819,7 +14855,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14819 /* Compute the vertical distance from PT to the scroll 14855 /* Compute the vertical distance from PT to the scroll
14820 margin position. Move as far as scroll_max allows, or 14856 margin position. Move as far as scroll_max allows, or
14821 one screenful, or 10 screen lines, whichever is largest. 14857 one screenful, or 10 screen lines, whichever is largest.
14822 Give up if distance is greater than scroll_max. */ 14858 Give up if distance is greater than scroll_max or if we
14859 didn't reach the scroll margin position. */
14823 SET_TEXT_POS (pos, PT, PT_BYTE); 14860 SET_TEXT_POS (pos, PT, PT_BYTE);
14824 start_display (&it, w, pos); 14861 start_display (&it, w, pos);
14825 y0 = it.current_y; 14862 y0 = it.current_y;
@@ -14829,7 +14866,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14829 y_to_move, -1, 14866 y_to_move, -1,
14830 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 14867 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14831 dy = it.current_y - y0; 14868 dy = it.current_y - y0;
14832 if (dy > scroll_max) 14869 if (dy > scroll_max
14870 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14833 return SCROLLING_FAILED; 14871 return SCROLLING_FAILED;
14834 14872
14835 /* Compute new window start. */ 14873 /* Compute new window start. */
@@ -14847,15 +14885,16 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14847 if (NUMBERP (aggressive)) 14885 if (NUMBERP (aggressive))
14848 { 14886 {
14849 double float_amount = XFLOATINT (aggressive) * height; 14887 double float_amount = XFLOATINT (aggressive) * height;
14850 amount_to_scroll = float_amount; 14888 int aggressive_scroll = float_amount;
14851 if (amount_to_scroll == 0 && float_amount > 0) 14889 if (aggressive_scroll == 0 && float_amount > 0)
14852 amount_to_scroll = 1; 14890 aggressive_scroll = 1;
14853 amount_to_scroll -=
14854 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14855 /* Don't let point enter the scroll margin near 14891 /* Don't let point enter the scroll margin near
14856 bottom of the window. */ 14892 bottom of the window, if the value of
14857 if (amount_to_scroll > height - 2*this_scroll_margin + dy) 14893 scroll_down_aggressively happens to be too
14858 amount_to_scroll = height - 2*this_scroll_margin + dy; 14894 large. */
14895 if (aggressive_scroll + 2*this_scroll_margin > height)
14896 aggressive_scroll = height - 2*this_scroll_margin;
14897 amount_to_scroll = dy + aggressive_scroll;
14859 } 14898 }
14860 } 14899 }
14861 14900
@@ -21018,10 +21057,8 @@ are the selected window and the WINDOW's buffer). */)
21018 Lisp_Object str; 21057 Lisp_Object str;
21019 int string_start = 0; 21058 int string_start = 0;
21020 21059
21021 if (NILP (window)) 21060 w = decode_any_window (window);
21022 window = selected_window; 21061 XSETWINDOW (window, w);
21023 CHECK_WINDOW (window);
21024 w = XWINDOW (window);
21025 21062
21026 if (NILP (buffer)) 21063 if (NILP (buffer))
21027 buffer = w->buffer; 21064 buffer = w->buffer;
@@ -21050,7 +21087,7 @@ are the selected window and the WINDOW's buffer). */)
21050 and set that to nil so that we don't alter the outer value. */ 21087 and set that to nil so that we don't alter the outer value. */
21051 record_unwind_protect (unwind_format_mode_line, 21088 record_unwind_protect (unwind_format_mode_line,
21052 format_mode_line_unwind_data 21089 format_mode_line_unwind_data
21053 (XFRAME (WINDOW_FRAME (XWINDOW (window))), 21090 (XFRAME (WINDOW_FRAME (w)),
21054 old_buffer, selected_window, 1)); 21091 old_buffer, selected_window, 1));
21055 mode_line_proptrans_alist = Qnil; 21092 mode_line_proptrans_alist = Qnil;
21056 21093
@@ -21334,6 +21371,12 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21334 Lisp_Object obj; 21371 Lisp_Object obj;
21335 struct frame *f = XFRAME (WINDOW_FRAME (w)); 21372 struct frame *f = XFRAME (WINDOW_FRAME (w));
21336 char *decode_mode_spec_buf = f->decode_mode_spec_buffer; 21373 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21374 /* We are going to use f->decode_mode_spec_buffer as the buffer to
21375 produce strings from numerical values, so limit preposterously
21376 large values of FIELD_WIDTH to avoid overrunning the buffer's
21377 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
21378 bytes plus the terminating null. */
21379 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
21337 struct buffer *b = current_buffer; 21380 struct buffer *b = current_buffer;
21338 21381
21339 obj = Qnil; 21382 obj = Qnil;
@@ -21429,7 +21472,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21429 { 21472 {
21430 ptrdiff_t col = current_column (); 21473 ptrdiff_t col = current_column ();
21431 wset_column_number_displayed (w, make_number (col)); 21474 wset_column_number_displayed (w, make_number (col));
21432 pint2str (decode_mode_spec_buf, field_width, col); 21475 pint2str (decode_mode_spec_buf, width, col);
21433 return decode_mode_spec_buf; 21476 return decode_mode_spec_buf;
21434 } 21477 }
21435 21478
@@ -21460,14 +21503,14 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21460 case 'i': 21503 case 'i':
21461 { 21504 {
21462 ptrdiff_t size = ZV - BEGV; 21505 ptrdiff_t size = ZV - BEGV;
21463 pint2str (decode_mode_spec_buf, field_width, size); 21506 pint2str (decode_mode_spec_buf, width, size);
21464 return decode_mode_spec_buf; 21507 return decode_mode_spec_buf;
21465 } 21508 }
21466 21509
21467 case 'I': 21510 case 'I':
21468 { 21511 {
21469 ptrdiff_t size = ZV - BEGV; 21512 ptrdiff_t size = ZV - BEGV;
21470 pint2hrstr (decode_mode_spec_buf, field_width, size); 21513 pint2hrstr (decode_mode_spec_buf, width, size);
21471 return decode_mode_spec_buf; 21514 return decode_mode_spec_buf;
21472 } 21515 }
21473 21516
@@ -21574,12 +21617,12 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21574 line_number_displayed = 1; 21617 line_number_displayed = 1;
21575 21618
21576 /* Make the string to show. */ 21619 /* Make the string to show. */
21577 pint2str (decode_mode_spec_buf, field_width, topline + nlines); 21620 pint2str (decode_mode_spec_buf, width, topline + nlines);
21578 return decode_mode_spec_buf; 21621 return decode_mode_spec_buf;
21579 no_value: 21622 no_value:
21580 { 21623 {
21581 char* p = decode_mode_spec_buf; 21624 char* p = decode_mode_spec_buf;
21582 int pad = field_width - 2; 21625 int pad = width - 2;
21583 while (pad-- > 0) 21626 while (pad-- > 0)
21584 *p++ = ' '; 21627 *p++ = ' ';
21585 *p++ = '?'; 21628 *p++ = '?';
@@ -29381,8 +29424,10 @@ start_hourglass (void)
29381 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0); 29424 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29382 29425
29383#ifdef HAVE_NTGUI 29426#ifdef HAVE_NTGUI
29384 extern void w32_note_current_window (void); 29427 {
29385 w32_note_current_window (); 29428 extern void w32_note_current_window (void);
29429 w32_note_current_window ();
29430 }
29386#endif /* HAVE_NTGUI */ 29431#endif /* HAVE_NTGUI */
29387 29432
29388 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, 29433 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
diff --git a/src/xfaces.c b/src/xfaces.c
index 221387c4b6d..daf329791c1 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -314,16 +314,10 @@ static Lisp_Object QCfontset;
314Lisp_Object Qnormal; 314Lisp_Object Qnormal;
315Lisp_Object Qbold; 315Lisp_Object Qbold;
316static Lisp_Object Qline, Qwave; 316static Lisp_Object Qline, Qwave;
317static Lisp_Object Qultra_light, Qreverse_oblique, Qreverse_italic;
318Lisp_Object Qextra_light, Qlight; 317Lisp_Object Qextra_light, Qlight;
319Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold; 318Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
320Lisp_Object Qoblique; 319Lisp_Object Qoblique;
321Lisp_Object Qitalic; 320Lisp_Object Qitalic;
322static Lisp_Object Qultra_condensed, Qextra_condensed;
323Lisp_Object Qcondensed;
324static Lisp_Object Qsemi_condensed, Qsemi_expanded, Qextra_expanded;
325Lisp_Object Qexpanded;
326static Lisp_Object Qultra_expanded;
327static Lisp_Object Qreleased_button, Qpressed_button; 321static Lisp_Object Qreleased_button, Qpressed_button;
328static Lisp_Object QCstyle, QCcolor, QCline_width; 322static Lisp_Object QCstyle, QCcolor, QCline_width;
329Lisp_Object Qunspecified; /* used in dosfns.c */ 323Lisp_Object Qunspecified; /* used in dosfns.c */
@@ -669,23 +663,6 @@ x_free_gc (struct frame *f, GC gc)
669} 663}
670#endif /* HAVE_NS */ 664#endif /* HAVE_NS */
671 665
672/* If FRAME is nil, return a pointer to the selected frame.
673 Otherwise, check that FRAME is a live frame, and return a pointer
674 to it. NPARAM is the parameter number of FRAME, for
675 CHECK_LIVE_FRAME. This is here because it's a frequent pattern in
676 Lisp function definitions. */
677
678static struct frame *
679frame_or_selected_frame (Lisp_Object frame, int nparam)
680{
681 if (NILP (frame))
682 frame = selected_frame;
683
684 CHECK_LIVE_FRAME (frame);
685 return XFRAME (frame);
686}
687
688
689/*********************************************************************** 666/***********************************************************************
690 Frames and faces 667 Frames and faces
691 ***********************************************************************/ 668 ***********************************************************************/
@@ -1204,15 +1181,9 @@ FRAME specifies the frame and thus the display for interpreting COLOR.
1204If FRAME is nil or omitted, use the selected frame. */) 1181If FRAME is nil or omitted, use the selected frame. */)
1205 (Lisp_Object color, Lisp_Object frame) 1182 (Lisp_Object color, Lisp_Object frame)
1206{ 1183{
1207 struct frame *f;
1208
1209 CHECK_STRING (color); 1184 CHECK_STRING (color);
1210 if (NILP (frame)) 1185 return (face_color_gray_p (decode_any_frame (frame), SSDATA (color))
1211 frame = selected_frame; 1186 ? Qt : Qnil);
1212 else
1213 CHECK_FRAME (frame);
1214 f = XFRAME (frame);
1215 return face_color_gray_p (f, SSDATA (color)) ? Qt : Qnil;
1216} 1187}
1217 1188
1218 1189
@@ -1225,17 +1196,10 @@ If FRAME is nil or omitted, use the selected frame.
1225COLOR must be a valid color name. */) 1196COLOR must be a valid color name. */)
1226 (Lisp_Object color, Lisp_Object frame, Lisp_Object background_p) 1197 (Lisp_Object color, Lisp_Object frame, Lisp_Object background_p)
1227{ 1198{
1228 struct frame *f;
1229
1230 CHECK_STRING (color); 1199 CHECK_STRING (color);
1231 if (NILP (frame)) 1200 return (face_color_supported_p (decode_any_frame (frame),
1232 frame = selected_frame; 1201 SSDATA (color), !NILP (background_p))
1233 else 1202 ? Qt : Qnil);
1234 CHECK_FRAME (frame);
1235 f = XFRAME (frame);
1236 if (face_color_supported_p (f, SSDATA (color), !NILP (background_p)))
1237 return Qt;
1238 return Qnil;
1239} 1203}
1240 1204
1241 1205
@@ -1683,9 +1647,7 @@ the WIDTH times as wide as FACE on FRAME. */)
1683 1647
1684 /* We can't simply call check_x_frame because this function may be 1648 /* We can't simply call check_x_frame because this function may be
1685 called before any frame is created. */ 1649 called before any frame is created. */
1686 if (NILP (frame)) 1650 f = decode_live_frame (frame);
1687 frame = selected_frame;
1688 f = frame_or_selected_frame (frame, 2);
1689 if (! FRAME_WINDOW_P (f)) 1651 if (! FRAME_WINDOW_P (f))
1690 { 1652 {
1691 /* Perhaps we have not yet created any frame. */ 1653 /* Perhaps we have not yet created any frame. */
@@ -1693,6 +1655,8 @@ the WIDTH times as wide as FACE on FRAME. */)
1693 frame = Qnil; 1655 frame = Qnil;
1694 face = Qnil; 1656 face = Qnil;
1695 } 1657 }
1658 else
1659 XSETFRAME (frame, f);
1696 1660
1697 /* Determine the width standard for comparison with the fonts we find. */ 1661 /* Determine the width standard for comparison with the fonts we find. */
1698 1662
@@ -3679,21 +3643,12 @@ frame. If FRAME is t, report on the defaults for face SYMBOL (for new
3679frames). If FRAME is omitted or nil, use the selected frame. */) 3643frames). If FRAME is omitted or nil, use the selected frame. */)
3680 (Lisp_Object symbol, Lisp_Object keyword, Lisp_Object frame) 3644 (Lisp_Object symbol, Lisp_Object keyword, Lisp_Object frame)
3681{ 3645{
3682 Lisp_Object lface, value = Qnil; 3646 struct frame *f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
3647 Lisp_Object lface = lface_from_face_name (f, symbol, 1), value = Qnil;
3683 3648
3684 CHECK_SYMBOL (symbol); 3649 CHECK_SYMBOL (symbol);
3685 CHECK_SYMBOL (keyword); 3650 CHECK_SYMBOL (keyword);
3686 3651
3687 if (EQ (frame, Qt))
3688 lface = lface_from_face_name (NULL, symbol, 1);
3689 else
3690 {
3691 if (NILP (frame))
3692 frame = selected_frame;
3693 CHECK_LIVE_FRAME (frame);
3694 lface = lface_from_face_name (XFRAME (frame), symbol, 1);
3695 }
3696
3697 if (EQ (keyword, QCfamily)) 3652 if (EQ (keyword, QCfamily))
3698 value = LFACE_FAMILY (lface); 3653 value = LFACE_FAMILY (lface);
3699 else if (EQ (keyword, QCfoundry)) 3654 else if (EQ (keyword, QCfoundry))
@@ -3876,7 +3831,7 @@ return the font name used for CHARACTER. */)
3876 } 3831 }
3877 else 3832 else
3878 { 3833 {
3879 struct frame *f = frame_or_selected_frame (frame, 1); 3834 struct frame *f = decode_live_frame (frame);
3880 int face_id = lookup_named_face (f, face, 1); 3835 int face_id = lookup_named_face (f, face, 1);
3881 struct face *fface = FACE_FROM_ID (f, face_id); 3836 struct face *fface = FACE_FROM_ID (f, face_id);
3882 3837
@@ -3963,14 +3918,11 @@ If FRAME is omitted or nil, use the selected frame. */)
3963 struct frame *f; 3918 struct frame *f;
3964 Lisp_Object lface1, lface2; 3919 Lisp_Object lface1, lface2;
3965 3920
3966 if (EQ (frame, Qt)) 3921 /* Don't use check_x_frame here because this function is called
3967 f = NULL; 3922 before X frames exist. At that time, if FRAME is nil,
3968 else 3923 selected_frame will be used which is the frame dumped with
3969 /* Don't use check_x_frame here because this function is called 3924 Emacs. That frame is not an X frame. */
3970 before X frames exist. At that time, if FRAME is nil, 3925 f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
3971 selected_frame will be used which is the frame dumped with
3972 Emacs. That frame is not an X frame. */
3973 f = frame_or_selected_frame (frame, 2);
3974 3926
3975 lface1 = lface_from_face_name (f, face1, 1); 3927 lface1 = lface_from_face_name (f, face1, 1);
3976 lface2 = lface_from_face_name (f, face2, 1); 3928 lface2 = lface_from_face_name (f, face2, 1);
@@ -3988,20 +3940,10 @@ If FRAME is t, report on the defaults for face FACE (for new frames).
3988If FRAME is omitted or nil, use the selected frame. */) 3940If FRAME is omitted or nil, use the selected frame. */)
3989 (Lisp_Object face, Lisp_Object frame) 3941 (Lisp_Object face, Lisp_Object frame)
3990{ 3942{
3991 struct frame *f; 3943 struct frame *f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
3992 Lisp_Object lface; 3944 Lisp_Object lface = lface_from_face_name (f, face, 1);
3993 int i; 3945 int i;
3994 3946
3995 if (NILP (frame))
3996 frame = selected_frame;
3997 CHECK_LIVE_FRAME (frame);
3998 f = XFRAME (frame);
3999
4000 if (EQ (frame, Qt))
4001 lface = lface_from_face_name (NULL, face, 1);
4002 else
4003 lface = lface_from_face_name (f, face, 1);
4004
4005 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) 3947 for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
4006 if (!UNSPECIFIEDP (AREF (lface, i))) 3948 if (!UNSPECIFIEDP (AREF (lface, i)))
4007 break; 3949 break;
@@ -4016,8 +3958,7 @@ DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
4016For internal use only. */) 3958For internal use only. */)
4017 (Lisp_Object frame) 3959 (Lisp_Object frame)
4018{ 3960{
4019 struct frame *f = frame_or_selected_frame (frame, 0); 3961 return decode_live_frame (frame)->face_alist;
4020 return f->face_alist;
4021} 3962}
4022 3963
4023 3964
@@ -4205,14 +4146,9 @@ or lists of the form (RED GREEN BLUE).
4205If FRAME is unspecified or nil, the current frame is used. */) 4146If FRAME is unspecified or nil, the current frame is used. */)
4206 (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame) 4147 (Lisp_Object color1, Lisp_Object color2, Lisp_Object frame)
4207{ 4148{
4208 struct frame *f; 4149 struct frame *f = decode_live_frame (frame);
4209 XColor cdef1, cdef2; 4150 XColor cdef1, cdef2;
4210 4151
4211 if (NILP (frame))
4212 frame = selected_frame;
4213 CHECK_LIVE_FRAME (frame);
4214 f = XFRAME (frame);
4215
4216 if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1)) 4152 if (!(CONSP (color1) && parse_rgb_list (color1, &cdef1))
4217 && !(STRINGP (color1) && defined_color (f, SSDATA (color1), &cdef1, 0))) 4153 && !(STRINGP (color1) && defined_color (f, SSDATA (color1), &cdef1, 0)))
4218 signal_error ("Invalid color", color1); 4154 signal_error ("Invalid color", color1);
@@ -5076,17 +5012,14 @@ face for italic. */)
5076 else 5012 else
5077 { 5013 {
5078 /* Find any frame on DISPLAY. */ 5014 /* Find any frame on DISPLAY. */
5079 Lisp_Object fl_tail; 5015 Lisp_Object tail;
5080 5016
5081 frame = Qnil; 5017 frame = Qnil;
5082 for (fl_tail = Vframe_list; CONSP (fl_tail); fl_tail = XCDR (fl_tail)) 5018 FOR_EACH_FRAME (tail, frame)
5083 { 5019 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
5084 frame = XCAR (fl_tail); 5020 XFRAME (frame)->param_alist)),
5085 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay, 5021 display)))
5086 XFRAME (frame)->param_alist)), 5022 break;
5087 display)))
5088 break;
5089 }
5090 } 5023 }
5091 5024
5092 CHECK_LIVE_FRAME (frame); 5025 CHECK_LIVE_FRAME (frame);
@@ -6509,7 +6442,6 @@ syms_of_xfaces (void)
6509 DEFSYM (Qreleased_button, "released-button"); 6442 DEFSYM (Qreleased_button, "released-button");
6510 DEFSYM (Qpressed_button, "pressed-button"); 6443 DEFSYM (Qpressed_button, "pressed-button");
6511 DEFSYM (Qnormal, "normal"); 6444 DEFSYM (Qnormal, "normal");
6512 DEFSYM (Qultra_light, "ultra-light");
6513 DEFSYM (Qextra_light, "extra-light"); 6445 DEFSYM (Qextra_light, "extra-light");
6514 DEFSYM (Qlight, "light"); 6446 DEFSYM (Qlight, "light");
6515 DEFSYM (Qsemi_light, "semi-light"); 6447 DEFSYM (Qsemi_light, "semi-light");
@@ -6519,16 +6451,6 @@ syms_of_xfaces (void)
6519 DEFSYM (Qultra_bold, "ultra-bold"); 6451 DEFSYM (Qultra_bold, "ultra-bold");
6520 DEFSYM (Qoblique, "oblique"); 6452 DEFSYM (Qoblique, "oblique");
6521 DEFSYM (Qitalic, "italic"); 6453 DEFSYM (Qitalic, "italic");
6522 DEFSYM (Qreverse_oblique, "reverse-oblique");
6523 DEFSYM (Qreverse_italic, "reverse-italic");
6524 DEFSYM (Qultra_condensed, "ultra-condensed");
6525 DEFSYM (Qextra_condensed, "extra-condensed");
6526 DEFSYM (Qcondensed, "condensed");
6527 DEFSYM (Qsemi_condensed, "semi-condensed");
6528 DEFSYM (Qsemi_expanded, "semi-expanded");
6529 DEFSYM (Qexpanded, "expanded");
6530 DEFSYM (Qextra_expanded, "extra-expanded");
6531 DEFSYM (Qultra_expanded, "ultra-expanded");
6532 DEFSYM (Qbackground_color, "background-color"); 6454 DEFSYM (Qbackground_color, "background-color");
6533 DEFSYM (Qforeground_color, "foreground-color"); 6455 DEFSYM (Qforeground_color, "foreground-color");
6534 DEFSYM (Qunspecified, "unspecified"); 6456 DEFSYM (Qunspecified, "unspecified");
diff --git a/src/xfns.c b/src/xfns.c
index d497cffe3df..1f98e9fc8c7 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -164,12 +164,8 @@ have_menus_p (void)
164FRAME_PTR 164FRAME_PTR
165check_x_frame (Lisp_Object frame) 165check_x_frame (Lisp_Object frame)
166{ 166{
167 FRAME_PTR f; 167 struct frame *f = decode_live_frame (frame);
168 168
169 if (NILP (frame))
170 frame = selected_frame;
171 CHECK_LIVE_FRAME (frame);
172 f = XFRAME (frame);
173 if (! FRAME_X_P (f)) 169 if (! FRAME_X_P (f))
174 error ("Non-X frame used"); 170 error ("Non-X frame used");
175 return f; 171 return f;
@@ -228,13 +224,11 @@ x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
228 Lisp_Object tail, frame; 224 Lisp_Object tail, frame;
229 struct frame *f; 225 struct frame *f;
230 226
231 if (wdesc == None) return 0; 227 if (wdesc == None)
228 return NULL;
232 229
233 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 230 FOR_EACH_FRAME (tail, frame)
234 { 231 {
235 frame = XCAR (tail);
236 if (!FRAMEP (frame))
237 continue;
238 f = XFRAME (frame); 232 f = XFRAME (frame);
239 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) 233 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
240 continue; 234 continue;
@@ -274,18 +268,16 @@ struct frame *
274x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc) 268x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
275{ 269{
276 Lisp_Object tail, frame; 270 Lisp_Object tail, frame;
277 struct frame *f, *found; 271 struct frame *f, *found = NULL;
278 struct x_output *x; 272 struct x_output *x;
279 273
280 if (wdesc == None) return NULL; 274 if (wdesc == None)
275 return NULL;
281 276
282 found = NULL; 277 FOR_EACH_FRAME (tail, frame)
283 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
284 { 278 {
285 frame = XCAR (tail); 279 if (found)
286 if (!FRAMEP (frame)) 280 break;
287 continue;
288
289 f = XFRAME (frame); 281 f = XFRAME (frame);
290 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo) 282 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
291 { 283 {
@@ -329,13 +321,11 @@ x_menubar_window_to_frame (struct x_display_info *dpyinfo, XEvent *event)
329 struct frame *f; 321 struct frame *f;
330 struct x_output *x; 322 struct x_output *x;
331 323
332 if (wdesc == None) return 0; 324 if (wdesc == None)
325 return NULL;
333 326
334 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 327 FOR_EACH_FRAME (tail, frame)
335 { 328 {
336 frame = XCAR (tail);
337 if (!FRAMEP (frame))
338 continue;
339 f = XFRAME (frame); 329 f = XFRAME (frame);
340 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) 330 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
341 continue; 331 continue;
@@ -363,13 +353,11 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
363 struct frame *f; 353 struct frame *f;
364 struct x_output *x; 354 struct x_output *x;
365 355
366 if (wdesc == None) return 0; 356 if (wdesc == None)
357 return NULL;
367 358
368 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 359 FOR_EACH_FRAME (tail, frame)
369 { 360 {
370 frame = XCAR (tail);
371 if (!FRAMEP (frame))
372 continue;
373 f = XFRAME (frame); 361 f = XFRAME (frame);
374 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) 362 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
375 continue; 363 continue;
@@ -3000,16 +2988,14 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms)
3000DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint, 2988DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
3001 0, 1, 0, 2989 0, 1, 0,
3002 doc: /* Send the size hints for frame FRAME to the window manager. 2990 doc: /* Send the size hints for frame FRAME to the window manager.
3003If FRAME is nil, use the selected frame. */) 2991If FRAME is omitted or nil, use the selected frame.
2992Signal error if FRAME is not an X frame. */)
3004 (Lisp_Object frame) 2993 (Lisp_Object frame)
3005{ 2994{
3006 struct frame *f; 2995 struct frame *f = check_x_frame (frame);
3007 if (NILP (frame)) 2996
3008 frame = selected_frame;
3009 f = XFRAME (frame);
3010 block_input (); 2997 block_input ();
3011 if (FRAME_X_P (f)) 2998 x_wm_set_size_hint (f, 0, 0);
3012 x_wm_set_size_hint (f, 0, 0);
3013 unblock_input (); 2999 unblock_input ();
3014 return Qnil; 3000 return Qnil;
3015} 3001}
@@ -3111,9 +3097,6 @@ This function is an internal primitive--use `make-frame' instead. */)
3111 3097
3112 XSETFRAME (frame, f); 3098 XSETFRAME (frame, f);
3113 3099
3114 /* Note that X Windows does support scroll bars. */
3115 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3116
3117 f->terminal = dpyinfo->terminal; 3100 f->terminal = dpyinfo->terminal;
3118 3101
3119 f->output_method = output_x_window; 3102 f->output_method = output_x_window;
@@ -4596,7 +4579,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
4596 Finsert (1, &text); 4579 Finsert (1, &text);
4597 set_buffer_internal_1 (old_buffer); 4580 set_buffer_internal_1 (old_buffer);
4598 4581
4599 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
4600 record_unwind_protect (unwind_create_tip_frame, frame); 4582 record_unwind_protect (unwind_create_tip_frame, frame);
4601 4583
4602 f->terminal = dpyinfo->terminal; 4584 f->terminal = dpyinfo->terminal;
diff --git a/src/xmenu.c b/src/xmenu.c
index 01d932cf8d8..b585df2125b 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -132,11 +132,8 @@ menubar_id_to_frame (LWLIB_ID id)
132 Lisp_Object tail, frame; 132 Lisp_Object tail, frame;
133 FRAME_PTR f; 133 FRAME_PTR f;
134 134
135 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 135 FOR_EACH_FRAME (tail, frame)
136 { 136 {
137 frame = XCAR (tail);
138 if (!FRAMEP (frame))
139 continue;
140 f = XFRAME (frame); 137 f = XFRAME (frame);
141 if (!FRAME_WINDOW_P (f)) 138 if (!FRAME_WINDOW_P (f))
142 continue; 139 continue;
diff --git a/src/xselect.c b/src/xselect.c
index de9386bd7d9..64c64fa0c76 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1940,7 +1940,7 @@ x_handle_selection_notify (XSelectionEvent *event)
1940static struct frame * 1940static struct frame *
1941frame_for_x_selection (Lisp_Object object) 1941frame_for_x_selection (Lisp_Object object)
1942{ 1942{
1943 Lisp_Object tail; 1943 Lisp_Object tail, frame;
1944 struct frame *f; 1944 struct frame *f;
1945 1945
1946 if (NILP (object)) 1946 if (NILP (object))
@@ -1949,9 +1949,9 @@ frame_for_x_selection (Lisp_Object object)
1949 if (FRAME_X_P (f) && FRAME_LIVE_P (f)) 1949 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1950 return f; 1950 return f;
1951 1951
1952 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 1952 FOR_EACH_FRAME (tail, frame)
1953 { 1953 {
1954 f = XFRAME (XCAR (tail)); 1954 f = XFRAME (frame);
1955 if (FRAME_X_P (f) && FRAME_LIVE_P (f)) 1955 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1956 return f; 1956 return f;
1957 } 1957 }
@@ -1959,15 +1959,14 @@ frame_for_x_selection (Lisp_Object object)
1959 else if (TERMINALP (object)) 1959 else if (TERMINALP (object))
1960 { 1960 {
1961 struct terminal *t = get_terminal (object, 1); 1961 struct terminal *t = get_terminal (object, 1);
1962
1962 if (t->type == output_x_window) 1963 if (t->type == output_x_window)
1963 { 1964 FOR_EACH_FRAME (tail, frame)
1964 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 1965 {
1965 { 1966 f = XFRAME (frame);
1966 f = XFRAME (XCAR (tail)); 1967 if (FRAME_LIVE_P (f) && f->terminal == t)
1967 if (FRAME_LIVE_P (f) && f->terminal == t) 1968 return f;
1968 return f; 1969 }
1969 }
1970 }
1971 } 1970 }
1972 else if (FRAMEP (object)) 1971 else if (FRAMEP (object))
1973 { 1972 {
diff --git a/src/xterm.c b/src/xterm.c
index f8420d13a32..463d82b4ee2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1438,7 +1438,7 @@ static struct frame *
1438x_frame_of_widget (Widget widget) 1438x_frame_of_widget (Widget widget)
1439{ 1439{
1440 struct x_display_info *dpyinfo; 1440 struct x_display_info *dpyinfo;
1441 Lisp_Object tail; 1441 Lisp_Object tail, frame;
1442 struct frame *f; 1442 struct frame *f;
1443 1443
1444 dpyinfo = x_display_info_for_display (XtDisplay (widget)); 1444 dpyinfo = x_display_info_for_display (XtDisplay (widget));
@@ -1452,15 +1452,15 @@ x_frame_of_widget (Widget widget)
1452 1452
1453 /* Look for a frame with that top-level widget. Allocate the color 1453 /* Look for a frame with that top-level widget. Allocate the color
1454 on that frame to get the right gamma correction value. */ 1454 on that frame to get the right gamma correction value. */
1455 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 1455 FOR_EACH_FRAME (tail, frame)
1456 if (FRAMEP (XCAR (tail)) 1456 {
1457 && (f = XFRAME (XCAR (tail)), 1457 f = XFRAME (frame);
1458 (FRAME_X_P (f) 1458 if (FRAME_X_P (f)
1459 && f->output_data.nothing != 1 1459 && f->output_data.nothing != 1
1460 && FRAME_X_DISPLAY_INFO (f) == dpyinfo)) 1460 && FRAME_X_DISPLAY_INFO (f) == dpyinfo
1461 && f->output_data.x->widget == widget) 1461 && f->output_data.x->widget == widget)
1462 return f; 1462 return f;
1463 1463 }
1464 emacs_abort (); 1464 emacs_abort ();
1465} 1465}
1466 1466
@@ -4098,20 +4098,15 @@ XTmouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
4098static struct scroll_bar * 4098static struct scroll_bar *
4099x_window_to_scroll_bar (Display *display, Window window_id) 4099x_window_to_scroll_bar (Display *display, Window window_id)
4100{ 4100{
4101 Lisp_Object tail; 4101 Lisp_Object tail, frame;
4102 4102
4103#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS) 4103#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
4104 window_id = (Window) xg_get_scroll_id_for_window (display, window_id); 4104 window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
4105#endif /* USE_GTK && USE_TOOLKIT_SCROLL_BARS */ 4105#endif /* USE_GTK && USE_TOOLKIT_SCROLL_BARS */
4106 4106
4107 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 4107 FOR_EACH_FRAME (tail, frame)
4108 { 4108 {
4109 Lisp_Object frame, bar, condemned; 4109 Lisp_Object bar, condemned;
4110
4111 frame = XCAR (tail);
4112 /* All elements of Vframe_list should be frames. */
4113 if (! FRAMEP (frame))
4114 emacs_abort ();
4115 4110
4116 if (! FRAME_X_P (XFRAME (frame))) 4111 if (! FRAME_X_P (XFRAME (frame)))
4117 continue; 4112 continue;
@@ -4143,20 +4138,16 @@ x_window_to_scroll_bar (Display *display, Window window_id)
4143static Widget 4138static Widget
4144x_window_to_menu_bar (Window window) 4139x_window_to_menu_bar (Window window)
4145{ 4140{
4146 Lisp_Object tail; 4141 Lisp_Object tail, frame;
4147 4142
4148 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 4143 FOR_EACH_FRAME (tail, frame)
4149 { 4144 if (FRAME_X_P (XFRAME (frame)))
4150 if (FRAME_X_P (XFRAME (XCAR (tail)))) 4145 {
4151 { 4146 Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
4152 Lisp_Object frame = XCAR (tail);
4153 Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
4154
4155 if (menu_bar && xlwmenu_window_p (menu_bar, window))
4156 return menu_bar;
4157 }
4158 }
4159 4147
4148 if (menu_bar && xlwmenu_window_p (menu_bar, window))
4149 return menu_bar;
4150 }
4160 return NULL; 4151 return NULL;
4161} 4152}
4162 4153
@@ -6108,7 +6099,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6108 SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display; 6099 SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
6109 SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection; 6100 SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
6110 SELECTION_EVENT_TIME (&inev.sie) = eventp->time; 6101 SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
6111 inev.ie.frame_or_window = Qnil;
6112 } 6102 }
6113 break; 6103 break;
6114 6104
@@ -6128,7 +6118,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6128 SELECTION_EVENT_TARGET (&inev.sie) = eventp->target; 6118 SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
6129 SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property; 6119 SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
6130 SELECTION_EVENT_TIME (&inev.sie) = eventp->time; 6120 SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
6131 inev.ie.frame_or_window = Qnil;
6132 } 6121 }
6133 break; 6122 break;
6134 6123
@@ -10870,10 +10859,10 @@ default is nil, which is the same as `super'. */);
10870 10859
10871 DEFVAR_LISP ("x-keysym-table", Vx_keysym_table, 10860 DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
10872 doc: /* Hash table of character codes indexed by X keysym codes. */); 10861 doc: /* Hash table of character codes indexed by X keysym codes. */);
10873 Vx_keysym_table = make_hash_table (Qeql, make_number (900), 10862 Vx_keysym_table = make_hash_table (hashtest_eql, make_number (900),
10874 make_float (DEFAULT_REHASH_SIZE), 10863 make_float (DEFAULT_REHASH_SIZE),
10875 make_float (DEFAULT_REHASH_THRESHOLD), 10864 make_float (DEFAULT_REHASH_THRESHOLD),
10876 Qnil, Qnil, Qnil); 10865 Qnil);
10877} 10866}
10878 10867
10879#endif /* HAVE_X_WINDOWS */ 10868#endif /* HAVE_X_WINDOWS */
diff --git a/src/xterm.h b/src/xterm.h
index 4bc8f9813ed..6ef3d11fe48 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -890,10 +890,8 @@ struct scroll_bar
890 by this structure. */ 890 by this structure. */
891 891
892/* For an event of kind SELECTION_REQUEST_EVENT, 892/* For an event of kind SELECTION_REQUEST_EVENT,
893 this structure really describes the contents. 893 this structure really describes the contents. */
894 **Don't make this struct longer!** 894
895 If it overlaps the frame_or_window field of struct input_event,
896 that will cause GC to crash. */
897struct selection_input_event 895struct selection_input_event
898{ 896{
899 int kind; 897 int kind;