aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2012-11-13 23:24:26 +0900
committerKenichi Handa2012-11-13 23:24:26 +0900
commit0cdbf84521791935fdfeabf2e84f585cc64db325 (patch)
tree68a169af3af4a8859685682ab07c05e8f9ff93b3 /src
parente1bf05c1fbf63087801c242208212df133921ed1 (diff)
parent5745cae6984ed60299a89485aaea8f2f3fb67382 (diff)
downloademacs-0cdbf84521791935fdfeabf2e84f585cc64db325.tar.gz
emacs-0cdbf84521791935fdfeabf2e84f585cc64db325.zip
merge trunk
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit49
-rw-r--r--src/ChangeLog352
-rw-r--r--src/alloc.c193
-rw-r--r--src/buffer.c28
-rw-r--r--src/buffer.h31
-rw-r--r--src/category.c4
-rw-r--r--src/composite.c4
-rw-r--r--src/data.c70
-rw-r--r--src/dispnew.c84
-rw-r--r--src/doc.c35
-rw-r--r--src/emacs.c4
-rw-r--r--src/eval.c21
-rw-r--r--src/fileio.c10
-rw-r--r--src/fns.c178
-rw-r--r--src/font.c40
-rw-r--r--src/fontset.c9
-rw-r--r--src/frame.c343
-rw-r--r--src/frame.h4
-rw-r--r--src/image.c4
-rw-r--r--src/keyboard.c21
-rw-r--r--src/lisp.h204
-rw-r--r--src/lread.c2
-rw-r--r--src/makefile.w32-in4
-rw-r--r--src/nsfont.m15
-rw-r--r--src/nsterm.m34
-rw-r--r--src/print.c8
-rw-r--r--src/profiler.c91
-rw-r--r--src/ralloc.c34
-rw-r--r--src/regex.c2
-rw-r--r--src/termhooks.h18
-rw-r--r--src/terminal.c9
-rw-r--r--src/w32fns.c44
-rw-r--r--src/w32term.c13
-rw-r--r--src/w32term.h11
-rw-r--r--src/window.c169
-rw-r--r--src/xdisp.c81
-rw-r--r--src/xfaces.c130
-rw-r--r--src/xfns.c56
-rw-r--r--src/xmenu.c5
-rw-r--r--src/xselect.c21
-rw-r--r--src/xterm.c55
-rw-r--r--src/xterm.h6
42 files changed, 1312 insertions, 1184 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 efe5e59cb73..e67518d63ba 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -3,6 +3,346 @@
3 * font.c (font_unparse_xlfd): Exclude special characters from the 3 * font.c (font_unparse_xlfd): Exclude special characters from the
4 generating XLFD name. 4 generating XLFD name.
5 5
62012-11-13 Dmitry Antipov <dmantipov@yandex.ru>
7
8 Omit glyphs initialization at startup.
9 * dispnew.c (glyphs_initialized_initially_p): Remove.
10 (adjust_frame_glyphs_initially): Likewise. Adjust users.
11 (Fredraw_frame): Move actual code from here...
12 (redraw_here): ...to here. Add eassert. Adjust comment.
13 (Fredraw_display): Use redraw_frame.
14 * xdisp.c (clear_garbaged_frames): Likewise.
15
162012-11-13 Eli Zaretskii <eliz@gnu.org>
17
18 * xdisp.c (decode_mode_spec): Limit the value of WIDTH argument
19 passed to pint2str and pint2hrstr to be at most the size of the
20 frame's decode_mode_spec_buffer. This avoids crashes with very
21 large values of FIELD_WIDTH argument to decode_mode_spec.
22 (Bug#12867)
23
242012-11-13 Paul Eggert <eggert@cs.ucla.edu>
25
26 Fix a race with verify-visited-file-modtime (Bug#12863).
27 Since at least 1991 Emacs has ignored an mtime difference of no
28 more than one second, but my guess is that this was to work around
29 file system bugs that were fixed long ago. Since the race is
30 causing problems now, let's remove that code.
31 * fileio.c (Fverify_visited_file_modtime): Do not accept a file
32 whose time stamp is off by no more than a second. Insist that the
33 file time stamps match exactly.
34
352012-11-12 Dmitry Antipov <dmantipov@yandex.ru>
36
37 * frame.h (struct frame): Convert external_tool_bar member to
38 1-bit unsigned bitfield.
39 * termhooks.h (struct terminal): Remove mouse_moved member since
40 all users are long dead. Adjust comment on mouse_position_hook.
41
422012-11-12 Dmitry Antipov <dmantipov@yandex.ru>
43
44 Simplify by using FOR_EACH_FRAME here and there.
45 * frame.c (next_frame, prev_frame, other_visible_frames)
46 (delete_frame, visible-frame-list): Use FOR_EACH_FRAME.
47 * w32term.c (x_window_to_scroll_bar): Likewise.
48 * window.c (window_list): Likewise.
49 * xdisp.c (x_consider_frame_title): Likewise.
50 * xfaces.c ( Fdisplay_supports_face_attributes_p): Likewise.
51 * xfns.c (x_window_to_frame, x_any_window_to_frame)
52 (x_menubar_window_to_frame, x_top_window_to_frame): Likewise.
53 * xmenu.c (menubar_id_to_frame): Likewise.
54 * xselect.c (frame_for_x_selection): Likewise.
55 * xterm.c (x_frame_of_widget, x_window_to_scroll_bar)
56 (x_window_to_menu_bar): Likewise.
57 * w32fns.c (x_window_to_frame): Likewise. Adjust comment.
58
592012-11-12 Paul Eggert <eggert@cs.ucla.edu>
60
61 * data.c (Qdefalias_fset_function): Now static.
62
63 Another tweak to vectorlike_header change.
64 * alloc.c (struct Lisp_Vectorlike_Free, NEXT_IN_FREE_LIST):
65 Remove, and replace all uses with ...
66 (next_in_free_list, set_next_in_free_list):
67 New functions, which respect C's aliasing rules better.
68
692012-11-11 Paul Eggert <eggert@cs.ucla.edu>
70
71 * window.c (list4i): Rename from 'quad'. All uses changed.
72 Needed because <sys/types.h> defines 'quad' on Solaris 10.
73
742012-11-11 Juanma Barranquero <lekktu@gmail.com>
75
76 * xdisp.c (start_hourglass) [HAVE_NTGUI]: Add block to silence
77 warning about mixing declarations and code in ISO C90.
78
792012-11-10 Martin Rudalics <rudalics@gmx.at>
80
81 * window.c (Fsplit_window_internal): Set combination limit of
82 new parent window to t iff Vwindow_combination_limit is t;
83 fixing a regression introduced with the change from 2012-09-22.
84 (Fset_window_combination_limit): Fix doc-string.
85
862012-11-10 Eli Zaretskii <eliz@gnu.org>
87
88 * xdisp.c (try_scrolling): Fix correction of aggressive-scroll
89 amount when the scroll margins are too large. When scrolling
90 backwards in the buffer, give up if cannot reach point or the
91 scroll margin within a reasonable number of screen lines. Fixes
92 point position in window under scroll-up/down-aggressively when
93 point is positioned many lines beyond the window top/bottom.
94 (Bug#12811)
95
96 * ralloc.c (relinquish): If real_morecore fails to return memory
97 to the system, don't crash; instead, leave the last heap
98 unchanged and return. (Bug#12774)
99
1002012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
101
102 * lisp.h (AUTOLOADP): New macro.
103 * eval.c (Fautoload): Don't attach to loadhist, call Fdefalias instead.
104 * data.c (Ffset): Remove special ad-advice-info handling.
105 (Fdefalias): Handle autoload definitions and new Qdefalias_fset_function.
106 (Fsubr_arity): CSE.
107 (Finteractive_form): Simplify.
108 (Fquo): Don't insist on having at least 2 arguments.
109 (Qdefalias_fset_function): New var.
110
1112012-11-09 Jan Djärv <jan.h.d@swipnet.se>
112
113 * image.c (xpm_make_color_table_h): Change to hashtest_equal.
114
115 * nsfont.m (Qcondensed, Qexpanded): New variables.
116 (ns_descriptor_to_entity): Restore Qcondensed, Qexpanded setting.
117 (syms_of_nsfont): Defsym Qcondensed, Qexpanded.
118
1192012-11-09 Dmitry Antipov <dmantipov@yandex.ru>
120
121 Fix recently introduced crash on MS-Windows (Bug#12839).
122 * w32term.h (struct scroll_bar): Use convenient header.
123 (SCROLL_BAR_VEC_SIZE): Remove.
124 * w32term.c (x_scroll_bar_create): Use VECSIZE.
125
1262012-11-09 Dmitry Antipov <dmantipov@yandex.ru>
127
128 Tweak last vectorlike_header change.
129 * alloc.c (struct Lisp_Vectorlike_Free): Special type to represent
130 vectorlike object on the free list. This is introduced to avoid
131 some (but not all) pointer casting and aliasing problems, see
132 http://lists.gnu.org/archive/html/emacs-devel/2012-11/msg00105.html.
133 * .gdbinit (pvectype, pvecsize): New commands to examine vectorlike
134 objects.
135 (xvectype, xvecsize): Use them to examine Lisp_Object values.
136
1372012-11-09 Jan Djärv <jan.h.d@swipnet.se>
138
139 * nsfont.m (ns_descriptor_to_entity): Qcondensed and Qexpanded has
140 been removed, so remove them here also.
141
1422012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
143
144 * doc.c (Fdocumentation): Handle new property
145 dynamic-docstring-function to replace the old ad-advice-info.
146
1472012-11-09 Paul Eggert <eggert@cs.ucla.edu>
148
149 * fns.c (Qeql, hashtest_eq): Now static.
150
1512012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
152
153 * lisp.h (XHASH): Redefine to be imperfect and fit in a Lisp int.
154 * fns.c (hashfn_eq, hashfn_eql, sxhash):
155 * profiler.c (hashfn_profiler): Don't use XUINT on non-integers.
156 * buffer.c (compare_overlays): Use XLI rather than XHASH.
157
1582012-11-08 Paul Eggert <eggert@cs.ucla.edu>
159
160 Use same hash function for hashfn_profiler as for hash_string etc.
161 * fns.c (SXHASH_COMBINE): Remove. All uses replaced by sxhash_combine.
162 * lisp.h (sxhash_combine): New inline function, with the contents
163 of the old SXHASH_COMBINE.
164 * profiler.c (hashfn_profiler): Use it, instead of having a
165 special hash function containing a comparison that always yields 1.
166
1672012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
168
169 * xfaces.c (Qultra_light, Qreverse_oblique, Qreverse_italic)
170 (Qultra_condensed, Qextra_condensed, Qcondensed, Qsemi_condensed)
171 (Qsemi_expanded, Qextra_expanded, Qexpanded, Qultra_expanded):
172 Remove unused vars.
173
1742012-11-08 Jan Djärv <jan.h.d@swipnet.se>
175
176 * image.c (xpm_make_color_table_h): Fix compiler error because
177 make_hash_table changed.
178
1792012-11-08 Thomas Kappler <tkappler@gmail.com> (tiny change)
180
181 * nsfont.m (ns_findfonts): Handle empty matchingDescs (Bug#11541).
182
1832012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
184
185 Use ad-hoc comparison function for the profiler's hash-tables.
186 * profiler.c (Qprofiler_backtrace_equal, hashtest_profiler): New vars.
187 (make_log): Use them.
188 (handle_profiler_signal): Don't inhibit quit any longer since we don't
189 call Fequal any more.
190 (Ffunction_equal): New function.
191 (cmpfn_profiler, hashfn_profiler): New functions.
192 (syms_of_profiler): Initialize them.
193 * lisp.h (struct hash_table_test): New struct.
194 (struct Lisp_Hash_Table): Use it.
195 * alloc.c (mark_object): Mark hash_table_test fields of hash tables.
196 * fns.c (make_hash_table): Take a struct to describe the test.
197 (cmpfn_eql, cmpfn_equal, cmpfn_user_defined, hashfn_eq, hashfn_eql)
198 (hashfn_equal, hashfn_user_defined): Adjust to new calling convention.
199 (hash_lookup, hash_remove_from_table): Move assertion checking of
200 hashfn result here. Check hash-equality before calling cmpfn.
201 (Fmake_hash_table): Adjust call to make_hash_table.
202 (hashtest_eq, hashtest_eql, hashtest_equal): New structs.
203 (syms_of_fns): Initialize them.
204 * emacs.c (main): Move syms_of_fns earlier.
205 * xterm.c (syms_of_xterm):
206 * category.c (hash_get_category_set): Adjust call to make_hash_table.
207 * print.c (print_object): Adjust to new hash-table struct.
208 * composite.c (composition_gstring_put_cache): Adjust to new hashfn.
209
2102012-11-08 Eli Zaretskii <eliz@gnu.org>
211
212 * w32fns.c (modifier_set): Fix handling of Scroll Lock when the
213 value of w32-scroll-lock-modifier is neither nil nor one of the
214 known key modifiers. (Bug#12806)
215
2162012-11-08 Dmitry Antipov <dmantipov@yandex.ru>
217
218 Shrink struct vectorlike_header to the only size field.
219 * lisp.h (enum pvec_type): Avoid explicit enum member values.
220 Adjust comment.
221 (enum More_Lisp_Bits): Change PSEUDOVECTOR_SIZE_BITS and
222 PVEC_TYPE_MASK to arrange new bitfield in the vector header.
223 (PSEUDOVECTOR_REST_BITS, PSEUDOVECTOR_REST_MASK): New members.
224 (PSEUDOVECTOR_AREA_BITS): New member used to extract subtype
225 information from the vector header. Adjust comment.
226 (XSETPVECTYPE, XSETPVECTYPESIZE, XSETTYPED_PSEUDOVECTOR)
227 (PSEUDOVECTOR_TYPEP, DEFUN): Adjust to match new vector header
228 layout.
229 (XSETSUBR, SUBRP): Adjust to match new Lisp_Subr layout.
230 (struct vectorlike_header): Remove next member. Adjust comment.
231 (struct Lisp_Subr): Add convenient header. Adjust comment.
232 (allocate_pseudovector): Adjust prototype.
233 * alloc.c (mark_glyph_matrix, mark_face_cache, allocate_string)
234 (sweep_string, lisp_malloc): Remove useless prototypes.
235 (enum mem_type): Adjust comment.
236 (NEXT_IN_FREE_LIST): New macro.
237 (SETUP_ON_FREE_LIST): Adjust XSETPVECTYPESIZE usage.
238 (Fmake_bool_vector): Likewise.
239 (struct large_vector): New type to represent allocation unit for
240 the vectors with the memory footprint more than VBLOOCK_BYTES_MAX.
241 (large_vectors): Change type to struct large_vector.
242 (allocate_vector_from_block): Simplify.
243 (PSEUDOVECTOR_NBYTES): Replace with...
244 (vector_nbytes): ...new function. Adjust users.
245 (sweep_vectors): Adjust processing of large vectors.
246 (allocate_vectorlike): Likewise.
247 (allocate_pseudovector): Change type of 3rd arg to enum pvec_type.
248 Add easserts. Adjust XSETPVECTYPESIZE usage.
249 (allocate_buffer): Use BUFFER_PVEC_INIT.
250 (live_vector_p): Adjust to match large vector.
251 * buffer.c (init_buffer_once): Use BUFFER_PVEC_INIT.
252 * buffer.h (struct buffer): Add next member.
253 (BUFFER_LISP_SIZE, BUFFER_REST_SIZE, BUFFER_PVEC_INIT):
254 New macros.
255 (FOR_EACH_BUFFER): Adjust to match struct buffer change.
256 * fns.c (internal_equal): Adjust to match enum pvec_type change.
257 (copy_hash_table): Adjust to match vector header change.
258 * lread.c (defsubr): Use XSETPVECTYPE.
259 * .gdbinit (xpr, xbacktrace): Adjust to match vector header change.
260 (xvectype): Likewise. Print PVEC_NORMAL_VECTOR for regular vectors.
261 (xvecsize): New command.
262
2632012-11-08 Dmitry Antipov <dmantipov@yandex.ru>
264
265 * keyboard.c (event_to_kboard): Do not dereference
266 frame_or_window field of SELECTION_REQUEST_EVENT
267 and SELECTION_CLEAR_EVENT events (Bug#12814).
268 * xterm.h (struct selection_input_event): Adjust comment.
269
2702012-11-07 Eli Zaretskii <eliz@gnu.org>
271
272 * w32fns.c (modifier_set): Don't report modifiers from toggle key,
273 such as Scroll Lock, if the respective keys are treated as
274 function keys, not as modifiers. This avoids destroying non-ASCII
275 keyboard input when Scroll Lock is toggled ON. (Bug#12806)
276
2772012-11-07 Dmitry Antipov <dmantipov@yandex.ru>
278
279 * xfns.c (Fx_wm_set_size_hint): Use check_x_frame. Adjust docstring.
280
2812012-11-06 Paul Eggert <eggert@cs.ucla.edu>
282
283 Restore some duplicate definitions (Bug#12814).
284 This undoes part of the 2012-11-03 changes. Some people build
285 with plain -g rather than with -g3, and they need the duplicate
286 definitions for .gdbinit to work; see <http://bugs.gnu.org/12814#26>.
287 * lisp.h (GCTYPEBITS, ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG, VALMASK):
288 Define as macros, as well as as enums or as constants.
289
2902012-11-06 Jan Djärv <jan.h.d@swipnet.se>
291
292 * nsterm.m (convert_ns_to_X_keysym, keyDown:): Add NSNumericPadKeyMask
293 to keypad keys (Bug#12816).
294
2952012-11-06 Paul Eggert <eggert@cs.ucla.edu>
296
297 Minor adjustments of recently-changed frame functions.
298 * buffer.c (Fbuffer_list): Omit CHECK_FRAME, since arg is already
299 known to be a frame (we're in the FRAMEP branch).
300 * lisp.h (Qframep): Remove decl. frame.h declares this.
301 * window.c (quad): Args are of type EMACS_INT, not ptrdiff_t,
302 since they're meant for Lisp fixnum values.
303
3042012-11-06 Dmitry Antipov <dmantipov@yandex.ru>
305
306 * window.c (Fwindow_combination_limit): Revert to the only
307 required argument and adjust docstring as suggested in
308 http://lists.gnu.org/archive/html/emacs-diffs/2012-11/msg01082.html
309 by Martin Rudalics <rudalics@gmx.at>.
310
3112012-11-06 Dmitry Antipov <dmantipov@yandex.ru>
312
313 Widely used frame validity and checking functions.
314 * frame.h (decode_live_frame, decode_any_frame): Add prototypes.
315 * frame.c (decode_live_frame, decode_any_frame): New functions.
316 (delete_frame, Fredirect_frame_focus, Fframe_parameters)
317 (Fframe_parameter, Fframe_char_height, Fframe_char_width)
318 (Fframe_pixel_height, Fframe_pixel_width, Ftool_bar_pixel_width)
319 (Fframe_pointer_visible_p): Use decode_any_frame.
320 (Fmake_frame_visible, Fmake_frame_invisible, Ficonify_frame)
321 (Fraise_frame, Flower_frame, Fmodify_frame_parameters)
322 (Fset_frame_height, Fset_frame_width): Use decode_live_frame.
323 (Fframe_focus): Likewise. Allow zero number of arguments.
324 Adjust docstring.
325 (frame_buffer_list, frame_buffer_predicate): Remove.
326 * lisp.h (frame_buffer_predicate): Remove prototype.
327 * buffer.c (Fother_buffer): Use decode_any_frame.
328 * xdisp.c (Ftool_bar_lines_needed): Likewise.
329 * xfaces.c (Fcolor_gray_p, Fcolor_supported_p): Likewise.
330 * font.c (Ffont_face_attributes, Ffont_family_list, Fopen_font)
331 (Fclose_font, Ffont_info): Use decode_live_frame.
332 * fontset.c (check_fontset_name): Likewise.
333 * terminal.c (Fframe_terminal): Likewise.
334 * w32fns.c (check_x_frame): Likewise.
335 * window.c (Fminibuffer_window, Fwindow_at)
336 (Fcurrent_window_configuration): Likewise.
337 (Frun_window_configuration_change_hook, Fwindow_resize_apply):
338 Likewise. Allow zero number of arguments. Adjust docstring.
339 * dispnew.c (Fredraw_frame): Likewise.
340 * xfaces.c (frame_or_selected_frame): Remove.
341 (Fx_list_fonts, Finternal_get_lisp_face_attribute, Fface_font)
342 (Finternal_lisp_face_equal_p, Finternal_lisp_face_empty_p)
343 (Fframe_face_alist): Use decode_live_frame.
344 * xfns.c (check_x_frame): Likewise.
345
62012-11-06 Dmitry Antipov <dmantipov@yandex.ru> 3462012-11-06 Dmitry Antipov <dmantipov@yandex.ru>
7 347
8 * window.c (quad): New function. 348 * window.c (quad): New function.
@@ -58,8 +398,8 @@
58 398
59 Remove EMACS_OUTQSIZE+sleep hack. 399 Remove EMACS_OUTQSIZE+sleep hack.
60 * dispnew.c (update_frame_1): Remove hack for terminals slower 400 * dispnew.c (update_frame_1): Remove hack for terminals slower
61 than 2400 bps, which throttled Emacs by having it sleep. This 401 than 2400 bps, which throttled Emacs by having it sleep.
62 code hasn't worked since at least 2007, when the multi-tty stuff 402 This code hasn't worked since at least 2007, when the multi-tty stuff
63 was added, and anyway those old terminals are long dead. 403 was added, and anyway those old terminals are long dead.
64 * systty.h (EMACS_OUTQSIZE): Remove; unused. The macro isn't used even 404 * systty.h (EMACS_OUTQSIZE): Remove; unused. The macro isn't used even
65 without the dispnew.c change, as dispnew.c doesn't include systty.h. 405 without the dispnew.c change, as dispnew.c doesn't include systty.h.
@@ -98,8 +438,8 @@
98 waitpid only on subprocesses that Emacs itself creates. 438 waitpid only on subprocesses that Emacs itself creates.
99 * process.c (create_process, record_child_status_change): 439 * process.c (create_process, record_child_status_change):
100 Don't use special value -1 in pid field, as the caller now must 440 Don't use special value -1 in pid field, as the caller now must
101 know the pid rather than having the callee infer it. The 441 know the pid rather than having the callee infer it.
102 inference was sometimes incorrect anyway, due to another race. 442 The inference was sometimes incorrect anyway, due to another race.
103 (create_process): Set new 'alive' member if child is created. 443 (create_process): Set new 'alive' member if child is created.
104 (process_status_retrieved): New function. 444 (process_status_retrieved): New function.
105 (record_child_status_change): Use it. 445 (record_child_status_change): Use it.
@@ -260,8 +600,8 @@
260 600
2612012-10-29 Daniel Colascione <dancol@dancol.org> 6012012-10-29 Daniel Colascione <dancol@dancol.org>
262 602
263 * cygw32.h, cygw32.c (Qutf_16le, from_unicode, to_unicode): In 603 * cygw32.h, cygw32.c (Qutf_16le, from_unicode, to_unicode):
264 preparation for fixing bug#12739, move these functions from 604 In preparation for fixing bug#12739, move these functions from
265 here... 605 here...
266 606
267 * coding.h, coding.c: ... to here, and compile them only when 607 * coding.h, coding.c: ... to here, and compile them only when
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 347f27edc3a..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! */
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/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/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 907259a3e94..675c06c22e9 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -141,10 +141,6 @@ struct frame *last_nonminibuf_frame;
141 141
142static bool delayed_size_change; 142static bool delayed_size_change;
143 143
144/* 1 means glyph initialization has been completed at startup. */
145
146static bool glyphs_initialized_initially_p;
147
148/* Updated window if != 0. Set by update_window. */ 144/* Updated window if != 0. Set by update_window. */
149 145
150struct window *updated_window; 146struct window *updated_window;
@@ -1850,43 +1846,6 @@ adjust_glyphs (struct frame *f)
1850 unblock_input (); 1846 unblock_input ();
1851} 1847}
1852 1848
1853
1854/* Adjust frame glyphs when Emacs is initialized.
1855
1856 To be called from init_display.
1857
1858 We need a glyph matrix because redraw will happen soon.
1859 Unfortunately, window sizes on selected_frame are not yet set to
1860 meaningful values. I believe we can assume that there are only two
1861 windows on the frame---the mini-buffer and the root window. Frame
1862 height and width seem to be correct so far. So, set the sizes of
1863 windows to estimated values. */
1864
1865static void
1866adjust_frame_glyphs_initially (void)
1867{
1868 struct frame *sf = SELECTED_FRAME ();
1869 struct window *root = XWINDOW (sf->root_window);
1870 struct window *mini = XWINDOW (root->next);
1871 int frame_lines = FRAME_LINES (sf);
1872 int frame_cols = FRAME_COLS (sf);
1873 int top_margin = FRAME_TOP_MARGIN (sf);
1874
1875 /* Do it for the root window. */
1876 wset_top_line (root, make_number (top_margin));
1877 wset_total_lines (root, make_number (frame_lines - 1 - top_margin));
1878 wset_total_cols (root, make_number (frame_cols));
1879
1880 /* Do it for the mini-buffer window. */
1881 wset_top_line (mini, make_number (frame_lines - 1));
1882 wset_total_lines (mini, make_number (1));
1883 wset_total_cols (mini, make_number (frame_cols));
1884
1885 adjust_frame_glyphs (sf);
1886 glyphs_initialized_initially_p = 1;
1887}
1888
1889
1890/* Allocate/reallocate glyph matrices of a single frame F. */ 1849/* Allocate/reallocate glyph matrices of a single frame F. */
1891 1850
1892static void 1851static void
@@ -3071,21 +3030,13 @@ window_to_frame_hpos (struct window *w, int hpos)
3071 Redrawing Frames 3030 Redrawing Frames
3072 **********************************************************************/ 3031 **********************************************************************/
3073 3032
3074DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0, 3033/* Redraw frame F. */
3075 doc: /* Clear frame FRAME and output again what is supposed to appear on it. */)
3076 (Lisp_Object frame)
3077{
3078 struct frame *f;
3079
3080 CHECK_LIVE_FRAME (frame);
3081 f = XFRAME (frame);
3082
3083 /* Ignore redraw requests, if frame has no glyphs yet.
3084 (Implementation note: It still has to be checked why we are
3085 called so early here). */
3086 if (!glyphs_initialized_initially_p)
3087 return Qnil;
3088 3034
3035void
3036redraw_frame (struct frame *f)
3037{
3038 /* Error if F has no glyphs. */
3039 eassert (f->glyphs_initialized_p);
3089 update_begin (f); 3040 update_begin (f);
3090#ifdef MSDOS 3041#ifdef MSDOS
3091 if (FRAME_MSDOS_P (f)) 3042 if (FRAME_MSDOS_P (f))
@@ -3102,22 +3053,17 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
3102 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); 3053 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3103 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1); 3054 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
3104 f->garbaged = 0; 3055 f->garbaged = 0;
3105 return Qnil;
3106} 3056}
3107 3057
3108 3058DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0,
3109/* 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.
3110 function redraw-frame. */ 3060If FRAME is omitted or nil, the selected frame is used. */)
3111 3061 (Lisp_Object frame)
3112void
3113redraw_frame (struct frame *f)
3114{ 3062{
3115 Lisp_Object frame; 3063 redraw_frame (decode_live_frame (frame));
3116 XSETFRAME (frame, f); 3064 return Qnil;
3117 Fredraw_frame (frame);
3118} 3065}
3119 3066
3120
3121DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "", 3067DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3122 doc: /* Clear and redisplay all visible frames. */) 3068 doc: /* Clear and redisplay all visible frames. */)
3123 (void) 3069 (void)
@@ -3126,7 +3072,7 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3126 3072
3127 FOR_EACH_FRAME (tail, frame) 3073 FOR_EACH_FRAME (tail, frame)
3128 if (FRAME_VISIBLE_P (XFRAME (frame))) 3074 if (FRAME_VISIBLE_P (XFRAME (frame)))
3129 Fredraw_frame (frame); 3075 redraw_frame (XFRAME (frame));
3130 3076
3131 return Qnil; 3077 return Qnil;
3132} 3078}
@@ -6210,7 +6156,6 @@ init_display (void)
6210 So call tgetent. */ 6156 So call tgetent. */
6211 { char b[2044]; tgetent (b, "xterm");} 6157 { char b[2044]; tgetent (b, "xterm");}
6212#endif 6158#endif
6213 adjust_frame_glyphs_initially ();
6214 return; 6159 return;
6215 } 6160 }
6216#endif /* HAVE_X_WINDOWS */ 6161#endif /* HAVE_X_WINDOWS */
@@ -6220,7 +6165,6 @@ init_display (void)
6220 { 6165 {
6221 Vinitial_window_system = Qw32; 6166 Vinitial_window_system = Qw32;
6222 Vwindow_system_version = make_number (1); 6167 Vwindow_system_version = make_number (1);
6223 adjust_frame_glyphs_initially ();
6224 return; 6168 return;
6225 } 6169 }
6226#endif /* HAVE_NTGUI */ 6170#endif /* HAVE_NTGUI */
@@ -6234,7 +6178,6 @@ init_display (void)
6234 { 6178 {
6235 Vinitial_window_system = Qns; 6179 Vinitial_window_system = Qns;
6236 Vwindow_system_version = make_number (10); 6180 Vwindow_system_version = make_number (10);
6237 adjust_frame_glyphs_initially ();
6238 return; 6181 return;
6239 } 6182 }
6240#endif 6183#endif
@@ -6324,7 +6267,6 @@ init_display (void)
6324 fatal ("screen size %dx%d too big", width, height); 6267 fatal ("screen size %dx%d too big", width, height);
6325 } 6268 }
6326 6269
6327 adjust_frame_glyphs_initially ();
6328 calculate_costs (XFRAME (selected_frame)); 6270 calculate_costs (XFRAME (selected_frame));
6329 6271
6330 /* 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. */
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 f12713b9628..fee9c332c55 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1154,6 +1154,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1154 1154
1155 /* Called before syms_of_fileio, because it sets up Qerror_condition. */ 1155 /* Called before syms_of_fileio, because it sets up Qerror_condition. */
1156 syms_of_data (); 1156 syms_of_data ();
1157 syms_of_fns (); /* Before syms_of_charset which uses hashtables. */
1157 syms_of_fileio (); 1158 syms_of_fileio ();
1158 /* Before syms_of_coding to initialize Vgc_cons_threshold. */ 1159 /* Before syms_of_coding to initialize Vgc_cons_threshold. */
1159 syms_of_alloc (); 1160 syms_of_alloc ();
@@ -1165,7 +1166,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1165 1166
1166 init_window_once (); /* Init the window system. */ 1167 init_window_once (); /* Init the window system. */
1167#ifdef HAVE_WINDOW_SYSTEM 1168#ifdef HAVE_WINDOW_SYSTEM
1168 init_fringe_once (); /* Swap bitmaps if necessary. */ 1169 init_fringe_once (); /* Swap bitmaps if necessary. */
1169#endif /* HAVE_WINDOW_SYSTEM */ 1170#endif /* HAVE_WINDOW_SYSTEM */
1170 } 1171 }
1171 1172
@@ -1348,7 +1349,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1348 syms_of_lread (); 1349 syms_of_lread ();
1349 syms_of_print (); 1350 syms_of_print ();
1350 syms_of_eval (); 1351 syms_of_eval ();
1351 syms_of_fns ();
1352 syms_of_floatfns (); 1352 syms_of_floatfns ();
1353 1353
1354 syms_of_buffer (); 1354 syms_of_buffer ();
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 1ec5929506e..c57ca3ccec4 100644
--- a/src/font.c
+++ b/src/font.c
@@ -4006,16 +4006,11 @@ The optional argument FRAME specifies the frame that the face attributes
4006are to be displayed on. If omitted, the selected frame is used. */) 4006are to be displayed on. If omitted, the selected frame is used. */)
4007 (Lisp_Object font, Lisp_Object frame) 4007 (Lisp_Object font, Lisp_Object frame)
4008{ 4008{
4009 struct frame *f; 4009 struct frame *f = decode_live_frame (frame);
4010 Lisp_Object plist[10]; 4010 Lisp_Object plist[10];
4011 Lisp_Object val; 4011 Lisp_Object val;
4012 int n = 0; 4012 int n = 0;
4013 4013
4014 if (NILP (frame))
4015 frame = selected_frame;
4016 CHECK_LIVE_FRAME (frame);
4017 f = XFRAME (frame);
4018
4019 if (STRINGP (font)) 4014 if (STRINGP (font))
4020 { 4015 {
4021 int fontset = fs_query_fontset (font, 0); 4016 int fontset = fs_query_fontset (font, 0);
@@ -4165,18 +4160,15 @@ how close they are to PREFER. */)
4165 4160
4166DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0, 4161DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0,
4167 doc: /* List available font families on the current frame. 4162 doc: /* List available font families on the current frame.
4168Optional argument FRAME, if non-nil, specifies the target frame. */) 4163If FRAME is omitted or nil, the selected frame is used. */)
4169 (Lisp_Object frame) 4164 (Lisp_Object frame)
4170{ 4165{
4171 FRAME_PTR f; 4166 struct frame *f = decode_live_frame (frame);
4172 struct font_driver_list *driver_list; 4167 struct font_driver_list *driver_list;
4173 Lisp_Object list; 4168 Lisp_Object list = Qnil;
4169
4170 XSETFRAME (frame, f);
4174 4171
4175 if (NILP (frame))
4176 frame = selected_frame;
4177 CHECK_LIVE_FRAME (frame);
4178 f = XFRAME (frame);
4179 list = Qnil;
4180 for (driver_list = f->font_driver_list; driver_list; 4172 for (driver_list = f->font_driver_list; driver_list;
4181 driver_list = driver_list->next) 4173 driver_list = driver_list->next)
4182 if (driver_list->driver->list_family) 4174 if (driver_list->driver->list_family)
@@ -4544,11 +4536,9 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
4544 (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame) 4536 (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame)
4545{ 4537{
4546 EMACS_INT isize; 4538 EMACS_INT isize;
4539 struct frame *f = decode_live_frame (frame);
4547 4540
4548 CHECK_FONT_ENTITY (font_entity); 4541 CHECK_FONT_ENTITY (font_entity);
4549 if (NILP (frame))
4550 frame = selected_frame;
4551 CHECK_LIVE_FRAME (frame);
4552 4542
4553 if (NILP (size)) 4543 if (NILP (size))
4554 isize = XINT (AREF (font_entity, FONT_SIZE_INDEX)); 4544 isize = XINT (AREF (font_entity, FONT_SIZE_INDEX));
@@ -4556,7 +4546,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
4556 { 4546 {
4557 CHECK_NUMBER_OR_FLOAT (size); 4547 CHECK_NUMBER_OR_FLOAT (size);
4558 if (FLOATP (size)) 4548 if (FLOATP (size))
4559 isize = POINT_TO_PIXEL (XFLOAT_DATA (size), XFRAME (frame)->resy); 4549 isize = POINT_TO_PIXEL (XFLOAT_DATA (size), f->resy);
4560 else 4550 else
4561 isize = XINT (size); 4551 isize = XINT (size);
4562 if (! (INT_MIN <= isize && isize <= INT_MAX)) 4552 if (! (INT_MIN <= isize && isize <= INT_MAX))
@@ -4564,7 +4554,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
4564 if (isize == 0) 4554 if (isize == 0)
4565 isize = 120; 4555 isize = 120;
4566 } 4556 }
4567 return font_open_entity (XFRAME (frame), font_entity, isize); 4557 return font_open_entity (f, font_entity, isize);
4568} 4558}
4569 4559
4570DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0, 4560DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0,
@@ -4572,10 +4562,7 @@ DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0,
4572 (Lisp_Object font_object, Lisp_Object frame) 4562 (Lisp_Object font_object, Lisp_Object frame)
4573{ 4563{
4574 CHECK_FONT_OBJECT (font_object); 4564 CHECK_FONT_OBJECT (font_object);
4575 if (NILP (frame)) 4565 font_close_object (decode_live_frame (frame), font_object);
4576 frame = selected_frame;
4577 CHECK_LIVE_FRAME (frame);
4578 font_close_object (XFRAME (frame), font_object);
4579 return Qnil; 4566 return Qnil;
4580} 4567}
4581 4568
@@ -4860,7 +4847,7 @@ where
4860If the named font is not yet loaded, return nil. */) 4847If the named font is not yet loaded, return nil. */)
4861 (Lisp_Object name, Lisp_Object frame) 4848 (Lisp_Object name, Lisp_Object frame)
4862{ 4849{
4863 FRAME_PTR f; 4850 struct frame *f;
4864 struct font *font; 4851 struct font *font;
4865 Lisp_Object info; 4852 Lisp_Object info;
4866 Lisp_Object font_object; 4853 Lisp_Object font_object;
@@ -4869,10 +4856,7 @@ If the named font is not yet loaded, return nil. */)
4869 4856
4870 if (! FONTP (name)) 4857 if (! FONTP (name))
4871 CHECK_STRING (name); 4858 CHECK_STRING (name);
4872 if (NILP (frame)) 4859 f = decode_live_frame (frame);
4873 frame = selected_frame;
4874 CHECK_LIVE_FRAME (frame);
4875 f = XFRAME (frame);
4876 4860
4877 if (STRINGP (name)) 4861 if (STRINGP (name))
4878 { 4862 {
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 1d375380d56..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{
@@ -889,7 +906,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
889static Lisp_Object 906static Lisp_Object
890next_frame (Lisp_Object frame, Lisp_Object minibuf) 907next_frame (Lisp_Object frame, Lisp_Object minibuf)
891{ 908{
892 Lisp_Object tail; 909 Lisp_Object f, tail;
893 int passed = 0; 910 int passed = 0;
894 911
895 /* There must always be at least one frame in Vframe_list. */ 912 /* There must always be at least one frame in Vframe_list. */
@@ -901,12 +918,8 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
901 CHECK_LIVE_FRAME (frame); 918 CHECK_LIVE_FRAME (frame);
902 919
903 while (1) 920 while (1)
904 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 921 FOR_EACH_FRAME (tail, f)
905 { 922 {
906 Lisp_Object f;
907
908 f = XCAR (tail);
909
910 if (passed 923 if (passed
911 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame)) 924 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
912 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) 925 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
@@ -967,22 +980,13 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
967static Lisp_Object 980static Lisp_Object
968prev_frame (Lisp_Object frame, Lisp_Object minibuf) 981prev_frame (Lisp_Object frame, Lisp_Object minibuf)
969{ 982{
970 Lisp_Object tail; 983 Lisp_Object f, tail, prev = Qnil;
971 Lisp_Object prev;
972 984
973 /* There must always be at least one frame in Vframe_list. */ 985 /* There must always be at least one frame in Vframe_list. */
974 if (! CONSP (Vframe_list)) 986 eassert (CONSP (Vframe_list));
975 emacs_abort ();
976 987
977 prev = Qnil; 988 FOR_EACH_FRAME (tail, f)
978 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
979 { 989 {
980 Lisp_Object f;
981
982 f = XCAR (tail);
983 if (!FRAMEP (f))
984 emacs_abort ();
985
986 if (EQ (frame, f) && !NILP (prev)) 990 if (EQ (frame, f) && !NILP (prev))
987 return prev; 991 return prev;
988 992
@@ -1083,11 +1087,10 @@ Otherwise, include all frames. */)
1083static int 1087static int
1084other_visible_frames (FRAME_PTR f) 1088other_visible_frames (FRAME_PTR f)
1085{ 1089{
1086 Lisp_Object frames; 1090 Lisp_Object frames, this;
1087 1091
1088 for (frames = Vframe_list; CONSP (frames); frames = XCDR (frames)) 1092 FOR_EACH_FRAME (frames, this)
1089 { 1093 {
1090 Lisp_Object this = XCAR (frames);
1091 if (f == XFRAME (this)) 1094 if (f == XFRAME (this))
1092 continue; 1095 continue;
1093 1096
@@ -1118,23 +1121,12 @@ other_visible_frames (FRAME_PTR f)
1118Lisp_Object 1121Lisp_Object
1119delete_frame (Lisp_Object frame, Lisp_Object force) 1122delete_frame (Lisp_Object frame, Lisp_Object force)
1120{ 1123{
1121 struct frame *f; 1124 struct frame *f = decode_any_frame (frame);
1122 struct frame *sf = SELECTED_FRAME (); 1125 struct frame *sf = SELECTED_FRAME ();
1123 struct kboard *kb; 1126 struct kboard *kb;
1124 1127
1125 int minibuffer_selected, is_tooltip_frame; 1128 int minibuffer_selected, is_tooltip_frame;
1126 1129
1127 if (EQ (frame, Qnil))
1128 {
1129 f = sf;
1130 XSETFRAME (frame, f);
1131 }
1132 else
1133 {
1134 CHECK_FRAME (frame);
1135 f = XFRAME (frame);
1136 }
1137
1138 if (! FRAME_LIVE_P (f)) 1130 if (! FRAME_LIVE_P (f))
1139 return Qnil; 1131 return Qnil;
1140 1132
@@ -1146,19 +1138,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1146 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp)) 1138 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1147 error ("Attempt to delete the only frame"); 1139 error ("Attempt to delete the only frame");
1148 1140
1141 XSETFRAME (frame, f);
1142
1149 /* Does this frame have a minibuffer, and is it the surrogate 1143 /* Does this frame have a minibuffer, and is it the surrogate
1150 minibuffer for any other frame? */ 1144 minibuffer for any other frame? */
1151 if (FRAME_HAS_MINIBUF_P (XFRAME (frame))) 1145 if (FRAME_HAS_MINIBUF_P (f))
1152 { 1146 {
1153 Lisp_Object frames; 1147 Lisp_Object frames, this;
1154 1148
1155 for (frames = Vframe_list; 1149 FOR_EACH_FRAME (frames, this)
1156 CONSP (frames);
1157 frames = XCDR (frames))
1158 { 1150 {
1159 Lisp_Object this;
1160 this = XCAR (frames);
1161
1162 if (! EQ (this, frame) 1151 if (! EQ (this, frame)
1163 && EQ (frame, 1152 && EQ (frame,
1164 WINDOW_FRAME (XWINDOW 1153 WINDOW_FRAME (XWINDOW
@@ -1351,15 +1340,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1351 another one. */ 1340 another one. */
1352 if (f == last_nonminibuf_frame) 1341 if (f == last_nonminibuf_frame)
1353 { 1342 {
1354 Lisp_Object frames; 1343 Lisp_Object frames, this;
1355 1344
1356 last_nonminibuf_frame = 0; 1345 last_nonminibuf_frame = 0;
1357 1346
1358 for (frames = Vframe_list; 1347 FOR_EACH_FRAME (frames, this)
1359 CONSP (frames);
1360 frames = XCDR (frames))
1361 { 1348 {
1362 f = XFRAME (XCAR (frames)); 1349 f = XFRAME (this);
1363 if (!FRAME_MINIBUF_ONLY_P (f)) 1350 if (!FRAME_MINIBUF_ONLY_P (f))
1364 { 1351 {
1365 last_nonminibuf_frame = f; 1352 last_nonminibuf_frame = f;
@@ -1372,27 +1359,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1372 single-kboard state if we're in it for this kboard. */ 1359 single-kboard state if we're in it for this kboard. */
1373 if (kb != NULL) 1360 if (kb != NULL)
1374 { 1361 {
1375 Lisp_Object frames; 1362 Lisp_Object frames, this;
1376 /* 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. */
1377 Lisp_Object frame_on_same_kboard; 1364 Lisp_Object frame_on_same_kboard = Qnil;
1378
1379 frame_on_same_kboard = Qnil;
1380
1381 for (frames = Vframe_list;
1382 CONSP (frames);
1383 frames = XCDR (frames))
1384 {
1385 Lisp_Object this;
1386 struct frame *f1;
1387 1365
1388 this = XCAR (frames); 1366 FOR_EACH_FRAME (frames, this)
1389 if (!FRAMEP (this)) 1367 if (kb == FRAME_KBOARD (XFRAME (this)))
1390 emacs_abort (); 1368 frame_on_same_kboard = this;
1391 f1 = XFRAME (this);
1392
1393 if (kb == FRAME_KBOARD (f1))
1394 frame_on_same_kboard = this;
1395 }
1396 1369
1397 if (NILP (frame_on_same_kboard)) 1370 if (NILP (frame_on_same_kboard))
1398 not_single_kboard_state (kb); 1371 not_single_kboard_state (kb);
@@ -1404,27 +1377,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1404 frames with other windows. */ 1377 frames with other windows. */
1405 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame))) 1378 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
1406 { 1379 {
1407 Lisp_Object frames; 1380 Lisp_Object frames, this;
1408 1381
1409 /* 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. */
1410 Lisp_Object frame_with_minibuf; 1383 Lisp_Object frame_with_minibuf = Qnil;
1411 /* 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. */
1412 Lisp_Object frame_on_same_kboard; 1385 Lisp_Object frame_on_same_kboard = Qnil;
1413 1386
1414 frame_on_same_kboard = Qnil; 1387 FOR_EACH_FRAME (frames, this)
1415 frame_with_minibuf = Qnil;
1416
1417 for (frames = Vframe_list;
1418 CONSP (frames);
1419 frames = XCDR (frames))
1420 { 1388 {
1421 Lisp_Object this; 1389 struct frame *f1 = XFRAME (this);
1422 struct frame *f1;
1423
1424 this = XCAR (frames);
1425 if (!FRAMEP (this))
1426 emacs_abort ();
1427 f1 = XFRAME (this);
1428 1390
1429 /* Consider only frames on the same kboard 1391 /* Consider only frames on the same kboard
1430 and only those with minibuffers. */ 1392 and only those with minibuffers. */
@@ -1663,25 +1625,23 @@ DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1663If omitted, FRAME defaults to the currently selected frame. */) 1625If omitted, FRAME defaults to the currently selected frame. */)
1664 (Lisp_Object frame) 1626 (Lisp_Object frame)
1665{ 1627{
1666 if (NILP (frame)) 1628 struct frame *f = decode_live_frame (frame);
1667 frame = selected_frame;
1668
1669 CHECK_LIVE_FRAME (frame);
1670 1629
1671 /* I think this should be done with a hook. */ 1630 /* I think this should be done with a hook. */
1672#ifdef HAVE_WINDOW_SYSTEM 1631#ifdef HAVE_WINDOW_SYSTEM
1673 if (FRAME_WINDOW_P (XFRAME (frame))) 1632 if (FRAME_WINDOW_P (f))
1674 { 1633 {
1675 FRAME_SAMPLE_VISIBILITY (XFRAME (frame)); 1634 FRAME_SAMPLE_VISIBILITY (f);
1676 x_make_frame_visible (XFRAME (frame)); 1635 x_make_frame_visible (f);
1677 } 1636 }
1678#endif 1637#endif
1679 1638
1680 make_frame_visible_1 (XFRAME (frame)->root_window); 1639 make_frame_visible_1 (f->root_window);
1681 1640
1682 /* Make menu bar update for the Buffers and Frames menus. */ 1641 /* Make menu bar update for the Buffers and Frames menus. */
1683 windows_or_buffers_changed++; 1642 windows_or_buffers_changed++;
1684 1643
1644 XSETFRAME (frame, f);
1685 return frame; 1645 return frame;
1686} 1646}
1687 1647
@@ -1722,16 +1682,13 @@ always considered visible, whether or not they are currently being
1722displayed in the terminal. */) 1682displayed in the terminal. */)
1723 (Lisp_Object frame, Lisp_Object force) 1683 (Lisp_Object frame, Lisp_Object force)
1724{ 1684{
1725 if (NILP (frame)) 1685 struct frame *f = decode_live_frame (frame);
1726 frame = selected_frame;
1727
1728 CHECK_LIVE_FRAME (frame);
1729 1686
1730 if (NILP (force) && !other_visible_frames (XFRAME (frame))) 1687 if (NILP (force) && !other_visible_frames (f))
1731 error ("Attempt to make invisible the sole visible or iconified frame"); 1688 error ("Attempt to make invisible the sole visible or iconified frame");
1732 1689
1733 /* Don't allow minibuf_window to remain on a deleted frame. */ 1690 /* Don't allow minibuf_window to remain on a deleted frame. */
1734 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) 1691 if (EQ (f->minibuffer_window, minibuf_window))
1735 { 1692 {
1736 struct frame *sf = XFRAME (selected_frame); 1693 struct frame *sf = XFRAME (selected_frame);
1737 /* Use set_window_buffer instead of Fset_window_buffer (see 1694 /* Use set_window_buffer instead of Fset_window_buffer (see
@@ -1743,8 +1700,8 @@ displayed in the terminal. */)
1743 1700
1744 /* I think this should be done with a hook. */ 1701 /* I think this should be done with a hook. */
1745#ifdef HAVE_WINDOW_SYSTEM 1702#ifdef HAVE_WINDOW_SYSTEM
1746 if (FRAME_WINDOW_P (XFRAME (frame))) 1703 if (FRAME_WINDOW_P (f))
1747 x_make_frame_invisible (XFRAME (frame)); 1704 x_make_frame_invisible (f);
1748#endif 1705#endif
1749 1706
1750 /* Make menu bar update for the Buffers and Frames menus. */ 1707 /* Make menu bar update for the Buffers and Frames menus. */
@@ -1759,19 +1716,10 @@ DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1759If omitted, FRAME defaults to the currently selected frame. */) 1716If omitted, FRAME defaults to the currently selected frame. */)
1760 (Lisp_Object frame) 1717 (Lisp_Object frame)
1761{ 1718{
1762 if (NILP (frame)) 1719 struct frame *f = decode_live_frame (frame);
1763 frame = selected_frame;
1764
1765 CHECK_LIVE_FRAME (frame);
1766
1767#if 0 /* This isn't logically necessary, and it can do GC. */
1768 /* Don't let the frame remain selected. */
1769 if (EQ (frame, selected_frame))
1770 Fhandle_switch_frame (next_frame (frame, Qt));
1771#endif
1772 1720
1773 /* Don't allow minibuf_window to remain on an iconified frame. */ 1721 /* Don't allow minibuf_window to remain on an iconified frame. */
1774 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window)) 1722 if (EQ (f->minibuffer_window, minibuf_window))
1775 { 1723 {
1776 struct frame *sf = XFRAME (selected_frame); 1724 struct frame *sf = XFRAME (selected_frame);
1777 /* Use set_window_buffer instead of Fset_window_buffer (see 1725 /* Use set_window_buffer instead of Fset_window_buffer (see
@@ -1783,8 +1731,8 @@ If omitted, FRAME defaults to the currently selected frame. */)
1783 1731
1784 /* I think this should be done with a hook. */ 1732 /* I think this should be done with a hook. */
1785#ifdef HAVE_WINDOW_SYSTEM 1733#ifdef HAVE_WINDOW_SYSTEM
1786 if (FRAME_WINDOW_P (XFRAME (frame))) 1734 if (FRAME_WINDOW_P (f))
1787 x_iconify_frame (XFRAME (frame)); 1735 x_iconify_frame (f);
1788#endif 1736#endif
1789 1737
1790 /* Make menu bar update for the Buffers and Frames menus. */ 1738 /* Make menu bar update for the Buffers and Frames menus. */
@@ -1822,20 +1770,12 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1822 doc: /* Return a list of all frames now \"visible\" (being updated). */) 1770 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1823 (void) 1771 (void)
1824{ 1772{
1825 Lisp_Object tail, frame; 1773 Lisp_Object tail, frame, value = Qnil;
1826 struct frame *f; 1774
1827 Lisp_Object value; 1775 FOR_EACH_FRAME (tail, frame)
1776 if (FRAME_VISIBLE_P (XFRAME (frame)))
1777 value = Fcons (frame, value);
1828 1778
1829 value = Qnil;
1830 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1831 {
1832 frame = XCAR (tail);
1833 if (!FRAMEP (frame))
1834 continue;
1835 f = XFRAME (frame);
1836 if (FRAME_VISIBLE_P (f))
1837 value = Fcons (frame, value);
1838 }
1839 return value; 1779 return value;
1840} 1780}
1841 1781
@@ -1848,13 +1788,9 @@ If Emacs is displaying on an ordinary terminal or some other device which
1848doesn't support multiple overlapping frames, this function selects FRAME. */) 1788doesn't support multiple overlapping frames, this function selects FRAME. */)
1849 (Lisp_Object frame) 1789 (Lisp_Object frame)
1850{ 1790{
1851 struct frame *f; 1791 struct frame *f = decode_live_frame (frame);
1852 if (NILP (frame))
1853 frame = selected_frame;
1854
1855 CHECK_LIVE_FRAME (frame);
1856 1792
1857 f = XFRAME (frame); 1793 XSETFRAME (frame, f);
1858 1794
1859 if (FRAME_TERMCAP_P (f)) 1795 if (FRAME_TERMCAP_P (f))
1860 /* On a text terminal select FRAME. */ 1796 /* On a text terminal select FRAME. */
@@ -1877,14 +1813,7 @@ If Emacs is displaying on an ordinary terminal or some other device which
1877doesn't support multiple overlapping frames, this function does nothing. */) 1813doesn't support multiple overlapping frames, this function does nothing. */)
1878 (Lisp_Object frame) 1814 (Lisp_Object frame)
1879{ 1815{
1880 struct frame *f; 1816 struct frame *f = decode_live_frame (frame);
1881
1882 if (NILP (frame))
1883 frame = selected_frame;
1884
1885 CHECK_LIVE_FRAME (frame);
1886
1887 f = XFRAME (frame);
1888 1817
1889 if (FRAME_TERMINAL (f)->frame_raise_lower_hook) 1818 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
1890 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0); 1819 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
@@ -1920,18 +1849,14 @@ is affected by `select-frame', while the latter is not.
1920The redirection lasts until `redirect-frame-focus' is called to change it. */) 1849The redirection lasts until `redirect-frame-focus' is called to change it. */)
1921 (Lisp_Object frame, Lisp_Object focus_frame) 1850 (Lisp_Object frame, Lisp_Object focus_frame)
1922{ 1851{
1923 struct frame *f;
1924
1925 /* 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
1926 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
1927 know what other frame should receive those keystrokes. */ 1854 know what other frame should receive those keystrokes. */
1928 CHECK_FRAME (frame); 1855 struct frame *f = decode_any_frame (frame);
1929 1856
1930 if (! NILP (focus_frame)) 1857 if (! NILP (focus_frame))
1931 CHECK_LIVE_FRAME (focus_frame); 1858 CHECK_LIVE_FRAME (focus_frame);
1932 1859
1933 f = XFRAME (frame);
1934
1935 fset_focus_frame (f, focus_frame); 1860 fset_focus_frame (f, focus_frame);
1936 1861
1937 if (FRAME_TERMINAL (f)->frame_rehighlight_hook) 1862 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
@@ -1941,15 +1866,14 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */)
1941} 1866}
1942 1867
1943 1868
1944DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0, 1869DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 0, 1, 0,
1945 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.
1946This 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.
1947See `redirect-frame-focus'. */) 1873See `redirect-frame-focus'. */)
1948 (Lisp_Object frame) 1874 (Lisp_Object frame)
1949{ 1875{
1950 CHECK_LIVE_FRAME (frame); 1876 return FRAME_FOCUS_FRAME (decode_live_frame (frame));
1951
1952 return FRAME_FOCUS_FRAME (XFRAME (frame));
1953} 1877}
1954 1878
1955 1879
@@ -1972,22 +1896,6 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
1972} 1896}
1973#endif 1897#endif
1974 1898
1975/* Return the buffer-predicate of the selected frame. */
1976
1977Lisp_Object
1978frame_buffer_predicate (Lisp_Object frame)
1979{
1980 return XFRAME (frame)->buffer_predicate;
1981}
1982
1983/* Return the buffer-list of the selected frame. */
1984
1985static Lisp_Object
1986frame_buffer_list (Lisp_Object frame)
1987{
1988 return XFRAME (frame)->buffer_list;
1989}
1990
1991/* 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. */
1992 1900
1993void 1901void
@@ -2166,20 +2074,14 @@ DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2166 doc: /* Return the parameters-alist of frame FRAME. 2074 doc: /* Return the parameters-alist of frame FRAME.
2167It 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.
2168The meaningful PARMs depend on the kind of frame. 2076The meaningful PARMs depend on the kind of frame.
2169If FRAME is omitted, return information on the currently selected frame. */) 2077If FRAME is omitted or nil, return information on the currently selected frame. */)
2170 (Lisp_Object frame) 2078 (Lisp_Object frame)
2171{ 2079{
2172 Lisp_Object alist; 2080 Lisp_Object alist;
2173 FRAME_PTR f; 2081 struct frame *f = decode_any_frame (frame);
2174 int height, width; 2082 int height, width;
2175 struct gcpro gcpro1; 2083 struct gcpro gcpro1;
2176 2084
2177 if (NILP (frame))
2178 frame = selected_frame;
2179
2180 CHECK_FRAME (frame);
2181 f = XFRAME (frame);
2182
2183 if (!FRAME_LIVE_P (f)) 2085 if (!FRAME_LIVE_P (f))
2184 return Qnil; 2086 return Qnil;
2185 2087
@@ -2240,9 +2142,8 @@ If FRAME is omitted, return information on the currently selected frame. */)
2240 : FRAME_MINIBUF_ONLY_P (f) ? Qonly 2142 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2241 : FRAME_MINIBUF_WINDOW (f))); 2143 : FRAME_MINIBUF_WINDOW (f)));
2242 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));
2243 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame)); 2145 store_in_alist (&alist, Qbuffer_list, f->buffer_list);
2244 store_in_alist (&alist, Qburied_buffer_list, 2146 store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
2245 XFRAME (frame)->buried_buffer_list);
2246 2147
2247 /* I think this should be done with a hook. */ 2148 /* I think this should be done with a hook. */
2248#ifdef HAVE_WINDOW_SYSTEM 2149#ifdef HAVE_WINDOW_SYSTEM
@@ -2267,17 +2168,12 @@ DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2267If FRAME is nil, describe the currently selected frame. */) 2168If FRAME is nil, describe the currently selected frame. */)
2268 (Lisp_Object frame, Lisp_Object parameter) 2169 (Lisp_Object frame, Lisp_Object parameter)
2269{ 2170{
2270 struct frame *f; 2171 struct frame *f = decode_any_frame (frame);
2271 Lisp_Object value; 2172 Lisp_Object value = Qnil;
2272 2173
2273 if (NILP (frame))
2274 frame = selected_frame;
2275 else
2276 CHECK_FRAME (frame);
2277 CHECK_SYMBOL (parameter); 2174 CHECK_SYMBOL (parameter);
2278 2175
2279 f = XFRAME (frame); 2176 XSETFRAME (frame, f);
2280 value = Qnil;
2281 2177
2282 if (FRAME_LIVE_P (f)) 2178 if (FRAME_LIVE_P (f))
2283 { 2179 {
@@ -2357,14 +2253,9 @@ Note that this functionality is obsolete as of Emacs 22.2, and its
2357use is not recommended. Explicitly check for a frame-parameter instead. */) 2253use is not recommended. Explicitly check for a frame-parameter instead. */)
2358 (Lisp_Object frame, Lisp_Object alist) 2254 (Lisp_Object frame, Lisp_Object alist)
2359{ 2255{
2360 FRAME_PTR f; 2256 struct frame *f = decode_live_frame (frame);
2361 register Lisp_Object tail, prop, val; 2257 register Lisp_Object tail, prop, val;
2362 2258
2363 if (EQ (frame, Qnil))
2364 frame = selected_frame;
2365 CHECK_LIVE_FRAME (frame);
2366 f = XFRAME (frame);
2367
2368 /* I think this should be done with a hook. */ 2259 /* I think this should be done with a hook. */
2369#ifdef HAVE_WINDOW_SYSTEM 2260#ifdef HAVE_WINDOW_SYSTEM
2370 if (FRAME_WINDOW_P (f)) 2261 if (FRAME_WINDOW_P (f))
@@ -2419,18 +2310,13 @@ use is not recommended. Explicitly check for a frame-parameter instead. */)
2419DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height, 2310DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2420 0, 1, 0, 2311 0, 1, 0,
2421 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.
2422If FRAME is omitted, the selected frame is used. 2313If FRAME is omitted or nil, the selected frame is used.
2423For a terminal frame, the value is always 1. */) 2314For a terminal frame, the value is always 1. */)
2424 (Lisp_Object frame) 2315 (Lisp_Object frame)
2425{ 2316{
2426 struct frame *f;
2427
2428 if (NILP (frame))
2429 frame = selected_frame;
2430 CHECK_FRAME (frame);
2431 f = XFRAME (frame);
2432
2433#ifdef HAVE_WINDOW_SYSTEM 2317#ifdef HAVE_WINDOW_SYSTEM
2318 struct frame *f = decode_any_frame (frame);
2319
2434 if (FRAME_WINDOW_P (f)) 2320 if (FRAME_WINDOW_P (f))
2435 return make_number (x_char_height (f)); 2321 return make_number (x_char_height (f));
2436 else 2322 else
@@ -2442,19 +2328,14 @@ For a terminal frame, the value is always 1. */)
2442DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width, 2328DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2443 0, 1, 0, 2329 0, 1, 0,
2444 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.
2445If FRAME is omitted, the selected frame is used. 2331If FRAME is omitted or nil, the selected frame is used.
2446On 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.
2447For a terminal screen, the value is always 1. */) 2333For a terminal screen, the value is always 1. */)
2448 (Lisp_Object frame) 2334 (Lisp_Object frame)
2449{ 2335{
2450 struct frame *f;
2451
2452 if (NILP (frame))
2453 frame = selected_frame;
2454 CHECK_FRAME (frame);
2455 f = XFRAME (frame);
2456
2457#ifdef HAVE_WINDOW_SYSTEM 2336#ifdef HAVE_WINDOW_SYSTEM
2337 struct frame *f = decode_any_frame (frame);
2338
2458 if (FRAME_WINDOW_P (f)) 2339 if (FRAME_WINDOW_P (f))
2459 return make_number (x_char_width (f)); 2340 return make_number (x_char_width (f));
2460 else 2341 else
@@ -2465,7 +2346,7 @@ For a terminal screen, the value is always 1. */)
2465DEFUN ("frame-pixel-height", Fframe_pixel_height, 2346DEFUN ("frame-pixel-height", Fframe_pixel_height,
2466 Sframe_pixel_height, 0, 1, 0, 2347 Sframe_pixel_height, 0, 1, 0,
2467 doc: /* Return a FRAME's height in pixels. 2348 doc: /* Return a FRAME's height in pixels.
2468If 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
2469of the result depends on the window-system and toolkit in use: 2350of the result depends on the window-system and toolkit in use:
2470 2351
2471In the Gtk+ version of Emacs, it includes only any window (including 2352In the Gtk+ version of Emacs, it includes only any window (including
@@ -2480,12 +2361,7 @@ result is really in characters rather than pixels (i.e., is identical
2480to `frame-height'). */) 2361to `frame-height'). */)
2481 (Lisp_Object frame) 2362 (Lisp_Object frame)
2482{ 2363{
2483 struct frame *f; 2364 struct frame *f = decode_any_frame (frame);
2484
2485 if (NILP (frame))
2486 frame = selected_frame;
2487 CHECK_FRAME (frame);
2488 f = XFRAME (frame);
2489 2365
2490#ifdef HAVE_WINDOW_SYSTEM 2366#ifdef HAVE_WINDOW_SYSTEM
2491 if (FRAME_WINDOW_P (f)) 2367 if (FRAME_WINDOW_P (f))
@@ -2499,15 +2375,10 @@ DEFUN ("frame-pixel-width", Fframe_pixel_width,
2499 Sframe_pixel_width, 0, 1, 0, 2375 Sframe_pixel_width, 0, 1, 0,
2500 doc: /* Return FRAME's width in pixels. 2376 doc: /* Return FRAME's width in pixels.
2501For a terminal frame, the result really gives the width in characters. 2377For a terminal frame, the result really gives the width in characters.
2502If FRAME is omitted, the selected frame is used. */) 2378If FRAME is omitted or nil, the selected frame is used. */)
2503 (Lisp_Object frame) 2379 (Lisp_Object frame)
2504{ 2380{
2505 struct frame *f; 2381 struct frame *f = decode_any_frame (frame);
2506
2507 if (NILP (frame))
2508 frame = selected_frame;
2509 CHECK_FRAME (frame);
2510 f = XFRAME (frame);
2511 2382
2512#ifdef HAVE_WINDOW_SYSTEM 2383#ifdef HAVE_WINDOW_SYSTEM
2513 if (FRAME_WINDOW_P (f)) 2384 if (FRAME_WINDOW_P (f))
@@ -2521,17 +2392,15 @@ DEFUN ("tool-bar-pixel-width", Ftool_bar_pixel_width,
2521 Stool_bar_pixel_width, 0, 1, 0, 2392 Stool_bar_pixel_width, 0, 1, 0,
2522 doc: /* Return width in pixels of FRAME's tool bar. 2393 doc: /* Return width in pixels of FRAME's tool bar.
2523The 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
2524or 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
2525used. */) 2396is used. */)
2526 (Lisp_Object frame) 2397 (Lisp_Object frame)
2527{ 2398{
2528 if (NILP (frame))
2529 frame = selected_frame;
2530 CHECK_FRAME (frame);
2531
2532#ifdef FRAME_TOOLBAR_WIDTH 2399#ifdef FRAME_TOOLBAR_WIDTH
2533 if (FRAME_WINDOW_P (XFRAME (frame))) 2400 struct frame *f = decode_any_frame (frame);
2534 return make_number (FRAME_TOOLBAR_WIDTH (XFRAME (frame))); 2401
2402 if (FRAME_WINDOW_P (f))
2403 return make_number (FRAME_TOOLBAR_WIDTH (f));
2535#endif 2404#endif
2536 return make_number (0); 2405 return make_number (0);
2537} 2406}
@@ -2542,13 +2411,9 @@ Optional third arg non-nil means that redisplay should use LINES lines
2542but 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. */)
2543 (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend) 2412 (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
2544{ 2413{
2545 register struct frame *f; 2414 register struct frame *f = decode_live_frame (frame);
2546 2415
2547 CHECK_TYPE_RANGED_INTEGER (int, lines); 2416 CHECK_TYPE_RANGED_INTEGER (int, lines);
2548 if (NILP (frame))
2549 frame = selected_frame;
2550 CHECK_LIVE_FRAME (frame);
2551 f = XFRAME (frame);
2552 2417
2553 /* I think this should be done with a hook. */ 2418 /* I think this should be done with a hook. */
2554#ifdef HAVE_WINDOW_SYSTEM 2419#ifdef HAVE_WINDOW_SYSTEM
@@ -2570,12 +2435,9 @@ Optional third arg non-nil means that redisplay should use COLS columns
2570but 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. */)
2571 (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend) 2436 (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
2572{ 2437{
2573 register struct frame *f; 2438 register struct frame *f = decode_live_frame (frame);
2439
2574 CHECK_TYPE_RANGED_INTEGER (int, cols); 2440 CHECK_TYPE_RANGED_INTEGER (int, cols);
2575 if (NILP (frame))
2576 frame = selected_frame;
2577 CHECK_LIVE_FRAME (frame);
2578 f = XFRAME (frame);
2579 2441
2580 /* I think this should be done with a hook. */ 2442 /* I think this should be done with a hook. */
2581#ifdef HAVE_WINDOW_SYSTEM 2443#ifdef HAVE_WINDOW_SYSTEM
@@ -4292,12 +4154,7 @@ Otherwise it returns nil. FRAME omitted or nil means the
4292selected frame. This is useful when `make-pointer-invisible' is set. */) 4154selected frame. This is useful when `make-pointer-invisible' is set. */)
4293 (Lisp_Object frame) 4155 (Lisp_Object frame)
4294{ 4156{
4295 if (NILP (frame)) 4157 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
4296 frame = selected_frame;
4297
4298 CHECK_FRAME (frame);
4299
4300 return (XFRAME (frame)->pointer_invisible ? Qnil : Qt);
4301} 4158}
4302 4159
4303 4160
diff --git a/src/frame.h b/src/frame.h
index eea618df797..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. */
@@ -943,6 +943,8 @@ extern Lisp_Object Qnoelisp;
943extern struct frame *last_nonminibuf_frame; 943extern struct frame *last_nonminibuf_frame;
944 944
945extern 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);
946extern struct frame *make_initial_frame (void); 948extern struct frame *make_initial_frame (void);
947extern struct frame *make_frame (int); 949extern struct frame *make_frame (int);
948#ifdef HAVE_WINDOW_SYSTEM 950#ifdef HAVE_WINDOW_SYSTEM
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/keyboard.c b/src/keyboard.c
index dfd4d0c2648..8f3a206139d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3416,13 +3416,20 @@ int stop_character EXTERNALLY_VISIBLE;
3416static KBOARD * 3416static KBOARD *
3417event_to_kboard (struct input_event *event) 3417event_to_kboard (struct input_event *event)
3418{ 3418{
3419 Lisp_Object obj = event->frame_or_window; 3419 /* Not applicable for these special events. */
3420 /* There are some events that set this field to nil or string. */ 3420 if (event->kind == SELECTION_REQUEST_EVENT
3421 if (WINDOWP (obj)) 3421 || event->kind == SELECTION_CLEAR_EVENT)
3422 obj = WINDOW_FRAME (XWINDOW (obj)); 3422 return NULL;
3423 /* Also ignore dead frames here. */ 3423 else
3424 return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj))) 3424 {
3425 ? FRAME_KBOARD (XFRAME (obj)) : NULL); 3425 Lisp_Object obj = event->frame_or_window;
3426 /* There are some events that set this field to nil or string. */
3427 if (WINDOWP (obj))
3428 obj = WINDOW_FRAME (XWINDOW (obj));
3429 /* Also ignore dead frames here. */
3430 return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj)))
3431 ? FRAME_KBOARD (XFRAME (obj)) : NULL);
3432 }
3426} 3433}
3427 3434
3428#ifdef subprocesses 3435#ifdef subprocesses
diff --git a/src/lisp.h b/src/lisp.h
index e9f47f4ed27..72e38fa4653 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -152,15 +152,18 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
152 on the few static Lisp_Objects used: all the defsubr as well 152 on the few static Lisp_Objects used: all the defsubr as well
153 as the two special buffers buffer_defaults and buffer_local_symbols. */ 153 as the two special buffers buffer_defaults and buffer_local_symbols. */
154 154
155/* Number of bits in a Lisp_Object tag. This can be used in #if. */ 155enum Lisp_Bits
156 {
157 /* Number of bits in a Lisp_Object tag. This can be used in #if,
158 and for GDB's sake also as a regular symbol. */
159 GCTYPEBITS =
156#define GCTYPEBITS 3 160#define GCTYPEBITS 3
161 GCTYPEBITS,
157 162
158/* 2**GCTYPEBITS. This must be a macro that expands to a literal 163 /* 2**GCTYPEBITS. This must be a macro that expands to a literal
159 integer constant, for MSVC. */ 164 integer constant, for MSVC. */
160#define GCALIGNMENT 8 165#define GCALIGNMENT 8
161 166
162enum Lisp_Bits
163 {
164 /* 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. */
165 VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS, 168 VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS,
166 169
@@ -378,11 +381,15 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 };
378 381
379/* In the size word of a vector, this bit means the vector has been marked. */ 382/* In the size word of a vector, this bit means the vector has been marked. */
380 383
384static ptrdiff_t const ARRAY_MARK_FLAG
381#define ARRAY_MARK_FLAG PTRDIFF_MIN 385#define ARRAY_MARK_FLAG PTRDIFF_MIN
386 = ARRAY_MARK_FLAG;
382 387
383/* In the size word of a struct Lisp_Vector, this bit means it's really 388/* In the size word of a struct Lisp_Vector, this bit means it's really
384 some other vector-like object. */ 389 some other vector-like object. */
390static ptrdiff_t const PSEUDOVECTOR_FLAG
385#define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2) 391#define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
392 = PSEUDOVECTOR_FLAG;
386 393
387/* In a pseudovector, the size field actually contains a word with one 394/* In a pseudovector, the size field actually contains a word with one
388 PSEUDOVECTOR_FLAG bit set, and one of the following values extracted 395 PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
@@ -401,14 +408,11 @@ enum pvec_type
401 PVEC_WINDOW_CONFIGURATION, 408 PVEC_WINDOW_CONFIGURATION,
402 PVEC_SUBR, 409 PVEC_SUBR,
403 PVEC_OTHER, 410 PVEC_OTHER,
404 /* 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. */
405 so they have to use a disjoint bit pattern: 412 PVEC_COMPILED,
406 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE 413 PVEC_CHAR_TABLE,
407 | PVEC_SUB_CHAR_TABLE | PVEC_FONT))) */ 414 PVEC_SUB_CHAR_TABLE,
408 PVEC_COMPILED = 0x10, 415 PVEC_FONT /* Should be last because it's used for range checking. */
409 PVEC_CHAR_TABLE = 0x20,
410 PVEC_SUB_CHAR_TABLE = 0x30,
411 PVEC_FONT = 0x40
412}; 416};
413 417
414/* 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
@@ -428,9 +432,18 @@ enum More_Lisp_Bits
428 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).
429 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
430 non-Lisp_Object fields at the end of the structure. */ 434 non-Lisp_Object fields at the end of the structure. */
431 PSEUDOVECTOR_SIZE_BITS = 16, 435 PSEUDOVECTOR_SIZE_BITS = 12,
432 PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, 436 PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
433 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,
434 447
435 /* 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
436 of bool vectors. This should not vary across implementations. */ 449 of bool vectors. This should not vary across implementations. */
@@ -441,9 +454,6 @@ enum More_Lisp_Bits
441 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,
442 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. */
443 456
444/* Return a perfect hash of the Lisp_Object representation. */
445#define XHASH(a) XLI (a)
446
447#if USE_LSB_TAG 457#if USE_LSB_TAG
448 458
449enum lsb_bits 459enum lsb_bits
@@ -464,7 +474,9 @@ enum lsb_bits
464 474
465#else /* not USE_LSB_TAG */ 475#else /* not USE_LSB_TAG */
466 476
477static EMACS_INT const VALMASK
467#define VALMASK VAL_MAX 478#define VALMASK VAL_MAX
479 = VALMASK;
468 480
469#define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS)) 481#define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS))
470 482
@@ -494,6 +506,11 @@ enum lsb_bits
494 506
495#endif /* not USE_LSB_TAG */ 507#endif /* not USE_LSB_TAG */
496 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
497/* For integers known to be positive, XFASTINT sometimes provides 514/* For integers known to be positive, XFASTINT sometimes provides
498 faster retrieval and XSETFASTINT provides faster storage. 515 faster retrieval and XSETFASTINT provides faster storage.
499 If not, fallback on the non-accelerated path. */ 516 If not, fallback on the non-accelerated path. */
@@ -509,7 +526,7 @@ enum lsb_bits
509# define XUNTAG(a, type) XPNTR (a) 526# define XUNTAG(a, type) XPNTR (a)
510#endif 527#endif
511 528
512#define EQ(x, y) (XHASH (x) == XHASH (y)) 529#define EQ(x, y) (XLI (x) == XLI (y))
513 530
514/* Largest and smallest representable fixnum values. These are the C 531/* Largest and smallest representable fixnum values. These are the C
515 values. They are macros for use in static initializers. */ 532 values. They are macros for use in static initializers. */
@@ -599,13 +616,13 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
599 616
600/* Pseudovector types. */ 617/* Pseudovector types. */
601 618
602#define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE (v, header.size, code) 619#define XSETPVECTYPE(v, code) \
603#define XSETTYPED_PVECTYPE(v, size_member, code) \ 620 ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
604 ((v)->size_member |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS)) 621#define XSETPVECTYPESIZE(v, code, lispsize, restsize) \
605#define XSETPVECTYPESIZE(v, code, sizeval) \
606 ((v)->header.size = (PSEUDOVECTOR_FLAG \ 622 ((v)->header.size = (PSEUDOVECTOR_FLAG \
607 | ((code) << PSEUDOVECTOR_SIZE_BITS) \ 623 | ((code) << PSEUDOVECTOR_AREA_BITS) \
608 | (sizeval))) 624 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \
625 | (lispsize)))
609 626
610/* The cast to struct vectorlike_header * avoids aliasing issues. */ 627/* The cast to struct vectorlike_header * avoids aliasing issues. */
611#define XSETPSEUDOVECTOR(a, b, code) \ 628#define XSETPSEUDOVECTOR(a, b, code) \
@@ -617,16 +634,14 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
617#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \ 634#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \
618 (XSETVECTOR (a, b), \ 635 (XSETVECTOR (a, b), \
619 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 636 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
620 == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_SIZE_BITS)))) 637 == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
621 638
622#define XSETWINDOW_CONFIGURATION(a, b) \ 639#define XSETWINDOW_CONFIGURATION(a, b) \
623 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)) 640 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION))
624#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) 641#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS))
625#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) 642#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW))
626#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) 643#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL))
627/* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */ 644#define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR))
628#define XSETSUBR(a, b) \
629 XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR)
630#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) 645#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
631#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) 646#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
632#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) 647#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
@@ -793,7 +808,7 @@ struct Lisp_String
793 }; 808 };
794 809
795/* Header of vector-like objects. This documents the layout constraints on 810/* Header of vector-like objects. This documents the layout constraints on
796 vectors and pseudovectors other than struct Lisp_Subr. It also prevents 811 vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents
797 compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR 812 compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR
798 and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *, 813 and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *,
799 because when two such pointers potentially alias, a compiler won't 814 because when two such pointers potentially alias, a compiler won't
@@ -801,43 +816,26 @@ struct Lisp_String
801 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */ 816 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */
802struct vectorlike_header 817struct vectorlike_header
803 { 818 {
804 /* This field contains various pieces of information: 819 /* The only field contains various pieces of information:
805 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. 820 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
806 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain 821 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
807 vector (0) or a pseudovector (1). 822 vector (0) or a pseudovector (1).
808 - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number 823 - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
809 of slots) of the vector. 824 of slots) of the vector.
810 - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into 825 - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:
811 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;
812 PSEUDOVECTOR_SIZE_BITS. That size normally indicates the number of 827 - b) number of Lisp_Objects slots at the beginning of the object
813 Lisp_Object slots at the beginning of the object that need to be 828 held in PSEUDOVECTOR_SIZE_MASK field. These objects are always
814 traced by the GC, tho some types use it slightly differently. 829 traced by the GC;
815 - 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
816 vector on a free-list and PSEUDOVECTOR_SIZE_BITS indicates its size 831 measured in word_size units. Rest fields may also include
817 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. */
818 ptrdiff_t size; 838 ptrdiff_t size;
819
820 /* When the vector is allocated from a vector block, NBYTES is used
821 if the vector is not on a free list, and VECTOR is used otherwise.
822 For large vector-like objects, BUFFER or VECTOR is used as a pointer
823 to the next vector-like object. It is generally a buffer or a
824 Lisp_Vector alias, so for convenience it is a union instead of a
825 pointer: this way, one can write P->next.vector instead of ((struct
826 Lisp_Vector *) P->next). */
827 union {
828 /* This is only needed for small vectors that are not free because the
829 `size' field only gives us the number of Lisp_Object slots, whereas we
830 need to know the total size, including non-Lisp_Object data.
831 FIXME: figure out a way to store this info elsewhere so we can
832 finally get rid of this extra word of overhead. */
833 ptrdiff_t nbytes;
834 struct buffer *buffer;
835 /* FIXME: This can be removed: For large vectors, this field could be
836 placed *before* the vector itself. And for small vectors on a free
837 list, this field could be stored in the vector's bytes, since the
838 empty vector is handled specially anyway. */
839 struct Lisp_Vector *vector;
840 } next;
841 }; 839 };
842 840
843/* Regular vector is just a header plus array of Lisp_Objects. */ 841/* Regular vector is just a header plus array of Lisp_Objects. */
@@ -1011,15 +1009,11 @@ struct Lisp_Sub_Char_Table
1011 1009
1012/* This structure describes a built-in function. 1010/* This structure describes a built-in function.
1013 It is generated by the DEFUN macro only. 1011 It is generated by the DEFUN macro only.
1014 defsubr makes it into a Lisp object. 1012 defsubr makes it into a Lisp object. */
1015
1016 This type is treated in most respects as a pseudovector,
1017 but since we never dynamically allocate or free them,
1018 we don't need a struct vectorlike_header and its 'next' field. */
1019 1013
1020struct Lisp_Subr 1014struct Lisp_Subr
1021 { 1015 {
1022 ptrdiff_t size; 1016 struct vectorlike_header header;
1023 union { 1017 union {
1024 Lisp_Object (*a0) (void); 1018 Lisp_Object (*a0) (void);
1025 Lisp_Object (*a1) (Lisp_Object); 1019 Lisp_Object (*a1) (Lisp_Object);
@@ -1167,14 +1161,29 @@ struct Lisp_Symbol
1167 1161
1168/* The structure of a Lisp hash table. */ 1162/* The structure of a Lisp hash table. */
1169 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
1170struct Lisp_Hash_Table 1182struct Lisp_Hash_Table
1171{ 1183{
1172 /* 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. */
1173 struct vectorlike_header header; 1185 struct vectorlike_header header;
1174 1186
1175 /* Function used to compare keys. */
1176 Lisp_Object test;
1177
1178 /* Nil if table is non-weak. Otherwise a symbol describing the 1187 /* Nil if table is non-weak. Otherwise a symbol describing the
1179 weakness of the table. */ 1188 weakness of the table. */
1180 Lisp_Object weak; 1189 Lisp_Object weak;
@@ -1205,12 +1214,6 @@ struct Lisp_Hash_Table
1205 hash table size to reduce collisions. */ 1214 hash table size to reduce collisions. */
1206 Lisp_Object index; 1215 Lisp_Object index;
1207 1216
1208 /* User-supplied hash function, or nil. */
1209 Lisp_Object user_hash_function;
1210
1211 /* User-supplied key comparison function, or nil. */
1212 Lisp_Object user_cmp_function;
1213
1214 /* 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
1215 `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
1216 a special way (e.g. because of weakness). */ 1219 a special way (e.g. because of weakness). */
@@ -1223,17 +1226,12 @@ struct Lisp_Hash_Table
1223 This is gc_marked specially if the table is weak. */ 1226 This is gc_marked specially if the table is weak. */
1224 Lisp_Object key_and_value; 1227 Lisp_Object key_and_value;
1225 1228
1229 /* The comparison and hash functions. */
1230 struct hash_table_test test;
1231
1226 /* 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
1227 of the list is in weak_hash_tables. */ 1233 of the list is in weak_hash_tables. */
1228 struct Lisp_Hash_Table *next_weak; 1234 struct Lisp_Hash_Table *next_weak;
1229
1230 /* C function to compare two keys. */
1231 bool (*cmpfn) (struct Lisp_Hash_Table *,
1232 Lisp_Object, EMACS_UINT,
1233 Lisp_Object, EMACS_UINT);
1234
1235 /* C function to compute hash code. */
1236 EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object);
1237}; 1235};
1238 1236
1239 1237
@@ -1288,6 +1286,15 @@ static double const DEFAULT_REHASH_THRESHOLD = 0.8;
1288 1286
1289static double const DEFAULT_REHASH_SIZE = 1.5; 1287static double const DEFAULT_REHASH_SIZE = 1.5;
1290 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
1291/* These structures are used for various misc types. */ 1298/* These structures are used for various misc types. */
1292 1299
1293struct Lisp_Misc_Any /* Supertype of all Misc types. */ 1300struct Lisp_Misc_Any /* Supertype of all Misc types. */
@@ -1687,6 +1694,8 @@ typedef struct {
1687#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) 1694#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
1688#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)
1689 1696
1697#define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x)))
1698
1690#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) 1699#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int)
1691#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) 1700#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool)
1692#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) 1701#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj)
@@ -1700,7 +1709,7 @@ typedef struct {
1700 1709
1701#define PSEUDOVECTOR_TYPEP(v, code) \ 1710#define PSEUDOVECTOR_TYPEP(v, code) \
1702 (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 1711 (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
1703 == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS))) 1712 == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS)))
1704 1713
1705/* 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
1706 code is CODE. */ 1715 code is CODE. */
@@ -1713,8 +1722,7 @@ typedef struct {
1713#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) 1722#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS)
1714#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) 1723#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW)
1715#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) 1724#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL)
1716/* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ 1725#define SUBRP(x) PSEUDOVECTORP (x, PVEC_SUBR)
1717#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR)
1718#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) 1726#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED)
1719#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) 1727#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)
1720#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) 1728#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE)
@@ -1889,8 +1897,8 @@ typedef struct {
1889#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1897#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1890 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1898 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1891 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ 1899 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \
1892 { (PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS) \ 1900 { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \
1893 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \ 1901 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \
1894 { (Lisp_Object (__cdecl *)(void))fnname }, \ 1902 { (Lisp_Object (__cdecl *)(void))fnname }, \
1895 minargs, maxargs, lname, intspec, 0}; \ 1903 minargs, maxargs, lname, intspec, 0}; \
1896 Lisp_Object fnname 1904 Lisp_Object fnname
@@ -1898,8 +1906,8 @@ typedef struct {
1898#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1906#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1899 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1907 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1900 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ 1908 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \
1901 { PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS, \ 1909 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
1902 { .a ## maxargs = fnname }, \ 1910 { .a ## maxargs = fnname }, \
1903 minargs, maxargs, lname, intspec, 0}; \ 1911 minargs, maxargs, lname, intspec, 0}; \
1904 Lisp_Object fnname 1912 Lisp_Object fnname
1905#endif 1913#endif
@@ -2628,9 +2636,6 @@ extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
2628 2636
2629EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST; 2637EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST;
2630 2638
2631/* Defined in frame.c. */
2632extern Lisp_Object Qframep;
2633
2634/* Defined in data.c. */ 2639/* Defined in data.c. */
2635extern Lisp_Object indirect_function (Lisp_Object); 2640extern Lisp_Object indirect_function (Lisp_Object);
2636extern Lisp_Object find_symbol_value (Lisp_Object); 2641extern Lisp_Object find_symbol_value (Lisp_Object);
@@ -2716,15 +2721,15 @@ extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
2716extern void sweep_weak_hash_tables (void); 2721extern void sweep_weak_hash_tables (void);
2717extern Lisp_Object Qcursor_in_echo_area; 2722extern Lisp_Object Qcursor_in_echo_area;
2718extern Lisp_Object Qstring_lessp; 2723extern Lisp_Object Qstring_lessp;
2719extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql; 2724extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq;
2720EMACS_UINT hash_string (char const *, ptrdiff_t); 2725EMACS_UINT hash_string (char const *, ptrdiff_t);
2721EMACS_UINT sxhash (Lisp_Object, int); 2726EMACS_UINT sxhash (Lisp_Object, int);
2722Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, 2727Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object,
2723 Lisp_Object, Lisp_Object, Lisp_Object, 2728 Lisp_Object, Lisp_Object);
2724 Lisp_Object);
2725ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); 2729ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
2726ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, 2730ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
2727 EMACS_UINT); 2731 EMACS_UINT);
2732extern struct hash_table_test hashtest_eql, hashtest_equal;
2728 2733
2729extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, 2734extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,
2730 ptrdiff_t, ptrdiff_t); 2735 ptrdiff_t, ptrdiff_t);
@@ -2946,7 +2951,7 @@ extern void make_byte_code (struct Lisp_Vector *);
2946extern Lisp_Object Qautomatic_gc; 2951extern Lisp_Object Qautomatic_gc;
2947extern Lisp_Object Qchar_table_extra_slots; 2952extern Lisp_Object Qchar_table_extra_slots;
2948extern struct Lisp_Vector *allocate_vector (EMACS_INT); 2953extern struct Lisp_Vector *allocate_vector (EMACS_INT);
2949extern struct Lisp_Vector *allocate_pseudovector (int memlen, int lisplen, int tag); 2954extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type);
2950#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ 2955#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \
2951 ((typ*) \ 2956 ((typ*) \
2952 allocate_pseudovector \ 2957 allocate_pseudovector \
@@ -3298,7 +3303,6 @@ extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
3298#if HAVE_NS 3303#if HAVE_NS
3299extern Lisp_Object get_frame_param (struct frame *, Lisp_Object); 3304extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
3300#endif 3305#endif
3301extern Lisp_Object frame_buffer_predicate (Lisp_Object);
3302extern void frames_discard_buffer (Lisp_Object); 3306extern void frames_discard_buffer (Lisp_Object);
3303extern void syms_of_frame (void); 3307extern void syms_of_frame (void);
3304 3308
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 9df5dedb7ea..f5cab34d7dc 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -1475,8 +1475,8 @@ $(BLD)/unexw32.$(O) : \
1475 $(SRC)/w32.h \ 1475 $(SRC)/w32.h \
1476 $(SRC)/w32common.h \ 1476 $(SRC)/w32common.h \
1477 $(SRC)/w32heap.h \ 1477 $(SRC)/w32heap.h \
1478 $(LISP_H) \ 1478 $(CONFIG_H) \
1479 $(CONFIG_H) 1479 $(LISP_H)
1480 1480
1481$(BLD)/vm-limit.$(O) : \ 1481$(BLD)/vm-limit.$(O) : \
1482 $(SRC)/vm-limit.c \ 1482 $(SRC)/vm-limit.c \
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 e4621247854..7ba1608268b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -145,22 +145,22 @@ static unsigned convert_ns_to_X_keysym[] =
145 NSNewlineCharacter, 0x0D, 145 NSNewlineCharacter, 0x0D,
146 NSEnterCharacter, 0x8D, 146 NSEnterCharacter, 0x8D,
147 147
148 0x41, 0xAE, /* KP_Decimal */ 148 0x41|NSNumericPadKeyMask, 0xAE, /* KP_Decimal */
149 0x43, 0xAA, /* KP_Multiply */ 149 0x43|NSNumericPadKeyMask, 0xAA, /* KP_Multiply */
150 0x45, 0xAB, /* KP_Add */ 150 0x45|NSNumericPadKeyMask, 0xAB, /* KP_Add */
151 0x4B, 0xAF, /* KP_Divide */ 151 0x4B|NSNumericPadKeyMask, 0xAF, /* KP_Divide */
152 0x4E, 0xAD, /* KP_Subtract */ 152 0x4E|NSNumericPadKeyMask, 0xAD, /* KP_Subtract */
153 0x51, 0xBD, /* KP_Equal */ 153 0x51|NSNumericPadKeyMask, 0xBD, /* KP_Equal */
154 0x52, 0xB0, /* KP_0 */ 154 0x52|NSNumericPadKeyMask, 0xB0, /* KP_0 */
155 0x53, 0xB1, /* KP_1 */ 155 0x53|NSNumericPadKeyMask, 0xB1, /* KP_1 */
156 0x54, 0xB2, /* KP_2 */ 156 0x54|NSNumericPadKeyMask, 0xB2, /* KP_2 */
157 0x55, 0xB3, /* KP_3 */ 157 0x55|NSNumericPadKeyMask, 0xB3, /* KP_3 */
158 0x56, 0xB4, /* KP_4 */ 158 0x56|NSNumericPadKeyMask, 0xB4, /* KP_4 */
159 0x57, 0xB5, /* KP_5 */ 159 0x57|NSNumericPadKeyMask, 0xB5, /* KP_5 */
160 0x58, 0xB6, /* KP_6 */ 160 0x58|NSNumericPadKeyMask, 0xB6, /* KP_6 */
161 0x59, 0xB7, /* KP_7 */ 161 0x59|NSNumericPadKeyMask, 0xB7, /* KP_7 */
162 0x5B, 0xB8, /* KP_8 */ 162 0x5B|NSNumericPadKeyMask, 0xB8, /* KP_8 */
163 0x5C, 0xB9, /* KP_9 */ 163 0x5C|NSNumericPadKeyMask, 0xB9, /* KP_9 */
164 164
165 0x1B, 0x1B /* escape */ 165 0x1B, 0x1B /* escape */
166}; 166};
@@ -4829,7 +4829,7 @@ not_in_argv (NSString *arg)
4829 4829
4830 /* is it a "function key"? */ 4830 /* is it a "function key"? */
4831 fnKeysym = (code < 0x00ff && (flags&NSNumericPadKeyMask)) 4831 fnKeysym = (code < 0x00ff && (flags&NSNumericPadKeyMask))
4832 ? ns_convert_key ([theEvent keyCode]) 4832 ? ns_convert_key ([theEvent keyCode] | NSNumericPadKeyMask)
4833 : ns_convert_key (code); 4833 : ns_convert_key (code);
4834 4834
4835 if (fnKeysym) 4835 if (fnKeysym)
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/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/termhooks.h b/src/termhooks.h
index 2d97fcdbc1e..b35c927fc53 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -414,14 +414,6 @@ struct terminal
414 int memory_below_frame; /* Terminal remembers lines scrolled 414 int memory_below_frame; /* Terminal remembers lines scrolled
415 off bottom */ 415 off bottom */
416 416
417#if 0 /* These are not used anywhere. */
418 /* EMACS_INT baud_rate; */ /* Output speed in baud */
419 int min_padding_speed; /* Speed below which no padding necessary. */
420 int dont_calculate_costs; /* Nonzero means don't bother computing
421 various cost tables; we won't use them. */
422#endif
423
424
425 /* Window-based redisplay interface for this device (0 for tty 417 /* Window-based redisplay interface for this device (0 for tty
426 devices). */ 418 devices). */
427 struct redisplay_interface *rif; 419 struct redisplay_interface *rif;
@@ -469,10 +461,7 @@ struct terminal
469 Otherwise, set *bar_window to Qnil, and *x and *y to the column and 461 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
470 row of the character cell the mouse is over. 462 row of the character cell the mouse is over.
471 463
472 Set *time to the time the mouse was at the returned position. 464 Set *time to the time the mouse was at the returned position. */
473
474 This should clear mouse_moved until the next motion
475 event arrives. */
476 void (*mouse_position_hook) (struct frame **f, int, 465 void (*mouse_position_hook) (struct frame **f, int,
477 Lisp_Object *bar_window, 466 Lisp_Object *bar_window,
478 enum scroll_bar_part *part, 467 enum scroll_bar_part *part,
@@ -480,11 +469,6 @@ struct terminal
480 Lisp_Object *y, 469 Lisp_Object *y,
481 Time *); 470 Time *);
482 471
483 /* The window system handling code should set this if the mouse has
484 moved since the last call to the mouse_position_hook. Calling that
485 hook should clear this. */
486 int mouse_moved;
487
488 /* When a frame's focus redirection is changed, this hook tells the 472 /* When a frame's focus redirection is changed, this hook tells the
489 window system code to re-decide where to put the highlight. Under 473 window system code to re-decide where to put the highlight. Under
490 X, this means that Emacs lies about where the focus is. */ 474 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 18e29ecaaf5..ed5625e802c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -264,12 +264,8 @@ have_menus_p (void)
264FRAME_PTR 264FRAME_PTR
265check_x_frame (Lisp_Object frame) 265check_x_frame (Lisp_Object frame)
266{ 266{
267 FRAME_PTR f; 267 struct frame *f = decode_live_frame (frame);
268 268
269 if (NILP (frame))
270 frame = selected_frame;
271 CHECK_LIVE_FRAME (frame);
272 f = XFRAME (frame);
273 if (! FRAME_W32_P (f)) 269 if (! FRAME_W32_P (f))
274 error ("Non-W32 frame used"); 270 error ("Non-W32 frame used");
275 return f; 271 return f;
@@ -308,19 +304,14 @@ check_x_display_info (Lisp_Object frame)
308/* Return the Emacs frame-object corresponding to an w32 window. 304/* Return the Emacs frame-object corresponding to an w32 window.
309 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. */
310 306
311/* This function can be called during GC, so use GC_xxx type test macros. */
312
313struct frame * 307struct frame *
314x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc) 308x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
315{ 309{
316 Lisp_Object tail, frame; 310 Lisp_Object tail, frame;
317 struct frame *f; 311 struct frame *f;
318 312
319 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 313 FOR_EACH_FRAME (tail, frame)
320 { 314 {
321 frame = XCAR (tail);
322 if (!FRAMEP (frame))
323 continue;
324 f = XFRAME (frame); 315 f = XFRAME (frame);
325 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo) 316 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
326 continue; 317 continue;
@@ -2089,8 +2080,35 @@ sync_modifiers (void)
2089static int 2080static int
2090modifier_set (int vkey) 2081modifier_set (int vkey)
2091{ 2082{
2092 if (vkey == VK_CAPITAL || vkey == VK_SCROLL) 2083 /* Warning: The fact that VK_NUMLOCK is not treated as the other 2
2093 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
2094 if (!modifiers_recorded) 2112 if (!modifiers_recorded)
2095 return (GetKeyState (vkey) & 0x8000); 2113 return (GetKeyState (vkey) & 0x8000);
2096 2114
diff --git a/src/w32term.c b/src/w32term.c
index 4cc0b860947..032912c27f4 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3437,16 +3437,11 @@ w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
3437static struct scroll_bar * 3437static struct scroll_bar *
3438x_window_to_scroll_bar (Window window_id) 3438x_window_to_scroll_bar (Window window_id)
3439{ 3439{
3440 Lisp_Object tail; 3440 Lisp_Object tail, frame;
3441 3441
3442 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 3442 FOR_EACH_FRAME (tail, frame)
3443 { 3443 {
3444 Lisp_Object frame, bar, condemned; 3444 Lisp_Object bar, condemned;
3445
3446 frame = XCAR (tail);
3447 /* All elements of Vframe_list should be frames. */
3448 if (! FRAMEP (frame))
3449 emacs_abort ();
3450 3445
3451 /* Scan this frame's scroll bar list for a scroll bar with the 3446 /* Scan this frame's scroll bar list for a scroll bar with the
3452 right window ID. */ 3447 right window ID. */
@@ -3626,7 +3621,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
3626 HWND hwnd; 3621 HWND hwnd;
3627 SCROLLINFO si; 3622 SCROLLINFO si;
3628 struct scroll_bar *bar 3623 struct scroll_bar *bar
3629 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil)); 3624 = XSCROLL_BAR (Fmake_vector (make_number (VECSIZE (struct scroll_bar)), Qnil));
3630 Lisp_Object barobj; 3625 Lisp_Object barobj;
3631 3626
3632 block_input (); 3627 block_input ();
diff --git a/src/w32term.h b/src/w32term.h
index af5b37a1171..72fb8a76e35 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/window.c b/src/window.c
index 75a8d42d8d1..9f3474fcd53 100644
--- a/src/window.c
+++ b/src/window.c
@@ -273,7 +273,7 @@ decode_valid_window (register Lisp_Object window)
273/* Build a frequently used 4-integer (X Y W H) list. */ 273/* Build a frequently used 4-integer (X Y W H) list. */
274 274
275static Lisp_Object 275static Lisp_Object
276quad (ptrdiff_t x, ptrdiff_t y, ptrdiff_t w, ptrdiff_t h) 276list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h)
277{ 277{
278 return list4 (make_number (x), make_number (y), 278 return list4 (make_number (x), make_number (y),
279 make_number (w), make_number (h)); 279 make_number (w), make_number (h));
@@ -340,10 +340,7 @@ DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
340If FRAME is omitted or nil, it defaults to the selected frame. */) 340If FRAME is omitted or nil, it defaults to the selected frame. */)
341 (Lisp_Object frame) 341 (Lisp_Object frame)
342{ 342{
343 if (NILP (frame)) 343 return FRAME_MINIBUF_WINDOW (decode_live_frame (frame));
344 frame = selected_frame;
345 CHECK_LIVE_FRAME (frame);
346 return FRAME_MINIBUF_WINDOW (XFRAME (frame));
347} 344}
348 345
349DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, 346DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p,
@@ -605,24 +602,29 @@ Return nil if WINDOW has no previous sibling. */)
605 return decode_valid_window (window)->prev; 602 return decode_valid_window (window)->prev;
606} 603}
607 604
608DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 0, 1, 0, 605DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
609 doc: /* Return combination limit of window WINDOW. 606 doc: /* Return combination limit of window WINDOW.
610WINDOW must be a valid window and defaults to the selected one.
611If 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
612WINDOW'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
613WINDOW 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. */)
614 (Lisp_Object window) 613 (Lisp_Object window)
615{ 614{
616 return decode_valid_window (window)->combination_limit; 615 CHECK_VALID_WINDOW (window);
616 return XWINDOW (window)->combination_limit;
617} 617}
618 618
619DEFUN ("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,
620 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT. 620 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
621WINDOW must be a valid window and defaults to the selected one.
622If 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
623siblings. LIMIT t means that child windows of WINDOW are never 622siblings. LIMIT t means that child windows of WINDOW are never
624\(re-)combined with WINDOW's siblings. Other values are reserved for 623\(re-)combined with WINDOW's siblings. Other values are reserved for
625future use. */) 624future use.
625
626WINDOW must be a valid window. Setting the combination limit is
627meaningful for internal windows only. */)
626 (Lisp_Object window, Lisp_Object limit) 628 (Lisp_Object window, Lisp_Object limit)
627{ 629{
628 wset_combination_limit (decode_valid_window (window), limit); 630 wset_combination_limit (decode_valid_window (window), limit);
@@ -882,8 +884,8 @@ header line, and/or mode line. For the edges of just the text area, use
882{ 884{
883 register struct window *w = decode_valid_window (window); 885 register struct window *w = decode_valid_window (window);
884 886
885 return quad (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w), 887 return list4i (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w),
886 WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w)); 888 WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w));
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,8 +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 quad (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w), 907 return list4i (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w),
906 WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w)); 908 WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w));
907} 909}
908 910
909static void 911static void
@@ -948,10 +950,10 @@ of just the text area, use `window-inside-absolute-pixel-edges'. */)
948 950
949 calc_absolute_offset (w, &add_x, &add_y); 951 calc_absolute_offset (w, &add_x, &add_y);
950 952
951 return quad (WINDOW_LEFT_EDGE_X (w) + add_x, 953 return list4i (WINDOW_LEFT_EDGE_X (w) + add_x,
952 WINDOW_TOP_EDGE_Y (w) + add_y, 954 WINDOW_TOP_EDGE_Y (w) + add_y,
953 WINDOW_RIGHT_EDGE_X (w) + add_x, 955 WINDOW_RIGHT_EDGE_X (w) + add_x,
954 WINDOW_BOTTOM_EDGE_Y (w) + add_y); 956 WINDOW_BOTTOM_EDGE_Y (w) + add_y);
955} 957}
956 958
957DEFUN ("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,
@@ -970,16 +972,16 @@ display margins, fringes, header line, and/or mode line. */)
970{ 972{
971 register struct window *w = decode_live_window (window); 973 register struct window *w = decode_live_window (window);
972 974
973 return quad (WINDOW_BOX_LEFT_EDGE_COL (w) 975 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
974 + WINDOW_LEFT_MARGIN_COLS (w) 976 + WINDOW_LEFT_MARGIN_COLS (w)
975 + WINDOW_LEFT_FRINGE_COLS (w), 977 + WINDOW_LEFT_FRINGE_COLS (w)),
976 WINDOW_TOP_EDGE_LINE (w) 978 (WINDOW_TOP_EDGE_LINE (w)
977 + WINDOW_HEADER_LINE_LINES (w), 979 + WINDOW_HEADER_LINE_LINES (w)),
978 WINDOW_BOX_RIGHT_EDGE_COL (w) 980 (WINDOW_BOX_RIGHT_EDGE_COL (w)
979 - WINDOW_RIGHT_MARGIN_COLS (w) 981 - WINDOW_RIGHT_MARGIN_COLS (w)
980 - WINDOW_RIGHT_FRINGE_COLS (w), 982 - WINDOW_RIGHT_FRINGE_COLS (w)),
981 WINDOW_BOTTOM_EDGE_LINE (w) 983 (WINDOW_BOTTOM_EDGE_LINE (w)
982 - WINDOW_MODE_LINE_LINES (w)); 984 - WINDOW_MODE_LINE_LINES (w)));
983} 985}
984 986
985DEFUN ("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,
@@ -997,16 +999,16 @@ display margins, fringes, header line, and/or mode line. */)
997{ 999{
998 register struct window *w = decode_live_window (window); 1000 register struct window *w = decode_live_window (window);
999 1001
1000 return quad (WINDOW_BOX_LEFT_EDGE_X (w) 1002 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
1001 + WINDOW_LEFT_MARGIN_WIDTH (w) 1003 + WINDOW_LEFT_MARGIN_WIDTH (w)
1002 + WINDOW_LEFT_FRINGE_WIDTH (w), 1004 + WINDOW_LEFT_FRINGE_WIDTH (w)),
1003 WINDOW_TOP_EDGE_Y (w) 1005 (WINDOW_TOP_EDGE_Y (w)
1004 + WINDOW_HEADER_LINE_HEIGHT (w), 1006 + WINDOW_HEADER_LINE_HEIGHT (w)),
1005 WINDOW_BOX_RIGHT_EDGE_X (w) 1007 (WINDOW_BOX_RIGHT_EDGE_X (w)
1006 - WINDOW_RIGHT_MARGIN_WIDTH (w) 1008 - WINDOW_RIGHT_MARGIN_WIDTH (w)
1007 - WINDOW_RIGHT_FRINGE_WIDTH (w), 1009 - WINDOW_RIGHT_FRINGE_WIDTH (w)),
1008 WINDOW_BOTTOM_EDGE_Y (w) 1010 (WINDOW_BOTTOM_EDGE_Y (w)
1009 - WINDOW_MODE_LINE_HEIGHT (w)); 1011 - WINDOW_MODE_LINE_HEIGHT (w)));
1010} 1012}
1011 1013
1012DEFUN ("window-inside-absolute-pixel-edges", 1014DEFUN ("window-inside-absolute-pixel-edges",
@@ -1029,16 +1031,16 @@ display margins, fringes, header line, and/or mode line. */)
1029 1031
1030 calc_absolute_offset (w, &add_x, &add_y); 1032 calc_absolute_offset (w, &add_x, &add_y);
1031 1033
1032 return quad (WINDOW_BOX_LEFT_EDGE_X (w) 1034 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
1033 + WINDOW_LEFT_MARGIN_WIDTH (w) 1035 + WINDOW_LEFT_MARGIN_WIDTH (w)
1034 + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x, 1036 + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
1035 WINDOW_TOP_EDGE_Y (w) 1037 (WINDOW_TOP_EDGE_Y (w)
1036 + WINDOW_HEADER_LINE_HEIGHT (w) + add_y, 1038 + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
1037 WINDOW_BOX_RIGHT_EDGE_X (w) 1039 (WINDOW_BOX_RIGHT_EDGE_X (w)
1038 - WINDOW_RIGHT_MARGIN_WIDTH (w) 1040 - WINDOW_RIGHT_MARGIN_WIDTH (w)
1039 - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x, 1041 - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
1040 WINDOW_BOTTOM_EDGE_Y (w) 1042 (WINDOW_BOTTOM_EDGE_Y (w)
1041 - WINDOW_MODE_LINE_HEIGHT (w) + add_y); 1043 - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
1042} 1044}
1043 1045
1044/* 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.
@@ -1371,12 +1373,7 @@ The top left corner of the frame is considered to be row 0,
1371column 0. */) 1373column 0. */)
1372 (Lisp_Object x, Lisp_Object y, Lisp_Object frame) 1374 (Lisp_Object x, Lisp_Object y, Lisp_Object frame)
1373{ 1375{
1374 struct frame *f; 1376 struct frame *f = decode_live_frame (frame);
1375
1376 if (NILP (frame))
1377 frame = selected_frame;
1378 CHECK_LIVE_FRAME (frame);
1379 f = XFRAME (frame);
1380 1377
1381 /* Check that arguments are integers or floats. */ 1378 /* Check that arguments are integers or floats. */
1382 CHECK_NUMBER_OR_FLOAT (x); 1379 CHECK_NUMBER_OR_FLOAT (x);
@@ -1624,7 +1621,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
1624 { 1621 {
1625 Lisp_Object part = Qnil; 1622 Lisp_Object part = Qnil;
1626 if (!fully_p) 1623 if (!fully_p)
1627 part = quad (rtop, rbot, rowh, vpos); 1624 part = list4i (rtop, rbot, rowh, vpos);
1628 in_window = Fcons (make_number (x), 1625 in_window = Fcons (make_number (x),
1629 Fcons (make_number (y), part)); 1626 Fcons (make_number (y), part));
1630 } 1627 }
@@ -1690,17 +1687,18 @@ Return nil if window display is not up-to-date. In that case, use
1690 if (!WINDOW_WANTS_HEADER_LINE_P (w)) 1687 if (!WINDOW_WANTS_HEADER_LINE_P (w))
1691 return Qnil; 1688 return Qnil;
1692 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); 1689 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
1693 return row->enabled_p ? quad (row->height, 0, 0, 0) : Qnil; 1690 return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
1694 } 1691 }
1695 1692
1696 if (EQ (line, Qmode_line)) 1693 if (EQ (line, Qmode_line))
1697 { 1694 {
1698 row = MATRIX_MODE_LINE_ROW (w->current_matrix); 1695 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
1699 return (row->enabled_p ? 1696 return (row->enabled_p ?
1700 quad (row->height, 1697 list4i (row->height,
1701 0, /* not accurate */ 1698 0, /* not accurate */
1702 WINDOW_HEADER_LINE_HEIGHT (w) 1699 (WINDOW_HEADER_LINE_HEIGHT (w)
1703 + window_text_bottom_y (w), 0) 1700 + window_text_bottom_y (w)),
1701 0)
1704 : Qnil); 1702 : Qnil);
1705 } 1703 }
1706 1704
@@ -1730,7 +1728,7 @@ Return nil if window display is not up-to-date. In that case, use
1730 1728
1731 found_row: 1729 found_row:
1732 crop = max (0, (row->y + row->height) - max_y); 1730 crop = max (0, (row->y + row->height) - max_y);
1733 return quad (row->height + min (0, row->y) - crop, i, row->y, crop); 1731 return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
1734} 1732}
1735 1733
1736DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p, 1734DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
@@ -2135,10 +2133,10 @@ window_list (void)
2135{ 2133{
2136 if (!CONSP (Vwindow_list)) 2134 if (!CONSP (Vwindow_list))
2137 { 2135 {
2138 Lisp_Object tail; 2136 Lisp_Object tail, frame;
2139 2137
2140 Vwindow_list = Qnil; 2138 Vwindow_list = Qnil;
2141 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 2139 FOR_EACH_FRAME (tail, frame)
2142 { 2140 {
2143 Lisp_Object args[2]; 2141 Lisp_Object args[2];
2144 2142
@@ -2146,7 +2144,7 @@ window_list (void)
2146 new windows at the front of args[1], which means we 2144 new windows at the front of args[1], which means we
2147 have to reverse this list at the end. */ 2145 have to reverse this list at the end. */
2148 args[1] = Qnil; 2146 args[1] = Qnil;
2149 foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1]); 2147 foreach_window (XFRAME (frame), add_window_to_list, &args[1]);
2150 args[0] = Vwindow_list; 2148 args[0] = Vwindow_list;
2151 args[1] = Fnreverse (args[1]); 2149 args[1] = Fnreverse (args[1]);
2152 Vwindow_list = Fnconc (2, args); 2150 Vwindow_list = Fnconc (2, args);
@@ -3109,12 +3107,12 @@ run_window_configuration_change_hook (struct frame *f)
3109} 3107}
3110 3108
3111DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook, 3109DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
3112 Srun_window_configuration_change_hook, 1, 1, 0, 3110 Srun_window_configuration_change_hook, 0, 1, 0,
3113 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. */)
3114 (Lisp_Object frame) 3113 (Lisp_Object frame)
3115{ 3114{
3116 CHECK_LIVE_FRAME (frame); 3115 run_window_configuration_change_hook (decode_live_frame (frame));
3117 run_window_configuration_change_hook (XFRAME (frame));
3118 return Qnil; 3116 return Qnil;
3119} 3117}
3120 3118
@@ -3641,10 +3639,12 @@ window_resize_apply (struct window *w, int horflag)
3641} 3639}
3642 3640
3643 3641
3644DEFUN ("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,
3645 doc: /* Apply requested size values for window-tree of FRAME. 3643 doc: /* Apply requested size values for window-tree of FRAME.
3646Optional argument HORIZONTAL omitted or nil means apply requested height 3644If FRAME is omitted or nil, it defaults to the selected frame.
3647values. 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.
3648 3648
3649This function checks whether the requested values sum up to a valid 3649This function checks whether the requested values sum up to a valid
3650window layout, recursively assigns the new sizes of all child windows 3650window layout, recursively assigns the new sizes of all child windows
@@ -3655,17 +3655,10 @@ Note: This function does not check any of `window-fixed-size-p',
3655be applied on the Elisp level. */) 3655be applied on the Elisp level. */)
3656 (Lisp_Object frame, Lisp_Object horizontal) 3656 (Lisp_Object frame, Lisp_Object horizontal)
3657{ 3657{
3658 struct frame *f; 3658 struct frame *f = decode_live_frame (frame);
3659 struct window *r; 3659 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
3660 int horflag = !NILP (horizontal); 3660 int horflag = !NILP (horizontal);
3661 3661
3662 if (NILP (frame))
3663 frame = selected_frame;
3664 CHECK_LIVE_FRAME (frame);
3665
3666 f = XFRAME (frame);
3667 r = XWINDOW (FRAME_ROOT_WINDOW (f));
3668
3669 if (!window_resize_check (r, horflag) 3662 if (!window_resize_check (r, horflag)
3670 || ! EQ (r->new_total, 3663 || ! EQ (r->new_total,
3671 (horflag ? r->total_cols : r->total_lines))) 3664 (horflag ? r->total_cols : r->total_lines)))
@@ -3879,9 +3872,10 @@ set correctly. See the code of `split-window' for how this is done. */)
3879 3872
3880 make_parent_window (old, horflag); 3873 make_parent_window (old, horflag);
3881 p = XWINDOW (o->parent); 3874 p = XWINDOW (o->parent);
3882 /* Store t in the new parent's combination_limit slot to avoid 3875 if (EQ (Vwindow_combination_limit, Qt))
3883 that its children get merged into another window. */ 3876 /* Store t in the new parent's combination_limit slot to avoid
3884 wset_combination_limit (p, Qt); 3877 that its children get merged into another window. */
3878 wset_combination_limit (p, Qt);
3885 /* These get applied below. */ 3879 /* These get applied below. */
3886 wset_new_total (p, horflag ? o->total_cols : o->total_lines); 3880 wset_new_total (p, horflag ? o->total_cols : o->total_lines);
3887 wset_new_normal (p, new_normal); 3881 wset_new_normal (p, new_normal);
@@ -6148,12 +6142,7 @@ saved by this function. */)
6148 register int n_windows; 6142 register int n_windows;
6149 register struct save_window_data *data; 6143 register struct save_window_data *data;
6150 register int i; 6144 register int i;
6151 FRAME_PTR f; 6145 struct frame *f = decode_live_frame (frame);
6152
6153 if (NILP (frame))
6154 frame = selected_frame;
6155 CHECK_LIVE_FRAME (frame);
6156 f = XFRAME (frame);
6157 6146
6158 n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); 6147 n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
6159 data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols, 6148 data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols,
diff --git a/src/xdisp.c b/src/xdisp.c
index 1ff7819f34d..a74628db392 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10769,7 +10769,7 @@ clear_garbaged_frames (void)
10769 { 10769 {
10770 if (f->resized_p) 10770 if (f->resized_p)
10771 { 10771 {
10772 Fredraw_frame (frame); 10772 redraw_frame (f);
10773 f->force_flush_display_p = 1; 10773 f->force_flush_display_p = 1;
10774 } 10774 }
10775 clear_current_matrices (f); 10775 clear_current_matrices (f);
@@ -11096,17 +11096,15 @@ x_consider_frame_title (Lisp_Object frame)
11096 || f->explicit_name) 11096 || f->explicit_name)
11097 { 11097 {
11098 /* 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? */
11099 Lisp_Object tail; 11099 Lisp_Object tail, other_frame, fmt;
11100 Lisp_Object fmt;
11101 ptrdiff_t title_start; 11100 ptrdiff_t title_start;
11102 char *title; 11101 char *title;
11103 ptrdiff_t len; 11102 ptrdiff_t len;
11104 struct it it; 11103 struct it it;
11105 ptrdiff_t count = SPECPDL_INDEX (); 11104 ptrdiff_t count = SPECPDL_INDEX ();
11106 11105
11107 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 11106 FOR_EACH_FRAME (tail, other_frame)
11108 { 11107 {
11109 Lisp_Object other_frame = XCAR (tail);
11110 struct frame *tf = XFRAME (other_frame); 11108 struct frame *tf = XFRAME (other_frame);
11111 11109
11112 if (tf != f 11110 if (tf != f
@@ -11916,19 +11914,14 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
11916 11914
11917DEFUN ("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,
11918 0, 1, 0, 11916 0, 1, 0,
11919 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. */)
11920 (Lisp_Object frame) 11919 (Lisp_Object frame)
11921{ 11920{
11922 struct frame *f; 11921 struct frame *f = decode_any_frame (frame);
11923 struct window *w; 11922 struct window *w;
11924 int nlines = 0; 11923 int nlines = 0;
11925 11924
11926 if (NILP (frame))
11927 frame = selected_frame;
11928 else
11929 CHECK_FRAME (frame);
11930 f = XFRAME (frame);
11931
11932 if (WINDOWP (f->tool_bar_window) 11925 if (WINDOWP (f->tool_bar_window)
11933 && (w = XWINDOW (f->tool_bar_window), 11926 && (w = XWINDOW (f->tool_bar_window),
11934 WINDOW_TOTAL_LINES (w) > 0)) 11927 WINDOW_TOTAL_LINES (w) > 0))
@@ -14791,13 +14784,18 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14791 if (NUMBERP (aggressive)) 14784 if (NUMBERP (aggressive))
14792 { 14785 {
14793 double float_amount = XFLOATINT (aggressive) * height; 14786 double float_amount = XFLOATINT (aggressive) * height;
14794 amount_to_scroll = float_amount; 14787 int aggressive_scroll = float_amount;
14795 if (amount_to_scroll == 0 && float_amount > 0) 14788 if (aggressive_scroll == 0 && float_amount > 0)
14796 amount_to_scroll = 1; 14789 aggressive_scroll = 1;
14797 /* Don't let point enter the scroll margin near top of 14790 /* Don't let point enter the scroll margin near top of
14798 the window. */ 14791 the window. This could happen if the value of
14799 if (amount_to_scroll > height - 2*this_scroll_margin + dy) 14792 scroll_up_aggressively is too large and there are
14800 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;
14801 } 14799 }
14802 } 14800 }
14803 14801
@@ -14857,7 +14855,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14857 /* Compute the vertical distance from PT to the scroll 14855 /* Compute the vertical distance from PT to the scroll
14858 margin position. Move as far as scroll_max allows, or 14856 margin position. Move as far as scroll_max allows, or
14859 one screenful, or 10 screen lines, whichever is largest. 14857 one screenful, or 10 screen lines, whichever is largest.
14860 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. */
14861 SET_TEXT_POS (pos, PT, PT_BYTE); 14860 SET_TEXT_POS (pos, PT, PT_BYTE);
14862 start_display (&it, w, pos); 14861 start_display (&it, w, pos);
14863 y0 = it.current_y; 14862 y0 = it.current_y;
@@ -14867,7 +14866,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14867 y_to_move, -1, 14866 y_to_move, -1,
14868 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 14867 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14869 dy = it.current_y - y0; 14868 dy = it.current_y - y0;
14870 if (dy > scroll_max) 14869 if (dy > scroll_max
14870 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14871 return SCROLLING_FAILED; 14871 return SCROLLING_FAILED;
14872 14872
14873 /* Compute new window start. */ 14873 /* Compute new window start. */
@@ -14885,15 +14885,16 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14885 if (NUMBERP (aggressive)) 14885 if (NUMBERP (aggressive))
14886 { 14886 {
14887 double float_amount = XFLOATINT (aggressive) * height; 14887 double float_amount = XFLOATINT (aggressive) * height;
14888 amount_to_scroll = float_amount; 14888 int aggressive_scroll = float_amount;
14889 if (amount_to_scroll == 0 && float_amount > 0) 14889 if (aggressive_scroll == 0 && float_amount > 0)
14890 amount_to_scroll = 1; 14890 aggressive_scroll = 1;
14891 amount_to_scroll -=
14892 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14893 /* Don't let point enter the scroll margin near 14891 /* Don't let point enter the scroll margin near
14894 bottom of the window. */ 14892 bottom of the window, if the value of
14895 if (amount_to_scroll > height - 2*this_scroll_margin + dy) 14893 scroll_down_aggressively happens to be too
14896 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;
14897 } 14898 }
14898 } 14899 }
14899 14900
@@ -21370,6 +21371,12 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21370 Lisp_Object obj; 21371 Lisp_Object obj;
21371 struct frame *f = XFRAME (WINDOW_FRAME (w)); 21372 struct frame *f = XFRAME (WINDOW_FRAME (w));
21372 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));
21373 struct buffer *b = current_buffer; 21380 struct buffer *b = current_buffer;
21374 21381
21375 obj = Qnil; 21382 obj = Qnil;
@@ -21465,7 +21472,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21465 { 21472 {
21466 ptrdiff_t col = current_column (); 21473 ptrdiff_t col = current_column ();
21467 wset_column_number_displayed (w, make_number (col)); 21474 wset_column_number_displayed (w, make_number (col));
21468 pint2str (decode_mode_spec_buf, field_width, col); 21475 pint2str (decode_mode_spec_buf, width, col);
21469 return decode_mode_spec_buf; 21476 return decode_mode_spec_buf;
21470 } 21477 }
21471 21478
@@ -21496,14 +21503,14 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21496 case 'i': 21503 case 'i':
21497 { 21504 {
21498 ptrdiff_t size = ZV - BEGV; 21505 ptrdiff_t size = ZV - BEGV;
21499 pint2str (decode_mode_spec_buf, field_width, size); 21506 pint2str (decode_mode_spec_buf, width, size);
21500 return decode_mode_spec_buf; 21507 return decode_mode_spec_buf;
21501 } 21508 }
21502 21509
21503 case 'I': 21510 case 'I':
21504 { 21511 {
21505 ptrdiff_t size = ZV - BEGV; 21512 ptrdiff_t size = ZV - BEGV;
21506 pint2hrstr (decode_mode_spec_buf, field_width, size); 21513 pint2hrstr (decode_mode_spec_buf, width, size);
21507 return decode_mode_spec_buf; 21514 return decode_mode_spec_buf;
21508 } 21515 }
21509 21516
@@ -21610,12 +21617,12 @@ decode_mode_spec (struct window *w, register int c, int field_width,
21610 line_number_displayed = 1; 21617 line_number_displayed = 1;
21611 21618
21612 /* Make the string to show. */ 21619 /* Make the string to show. */
21613 pint2str (decode_mode_spec_buf, field_width, topline + nlines); 21620 pint2str (decode_mode_spec_buf, width, topline + nlines);
21614 return decode_mode_spec_buf; 21621 return decode_mode_spec_buf;
21615 no_value: 21622 no_value:
21616 { 21623 {
21617 char* p = decode_mode_spec_buf; 21624 char* p = decode_mode_spec_buf;
21618 int pad = field_width - 2; 21625 int pad = width - 2;
21619 while (pad-- > 0) 21626 while (pad-- > 0)
21620 *p++ = ' '; 21627 *p++ = ' ';
21621 *p++ = '?'; 21628 *p++ = '?';
@@ -29417,8 +29424,10 @@ start_hourglass (void)
29417 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0); 29424 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29418 29425
29419#ifdef HAVE_NTGUI 29426#ifdef HAVE_NTGUI
29420 extern void w32_note_current_window (void); 29427 {
29421 w32_note_current_window (); 29428 extern void w32_note_current_window (void);
29429 w32_note_current_window ();
29430 }
29422#endif /* HAVE_NTGUI */ 29431#endif /* HAVE_NTGUI */
29423 29432
29424 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 aca227385bf..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}
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 4dd1dee0f75..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
@@ -10868,10 +10859,10 @@ default is nil, which is the same as `super'. */);
10868 10859
10869 DEFVAR_LISP ("x-keysym-table", Vx_keysym_table, 10860 DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
10870 doc: /* Hash table of character codes indexed by X keysym codes. */); 10861 doc: /* Hash table of character codes indexed by X keysym codes. */);
10871 Vx_keysym_table = make_hash_table (Qeql, make_number (900), 10862 Vx_keysym_table = make_hash_table (hashtest_eql, make_number (900),
10872 make_float (DEFAULT_REHASH_SIZE), 10863 make_float (DEFAULT_REHASH_SIZE),
10873 make_float (DEFAULT_REHASH_THRESHOLD), 10864 make_float (DEFAULT_REHASH_THRESHOLD),
10874 Qnil, Qnil, Qnil); 10865 Qnil);
10875} 10866}
10876 10867
10877#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;