aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog1787
-rw-r--r--src/ChangeLog.102
-rw-r--r--src/ChangeLog.112
-rw-r--r--src/ChangeLog.81266
-rw-r--r--src/Makefile.in65
-rw-r--r--src/alloc.c107
-rw-r--r--src/buffer.c141
-rw-r--r--src/buffer.h22
-rw-r--r--src/bytecode.c5
-rw-r--r--src/callint.c34
-rw-r--r--src/callproc.c87
-rw-r--r--src/category.c2
-rw-r--r--src/character.h2
-rw-r--r--src/charset.c96
-rw-r--r--src/chartab.c13
-rw-r--r--src/coding.c84
-rw-r--r--src/composite.c27
-rw-r--r--src/conf_post.h28
-rw-r--r--src/data.c47
-rw-r--r--src/dbusbind.c13
-rw-r--r--src/decompress.c10
-rw-r--r--src/dispextern.h6
-rw-r--r--src/dispnew.c57
-rw-r--r--src/doc.c30
-rw-r--r--src/editfns.c420
-rw-r--r--src/emacs.c109
-rw-r--r--src/eval.c202
-rw-r--r--src/fileio.c183
-rw-r--r--src/fns.c268
-rw-r--r--src/font.c159
-rw-r--r--src/font.h6
-rw-r--r--src/fontset.c26
-rw-r--r--src/frame.c137
-rw-r--r--src/frame.h18
-rw-r--r--src/ftfont.c171
-rw-r--r--src/ftxfont.c4
-rw-r--r--src/gmalloc.c237
-rw-r--r--src/gtkutil.c44
-rw-r--r--src/image.c41
-rw-r--r--src/indent.c31
-rw-r--r--src/keyboard.c278
-rw-r--r--src/keymap.c48
-rw-r--r--src/lastfile.c2
-rw-r--r--src/lisp.h501
-rw-r--r--src/lisp.mk2
-rw-r--r--src/lread.c157
-rw-r--r--src/macfont.h13
-rw-r--r--src/macfont.m3270
-rw-r--r--src/marker.c17
-rw-r--r--src/menu.c49
-rw-r--r--src/minibuf.c19
-rw-r--r--src/msdos.c2
-rw-r--r--src/nsfns.m40
-rw-r--r--src/nsfont.m19
-rw-r--r--src/nsimage.m2
-rw-r--r--src/nsmenu.m19
-rw-r--r--src/nsselect.m43
-rw-r--r--src/nsterm.h30
-rw-r--r--src/nsterm.m129
-rw-r--r--src/print.c35
-rw-r--r--src/process.c126
-rw-r--r--src/ralloc.c12
-rw-r--r--src/regex.c60
-rw-r--r--src/regex.h3
-rw-r--r--src/scroll.c28
-rw-r--r--src/search.c73
-rw-r--r--src/sheap.c2
-rw-r--r--src/sound.c176
-rw-r--r--src/syntax.c19
-rw-r--r--src/sysdep.c304
-rw-r--r--src/systime.h16
-rw-r--r--src/term.c110
-rw-r--r--src/termhooks.h32
-rw-r--r--src/terminal.c95
-rw-r--r--src/textprop.c25
-rw-r--r--src/unexcw.c9
-rw-r--r--src/unexhp9k800.c1
-rw-r--r--src/unexmacosx.c116
-rw-r--r--src/unexw32.c8
-rw-r--r--src/vm-limit.c16
-rw-r--r--src/w32.c129
-rw-r--r--src/w32.h7
-rw-r--r--src/w32fns.c77
-rw-r--r--src/w32font.c175
-rw-r--r--src/w32font.h4
-rw-r--r--src/w32inevt.c4
-rw-r--r--src/w32inevt.h2
-rw-r--r--src/w32proc.c214
-rw-r--r--src/w32term.c86
-rw-r--r--src/w32term.h16
-rw-r--r--src/w32uniscribe.c12
-rw-r--r--src/widget.c9
-rw-r--r--src/window.c464
-rw-r--r--src/window.h10
-rw-r--r--src/xdisp.c280
-rw-r--r--src/xfaces.c59
-rw-r--r--src/xfns.c70
-rw-r--r--src/xfont.c52
-rw-r--r--src/xftfont.c20
-rw-r--r--src/xmenu.c33
-rw-r--r--src/xselect.c60
-rw-r--r--src/xsmfns.c8
-rw-r--r--src/xterm.c339
-rw-r--r--src/xterm.h18
104 files changed, 8269 insertions, 5774 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 5d2e75577b9..c1b7c6cc8c3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,1648 @@
12014-10-14 Dmitry Antipov <dmantipov@yandex.ru>
2
3 Cleanup terminal handling code.
4 * dispextern.h (get_named_tty): Remove prototype but...
5 * termhooks.h (get_named_terminal): ...resurrect it under
6 more meaningful name.
7 (get_terminal): Likewise, but with...
8 (decode_live_terminal): ...this name.
9 (decode_tty_terminal): Add prototype.
10 * term.c (get_tty_terminal): Remove.
11 (get_named_tty): Remove.
12 (Ftty_display_color_p, Ftty_display_color_cells, Ftty_type)
13 (Fcontrolling_tty_p, Fsuspend_tty, Fresume_tty):
14 Use decode_tty_terminal.
15 (Ftty_no_underline, Ftty_top_frame): Use decode_live_terminal.
16 * terminal.c (get_terminal): Refactor to...
17 (decode_terminal, decode_live_terminal): ...new functions.
18 (decode_tty_terminal): Replacement for get_tty_terminal.
19 (get_named_terminal): Likewise for get_named_tty.
20 * coding.c (Fset_terminal_coding_system_internal)
21 (Fterminal_coding_system, Fset_keyboard_coding_system_internal):
22 (Fkeyboard_coding_system):
23 * composite.c (Fcomposition_get_gstring):
24 * dispnew.c (Fsend_string_to_terminal):
25 * frame.c (Fmake_terminal_frame):
26 * nsfns.m (check_ns_display_info):
27 * w32fns.c, xfns.c (check_x_display_info):
28 * xselect.c (frame_for_x_selection): Use decode_live_terminal.
29 * keyboard.c (handle_interrupt_signal, handle_interrupt)
30 (Fset_quit_char): Use get_named_terminal.
31 (Fset_output_flow_control, Fset_input_meta_mode):
32 Use decode_tty_terminal.
33
342014-10-13 Eli Zaretskii <eliz@gnu.org>
35
36 * w32term.h (ALIGN_STACK): Use _WIN64, not _W64, to distinguish
37 between 32-bit and 64-bit MinGW builds. (Bug#18699)
38
392014-10-12 Paul Eggert <eggert@cs.ucla.edu>
40
41 Fix port to Debian GNU/kFreeBSD 7 (wheezy) (Bug#18666).
42 * process.c (accept4) [!HAVE_ACCEPT4]: New macro.
43
442014-10-12 Stefan Monnier <monnier@iro.umontreal.ca>
45
46 * frame.c (Fmouse_pixel_position): Call Vmouse_position_function
47 (bug#18638).
48
492014-10-12 Paul Eggert <eggert@cs.ucla.edu>
50
51 * editfns.c (dump_tz_string): No longer const.
52 It might be modified.
53
54 * nsmenu.m (clear): Assume OS X 10.6 or later.
55
562014-10-12 Jan Djärv <jan.h.d@swipnet.se>
57
58 * unexmacosx.c: Remove include ppc/reloc.h.
59 (unrelocate, copy_dysymtab): Remove PPC code.
60 (rebase_reloc_address): Remove, only used for PPC:
61
62 * nsterm.m: Always include macfont.h on COCOA.
63 (ns_update_auto_hide_menu_bar, ns_draw_fringe_bitmap)
64 (ns_dumpglyphs_image, ns_check_menu_open)
65 (applicationDidFinishLaunching)
66 (antialiasThresholdDidChange:)
67 (keyDown:, toggleFullScreen:, setPosition:portion:whole:): Remove
68 checks for OSX <= 10.5/10.6.
69 (changeFont:): Use macfont on COCOA, nsfont on GNUSTEP.
70 (syms_of_nsterm): Call syms_of_macfont on COCOA, syms_of_nsfont on
71 GNUSTEP.
72
73 * nsterm.h (MAC_OS_X_VERSION_10_4, MAC_OS_X_VERSION_10_5): Remove.
74 (NS_HAVE_NSINTEGER): Remove block.
75 Remove >= OSX 10.6 tests.
76
77 * nsmenu.m (NSMenuDidBeginTrackingNotification): Remove.
78 (x_activate_menubar, trackingNotification:): Remove check for
79 OSX >= 10.5.
80 (menuNeedsUpdate:): Remove check for OSX < 10.5.
81
82 * nsimage.m (allocInitFromFile:): Remove code for OSX < 10.6.
83
84 * nsfns.m: Always include macfont.h on COCOA.
85 (ns_filename_from_panel, ns_directory_from_panel)
86 (Fx_create_frame, Fns_popup_font_panel, ns_run_file_dialog)
87 (Fns_read_file_name, Fns_list_services): Remove code for OSX < 10.6
88
89 * macfont.m: Remove >= 1050 check.
90 (macfont_create_family_with_symbol)
91 (macfont_get_glyph_for_character)
92 (mac_font_get_glyphs_for_variants)
93 (mac_ctfont_create_available_families, syms_of_macfont): Remove
94 code for OSX < 10.6.
95 (mac_font_family_group, mac_font_family_compare): Remove, only used
96 for OSX < 10.6.
97
98 * macfont.h (MAC_FONT_FORMAT_ATTRIBUTE, MAC_FONT_FORMAT_BITMAP)
99 (mac_font_copy_non_synthetic_table): Remove versions for OSX < 10.6
100
101 * Makefile.in: Replace nsfont.o macfont.o with ns_fontfile in
102 comment.
103
1042014-10-12 Paul Eggert <eggert@cs.ucla.edu>
105
106 Fix putenv race conditions with undefined behavior (Bug#8705).
107 Do all putenv calls before Emacs creates any threads.
108 Use a safer way to modify the TZ environment variable in the
109 presence of multiple threads. For further thread-safety,
110 prefer localtime_r and gmtime_r to localtime and gmtime,
111 and prefer struct tm's tm_gmtoff (if available) to calling
112 both localtime_r and gmtime_r.
113 * dbusbind.c (Fdbus__init_bus): Move xputenv call from here ...
114 (init_dbusbind): ... to this new function.
115 * emacs.c (main) [HAVE_DBUS]: Call it before creating threads.
116 * xterm.c (x_term_init): Move xputenv call from here ...
117 (init_xterm): ... to this new function.
118 * emacs.c (main) [USE_GTK]: Call it before creating threads.
119 * editfns.c (HAVE_TM_GMTOFF): Default to false.
120 (dump_tz_string): New constant.
121 (init_editfns): Use it. This centralizes the dump_tz stuff.
122 Call set_time_zone_rule here, so that its xputenv is done
123 before Emacs goes multithreaded.
124 (mktime_z) [!HAVE_TZALLOC]: New function, which is typically
125 thread-safe enough for Emacs.
126 (format_time_string, Fdecode_time, Fcurrent_time_string)
127 (Fcurrent_time_zone):
128 Prefer localtime_r and gmtime_r, which are more thread-safe, to
129 localtime and gmtime. Remove now-unnecessary calls to block_input.
130 (tm_gmtoff): New static function.
131 (Fdecode_time, Fcurrent_time_zone): Use it.
132 (Fencode_time): Use mktime_z, for better thread-safety.
133 (set_time_zone_rule): Now static. Rewrite to be mostly thread-safe,
134 i.e., not quite thread-safe but good enough for Emacs typical usage.
135 Do not reclaim storage that is in the environment; let it leak.
136 Always call tzset, since localtime_r does not.
137 * emacs.c (dump_tz, Fdump_emacs) [HAVE_TZSET]: Remove dump_tz stuff.
138 This is now done in init_editfns.
139 * systime.h (mktime_z, timezone_t, tzalloc, tzfree) [!HAVE_TZALLOC]:
140 New macros and declarations, for platforms lacking tzalloc & friends.
141
1422014-10-09 Paul Eggert <eggert@cs.ucla.edu>
143
144 * lisp.h (USE_STACK_STRING): Now true only if USE_STACK CONS.
145 On x86 platforms this works around GCC bug 63495
146 <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63495>,
147 and more generally should fix a portability problem in Emacs.
148 Problem reported by Stefan Monnier in:
149 http://lists.gnu.org/archive/html/emacs-devel/2014-10/msg00261.html
150
1512014-10-08 Leo Liu <sdl.web@gmail.com>
152
153 Enhance terpri to allow conditionally output a newline. (Bug#18652)
154 * keymap.c (describe_vector_princ):
155 * keyboard.c (Fcommand_error_default_function): Adapt to change to
156 Fterpri.
157
158 * print.c (printchar_stdout_last): Declare.
159 (printchar): Record the last char written to stdout.
160 (Fterpri): Add optional argument ENSURE.
161
1622014-10-08 Eli Zaretskii <eliz@gnu.org>
163
164 * w32inevt.c (maybe_generate_resize_event): Pass non-zero as the
165 DELAY argument to change_frame_size, so that the frame size
166 changes, if any are needed, are delayed until the next redisplay.
167 This is to avoid a too early QUIT inside change_frame_size, when
168 it calls Lisp in frame_windows_min_size, in case one of the events
169 we've read sets the quit-flag. (Bug#18649)
170
171 * w32fns.c (check_x_display_info): Accept terminal objects as
172 argument, to follow what xfns.c does.
173
1742014-10-07 Glenn Morris <rgm@gnu.org>
175
176 * Makefile.in ($(srcdir)/macuvs.h)
177 ($(lispsource)/international/charprop.el): Add explicit FORCE.
178
1792014-10-07 Eli Zaretskii <eliz@gnu.org>
180
181 * decompress.c (init_zlib_functions): Move the message about zlib
182 being unavailable from here...
183 (Fzlib_decompress_region): ...to here. (Bug#18650)
184
1852014-10-07 Dmitry Antipov <dmantipov@yandex.ru>
186
187 * font.c (Ffont_get_glyphs): Use validate_subarray and fix
188 the case where an optional string is used. Adjust docstring.
189
1902014-10-06 Stefan Monnier <monnier@iro.umontreal.ca>
191
192 * lisp.mk (lisp): Remove w32-common-fns.elc.
193
1942014-10-05 Paul Eggert <eggert@cs.ucla.edu>
195
196 * keyboard.c (Qleft, Qright): Remove duplicate definitions (Bug#9927).
197 These were already defined in buffer.c, and the duplicate
198 definitions cause problems on platforms like 'gcc -fno-common'.
199 Reported by Peter Dyballa in: http://bugs.gnu.org/9927#137
200
2012014-10-05 Jan Djärv <jan.h.d@swipnet.se>
202
203 * nsterm.m (updateFrameSize:): Only call update_frame_tool_bar
204 if toolbar is visible.
205
206 * nsfont.m (nsfont_draw): Use CGFloat for GNUstep newer than
207 0.23 (Bug#18030).
208
209 * nsterm.m (syms_of_nsterm): ns-use-fullscreen-animation is new.
210 (toggleFullScreen:): Use ns-use-fullscreen-animation for animate.
211 (ns_select, ns_read_socket): Use unwind_protect to decrease
212 apploopnr (Bug#18345).
213 (ns_draw_window_cursor): Adjust y for hbar cursor only if smaller than
214 line height (Bug#17977).
215
216 * macfont.m: Fix indentation and import changes from macport 24.3.94.
217 (macfont_closest_traits_index): New function.
218 (macfont_closest_traits_index_p): Rename from
219 macfont_closest_traits_index.
220 (macfont_list): Use macfont_closest_traits_index_p.
221
2222014-10-05 K. Handa <handa@gnu.org>
223
224 * coding.c (detect_coding_iso_2022): Set coding->rejected
225 correctly when an invalid escape sequence is found (Bug#18610).
226
2272014-10-04 Jan Djärv <jan.h.d@swipnet.se>
228
229 * gtkutil.c (create_menus): Only add tearoffs to empty menus.
230 (xg_update_submenu): Remove has_tearoff_p, pass 1 to create_menus
231 for add_tearoff_p.
232
2332014-10-04 Martin Rudalics <rudalics@gmx.at>
234
235 * buffer.c (scroll_bar_width, scroll_bar_height):
236 Fix doc-strings.
237 * window.c (Fset_window_scroll_bars): Fix doc-string.
238 (Fwindow_scroll_bars): Have it return what the doc-string says.
239
2402014-10-03 Eli Zaretskii <eliz@gnu.org>
241
242 * xdisp.c (move_it_by_lines): Call reseat_1 after moving the
243 iterator backwards, to resync the bidi iterator. (Bug#18584)
244
2452014-10-03 Dmitry Antipov <dmantipov@yandex.ru>
246
247 Consistently use min and max macros from lisp.h.
248 * coding.c (min, max):
249 * font.c (MAX):
250 * unexhp9k800.c (min):
251 * unexw32.c (min, max): Use definitions from lisp.h.
252 * regex.c (MAX, MIN) [!emacs]: Define own max and min as such.
253 Adjust users.
254 * gmalloc.c (min): Tiny style change.
255
256 * fileio.c (emacs_readlinkat, Finsert_file_contents):
257 * w32fns.c, xfns.c (x_create_tip_frame): Use AUTO_STRING.
258
2592014-10-03 Paul Eggert <eggert@cs.ucla.edu>
260
261 Fix x-focus-frame bug with "Not an in-range integer" (Bug#18586).
262 * xselect.c (X_SHRT_MAX, X_SHRT_MIN, X_LONG_MAX, X_LONG_MIN)
263 (X_ULONG_MAX): Move these macros to xterm.h.
264 (x_fill_property_data): Be more generous about allowing either
265 signed or unsigned data of the appropriate width.
266 * xterm.h (x_display_set_last_user_time): New function.
267 All setters of last_user_time changd to use this function.
268 If ENABLE_CHECKING, check that the times are in range.
269
2702014-10-02 Eli Zaretskii <eliz@gnu.org>
271
272 * dispnew.c (adjust_decode_mode_spec_buffer): Use 'int' instead of
273 'ssize_t'. Suggested by Paul Eggert <eggert@cs.ucla.edu>.
274
2752014-10-02 Jan Djärv <jan.h.d@swipnet.se>
276
277 * xfaces.c (Finternal_set_lisp_face_attribute): Don't try to
278 make a font_object from a tty frame (Bug#18573).
279 (Finternal_set_lisp_face_attribute): Add FIXME comment.
280
2812014-10-02 Dmitry Antipov <dmantipov@yandex.ru>
282
283 * alloc.c (mark_overlay): Assume that overlay boundaries are
284 always markers. Add comment.
285 * lread.c (read_internal_start): Use convenient validate_subarray.
286 Adjust docstring.
287 (Fread_from_string): Adjust docstring.
288
2892014-10-02 Stefan Monnier <monnier@iro.umontreal.ca>
290
291 * lisp.h: Fix up compilation for USE_STACK_LISP_OBJECTS=false.
292
293 * nsselect.m (ns-own-selection-internal, ns-disown-selection-internal):
294 Rename from the "x-" prefix.
295
2962014-10-01 Stefan Monnier <monnier@iro.umontreal.ca>
297
298 * xselect.c (selection-converter-alist): Fix docstring.
299
3002014-10-01 Eli Zaretskii <eliz@gnu.org>
301
302 * w32proc.c (sys_spawnve): Avoid modification of the CMDNAME
303 argument passed by the caller, when we mirror all slashes into
304 backslashes.
305
3062014-10-01 Dmitry Antipov <dmantipov@yandex.ru>
307
308 * gtkutil.c (xg_set_toolkit_horizontal_scroll_bar_thumb):
309 Resurrect old code and fix compilation with GTK < 2.13.6.
310
3112014-10-01 Paul Eggert <eggert@cs.ucla.edu>
312
313 Use AUTO_CONS instead of SCOPED_CONS, etc.
314 * frame.h (AUTO_FRAME_ARG): Rename from FRAME_PARAMETER.
315 * lisp.h (AUTO_CONS): Rename from scoped_cons.
316 (AUTO_LIST1): Rename from scoped_list1.
317 (AUTO_LIST2): Rename from scoped_list2.
318 (AUTO_LIST3): Rename from scoped_list3.
319 (AUTO_LIST4): Rename from scoped_list4.
320 (AUTO_STRING): Rename from SCOPED_STRING.
321 * frame.h (AUTO_FRAME_ARG):
322 * lisp.h (AUTO_CONS, AUTO_LIST1, AUTO_LIST2, AUTO_LIST3)
323 (AUTO_LIST4, AUTO_STRING):
324 Prepend a new argument 'name'.
325 Declare a variable instead of yielding a value.
326 All uses changed.
327 * lisp.h (STACK_CONS, AUTO_CONS_EXPR): New internal macros.
328
3292014-09-30 Eli Zaretskii <eliz@gnu.org>
330
331 * w32fns.c (w32_createwindow): Accept an additional argument, an
332 array of 2 values specifying the coordinates of the frame's
333 top-left corner. Use these values instead of calling x_get_arg,
334 which can cons Lisp objects, and therefore cannot be called except
335 from the main thread. Remove redundant tests for the default
336 values.
337 (my_create_window): Move the calculation of the coordinates of the
338 frame's top-left edge here. Pass them to the input thread via the
339 second parameter of the WM_EMACS_CREATEWINDOW message.
340 See http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00892.html
341 for the details.
342
3432014-09-30 Eli Zaretskii <eliz@gnu.org>
344
345 * xdisp.c (cursor_row_fully_visible_p): Update commentary.
346 (redisplay_window): Treat the frame's frozen_window_starts flag
347 the same way as the optional_new_start flag for the window: only
348 obey it if the glyph row showing point will be fully visible.
349 Likewise when the window start is in a continuation line. If,
350 after trying everything under the 'force_start' label, point is
351 still not fully visible, give up and scroll the window.
352 Add debugging traces. (Bug#18545)
353
354 * window.c (Frecenter): Set the window's redisplay flag.
355
3562014-09-30 Eli Zaretskii <eliz@gnu.org>
357
358 * w32term.c (w32_read_socket): Don't use frame dimensions for
359 resizing if GetClientRect returned an empty (0, 0, 0, 0)
360 rectangle. Check the return value of GetClientRect, and don't use
361 the results if it didn't succeed.
362
363 * dispnew.c (change_frame_size_1): Recompute the frame dimensions
364 in columns and lines after correcting the pixel dimensions in
365 check_frame_size.
366 (adjust_decode_mode_spec_buffer): Add assertion to avoid passing
367 negative values to xrealloc. (Bug#18528)
368
3692014-09-30 Paul Eggert <eggert@cs.ucla.edu>
370
371 * alloc.c: Remove now-unnecessary check.
372 Suggested by Dmitry Antipov in:
373 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00891.html
374
375 * xterm.c (x_term_init): Allocate temps on stack, not on heap.
376
377 * frame.c (x_set_frame_parameters): Port --enable-gcc-warnings
378 to Ubuntu 14.04.1 x86-64.
379
380 Simplify stack-allocated Lisp objects, and make them more portable.
381 The build_local_string macro was used in two ways: (1) string
382 literals for which scoped allocation suffices, and (2) file name
383 components, where it's not safe in general to assume bounded-size
384 ASCII data. Simplify by defining a new macro SCOPED_STRING that
385 allocates a block-scope string, and by using SCOPED_STRING for (1)
386 and build_string for (2). Furthermore, actually use stack
387 allocation only for objects known to have sufficient alignment.
388 This simpler implementation means Emacs can make
389 USE_STACK_LISP_OBJECTS the default unless GC_MARK_STACK !=
390 GC_MAKE_GCPROS_NOOPS.
391 * lisp.h (GCALIGNED): Align even if !USE_STACK_LISP_OBJECTS,
392 for fewer differences among implementations.
393 (struct Lisp_String): Now GCALIGNED.
394 (USE_STACK_LISP_OBJECTS): Default to true, since the
395 implementation no longer insists on a nonempty GCALIGNED.
396 But make it false if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS.
397 (SCOPED_CONS_INITIALIZER): Remove, since it's no longer needed
398 separately. Move definiens to scoped_cons. The old definition
399 was incorrect when GCALIGNED was defined to be empty.
400 (union Aligned_String): New type.
401 (USE_STACK_CONS, USE_STACK_STRING): New constants, so that the
402 implementation ports to compilers that don't align strictly enough.
403 Don't worry about the union sizes; it's not worth bothering about.
404 (scoped_cons, scoped_list1, scoped_list3, scoped_list4):
405 Rewrite using USE_STACK_CONS.
406 (scoped_cons): Assume the use of union Aligned_Cons.
407 (lisp_string_size, make_local_string, build_local_string): Remove.
408 Unless otherwise specified, all callers of build_local_string
409 changed to use SCOPED_STRING.
410 (SCOPED_STRING): New macro.
411 * data.c (wrong_choice):
412 * menu.c (single_menu_item):
413 * process.c (Fformat_network_address):
414 Hoist use of SCOPED_STRING out of a scope, so that its returned
415 object lives long enough.
416 * fileio.c (Fexpand_file_name): Use build_string, not SCOPED_STRING,
417 as the string might be long or might not be ASCII.
418
4192014-09-29 Eli Zaretskii <eliz@gnu.org>
420
421 * msdos.c (internal_terminal_init): Bump version to 25.
422
4232014-09-29 Dmitry Antipov <dmantipov@yandex.ru>
424
425 Keep stack-allocated Lisp objects fast rather than versatile.
426 * lisp.h (union Aligned_Cons) [!GCALIGNED]: Define as such.
427 (SCOPED_CONS_INITIALIZER): New macro.
428 (scoped_cons) [USE_STACK_LISP_OBJECTS]: Use it.
429 (USE_LOCAL_ALLOCA): Remove.
430 (local_cons, local_list1, local_list2, local_list3, local_list4):
431 Remove. Stack overflow checking makes them too slow.
432 (make_local_vector): Likewise. Also we just don't have enough
433 users for it.
434 (enum LISP_STRING_OVERHEAD): Remove.
435 (local_string_init, local_vector_init): Remove prototypes.
436 (make_local_string, build_local_string): Redesign to target short
437 compile-time string constants, fall back to regular string allocation
438 where appropriate.
439 (lisp_string_size): New function.
440 (verify_ascii) [ENABLE_CHECKING]: Add prototype.
441 * alloc.c (local_string_init, local_vector_init): Remove.
442 (verify_ascii) [ENABLE_CHECKING]: New function.
443 * buffer.c, charset.c, chartab.c, data.c, editfns.c, emacs.c, fileio.c:
444 * fns.c, font.c, fontset.c, frame.c, keyboard.c, keymap.c, lread.c:
445 * menu.c, minibuf.c, process.c, textprop.c, xdisp.c, xfns.c, xfont.c:
446 * xselect.c, xterm.c: All related users changed.
447
4482014-09-28 Ken Brown <kbrown@cornell.edu>
449
450 * sheap.c (bss_sbrk_buffer_beg): Remove redundant variable.
451 * gmalloc.c [CYGWIN]: Adapt to change in sheap.c.
452
4532014-09-27 Ken Brown <kbrown@cornell.edu>
454
455 Fix implementation of HYBRID_MALLOC on Cygwin.
456 * sheap.c (bss_sbrk_buffer_end): Cast to void *.
457 (bss_sbrk_buffer_beg): New variable. Use it...
458 * gmalloc.c (ALLOCATED_BEFORE_DUMPING) [CYGWIN]: ...here, to fix
459 incorrect definition.
460
4612014-09-27 Stefan Monnier <monnier@iro.umontreal.ca>
462
463 * keyboard.c (track-mouse): Rename to internal--track-mouse.
464 Make it into a function and change arg to be a function.
465
466 * lisp.mk (lisp): Add elisp-mode.elc.
467
4682014-09-26 Paul Eggert <eggert@cs.ucla.edu>
469
470 * xfns.c (x_default_scroll_bar_color_parameter):
471 Use USE_LOCAL_ALLOCA only if USE_TOOLKIT_SCROLL_BARS,
472 to pacify --enable-gcc-warnings in non-scrollbar builds.
473
4742014-09-26 Ken Brown <kbrown@cornell.edu>
475
476 * w32term.h (ALIGN_STACK): Fix the cpp condition.
477
4782014-09-25 Eli Zaretskii <eliz@gnu.org>
479
480 * lisp.h (USE_STACK_LISP_OBJECTS): Default to false for 32-bit
481 MinGW builds that use GCC before 4.2.
482
483 Default to stack objects on DOS_NT platforms as well.
484 * w32term.h (ALIGN_STACK) [__GNUC__]: Define to
485 __attribute__((force_align_arg_pointer)) for GCC 4.2 and later.
486
487 * lisp.h (USE_STACK_LISP_OBJECTS): Remove the !DOS_NT condition.
488
489 * w32proc.c (enum_locale_fn, enum_codepage_fn): Add the
490 ALIGN_STACK attribute.
491
492 * w32fns.c (w32_monitor_enum): Add the ALIGN_STACK attribute.
493
494 * w32uniscribe.c (add_opentype_font_name_to_list): Add the
495 ALIGN_STACK attribute.
496
497 * w32font.c (add_font_name_to_list, add_font_entity_to_list)
498 (add_one_font_entity_to_list): Add the ALIGN_STACK attribute.
499
5002014-09-25 Martin Rudalics <rudalics@gmx.at>
501
502 * frame.c (frame_inhibit_resize):
503 * widget.c (EmacsFrameResize):
504 * window.c (resize_frame_windows, Fset_window_configuration):
505 * xdisp.c (expose_frame):
506 * xfns.c (x_change_tool_bar_height):
507 * xmenu.c (update_frame_menubar):
508 * xterm.c (handle_one_xevent, x_new_font, x_set_window_size_1):
509 Remove code left dead after 2014-07-27 changes.
510
5112014-09-25 Paul Eggert <eggert@cs.ucla.edu>
512
513 Fix local_cons etc. to not exhaust the stack when in a loop.
514 Problem reported in:
515 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00696.html
516 * buffer.c (Fother_buffer, other_buffer_safely, init_buffer):
517 * charset.c (load_charset_map_from_file, Ffind_charset_region)
518 (Ffind_charset_string):
519 * chartab.c (uniprop_encode_value_numeric, uniprop_table):
520 * data.c (wrong_range):
521 * editfns.c (Fpropertize, format2):
522 * emacs.c (init_cmdargs, decode_env_path):
523 * fileio.c (auto_save_error):
524 * fns.c (Fyes_or_no_p):
525 * font.c (font_style_to_value, font_parse_xlfd)
526 (font_parse_family_registry, font_delete_unmatched)
527 (font_add_log):
528 * fontset.c (Fset_fontset_font):
529 * frame.c (x_get_arg):
530 * keyboard.c (echo_dash, safe_run_hooks_error, parse_menu_item)
531 (read_char_minibuf_menu_prompt):
532 * keymap.c (silly_event_symbol_error, describe_vector):
533 * lread.c (load_warn_old_style_backquotes):
534 * menu.c (single_menu_item):
535 * minibuf.c (Fread_buffer):
536 * process.c (status_message, Fformat_network_address)
537 (server_accept_connection):
538 * textprop.c (copy_text_properties):
539 * xdisp.c (Fcurrent_bidi_paragraph_direction):
540 * xfns.c (x_default_scroll_bar_color_parameter):
541 * xfont.c (xfont_open):
542 * xselect.c (x_clipboard_manager_error_1):
543 * xterm.c (x_term_init):
544 Put USE_LOCAL_ALLOCA at the start of the function.
545 * fns.c (maybe_resize_hash_table): Use build_string instead of
546 build_local_string, since we'd otherwise need a conditional
547 USE_LOCAL_ALLOCA here, but this is just debugging output and is
548 not worth the bother of optimization.
549 * font.c (font_delete_unmatched): Remove by-hand code that
550 observed MAX_ALLOCA limit, since it's now done automatically.
551 * keymap.c (Fsingle_key_description): Put USE_SAFE_ALLOCA at top,
552 since build_local_string needs its sa_alloc.
553 * lisp.h (lisp_word_count): New function.
554 (SAFE_ALLOCA_LISP): Use it.
555 (USE_LOCAL_ALLOCA): New macro.
556 (local_cons, make_local_vector, make_local_string):
557 Observe the MAX_ALLOCA limit.
558 (LISP_STRING_OVERHEAD): New constant.
559 (make_local_string): Use it.
560
5612014-09-24 Paul Eggert <eggert@cs.ucla.edu>
562
563 Default to stack objects on non-GNU/Linux, non-DOS_NT platforms.
564 * lisp.h (USE_STACK_LISP_OBJECTS): Also default to true
565 if !defined DOS_NT && !defined GNU_LINUX. I've tested this on AIX
566 and Solaris and it's likely to work on similar platforms.
567
568 Avoid signed integer overflow when converting Time to ptrdiff_t.
569 * keyboard.c (INPUT_EVENT_POS_MAX, INPUT_EVENT_POS_MIN):
570 New macros.
571 (position_to_Time, Time_to_position): New functions.
572 (gen_help_event, kbd_buffer_get_event): Use them.
573 * systime.h (Time) [emacs && !HAVE_X_WINDOWS]:
574 Go back to plain 'unsigned long', so that 'Time' is the same
575 for both X and non-X builds; this is less likely to cause surprise.
576 * termhooks.h: Remove compile-time check that Time and ptrdiff_t
577 are the same size; this is no longer required.
578
579 * keyboard.c (make_lispy_event): Avoid unnecessary tests
580 of bit 28 and of whether an unsigned value is negative.
581 This simplifies the code a bit, and pacifies clang 3.4.
582
5832014-09-24 Eli Zaretskii <eliz@gnu.org>
584
585 * systime.h (Time): Define as size_t, to be consistent with 64-bit
586 Windows builds, where 'long' is a 32-bit type.
587
588 * w32inevt.h (w32_console_mouse_position): Update the argument
589 types to use 'Time'.
590
591 * w32term.c (w32_mouse_position)
592 (x_horizontal_scroll_bar_report_motion)
593 (x_scroll_bar_report_motion): Update the argument types to use
594 'Time'.
595
5962014-09-24 Dmitry Antipov <dmantipov@yandex.ru>
597
598 * termhooks.h (enum scroll_bar_part): Begin from 0 to allow...
599 (struct input_event): ...unsigned bitfields. Likewise for
600 `event_kind' member. Prefer unsigned for `code' and 'modifiers'.
601 Use `timestamp' for HELP_EVENT position. Add compile-time assert.
602 * keyboard.c (gen_help_event, kbd_buffer_store_help_event)
603 (kbd_buffer_get_event): Adjust users.
604 (scroll_bar_parts): Add Qnil to match scroll_bar_nowhere.
605 (make_scroll_bar_position): New function, refactored out of...
606 (make_lispy_event): ...adjusted user.
607 * nsterm.h (EmacsScroller): Use enum for `last_hit_part' member.
608 * nsterm.m (ns_mouse_position, mouseUp):
609 * term.c (term_mouse_position):
610 * w32inevt.c (w32_console_mouse_position):
611 * w32term.c (w32_mouse_position):
612 * xterm.c (XTmouse_position): Use scroll_bar_above_handle.
613 (x_send_scroll_bar_event, xm_scroll_callback, xg_scroll_callback):
614 Prefer enum and explicit enum members to integers and numeric values.
615
616 * chartab.c (uniprop_encode_value_numeric):
617 * font.c (font_style_to_value): Use make_local_vector.
618 (font_delete_unmatched): Use local_cons but respect MAX_ALLOCA.
619 * keymap.c (append_key): Use scoped_list1.
620
621 * lisp.h (USE_STACK_LISP_OBJECTS): Enable by default if GNU_LINUX
622 && __GNUC__ && !__clang__. Mention known problems. Adjust comment.
623
6242014-09-24 Paul Eggert <eggert@cs.ucla.edu>
625
626 Fix some slow uses and misuses of strcat.
627 * doc.c (get_doc_string):
628 * gtkutil.c (get_utf8_string):
629 * xsmfns.c (x_session_initialize):
630 Avoid recomputation of string length.
631 * ftfont.c (ftfont_spec_pattern):
632 * xfns.c (xic_create_fontsetname):
633 Don't assume output buffer is initially zero.
634
6352014-09-23 Paul Eggert <eggert@cs.ucla.edu>
636
637 * lisp.h (lispstpcpy): Rename from lispstrcpy, and act like stpcpy.
638 All callers changed.
639 * xterm.c (x_term_init): Use new functionality to avoid two needs
640 to compute a string length.
641
642 * dispextern.h, xdisp.c (window_box_right_offset): Now static.
643
6442014-09-23 Dmitry Antipov <dmantipov@yandex.ru>
645
646 Use known length of a Lisp string to copy it faster.
647 * lisp.h (lispstrcpy): New function. Add comment.
648 * callproc.c (child_setup):
649 * dbusbind.c (xd_append_arg):
650 * doc.c (get_doc_string):
651 * font.c (Ffont_xlfd_name):
652 * frame.c (xrdb_get_resource):
653 * process.c (Fmake_network_process, network_interface_info):
654 * w32fns.c (Fx_open_connection):
655 * w32proc.c (sys_spawnve):
656 * xfns.c (select_visual):
657 * xfont.c (xfont_list):
658 * xsmfns.c (x_session_initialize):
659 * xterm.c (x_term_init): Use it.
660
6612014-09-23 Paul Eggert <eggert@cs.ucla.edu>
662
663 Fix SAFE_ALLOCA to not exhaust the stack when in a loop.
664 Problem reported by Dmitry Antipov in thread leading to:
665 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html
666 This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP;
667 the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS
668 remain unfixed.
669 * callproc.c (call_process): Save and restore sa_avail.
670 * lisp.h (USE_SAFE_ALLOCA): Define sa_avail.
671 (AVAIL_ALLOCA): New macro.
672 (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP):
673 Use it, and check against sa_avail rather than MAX_ALLOCA.
674
6752014-09-22 Dmitry Antipov <dmantipov@yandex.ru>
676
677 On OSX, do not free font-specific data more than once (Bug#18501).
678 * macfont.m (macfont_close): Release and free font-specific data
679 only if it wasn't previously freed.
680
6812014-09-22 David Caldwell <david@porkrind.org> (tiny change)
682
683 * unexmacosx.c (dump_it): Improve error message.
684
6852014-09-22 Juri Linkov <juri@jurta.org>
686
687 * image.c (imagemagick_load_image): Add delay to imagemagick metadata.
688 (Bug#10747, bug#18334)
689
6902014-09-22 Eli Zaretskii <eliz@gnu.org>
691
692 * frame.c (Fmouse_position, Fset_mouse_position): Clarify the
693 units in which the position is measured. (Bug#18493)
694
695 * xdisp.c (redisplay_internal): Force redisplay of all windows
696 that show a buffer whose narrowing has changed. (Bug#18490)
697
6982014-09-22 Eli Zaretskii <eliz@gnu.org>
699
700 * xterm.c (x_draw_hollow_cursor, x_draw_bar_cursor):
701 * w32term.c (x_draw_hollow_cursor, x_draw_bar_cursor): In R2L
702 lines, draw the hollow-box and hbar cursors on the right side of
703 cursor-glyph. Thanks to martin rudalics <rudalics@gmx.at> for
704 testing on X.
705
706 * xterm.c (x_draw_stretch_glyph_string):
707 * w32term.c (x_draw_stretch_glyph_string): Fix a thinko that
708 caused the block cursor to disappear on a TAB in R2L lines in
709 every window except the leftmost one. Reported by Martin Rudalics
710 <rudalics@gmx.at>.
711
7122014-09-22 Dmitry Antipov <dmantipov@yandex.ru>
713
714 Always use matched specpdl entry to record call arguments (Bug#18473).
715 * lisp.h (record_in_backtrace): Adjust prototype.
716 * eval.c (record_in_backtrace): Return current specpdl level.
717 (set_backtrace_args, set_backtrace_nargs): Merge. Adjust all users.
718 (eval_sub, Ffuncall): Record call arguments in matched specpdl
719 entry and use that entry in call to backtrace_debug_on_exit.
720 (apply_lambda): Likewise. Get current specpdl level as 3rd arg.
721 (do_debug_on_call): Get current specpdl level as 2nd arg.
722
723 Prefer ptrdiff_t to int and avoid integer overflows.
724 * fileio.c (make_temp_name):
725 * font.c (font_parse_family_registry): Avoid integer
726 overflow on string size calculation.
727 * data.c (Faset): Likewise for byte index.
728
7292014-09-22 Eli Zaretskii <eliz@gnu.org>
730
731 Fix display of R2L lines in partial-width windows.
732 * xdisp.c (init_iterator): Don't use it->bidi_p before it is
733 assigned the correct value.
734 (extend_face_to_end_of_line): Account for truncation and
735 continuation glyphs in R2L rows when one of the fringes is not
736 displayed.
737 (display_line): Don't assign negative X offset to a row if we are
738 going to produce a truncation glyph for it. When handling
739 truncated R2L rows, consider the width of the left fringe instead
740 of the right one.
741 (produce_special_glyphs): Fix bogus assignments.
742
7432014-09-22 Eli Zaretskii <eliz@gnu.org>
744
745 * w32.c (fcntl): Support O_NONBLOCK fcntl on the write side of pipes.
746
7472014-09-22 Eli Zaretskii <eliz@gnu.org>
748
749 * fileio.c (Fexpand_file_name) [DOS_NT]: Make sure newdirlim is
750 always set to a valid value. Make sure the size passed to alloca
751 is always positive. (Bug#18516)
752
7532014-09-22 Dmitry Antipov <dmantipov@yandex.ru>
754
755 Avoid extra call to oblookup when interning symbols.
756 * lisp.h (intern_driver): Add prototype.
757 * lread.c (intern_driver): New function.
758 (intern1, intern_c_string_1, Fintern):
759 * font.c (font_intern_prop):
760 * w32font.c (intern_font_name): Use it.
761
7622014-09-21 Paul Eggert <eggert@cs.ucla.edu>
763
764 Minor improvements to new stack-allocated Lisp objects.
765 * frame.h (FRAME_PARAMETER):
766 Prefer scoped_list1 to local_list1 where either would do.
767 * lisp.h (scoped_list4): New macro.
768 (local_cons, local_list1, local_list2, local_list3, local_list4)
769 (make_local_vector, make_local_string, build_local_string):
770 Prefer functions to macros where either would do.
771 * xdisp.c (build_desired_tool_bar_string):
772 Prefer scoped_list4 to local_list4 where either would do.
773
7742014-09-18 Dmitry Antipov <dmantipov@yandex.ru>
775
776 More and more stack-allocated Lisp objects if USE_LOCAL_ALLOCATORS.
777 * lisp.h (local_list4) [USE_LOCAL_ALLOCATORS]: New macro.
778 [!USE_LOCAL_ALLOCATORS]: Fall back to regular list4.
779 * frame.h (FRAME_PARAMETER): New macro.
780 * dispnew.c (init_display):
781 * fontset.c (Fset_fontset_font):
782 * frame.c (x_default_parameter):
783 * xfaces.c (set_font_frame_param, Finternal_merge_in_global_face):
784 * xfns.c (x_default_scroll_bar_color_parameter)
785 (x_default_font_parameter, x_create_tip_frame): Use it.
786 * editfns.c (Fpropertize): Use local_cons.
787 * process.c (status_message): Use build_local_string.
788 * xfont.c (xfont_open): Use make_local_string.
789 * xdisp.c (build_desired_tool_bar_string): Use local_list4.
790
7912014-09-18 Paul Eggert <eggert@cs.ucla.edu>
792
793 Port USE_LOCAL_ALLOCATORS code to clang 3.4 x86-64.
794 * lisp.h (USE_LOCAL_ALLOCATORS): Define only if __GNUC__ &&
795 !__clang__. This works with GCC and with clang and is safer for
796 compilers we don't know about.
797 (local_cons): Rename parameter to make capture less likely.
798
7992014-09-17 Samuel Bronson <naesten@gmail.com>
800
801 * unexmacosx.c (copy_data_segment): Port to GCC 4.6+ (Bug#9927).
802
8032014-09-17 Paul Eggert <eggert@cs.ucla.edu>
804
805 Fix minor problems found by static checking.
806 * alloc.c, lisp.h (SAVE_TYPE_INT_OBJ, make_save_int_obj):
807 Remove; now unused.
808 * buffer.h (decode_buffer): Doc and indentation fixes.
809 * fns.c (Qstring_collate_lessp, Qstring_collate_equalp): Now static.
810
8112014-09-17 Dmitry Antipov <dmantipov@yandex.ru>
812
813 Avoid clang-specific warnings.
814 * buffer.c (init_buffer): Shut up -Wself-assign.
815 * process.c (server_accept_connection): Shut up -Wunsequenced.
816
8172014-09-16 Daniel Colascione <dancol@dancol.org>
818
819 * fns.c (sxhash): For symbols, use address as hash code.
820
8212014-09-16 Dmitry Antipov <dmantipov@yandex.ru>
822
823 If USE_LOCAL_ALLOCATORS, allocate even more Lisp objects on stack.
824 * charset.c (load_charset_map_from_file): Use scoped_list2
825 and build_local_string.
826 * buffer.c (Fother_buffer, other_buffer_safely, init_buffer):
827 * emacs.c (init_cmdargs, decode_env_path):
828 * fileio.c (Fexpand_file_name):
829 * fns.c (maybe_resize_hash_table) [ENABLE_CHECKING]:
830 * frame.c (x_get_arg):
831 * keyboard.c (safe_run_hooks_error):
832 * lread.c (load_warn_old_style_backquotes):
833 * xdisp.c (Fcurrent_bidi_paragraph_direction):
834 * xfns.c (x_default_scroll_bar_color_parameter, select_visual):
835 * xselect.c (x_clipboard_manager_error_1)
836 (x_clipboard_manager_save_all):
837 * xterm.c (x_term_init): Use build_local_string.
838
839 Avoid more integer overflows on string size calculations.
840 * category.c (Fmake_category_set):
841 * xdisp.c (get_overlay_arrow_glyph_row):
842 * w32font.c (intern_font_name): Prefer ptrdiff_t to int.
843
8442014-09-15 Eli Zaretskii <eliz@gnu.org>
845
846 * sound.c [WINDOWSNT]: Include w32common.h and mbstring.h.
847 (SOUND_WARNING) [WINDOWSNT]: Include in do..while and improve the
848 error message format. Use message_with_string to have non-ASCII
849 file names properly displayed.
850 (do_play_sound) [WINDOWSNT]: Use Unicode APIs to play sound files
851 when w32-unicode-filenames is non-nil, but not on Windows 9X,
852 where these APIs are not available even in UNICOWS.DLL.
853 Improve the format of error messages and include the file name in them
854 where appropriate.
855 (Fplay_sound_internal) [WINDOWSNT]: Make the MS-Windows branch
856 call play-sound-functions, per documentation.
857
858 * w32.c (w32_get_long_filename, w32_get_short_filename):
859 Constify the input file name arguments.
860
861 * w32.h (w32_get_long_filename, w32_get_short_filename):
862 Update prototypes.
863
8642014-09-15 Dmitry Antipov <dmantipov@yandex.ru>
865
866 If USE_LOCAL_ALLOCATORS, allocate some Lisp objects on stack.
867 * lisp.h (local_cons, local_list1, local_list2, local_list3)
868 [USE_LOCAL_ALLOCATORS]: New macros.
869 [!USE_LOCAL_ALLOCATORS]: Fall back to regular functions.
870 (build_local_string): Avoid argument name expansion clash with
871 make_local_string.
872 * alloc.c (toplevel)
873 [USE_LOCAL_ALLOCATORS && GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS]:
874 Preprocessor guard to avoid impossible configuration.
875 * charset.c (Ffind_charset_region, Ffind_charset_string):
876 Use make_local_vector.
877 * lread.c (read1, substitute_object_recurse): Use scoped_cons.
878 * textprop.c (Fput_text_property, Fadd_face_text_property):
879 Use scoped_list2.
880 (copy_text_properties): Use local_cons and local_list3.
881 * chartab.c (uniprop_table):
882 * data.c (wrong_choice, wrong_range):
883 * doc.c (get_doc_string):
884 * editfns.c (format2):
885 * fileio.c (Fexpand_file_name, auto_save_error):
886 * fns.c (Fyes_or_no_p):
887 * font.c (font_parse_xlfd, font_parse_family_registry, font_add_log):
888 * fontset.c (Fset_fontset_font):
889 * keyboard.c (echo_add_key, echo_dash, parse_menu_item)
890 (read_char_minibuf_menu_prompt):
891 * keymap.c (silly_event_symbol_error, describe_vector):
892 * menu.c (single_menu_item):
893 * minibuf.c (Fread_buffer):
894 * process.c (status_message, Fformat_network_address)
895 (server_accept_connection): Use make_local_string and
896 build_local_string. Prefer compound literals where appropriate.
897
8982014-09-15 Daniel Colascione <dancol@dancol.org>
899
900 * fns.c (Fsort): Tweak sort docstring.
901
9022014-09-15 Eli Zaretskii <eliz@gnu.org>
903
904 * w32.c (fcntl): Support O_NONBLOCK fcntl on the write side of pipes.
905 (sys_write): When a write to a non-blocking pipe returns ENOSPC,
906 set errno to EAGAIN instead, to allow the caller to retry the
907 write after some waiting. Fixes deadlocks when Emacs exchanges a
908 lot of data through the pipe. (Bug#18420)
909
910 * sound.c (Fplay_sound_internal): Encode the sound file name in
911 the ANSI codepage. Expand it against data-directory, as per docs,
912 not against the current directory. No need to make a local copy
913 of the file name; pass the encoded file name directly to
914 do_play_sound. (Bug#18463)
915
916 * w32.c (ansi_encode_filename): If w32_get_short_filename returns
917 NULL, and the file name is not encodable in ANSI codepage, return
918 the string with "?" replacement characters, which will fail the
919 caller. This avoids returning a random value in that case.
920
9212014-09-15 Martin Rudalics <rudalics@gmx.at>
922
923 * window.c (Fresize_mini_window_internal): Set w->total_lines
924 from w->pixel_height (Bug#18422).
925
9262014-09-15 Jan Djärv <jan.h.d@swipnet.se>
927
928 * nsterm.m (updateFrameSize:, initFrameFromEmacs:)
929 (toggleFullScreen:): Take frame_resize_pixelwise into account when
930 setting resize increments (Bug#18435).
931
9322014-09-15 Eli Zaretskii <eliz@gnu.org>
933
934 * xdisp.c (pos_visible_p): Properly save and restore the iterator
935 state around the call to line_bottom, since it can move the
936 iterator to another screen line. This fixes off-by-one errors in
937 the reported row in some rare cases.
938
9392014-09-14 Jan Djärv <jan.h.d@swipnet.se>
940
941 * callproc.c (init_callproc): Fix bug introduced at
942 2014-09-07 (Bug#18474).
943
9442014-09-13 Dmitry Antipov <dmantipov@yandex.ru>
945
946 Prefer ptrdiff_t to int and avoid integer overflows.
947 * fileio.c (make_temp_name):
948 * font.c (font_parse_family_registry): Avoid integer
949 overflow on string size calculation.
950 * data.c (Faset): Likewise for byte index.
951
9522014-09-12 Detlev Zundel <dzu@member.fsf.org>
953
954 * buffer.c (syms_of_buffer): DEFSYM Qchoice (Bug#18337).
955
9562014-09-11 Dmitry Antipov <dmantipov@yandex.ru>
957
958 * lisp.h (make_local_string): Nitpick indent.
959 * print.c (Fprin1_to_string): Remove unused GCPROs.
960
961 More debugging aids around GCPROs.
962 * lisp.h (struct gcpro) [DEBUG_GCPRO]: Add extra members.
963 (GCPRO1, GCPRO2, GCPRO3, GCPRO4, GCPRO5, GCPRO6, GCPRO7):
964 Minor restyle. If DEBUG_GCPRO, initialize extra fields.
965
966 * lread.c (readevalloop_eager_expand_eval): Add GCPRO and fix
967 bootstrap broken if GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE.
968
969 Remove redundant GCPROs around Ffuncall and Fapply calls.
970 This is safe because Ffuncall protects all of its arguments by itself.
971 * charset.c (map_charset_for_dump): Remove redundant GCPRO.
972 * eval.c (Fapply, apply1, call0, call1, call2, call3, call4, call5)
973 (call6, call7): Likewise. Use compound literals where applicable.
974 (run_hook_with_args_2): Use compound literal.
975
9762014-09-11 Paul Eggert <eggert@cs.ucla.edu>
977
978 Pacify --enable-gcc-warnings when no window system is used.
979 These warnings found that subscript error, so they seem worthwhile.
980 * composite.c (char_composable_p): Simplify a bit.
981 * frame.c (x_set_frame_parameters): Add an IF_LINT.
982 * frame.c (x_set_horizontal_scroll_bars, x_set_scroll_bar_height):
983 * frame.h (FRAME_HAS_HORIZONTAL_SCROLL_BARS):
984 * window.c (set_window_scroll_bars):
985 Use USE_HORIZONTAL_SCROLL_BARS for simplicity.
986 * frame.h [! USE_HORIZONTAL_SCROLL_BARS]:
987 Ignore -Wsuggest-attribute=const.
988 * window.h (USE_HORIZONTAL_SCROLL_BARS): New macro.
989 (WINDOW_HAS_HORIZONTAL_SCROLL_BAR): Use it.
990
9912014-09-10 Paul Eggert <eggert@penguin.cs.ucla.edu>
992
993 * charset.c (Fget_unused_iso_final_char): Fix subscript error.
994 Use check_iso_charset_parameter instead of doing the checks by hand.
995 (check_iso_charset_parameter): Move up. Check parameters a bit
996 more carefully, and return true for 96-char sets. All callers changed.
997
9982014-09-10 Paul Eggert <eggert@cs.ucla.edu>
999
1000 Simplify lisp.h by removing the __COUNTER__ business.
1001 Problem reported by Dmitry Antipov in:
1002 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00220.html
1003 * lisp.h (make_local_vector, make_local_string)
1004 (build_local_string): Simplify by not bothering with __COUNTER__.
1005 The __COUNTER__ business wasn't working properly, and was needed
1006 only for hypothetical future expansion anyway.
1007
10082014-09-10 Alp Aker <alp.tekin.aker@gmail.com>
1009
1010 * nsterm.m (ns_draw_fringe_bitmap): Use the same logic as other
1011 terms to determine bitmap color. (Bug#18437)
1012
10132014-09-10 Eli Zaretskii <eliz@gnu.org>
1014
1015 * w32.c (sys_write): Use SAFE_NALLOCA for the NL -> CRLF
1016 translation buffer.
1017
10182014-09-10 Paul Eggert <eggert@cs.ucla.edu>
1019
1020 * xterm.c (handle_one_xevent): Add braces to pacify gcc -Wall.
1021
10222014-09-10 Jan Djärv <jan.h.d@swipnet.se>
1023
1024 * xterm.c (handle_one_xevent): Detect iconified by looking at
1025 _NET_WM_STATE_HIDDEN.
1026
10272014-09-10 Paul Eggert <eggert@cs.ucla.edu>
1028
1029 * lisp.h (DEFINE_GDB_SYMBOL_ENUM): Remove.
1030 These can generate a constant with the correct value but the wrong
1031 width, which doesn't work as a printf argument. All uses removed.
1032 Problem reported by Dmitry Antipov in:
1033 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00213.html
1034 (ENUMABLE): Remove; no longer needed.
1035 (ARRAY_MARK_FLAG_val, PSEUDOVECTOR_FLAG_val, VALMASK_val):
1036 Remove; no longer needed because of the above change.
1037 Each definiens moved to the only use.
1038
1039 Improve the experimental local and scoped allocation.
1040 * alloc.c (local_string_init, local_vector_init):
1041 New functions, defined if USE_LOCAL_ALLOCATORS.
1042 Mostly, these are moved here from lisp.h, as it's not
1043 clear it's worth making them inline.
1044 * lisp.h (USE_STACK_LISP_OBJECTS): Default to false.
1045 (GCALIGNED): Depend on HAVE_STRUCT_ATTRIBUTE_ALIGNED and
1046 USE_STACK_LISP_OBJECTS, not on a laundry list.
1047 (local_string_init, local_vector_init): New decls.
1048 (union Aligned_Cons): New type.
1049 (scoped_cons): Use it. Give up on the char trick, as it's a too
1050 much of a maintenance hassle; if someone wants this speedup
1051 they'll just need to convince their compiler to align properly.
1052 Conversely, use the speedup if struct Lisp_Cons happens to
1053 be aligned even without a directive. Better yet, help it along
1054 by using union Aligned_Cons rather than struct Lisp_Cons.
1055 (pointer_valid_for_lisp_object): Remove. This check is not
1056 necessary, since make_lisp_ptr is already doing it. All uses removed.
1057 (local_vector_init, local_string_init): Move to alloc.c.
1058 (build_local_vector): Remove this awkward macro, replacing with ...
1059 (make_local_vector): New macro, which acts more like a function.
1060 Use statement expressions and use __COUNTER__ to avoid macro
1061 capture. Fall back on functions if these features are not supported.
1062 (build_local_string, make_local_string): Likewise.
1063
10642014-09-09 Dmitry Antipov <dmantipov@yandex.ru>
1065
1066 * xterm.c (x_term_init): Consolidate duplicated code.
1067 [USE_LUCID]: Revert 2014-04-02 change (Bug#18403). Add comment.
1068 (x_delete_terminal): Do not close X connection fd (Bug#18403).
1069 Add eassert and mark dpyinfo as dead only if it was alive.
1070
1071 Add macros to allocate temporary Lisp objects with alloca.
1072 Respect MAX_ALLOCA and fall back to regular GC for large objects.
1073 * character.h (parse_str_as_multibyte): Move prototype to ...
1074 * lisp.h (parse_str_as_multibyte): ... here.
1075 (struct Lisp_Cons): Add GCALIGNED attribute if supported.
1076 (scoped_cons, scoped_list2, build_local_vector, build_local_string):
1077 New macros.
1078 (scoped_cons_init, pointer_valid_for_lisp_object, local_vector_init)
1079 (local_string_init): New functions.
1080 * alloc.c (verify_alloca) [ENABLE_CHECKING]: New function.
1081 (init_alloc_once): Call it.
1082
1083 Cleanup last change and make all new stuff conditional.
1084 * lisp.h (build_local_string): Rename to ...
1085 (make_local_string): ... this macro.
1086 (build_local_string, scoped_list1, scoped_list3): New macros.
1087 (toplevel) [USE_STACK_LISP_OBJECTS]: Define all new macros
1088 and functions as such, use regular fallbacks otherwise.
1089 * alloc.c (verify_alloca) [USE_STACK_LISP_OBJECTS]: Define
1090 conditionally.
1091
10922014-09-08 Eli Zaretskii <eliz@gnu.org>
1093
1094 * dispnew.c (prepare_desired_row): When MODE_LINE_P is zero,
1095 always make sure the marginal areas of the row are in sync with
1096 what the window wants. (Bug#18419)
1097
1098 * data.c (set_internal): Use assq_no_quit, not Fassq, to find an
1099 existing binding of a variable, to avoid silently aborting
1100 commands that use specbind. (Bug#18331)
1101
11022014-09-07 Paul Eggert <eggert@cs.ucla.edu>
1103
1104 Fix bug uncovered by changing alloca to auto buffer (Bug#18410).
1105 * coding.c (growable_destination): New function.
1106 (produce_chars): Use it for sanity checks. Do not fiddle with
1107 dst_end if the source and destination are both nil, as it's
1108 the caller's responsibility to avoid overlap.
1109 * keyboard.c (read_decoded_event_from_main_queue):
1110 The destination must be MAX_MULTIBYTE_LENGTH times the max source
1111 length, not 4 times, to prevent decode_coding_c_string from trying
1112 to reallocate a destination. This removes the need for the FIXME.
1113
1114 * callproc.c (exec_failed) [DOS_NT]: Define a dummy.
1115 All callers simplified. Add a comment about exec_failed, vfork,
1116 and alloca.
1117
1118 Adjust drag-and-drop fix when window is above top (Bug#18303).
1119 * xselect.c (x_fill_property_data): Don't let sign bit of negative
1120 XCDR bleed into XCAR's encoded value. Improve checks for
1121 out-of-range data while we're at it.
1122
11232014-09-07 Jan Djärv <jan.h.d@swipnet.se>
1124
1125 * xselect.c (x_fill_property_data): Handle negative XCDR when data
1126 is CONSP (Bug#18303).
1127
11282014-09-07 Eli Zaretskii <eliz@gnu.org>
1129
1130 * callproc.c (child_setup) [WINDOWSNT]: Don't call exec_failed if
1131 'alloca' gets passed arguments larger than MAX_ALLOCA.
1132
1133 * font.c (MAX): Define if not defined elsewhere.
1134
11352014-09-07 Paul Eggert <eggert@cs.ucla.edu>
1136
1137 * keyboard.c (read_decoded_event_from_main_queue): Reinstitute alloca
1138 here for destination buffer, to work around what appears to be a
1139 bug in decode_coding_c_string when the source and destination are
1140 both C strings.
1141
1142 Use SAFE_ALLOCA etc. to avoid unbounded stack allocation (Bug#18410).
1143 This follows up on the recent thread in emacs-devel on alloca; see:
1144 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00042.html
1145 This patch also cleans up alloca-related glitches noted while
1146 examining the code looking for unbounded alloca.
1147 * alloc.c (listn):
1148 * callproc.c (init_callproc):
1149 Rewrite to avoid need for alloca.
1150 * buffer.c (mouse_face_overlay_overlaps)
1151 (report_overlay_modification):
1152 * buffer.h (GET_OVERLAYS_AT):
1153 * coding.c (make_subsidiaries):
1154 * doc.c (Fsnarf_documentation):
1155 * editfns.c (Fuser_full_name):
1156 * fileio.c (Ffile_name_directory, Fexpand_file_name)
1157 (search_embedded_absfilename, Fsubstitute_in_file_name):
1158 * fns.c (Fmake_hash_table):
1159 * font.c (font_vconcat_entity_vectors, font_update_drivers):
1160 * fontset.c (fontset_pattern_regexp, Ffontset_info):
1161 * frame.c (Fmake_terminal_frame, x_set_frame_parameters)
1162 (xrdb_get_resource, x_get_resource_string):
1163 * ftfont.c (ftfont_get_charset, ftfont_check_otf, ftfont_drive_otf):
1164 * ftxfont.c (ftxfont_draw):
1165 * image.c (xbm_load, xpm_load, jpeg_load_body):
1166 * keyboard.c (echo_add_key, menu_bar_items, tool_bar_items)
1167
1168 * keymap.c (Fdescribe_buffer_bindings, describe_map):
1169 * lread.c (openp):
1170 * menu.c (digest_single_submenu, find_and_call_menu_selection)
1171 (find_and_return_menu_selection):
1172 * print.c (PRINTFINISH):
1173 * process.c (Fformat_network_address):
1174 * scroll.c (do_scrolling, do_direct_scrolling, scrolling_1):
1175 * search.c (search_buffer, Fmatch_data, Fregexp_quote):
1176 * sound.c (wav_play, au_play):
1177 * syntax.c (skip_chars):
1178 * term.c (tty_menu_activate, tty_menu_show):
1179 * textprop.c (get_char_property_and_overlay):
1180 * window.c (Fset_window_configuration):
1181 * xdisp.c (safe__call, next_overlay_change, vmessage)
1182 (compute_overhangs_and_x, draw_glyphs, note_mouse_highlight):
1183 * xfaces.c (face_at_buffer_position):
1184 * xmenu.c (x_menu_show):
1185 Use SAFE_ALLOCA etc. instead of plain alloca, since the
1186 allocation size isn't bounded.
1187 * callint.c (Fcall_interactively): Redo memory_full check
1188 so that it can be done at compile-time on some platforms.
1189 * coding.c (MAX_LOOKUP_MAX): New constant.
1190 (get_translation_table): Use it.
1191 * callproc.c (call_process): Use SAFE_NALLOCA instead of
1192 SAFE_ALLOCA, to catch integer overflows on size calculation.
1193 (exec_failed) [!DOS_NT]: New function.
1194 (child_setup) [!DOS_NT]: Use it.
1195 * editfns.c (Ftranspose_regions):
1196 Hoist USE_SAFE_ALLOC + SAFE_FREE out of 'if'.
1197 * editfns.c (check_translation):
1198 Allocate larger buffers on the heap.
1199 * eval.c (internal_lisp_condition_case):
1200 Check for MAX_ALLOCA overflow.
1201 * fns.c (sort_vector): Use SAFE_ALLOCA_LISP rather than Fmake_vector.
1202 (Fbase64_encode_region, Fbase64_decode_region):
1203 Avoid unnecessary calls to SAFE_FREE before 'error'.
1204 * buffer.c (mouse_face_overlay_overlaps):
1205 * editfns.c (Fget_pos_property, check_translation):
1206 * eval.c (Ffuncall):
1207 * font.c (font_unparse_xlfd, font_find_for_lface):
1208 * ftfont.c (ftfont_drive_otf):
1209 * keyboard.c (echo_add_key, read_decoded_event_from_main_queue)
1210 (menu_bar_items, tool_bar_items):
1211 * sound.c (Fplay_sound_internal):
1212 * xdisp.c (load_overlay_strings, dump_glyph_row):
1213 Use an ordinary auto buffer rather than alloca, since the
1214 allocation size is fixed and small.
1215 * ftfont.c: Include <c-strcase.h>.
1216 (matching_prefix): New function.
1217 (get_adstyle_property): Use it, to avoid need for alloca.
1218 * keyboard.c (echo_add_key):
1219 * keymap.c (describe_map): Use ptrdiff_t, not int.
1220 * keyboard.c (echo_add_key): Prefer sizeof to strlen.
1221 * keymap.c (Fdescribe_buffer_bindings): Use SBYTES, not SCHARS,
1222 when counting bytes.
1223 * lisp.h (xlispstrdupa): Remove, replacing with ...
1224 (SAFE_ALLOCA_STRING): ... new macro with different API.
1225 This fixes a portability problem, namely, alloca result
1226 passed to another function. All uses changed.
1227 (SAFE_ALLOCA, SAFE_ALLOCA_LISP): Check for MAX_ALLOCA,
1228 not MAX_ALLOCA - 1.
1229 * regex.c (REGEX_USE_SAFE_ALLOCA, REGEX_SAFE_FREE)
1230 (REGEX_ALLOCATE): New macros.
1231 (REGEX_REALLOCATE, REGEX_ALLOCATE_STACK, REGEX_REALLOCATE_STACK)
1232 (REGEX_FREE_STACK, FREE_VARIABLES, re_match_2_internal):
1233 Use them.
1234 * xdisp.c (message3): Use SAFE_ALLOCA_STRING rather than doing it
1235 by hand.
1236 (decode_mode_spec_coding): Store directly into buf rather than
1237 into an alloca temporary and copying the temporary to the buf.
1238
12392014-09-06 Eli Zaretskii <eliz@gnu.org>
1240
1241 * Makefile.in (EMACS_HEAPSIZE): Remove, no longer used. (Bug#18416)
1242
12432014-09-04 Jan D <jan.h.d@swipnet.se>
1244
1245 * xterm.c (x_term_init): Don't call x_session_initialize if running
1246 as a daemon (Bug#18375).
1247
1248 * xsmfns.c: Initialize ice_fd.
1249
12502014-09-04 Paul Eggert <eggert@cs.ucla.edu>
1251
1252 Less chatter in 'make' output.
1253 * Makefile.in (AM_V_GEN, am__v_GEN_, am__v_GEN_0, am__v_GEN_1, AM_V_at)
1254 (am__v_at_, am__v_at_0, am__v_at_1): New macros, taken from Automake.
1255 ($(etc)/DOC, buildobj.h, gl-stamp): Use them.
1256
12572014-09-03 Martin Rudalics <rudalics@gmx.at>
1258
1259 * buffer.c (scroll-bar-height): Fix typo in doc-string.
1260 * frame.c (Vdefault_frame_horizontal_scroll_bars):
1261 Remove variable.
1262 * nsfns.m (Fx_create_frame):
1263 * w32fns.c (Fx_create_frame):
1264 * xfns.c (Fx_create_frame): Default horizontal scroll bars to
1265 nil.
1266
12672014-09-03 Eli Zaretskii <eliz@gnu.org>
1268
1269 * dispnew.c (buffer_posn_from_coords): Fix an off-by-one error in
1270 the reported row in the case of a window with a header line, by
1271 improving on the fix committed in 2011-10-08T10:58:50Z!eliz@gnu.org
1272 eliz@gnu.org-20111008105850-ht4tvsayohvr1kjc. (Bug#18384)
1273
12742014-09-03 Paul Eggert <eggert@cs.ucla.edu>
1275
1276 * eval.c (internal_lisp_condition_case): Don't overrun the stack
1277 when configured --with-wide-int on typical 32-bit platforms.
1278
12792014-09-03 Eli Zaretskii <eliz@gnu.org>
1280
1281 * xdisp.c (display_and_set_cursor): Call erase_phys_cursor also
1282 when HPOS is negative, for the benefit of R2L glyph rows whose
1283 newline overflows into the fringe.
1284
12852014-09-03 Ken Brown <kbrown@cornell.edu>
1286
1287 * conf_post.h (strnicmp) [CYGWIN && HAVE_NTGUI]: Define. (Bug#18366)
1288
12892014-09-02 Paul Eggert <eggert@cs.ucla.edu>
1290
1291 Minor cleanup of recent strlen-avoiding patch.
1292 * fileio.c (CHECK_LENGTH): Remove.
1293 Rewrite callers so that they don't need it.
1294 (Fexpand_file_name) [DOS_NT]: Fix a case where directory length
1295 variable wasn't set.
1296
12972014-09-02 Dmitry Antipov <dmantipov@yandex.ru>
1298
1299 * fileio.c (CHECK_LENGTH): New macro.
1300 (Fexpand_file_name): Use it and get rid of a few more calls
1301 to strlen and strcat.
1302 * callproc.c (egetenv_internal): Add arg and rename from egetenv ...
1303 * lisp.h (egetenv): ... because of a new inline function used to
1304 avoid calls to strlen for a compile-time constants.
1305
1306 * buffer.h (decode_buffer): New function.
1307 * buffer.c (Fbuffer_name, Fbuffer_file_name, Fbuffer_base_buffer)
1308 (Fbuffer_local_variables, Fbuffer_modified_p, Fbuffer_modified_tick)
1309 (Fbuffer_chars_modified_tick, Fdelete_all_overlays):
1310 * data.c (Flocal_variables_p):
1311 * fileio.c (Fverify_visited_file_modtime):
1312 * marker.c (live_buffer): Use it.
1313
13142014-09-01 Dmitry Antipov <dmantipov@yandex.ru>
1315
1316 Avoid extra calls to strlen in filesystem I/O routines.
1317 * fileio.c (Fexpand_file_name): Avoid calls to strlen if
1318 the length of 'newdir' is known or may be precalculated.
1319 (file_accessible_directory_p): Prefer to pass Lisp_Object,
1320 not 'char *', and so use precalculated length.
1321 (Ffile_accessible_directory_p):
1322 * callproc.c (encode_current_directory, init_callproc):
1323 * charset.c (init_charset):
1324 * lread.c (load_path_check, load_path_default): Adjust users.
1325 * lisp.h (file_accessible_directory_p): Tweak prototype.
1326
13272014-09-01 Eli Zaretskii <eliz@gnu.org>
1328
1329 * w32proc.c (w32_compare_strings): Support "C" and "POSIX"
1330 locales.
1331
13322014-09-01 Paul Eggert <eggert@cs.ucla.edu>
1333
1334 --enable-silent-rules now suppresses more chatter.
1335 * Makefile.in (AM_DEFAULT_VERBOSITY, AM_V_CC, am__v_CC_)
1336 (am__v_CC_0, am__v_CC_1, AM_V_CCLD, am__v_CCLD_, am__v_CCLD_0)
1337 (am__v_CCLD_1): New macros, taken from Automake.
1338 (.c.o, .m.o, temacs$(EXEEXT)): Use them.
1339
1340 Clean up extern decls a bit.
1341 * bytecode.c: Include blockinput.h and keyboard.h rather
1342 than rolling their APIs by hand.
1343 * emacs.c: Include regex.h and rely on its and lisp.h's API
1344 rather than rolling them by hand.
1345 * lastfile.c: Include lisp.h, to check this file's API.
1346 * lisp.h (lisp_eval_depth, my_edata, my_endbss, my_endbss_static):
1347 New decls.
1348 * regex.h (re_max_failures): New decl.
1349 * unexcw.c, unexmacosx.c, unexw32.c:
1350 Rely on lisp.h's API rather than rolling it by hand.
1351 * vm-limit.c (__after_morecore_hook, __morecore, real_morecore):
1352 Declare at top level, to pacify GCC -Wnested-externs.
1353
13542014-08-31 Eli Zaretskii <eliz@gnu.org>
1355
1356 * xdisp.c (get_glyph_string_clip_rects): Don't let the width of a
1357 clipping rectangle become negative (i.e. large positive, since
1358 it's an unsigned data type). This can happen in R2L hscrolled
1359 glyph rows, and caused us to draw the cursor glyph on the fringe.
1360 For the details, see
1361 http://lists.gnu.org/archive/html/emacs-devel/2014-08/msg00543.html.
1362
13632014-08-31 Ken Brown <kbrown@cornell.edu>
1364
1365 * gmalloc.c: Don't include <stdlib.h>. Declare system malloc and
1366 friends before defining hybrid_malloc and friends if HYBRID_MALLOC
1367 is defined. (Bug#18368)
1368
13692014-08-30 Paul Eggert <eggert@cs.ucla.edu>
1370
1371 Vector-sorting fixes (Bug#18361).
1372 It's not safe to call qsort or qsort_r, since they have undefined
1373 behavior if the user-specified predicate is not a total order.
1374 Also, watch out for garbage-collection while sorting vectors.
1375 * fns.c: Include <vla.h>.
1376 (sort_vector_predicate) [!HAVE_QSORT_R]: Remove.
1377 (sort_vector_compare): Remove, replacing with ....
1378 (inorder, merge_vectors, sort_vector_inplace, sort_vector_copy):
1379 ... these new functions.
1380 (sort_vector): Rewrite to use the new functions.
1381 GCPRO locals, since the predicate can invoke the GC.
1382 Since it's in-place return void; caller changed.
1383 (merge): Use 'inorder', for clarity.
1384
1385 * sysdep.c (str_collate): Clear errno just before wcscoll(_l).
1386 One can't hoist this out of the 'if', because intervening calls to
1387 newlocale, twolower, etc. can change errno.
1388
13892014-08-30 Eli Zaretskii <eliz@gnu.org>
1390
1391 * sysdep.c (str_collate) [__STDC_ISO_10646__]: Improve the
1392 wording of the error messages.
1393 (str_collate) [WINDOWSNT]: Signal an error if w32_compare_strings
1394 sets errno.
1395
1396 * w32proc.c (get_lcid_callback): Accept locale specifications
1397 without the country part, as in "enu" vs "enu_USA".
1398 (w32_compare_strings): Signal an error if a locale was specified,
1399 but couldn't be translated into a valid LCID.
1400
14012014-08-29 Michael Albinus <michael.albinus@gmx.de>
1402
1403 * sysdep.c (str_collate) [__STDC_ISO_10646__]: Move up setting errno.
1404
14052014-08-29 Paul Eggert <eggert@cs.ucla.edu>
1406
1407 * sysdep.c (str_collate) [__STDC_ISO_10646__]: Do not look at
1408 errno after towlower_l. errno's value is not specified after
1409 towlower_l. Instead, assume that towlower_l returns its argument
1410 on failure, which is portable in practice.
1411
14122014-08-29 Eli Zaretskii <eliz@gnu.org>
1413
1414 * fns.c (Fstring_collate_lessp, Fstring_collate_equalp): Doc fix.
1415
1416 * w32proc.c (w32_compare_strings): Accept additional argument
1417 IGNORE_CASE. Set up the flags for CompareStringW to ignore case
1418 if requested. If w32-collate-ignore-punctuation is non-nil, add
1419 NORM_IGNORESYMBOLS to the flags.
1420 (LINGUISTIC_IGNORECASE): Define if not already defined.
1421 (syms_of_ntproc) <Vw32_collate_ignore_punctuation>: New variable.
1422
1423 * sysdep.c (str_collate) [WINDOWSNT]: Adapt to the interface
1424 change.
1425
14262014-08-29 Michael Albinus <michael.albinus@gmx.de>
1427
1428 * sysdep.c (LC_CTYPE, LC_CTYPE_MASK, towlower_l):
1429 Define substitutes for platforms that lack them.
1430 (str_collate): Add arguments locale and ignore_case.
1431
1432 * fns.c (Fstring_collate_lessp, Fstring_collate_equalp):
1433 Add optional arguments LOCALE and IGNORE-CASE.
1434
1435 * lisp.h (str_collate): Adapt argument list.
1436
14372014-08-29 Dmitry Antipov <dmantipov@yandex.ru>
1438
1439 Add vectors support to Fsort.
1440 * fns.c (sort_vector, sort_vector_compare): New functions.
1441 (sort_list): Likewise, refactored out of ...
1442 (Fsort): ... adjusted user. Mention vectors in docstring.
1443 (sort_vector_predicate) [!HAVE_QSORT_R]: New variable.
1444 * alloc.c (make_save_int_obj): New function.
1445 * lisp.h (enum Lisp_Save_Type): New member SAVE_TYPE_INT_OBJ.
1446 (make_save_int_obj): Add prototype.
1447
1448 Fix last change to support Darwin/OSX and FreeBSD (Bug#18354).
1449 * sysdep.c (sort_vector_compare) [DARWIN_OS || __FreeBSD__]:
1450 Conditionally define to match system's qsort_r signature.
1451 (sort_vector) [DARWIN_OS || __FreeBSD__]: Likewise in call to qsort_r.
1452
14532014-08-28 Ken Brown <kbrown@cornell.edu>
1454
1455 Add support for HYBRID_MALLOC, allowing the use of gmalloc before
1456 dumping and the system malloc after dumping. (Bug#18222)
1457
1458 * conf_post.h (malloc, realloc, calloc, free) [HYBRID_MALLOC]:
1459 Define as macros, expanding to hybrid_malloc, etc.
1460 (HYBRID_GET_CURRENT_DIR_NAME): New macro.
1461 (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: Define as
1462 macro.
1463 * gmalloc.c: Set up the infrastructure for HYBRID_MALLOC, with a
1464 full implementation on Cygwin. Remove Cygwin-specific code that
1465 is no longer needed.
1466 (malloc, realloc, calloc, free, aligned_alloc) [HYBRID_MALLOC]:
1467 Redefine as macros expanding to gmalloc, grealloc, etc.
1468 (DUMPED, ALLOCATED_BEFORE_DUMPING) [CYGWIN]: New macros.
1469 (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: Undefine.
1470 (USE_PTHREAD, posix_memalign) [HYBRID_MALLOC]: Don't define.
1471 (hybrid_malloc, hybrid_calloc, hybrid_free, hybrid_realloc)
1472 [HYBRID_MALLOC]:
1473 (hybrid_get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]:
1474 (hybrid_aligned_alloc) [HYBRID_MALLOC && (HAVE_ALIGNED_ALLOC ||
1475 HAVE_POSIX_MEMALIGN)]: New functions.
1476 * alloc.c (aligned_alloc) [HYBRID_MALLOC && (ALIGNED_ALLOC ||
1477 HAVE_POSIX_MEMALIGN)]: Define as macro expanding to
1478 hybrid_aligned_alloc; declare.
1479 (USE_ALIGNED_ALLOC) [HYBRID_MALLOC && (ALIGNED_ALLOC ||
1480 HAVE_POSIX_MEMALIGN)]: Define.
1481 (refill_memory_reserve) [HYBRID_MALLOC]: Do nothing.
1482 * sysdep.c (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]:
1483 Define as macro, expanding to gget_current_dir_name, and define
1484 the latter.
1485 * emacs.c (main) [HYBRID_MALLOC]: Don't call memory_warnings() or
1486 malloc_enable_thread(). Don't initialize malloc.
1487 * lisp.h (NONPOINTER_BITS) [CYGWIN]: Define (because GNU_MALLOC is
1488 no longer defined on Cygwin).
1489 (refill_memory_reserve) [HYBRID_MALLOC]: Don't declare.
1490 * sheap.c (bss_sbrk_buffer_end): New variable.
1491 * unexcw.c (__malloc_initialized): Remove variable.
1492 * ralloc.c: Throughout, treat HYBRID_MALLOC the same as
1493 SYSTEM_MALLOC.
1494 * xdisp.c (decode_mode_spec) [HYBRID_MALLOC]: Don't check
1495 Vmemory_full.
1496
14972014-08-28 Martin Rudalics <rudalics@gmx.at>
1498
1499 * w32term.c (w32_horizontal_scroll_bar_handle_click):
1500 In `event->y' return entire range (the size of the scroll bar minus
1501 that of the thumb).
1502 * xterm.c (xm_scroll_callback, xaw_jump_callback): In `whole'
1503 return entire range (the scaled size of the scroll bar minus
1504 that of the slider). In `portion' return the scaled position of
1505 the slider.
1506 (xaw_jump_callback): Restore part of code for vertical scroll
1507 bar broken in change from 2014-07-27.
1508 (xaw_scroll_callback): Provide incremental scrolling with
1509 horizontal scroll bars.
1510
15112014-08-28 Eli Zaretskii <eliz@gnu.org>
1512
1513 * conf_post.h (_GL_EXECINFO_INLINE) [MSDOS]: Don't define.
1514
1515 * indent.c (Fvertical_motion): Fix vertical motion up through a
1516 display property after a newline. (Bug#18276)
1517
1518 * xdisp.c (display_line): Don't assume that the call to
1519 reseat_at_next_visible_line_start ends up at a character
1520 immediately following the newline on the previous line.
1521 Avoids setting the ends_at_zv_p flag on screen lines that are not at or
1522 beyond ZV, which causes infloop in redisplay. For the details, see
1523 http://lists.gnu.org/archive/html/emacs-devel/2014-08/msg00368.html.
1524
1525 * dispnew.c (buffer_posn_from_coords): Fix mirroring of X
1526 coordinate for hscrolled R2L screen lines. (Bug#18277)
1527
15282014-08-28 Paul Eggert <eggert@cs.ucla.edu>
1529
1530 * sysdep.c (LC_COLLATE, LC_COLLATE_MASK): Give individual defaults
1531 (Bug#18051).
1532
15332014-08-27 Eli Zaretskii <eliz@gnu.org>
1534
1535 * syntax.c (scan_lists): Don't examine positions before BEGV.
1536 (Bug#18339)
1537
15382014-08-27 Paul Eggert <eggert@cs.ucla.edu>
1539
1540 Improve robustness of new string-collation code (Bug#18051).
1541 * sysdep.c (LC_COLLATE, LC_COLLATE_MASK, freelocale, locale_t)
1542 (newlocale, wcscoll_l): Define substitutes for platforms that
1543 lack them, so as to simplify the mainline code.
1544 (str_collate): Simplify the code by assuming the above definitions.
1545 Use wcscoll_l, not uselocale, as uselocale is too fragile.
1546 For example, the old version left the Emacs in the wrong locale if
1547 wcscoll reported an error. Use 'int', not ptrdiff_t, for the int
1548 result. Report an error if newlocale fails.
1549
15502014-08-27 Michael Albinus <michael.albinus@gmx.de>
1551
1552 * lisp.h (str_collate):
1553 * sysdep.c (str_collate): Return int.
1554 (str_collate) [__STDC_ISO_10646__]: Propagate error of wcscoll.
1555
15562014-08-27 Dmitry Antipov <dmantipov@yandex.ru>
1557
1558 Fix some glitches in previous change.
1559 * sysdep.c (stack_direction): Replace stack_grows_down
1560 to simplify calculation of stack boundaries.
1561 (handle_sigsegv): Check whether we really crash somewhere near
1562 to stack boundary, and handle fatal signal as usual if not.
1563 (init_sigsegv): Adjust accordingly.
1564 * keyboard.c (Vtop_level_message): Rename to
1565 Vinternal__top_level_message, as suggested by Stefan Monnier in
1566 http://lists.gnu.org/archive/html/emacs-devel/2014-08/msg00493.html
1567 All related users changed.
1568
15692014-08-26 Dmitry Antipov <dmantipov@yandex.ru>
1570
1571 Handle C stack overflow caused by too nested Lisp evaluation.
1572 * lisp.h (toplevel) [HAVE_STACK_OVERFLOW_HANDLING]: Declare
1573 siglongjmp point to transfer control from SIGSEGV handler.
1574 * keyboard.c (return_to_command_loop, recover_top_level_message)
1575 [HAVE_STACK_OVERFLOW_HANDLING]: New variables.
1576 (regular_top_level_message): New variable.
1577 (command_loop) [HAVE_STACK_OVERFLOW_HANDLING]: Handle non-local
1578 exit from SIGSEGV handler and adjust message displayed by Vtop_level
1579 if appropriate.
1580 (syms_of_keyboard): DEFVAR Vtop_level_message and initialize
1581 new variables described above.
1582 * sysdep.c [HAVE_SYS_RESOURCE_H]: Include sys/resource.h as such.
1583 (stack_grows_down, sigsegv_stack, handle_sigsegv)
1584 [HAVE_STACK_OVERFLOW_HANDLING]: New variables and function.
1585 (init_sigsegv): New function.
1586 (init_signals): Use it.
1587
15882014-08-25 Ken Brown <kbrown@cornell.edu>
1589
1590 * emacs.c (main): Remove use of obsolete macro
1591 G_SLICE_ALWAYS_MALLOC.
1592
15932014-08-25 Eli Zaretskii <eliz@gnu.org>
1594
1595 Implement locale-sensitive string collation for MS-Windows.
1596 * w32proc.c (get_lcid_callback, get_lcid, w32_compare_strings):
1597 New functions. (Bug#18051)
1598
1599 * w32.h (w32_compare_strings): Add prototype.
1600
1601 * w32.c <g_b_init_compare_string_w>: New global flag.
1602 (globals_of_w32): Initialize it.
1603
1604 * sysdep.c (str_collate) [WINDOWSNT]: Implementation for MS-Windows.
1605
1606 * fns.c (Fstring_collate_lessp, Fstring_collate_equalp)
1607 [WINDOWSNT]: Call str_collate on MS-Windows.
1608
16092014-08-25 Dmitry Antipov <dmantipov@yandex.ru>
1610
1611 One more minor cleanup of font subsystem.
1612 * font.h (struct font_driver): Convert text_extents to
1613 return void because returned value is never actually used.
1614 * macfont.m (macfont_text_extents):
1615 * w32font.c (w32font_text_extents):
1616 * xftfont.c (xftfont_text_extents): Adjust to return void
1617 and assume that 'metrics' argument is always non-NULL.
1618 * ftfont.c (ftfont_text_extents):
1619 * xfont.c (xfont_text_extents): Likewise. Avoid redundant memset.
1620
16212014-08-25 Paul Eggert <eggert@cs.ucla.edu>
1622
1623 Minor cleanups of str_collate fix (Bug#18051).
1624 * fns.c (str_collate): Move decl from here ...
1625 * lisp.h (str_collate): ... to here.
1626 * sysdep.c (str_collate): Prune away some of the forest of ifdefs.
1627 Remove unnecessary casts. Use SAFE_NALLOCA to avoid
1628 potential problems with integer overflow. Don't assume
1629 setlocale succeeds. Remove unnecessary test before restoring
1630 locale via setlocale, and free the copied setlocale string
1631 when done with it.
1632
16332014-08-24 Michael Albinus <michael.albinus@gmx.de>
1634
1635 * fns.c (Fstring_collate_lessp, Fstring_collate_equalp): New DEFUNs.
1636
1637 * sysdep.c (str_collate): New function. (Bug#18051)
1638
16392014-08-23 Karol Ostrovsky <karol.ostrovsky@gmail.com> (tiny change)
1640
1641 * Makefile.in (emacs$(EXEEXT)): Retry deletion of bootstrap-emacs
1642 if the initial "rm -f" fails. This is for MinGW builds, where
1643 MS-Windows will not allow deleting the executable file of a
1644 running program.
1645
12014-08-20 Eli Zaretskii <eliz@gnu.org> 16462014-08-20 Eli Zaretskii <eliz@gnu.org>
2 1647
3 * w32term.c (w32_scroll_bar_handle_click) 1648 * w32term.c (w32_scroll_bar_handle_click)
@@ -117,8 +1762,8 @@
117 * term.c (OUTPUT, tty_set_terminal_modes) 1762 * term.c (OUTPUT, tty_set_terminal_modes)
118 (tty_set_terminal_window, tty_set_scroll_region) 1763 (tty_set_terminal_window, tty_set_scroll_region)
119 (tty_clear_to_end, tty_write_glyphs, tty_write_glyphs_with_face) 1764 (tty_clear_to_end, tty_write_glyphs, tty_write_glyphs_with_face)
120 (tty_ins_del_lines, tty_menu_display, tty_menu_activate): Use 1765 (tty_ins_del_lines, tty_menu_display, tty_menu_activate):
121 FRAME_TOTAL_LINES instead of FRAME_LINES. 1766 Use FRAME_TOTAL_LINES instead of FRAME_LINES.
122 (Fresume_tty): Use FRAME_TOTAL_LINES instead of FRAME_LINES. 1767 (Fresume_tty): Use FRAME_TOTAL_LINES instead of FRAME_LINES.
123 Call change_frame_size with frame's menu bar lines subtracted 1768 Call change_frame_size with frame's menu bar lines subtracted
124 from height. 1769 from height.
@@ -129,9 +1774,10 @@
1292014-08-09 Reuben Thomas <rrt@sc3d.org> 17742014-08-09 Reuben Thomas <rrt@sc3d.org>
130 1775
131 * alloc.c (Fmemory_info): Remove a stray brace. 1776 * alloc.c (Fmemory_info): Remove a stray brace.
1777
132 * process.c: Fix a comment typo. 1778 * process.c: Fix a comment typo.
133 * msdos.c: 1779
134 * dosfns.c (init_dosfns): Remove support for DJGPP < 2.02. 1780 * msdos.c, dosfns.c (init_dosfns): Remove support for DJGPP < 2.02.
135 1781
1362014-08-09 Jan Djärv <jan.h.d@swipnet.se> 17822014-08-09 Jan Djärv <jan.h.d@swipnet.se>
137 1783
@@ -168,14 +1814,14 @@
168 1814
1692014-08-04 Martin Rudalics <rudalics@gmx.at> 18152014-08-04 Martin Rudalics <rudalics@gmx.at>
170 1816
171 * frame.h (FRAME_HAS_HORIZONTAL_SCROLL_BARS): Condition 1817 * frame.h (FRAME_HAS_HORIZONTAL_SCROLL_BARS):
172 correctly according to toolkit used. 1818 Condition correctly according to toolkit used.
173 * frame.c (make_initial_frame, make_terminal_frame) 1819 * frame.c (make_initial_frame, make_terminal_frame)
174 (x_set_horizontal_scroll_bars, x_set_scroll_bar_height) 1820 (x_set_horizontal_scroll_bars, x_set_scroll_bar_height)
175 (Vdefault_frame_horizontal_scroll_bars): Correctly condition 1821 (Vdefault_frame_horizontal_scroll_bars): Correctly condition
176 assignments according to presence of toolkit scrollbars. 1822 assignments according to presence of toolkit scrollbars.
177 * window.h (WINDOW_HAS_HORIZONTAL_SCROLL_BAR): Condition 1823 * window.h (WINDOW_HAS_HORIZONTAL_SCROLL_BAR):
178 correctly according to toolkit used. 1824 Condition correctly according to toolkit used.
179 * window.c (set_window_scroll_bars): Set horizontal scroll bar 1825 * window.c (set_window_scroll_bars): Set horizontal scroll bar
180 only if toolkit supports it. 1826 only if toolkit supports it.
181 * w32term.c (w32_redeem_scroll_bar): Always redeem scroll bar if 1827 * w32term.c (w32_redeem_scroll_bar): Always redeem scroll bar if
@@ -431,15 +2077,15 @@
431 (x_set_scroll_bar_height): Add external declarations. 2077 (x_set_scroll_bar_height): Add external declarations.
432 * frame.c: (frame_inhibit_resize, frame_windows_min_size) 2078 * frame.c: (frame_inhibit_resize, frame_windows_min_size)
433 (adjust_frame_size): New functions. 2079 (adjust_frame_size): New functions.
434 (make_frame): Initial horizontal_scroll_bars field. Use 2080 (make_frame): Initial horizontal_scroll_bars field.
435 SET_FRAME_LINES. Don't allow horizontal scroll bar in 2081 Use SET_FRAME_LINES. Don't allow horizontal scroll bar in
436 minibuffer window. 2082 minibuffer window.
437 (make_initial_frame, make_terminal_frame): No horizontal scroll 2083 (make_initial_frame, make_terminal_frame): No horizontal scroll
438 bar in initial and terminal frames. Use adjust_frame_size. 2084 bar in initial and terminal frames. Use adjust_frame_size.
439 (Fframe_total_cols): Fix doc-string. 2085 (Fframe_total_cols): Fix doc-string.
440 (Fframe_total_lines, Fscroll_bar_height): New Lisp functions. 2086 (Fframe_total_lines, Fscroll_bar_height): New Lisp functions.
441 (Fset_frame_height, Fset_frame_width, Fset_frame_size): Rewrite 2087 (Fset_frame_height, Fset_frame_width, Fset_frame_size):
442 using adjust_frame_size. 2088 Rewrite using adjust_frame_size.
443 (Qscroll_bar_height, Qhorizontal_scroll_bars) 2089 (Qscroll_bar_height, Qhorizontal_scroll_bars)
444 (Qframe_windows_min_size): New symbols. 2090 (Qframe_windows_min_size): New symbols.
445 (x_set_frame_parameters): Remove call of check_frame_size. 2091 (x_set_frame_parameters): Remove call of check_frame_size.
@@ -450,8 +2096,8 @@
450 (x_set_internal_border_width, x_set_vertical_scroll_bars) 2096 (x_set_internal_border_width, x_set_vertical_scroll_bars)
451 (x_set_scroll_bar_width, x_set_right_divider_width) 2097 (x_set_scroll_bar_width, x_set_right_divider_width)
452 (x_set_bottom_divider_width): Rewrite using adjust_frame_size. 2098 (x_set_bottom_divider_width): Rewrite using adjust_frame_size.
453 (x_set_horizontal_scroll_bars, x_set_scroll_bar_height): New 2099 (x_set_horizontal_scroll_bars, x_set_scroll_bar_height):
454 functions. 2100 New functions.
455 (x_figure_window_size): Rewrite to make frame display the 2101 (x_figure_window_size): Rewrite to make frame display the
456 expected number of lines. 2102 expected number of lines.
457 (Vdefault_frame_scroll_bars): Rewrite doc-string. 2103 (Vdefault_frame_scroll_bars): Rewrite doc-string.
@@ -498,8 +2144,8 @@
498 compute_fringe_widths. 2144 compute_fringe_widths.
499 * term.c (Fresume_tty): When changing the size of a tty frame do 2145 * term.c (Fresume_tty): When changing the size of a tty frame do
500 not pass height of menu bar. 2146 not pass height of menu bar.
501 (clear_tty_hooks, set_tty_hooks): Clear 2147 (clear_tty_hooks, set_tty_hooks):
502 horizontal_scroll_bar_hook. 2148 Clear horizontal_scroll_bar_hook.
503 (init_tty): Frame has no horizontal scroll bars. 2149 (init_tty): Frame has no horizontal scroll bars.
504 * termhooks.h (enum scroll_bar_part): Add scroll_bar_move_ratio, 2150 * termhooks.h (enum scroll_bar_part): Add scroll_bar_move_ratio,
505 scroll_bar_before_handle, scroll_bar_horizontal_handle, 2151 scroll_bar_before_handle, scroll_bar_horizontal_handle,
@@ -508,25 +2154,25 @@
508 scroll_bar_to_rightmost entries. 2154 scroll_bar_to_rightmost entries.
509 (enum event_kind): Add HORIZONTAL_SCROLL_BAR_CLICK_EVENT 2155 (enum event_kind): Add HORIZONTAL_SCROLL_BAR_CLICK_EVENT
510 (struct terminal): Add set_horizontal_scroll_bar_hook. 2156 (struct terminal): Add set_horizontal_scroll_bar_hook.
511 * w32console.c (initialize_w32_display): Clear 2157 * w32console.c (initialize_w32_display):
512 horizontal_scroll_bar_hook. 2158 Clear horizontal_scroll_bar_hook.
513 * w32fns.c (x_set_mouse_color): Use FRAME_W32_DISPLAY instead of 2159 * w32fns.c (x_set_mouse_color): Use FRAME_W32_DISPLAY instead of
514 FRAME_X_DISPLAY. 2160 FRAME_X_DISPLAY.
515 (x_clear_under_internal_border, x_set_internal_border_width): 2161 (x_clear_under_internal_border, x_set_internal_border_width):
516 New functions. 2162 New functions.
517 (x_set_menu_bar_lines): Rewrite using frame_inhibit_resize. Set 2163 (x_set_menu_bar_lines): Rewrite using frame_inhibit_resize.
518 windows_or_buffers_changed when adding the menu bar. 2164 Set windows_or_buffers_changed when adding the menu bar.
519 (x_set_tool_bar_lines): Rewrite using adjust_frame_size. 2165 (x_set_tool_bar_lines): Rewrite using adjust_frame_size.
520 (x_change_tool_bar_height, x_set_scroll_bar_default_height) 2166 (x_change_tool_bar_height, x_set_scroll_bar_default_height)
521 (w32_createhscrollbar): New functions. 2167 (w32_createhscrollbar): New functions.
522 (w32_createscrollbar): Rename to w32_createvscrollbar. 2168 (w32_createscrollbar): Rename to w32_createvscrollbar.
523 (w32_createwindow): Init WND_HSCROLLBAR_INDEX. 2169 (w32_createwindow): Init WND_HSCROLLBAR_INDEX.
524 (w32_name_of_message): Replace WM_EMACS_CREATESCROLLBAR by 2170 (w32_name_of_message): Replace WM_EMACS_CREATESCROLLBAR by
525 WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR. Add 2171 WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR.
526 WM_EMACS_SHOWCURSOR. 2172 Add WM_EMACS_SHOWCURSOR.
527 (w32_wnd_proc): Handle WM_HSCROLL case. In WM_WINDOWPOSCHANGING 2173 (w32_wnd_proc): Handle WM_HSCROLL case. In WM_WINDOWPOSCHANGING
528 case do not artificially impose WM size hints. Handle 2174 case do not artificially impose WM size hints.
529 WM_EMACS_SHOWCURSOR case. Replace WM_EMACS_CREATESCROLLBAR case 2175 Handle WM_EMACS_SHOWCURSOR case. Replace WM_EMACS_CREATESCROLLBAR case
530 by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR 2176 by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR
531 cases. 2177 cases.
532 (my_create_tip_window): Replace WND_SCROLLBAR_INDEX by 2178 (my_create_tip_window): Replace WND_SCROLLBAR_INDEX by
@@ -545,8 +2191,8 @@
545 pass height of menu bar to change_frame_size. 2191 pass height of menu bar to change_frame_size.
546 * w32menu.c (set_frame_menubar): Rewrite using 2192 * w32menu.c (set_frame_menubar): Rewrite using
547 frame_inhibit_resize. 2193 frame_inhibit_resize.
548 * w32term.h (struct w32_display_info): Add 2194 * w32term.h (struct w32_display_info):
549 horizontal_scroll_bar_cursor and cursor_display_counter. 2195 Add horizontal_scroll_bar_cursor and cursor_display_counter.
550 (struct scroll_bar): Add horizontal. 2196 (struct scroll_bar): Add horizontal.
551 (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT) 2197 (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
552 (HORIZONTAL_SCROLL_BAR_LEFT_RANGE) 2198 (HORIZONTAL_SCROLL_BAR_LEFT_RANGE)
@@ -556,8 +2202,8 @@
556 (HORIZONTAL_SCROLL_BAR_TOP_BORDER) 2202 (HORIZONTAL_SCROLL_BAR_TOP_BORDER)
557 (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER) 2203 (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
558 (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): New macros. 2204 (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): New macros.
559 (WM_EMACS_CREATEVSCROLLBAR, WM_EMACS_CREATEHSCROLLBAR): Define 2205 (WM_EMACS_CREATEVSCROLLBAR, WM_EMACS_CREATEHSCROLLBAR):
560 instead of WM_EMACS_CREATESCROLLBAR. 2206 Define instead of WM_EMACS_CREATESCROLLBAR.
561 (WND_VSCROLLBAR_INDEX, WND_HSCROLLBAR_INDEX): Define instead of 2207 (WND_VSCROLLBAR_INDEX, WND_HSCROLLBAR_INDEX): Define instead of
562 WND_SCROLLBAR_INDEX. 2208 WND_SCROLLBAR_INDEX.
563 * w32term.c (horizontal_scroll_bar_min_handle) 2209 * w32term.c (horizontal_scroll_bar_min_handle)
@@ -576,18 +2222,18 @@
576 scrollbar cases. 2222 scrollbar cases.
577 (my_create_scrollbar): Replace with two new functions 2223 (my_create_scrollbar): Replace with two new functions
578 my_create_vscrollbar and my_create_hscrollbar. 2224 my_create_vscrollbar and my_create_hscrollbar.
579 (x_scroll_bar_create): New argument "horizontal". Update 2225 (x_scroll_bar_create): New argument "horizontal".
580 callers accordingly. 2226 Update callers accordingly.
581 (x_scroll_bar_remove, w32_condemn_scroll_bars) 2227 (x_scroll_bar_remove, w32_condemn_scroll_bars)
582 (w32_redeem_scroll_bar, x_scroll_bar_clear): Handle horizontal 2228 (w32_redeem_scroll_bar, x_scroll_bar_clear): Handle horizontal
583 scroll bar case. 2229 scroll bar case.
584 (w32_read_socket): Handle WM_HSCROLL cae. 2230 (w32_read_socket): Handle WM_HSCROLL cae.
585 (x_new_font): Don't recompute fringe widths. Use 2231 (x_new_font): Don't recompute fringe widths.
586 frame_inhibit_resize. Calculate new menu bar height iff we 2232 Use frame_inhibit_resize. Calculate new menu bar height iff we
587 build without toolkit. Always clear under internal border. 2233 build without toolkit. Always clear under internal border.
588 (x_set_window_size): Don't check frame size or recompute 2234 (x_set_window_size): Don't check frame size or recompute
589 fringes. Reset fullscreen status before applying sizes. Always 2235 fringes. Reset fullscreen status before applying sizes.
590 resize as requested by pixelwise argument. Don't call 2236 Always resize as requested by pixelwise argument. Don't call
591 do_pending_window_change. 2237 do_pending_window_change.
592 (x_wm_set_size_hint): Add call for FRAME_SCROLL_BAR_AREA_HEIGHT. 2238 (x_wm_set_size_hint): Add call for FRAME_SCROLL_BAR_AREA_HEIGHT.
593 (w32_initialize_display_info): Initialize dpyinfo's 2239 (w32_initialize_display_info): Initialize dpyinfo's
@@ -613,8 +2259,8 @@
613 (WINDOW_TOPMOST_P, WINDOW_HAS_HORIZONTAL_SCROLL_BAR) 2259 (WINDOW_TOPMOST_P, WINDOW_HAS_HORIZONTAL_SCROLL_BAR)
614 (WINDOW_CONFIG_SCROLL_BAR_HEIGHT) 2260 (WINDOW_CONFIG_SCROLL_BAR_HEIGHT)
615 (WINDOW_CONFIG_SCROLL_BAR_LINES) 2261 (WINDOW_CONFIG_SCROLL_BAR_LINES)
616 (WINDOW_SCROLL_BAR_LINES, WINDOW_SCROLL_BAR_AREA_HEIGHT): New 2262 (WINDOW_SCROLL_BAR_LINES, WINDOW_SCROLL_BAR_AREA_HEIGHT):
617 macros. 2263 New macros.
618 (WINDOW_LEFT_FRINGE_COLS, WINDOW_RIGHT_FRINGE_COLS) 2264 (WINDOW_LEFT_FRINGE_COLS, WINDOW_RIGHT_FRINGE_COLS)
619 (WINDOW_FRINGE_COLS, WINDOW_FRINGE_EXTENDED_P): Remove macros. 2265 (WINDOW_FRINGE_COLS, WINDOW_FRINGE_EXTENDED_P): Remove macros.
620 (WINDOW_VERTICAL_SCROLL_BAR_TYPE) 2266 (WINDOW_VERTICAL_SCROLL_BAR_TYPE)
@@ -627,11 +2273,11 @@
627 (Fwindow_old_point, sanitize_window_sizes): New functions. 2273 (Fwindow_old_point, sanitize_window_sizes): New functions.
628 (Qwindow_sanitize_window_sizes): New symbol. 2274 (Qwindow_sanitize_window_sizes): New symbol.
629 (window_body_height): Count in horizontal scroll bar. 2275 (window_body_height): Count in horizontal scroll bar.
630 (set_window_hscroll, Fscroll_left, Fscroll_right): Set 2276 (set_window_hscroll, Fscroll_left, Fscroll_right):
631 suspend_auto_hscroll slot. 2277 Set suspend_auto_hscroll slot.
632 (Fwindow_inside_edges): Count fringes pixelwise. 2278 (Fwindow_inside_edges): Count fringes pixelwise.
633 (coordinates_in_window, Fcoordinates_in_window_p): Consider 2279 (coordinates_in_window, Fcoordinates_in_window_p):
634 horizontal scroll bar. 2280 Consider horizontal scroll bar.
635 (check_frame_size, adjust_window_margins): Remove functions and 2281 (check_frame_size, adjust_window_margins): Remove functions and
636 corresponding calls. 2282 corresponding calls.
637 (set_window_buffer): Initialize old_pointm and horizontal scroll 2283 (set_window_buffer): Initialize old_pointm and horizontal scroll
@@ -647,8 +2293,8 @@
647 (Fsplit_window_internal): Inherit horizontal scroll bar type and 2293 (Fsplit_window_internal): Inherit horizontal scroll bar type and
648 height. 2294 height.
649 (Fdelete_window_internal): Unchain old_pointm marker. 2295 (Fdelete_window_internal): Unchain old_pointm marker.
650 (window_scroll_pixel_based, Fscroll_other_window): Adjust 2296 (window_scroll_pixel_based, Fscroll_other_window):
651 old_pointm. 2297 Adjust old_pointm.
652 (Fwindow_text_width, Fwindow_text_height): New argument 2298 (Fwindow_text_width, Fwindow_text_height): New argument
653 "pixelwise". 2299 "pixelwise".
654 (struct saved_window): New fields, old_pointm, hscroll_whole, 2300 (struct saved_window): New fields, old_pointm, hscroll_whole,
@@ -703,10 +2349,10 @@
703 (x_frame_parm_handlers): Add x_set_scroll_bar_height, 2349 (x_frame_parm_handlers): Add x_set_scroll_bar_height,
704 x_set_horizontal_scroll_bars, x_set_left_fringe, 2350 x_set_horizontal_scroll_bars, x_set_left_fringe,
705 x_set_right_fringe. 2351 x_set_right_fringe.
706 * xmenu.c (update_frame_menubar, free_frame_menubar): Use 2352 * xmenu.c (update_frame_menubar, free_frame_menubar):
707 adjust_frame_size. 2353 Use adjust_frame_size.
708 * xterm.h (struct x_display_info): Add 2354 * xterm.h (struct x_display_info):
709 horizontal_scroll_bar_cursor and Xatom_Horizontal_Scrollbar 2355 Add horizontal_scroll_bar_cursor and Xatom_Horizontal_Scrollbar
710 slots. 2356 slots.
711 (struct scroll_bar): Add horizontal slot. 2357 (struct scroll_bar): Add horizontal slot.
712 (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT) 2358 (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
@@ -729,15 +2375,15 @@
729 (x_set_toolkit_horizontal_scroll_bar_thumb) 2375 (x_set_toolkit_horizontal_scroll_bar_thumb)
730 (XTset_horizontal_scroll_bar, x_net_wm_state) 2376 (XTset_horizontal_scroll_bar, x_net_wm_state)
731 (x_horizontal_scroll_bar_report_motion): New functions. 2377 (x_horizontal_scroll_bar_report_motion): New functions.
732 (xg_scroll_callback, x_scroll_bar_handle_click): Handle 2378 (xg_scroll_callback, x_scroll_bar_handle_click):
733 horizontal scroll bars. 2379 Handle horizontal scroll bars.
734 (SCROLL_BAR_HORIZONTAL_NAME): Define. 2380 (SCROLL_BAR_HORIZONTAL_NAME): Define.
735 (XTset_vertical_scroll_bar): Attempt to clear areas not covered 2381 (XTset_vertical_scroll_bar): Attempt to clear areas not covered
736 by scroll bar. 2382 by scroll bar.
737 (XTcondemn_scroll_bars, XTredeem_scroll_bar): Rewrite. Handle 2383 (XTcondemn_scroll_bars, XTredeem_scroll_bar): Rewrite.
738 horizontal scroll bars. 2384 Handle horizontal scroll bars.
739 (handle_one_xevent): Handle horizontal scroll bar events. Call 2385 (handle_one_xevent): Handle horizontal scroll bar events.
740 x_net_wm_state. 2386 Call x_net_wm_state.
741 (x_set_window_size_1, x_wm_set_size_hint): Don't call 2387 (x_set_window_size_1, x_wm_set_size_hint): Don't call
742 check_frame_size. 2388 check_frame_size.
743 (x_set_window_size): Don't call check_frame_size and 2389 (x_set_window_size): Don't call check_frame_size and
@@ -787,8 +2433,8 @@
787 2433
7882014-07-25 Eli Zaretskii <eliz@gnu.org> 24342014-07-25 Eli Zaretskii <eliz@gnu.org>
789 2435
790 * w32term.h (current_popup_menu, menubar_in_use): Move 2436 * w32term.h (current_popup_menu, menubar_in_use):
791 declarations from w32term.c. 2437 Move declarations from w32term.c.
792 2438
7932014-07-25 Martin Rudalics <rudalics@gmx.at> 24392014-07-25 Martin Rudalics <rudalics@gmx.at>
794 2440
@@ -842,8 +2488,8 @@
842 * xterm.c (handle_one_xevent): 2488 * xterm.c (handle_one_xevent):
843 * gtkutil.c (xg_event_is_for_menubar): 2489 * gtkutil.c (xg_event_is_for_menubar):
844 * xfns.c (x_window) [USE_X_TOOLKIT]: 2490 * xfns.c (x_window) [USE_X_TOOLKIT]:
845 * xmenu.c (set_frame_menubar, free_frame_menubar): Prefer 2491 * xmenu.c (set_frame_menubar, free_frame_menubar):
846 to use FRAME_MENUBAR_HEIGHT. 2492 Prefer to use FRAME_MENUBAR_HEIGHT.
847 2493
8482014-07-21 Dmitry Antipov <dmantipov@yandex.ru> 24942014-07-21 Dmitry Antipov <dmantipov@yandex.ru>
849 2495
@@ -864,12 +2510,12 @@
864 2510
8652014-07-21 Eli Zaretskii <eliz@gnu.org> 25112014-07-21 Eli Zaretskii <eliz@gnu.org>
866 2512
867 * w32select.c (setup_windows_coding_system): Apply 2513 * w32select.c (setup_windows_coding_system):
868 CODING_ANNOTATION_MASK to the common_flags member of struct 2514 Apply CODING_ANNOTATION_MASK to the common_flags member of struct
869 coding_system. Reported by martin rudalics <rudalics@gmx.at>. 2515 coding_system. Reported by martin rudalics <rudalics@gmx.at>.
870 2516
871 * w16select.c (Fw16_get_clipboard_data): Apply 2517 * w16select.c (Fw16_get_clipboard_data):
872 CODING_ANNOTATION_MASK to the common_flags member of struct 2518 Apply CODING_ANNOTATION_MASK to the common_flags member of struct
873 coding_system. 2519 coding_system.
874 2520
875 * xdisp.c (init_iterator): Initialize it->stop_charpos to the 2521 * xdisp.c (init_iterator): Initialize it->stop_charpos to the
@@ -877,8 +2523,8 @@
877 (handle_invisible_prop): Record in it->stop_charpos the position 2523 (handle_invisible_prop): Record in it->stop_charpos the position
878 where the invisible text ends. (Bug#18035) 2524 where the invisible text ends. (Bug#18035)
879 (hscroll_window_tree): Don't try hscrolling windows whose cursor 2525 (hscroll_window_tree): Don't try hscrolling windows whose cursor
880 row has zero buffer position as their start position. Reported by 2526 row has zero buffer position as their start position.
881 martin rudalics <rudalics@gmx.at>. 2527 Reported by martin rudalics <rudalics@gmx.at>.
882 2528
883 * xdisp.c (move_it_vertically_backward, move_it_by_lines): Prevent 2529 * xdisp.c (move_it_vertically_backward, move_it_by_lines): Prevent
884 infinite looping in redisplay when display lines don't have enough 2530 infinite looping in redisplay when display lines don't have enough
@@ -1318,8 +2964,8 @@
1318 are in sync with what the window wants. 2964 are in sync with what the window wants.
1319 (Bug#17892) 2965 (Bug#17892)
1320 2966
1321 * xdisp.c (display_line, display_mode_line): Call 2967 * xdisp.c (display_line, display_mode_line):
1322 prepare_desired_row with additional arguments, as appropriate. 2968 Call prepare_desired_row with additional arguments, as appropriate.
1323 2969
1324 * dispextern.h (prepare_desired_row): Adjust prototype. 2970 * dispextern.h (prepare_desired_row): Adjust prototype.
1325 2971
@@ -1408,7 +3054,7 @@
1408 3054
14092014-06-28 K. Handa <handa@gnu.org> 30552014-06-28 K. Handa <handa@gnu.org>
1410 3056
1411 * coding.c (MAX_CHARBUF_SIZE): Renamed from CHARBUF_SIZE. 3057 * coding.c (MAX_CHARBUF_SIZE): Rename from CHARBUF_SIZE.
1412 (MIN_CHARBUF_SIZE): New macro. 3058 (MIN_CHARBUF_SIZE): New macro.
1413 (ALLOC_CONVERSION_WORK_AREA): New arg SIZE. Callers changed. 3059 (ALLOC_CONVERSION_WORK_AREA): New arg SIZE. Callers changed.
1414 3060
@@ -1674,7 +3320,7 @@
1674 3320
1675 * dispextern.h (struct face) [HAVE_XFT]: Ifdef 'extra' member. 3321 * dispextern.h (struct face) [HAVE_XFT]: Ifdef 'extra' member.
1676 * font.c (font_done_for_face): 3322 * font.c (font_done_for_face):
1677 * xface.c (realize_non_ascii_face): Adjust user. 3323 * xfaces.c (realize_non_ascii_face): Adjust user.
1678 * font.h (struct font_driver): Convert 'prepare_face' to return 3324 * font.h (struct font_driver): Convert 'prepare_face' to return
1679 void because its return value is never used anyway. 3325 void because its return value is never used anyway.
1680 * xfont.c (xfont_prepare_face): Return void. 3326 * xfont.c (xfont_prepare_face): Return void.
@@ -2167,7 +3813,7 @@
2167 3813
2168 Use mmap(2) emulation for allocating buffer text on MS-Windows. 3814 Use mmap(2) emulation for allocating buffer text on MS-Windows.
2169 * Makefile.in (C_HEAP_SWITCH): Get the predefined heap size from 3815 * Makefile.in (C_HEAP_SWITCH): Get the predefined heap size from
2170 configure. 3816 configure, not from HEAPSIZE.
2171 (ADDSECTION, MINGW_TEMACS_POST_LINK): Remove, no longer used. 3817 (ADDSECTION, MINGW_TEMACS_POST_LINK): Remove, no longer used.
2172 3818
2173 * lisp.h (NONPOINTER_BITS): Modify the condition to define to zero 3819 * lisp.h (NONPOINTER_BITS): Modify the condition to define to zero
@@ -3211,8 +4857,7 @@
3211 * doc.c (store_function_docstring): Warn when we don't know where to 4857 * doc.c (store_function_docstring): Warn when we don't know where to
3212 put a docstring. 4858 put a docstring.
3213 (Fsubstitute_command_keys): Don't advertise the fact that 4859 (Fsubstitute_command_keys): Don't advertise the fact that
3214 text-properties are dropped, since we think it's a bug that we'll fix 4860 text-properties are dropped, since we think it's a bug that we'll fix.
3215 in 24.5.
3216 4861
3217 * frame.h (SET_FRAME_VISIBLE): Keep frame_garbaged up to date. 4862 * frame.h (SET_FRAME_VISIBLE): Keep frame_garbaged up to date.
3218 * xterm.c (handle_one_xevent) <MapNotify>: Don't garbage the frame. 4863 * xterm.c (handle_one_xevent) <MapNotify>: Don't garbage the frame.
@@ -8443,7 +10088,7 @@
8443 * eval.c (Ffuncall): Fix handling of ((lambda ..) ..) in lexically 10088 * eval.c (Ffuncall): Fix handling of ((lambda ..) ..) in lexically
8444 scoped code (bug#11258). 10089 scoped code (bug#11258).
8445 10090
84462013-08-28 Davor Cubranic <cubranic@stat.ubc.ca> (tiny change) 100912013-08-28 Davor Cubranic <cubranic@stat.ubc.ca> (tiny change)
8447 10092
8448 * nsterm.m (last_window): New variable. 10093 * nsterm.m (last_window): New variable.
8449 (EV_TRAILER2): New macro. 10094 (EV_TRAILER2): New macro.
@@ -8851,7 +10496,7 @@
8851 (imagemagick_get_animation_cache): Fix a double-free error. 10496 (imagemagick_get_animation_cache): Fix a double-free error.
8852 (imagemagick_load_image): Remove the ping_wand code, which only 10497 (imagemagick_load_image): Remove the ping_wand code, which only
8853 apparently saved time on invalid animated images, and slowed down 10498 apparently saved time on invalid animated images, and slowed down
8854 everything else. Optimise for the common case. 10499 everything else. Optimize for the common case.
8855 10500
88562013-08-16 Xue Fuqiao <xfq.free@gmail.com> 105012013-08-16 Xue Fuqiao <xfq.free@gmail.com>
8857 10502
diff --git a/src/ChangeLog.10 b/src/ChangeLog.10
index 19adb22b869..1b77eaf5803 100644
--- a/src/ChangeLog.10
+++ b/src/ChangeLog.10
@@ -3264,7 +3264,7 @@
3264 * w32term.c (x_make_frame_visible): Use SystemParametersInfo with 3264 * w32term.c (x_make_frame_visible): Use SystemParametersInfo with
3265 SPI_GETWORKAREA to find the dimensions of the screen work area, 3265 SPI_GETWORKAREA to find the dimensions of the screen work area,
3266 and adjust vertical position of the frame in order to avoid being 3266 and adjust vertical position of the frame in order to avoid being
3267 covered by the task bar. 3267 covered by the taskbar.
3268 3268
3269 * w32fns.c (w32_createwindow): Use CW_USEDEFAULT instead of 3269 * w32fns.c (w32_createwindow): Use CW_USEDEFAULT instead of
3270 f->left_pos and SH_SHOW instead of f->top_pos in the call to 3270 f->left_pos and SH_SHOW instead of f->top_pos in the call to
diff --git a/src/ChangeLog.11 b/src/ChangeLog.11
index ac886d38966..fc6ff1fda6a 100644
--- a/src/ChangeLog.11
+++ b/src/ChangeLog.11
@@ -2241,7 +2241,7 @@
2241 * xdisp.c (try_scrolling): Avoid infloop if the first line is 2241 * xdisp.c (try_scrolling): Avoid infloop if the first line is
2242 obscured due to a vscroll (Bug#7537). 2242 obscured due to a vscroll (Bug#7537).
2243 2243
22442010-12-13 Jan Djärv <jhd@zeplinf.localdomain> 22442010-12-13 Jan Djärv <jan.h.d@swipnet.se>
2245 2245
2246 * nsterm.h (FRAME_NS_TOOLBAR_HEIGHT): Rename to FRAME_TOOLBAR_HEIGHT. 2246 * nsterm.h (FRAME_NS_TOOLBAR_HEIGHT): Rename to FRAME_TOOLBAR_HEIGHT.
2247 2247
diff --git a/src/ChangeLog.8 b/src/ChangeLog.8
index a483a561d06..fd8ae6caa20 100644
--- a/src/ChangeLog.8
+++ b/src/ChangeLog.8
@@ -73,8 +73,8 @@
73 73
74 * msdos.c (dos_set_window_size) [__DJGPP__ > 1]: If the frame 74 * msdos.c (dos_set_window_size) [__DJGPP__ > 1]: If the frame
75 dimensions changed, invalidate the mouse highlight info. 75 dimensions changed, invalidate the mouse highlight info.
76 (disable_mouse_highlight, help_echo, previous_help_echo): New 76 (disable_mouse_highlight, help_echo, previous_help_echo):
77 variables. 77 New variables.
78 (IT_set_mouse_pointer, show_mouse_face, clear_mouse_face) 78 (IT_set_mouse_pointer, show_mouse_face, clear_mouse_face)
79 (fast_find_position, IT_note_mode_line_highlight) 79 (fast_find_position, IT_note_mode_line_highlight)
80 (IT_note_mouse_highlight): New functions. 80 (IT_note_mouse_highlight): New functions.
@@ -89,8 +89,8 @@
89 (internal_terminal_init): Initialize mouse-highlight related 89 (internal_terminal_init): Initialize mouse-highlight related
90 members of the_only_x_display. Assign IT_frame_up_to_date to 90 members of the_only_x_display. Assign IT_frame_up_to_date to
91 frame_up_to_date_hook. 91 frame_up_to_date_hook.
92 (dos_rawgetc): If the mouse moved, update mouse highlight. If 92 (dos_rawgetc): If the mouse moved, update mouse highlight.
93 help_echo changed value, generate a HELP_EVENT event. 93 If help_echo changed value, generate a HELP_EVENT event.
94 (syms_of_msdos): Staticpro help_echo and previous_help_echo. 94 (syms_of_msdos): Staticpro help_echo and previous_help_echo.
95 95
96 * msdos.h (struct display_info): New. 96 * msdos.h (struct display_info): New.
@@ -116,7 +116,7 @@
116 * lisp.h (GLYPH): Defined as `int', not `unsigned int'. Now the 116 * lisp.h (GLYPH): Defined as `int', not `unsigned int'. Now the
117 lowest 8 bits are single byte character code, the bits above are 117 lowest 8 bits are single byte character code, the bits above are
118 face ID. 118 face ID.
119 (GLYPH_MASK_FACE, GLYPH_MASK_CHAR): Adjusted for the change 119 (GLYPH_MASK_FACE, GLYPH_MASK_CHAR): Adjust for the change
120 above. 120 above.
121 (FAST_MAKE_GLYPH, FSST_GLYPH_FACE): Likewise. 121 (FAST_MAKE_GLYPH, FSST_GLYPH_FACE): Likewise.
122 (GLYPH_MASK_REV_DIR, GLYPH_MASK_PADDING): Macros deleted. 122 (GLYPH_MASK_REV_DIR, GLYPH_MASK_PADDING): Macros deleted.
@@ -131,20 +131,20 @@
131 level members. Change members in union `u'. 131 level members. Change members in union `u'.
132 (GLYPH_EQUAL_P): Check also members face_id and padding_p. 132 (GLYPH_EQUAL_P): Check also members face_id and padding_p.
133 (GLYPH_CHAR_AND_FACE_EQUAL_P): New macro. 133 (GLYPH_CHAR_AND_FACE_EQUAL_P): New macro.
134 (SET_CHAR_GLYPH): Adjusted for the change of struct glyph. 134 (SET_CHAR_GLYPH): Adjust for the change of struct glyph.
135 (CHAR_GLYPH_PADDING_P): Likewise. 135 (CHAR_GLYPH_PADDING_P): Likewise.
136 (GLYPH_FROM_CHAR_GLYPH): Likewise. Always return -1 for multibyte 136 (GLYPH_FROM_CHAR_GLYPH): Likewise. Always return -1 for multibyte
137 characters. 137 characters.
138 138
139 * dispnew.c (line_hash_code, direct_output_for_insert): Adjusted 139 * dispnew.c (line_hash_code, direct_output_for_insert):
140 for the change of struct glyph. 140 Adjust for the change of struct glyph.
141 (line_draw_cost): Adjusted for the change of 141 (line_draw_cost): Adjust for the change of
142 GLYPH_FROM_CHAR_GLYPH. 142 GLYPH_FROM_CHAR_GLYPH.
143 (count_match): Use macro GLYPH_CHAR_AND_FACE_EQUAL_P. 143 (count_match): Use macro GLYPH_CHAR_AND_FACE_EQUAL_P.
144 144
145 * term.c (encode_terminal_code): Adjusted for the change of struct 145 * term.c (encode_terminal_code): Adjust for the change of struct
146 glyph and GLYPH_FROM_CHAR_GLYPH. 146 glyph and GLYPH_FROM_CHAR_GLYPH.
147 (write_glyphs, insert_glyphs, append_glyph): Adjusted for the 147 (write_glyphs, insert_glyphs, append_glyph): Adjust for the
148 change of struct glyph. 148 change of struct glyph.
149 149
150 * xdisp.c: All codes adjusted for the change of struct glyph. 150 * xdisp.c: All codes adjusted for the change of struct glyph.
@@ -284,8 +284,8 @@
284 284
2851999-12-15 Kenichi Handa <handa@etl.go.jp> 2851999-12-15 Kenichi Handa <handa@etl.go.jp>
286 286
287 The following changes are for the new composition mechanism. We 287 The following changes are for the new composition mechanism.
288 have deleted `composition' charset and composite characters, 288 We have deleted `composition' charset and composite characters,
289 instead introduced a special text property `composition'. 289 instead introduced a special text property `composition'.
290 290
291 * Makefile.in (INTERVAL_SRC): Include composite.h. 291 * Makefile.in (INTERVAL_SRC): Include composite.h.
@@ -298,7 +298,7 @@
298 (keyboard.o) (textprop.o) (intervals.o): Depend on INTERVAL_SRC. 298 (keyboard.o) (textprop.o) (intervals.o): Depend on INTERVAL_SRC.
299 (composite.o): New target. 299 (composite.o): New target.
300 300
301 * alloc.c (Fmake_string): Adjusted for the change of CHAR_STRING. 301 * alloc.c (Fmake_string): Adjust for the change of CHAR_STRING.
302 302
303 * callproc.c (Fcall_process): Call code_convert_string to encode 303 * callproc.c (Fcall_process): Call code_convert_string to encode
304 arguments. Use CODING_REQUIRE_DECODING to check if the process 304 arguments. Use CODING_REQUIRE_DECODING to check if the process
@@ -317,7 +317,7 @@
317 (Fmake_category_table): New function. 317 (Fmake_category_table): New function.
318 (syms_of_category): Defsubr it. 318 (syms_of_category): Defsubr it.
319 319
320 * ccl.c (CCL_WRITE_CHAR): Adjusted for the change of CHAR_STRING. 320 * ccl.c (CCL_WRITE_CHAR): Adjust for the change of CHAR_STRING.
321 (ccl_driver): Delete codes for a composite character. 321 (ccl_driver): Delete codes for a composite character.
322 322
323 * charset.h: In this entry, just `Modified' means that codes for a 323 * charset.h: In this entry, just `Modified' means that codes for a
@@ -326,49 +326,49 @@
326 (charset_composition) (MIN_CHAR_COMPOSITION) 326 (charset_composition) (MIN_CHAR_COMPOSITION)
327 (MAX_CHAR_COMPOSITION) (GENERIC_COMPOSITION_CHAR) 327 (MAX_CHAR_COMPOSITION) (GENERIC_COMPOSITION_CHAR)
328 (COMPOSITE_CHAR_P) (MAKE_COMPOSITE_CHAR) (COMPOSITE_CHAR_ID) 328 (COMPOSITE_CHAR_P) (MAKE_COMPOSITE_CHAR) (COMPOSITE_CHAR_ID)
329 (PARSE_COMPOSITE_SEQ) (PARSE_CHARACTER_SEQ): Deleted. 329 (PARSE_COMPOSITE_SEQ) (PARSE_CHARACTER_SEQ): Delete.
330 (MAX_CHAR) (CHARSET_VALID_P) (CHARSET_DEFINED_P) (CHARSET_AT) 330 (MAX_CHAR) (CHARSET_VALID_P) (CHARSET_DEFINED_P) (CHARSET_AT)
331 (FIRST_CHARSET_AT) (SAME_CHARSET_P) (MAKE_NON_ASCII_CHAR) 331 (FIRST_CHARSET_AT) (SAME_CHARSET_P) (MAKE_NON_ASCII_CHAR)
332 (PARSE_MULTIBYTE_SEQ) (SPLIT_NON_ASCII_CHAR) (CHAR_PRINTABLE_P): 332 (PARSE_MULTIBYTE_SEQ) (SPLIT_NON_ASCII_CHAR) (CHAR_PRINTABLE_P):
333 Modified. 333 Modify.
334 (SPLIT_STRING): Call split_string, not split_non_ascii_string. 334 (SPLIT_STRING): Call split_string, not split_non_ascii_string.
335 (CHAR_STRING): Delete WORKBUF argument. Call char_string, not 335 (CHAR_STRING): Delete WORKBUF argument. Call char_string, not
336 non_ascii_char_to_string. 336 non_ascii_char_to_string.
337 (STRING_CHAR): Call string_to_char, not string_to_non_ascii_char. 337 (STRING_CHAR): Call string_to_char, not string_to_non_ascii_char.
338 (STRING_CHAR_AND_LENGTH): Likewise. 338 (STRING_CHAR_AND_LENGTH): Likewise.
339 (FETCH_CHAR_ADVANCE): New macro. 339 (FETCH_CHAR_ADVANCE): New macro.
340 (MAX_COMPONENT_COUNT) (struct cmpchar_info): Deleted. 340 (MAX_COMPONENT_COUNT) (struct cmpchar_info): Delete.
341 (MAX_MULTIBYTE_LENGTH): New macro. 341 (MAX_MULTIBYTE_LENGTH): New macro.
342 (MAX_LENGTH_OF_MULTI_BYTE_FORM): Deleted. 342 (MAX_LENGTH_OF_MULTI_BYTE_FORM): Delete.
343 (find_charset_in_str): Argument adjusted. 343 (find_charset_in_str): Argument adjusted.
344 (CHAR_LEN): Modified. 344 (CHAR_LEN): Modify.
345 345
346 * charset.c: In this entry, just `Modified' means that codes for a 346 * charset.c: In this entry, just `Modified' means that codes for a
347 composite character is deleted. 347 composite character is deleted.
348 (Qcomposition) (leading_code_composition) 348 (Qcomposition) (leading_code_composition)
349 (charset_composition) (min_composite_char) (cmpchar_table) 349 (charset_composition) (min_composite_char) (cmpchar_table)
350 (cmpchar_table_size) (n_cmpchars): Deleted. 350 (cmpchar_table_size) (n_cmpchars): Delete.
351 (SPLIT_COMPOSITE_SEQ): Deleted. 351 (SPLIT_COMPOSITE_SEQ): Delete.
352 (SPLIT_MULTIBYTE_SEQ): Modified. 352 (SPLIT_MULTIBYTE_SEQ): Modify.
353 (char_to_string): Renamed from non_ascii_char_to_string. 353 (char_to_string): Rename from non_ascii_char_to_string.
354 Modified. 354 Modified.
355 (string_to_char): Renamed from string_to_non_ascii_char. 355 (string_to_char): Rename from string_to_non_ascii_char.
356 (split_string): Renamed from split_non_ascii_string. 356 (split_string): Rename from split_non_ascii_string.
357 (char_printable_p) (Fsplit_char) 357 (char_printable_p) (Fsplit_char)
358 (Ffind_charset_region) (Ffind_charset_string) (char_valid_p) 358 (Ffind_charset_region) (Ffind_charset_string) (char_valid_p)
359 (char_bytes) (Fchar_width) (strwidth): Modified. 359 (char_bytes) (Fchar_width) (strwidth): Modify.
360 (find_charset_in_str): Argument CMPCHARP deleted. Modified. 360 (find_charset_in_str): Argument CMPCHARP deleted. Modified.
361 (Fstring): Adjusted for the change of CHAR_STRING. Modified. 361 (Fstring): Adjust for the change of CHAR_STRING. Modified.
362 (hash_string) (CMPCHAR_HASH_TABLE_SIZE) (cmpchar_hash_table) 362 (hash_string) (CMPCHAR_HASH_TABLE_SIZE) (cmpchar_hash_table)
363 (CMPCHAR_HASH_SIZE) (CMPCHAR_HASH_USED) (CMPCHAR_HASH_CMPCHAR_ID) 363 (CMPCHAR_HASH_SIZE) (CMPCHAR_HASH_USED) (CMPCHAR_HASH_CMPCHAR_ID)
364 (str_cmpchar_id) (cmpchar_component) (Fcmpcharp) 364 (str_cmpchar_id) (cmpchar_component) (Fcmpcharp)
365 (Fcmpchar_component) (Fcmpchar_cmp_rule) (Fcmpchar_cmp_rule_p) 365 (Fcmpchar_component) (Fcmpchar_cmp_rule) (Fcmpchar_cmp_rule_p)
366 (Fcmpchar_cmp_count): Deleted. 366 (Fcmpchar_cmp_count): Delete.
367 (Fcompose_string): Implemented by Emacs Lisp in composite.el. 367 (Fcompose_string): Implemented by Emacs Lisp in composite.el.
368 (init_charset_once): Modified. 368 (init_charset_once): Modify.
369 (syms_of_charset): Modified. 369 (syms_of_charset): Modify.
370 370
371 * cmds.c (internal_self_insert): Adjusted for the change of 371 * cmds.c (internal_self_insert): Adjust for the change of
372 CHAR_STRING. 372 CHAR_STRING.
373 373
374 * coding.h (emacs_code_class_type): Delete the member 374 * coding.h (emacs_code_class_type): Delete the member
@@ -377,8 +377,8 @@
377 (COMPOSING_WITH_RULE_TAIL) (COMPOSING_NO_RULE_TAIL) 377 (COMPOSING_WITH_RULE_TAIL) (COMPOSING_NO_RULE_TAIL)
378 (COMPOSING_WITH_RULE_RULE) (COMPOSING_HEAD_P) 378 (COMPOSING_WITH_RULE_RULE) (COMPOSING_HEAD_P)
379 (COMPOSING_WITH_RULE_P): Macros deleted. 379 (COMPOSING_WITH_RULE_P): Macros deleted.
380 (COMPOSITION_DATA_SIZE) (COMPOSITION_DATA_MAX_BUNCH_LENGTH): New 380 (COMPOSITION_DATA_SIZE) (COMPOSITION_DATA_MAX_BUNCH_LENGTH):
381 macros. 381 New macros.
382 (struct composition_data): New structure. 382 (struct composition_data): New structure.
383 (CODING_FINISH_INSUFFICIENT_CMP): New macro. 383 (CODING_FINISH_INSUFFICIENT_CMP): New macro.
384 (struct coding_system): New members composition_rule_follows, 384 (struct coding_system): New members composition_rule_follows,
@@ -395,7 +395,7 @@
395 EMACS_leading_code_composition to 0x80. 395 EMACS_leading_code_composition to 0x80.
396 (detect_coding_iso2022): Handle new composition sequence. 396 (detect_coding_iso2022): Handle new composition sequence.
397 (DECODE_ISO_CHARACTER): Likewise. 397 (DECODE_ISO_CHARACTER): Likewise.
398 (check_composing_code): Deleted. 398 (check_composing_code): Delete.
399 (coding_allocate_composition_data): New function. 399 (coding_allocate_composition_data): New function.
400 (CODING_ADD_COMPOSITION_START) (CODING_ADD_COMPOSITION_END) 400 (CODING_ADD_COMPOSITION_START) (CODING_ADD_COMPOSITION_END)
401 (CODING_ADD_COMPOSITION_COMPONENT) (DECODE_COMPOSITION_START) 401 (CODING_ADD_COMPOSITION_COMPONENT) (DECODE_COMPOSITION_START)
@@ -404,7 +404,7 @@
404 (ENCODE_ISO_CHARACTER): Don't check composition here. 404 (ENCODE_ISO_CHARACTER): Don't check composition here.
405 (ENCODE_COMPOSITION_RULE) (ENCODE_COMPOSITION_START): New macros. 405 (ENCODE_COMPOSITION_RULE) (ENCODE_COMPOSITION_START): New macros.
406 (ENCODE_COMPOSITION_NO_RULE_START) 406 (ENCODE_COMPOSITION_NO_RULE_START)
407 (ENCODE_COMPOSITION_WITH_RULE_START): Deleted. 407 (ENCODE_COMPOSITION_WITH_RULE_START): Delete.
408 (ENCODE_COMPOSITION_END): Handle new composition sequence. 408 (ENCODE_COMPOSITION_END): Handle new composition sequence.
409 (ENCODE_COMPOSITION_FAKE_START): New macro. 409 (ENCODE_COMPOSITION_FAKE_START): New macro.
410 (encode_coding_iso2022): Handle new composition sequence. 410 (encode_coding_iso2022): Handle new composition sequence.
@@ -414,12 +414,12 @@
414 coding_system. Enable composition only when the coding system has 414 coding_system. Enable composition only when the coding system has
415 `composition' property t. 415 `composition' property t.
416 (coding_free_composition_data) (coding_adjust_composition_offset) 416 (coding_free_composition_data) (coding_adjust_composition_offset)
417 (coding_save_composition) (coding_restore_composition): New 417 (coding_save_composition) (coding_restore_composition):
418 functions. 418 New functions.
419 (code_convert_region): Call coding_save_composition for encoding 419 (code_convert_region): Call coding_save_composition for encoding
420 and coding_allocate_composition_data for decoding. Don't skip 420 and coding_allocate_composition_data for decoding. Don't skip
421 ASCII characters if we handle composition on encoding. Call 421 ASCII characters if we handle composition on encoding.
422 signal_after_change with Check_BORDER. 422 Call signal_after_change with Check_BORDER.
423 (code_convert_string): Call coding_save_composition for encoding 423 (code_convert_string): Call coding_save_composition for encoding
424 and coding_allocate_composition_data for decoding. Don't skip 424 and coding_allocate_composition_data for decoding. Don't skip
425 ASCII characters if we handle composition on encoding. 425 ASCII characters if we handle composition on encoding.
@@ -448,9 +448,9 @@
448 * dispnew.c (direct_output_forward_char): Check point moving into 448 * dispnew.c (direct_output_forward_char): Check point moving into
449 or out of a composition. If so, give up direct method. 449 or out of a composition. If so, give up direct method.
450 450
451 * doprnt.c (doprnt1): Adjusted for the change of CHAR_STRING. 451 * doprnt.c (doprnt1): Adjust for the change of CHAR_STRING.
452 452
453 * editfns.c (Fchar_to_string): Adjusted for the change of 453 * editfns.c (Fchar_to_string): Adjust for the change of
454 CHAR_STRING. 454 CHAR_STRING.
455 (general_insert_function): Likewise. 455 (general_insert_function): Likewise.
456 (Finsert_char): Likewise. 456 (Finsert_char): Likewise.
@@ -460,19 +460,19 @@
460 460
461 * emacs.c (main): Call syms_of_composite. 461 * emacs.c (main): Call syms_of_composite.
462 462
463 * fileio.c (Fsubstitute_in_file_name): Adjusted for the change of 463 * fileio.c (Fsubstitute_in_file_name): Adjust for the change of
464 CHAR_STRING. 464 CHAR_STRING.
465 (Finsert_file_contents): Set Vlast_coding_system_used before 465 (Finsert_file_contents): Set Vlast_coding_system_used before
466 calling signal_after_change. Call update_compositions if some 466 calling signal_after_change. Call update_compositions if some
467 texts are inserted.. 467 texts are inserted..
468 (Fwrite_region): Adjusted for the change of a_write and e_write. 468 (Fwrite_region): Adjust for the change of a_write and e_write.
469 (a_write): Argument changed. Work based on character position, 469 (a_write): Argument changed. Work based on character position,
470 not byte position. 470 not byte position.
471 (e_write): Argument changed. Handle new way of composition. 471 (e_write): Argument changed. Handle new way of composition.
472 472
473 * fns.c (Flength): The length of char-table is MAX_CHAR. 473 * fns.c (Flength): The length of char-table is MAX_CHAR.
474 (concat): Adjusted for the change of CHAR_STRING. 474 (concat): Adjust for the change of CHAR_STRING.
475 (Ffillarray): Adjusted for the change of CHAR_STRING. 475 (Ffillarray): Adjust for the change of CHAR_STRING.
476 (Fset_char_table_default): Delete codes for a composite character. 476 (Fset_char_table_default): Delete codes for a composite character.
477 (hash_put): Return hash index. 477 (hash_put): Return hash index.
478 478
@@ -492,7 +492,7 @@
492 (Fmove_to_column): Likewise. 492 (Fmove_to_column): Likewise.
493 (compute_motion): Likewise. 493 (compute_motion): Likewise.
494 494
495 * insdel.c (copy_text): Adjusted for the change of CHAR_STRING. 495 * insdel.c (copy_text): Adjust for the change of CHAR_STRING.
496 (insert_char): Likewise. 496 (insert_char): Likewise.
497 (insert): Call update_compositions. 497 (insert): Call update_compositions.
498 (insert_and_inherit): Likewise. 498 (insert_and_inherit): Likewise.
@@ -502,7 +502,7 @@
502 (insert_from_string_before_markers): Likewise. 502 (insert_from_string_before_markers): Likewise.
503 (insert_from_buffer): Likewise. 503 (insert_from_buffer): Likewise.
504 (replace_range): Likewise. 504 (replace_range): Likewise.
505 (count_combining_composition): Deleted. 505 (count_combining_composition): Delete.
506 (count_combining_before): Delete codes for a composite character. 506 (count_combining_before): Delete codes for a composite character.
507 (count_combining_after): Likewise. 507 (count_combining_after): Likewise.
508 (del_range_1): Call update_compositions. 508 (del_range_1): Call update_compositions.
@@ -526,16 +526,16 @@
526 necessary. 526 necessary.
527 (adjust_point_for_property): New function. 527 (adjust_point_for_property): New function.
528 528
529 * keymap.c (push_key_description): Adjusted for the change of 529 * keymap.c (push_key_description): Adjust for the change of
530 CHAR_STRING. 530 CHAR_STRING.
531 (Ftext_char_description): Likewise. 531 (Ftext_char_description): Likewise.
532 532
533 * lisp.h (QCtest, QCweakness, Qequal): Extern them. 533 * lisp.h (QCtest, QCweakness, Qequal): Extern them.
534 (hash_put): Adjusted for the change of the definition. 534 (hash_put): Adjust for the change of the definition.
535 (signal_after_change): Likewise. 535 (signal_after_change): Likewise.
536 (check_point_in_composition): Extern it. 536 (check_point_in_composition): Extern it.
537 537
538 * lread.c (readchar): Adjusted for the change of CHAR_STRING. 538 * lread.c (readchar): Adjust for the change of CHAR_STRING.
539 Delete a code that handles an invalid too-long multibyte sequence 539 Delete a code that handles an invalid too-long multibyte sequence
540 because we are now sure that we never encounter with such a 540 because we are now sure that we never encounter with such a
541 sequence. 541 sequence.
@@ -544,14 +544,14 @@
544 (init_obarray): Likewise. 544 (init_obarray): Likewise.
545 (read1): Likewise. Adjusted for the change of CHAR_STRING. 545 (read1): Likewise. Adjusted for the change of CHAR_STRING.
546 546
547 * print.c (printchar): Adjusted for the change of CHAR_STRING. 547 * print.c (printchar): Adjust for the change of CHAR_STRING.
548 548
549 * process.c: Include composite.h. 549 * process.c: Include composite.h.
550 (read_process_output): Call update_compositions. 550 (read_process_output): Call update_compositions.
551 551
552 * regex.c (regex_compile): Adjusted for the change of CHAR_STRING. 552 * regex.c (regex_compile): Adjust for the change of CHAR_STRING.
553 553
554 * search.c (search_buffer): Adjusted for the change of CHAR_STRING. 554 * search.c (search_buffer): Adjust for the change of CHAR_STRING.
555 555
556 * syntax.h (SYNTAX_ENTRY_INT): Delete codes for a composite 556 * syntax.h (SYNTAX_ENTRY_INT): Delete codes for a composite
557 character. 557 character.
@@ -570,19 +570,19 @@
570 (face_before_or_after_it_pos): For composition, check face of a 570 (face_before_or_after_it_pos): For composition, check face of a
571 character after the composition. 571 character after the composition.
572 (handle_composition_prop): New function. 572 (handle_composition_prop): New function.
573 (get_next_display_element): Adjusted for the change of 573 (get_next_display_element): Adjust for the change of
574 CHAR_STRING. 574 CHAR_STRING.
575 (set_iterator_to_next): Handle the case that it->method == 575 (set_iterator_to_next): Handle the case that it->method ==
576 next_element_from_composition. 576 next_element_from_composition.
577 (next_element_from_composition): New function. 577 (next_element_from_composition): New function.
578 (message_dolog): Adjusted for the change of CHAR_STRING. 578 (message_dolog): Adjust for the change of CHAR_STRING.
579 (set_message_1): Likewise. 579 (set_message_1): Likewise.
580 (check_point_in_composition): New function. 580 (check_point_in_composition): New function.
581 (reconsider_clip_changes): If point moved into or out of 581 (reconsider_clip_changes): If point moved into or out of
582 composition, set b->clip_changed to 1 to force updating of the 582 composition, set b->clip_changed to 1 to force updating of the
583 screen. 583 screen.
584 (disp_char_vector): Delete codes for a composite character. 584 (disp_char_vector): Delete codes for a composite character.
585 (decode_mode_spec_coding): Adjusted for the change of CHAR_STRING. 585 (decode_mode_spec_coding): Adjust for the change of CHAR_STRING.
586 586
587 * xfaces.c (choose_face_fontset_font): Delete codes for a 587 * xfaces.c (choose_face_fontset_font): Delete codes for a
588 composite character. 588 composite character.
@@ -592,7 +592,7 @@
592 * xfns.c: Include intervals.h. 592 * xfns.c: Include intervals.h.
593 (syms_of_xfns): Make `display' property nonsticky by default. 593 (syms_of_xfns): Make `display' property nonsticky by default.
594 594
595 * xselect.c (lisp_data_to_selection_data): Adjusted for the change 595 * xselect.c (lisp_data_to_selection_data): Adjust for the change
596 for find_charset_in_str. 596 for find_charset_in_str.
597 597
598 * xterm.h (struct x_output): Change member font_baseline to 598 * xterm.h (struct x_output): Change member font_baseline to
@@ -618,9 +618,9 @@
618 (x_draw_composite_glyph_string_foreground): New function. 618 (x_draw_composite_glyph_string_foreground): New function.
619 (x_draw_glyph_string_box): Check s->cmp, not s->cmpcharp. 619 (x_draw_glyph_string_box): Check s->cmp, not s->cmpcharp.
620 (x_draw_glyph_string): Handle the case of COMPOSITE_GLYPH. 620 (x_draw_glyph_string): Handle the case of COMPOSITE_GLYPH.
621 (struct work): Deleted. 621 (struct work): Delete.
622 (x_fill_composite_glyph_string): Argument changed. Mostly 622 (x_fill_composite_glyph_string): Argument changed.
623 rewritten for that. 623 Mostly rewritten for that.
624 (x_fill_glyph_string): Don't check CHARSET_COMPOSITION. 624 (x_fill_glyph_string): Don't check CHARSET_COMPOSITION.
625 (BUILD_CHAR_GLYPH_STRINGS): Don't handle composition here. 625 (BUILD_CHAR_GLYPH_STRINGS): Don't handle composition here.
626 (BUILD_COMPOSITE_GLYPH_STRING): New macro. 626 (BUILD_COMPOSITE_GLYPH_STRING): New macro.
@@ -656,8 +656,8 @@
656 * frame.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL) 656 * frame.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL)
657 [!MSDOS && !WINDOWSNT && !macintosh]: Moved here from xterm.h. 657 [!MSDOS && !WINDOWSNT && !macintosh]: Moved here from xterm.h.
658 658
659 * xterm.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL): Moved 659 * xterm.h (FRAME_FOREGROUND_PIXEL, FRAME_BACKGROUND_PIXEL):
660 to frame.h. 660 Move to frame.h.
661 661
6621999-12-09 Stefan Monnier <monnier@cs.yale.edu> 6621999-12-09 Stefan Monnier <monnier@cs.yale.edu>
663 663
@@ -668,11 +668,11 @@
668 * xterm.c (#includes): Allow compilation with only Xaw. 668 * xterm.c (#includes): Allow compilation with only Xaw.
669 (xaw3d_arrow_scroll, xaw3d_pick_top): New variables. 669 (xaw3d_arrow_scroll, xaw3d_pick_top): New variables.
670 (xt_action_hook): Replace XAW3D by XAW. 670 (xt_action_hook): Replace XAW3D by XAW.
671 (xaw3d_jump_callback): Renamed to xaw_jump_callback. 671 (xaw3d_jump_callback): Rename to xaw_jump_callback.
672 (xaw_jump_callback): Renamed from xaw3d_jump_callback. 672 (xaw_jump_callback): Rename from xaw3d_jump_callback.
673 Determine epsilon dynamically and don't try to be too clever. 673 Determine epsilon dynamically and don't try to be too clever.
674 (xaw3d_scroll_callback): Renamed to xaw_scroll_callback. 674 (xaw3d_scroll_callback): Rename to xaw_scroll_callback.
675 (xaw_scroll_callback): Renamed from xaw3d_scroll_callback. 675 (xaw_scroll_callback): Rename from xaw3d_scroll_callback.
676 Handle both Xaw3d with arrow-scrollbars and with Xaw-style 676 Handle both Xaw3d with arrow-scrollbars and with Xaw-style
677 scrollbar (using `ratio'). 677 scrollbar (using `ratio').
678 (x_create_toolkit_scroll_bar): Try to detect which style of Xaw3d 678 (x_create_toolkit_scroll_bar): Try to detect which style of Xaw3d
@@ -710,9 +710,9 @@
710 710
7111999-12-07 Alexandre Oliva <oliva@dcc.unicamp.br> 7111999-12-07 Alexandre Oliva <oliva@dcc.unicamp.br>
712 712
713 * unexelf.c: Include <syms.h>, not <sym.h> on IRIX. Removed 713 * unexelf.c: Include <syms.h>, not <sym.h> on IRIX.
714 duplicate definition of ElfW. 714 Removed duplicate definition of ElfW.
715 (find_section): Copied from unexsgi.c. 715 (find_section): Copy from unexsgi.c.
716 (unexec): Use find_section. Adjust whitespace. Initialize 716 (unexec): Use find_section. Adjust whitespace. Initialize
717 new_data2_offset based on old_data, not sbss (this fixes a bug on 717 new_data2_offset based on old_data, not sbss (this fixes a bug on
718 IRIX6). Change #ifdef __mips to __sgi, since it's IRIX-specific. 718 IRIX6). Change #ifdef __mips to __sgi, since it's IRIX-specific.
@@ -798,8 +798,8 @@
798 (FRAME_PARAM_FACES, FRAME_N_PARAM_FACES, FRAME_DEFAULT_PARAM_FACE) 798 (FRAME_PARAM_FACES, FRAME_N_PARAM_FACES, FRAME_DEFAULT_PARAM_FACE)
799 (FRAME_MODE_LINE_PARAM_FACE, FRAME_COMPUTED_FACES) 799 (FRAME_MODE_LINE_PARAM_FACE, FRAME_COMPUTED_FACES)
800 (FRAME_N_COMPUTED_FACES, FRAME_SIZE_COMPUTED_FACES) 800 (FRAME_N_COMPUTED_FACES, FRAME_SIZE_COMPUTED_FACES)
801 (FRAME_DEFAULT_FACE, FRAME_MODE_LINE_FACE, unload_color): Remove 801 (FRAME_DEFAULT_FACE, FRAME_MODE_LINE_FACE, unload_color):
802 unused macro definitions. 802 Remove unused macro definitions.
803 803
804 * msdos.c (IT_set_frame_parameters): Don't call 804 * msdos.c (IT_set_frame_parameters): Don't call
805 recompute_basic_faces, the next redisplay will, anyway. 805 recompute_basic_faces, the next redisplay will, anyway.
@@ -818,13 +818,13 @@
818 818
819 * Makefile.in (lisp, shortlisp): Add lisp/term/tty-colors.elc. 819 * Makefile.in (lisp, shortlisp): Add lisp/term/tty-colors.elc.
820 820
821 * xfns.c (x_defined_color): Rename from defined_color. All 821 * xfns.c (x_defined_color): Rename from defined_color.
822 callers changed. 822 All callers changed.
823 (Fxw_color_defined_p): Renamed from Fx_color_defined_p; 823 (Fxw_color_defined_p): Rename from Fx_color_defined_p;
824 all callers changed. 824 all callers changed.
825 (Fxw_color_values): Renamed from Fx_color_values; all callers 825 (Fxw_color_values): Rename from Fx_color_values; all callers
826 changed. 826 changed.
827 (Fxw_display_color_p): Renamed from Fx_display_color_p; all 827 (Fxw_display_color_p): Rename from Fx_display_color_p; all
828 callers changed. 828 callers changed.
829 (x_window_to_frame, x_any_window_to_frame) 829 (x_window_to_frame, x_any_window_to_frame)
830 (x_non_menubar_window_to_frame, x_menubar_window_to_frame) 830 (x_non_menubar_window_to_frame, x_menubar_window_to_frame)
@@ -834,11 +834,11 @@
834 834
835 * w32fns.c (x_window_to_frame): Use FRAME_W32_P instead of 835 * w32fns.c (x_window_to_frame): Use FRAME_W32_P instead of
836 f->output_data.nothing. 836 f->output_data.nothing.
837 (Fxw_color_defined_p): Renamed from Fx_color_defined_p; 837 (Fxw_color_defined_p): Rename from Fx_color_defined_p;
838 all callers changed. 838 all callers changed.
839 (Fxw_color_values): Renamed from Fx_color_values; all callers 839 (Fxw_color_values): Rename from Fx_color_values; all callers
840 changed. 840 changed.
841 (Fxw_display_color_p): Renamed from Fx_display_color_p; all 841 (Fxw_display_color_p): Rename from Fx_display_color_p; all
842 callers changed. 842 callers changed.
843 843
844 * dispextern.h (tty_color_name): Add prototype. 844 * dispextern.h (tty_color_name): Add prototype.
@@ -856,7 +856,7 @@
856 856
8571999-12-06 Kenichi Handa <handa@etl.go.jp> 8571999-12-06 Kenichi Handa <handa@etl.go.jp>
858 858
859 * fileio.c (decide_coding_unwind): Renamed from 859 * fileio.c (decide_coding_unwind): Rename from
860 set_auto_coding_unwind. 860 set_auto_coding_unwind.
861 (Finsert_file_contents): Make single unwind protect to call both 861 (Finsert_file_contents): Make single unwind protect to call both
862 Vset_auto_coding_function and Ffind_operation_coding_system. 862 Vset_auto_coding_function and Ffind_operation_coding_system.
@@ -868,7 +868,7 @@
868 * regex.c (regex_compile): Recognize *?, +? and ?? as non-greedy 868 * regex.c (regex_compile): Recognize *?, +? and ?? as non-greedy
869 operators and handle them properly. 869 operators and handle them properly.
870 * regex.h (RE_ALL_GREEDY): New option. 870 * regex.h (RE_ALL_GREEDY): New option.
871 (RE_UNMATCHED_RIGHT_PAREN_ORD): Moved to the end where alphabetic 871 (RE_UNMATCHED_RIGHT_PAREN_ORD): Move to the end where alphabetic
872 sorting would put it. 872 sorting would put it.
873 (RE_SYNTAX_AWK, RE_SYNTAX_GREP, RE_SYNTAX_EGREP) 873 (RE_SYNTAX_AWK, RE_SYNTAX_GREP, RE_SYNTAX_EGREP)
874 (_RE_SYNTAX_POSIX_COMMON): Use the new option to keep old behavior. 874 (_RE_SYNTAX_POSIX_COMMON): Use the new option to keep old behavior.
@@ -898,8 +898,8 @@
8981999-11-28 Gerd Moellmann <gerd@gnu.org> 8981999-11-28 Gerd Moellmann <gerd@gnu.org>
899 899
900 * systime.h (EMACS_TIME_CMP, EMACS_TIME_EQ, EMACS_TIME_NE) 900 * systime.h (EMACS_TIME_CMP, EMACS_TIME_EQ, EMACS_TIME_NE)
901 (EMACS_TIME_GT, EMACS_TIME_GE, EMACS_TIME_LT, EMACS_TIME_LE): New 901 (EMACS_TIME_GT, EMACS_TIME_GE, EMACS_TIME_LT, EMACS_TIME_LE):
902 macros. 902 New macros.
903 903
904 * config.in (HAVE_SETITIMER, HAVE_UALARM): New. 904 * config.in (HAVE_SETITIMER, HAVE_UALARM): New.
905 905
@@ -932,8 +932,8 @@
932 932
933 * puresize.h (BASE_PURESIZE): Increase to 550000. 933 * puresize.h (BASE_PURESIZE): Increase to 550000.
934 934
935 * textprop.c (set_text_properties): New function. Like 935 * textprop.c (set_text_properties): New function.
936 Fset_text_properties, but with additional parameter 936 Like Fset_text_properties, but with additional parameter
937 SIGNAL_AFTER_CHANGE_P. If that is nil, don't signal after 937 SIGNAL_AFTER_CHANGE_P. If that is nil, don't signal after
938 changes. 938 changes.
939 (Fset_text_properties): Use it. 939 (Fset_text_properties): Use it.
@@ -1018,7 +1018,7 @@
1018 * fileio.c (strerror): Likewise. 1018 * fileio.c (strerror): Likewise.
1019 * process.c (strerror): Likewise. 1019 * process.c (strerror): Likewise.
1020 * emacs.c (strerror): Likewise. 1020 * emacs.c (strerror): Likewise.
1021 (Vsystem_messages_locale): Renamed from Vmessages_locale. 1021 (Vsystem_messages_locale): Rename from Vmessages_locale.
1022 All uses changed. 1022 All uses changed.
1023 (Vprevious_system_messages_locale): Likewise, from 1023 (Vprevious_system_messages_locale): Likewise, from
1024 Vprevious_messages_locale. 1024 Vprevious_messages_locale.
@@ -1041,7 +1041,7 @@
1041 (FREE_RETURN_TYPE): New macro. 1041 (FREE_RETURN_TYPE): New macro.
1042 (free): Return type is now FREE_RETURN_TYPE. 1042 (free): Return type is now FREE_RETURN_TYPE.
1043 1043
1044 * lisp.h (synchronize_system_time_locale): Renamed from 1044 * lisp.h (synchronize_system_time_locale): Rename from
1045 synchronize_time_locale. All uses changed. 1045 synchronize_time_locale. All uses changed.
1046 (synchronize_system_messages_locale): Likewise, from 1046 (synchronize_system_messages_locale): Likewise, from
1047 synchronize_messages_locale. 1047 synchronize_messages_locale.
@@ -1135,13 +1135,13 @@
1135 1135
11361999-11-10 Gerd Moellmann <gerd@gnu.org> 11361999-11-10 Gerd Moellmann <gerd@gnu.org>
1137 1137
1138 * xfns.c (QCuser_data): Removed. 1138 * xfns.c (QCuser_data): Remove.
1139 (syms_of_xfns): Initialization of QCuser_data removed. 1139 (syms_of_xfns): Initialization of QCuser_data removed.
1140 (parse_image_spec): Don't handle :user-data specially. Allow 1140 (parse_image_spec): Don't handle :user-data specially.
1141 unknown keys. Remove parameter ALLOW_OTHER_KEYS. 1141 Allow unknown keys. Remove parameter ALLOW_OTHER_KEYS.
1142 (xbm_image_p, xbm_load, xpm_image_p, pbm_image_p, png_image_p) 1142 (xbm_image_p, xbm_load, xpm_image_p, pbm_image_p, png_image_p)
1143 (tiff_image_p, jpeg_image_p, gif_image_p, gs_image_p): Call 1143 (tiff_image_p, jpeg_image_p, gif_image_p, gs_image_p):
1144 parse_image_spec accordingly. 1144 Call parse_image_spec accordingly.
1145 1145
11461999-11-09 Richard M. Stallman <rms@gnu.org> 11461999-11-09 Richard M. Stallman <rms@gnu.org>
1147 1147
@@ -1178,8 +1178,8 @@
1178 * lisp.h: Add prototype for unmark_byte_stack. 1178 * lisp.h: Add prototype for unmark_byte_stack.
1179 1179
1180 * bytecode.c (mark_byte_stack): Use XMARKBIT and XMARK. 1180 * bytecode.c (mark_byte_stack): Use XMARKBIT and XMARK.
1181 (unmark_byte_stack): Renamed from relocate_byte_pcs. Use 1181 (unmark_byte_stack): Rename from relocate_byte_pcs.
1182 XUNMARK. 1182 Use XUNMARK.
1183 1183
1184 * xdisp.c (resize_mini_window): Fix computation of needed 1184 * xdisp.c (resize_mini_window): Fix computation of needed
1185 mini-window height. 1185 mini-window height.
@@ -1214,7 +1214,7 @@
1214 (byte_stack_list, mark_byte_stack, relocate_byte_pcs): New. 1214 (byte_stack_list, mark_byte_stack, relocate_byte_pcs): New.
1215 (BEFORE_POTENTIAL_GC, AFTER_POTENTIAL_GC): New. 1215 (BEFORE_POTENTIAL_GC, AFTER_POTENTIAL_GC): New.
1216 (FETCH, PUSH, POP, DISCARD, TOP, MAYBE_GC): Rewritten. 1216 (FETCH, PUSH, POP, DISCARD, TOP, MAYBE_GC): Rewritten.
1217 (HANDLE_RELOCATION): Removed. 1217 (HANDLE_RELOCATION): Remove.
1218 (Fbyte_code): Use byte_stack structures. 1218 (Fbyte_code): Use byte_stack structures.
1219 1219
1220 * filelock.c (Ffile_locked_p): Make FILENAME a required argument. 1220 * filelock.c (Ffile_locked_p): Make FILENAME a required argument.
@@ -1224,10 +1224,10 @@
1224 1224
12251999-11-04 Gerd Moellmann <gerd@gnu.org> 12251999-11-04 Gerd Moellmann <gerd@gnu.org>
1226 1226
1227 * editfns.c (Fdelete_field): Renamed from Ferase_field. 1227 * editfns.c (Fdelete_field): Rename from Ferase_field.
1228 1228
1229 * minibuf.c (do_completion, Fminibuffer_complete_word): Use 1229 * minibuf.c (do_completion, Fminibuffer_complete_word):
1230 Ferase_field instead of Fdelete_field. 1230 Use Ferase_field instead of Fdelete_field.
1231 1231
12321999-11-03 Gerd Moellmann <gerd@gnu.org> 12321999-11-03 Gerd Moellmann <gerd@gnu.org>
1233 1233
@@ -1279,7 +1279,7 @@
1279 * xfns.c (png_load) [PNG_READ_sRGB_SUPPORTED]: Put code using 1279 * xfns.c (png_load) [PNG_READ_sRGB_SUPPORTED]: Put code using
1280 png_get_sRGB in #ifdef. 1280 png_get_sRGB in #ifdef.
1281 1281
1282 * dispnew.c (Finternal_show_cursor): Renamed from Fshow_cursor. 1282 * dispnew.c (Finternal_show_cursor): Rename from Fshow_cursor.
1283 (syms_of_display): Use the new name. 1283 (syms_of_display): Use the new name.
1284 1284
1285 * textprop.c (verify_interval_modification): Signal text-read-only 1285 * textprop.c (verify_interval_modification): Signal text-read-only
@@ -1346,7 +1346,7 @@
1346 1346
13471999-10-27 Richard M. Stallman <rms@gnu.org> 13471999-10-27 Richard M. Stallman <rms@gnu.org>
1348 1348
1349 * data.c (Qad_activate_internal): Renamed from Qad_activate. 1349 * data.c (Qad_activate_internal): Rename from Qad_activate.
1350 (Ffset): Call Qad_activate_internal. 1350 (Ffset): Call Qad_activate_internal.
1351 (syms_of_data): Initialize Qad_activate_internal. 1351 (syms_of_data): Initialize Qad_activate_internal.
1352 1352
@@ -1493,12 +1493,12 @@
1493 * editfns.c: Include coding.h. 1493 * editfns.c: Include coding.h.
1494 (emacs_strftime): Remove decl. 1494 (emacs_strftime): Remove decl.
1495 (emacs_strftimeu): New decl. 1495 (emacs_strftimeu): New decl.
1496 (emacs_memftimeu): Renamed from emacs_memftime; new arg UT. 1496 (emacs_memftimeu): Rename from emacs_memftime; new arg UT.
1497 Use emacs_strftimeu instead of emacs_strftime. 1497 Use emacs_strftimeu instead of emacs_strftime.
1498 (Fformat_time_string): Convert format string using 1498 (Fformat_time_string): Convert format string using
1499 Vlocale_coding_system, and convert result back. Synchronize time 1499 Vlocale_coding_system, and convert result back. Synchronize time
1500 locale before invoking lower level function. Invoke 1500 locale before invoking lower level function.
1501 emacs_memftimeu, passing ut, instead of emacs_memftime. 1501 Invoke emacs_memftimeu, passing ut, instead of emacs_memftime.
1502 1502
1503 * emacs.c: Include <locale.h> if HAVE_SETLOCALE is defined. 1503 * emacs.c: Include <locale.h> if HAVE_SETLOCALE is defined.
1504 (Vmessages_locale, Vprevious_messages_locale, Vtime_locale) 1504 (Vmessages_locale, Vprevious_messages_locale, Vtime_locale)
@@ -1506,7 +1506,7 @@
1506 (main): Invoke setlocale early, so that initial error messages are 1506 (main): Invoke setlocale early, so that initial error messages are
1507 localized properly. But skip locale-setting if LC_ALL is "C". 1507 localized properly. But skip locale-setting if LC_ALL is "C".
1508 Fix up locale when it's safe to do so. 1508 Fix up locale when it's safe to do so.
1509 (fixup_locale): Moved here from xterm.c. 1509 (fixup_locale): Move here from xterm.c.
1510 (synchronize_locale, synchronize_time_locale) 1510 (synchronize_locale, synchronize_time_locale)
1511 (synchronize_messages_locale): New functions. 1511 (synchronize_messages_locale): New functions.
1512 (syms_of_emacs): Accommodate above changes. 1512 (syms_of_emacs): Accommodate above changes.
@@ -1534,8 +1534,8 @@
1534 1534
1535 * lread.c (file_offset, file_tell): New macros. All uses of ftell 1535 * lread.c (file_offset, file_tell): New macros. All uses of ftell
1536 changed to file_tell. 1536 changed to file_tell.
1537 (saved_doc_string_position, prev_saved_doc_string_position): Now 1537 (saved_doc_string_position, prev_saved_doc_string_position):
1538 of type file_offset. 1538 Now of type file_offset.
1539 (init_lread): Do not fix locale here; fixup_locale now does this. 1539 (init_lread): Do not fix locale here; fixup_locale now does this.
1540 1540
1541 * m/amdahl.h, s/usg5-4.h: 1541 * m/amdahl.h, s/usg5-4.h:
@@ -1589,10 +1589,10 @@
1589 (emacs_open, emacs_close, emacs_read, emacs_write): Always define; 1589 (emacs_open, emacs_close, emacs_read, emacs_write): Always define;
1590 the old INTERRUPTIBLE_OPEN, INTERRUPTIBLE_CLOSE, and INTERRUPTIBLE_IO 1590 the old INTERRUPTIBLE_OPEN, INTERRUPTIBLE_CLOSE, and INTERRUPTIBLE_IO
1591 macros are no longer used. 1591 macros are no longer used.
1592 (emacs_open): Renamed from sys_open. Merge BSD4_1 version. 1592 (emacs_open): Rename from sys_open. Merge BSD4_1 version.
1593 (emacs_close): Renamed from sys_close. 1593 (emacs_close): Rename from sys_close.
1594 (emacs_read): Renamed from sys_read. 1594 (emacs_read): Rename from sys_read.
1595 (emacs_write): Renamed from sys_write. 1595 (emacs_write): Rename from sys_write.
1596 (sys_siglist): Do not declare if HAVE_STRSIGNAL. 1596 (sys_siglist): Do not declare if HAVE_STRSIGNAL.
1597 (dup2): Do not print error on failure; the real dup2 doesn't. 1597 (dup2): Do not print error on failure; the real dup2 doesn't.
1598 (strsignal): New function, defined if !HAVE_STRSIGNAL. 1598 (strsignal): New function, defined if !HAVE_STRSIGNAL.
@@ -1638,8 +1638,8 @@
16381999-10-18 Kenichi Handa <handa@etl.go.jp> 16381999-10-18 Kenichi Handa <handa@etl.go.jp>
1639 1639
1640 * coding.c (code_convert_string): Add record_unwind_protect to 1640 * coding.c (code_convert_string): Add record_unwind_protect to
1641 assure setting inhibit_pre_post_conversion back to zero. Take 1641 assure setting inhibit_pre_post_conversion back to zero.
1642 care of the multibyteness of the working buffer. 1642 Take care of the multibyteness of the working buffer.
1643 1643
1644 * coding.c (inhibit_pre_post_conversion): New variable. 1644 * coding.c (inhibit_pre_post_conversion): New variable.
1645 (setup_coding_system): If inhibit_pre_post_conversion is nonzero, 1645 (setup_coding_system): If inhibit_pre_post_conversion is nonzero,
@@ -1666,13 +1666,13 @@
1666 * minibuf.c (Fminibuffer_complete_and_exit): Supply value for new 1666 * minibuf.c (Fminibuffer_complete_and_exit): Supply value for new
1667 ESCAPE_FROM_EDGE parameter to Ffield_beginning. 1667 ESCAPE_FROM_EDGE parameter to Ffield_beginning.
1668 1668
1669 * editfns.c (text_property_eq, text_property_stickiness): Don't 1669 * editfns.c (text_property_eq, text_property_stickiness):
1670 use initializers for auto variables of type Lisp_Object. 1670 Don't use initializers for auto variables of type Lisp_Object.
1671 (find_field): Likewise. Use braces around nested ifs. 1671 (find_field): Likewise. Use braces around nested ifs.
1672 (Fline_end_position): Store the raw eol in a variable, so that the 1672 (Fline_end_position): Store the raw eol in a variable, so that the
1673 final expression doesn't look so ugly. 1673 final expression doesn't look so ugly.
1674 (Fconstrain_to_field): Doc fix. 1674 (Fconstrain_to_field): Doc fix.
1675 (preceding_pos): Renamed from `preceeding_pos'. 1675 (preceding_pos): Rename from `preceeding_pos'.
1676 (text_property_stickiness, find_field): Call preceding_pos, 1676 (text_property_stickiness, find_field): Call preceding_pos,
1677 not preceeding_pos. 1677 not preceeding_pos.
1678 1678
@@ -1696,8 +1696,8 @@
1696 * syntax.c (Fforward_word): Supply new ESCAPE_FROM_EDGE parameter 1696 * syntax.c (Fforward_word): Supply new ESCAPE_FROM_EDGE parameter
1697 to Fconstrain_to_field. 1697 to Fconstrain_to_field.
1698 1698
1699 * minibuf.c (Fminibuffer_complete_word): Use 1699 * minibuf.c (Fminibuffer_complete_word):
1700 Ffield_beginning to find the prompt end. 1700 Use Ffield_beginning to find the prompt end.
1701 1701
17021999-10-17 Miles Bader <miles@gnu.org> 17021999-10-17 Miles Bader <miles@gnu.org>
1703 1703
@@ -1746,8 +1746,8 @@
17461999-10-16 Gerd Moellmann <gerd@gnu.org> 17461999-10-16 Gerd Moellmann <gerd@gnu.org>
1747 1747
1748 * window.c (enum save_restore_action): New. 1748 * window.c (enum save_restore_action): New.
1749 (save_restore_orig_size): Change parameter list. Add 1749 (save_restore_orig_size): Change parameter list.
1750 functionality to check for valid orig_top and orig_height members 1750 Add functionality to check for valid orig_top and orig_height members
1751 in a window tree. 1751 in a window tree.
1752 (grow_mini_window): Call save_restore_orig_size with new parameter 1752 (grow_mini_window): Call save_restore_orig_size with new parameter
1753 list. 1753 list.
@@ -1848,8 +1848,8 @@
1848 (Finternal_set_lisp_face_attribute): Ditto. 1848 (Finternal_set_lisp_face_attribute): Ditto.
1849 (Fpixmap_spec_p): Rewritten. Extend doc string. 1849 (Fpixmap_spec_p): Rewritten. Extend doc string.
1850 1850
1851 * xmenu.c (set_frame_menubar, xmenu_show): Call 1851 * xmenu.c (set_frame_menubar, xmenu_show):
1852 x_set_menu_resources_from_menu_face. 1852 Call x_set_menu_resources_from_menu_face.
1853 1853
1854 * dispextern.h (enum face_id): Add MENU_FACE_ID. 1854 * dispextern.h (enum face_id): Add MENU_FACE_ID.
1855 (toplevel): Include X11/Intrinsic.h. 1855 (toplevel): Include X11/Intrinsic.h.
@@ -1869,7 +1869,7 @@
1869 1869
18701999-09-29 Gerd Moellmann <gerd@gnu.org> 18701999-09-29 Gerd Moellmann <gerd@gnu.org>
1871 1871
1872 * editfns.c (Fpropertize): Renamed from Fproperties. 1872 * editfns.c (Fpropertize): Rename from Fproperties.
1873 1873
18741999-09-29 Gerd Moellmann <gerd@gnu.org> 18741999-09-29 Gerd Moellmann <gerd@gnu.org>
1875 1875
@@ -1897,8 +1897,8 @@
1897 1897
1898 * textprop.c (next_single_char_property_change): New. 1898 * textprop.c (next_single_char_property_change): New.
1899 1899
1900 * xdisp.c (display_prop_end, invisible_text_between_p): Use 1900 * xdisp.c (display_prop_end, invisible_text_between_p):
1901 next_single_char_property_change. 1901 Use next_single_char_property_change.
1902 1902
19031999-09-25 Gerd Moellmann <gerd@gnu.org> 19031999-09-25 Gerd Moellmann <gerd@gnu.org>
1904 1904
@@ -1928,7 +1928,7 @@
1928 1928
1929 * xfaces.c (add_to_log): Move to xdisp.c. 1929 * xfaces.c (add_to_log): Move to xdisp.c.
1930 1930
1931 * xdisp.c (add_to_log): Moved from xfaces.c. Remove frame 1931 * xdisp.c (add_to_log): Move from xfaces.c. Remove frame
1932 parameter. 1932 parameter.
1933 1933
19341999-09-23 Gerd Moellmann <gerd@gnu.org> 19341999-09-23 Gerd Moellmann <gerd@gnu.org>
@@ -1945,10 +1945,10 @@
1945 (grow_mini_window, shrink_mini_window): New. 1945 (grow_mini_window, shrink_mini_window): New.
1946 (make_window, replace_window): Initialize orig_top and 1946 (make_window, replace_window): Initialize orig_top and
1947 orig_height. 1947 orig_height.
1948 (enlarge_window): Renamed from change_window_height. Make it 1948 (enlarge_window): Rename from change_window_height. Make it
1949 static. 1949 static.
1950 (Fdisplay_buffer, Fenlage_window, Fshrink_window): Call 1950 (Fdisplay_buffer, Fenlage_window, Fshrink_window):
1951 enlarge_window instead of change_window_height. 1951 Call enlarge_window instead of change_window_height.
1952 1952
1953 * window.h (struct window): New members orig_top, orig_height. 1953 * window.h (struct window): New members orig_top, orig_height.
1954 (toplevel): Add prototypes for grow_mini_window and 1954 (toplevel): Add prototypes for grow_mini_window and
@@ -2003,8 +2003,8 @@
2003 2003
2004 * xdisp.c (compute_window_start_on_continuation_line): Handle case 2004 * xdisp.c (compute_window_start_on_continuation_line): Handle case
2005 that window start is out of range. 2005 that window start is out of range.
2006 (handle_display_prop, handle_single_display_prop): Replace 2006 (handle_display_prop, handle_single_display_prop):
2007 marginal area specifications like `left-margin' with `(margin 2007 Replace marginal area specifications like `left-margin' with `(margin
2008 left-margin)'. 2008 left-margin)'.
2009 (Qmargin): New. 2009 (Qmargin): New.
2010 (syms_of_xdisp): Initialize Qmargin. 2010 (syms_of_xdisp): Initialize Qmargin.
@@ -2020,7 +2020,7 @@
2020 (Fopen_network_stream, create_process): Add parentheses to 2020 (Fopen_network_stream, create_process): Add parentheses to
2021 conditional expressions. 2021 conditional expressions.
2022 (create_process): Put declaration of sigchld in #if 0. 2022 (create_process): Put declaration of sigchld in #if 0.
2023 (Fopen_network_stream): Removed unused variables. 2023 (Fopen_network_stream): Remove unused variables.
2024 (Fopen_network_stream, wait_reading_process_input) 2024 (Fopen_network_stream, wait_reading_process_input)
2025 (wait_reading_process_input, send_process, send_process): Ditto. 2025 (wait_reading_process_input, send_process, send_process): Ditto.
2026 (toplevel): Add prototypes for set_waiting_for_input and 2026 (toplevel): Add prototypes for set_waiting_for_input and
@@ -2057,7 +2057,7 @@
2057 2057
2058 * buffer.h: Add prototype for r_re_alloc. 2058 * buffer.h: Add prototype for r_re_alloc.
2059 2059
2060 * insdel.c (copy_text): Removed unused variables. 2060 * insdel.c (copy_text): Remove unused variables.
2061 (count_combining_after, count_combining_after, insert_1_both) 2061 (count_combining_after, count_combining_after, insert_1_both)
2062 (insert_from_string_1, insert_from_buffer_1, check_markers): Ditto. 2062 (insert_from_string_1, insert_from_buffer_1, check_markers): Ditto.
2063 (adjust_after_replace, replace_range): Add parentheses to logical 2063 (adjust_after_replace, replace_range): Add parentheses to logical
@@ -2177,8 +2177,8 @@
2177 * xdisp.c (resize_mini_window): Don't report changed window 2177 * xdisp.c (resize_mini_window): Don't report changed window
2178 height if it actually hasn't changed. 2178 height if it actually hasn't changed.
2179 2179
2180 * widget.c (set_frame_size, EmacsFrameSetCharSize): Remove 2180 * widget.c (set_frame_size, EmacsFrameSetCharSize):
2181 unused variables. 2181 Remove unused variables.
2182 (mark_shell_size_user_specified): Put in #if 0 because not used. 2182 (mark_shell_size_user_specified): Put in #if 0 because not used.
2183 (create_frame_gcs): Put in #if 0 because currently unused. 2183 (create_frame_gcs): Put in #if 0 because currently unused.
2184 (first_frame_p): Ditto. 2184 (first_frame_p): Ditto.
@@ -2188,7 +2188,7 @@
2188 (free_frame_menubar, xmenu_show, xdialog_show): Remove unused 2188 (free_frame_menubar, xmenu_show, xdialog_show): Remove unused
2189 variables. 2189 variables.
2190 2190
2191 * print.c (PRINTFULLP): Removed because it is no longer used and 2191 * print.c (PRINTFULLP): Remove because it is no longer used and
2192 is misleading. 2192 is misleading.
2193 (Ferror_message_string): Remove unused variables. 2193 (Ferror_message_string): Remove unused variables.
2194 (print_object): Cast argument of sprintf to long for `%ld' 2194 (print_object): Cast argument of sprintf to long for `%ld'
@@ -2297,7 +2297,7 @@
2297 2297
2298 * xterm.c (XTcursor_to): Change for Lisp_Object selected_frame. 2298 * xterm.c (XTcursor_to): Change for Lisp_Object selected_frame.
2299 (x_clear_frame, XTring_bell, XTmouse_position, XTread_socket): Ditto. 2299 (x_clear_frame, XTring_bell, XTmouse_position, XTread_socket): Ditto.
2300 (XRINGBELL): Removed. 2300 (XRINGBELL): Remove.
2301 2301
23021999-09-13 Dave Love <fx@gnu.org> 23021999-09-13 Dave Love <fx@gnu.org>
2303 2303
@@ -2307,7 +2307,7 @@
2307 2307
23081999-09-13 Gerd Moellmann <gerd@delysid.gnu.org> 23081999-09-13 Gerd Moellmann <gerd@delysid.gnu.org>
2309 2309
2310 * xfns.c (QCfile): Moved to xdisp.c. 2310 * xfns.c (QCfile): Move to xdisp.c.
2311 (syms_of_xfns): Don't initialize QCfile. 2311 (syms_of_xfns): Don't initialize QCfile.
2312 (check_x_frame): Change for Lisp_Object selected_frame. 2312 (check_x_frame): Change for Lisp_Object selected_frame.
2313 (check_x_display_info, x_get_resource_string): Ditto. 2313 (check_x_display_info, x_get_resource_string): Ditto.
@@ -2317,7 +2317,7 @@
2317 * minibuf.c (choose_minibuf_frame): Don't try to set the 2317 * minibuf.c (choose_minibuf_frame): Don't try to set the
2318 mini-buffer window's buffer, if the buffer is invalid. 2318 mini-buffer window's buffer, if the buffer is invalid.
2319 2319
2320 * xfns.c (QCfile): Moved to xdisp.c. 2320 * xfns.c (QCfile): Move to xdisp.c.
2321 (syms_of_xfns): Don't initialize QCfile. 2321 (syms_of_xfns): Don't initialize QCfile.
2322 2322
2323 * xdisp.c (QCfile): Move here from xfns.c. 2323 * xdisp.c (QCfile): Move here from xfns.c.
@@ -2401,7 +2401,7 @@
2401 2401
2402 * xterm.c (XTcursor_to): Change for Lisp_Object selected_frame. 2402 * xterm.c (XTcursor_to): Change for Lisp_Object selected_frame.
2403 (x_clear_frame, XTring_bell, XTmouse_position, XTread_socket): Ditto. 2403 (x_clear_frame, XTring_bell, XTmouse_position, XTread_socket): Ditto.
2404 (XRINGBELL): Removed. 2404 (XRINGBELL): Remove.
2405 2405
2406 * window.c (Fminibuffer_window): Change for Lisp_Object 2406 * window.c (Fminibuffer_window): Change for Lisp_Object
2407 selected_frame. 2407 selected_frame.
@@ -2456,8 +2456,8 @@
2456 * keyboard.c (command_loop_1): Resize mini-window to the 2456 * keyboard.c (command_loop_1): Resize mini-window to the
2457 exact size of a message displayed, if any. 2457 exact size of a message displayed, if any.
2458 2458
2459 * xdisp.c (resize_mini_window): Add parameter exact_p. Resize 2459 * xdisp.c (resize_mini_window): Add parameter exact_p.
2460 to exact size if exact_p is non-zero. 2460 Resize to exact size if exact_p is non-zero.
2461 (display_echo_area_1): Call resize_mini_window with 2461 (display_echo_area_1): Call resize_mini_window with
2462 new parameter. 2462 new parameter.
2463 (redisplay_internal): Ditto. 2463 (redisplay_internal): Ditto.
@@ -2498,8 +2498,8 @@
2498 (Fkill_buffer): Ditto. 2498 (Fkill_buffer): Ditto.
2499 (Ferase_buffer): Ditto. 2499 (Ferase_buffer): Ditto.
2500 2500
2501 * buffer.h (prompt_end_charpos): Replaces 2501 * buffer.h (prompt_end_charpos):
2502 minibuffer_prompt_length. 2502 Replaces minibuffer_prompt_length.
2503 2503
2504 * minibuf.c (read_minibuf): Return mini-buffer contents 2504 * minibuf.c (read_minibuf): Return mini-buffer contents
2505 without the prompt. 2505 without the prompt.
@@ -2582,8 +2582,8 @@
2582 (x_load_font, x_find_ccl_program, x_term_init, x_delete_display): 2582 (x_load_font, x_find_ccl_program, x_term_init, x_delete_display):
2583 Likewise. 2583 Likewise.
2584 2584
2585 * alloc.c (make_float, make_pure_float, Fpurecopy): Use 2585 * alloc.c (make_float, make_pure_float, Fpurecopy):
2586 XFLOAT_DATA. 2586 Use XFLOAT_DATA.
2587 * bytecode.c (Fbyte_code): Likewise. 2587 * bytecode.c (Fbyte_code): Likewise.
2588 * floatfns.c (extract_float, Fexpt, Fabs, rounding_driver) 2588 * floatfns.c (extract_float, Fexpt, Fabs, rounding_driver)
2589 (fmod_float): Likewise. 2589 (fmod_float): Likewise.
@@ -2614,7 +2614,7 @@
26141999-09-10 Keisuke Nishida <kxn30@po.cwru.edu> 26141999-09-10 Keisuke Nishida <kxn30@po.cwru.edu>
2615 2615
2616 * print.c: Support print-circle and related features. 2616 * print.c: Support print-circle and related features.
2617 (Vprint_gensym_alist): Removed. 2617 (Vprint_gensym_alist): Remove.
2618 (Vprint_circle, Vprint_continuous_numbering, print_number_index) 2618 (Vprint_circle, Vprint_continuous_numbering, print_number_index)
2619 (Vprint_number_table): New variables. 2619 (Vprint_number_table): New variables.
2620 (PRINT_NUMBER_OBJECT, PRINT_NUMBER_STATUS): New macros. 2620 (PRINT_NUMBER_OBJECT, PRINT_NUMBER_STATUS): New macros.
@@ -2703,8 +2703,8 @@
2703 2703
27041999-09-07 Gerd Moellmann <gerd@gnu.org> 27041999-09-07 Gerd Moellmann <gerd@gnu.org>
2705 2705
2706 * xfns.c (x_set_foreground_color): Call 2706 * xfns.c (x_set_foreground_color):
2707 update_face_from_frame_parameter. 2707 Call update_face_from_frame_parameter.
2708 (x_set_background_color): Ditto. 2708 (x_set_background_color): Ditto.
2709 (x_set_mouse_color): Ditto. 2709 (x_set_mouse_color): Ditto.
2710 (x_set_cursor_color): Ditto. 2710 (x_set_cursor_color): Ditto.
@@ -2926,7 +2926,7 @@
2926 (Fset_window_start): Ditto. 2926 (Fset_window_start): Ditto.
2927 2927
2928 * xdisp.c (Vresize_mini_config, resize_mini_frame) 2928 * xdisp.c (Vresize_mini_config, resize_mini_frame)
2929 (resize_mini_initial_height): Removed. 2929 (resize_mini_initial_height): Remove.
2930 (syms_of_xdisp): Remove references to these variables. 2930 (syms_of_xdisp): Remove references to these variables.
2931 (resize_mini_window): Don't save window configuration, freeze 2931 (resize_mini_window): Don't save window configuration, freeze
2932 window starts instead. Enlarge window until displaying an empty 2932 window starts instead. Enlarge window until displaying an empty
@@ -2952,16 +2952,16 @@
2952 2952
2953 * xterm.c (x_scroll_bar_create): Don't clear under scroll bar 2953 * xterm.c (x_scroll_bar_create): Don't clear under scroll bar
2954 here. 2954 here.
2955 (XTset_vertical_scroll_bar): Clarify position computations. Clear 2955 (XTset_vertical_scroll_bar): Clarify position computations.
2956 under newly created scroll bar. Put toolkit scroll bars in the 2956 Clear under newly created scroll bar. Put toolkit scroll bars in the
2957 middle of the area reserved for the scroll bar. 2957 middle of the area reserved for the scroll bar.
2958 2958
29591999-09-03 Kenichi Handa <handa@etl.go.jp> 29591999-09-03 Kenichi Handa <handa@etl.go.jp>
2960 2960
2961 The following changes are for the new handling of multibyte 2961 The following changes are for the new handling of multibyte
2962 sequence. Now, except for a composite character, no multibyte 2962 sequence. Now, except for a composite character, no multibyte
2963 character in string/buffer has trailing garbage bytes. For 2963 character in string/buffer has trailing garbage bytes.
2964 instance, the length of string "\201\300\300" is now 2, the first 2964 For instance, the length of string "\201\300\300" is now 2, the first
2965 character is Latin-1 A-grave, the second is raw \300. 2965 character is Latin-1 A-grave, the second is raw \300.
2966 2966
2967 * charset.h (MAKE_NON_ASCII_CHAR): Handle the case that C1 or C2 2967 * charset.h (MAKE_NON_ASCII_CHAR): Handle the case that C1 or C2
@@ -2972,7 +2972,7 @@
2972 (PARSE_CHARACTER_SEQ): New macro. 2972 (PARSE_CHARACTER_SEQ): New macro.
2973 (PARSE_MULTIBYTE_SEQ): New macro. 2973 (PARSE_MULTIBYTE_SEQ): New macro.
2974 (CHAR_PRINTABLE_P): New macro. 2974 (CHAR_PRINTABLE_P): New macro.
2975 (STRING_CHAR): Adjusted for the change of string_to_non_ascii_char. 2975 (STRING_CHAR): Adjust for the change of string_to_non_ascii_char.
2976 (STRING_CHAR_AND_LENGTH): Likewise. 2976 (STRING_CHAR_AND_LENGTH): Likewise.
2977 (STRING_CHAR_AND_CHAR_LENGTH): Define it as STRING_CHAR_AND_LENGTH. 2977 (STRING_CHAR_AND_CHAR_LENGTH): Define it as STRING_CHAR_AND_LENGTH.
2978 (INC_POS): Use the macro PARSE_MULTIBYTE_SEQ. 2978 (INC_POS): Use the macro PARSE_MULTIBYTE_SEQ.
@@ -3016,8 +3016,8 @@
3016 3016
3017 * insdel.c (count_combining_composition): New function. 3017 * insdel.c (count_combining_composition): New function.
3018 (count_combining_before): Adjust the way to check byte-combining 3018 (count_combining_before): Adjust the way to check byte-combining
3019 possibility for the new handling of multibyte sequence. Call 3019 possibility for the new handling of multibyte sequence.
3020 count_combining_composition for a composite character. 3020 Call count_combining_composition for a composite character.
3021 (count_combining_after): Likewise. 3021 (count_combining_after): Likewise.
3022 3022
3023 * print.c (print_string): Use the macro STRING_CHAR_AND_LENGTH. 3023 * print.c (print_string): Use the macro STRING_CHAR_AND_LENGTH.
@@ -3093,8 +3093,8 @@
3093 (window_box_left): Use FRAME_LEFT_FLAGS_AREA_WIDTH instead of 3093 (window_box_left): Use FRAME_LEFT_FLAGS_AREA_WIDTH instead of
3094 FRAME_FLAGS_AREA_WIDTH. 3094 FRAME_FLAGS_AREA_WIDTH.
3095 3095
3096 * window.c (coordinates_in_window): Use 3096 * window.c (coordinates_in_window):
3097 FRAME_LEFT_FLAGS_AREA_WIDTH instead of FRAME_FLAGS_AREA_WIDTH. 3097 Use FRAME_LEFT_FLAGS_AREA_WIDTH instead of FRAME_FLAGS_AREA_WIDTH.
3098 (window_internal_width): Subtract FRAME_FLAGS_AREA_WIDTH once 3098 (window_internal_width): Subtract FRAME_FLAGS_AREA_WIDTH once
3099 instead of twice. 3099 instead of twice.
3100 3100
@@ -3105,14 +3105,14 @@
3105 * dispnew.c (mode_line_string): Add FRAME_LEFT_FLAGS_AREA_WIDTH 3105 * dispnew.c (mode_line_string): Add FRAME_LEFT_FLAGS_AREA_WIDTH
3106 instead of FRAME_FLAGS_AREA_WIDTH. 3106 instead of FRAME_FLAGS_AREA_WIDTH.
3107 3107
3108 * dispextern.h (WINDOW_DISPLAY_PIXEL_WIDTH): Subtract 3108 * dispextern.h (WINDOW_DISPLAY_PIXEL_WIDTH):
3109 FRAME_FLAGS_AREA_COLS once. 3109 Subtract FRAME_FLAGS_AREA_COLS once.
3110 (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X): Add 3110 (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X):
3111 FRAME_LEFT_FLAGS_AREA_WIDTH instead of FRAME_FLAGS_AREA_WIDTH. 3111 Add FRAME_LEFT_FLAGS_AREA_WIDTH instead of FRAME_FLAGS_AREA_WIDTH.
3112 3112
31131999-08-30 Gerd Moellmann <gerd@gnu.org> 31131999-08-30 Gerd Moellmann <gerd@gnu.org>
3114 3114
3115 * s/freebsd.h (C_SWITCH_SYSTEM): Added to let configure find headers 3115 * s/freebsd.h (C_SWITCH_SYSTEM): Add to let configure find headers
3116 in /usr/X11R6/include which are checked for with AC_CHECK_HEADER. 3116 in /usr/X11R6/include which are checked for with AC_CHECK_HEADER.
3117 3117
31181999-08-30 Gerd Moellmann <gerd@gnu.org> 31181999-08-30 Gerd Moellmann <gerd@gnu.org>
@@ -3139,8 +3139,8 @@
3139 3139
31401999-08-28 Ken Raeburn <raeburn@gnu.org> 31401999-08-28 Ken Raeburn <raeburn@gnu.org>
3141 3141
3142 * lisp.h (struct Lisp_Cons, XCAR, XCDR, struct Lisp_Float): Change 3142 * lisp.h (struct Lisp_Cons, XCAR, XCDR, struct Lisp_Float):
3143 names of structure elements if HIDE_LISP_IMPLEMENTATION is 3143 Change names of structure elements if HIDE_LISP_IMPLEMENTATION is
3144 defined, to help detect code that uses knowledge of the Lisp 3144 defined, to help detect code that uses knowledge of the Lisp
3145 internals that it shouldn't have. 3145 internals that it shouldn't have.
3146 (XFLOAT_DATA): New macro. 3146 (XFLOAT_DATA): New macro.
@@ -3226,8 +3226,8 @@
3226 3226
32271999-08-22 Gerd Moellmann <gerd@gnu.org> 32271999-08-22 Gerd Moellmann <gerd@gnu.org>
3228 3228
3229 * xdisp.c (unwind_with_echo_area_buffer): Use 3229 * xdisp.c (unwind_with_echo_area_buffer):
3230 set_buffer_internal_1 instead of set_buffer_internal. 3230 Use set_buffer_internal_1 instead of set_buffer_internal.
3231 (with_echo_area_buffer): Ditto. 3231 (with_echo_area_buffer): Ditto.
3232 3232
3233 * buffer.c (set_buffer_internal): Set windows_or_buffers_changed 3233 * buffer.c (set_buffer_internal): Set windows_or_buffers_changed
@@ -3255,8 +3255,8 @@
3255 (mark_window_display_accurate, redisplay_internal): Set current 3255 (mark_window_display_accurate, redisplay_internal): Set current
3256 matrix' buffer, begv, zv. 3256 matrix' buffer, begv, zv.
3257 3257
3258 * window.c (Fset_window_hscroll): Set 3258 * window.c (Fset_window_hscroll):
3259 prevent_redisplay_optimizations_p instead of clip_changed. 3259 Set prevent_redisplay_optimizations_p instead of clip_changed.
3260 (Fset_window_hscroll): Ditto. 3260 (Fset_window_hscroll): Ditto.
3261 (temp_output_buffer_show): Ditto. 3261 (temp_output_buffer_show): Ditto.
3262 (Fset_window_vscroll): Ditto. 3262 (Fset_window_vscroll): Ditto.
@@ -3273,7 +3273,7 @@
3273 unchanged_modified, overlay_unchanged_modified. 3273 unchanged_modified, overlay_unchanged_modified.
3274 3274
3275 * window.h (beg_unchanged, end_unchanged, unchanged_modified) 3275 * window.h (beg_unchanged, end_unchanged, unchanged_modified)
3276 (overlay_unchanged_modified): Removed. 3276 (overlay_unchanged_modified): Remove.
3277 (with_echo_area_unwind_data): Don't save beg/end_unchanged. 3277 (with_echo_area_unwind_data): Don't save beg/end_unchanged.
3278 (unwind_with_echo_area_buffer): Don't restore them. 3278 (unwind_with_echo_area_buffer): Don't restore them.
3279 (debug_beg_unchanged, debug_end_unchanged) [GLYPH_DEBUG]: Removed. 3279 (debug_beg_unchanged, debug_end_unchanged) [GLYPH_DEBUG]: Removed.
@@ -3310,8 +3310,8 @@
3310 3310
3311 * lisp.h: Add prototype for copy_hash_table and Fcopy_hash_table. 3311 * lisp.h: Add prototype for copy_hash_table and Fcopy_hash_table.
3312 3312
3313 * fns.c (Qkey, Qvalue): Renamed from Qkey_weak, and Qvalue_weak. 3313 * fns.c (Qkey, Qvalue): Rename from Qkey_weak, and Qvalue_weak.
3314 (Qkey_value_weak): Removed. 3314 (Qkey_value_weak): Remove.
3315 (make_hash_table): Use nil, `key', `value', t for weakness. 3315 (make_hash_table): Use nil, `key', `value', t for weakness.
3316 (Fmake_hash_table): Ditto. 3316 (Fmake_hash_table): Ditto.
3317 (copy_hash_table): New. 3317 (copy_hash_table): New.
@@ -3336,7 +3336,7 @@
3336 * fns.c (hash_lookup): Test with EQ before calling key comparison 3336 * fns.c (hash_lookup): Test with EQ before calling key comparison
3337 function. 3337 function.
3338 (hash_remove): Ditto. 3338 (hash_remove): Ditto.
3339 (cmpfn_eq): Removed. 3339 (cmpfn_eq): Remove.
3340 (cmpfn_eql): Don't test with EQ. 3340 (cmpfn_eql): Don't test with EQ.
3341 (cmpfn_equal): Ditto. 3341 (cmpfn_equal): Ditto.
3342 (make_hash_table): Set comparison function for `eq' to null. 3342 (make_hash_table): Set comparison function for `eq' to null.
@@ -3344,7 +3344,7 @@
3344 * buffer.c, cmds.c, editfns.c, indent.c, insdel.c, buffer.h: 3344 * buffer.c, cmds.c, editfns.c, indent.c, insdel.c, buffer.h:
3345 Remove conditional compilation on NO_PROMPT_IN_BUFFER. 3345 Remove conditional compilation on NO_PROMPT_IN_BUFFER.
3346 3346
3347 * dispextern.h (NO_PROMPT_IN_BUFFER): Removed. 3347 * dispextern.h (NO_PROMPT_IN_BUFFER): Remove.
3348 3348
3349 * window.c, widget.c, process.c, keyboard.c, frame.c, xdisp.c, 3349 * window.c, widget.c, process.c, keyboard.c, frame.c, xdisp.c,
3350 xterm.c: Call change_frame_size and do_pending_window_change with 3350 xterm.c: Call change_frame_size and do_pending_window_change with
@@ -3369,8 +3369,8 @@
3369 NO_PROMPT_IN_BUFFER. 3369 NO_PROMPT_IN_BUFFER.
3370 3370
3371 * minibuf.c (Fminibuffer_prompt_end): New. 3371 * minibuf.c (Fminibuffer_prompt_end): New.
3372 (syms_of_minibuf): Defsubr it. Remove 3372 (syms_of_minibuf): Defsubr it.
3373 minibuffer-prompt-in-buffer. 3373 Remove minibuffer-prompt-in-buffer.
3374 (Fminibuffer_prompt_width): Return 0 if not in mini-buffer. 3374 (Fminibuffer_prompt_width): Return 0 if not in mini-buffer.
3375 Extend documentation. 3375 Extend documentation.
3376 3376
@@ -3381,7 +3381,7 @@
3381 3381
33821999-08-21 Gerd Moellmann <gerd@gnu.org> 33821999-08-21 Gerd Moellmann <gerd@gnu.org>
3383 3383
3384 * xdisp.c (minibuffer_scroll_overlap): Removed because not used 3384 * xdisp.c (minibuffer_scroll_overlap): Remove because not used
3385 anywhere. 3385 anywhere.
3386 (unwind_redisplay): Return nil. 3386 (unwind_redisplay): Return nil.
3387 (clear_garbaged_frames): New. 3387 (clear_garbaged_frames): New.
@@ -3400,7 +3400,7 @@
3400 * xdisp.c (echo_area_glyphs, echo_area_message) 3400 * xdisp.c (echo_area_glyphs, echo_area_message)
3401 (echo_area_glyphs_length, previous_echo_glyphs) 3401 (echo_area_glyphs_length, previous_echo_glyphs)
3402 (previous_echo_area_message, previous_echo_area_glyphs_length): 3402 (previous_echo_area_message, previous_echo_area_glyphs_length):
3403 Removed. 3403 Remove.
3404 (Vmessage_stack, echo_area_buffer, echo_buffer) 3404 (Vmessage_stack, echo_area_buffer, echo_buffer)
3405 (display_last_displayed_message_p, Vwith_echo_area_save_vector): New. 3405 (display_last_displayed_message_p, Vwith_echo_area_save_vector): New.
3406 (message2_nolog): Use set_message and clear_message. 3406 (message2_nolog): Use set_message and clear_message.
@@ -3426,7 +3426,7 @@
3426 Remove initialization of removed variables. 3426 Remove initialization of removed variables.
3427 (init_xdisp): Remove references to removed variables. 3427 (init_xdisp): Remove references to removed variables.
3428 3428
3429 * dispnew.c (adjust_frame_message_buffer): Removed references 3429 * dispnew.c (adjust_frame_message_buffer): Remove references
3430 to echo_area_glyphs and previous_echo_glyphs. 3430 to echo_area_glyphs and previous_echo_glyphs.
3431 (direct_output_for_insert): Check for mini-window displaying 3431 (direct_output_for_insert): Check for mini-window displaying
3432 echo area message differently. 3432 echo area message differently.
@@ -3440,7 +3440,7 @@
3440 longer used in that way. 3440 longer used in that way.
3441 (PRINTDECLARE): Add multibyte. 3441 (PRINTDECLARE): Add multibyte.
3442 (PRINTPREPARE, PRINTFINISH): Handle printcharfun t differently. 3442 (PRINTPREPARE, PRINTFINISH): Handle printcharfun t differently.
3443 (printbufidx): Removed. 3443 (printbufidx): Remove.
3444 (printchar, strout): Rewritten. 3444 (printchar, strout): Rewritten.
3445 3445
3446 * keyboard.c (ok_to_echo_at_next_pause): Make it a pointer to 3446 * keyboard.c (ok_to_echo_at_next_pause): Make it a pointer to
@@ -3493,8 +3493,8 @@
3493 3493
34941999-08-19 Gerd Moellmann <gerd@gnu.org> 34941999-08-19 Gerd Moellmann <gerd@gnu.org>
3495 3495
3496 * xterm.c (XTset_vertical_scroll_bar): Fix previous change. Clear 3496 * xterm.c (XTset_vertical_scroll_bar): Fix previous change.
3497 under scroll bar with width FRAME_SCROLL_BAR_COLS. 3497 Clear under scroll bar with width FRAME_SCROLL_BAR_COLS.
3498 3498
34991999-08-18 Dave Love <fx@gnu.org> 34991999-08-18 Dave Love <fx@gnu.org>
3500 3500
@@ -3511,8 +3511,8 @@
3511 3511
3512 * xfns.c (x_window) [USE_X_TOOLKIT]: Remove test for 3512 * xfns.c (x_window) [USE_X_TOOLKIT]: Remove test for
3513 FRAME_X_WINDOW (f) being null at the of the function. If widgets 3513 FRAME_X_WINDOW (f) being null at the of the function. If widgets
3514 cannot be created we will already have crashed earlier. Call 3514 cannot be created we will already have crashed earlier.
3515 lw_set_main_areas with a null menu-bar widget, so that we have 3515 Call lw_set_main_areas with a null menu-bar widget, so that we have
3516 a reasonable default. 3516 a reasonable default.
3517 (Fx_create_frame): Rearranged so that Lisp errors during frame 3517 (Fx_create_frame): Rearranged so that Lisp errors during frame
3518 initialization cause less damage. Initialize menu bar widget 3518 initialization cause less damage. Initialize menu bar widget
@@ -3526,8 +3526,8 @@
35261999-08-17 Gerd Moellmann <gerd@gnu.org> 35261999-08-17 Gerd Moellmann <gerd@gnu.org>
3527 3527
3528 * window.c (Fcoordinates_in_window_p): Return `left-bitmap-area' 3528 * window.c (Fcoordinates_in_window_p): Return `left-bitmap-area'
3529 and `right-bitmap-area' if position is in the bitmap areas. This 3529 and `right-bitmap-area' if position is in the bitmap areas.
3530 avoids an error when clicking on the bitmap areas. Instead, they 3530 This avoids an error when clicking on the bitmap areas. Instead, they
3531 are currently treated like clicks inside the window. 3531 are currently treated like clicks inside the window.
3532 (coordinates_in_window): Return 5 and 6 for bitmap areas. 3532 (coordinates_in_window): Return 5 and 6 for bitmap areas.
3533 (Qleft_bitmap_area, Qright_bitmap_area): New. 3533 (Qleft_bitmap_area, Qright_bitmap_area): New.
@@ -3553,14 +3553,14 @@
3553 * dispextern.h (struct it): Remove member 3553 * dispextern.h (struct it): Remove member
3554 show_trailing_whitespace_p. 3554 show_trailing_whitespace_p.
3555 3555
3556 * dispnew.c (direct_output_for_insert): Use 3556 * dispnew.c (direct_output_for_insert):
3557 Vshow_trailing_whitespace instead of former iterator member 3557 Use Vshow_trailing_whitespace instead of former iterator member
3558 show_trailing_whitespace_p. 3558 show_trailing_whitespace_p.
3559 (direct_output_forward_char): Don't do it if highlighting 3559 (direct_output_forward_char): Don't do it if highlighting
3560 trailing whitespace. 3560 trailing whitespace.
3561 3561
3562 * xdisp.c (Qshow_trailing_whitespace): Removed. 3562 * xdisp.c (Qshow_trailing_whitespace): Remove.
3563 (Vshow_trailing_whitespace): Added. 3563 (Vshow_trailing_whitespace): Add.
3564 (init_iterator): Remove initialization code for 3564 (init_iterator): Remove initialization code for
3565 show_trailing_whitespace_p. 3565 show_trailing_whitespace_p.
3566 (redisplay_internal): Don't try cursor movement in this_line 3566 (redisplay_internal): Don't try cursor movement in this_line
@@ -3578,7 +3578,7 @@
3578 3578
3579 * window.c (Fpos_visible_in_window_p): Rewritten. 3579 * window.c (Fpos_visible_in_window_p): Rewritten.
3580 3580
3581 * xfaces.c (add_to_log): Renamed from display_message. 3581 * xfaces.c (add_to_log): Rename from display_message.
3582 Don't display messages in echo area. 3582 Don't display messages in echo area.
3583 3583
3584 * xterm.c (x_draw_glyph_string_box): Use the background width 3584 * xterm.c (x_draw_glyph_string_box): Use the background width
@@ -3650,7 +3650,7 @@
3650 3650
36511999-08-13 Gerd Moellmann <gerd@gnu.org> 36511999-08-13 Gerd Moellmann <gerd@gnu.org>
3652 3652
3653 * window.c (MINSIZE): Removed. 3653 * window.c (MINSIZE): Remove.
3654 (window_min_size): New. 3654 (window_min_size): New.
3655 (set_window_height): Use window_min_size. 3655 (set_window_height): Use window_min_size.
3656 (change_window_height): Ditto. 3656 (change_window_height): Ditto.
@@ -3819,8 +3819,8 @@
3819 3819
3820 * dispextern.h (MATRIX_ROW_OVERLAPPING_P): New. 3820 * dispextern.h (MATRIX_ROW_OVERLAPPING_P): New.
3821 3821
3822 * dispextern.h (struct redisplay_interface): Add 3822 * dispextern.h (struct redisplay_interface):
3823 fix_overlapping_area. 3823 Add fix_overlapping_area.
3824 3824
3825 * xterm.c (x_append_glyph): Set glyph flag overlaps_vertically_p. 3825 * xterm.c (x_append_glyph): Set glyph flag overlaps_vertically_p.
3826 3826
@@ -3869,7 +3869,7 @@
3869 3869
38701999-08-03 Tom Breton <tob@world.std.com> 38701999-08-03 Tom Breton <tob@world.std.com>
3871 3871
3872 * lread.c (read1): Added circular reading code to #N=. 3872 * lread.c (read1): Add circular reading code to #N=.
3873 (SUBSTITUTE): New macro. 3873 (SUBSTITUTE): New macro.
3874 (seen_list): New variable. 3874 (seen_list): New variable.
3875 (substitute_object_in_subtree): New function. 3875 (substitute_object_in_subtree): New function.
@@ -4068,7 +4068,7 @@
4068 * ccl.c (ccl_driver) <CCL_Call>: Now CCL program ID to call may be 4068 * ccl.c (ccl_driver) <CCL_Call>: Now CCL program ID to call may be
4069 stored in the following CCL code. Adjusted for the change of 4069 stored in the following CCL code. Adjusted for the change of
4070 Vccl_program_table. 4070 Vccl_program_table.
4071 (resolve_symbol_ccl_program): Adjusted for the new style of 4071 (resolve_symbol_ccl_program): Adjust for the new style of
4072 embedded symbols (SYMBOL . PROP) in CCL compiled code. Return Qt 4072 embedded symbols (SYMBOL . PROP) in CCL compiled code. Return Qt
4073 is resolving failed. 4073 is resolving failed.
4074 (ccl_get_compiled_code): New function. 4074 (ccl_get_compiled_code): New function.
@@ -4078,7 +4078,7 @@
4078 (Fccl_execute): Get compiled CCL code by just calling 4078 (Fccl_execute): Get compiled CCL code by just calling
4079 setup_ccl_program. 4079 setup_ccl_program.
4080 (Fccl_execute_on_string): Likewise. 4080 (Fccl_execute_on_string): Likewise.
4081 (Fregister_ccl_program): Adjusted for the change of 4081 (Fregister_ccl_program): Adjust for the change of
4082 Vccl_program_table. 4082 Vccl_program_table.
4083 4083
4084 * coding.c (setup_coding_system): Get compiled CCL code by just 4084 * coding.c (setup_coding_system): Get compiled CCL code by just
@@ -4125,7 +4125,7 @@
4125 * xrdb.c (x_load_resources): Set double-click time defaults 4125 * xrdb.c (x_load_resources): Set double-click time defaults
4126 for Motif list boxes from double-click-time. 4126 for Motif list boxes from double-click-time.
4127 4127
4128 * fns.c (Vhash_table_tests): Removed. 4128 * fns.c (Vhash_table_tests): Remove.
4129 (Qhash_table_test): New. 4129 (Qhash_table_test): New.
4130 (syms_of_fns): Initialize Qhash_table_test. 4130 (syms_of_fns): Initialize Qhash_table_test.
4131 (Fmake_hash_table): Look up user-defined tests in symbol prop 4131 (Fmake_hash_table): Look up user-defined tests in symbol prop
@@ -4152,7 +4152,7 @@
4152 4152
41531999-07-16 Gerd Moellmann <gerd@gnu.org> 41531999-07-16 Gerd Moellmann <gerd@gnu.org>
4154 4154
4155 * frame.h (FRAME_WINDOW_REDISPLAY_P): Removed. Use FRAME_WINDOW_P 4155 * frame.h (FRAME_WINDOW_REDISPLAY_P): Remove. Use FRAME_WINDOW_P
4156 instead. 4156 instead.
4157 4157
4158 * fns.c (cmpfn_eq): Add hash code parameters. 4158 * fns.c (cmpfn_eq): Add hash code parameters.
@@ -4162,7 +4162,7 @@
4162 4162
41631999-07-15 Gerd Moellmann <gerd@gnu.org> 41631999-07-15 Gerd Moellmann <gerd@gnu.org>
4164 4164
4165 * lisp.h (DEFAULT_REHASH_THRESHOLD): Changed to 0.8. 4165 * lisp.h (DEFAULT_REHASH_THRESHOLD): Change to 0.8.
4166 4166
4167 * fns.c (maybe_resize_hash_table): Correct computation of 4167 * fns.c (maybe_resize_hash_table): Correct computation of
4168 index vector size. 4168 index vector size.
@@ -4175,19 +4175,19 @@
4175 (survives_gc_p): Make it externally visible. 4175 (survives_gc_p): Make it externally visible.
4176 (mark_object): Ditto. 4176 (mark_object): Ditto.
4177 4177
4178 * fns.c (remove_hash_entry): Removed. 4178 * fns.c (remove_hash_entry): Remove.
4179 (sweep_weak_hash_tables): New. 4179 (sweep_weak_hash_tables): New.
4180 4180
4181 * print.c (print): Print more information about hash tables. 4181 * print.c (print): Print more information about hash tables.
4182 4182
4183 * xfns.c (image_spec_hash): Removed. 4183 * xfns.c (image_spec_hash): Remove.
4184 (lookup_image): Use sxhash instead of image_spec_hash. 4184 (lookup_image): Use sxhash instead of image_spec_hash.
4185 (image_spec_equal_p): Removed. 4185 (image_spec_equal_p): Remove.
4186 (lookup_image): Use Fequal instead of image_spec_equal_p. 4186 (lookup_image): Use Fequal instead of image_spec_equal_p.
4187 4187
41881999-07-14 Gerd Moellmann <gerd@gnu.org> 41881999-07-14 Gerd Moellmann <gerd@gnu.org>
4189 4189
4190 * lisp.h (P_): Moved to top of file. 4190 * lisp.h (P_): Move to top of file.
4191 4191
4192 * fns.c (make_hash_table): Set new members. 4192 * fns.c (make_hash_table): Set new members.
4193 4193
@@ -4197,8 +4197,8 @@
4197 * lisp.h (struct Lisp_Hash_Table): Add user_cmp_function, 4197 * lisp.h (struct Lisp_Hash_Table): Add user_cmp_function,
4198 user_hash_function, cmpfn, and hashfn. 4198 user_hash_function, cmpfn, and hashfn.
4199 4199
4200 * fns.c (build_hash): Removed. 4200 * fns.c (build_hash): Remove.
4201 (hash_test): Removed. 4201 (hash_test): Remove.
4202 (cmpfn_eq, cmpfn_eql, cmpfn_equal, cmpfn_user_defined): New. 4202 (cmpfn_eq, cmpfn_eql, cmpfn_equal, cmpfn_user_defined): New.
4203 (hashfn_eq, hashfn_eql, hashfn_equal, hashfn_user_defined): New. 4203 (hashfn_eq, hashfn_eql, hashfn_equal, hashfn_user_defined): New.
4204 4204
@@ -4261,7 +4261,7 @@
4261 properties. 4261 properties.
4262 (handle_single_display_prop): Handle some display property 4262 (handle_single_display_prop): Handle some display property
4263 forms for terminal frames. 4263 forms for terminal frames.
4264 (Qimage): Moved here from xfns.c. 4264 (Qimage): Move here from xfns.c.
4265 4265
4266 * dispextern.h (struct it): New field string_from_display_prop_p. 4266 * dispextern.h (struct it): New field string_from_display_prop_p.
4267 4267
@@ -4331,8 +4331,8 @@
4331 4331
43321999-07-05 Gerd Moellmann <gerd@gnu.org> 43321999-07-05 Gerd Moellmann <gerd@gnu.org>
4333 4333
4334 * term.c (TS_cursor_visible): Renamed from TS_visual_mode. 4334 * term.c (TS_cursor_visible): Rename from TS_visual_mode.
4335 (TS_cursor_normal): Renamed from TS_end_visual_mode. 4335 (TS_cursor_normal): Rename from TS_end_visual_mode.
4336 (TS_cursor_invisible): New. 4336 (TS_cursor_invisible): New.
4337 (term_init): Initialize TS_cursor_invisible. 4337 (term_init): Initialize TS_cursor_invisible.
4338 (tty_hide_cursor): New. 4338 (tty_hide_cursor): New.
@@ -4364,7 +4364,7 @@
4364 4364
43651999-07-02 Gerd Moellmann <gerd@gnu.org> 43651999-07-02 Gerd Moellmann <gerd@gnu.org>
4366 4366
4367 * dispextern.h (HSCROLL_WINDOWS): Removed. 4367 * dispextern.h (HSCROLL_WINDOWS): Remove.
4368 4368
4369 * xdisp.c (mark_window_display_accurate): Don't set 4369 * xdisp.c (mark_window_display_accurate): Don't set
4370 w->region_showing. 4370 w->region_showing.
@@ -4378,12 +4378,12 @@
4378 up when cursor is partially visible, make it fully visible. 4378 up when cursor is partially visible, make it fully visible.
4379 (mark_window_display_accurate): Some cleanup. Record window's 4379 (mark_window_display_accurate): Some cleanup. Record window's
4380 last cursor information. 4380 last cursor information.
4381 (debug_method_add): Improved. 4381 (debug_method_add): Improve.
4382 (redisplay_internal): Record last cursor info only if not 4382 (redisplay_internal): Record last cursor info only if not
4383 consider_all_windows_p. 4383 consider_all_windows_p.
4384 4384
4385 * dispnew.c (update_window): Update top line after scrolling. 4385 * dispnew.c (update_window): Update top line after scrolling.
4386 (blank_row): Renamed from make_empty_enabled_row. 4386 (blank_row): Rename from make_empty_enabled_row.
4387 (increment_glyph_row_buffer_positions): Increment positions 4387 (increment_glyph_row_buffer_positions): Increment positions
4388 in buffers, only. 4388 in buffers, only.
4389 4389
@@ -4406,7 +4406,7 @@
4406 * dispextern.h (struct glyph_matrix): Add member window_vscroll. 4406 * dispextern.h (struct glyph_matrix): Add member window_vscroll.
4407 4407
4408 * xdisp.c (debug_method_add): New. 4408 * xdisp.c (debug_method_add): New.
4409 (debug_redisplay_method): Removed. 4409 (debug_redisplay_method): Remove.
4410 (try_window_reusing_current_matrix): Handle case where old 4410 (try_window_reusing_current_matrix): Handle case where old
4411 window start is the same as new window start. 4411 window start is the same as new window start.
4412 4412
@@ -4550,8 +4550,8 @@
4550 (CURRENT_TOP_LINE_HEIGHT): New. 4550 (CURRENT_TOP_LINE_HEIGHT): New.
4551 (DESIRED_TOP_LINE_HEIGHT): New. 4551 (DESIRED_TOP_LINE_HEIGHT): New.
4552 (WINDOW_DISPLAY_TOP_LINE_HEIGHT): New. 4552 (WINDOW_DISPLAY_TOP_LINE_HEIGHT): New.
4553 (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE): Replaces 4553 (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE):
4554 WINDOW_DISPLAY_TEXT_AREA_PIXEL_HEIGHT. 4554 Replaces WINDOW_DISPLAY_TEXT_AREA_PIXEL_HEIGHT.
4555 (WINDOW_DISPLAY_TEXT_HEIGHT): New. 4555 (WINDOW_DISPLAY_TEXT_HEIGHT): New.
4556 4556
4557 * xterm.c (x_after_update_window_line): Don't draw bitmaps for top 4557 * xterm.c (x_after_update_window_line): Don't draw bitmaps for top
@@ -4562,8 +4562,8 @@
4562 x_frame_mode_line_height. 4562 x_frame_mode_line_height.
4563 (x_get_glyph_string_clip_rect): Take top line into account. 4563 (x_get_glyph_string_clip_rect): Take top line into account.
4564 (x_clear_end_of_line): Ditto. 4564 (x_clear_end_of_line): Ditto.
4565 (note_mode_line_highlight): Add parameter mode_line_p. Handle 4565 (note_mode_line_highlight): Add parameter mode_line_p.
4566 top lines. 4566 Handle top lines.
4567 (note_mouse_highlight): Call note_mode_line_highlight for top lines. 4567 (note_mouse_highlight): Call note_mode_line_highlight for top lines.
4568 (x_erase_phys_cursor): Take top line into account. 4568 (x_erase_phys_cursor): Take top line into account.
4569 4569
@@ -4578,12 +4578,12 @@
4578 4578
4579 * xterm.c (x_frame_mode_line_height): Add parameter face_id. 4579 * xterm.c (x_frame_mode_line_height): Add parameter face_id.
4580 4580
4581 * term.c (estimate_mode_line_height): Renamed from 4581 * term.c (estimate_mode_line_height): Rename from
4582 frame_mode_line_height. Add parameter face_id. 4582 frame_mode_line_height. Add parameter face_id.
4583 (estimate_mode_line_height_hook): Renamed from 4583 (estimate_mode_line_height_hook): Rename from
4584 frame_mode_line_height_hook. 4584 frame_mode_line_height_hook.
4585 (produce_special_glyphs_hook): Removed. 4585 (produce_special_glyphs_hook): Remove.
4586 (produce_glyphs_hook): Removed. 4586 (produce_glyphs_hook): Remove.
4587 4587
45881999-06-23 Gerd Moellmann <gerd@gnu.org> 45881999-06-23 Gerd Moellmann <gerd@gnu.org>
4589 4589
@@ -4604,7 +4604,7 @@
4604 4604
4605 * buffer.h: Add top_line_format. 4605 * buffer.h: Add top_line_format.
4606 4606
4607 * xdisp.c (overlay_arrow_changed_p): Removed because not used. 4607 * xdisp.c (overlay_arrow_changed_p): Remove because not used.
4608 4608
46091999-06-17 Dave Love <fx@gnu.org> 46091999-06-17 Dave Love <fx@gnu.org>
4610 4610
@@ -4629,8 +4629,8 @@
4629 4629
4630 * Makefile.in (LIBGIF): Use libungif. 4630 * Makefile.in (LIBGIF): Use libungif.
4631 4631
4632 * xdisp.c (compute_window_start_on_continuation_line): Don't 4632 * xdisp.c (compute_window_start_on_continuation_line):
4633 do it if line start is too far away from window start. 4633 Don't do it if line start is too far away from window start.
4634 4634
46351999-06-14 Gerd Moellmann <gerd@gnu.org> 46351999-06-14 Gerd Moellmann <gerd@gnu.org>
4636 4636
@@ -4714,8 +4714,8 @@
4714 * xfaces.c (SCALABLE_FONTS): Define this to enable scalable 4714 * xfaces.c (SCALABLE_FONTS): Define this to enable scalable
4715 font support. 4715 font support.
4716 (Vscalable_fonts_allowed) [SCALABLE_FONTS]: New. 4716 (Vscalable_fonts_allowed) [SCALABLE_FONTS]: New.
4717 (x_face_list_fonts): Add parameter scalable_fonts_p. Handle 4717 (x_face_list_fonts): Add parameter scalable_fonts_p.
4718 scalable fonts depending on the setting of SCALABLE_FONTS. 4718 Handle scalable fonts depending on the setting of SCALABLE_FONTS.
4719 (first_font_matching): List more than one font to find the 4719 (first_font_matching): List more than one font to find the
4720 first non-scalable matching font. 4720 first non-scalable matching font.
4721 (sorted_font_list): Let x_face_list_fonts return scalable fonts 4721 (sorted_font_list): Let x_face_list_fonts return scalable fonts
@@ -4730,8 +4730,8 @@
4730 4730
47311999-05-26 Gerd Moellmann <gerd@gnu.org> 47311999-05-26 Gerd Moellmann <gerd@gnu.org>
4732 4732
4733 * xfns.c (png_load): Let PNG lib handle gamma. Construct 4733 * xfns.c (png_load): Let PNG lib handle gamma.
4734 mask only if image contains simple transparency information. 4734 Construct mask only if image contains simple transparency information.
4735 Otherwise, combine image with frame background color. 4735 Otherwise, combine image with frame background color.
4736 4736
4737 * configure.in (--with-png, HAVE_PNG): New. 4737 * configure.in (--with-png, HAVE_PNG): New.
@@ -4829,7 +4829,7 @@
4829 4829
48301999-03-29 Gerd Moellmann <gerd@gnu.org> 48301999-03-29 Gerd Moellmann <gerd@gnu.org>
4831 4831
4832 * xfaces.c (Qraised, Qsunken, QCshadow): Removed. 4832 * xfaces.c (Qraised, Qsunken, QCshadow): Remove.
4833 (QCline_width, QCstyle, Qpressed_button, Qreleased_button): New. 4833 (QCline_width, QCstyle, Qpressed_button, Qreleased_button): New.
4834 Use these symbols for the box face attribute instead of the 4834 Use these symbols for the box face attribute instead of the
4835 removed ones. 4835 removed ones.
@@ -4852,7 +4852,7 @@
4852 * xfaces.c (x_face_list_fonts): New parameter try_alternatives_p. 4852 * xfaces.c (x_face_list_fonts): New parameter try_alternatives_p.
4853 (first_font_matching): New. 4853 (first_font_matching): New.
4854 (set_lface_from_font_name): Use it if font name is a pattern. 4854 (set_lface_from_font_name): Use it if font name is a pattern.
4855 (font_field_wildcard_p): Removed. 4855 (font_field_wildcard_p): Remove.
4856 4856
4857 * dispnew.c (shift_glyph_matrix): Add `window' parameter. 4857 * dispnew.c (shift_glyph_matrix): Add `window' parameter.
4858 Recompute visible height of rows. 4858 Recompute visible height of rows.
@@ -4881,12 +4881,12 @@
4881 (update_window_line): Call after_update_window_line_hook 4881 (update_window_line): Call after_update_window_line_hook
4882 if visible row height has changed. 4882 if visible row height has changed.
4883 4883
4884 * dispextern.h (MATRIX_ROW_VISIBLE_HEIGHT): Removed. 4884 * dispextern.h (MATRIX_ROW_VISIBLE_HEIGHT): Remove.
4885 (struct glyph_row): New member visible_height. 4885 (struct glyph_row): New member visible_height.
4886 4886
4887 * xfaces.c (font_field_wildcard_p): New. 4887 * xfaces.c (font_field_wildcard_p): New.
4888 (set_lface_from_font_name): Remove parameter force_p. Accept 4888 (set_lface_from_font_name): Remove parameter force_p.
4889 font names containing wildcards. 4889 Accept font names containing wildcards.
4890 4890
48911999-03-04 Gerd Moellmann <gerd@gnu.org> 48911999-03-04 Gerd Moellmann <gerd@gnu.org>
4892 4892
@@ -4906,7 +4906,7 @@
4906 * dispextern.h (struct face): Add use_box_color_for_shadows_p. 4906 * dispextern.h (struct face): Add use_box_color_for_shadows_p.
4907 4907
4908 * xterm.c (x_draw_box_rect): New. 4908 * xterm.c (x_draw_box_rect): New.
4909 (x_draw_glyph_string_box): Renamed from 4909 (x_draw_glyph_string_box): Rename from
4910 x_draw_glyph_string_relief. Call x_draw_box_rect. 4910 x_draw_glyph_string_relief. Call x_draw_box_rect.
4911 4911
4912 * xfns.c (QCrelief): New. 4912 * xfns.c (QCrelief): New.
@@ -4914,20 +4914,20 @@
4914 4914
4915 * dispextern.h (struct glyph): Rename left_shadow_p to 4915 * dispextern.h (struct glyph): Rename left_shadow_p to
4916 left_box_line_p, right_shadow_p to right_box_line_p. 4916 left_box_line_p, right_shadow_p to right_box_line_p.
4917 (MAX_RELIEF_THICKNESS): Removed. 4917 (MAX_RELIEF_THICKNESS): Remove.
4918 (struct it): Rename members having `relief' in their names 4918 (struct it): Rename members having `relief' in their names
4919 to contain `box' instead. 4919 to contain `box' instead.
4920 4920
4921 * xfaces.c (realize_x_face): Handle new box attribute values. 4921 * xfaces.c (realize_x_face): Handle new box attribute values.
4922 (QCrelief, Qbox): Removed. 4922 (QCrelief, Qbox): Remove.
4923 (QCshadow, QCcolor, Qraised, Qsunken): New. 4923 (QCshadow, QCcolor, Qraised, Qsunken): New.
4924 (syms_of_xfaces): Initialize new symbols. 4924 (syms_of_xfaces): Initialize new symbols.
4925 4925
49261999-03-02 Gerd Moellmann <gerd@gnu.org> 49261999-03-02 Gerd Moellmann <gerd@gnu.org>
4927 4927
4928 * dispextern.h (LFACE_RELIEF_INDEX): Removed. 4928 * dispextern.h (LFACE_RELIEF_INDEX): Remove.
4929 4929
4930 * xfaces.c (LFACE_RELIEF): Removed. 4930 * xfaces.c (LFACE_RELIEF): Remove.
4931 (merge_face_vector_with_property): Remove handling of `:relief'. 4931 (merge_face_vector_with_property): Remove handling of `:relief'.
4932 (Finternal_set_lisp_face_attribute): Ditto. 4932 (Finternal_set_lisp_face_attribute): Ditto.
4933 (Finternal_set_lisp_face_attribute_from_resource): Ditto. 4933 (Finternal_set_lisp_face_attribute_from_resource): Ditto.
@@ -4946,7 +4946,7 @@
4946 4946
4947 * xterm.c (x_draw_glyph_string): Draw underline, overline, 4947 * xterm.c (x_draw_glyph_string): Draw underline, overline,
4948 strike-through, and boxes. 4948 strike-through, and boxes.
4949 (x_draw_glyph_string_underline): Removed. 4949 (x_draw_glyph_string_underline): Remove.
4950 4950
4951 * xfaces.c (QCoverline, QCstrike_through, QCbox): New. 4951 * xfaces.c (QCoverline, QCstrike_through, QCbox): New.
4952 (Qoverline, Qstrike_through, Qbox): New. 4952 (Qoverline, Qstrike_through, Qbox): New.
@@ -5019,7 +5019,7 @@
50191999-01-03 Masatake Yamato <masata-y@is.aist-nara.ac.jp> 50191999-01-03 Masatake Yamato <masata-y@is.aist-nara.ac.jp>
5020 5020
5021 * dispextern.h (UNDERLINE_COLOR): Defined. 5021 * dispextern.h (UNDERLINE_COLOR): Defined.
5022 (struct face): Added two new members. 5022 (struct face): Add two new members.
5023 underline_color, underline_defaulted_p. 5023 underline_color, underline_defaulted_p.
5024 5024
5025 * xfaces.c (merge_face_vector_with_property): 5025 * xfaces.c (merge_face_vector_with_property):
@@ -5032,7 +5032,7 @@
5032 5032
50331999-02-12 Gerd Moellmann <gerd@gnu.org> 50331999-02-12 Gerd Moellmann <gerd@gnu.org>
5034 5034
5035 * xfns.c (Fx_image_header): Removed. 5035 * xfns.c (Fx_image_header): Remove.
5036 5036
50371999-02-07 Gerd Moellmann <gerd@gnu.org> 50371999-02-07 Gerd Moellmann <gerd@gnu.org>
5038 5038
@@ -5073,16 +5073,16 @@
5073 5073
5074 * xdisp.c (handle_single_display_prop): New. 5074 * xdisp.c (handle_single_display_prop): New.
5075 (handle_display_prop): Call it. 5075 (handle_display_prop): Call it.
5076 (handle_raise_prop): Removed. 5076 (handle_raise_prop): Remove.
5077 (handle_height_prop): Removed. 5077 (handle_height_prop): Remove.
5078 (handle_space_width_prop): Removed. 5078 (handle_space_width_prop): Remove.
5079 (handle_face_prop): Remove handling of raised text. 5079 (handle_face_prop): Remove handling of raised text.
5080 (handle_display_prop): Do it here. 5080 (handle_display_prop): Do it here.
5081 5081
5082 * dispextern.h (DISPLAY_PROP_IDX): Replaces GLYPH_PROP_IDX. 5082 * dispextern.h (DISPLAY_PROP_IDX): Replaces GLYPH_PROP_IDX.
5083 (RAISE_PROP_IDX): Removed. 5083 (RAISE_PROP_IDX): Remove.
5084 (HEIGHT_PROP_IDX): Removed. 5084 (HEIGHT_PROP_IDX): Remove.
5085 (SPACE_WIDTH_PROP_IDX): Removed. 5085 (SPACE_WIDTH_PROP_IDX): Remove.
5086 5086
5087 * xdisp.c (Qdisplay): Replaces Qglyph. 5087 * xdisp.c (Qdisplay): Replaces Qglyph.
5088 (handle_display_prop): Formerly handle_glyph_prop. 5088 (handle_display_prop): Formerly handle_glyph_prop.
@@ -5090,8 +5090,8 @@
50901999-01-11 Gerd Moellmann <gerd@gnu.org> 50901999-01-11 Gerd Moellmann <gerd@gnu.org>
5091 5091
5092 * xdisp.c (reseat_to_string): Set position in display vector to -1. 5092 * xdisp.c (reseat_to_string): Set position in display vector to -1.
5093 (handle_stop): Set position in display vector to -1. Don't 5093 (handle_stop): Set position in display vector to -1.
5094 check overlay strings when set up to deliver characters from a 5094 Don't check overlay strings when set up to deliver characters from a
5095 display vector. 5095 display vector.
5096 (set_iterator_to_next): At the end of a run of characters from a 5096 (set_iterator_to_next): At the end of a run of characters from a
5097 display vector, check whether the display vector display replaces 5097 display vector, check whether the display vector display replaces
@@ -5124,7 +5124,7 @@
5124 * buffer.h (struct buffer): indicate_empty_lines renamed from 5124 * buffer.h (struct buffer): indicate_empty_lines renamed from
5125 indicate_zv_lines. 5125 indicate_zv_lines.
5126 5126
5127 * buffer.c (indicate-empty-lines): Renamed from indicate_zv_lines. 5127 * buffer.c (indicate-empty-lines): Rename from indicate_zv_lines.
5128 (default-indicate-zv-lines): Likewise. 5128 (default-indicate-zv-lines): Likewise.
5129 5129
5130 * dispextern.h (struct glyph_row): Rename indicate_zv_line_p 5130 * dispextern.h (struct glyph_row): Rename indicate_zv_line_p
@@ -5139,7 +5139,7 @@
5139 and `N-'. 5139 and `N-'.
5140 5140
5141 * xfns.c (xbm_scan): New. 5141 * xfns.c (xbm_scan): New.
5142 (xbm_read_hexint): Removed. 5142 (xbm_read_hexint): Remove.
5143 (xbm_read_bitmap_file_data): Use xbm_scan. 5143 (xbm_read_bitmap_file_data): Use xbm_scan.
5144 5144
5145 * fileio.c (Finsert_file_contents): Prevent redisplay optimizations. 5145 * fileio.c (Finsert_file_contents): Prevent redisplay optimizations.
@@ -5155,8 +5155,8 @@
5155 5155
5156 * xfaces.c (face_with_height): New. 5156 * xfaces.c (face_with_height): New.
5157 5157
5158 * xdisp.c (eval_handler): Renamed from eval_mode_handler. 5158 * xdisp.c (eval_handler): Rename from eval_mode_handler.
5159 (eval_form): Renamed from eval_mode_element. 5159 (eval_form): Rename from eval_mode_element.
5160 (handle_face_prop): Use it. 5160 (handle_face_prop): Use it.
5161 (Qheight): Replaces Qsmaller. 5161 (Qheight): Replaces Qsmaller.
5162 (handle_height_prop): Replaces handle_smaller_prop. 5162 (handle_height_prop): Replaces handle_smaller_prop.
@@ -5183,7 +5183,7 @@
5183 5183
51841998-11-28 Gerd Moellmann <gerd@gnu.org> 51841998-11-28 Gerd Moellmann <gerd@gnu.org>
5185 5185
5186 * config.in (PROTO): Removed. 5186 * config.in (PROTO): Remove.
5187 5187
5188 * xterm.h: Change PROTO to P_. 5188 * xterm.h: Change PROTO to P_.
5189 5189
@@ -5225,7 +5225,7 @@
5225 5225
5226 * xterm.c (x_scroll_bar_move): Clear to the left and right 5226 * xterm.c (x_scroll_bar_move): Clear to the left and right
5227 of toolkit scroll bars differently. 5227 of toolkit scroll bars differently.
5228 (x_scroll_bar_move): Removed. 5228 (x_scroll_bar_move): Remove.
5229 (XTset_vertical_scroll_bar): Move code from x_scroll_bar_move here. 5229 (XTset_vertical_scroll_bar): Move code from x_scroll_bar_move here.
5230 5230
5231 * dispextern.h: Make it compilable --with-x=no. 5231 * dispextern.h: Make it compilable --with-x=no.
@@ -5256,8 +5256,8 @@
5256 5256
52571998-11-23 Gerd Moellmann <gerd@gnu.org> 52571998-11-23 Gerd Moellmann <gerd@gnu.org>
5258 5258
5259 * xdisp.c (restore_overlay_strings): Removed. 5259 * xdisp.c (restore_overlay_strings): Remove.
5260 (restore_dpvec): Removed. 5260 (restore_dpvec): Remove.
5261 (init_from_display_pos): Inline both functions above. 5261 (init_from_display_pos): Inline both functions above.
5262 5262
5263 * xfns.c (IMAGE_NON_NEGATIVE_INTEGER_VALUE): New. 5263 * xfns.c (IMAGE_NON_NEGATIVE_INTEGER_VALUE): New.
@@ -5270,7 +5270,7 @@
5270 (gif_format): Ditto. 5270 (gif_format): Ditto.
5271 (gs_format): Ditto. 5271 (gs_format): Ditto.
5272 5272
5273 * xdisp.c (set_window_cursor): Removed. 5273 * xdisp.c (set_window_cursor): Remove.
5274 (redisplay_internal): Case cursor motion in cursor line of 5274 (redisplay_internal): Case cursor motion in cursor line of
5275 selected window; use set_cursor_from_row. 5275 selected window; use set_cursor_from_row.
5276 5276
@@ -5641,7 +5641,7 @@
5641 5641
5642 * xdisp.c (redisplay_window): Always resize toolbar window if 5642 * xdisp.c (redisplay_window): Always resize toolbar window if
5643 auto_resize_toolbar_p is non-zero. 5643 auto_resize_toolbar_p is non-zero.
5644 (auto_resize_toolbar_p): Renamed from auto_resize_toolbar. 5644 (auto_resize_toolbar_p): Rename from auto_resize_toolbar.
5645 (window_box): New. 5645 (window_box): New.
5646 (window_box_height): New. 5646 (window_box_height): New.
5647 (window_box_width): New. 5647 (window_box_width): New.
@@ -5735,12 +5735,12 @@
5735 * xfns.c (x_laplace): New. 5735 * xfns.c (x_laplace): New.
5736 (x_laplace_read_row): New. 5736 (x_laplace_read_row): New.
5737 (x_laplace_write_row): New. 5737 (x_laplace_write_row): New.
5738 (lookup_image): Handle common image attributes here. New 5738 (lookup_image): Handle common image attributes here.
5739 attribute `:algorithm'. 5739 New attribute `:algorithm'.
5740 5740
5741 * xfaces.c (clear_face_cache): Call clear_image_cache. 5741 * xfaces.c (clear_face_cache): Call clear_image_cache.
5742 5742
5743 * xterm.c (x_inverted_image_mask): Removed. 5743 * xterm.c (x_inverted_image_mask): Remove.
5744 (x_draw_image_foreground_1): New. 5744 (x_draw_image_foreground_1): New.
5745 (x_draw_image_glyph_string): Draw images with mask to a temporary 5745 (x_draw_image_glyph_string): Draw images with mask to a temporary
5746 pixmap to reduce flickering. 5746 pixmap to reduce flickering.
@@ -5755,7 +5755,7 @@
5755 5755
5756 * xfns.c (cache_image): Correct call to xrealloc. 5756 * xfns.c (cache_image): Correct call to xrealloc.
5757 5757
5758 * dispnew.c (Fset_toolbar_height): Removed. 5758 * dispnew.c (Fset_toolbar_height): Remove.
5759 5759
5760 * xdisp.c (init_xdisp): Use FRAME_TOP_MARGIN instead of 5760 * xdisp.c (init_xdisp): Use FRAME_TOP_MARGIN instead of
5761 FRAME_MENU_BAR_LINES. 5761 FRAME_MENU_BAR_LINES.
@@ -5838,8 +5838,8 @@
5838 (clear_image_cache): Additional parameter force_p. 5838 (clear_image_cache): Additional parameter force_p.
5839 (Fclear_image_cache): New. 5839 (Fclear_image_cache): New.
5840 (x_find_image_file): New. 5840 (x_find_image_file): New.
5841 (xbm_load): Handle `:margin' and `:relief'. Use 5841 (xbm_load): Handle `:margin' and `:relief'.
5842 x_find_image_file. 5842 Use x_find_image_file.
5843 (xpm_load): Likewise. 5843 (xpm_load): Likewise.
5844 (pbm_load): Likewise. 5844 (pbm_load): Likewise.
5845 (jpeg_load): Likewise. 5845 (jpeg_load): Likewise.
@@ -5939,8 +5939,8 @@
5939 * frame.h (struct frame): Add toolbar-related members 5939 * frame.h (struct frame): Add toolbar-related members
5940 toolbar_window, desired_toolbar_items, current_toolbar_items, 5940 toolbar_window, desired_toolbar_items, current_toolbar_items,
5941 desired_toolbar_string, current_toolbar_string, 5941 desired_toolbar_string, current_toolbar_string,
5942 n_desired_toolbar_items, n_current_toolbar_items. Add 5942 n_desired_toolbar_items, n_current_toolbar_items.
5943 window_height. 5943 Add window_height.
5944 5944
5945 * xterm.c (x_after_update_window_line): Don't draw bitmap 5945 * xterm.c (x_after_update_window_line): Don't draw bitmap
5946 areas for pseudo-windows. 5946 areas for pseudo-windows.
@@ -6024,17 +6024,17 @@
6024 6024
60251998-09-06 Gerd Moellmann <gerd@gnu.org> 60251998-09-06 Gerd Moellmann <gerd@gnu.org>
6026 6026
6027 * lisp.h (HAVE_FACES): Removed. 6027 * lisp.h (HAVE_FACES): Remove.
6028 6028
6029 * dispextern.h (HAVE_FACES): Removed. 6029 * dispextern.h (HAVE_FACES): Remove.
6030 6030
6031 * config.in (HAVE_FACES): Removed. 6031 * config.in (HAVE_FACES): Remove.
6032 6032
6033 * dispnew.c (HAVE_FACES): Removed. 6033 * dispnew.c (HAVE_FACES): Remove.
6034 6034
6035 * xdisp.c (HAVE_FACES): Removed. 6035 * xdisp.c (HAVE_FACES): Remove.
6036 6036
6037 * xfaces.c (HAVE_FACES): Removed. 6037 * xfaces.c (HAVE_FACES): Remove.
6038 6038
60391998-09-05 Gerd Moellmann <gerd@gnu.org> 60391998-09-05 Gerd Moellmann <gerd@gnu.org>
6040 6040
@@ -6042,8 +6042,8 @@
6042 free realized faces. 6042 free realized faces.
6043 6043
6044 * xfaces.c (free_all_realized_faces): Make it externally visible. 6044 * xfaces.c (free_all_realized_faces): Make it externally visible.
6045 (Finternal_set_lisp_face_attribute): Increment 6045 (Finternal_set_lisp_face_attribute):
6046 windows_or_buffers_changed. 6046 Increment windows_or_buffers_changed.
6047 6047
6048 * dispnew.c (direct_output_for_insert): Give up if 6048 * dispnew.c (direct_output_for_insert): Give up if
6049 face_change_count is non-zero. 6049 face_change_count is non-zero.
@@ -6076,9 +6076,9 @@
6076 6076
6077 * term.c (OUTPUT_IF): Make replacement text have statement form. 6077 * term.c (OUTPUT_IF): Make replacement text have statement form.
6078 (OUTPUT1_IF): Ditto. 6078 (OUTPUT1_IF): Ditto.
6079 (TS_italic_mode, TS_end_italic_mode): Removed. 6079 (TS_italic_mode, TS_end_italic_mode): Remove.
6080 (TS_bold_mode): Removed. 6080 (TS_bold_mode): Remove.
6081 (TS_underscore_mode, TS_end_underscore_mode): Removed. 6081 (TS_underscore_mode, TS_end_underscore_mode): Remove.
6082 (TS_enter_bold_mode, TS_enter_dim_mode, TS_enter_blink_mode): New. 6082 (TS_enter_bold_mode, TS_enter_dim_mode, TS_enter_blink_mode): New.
6083 (TS_enter_reverse_mode): New. 6083 (TS_enter_reverse_mode): New.
6084 (TS_enter_underline_mode, TS_exit_underline_mode): New. 6084 (TS_enter_underline_mode, TS_exit_underline_mode): New.
@@ -6187,8 +6187,8 @@
6187 6187
6188 * frame.h (FRAME_WINDOW_WIDTH_ARG): Add bitmap area widths. 6188 * frame.h (FRAME_WINDOW_WIDTH_ARG): Add bitmap area widths.
6189 6189
6190 * dispnew.c (allocate_matrices_for_window_redisplay): Compute 6190 * dispnew.c (allocate_matrices_for_window_redisplay):
6191 total pixel width of window differently. 6191 Compute total pixel width of window differently.
6192 6192
6193 * xdisp.c (init_iterator): Compute width of mode line differently. 6193 * xdisp.c (init_iterator): Compute width of mode line differently.
6194 6194
@@ -6209,7 +6209,7 @@
6209 (update_window_tree): Parameter no_scrolling_p removed. 6209 (update_window_tree): Parameter no_scrolling_p removed.
6210 (update_single_window): Ditto. 6210 (update_single_window): Ditto.
6211 6211
6212 * xterm.c (x_get_char_font_and_encoding): Renamed to 6212 * xterm.c (x_get_char_font_and_encoding): Rename to
6213 x_get_char_face_and_encoding. 6213 x_get_char_face_and_encoding.
6214 6214
6215 * dispnew.c (update_text_area): Don't call get_glyph_overhangs 6215 * dispnew.c (update_text_area): Don't call get_glyph_overhangs
@@ -6254,8 +6254,8 @@
6254 6254
6255 * xterm.c (note_mouse_highlight): Set BEGV_BYTE, ZV_BYTE. 6255 * xterm.c (note_mouse_highlight): Set BEGV_BYTE, ZV_BYTE.
6256 6256
6257 * xfaces.c (Vx_unibyte_registry_and_encoding): Removed. Use 6257 * xfaces.c (Vx_unibyte_registry_and_encoding): Remove.
6258 face_default_registry instead. 6258 Use face_default_registry instead.
6259 6259
6260 * syntax.c (scan_sexps_forward): Set up syntax table before 6260 * syntax.c (scan_sexps_forward): Set up syntax table before
6261 jumping to initial state label. 6261 jumping to initial state label.
@@ -6372,13 +6372,13 @@
6372 (struct iterator_stack_entry): Add multibyte_p. 6372 (struct iterator_stack_entry): Add multibyte_p.
6373 6373
6374 * xdisp.c (string_pos): Use string_char_to_byte. 6374 * xdisp.c (string_pos): Use string_char_to_byte.
6375 (char_charset): Removed. 6375 (char_charset): Remove.
6376 6376
63771998-08-03 Gerd Moellmann <gerd@gnu.org> 63771998-08-03 Gerd Moellmann <gerd@gnu.org>
6378 6378
6379 * xterm.c (x_draw_image_glyph_string_foreground): Draw a 6379 * xterm.c (x_draw_image_glyph_string_foreground): Draw a
6380 rectangle for a block cursor over an image without a mask. 6380 rectangle for a block cursor over an image without a mask.
6381 (x_stretch_block_cursor): Added. Non-zero means don't draw 6381 (x_stretch_block_cursor): Add. Non-zero means don't draw
6382 a block cursor over a stretch as wide as that stretch. 6382 a block cursor over a stretch as wide as that stretch.
6383 (x_draw_stretch_glyph_string): Use it. 6383 (x_draw_stretch_glyph_string): Use it.
6384 (x_draw_hollow_cursor): Ditto. 6384 (x_draw_hollow_cursor): Ditto.
@@ -6389,7 +6389,7 @@
6389 * xdisp.c (char_charset): Return charset of a character, 6389 * xdisp.c (char_charset): Return charset of a character,
6390 depending on whether or not multi-byte characters are enabled. 6390 depending on whether or not multi-byte characters are enabled.
6391 6391
6392 * xfaces.c (Fset_face_charset_registry): Removed. 6392 * xfaces.c (Fset_face_charset_registry): Remove.
6393 (x_charset_registry): Determine registry from charset plist. 6393 (x_charset_registry): Determine registry from charset plist.
6394 6394
63951998-08-02 Gerd Moellmann <gerd@gnu.org> 63951998-08-02 Gerd Moellmann <gerd@gnu.org>
@@ -6401,7 +6401,7 @@
6401 redisplay interface. 6401 redisplay interface.
6402 * keyboard.c (detect_input_pending_run_timers): Likewise. 6402 * keyboard.c (detect_input_pending_run_timers): Likewise.
6403 6403
6404 * dispextern.h (produce_*glyphs_hook): Removed. 6404 * dispextern.h (produce_*glyphs_hook): Remove.
6405 * term.c (produce_*glyphs): Ditto. 6405 * term.c (produce_*glyphs): Ditto.
6406 (cursor_to): Remove pixel position parameters. 6406 (cursor_to): Remove pixel position parameters.
6407 6407
@@ -6457,7 +6457,7 @@
6457 * xterm.c (x_flush): Flush X output buffer. 6457 * xterm.c (x_flush): Flush X output buffer.
6458 (XTflash): Use it. 6458 (XTflash): Use it.
6459 6459
6460 * xfaces.c (lface_from_face_name): Renamed from lface_from_symbol. 6460 * xfaces.c (lface_from_face_name): Rename from lface_from_symbol.
6461 Allow strings as face names. 6461 Allow strings as face names.
6462 6462
6463 * xfns.c (forall_images_in_image_cache): Check that frame is 6463 * xfns.c (forall_images_in_image_cache): Check that frame is
@@ -6493,7 +6493,7 @@
6493 (Finternal_lisp_face_attribute_values): Ditto. 6493 (Finternal_lisp_face_attribute_values): Ditto.
6494 (syms_of_xfaces): Define the symbol `:reverse-video'. 6494 (syms_of_xfaces): Define the symbol `:reverse-video'.
6495 6495
6496 * xdisp.c (get_glyph_property): Renamed from 6496 * xdisp.c (get_glyph_property): Rename from
6497 fill_iterator_from_glyph_property. 6497 fill_iterator_from_glyph_property.
6498 (next_element_from_buffer): Handle case that no `glyph' property 6498 (next_element_from_buffer): Handle case that no `glyph' property
6499 was found correctly. 6499 was found correctly.
@@ -6501,28 +6501,28 @@
6501 6501
65021998-07-29 Gerd Moellmann <gerd@gnu.org> 65021998-07-29 Gerd Moellmann <gerd@gnu.org>
6503 6503
6504 * dispnew.c (Fshow_cursor): Renamed from blink_cursor. Take 6504 * dispnew.c (Fshow_cursor): Rename from blink_cursor.
6505 additional window argument. 6505 Take additional window argument.
6506 6506
6507 * xdisp.c (reseat_at_previous_visible_line_start): Renamed from 6507 * xdisp.c (reseat_at_previous_visible_line_start): Rename from
6508 set_iterator_to_previous_visible_line_start. 6508 set_iterator_to_previous_visible_line_start.
6509 (reseat_at_next_visible_line_start): Likewise. 6509 (reseat_at_next_visible_line_start): Likewise.
6510 (compute_stop_pos): Renamed from set_iterator_stop_pos. 6510 (compute_stop_pos): Rename from set_iterator_stop_pos.
6511 (face_before_or_after_it_pos): Renamed from get_face_at_it_pos. 6511 (face_before_or_after_it_pos): Rename from get_face_at_it_pos.
6512 (compute_face_in_buffer): Renamed from 6512 (compute_face_in_buffer): Rename from
6513 compute_face_at_iterator_position. 6513 compute_face_at_iterator_position.
6514 (compute_face_in_string): Renamed from 6514 (compute_face_in_string): Rename from
6515 compute_face_at_iterator_string_position. 6515 compute_face_at_iterator_string_position.
6516 (get_space_width): Renamed from get_iterator_space_width. 6516 (get_space_width): Rename from get_iterator_space_width.
6517 (next_overlay_string): Renamed from 6517 (next_overlay_string): Rename from
6518 set_iterator_to_next_overlay_string. 6518 set_iterator_to_next_overlay_string.
6519 (get_overlay_strings): Renamed from 6519 (get_overlay_strings): Rename from
6520 get_overlay_strings_at_iterator_position. 6520 get_overlay_strings_at_iterator_position.
6521 (restore_overlay_strings): Renamed from 6521 (restore_overlay_strings): Rename from
6522 setup_overlay_strings_from_glyph_pos. 6522 setup_overlay_strings_from_glyph_pos.
6523 (restore_dpvec): Renamed from setup_iterator_dpvec_from_glyph_pos. 6523 (restore_dpvec): Rename from setup_iterator_dpvec_from_glyph_pos.
6524 (init_from_display_pos): Renamed from init_iterator_from_glyph_pos. 6524 (init_from_display_pos): Rename from init_iterator_from_glyph_pos.
6525 (init_to_row_start): Renamed from init_iterator_to_row_start. 6525 (init_to_row_start): Rename from init_iterator_to_row_start.
6526 (init_to_row_end): Formerly init_iterator_to_next_row_start. 6526 (init_to_row_end): Formerly init_iterator_to_next_row_start.
6527 6527
6528 * xterm.c: Merge with 20.2.97. 6528 * xterm.c: Merge with 20.2.97.
@@ -6532,26 +6532,26 @@
6532 simple charpos. 6532 simple charpos.
6533 6533
6534 * xdisp.c (this_line_start_pos): Use struct text_pos. 6534 * xdisp.c (this_line_start_pos): Use struct text_pos.
6535 (this_line_end_pos): Renamed from .*endpos; use struct text_pos. 6535 (this_line_end_pos): Rename from .*endpos; use struct text_pos.
6536 (enum move_it_result): Renamed from move_iterator_result. 6536 (enum move_it_result): Rename from move_iterator_result.
6537 (string_pos_nchars_ahead): Compute text_pos in a string from a 6537 (string_pos_nchars_ahead): Compute text_pos in a string from a
6538 known text_pos plus a character delta. 6538 known text_pos plus a character delta.
6539 (string_pos): Compute text_pos in string from charpos. 6539 (string_pos): Compute text_pos in string from charpos.
6540 (c_string_pos): Likewise for a C string. 6540 (c_string_pos): Likewise for a C string.
6541 (number_of_chars): Return number of characters in a possibly 6541 (number_of_chars): Return number of characters in a possibly
6542 multi-byte C string. 6542 multi-byte C string.
6543 (check_it): Renamed from check_iterator. Check that charpos and 6543 (check_it): Rename from check_iterator. Check that charpos and
6544 bytepos are in sync. 6544 bytepos are in sync.
6545 (push_it): Renamed from save_iterator_settings. 6545 (push_it): Rename from save_iterator_settings.
6546 (pop_it): Renamed from restore_iterator_settings. 6546 (pop_it): Rename from restore_iterator_settings.
6547 (move_it_.*): Renamed from move_iterator_.*. 6547 (move_it_.*): Rename from move_iterator_.*.
6548 (charset_at_position): Take charpos/bytepos into account. 6548 (charset_at_position): Take charpos/bytepos into account.
6549 (back_to_previous_line_start): Set iterator to previous line start. 6549 (back_to_previous_line_start): Set iterator to previous line start.
6550 (forward_to_next_line_start): Set iterator to next line start. 6550 (forward_to_next_line_start): Set iterator to next line start.
6551 (back_to_previous_visible_line_start): Renamed from 6551 (back_to_previous_visible_line_start): Rename from
6552 move_iterator_previous_visible_line_start. 6552 move_iterator_previous_visible_line_start.
6553 (set_iterator_to_next_visible_line_start): Handle charpos/bytepos. 6553 (set_iterator_to_next_visible_line_start): Handle charpos/bytepos.
6554 (get_face_at_it_pos): Renamed from get_face_from_cursor_pos. 6554 (get_face_at_it_pos): Rename from get_face_from_cursor_pos.
6555 Handle charpos/bytepos. 6555 Handle charpos/bytepos.
6556 (compute_face_at_iterator_position): Handle charpos/bytepos. 6556 (compute_face_at_iterator_position): Handle charpos/bytepos.
6557 (compute_face_at_iterator_string_position): Likewise. 6557 (compute_face_at_iterator_string_position): Likewise.
@@ -6593,7 +6593,7 @@
6593 (copy_glyph_row_contents): Ditto. 6593 (copy_glyph_row_contents): Ditto.
6594 (check_matrix_invariants): Add additional checks for charpos/ 6594 (check_matrix_invariants): Add additional checks for charpos/
6595 bytepos consistency. 6595 bytepos consistency.
6596 (direct_output_for_insert): Changed for charpos/bytepos. 6596 (direct_output_for_insert): Change for charpos/bytepos.
6597 (buffer_posn_from_coords): Likewise. Put code dealing with 6597 (buffer_posn_from_coords): Likewise. Put code dealing with
6598 `direction-reversed' in #if 0. 6598 `direction-reversed' in #if 0.
6599 6599
@@ -6630,10 +6630,10 @@
6630 (SET_TEXT_POS_FROM_MARKER): Set a text_pos from a marker. 6630 (SET_TEXT_POS_FROM_MARKER): Set a text_pos from a marker.
6631 (SET_MARKER_FROM_TEXT_POS): Set a marker from a text_pos. 6631 (SET_MARKER_FROM_TEXT_POS): Set a marker from a text_pos.
6632 (TEXT_POS_EQUAL_P): Compare two text_pos structures for equality. 6632 (TEXT_POS_EQUAL_P): Compare two text_pos structures for equality.
6633 (struct display_pos): Renamed from glyph_pos. Use struct text_pos 6633 (struct display_pos): Rename from glyph_pos. Use struct text_pos
6634 for buffer and string positions. 6634 for buffer and string positions.
6635 (struct glyph): Use text_pos. 6635 (struct glyph): Use text_pos.
6636 (struct it): Renamed from display_iterator. Use text_pos. 6636 (struct it): Rename from display_iterator. Use text_pos.
6637 6637
66381998-07-23 Gerd Moellmann <gerd@gnu.org> 66381998-07-23 Gerd Moellmann <gerd@gnu.org>
6639 6639
@@ -6650,7 +6650,7 @@
6650 * xfns.c (prepare_image_for_display): Don't set loading_failed_p 6650 * xfns.c (prepare_image_for_display): Don't set loading_failed_p
6651 flag of images. 6651 flag of images.
6652 6652
6653 * dispextern.h (struct image): Removed member loading_failed_p. 6653 * dispextern.h (struct image): Remove member loading_failed_p.
6654 It's probably better to have the chance to try to load an image 6654 It's probably better to have the chance to try to load an image
6655 again. 6655 again.
6656 6656
@@ -6703,28 +6703,28 @@
6703 * xfns.c (tiff_image_p, tiff_load): Support TIFF images via 6703 * xfns.c (tiff_image_p, tiff_load): Support TIFF images via
6704 libtiff34. 6704 libtiff34.
6705 6705
6706 * configure.in (--with-tiff, HAVE_TIFF): Added. 6706 * configure.in (--with-tiff, HAVE_TIFF): Add.
6707 6707
6708 * config.in (HAVE_TIFF): Added. 6708 * config.in (HAVE_TIFF): Add.
6709 6709
6710 * Makefile.in (LIBTIFF): Added. 6710 * Makefile.in (LIBTIFF): Add.
6711 6711
6712 * xfns.c (jpeg_image_p, jpeg_load): Support JPEG images. 6712 * xfns.c (jpeg_image_p, jpeg_load): Support JPEG images.
6713 6713
6714 * Makefile.in (LIBJPEG): Added. 6714 * Makefile.in (LIBJPEG): Add.
6715 6715
6716 * xfns.c (resource_types): Enumerators renamed to RES_TYPE_NUMBER, 6716 * xfns.c (resource_types): Enumerators renamed to RES_TYPE_NUMBER,
6717 RES_TYPE_BOOLEAN etc. because of conflict of `boolean' with 6717 RES_TYPE_BOOLEAN etc. because of conflict of `boolean' with
6718 jpeglib.h. 6718 jpeglib.h.
6719 6719
6720 * configure.in (HAVE_JPEG, --with-jpeg): Added. On systems 6720 * configure.in (HAVE_JPEG, --with-jpeg): Add. On systems
6721 where the library is installed in /usr/local/lib, e.g. FreeBSD, 6721 where the library is installed in /usr/local/lib, e.g. FreeBSD,
6722 configure must be run with `--x-includes=/usr/X11R6/include: 6722 configure must be run with `--x-includes=/usr/X11R6/include:
6723 /usr/local/include --x-libraries=/usr/X11R6/lib:/usr/local/lib'. 6723 /usr/local/include --x-libraries=/usr/X11R6/lib:/usr/local/lib'.
6724 6724
67251998-07-18 Gerd Moellmann <gerd@gnu.org> 67251998-07-18 Gerd Moellmann <gerd@gnu.org>
6726 6726
6727 * config.in (HAVE_JPEG): Added. 6727 * config.in (HAVE_JPEG): Add.
6728 6728
6729 * xfns.c (ct_init): Initialize color table used to map RGB colors 6729 * xfns.c (ct_init): Initialize color table used to map RGB colors
6730 from images to X pixel colors. 6730 from images to X pixel colors.
@@ -6837,20 +6837,20 @@
6837 (redisplay_window): Case cursor movement. Don't try it if 6837 (redisplay_window): Case cursor movement. Don't try it if
6838 last_cursor.vpos is out of range. 6838 last_cursor.vpos is out of range.
6839 6839
6840 * xdisp.c (set_cursor_from_row): Set this_line_.* variables. This 6840 * xdisp.c (set_cursor_from_row): Set this_line_.* variables.
6841 way, the display optimization for the line containing the cursor 6841 This way, the display optimization for the line containing the cursor
6842 is used more frequently, esp. when we have a blinking cursor. 6842 is used more frequently, esp. when we have a blinking cursor.
6843 (display_line): Don't set this_line_.* variables. 6843 (display_line): Don't set this_line_.* variables.
6844 6844
6845 * xterm.c (x_redraw_cursor): Removed. 6845 * xterm.c (x_redraw_cursor): Remove.
6846 (x_display_and_set_cursor): Set cursor type depending on 6846 (x_display_and_set_cursor): Set cursor type depending on
6847 cursor_off_p flag of window. 6847 cursor_off_p flag of window.
6848 6848
6849 * dispnew.c (redraw_cursor_hook): Removed. 6849 * dispnew.c (redraw_cursor_hook): Remove.
6850 (Fblink_cursor): Additional parameter on_p to set the cursor_off_p 6850 (Fblink_cursor): Additional parameter on_p to set the cursor_off_p
6851 member of the selected window. 6851 member of the selected window.
6852 6852
6853 * xfaces.c (Fface_font): Added for compatibility with 20.2. 6853 * xfaces.c (Fface_font): Add for compatibility with 20.2.
6854 6854
6855 * xterm.c (x_y_to_hpos_vpos): Return null if not over text. 6855 * xterm.c (x_y_to_hpos_vpos): Return null if not over text.
6856 Return glyph area under x/y. 6856 Return glyph area under x/y.
@@ -6880,8 +6880,8 @@
6880 6880
68811998-06-29 Gerd Moellmann <gerd@gnu.org> 68811998-06-29 Gerd Moellmann <gerd@gnu.org>
6882 6882
6883 * xfaces.c (Finternal_make_lisp_face): Increment 6883 * xfaces.c (Finternal_make_lisp_face):
6884 lface_id_to_name_size when lface_id_to_name is reallocated. 6884 Increment lface_id_to_name_size when lface_id_to_name is reallocated.
6885 6885
68861998-06-27 Gerd Moellmann <gerd@gnu.org> 68861998-06-27 Gerd Moellmann <gerd@gnu.org>
6887 6887
@@ -6892,12 +6892,12 @@
6892 6892
68931998-05-09 Gerd Moellmann <gerd@gnu.org> 68931998-05-09 Gerd Moellmann <gerd@gnu.org>
6894 6894
6895 * xdisp.c (set_iterator_to_next_visible_line_start): Don't 6895 * xdisp.c (set_iterator_to_next_visible_line_start):
6896 do anything if iterator is at ZV because scan_buffer doesn't 6896 Don't do anything if iterator is at ZV because scan_buffer doesn't
6897 work otherwise. 6897 work otherwise.
6898 6898
6899 * xterm.c (x_encode_char): Inline it. 6899 * xterm.c (x_encode_char): Inline it.
6900 (x_get_char_font_and_encoding): Simplified. 6900 (x_get_char_font_and_encoding): Simplify.
6901 (x_per_char_metric): Inline it. 6901 (x_per_char_metric): Inline it.
6902 6902
6903 * xterm.c (x_draw_glyph_string_relief): Use clipping. 6903 * xterm.c (x_draw_glyph_string_relief): Use clipping.
@@ -6926,15 +6926,15 @@
6926 * xdisp.c (display_line): Compute row height from glyphs in 6926 * xdisp.c (display_line): Compute row height from glyphs in
6927 marginal areas. 6927 marginal areas.
6928 6928
6929 * xterm.c (x_draw_image_glyph_string_background): Draw 6929 * xterm.c (x_draw_image_glyph_string_background):
6930 background of an image glyph string. 6930 Draw background of an image glyph string.
6931 (x_draw_glyph_string_bg_rect): Draw a rectangular region of 6931 (x_draw_glyph_string_bg_rect): Draw a rectangular region of
6932 the background of a glyph string. 6932 the background of a glyph string.
6933 (x_draw_image_glyph_string_foreground): Draw the foreground of 6933 (x_draw_image_glyph_string_foreground): Draw the foreground of
6934 an image glyph string. 6934 an image glyph string.
6935 (x_inverted_image_mask): Return the inverted mask of an image. 6935 (x_inverted_image_mask): Return the inverted mask of an image.
6936 6936
6937 * xfns.c (x_draw_image): Removed. 6937 * xfns.c (x_draw_image): Remove.
6938 6938
6939 * dispextern.h (struct image_type): Remove drawing function. 6939 * dispextern.h (struct image_type): Remove drawing function.
6940 6940
@@ -6966,8 +6966,8 @@
6966 image drawing function. 6966 image drawing function.
6967 6967
6968 * xdisp.c (fill_iterator_from_glyph_property): Use position of 6968 * xdisp.c (fill_iterator_from_glyph_property): Use position of
6969 first character with `glyph' property as image position. Set 6969 first character with `glyph' property as image position.
6970 iterator back to that position as long as the image hasn't been 6970 Set iterator back to that position as long as the image hasn't been
6971 consumed with set_iterator_to_next. 6971 consumed with set_iterator_to_next.
6972 (set_cursor_from_row): Accept when glyph with given position is 6972 (set_cursor_from_row): Accept when glyph with given position is
6973 not found in the row. Set cursor x to end of line in that case, 6973 not found in the row. Set cursor x to end of line in that case,
@@ -6993,7 +6993,7 @@
6993 6993
6994 * dispextern.h (struct glyph_row): Use unsigned hash value. 6994 * dispextern.h (struct glyph_row): Use unsigned hash value.
6995 6995
6996 * xdisp.c (display_line): Simplified and made faster by setting 6996 * xdisp.c (display_line): Simplify and made faster by setting
6997 the cursor with set_cursor_from_row. 6997 the cursor with set_cursor_from_row.
6998 (set_cursor_from_row): Handle rows of desired matrix. 6998 (set_cursor_from_row): Handle rows of desired matrix.
6999 6999
@@ -7001,8 +7001,8 @@
7001 7001
7002 * xdisp.c (set_cursor_from_row): Don't put cursor on glyphs 7002 * xdisp.c (set_cursor_from_row): Don't put cursor on glyphs
7003 with type != CHAR_GLYPH. 7003 with type != CHAR_GLYPH.
7004 (fill_iterator_from_glyph_property): Return void. Set 7004 (fill_iterator_from_glyph_property): Return void.
7005 method to next_element_from_image. 7005 Set method to next_element_from_image.
7006 (next_element_from_image): Dummy function for delivering a 7006 (next_element_from_image): Dummy function for delivering a
7007 single image id. 7007 single image id.
7008 (set_iterator_to_next): Add method next_element_from_image. 7008 (set_iterator_to_next): Add method next_element_from_image.
@@ -7037,7 +7037,7 @@
7037 7037
7038 * xterm.c (x_produce_glyphs): Use ASCII face for spaces of a TAB. 7038 * xterm.c (x_produce_glyphs): Use ASCII face for spaces of a TAB.
7039 7039
7040 * xdisp.c (fill_iterator_from_glyph_property): Renamed from 7040 * xdisp.c (fill_iterator_from_glyph_property): Rename from
7041 setup_iterator_from_glyph_property. Don't do it for terminal 7041 setup_iterator_from_glyph_property. Don't do it for terminal
7042 frames. 7042 frames.
7043 7043
@@ -7073,12 +7073,12 @@
7073 7073
7074 * config.in: Add HAVE_XPM. 7074 * config.in: Add HAVE_XPM.
7075 7075
7076 * xfns.c (xbm_draw): Removed. 7076 * xfns.c (xbm_draw): Remove.
7077 (x_draw_image): Default implementation for drawing images. 7077 (x_draw_image): Default implementation for drawing images.
7078 (xbm_keyword_index): Remove XBM_DEPTH. 7078 (xbm_keyword_index): Remove XBM_DEPTH.
7079 (xbm_format): Remove `:depth'. 7079 (xbm_format): Remove `:depth'.
7080 (xbm_image_spec_from_file): Removed to reduce consing. 7080 (xbm_image_spec_from_file): Remove to reduce consing.
7081 (xbm_load_image_from_file): Added for the same reason. 7081 (xbm_load_image_from_file): Add for the same reason.
7082 7082
7083 * xterm.c (x_fill_image_glyph_string): Don't set ybase of 7083 * xterm.c (x_fill_image_glyph_string): Don't set ybase of
7084 glyph string. 7084 glyph string.
@@ -7148,8 +7148,8 @@
7148 7148
7149 * widget.c (widget_store_internal_border): Return void. 7149 * widget.c (widget_store_internal_border): Return void.
7150 7150
7151 * xfns.c (x_destroy_bitmap): Use xfree instead of free. Return 7151 * xfns.c (x_destroy_bitmap): Use xfree instead of free.
7152 void. 7152 Return void.
7153 (init_x_parm_symbols): Return void. 7153 (init_x_parm_symbols): Return void.
7154 (x_report_frame_params): Ditto. 7154 (x_report_frame_params): Ditto.
7155 (x_set_border_pixel): Ditto. 7155 (x_set_border_pixel): Ditto.
@@ -7220,7 +7220,7 @@
7220 * dispnew.c (adjust_frame_glyphs_for_window_redisplay): Use these 7220 * dispnew.c (adjust_frame_glyphs_for_window_redisplay): Use these
7221 macros. 7221 macros.
7222 7222
7223 * xterm.c (x_font_min_bounds): Moved here from xfaces.c. 7223 * xterm.c (x_font_min_bounds): Move here from xfaces.c.
7224 (x_compute_min_char_bounds): Formerly min_char_bounds in xfaces.c. 7224 (x_compute_min_char_bounds): Formerly min_char_bounds in xfaces.c.
7225 (x_load_font): Use x_compute_min_char_bounds. 7225 (x_load_font): Use x_compute_min_char_bounds.
7226 7226
@@ -7238,7 +7238,7 @@
7238 for characters < 0177 in default face. Prepare face for 7238 for characters < 0177 in default face. Prepare face for
7239 display before returning it. 7239 display before returning it.
7240 (x_produce_glyphs): Use it->charset. 7240 (x_produce_glyphs): Use it->charset.
7241 (x_get_char_font_and_encoding): Simplified. 7241 (x_get_char_font_and_encoding): Simplify.
7242 (x_encode_char): Remove parameter `font'. 7242 (x_encode_char): Remove parameter `font'.
7243 7243
7244 * xfaces.c (choose_face_font): If registry from charset symbol 7244 * xfaces.c (choose_face_font): If registry from charset symbol
@@ -7309,8 +7309,8 @@
7309 * dispextern.h (FACE_FOR_CHARSET): Replacement for function 7309 * dispextern.h (FACE_FOR_CHARSET): Replacement for function
7310 lookup_face_for_charset. 7310 lookup_face_for_charset.
7311 7311
7312 * xfaces.c (free_font_names): Renamed from free_split_font_names. 7312 * xfaces.c (free_font_names): Rename from free_split_font_names.
7313 (free_all_realized_faces): Renamed from remove_all_realized_faces. 7313 (free_all_realized_faces): Rename from remove_all_realized_faces.
7314 7314
73151998-04-25 Gerd Moellmann <gerd@gnu.org> 73151998-04-25 Gerd Moellmann <gerd@gnu.org>
7316 7316
@@ -7329,8 +7329,8 @@
7329 7329
73301998-04-24 Gerd Moellmann <gerd@gnu.org> 73301998-04-24 Gerd Moellmann <gerd@gnu.org>
7331 7331
7332 * dispextern.h (struct face): Member 7332 * dispextern.h (struct face):
7333 fontset_chosen_for_realization_p removed. 7333 Member fontset_chosen_for_realization_p removed.
7334 7334
7335 * xfaces.c (cache_face): If face->fontset >= 0, add face to the 7335 * xfaces.c (cache_face): If face->fontset >= 0, add face to the
7336 end of the collision list, so that we find more specific faces 7336 end of the collision list, so that we find more specific faces
@@ -7365,8 +7365,8 @@
7365 (xlfd_point_size): Return -1 if resolution or point size of 7365 (xlfd_point_size): Return -1 if resolution or point size of
7366 font unknown. 7366 font unknown.
7367 7367
7368 * xfaces.c (free_font): Removed. 7368 * xfaces.c (free_font): Remove.
7369 (load_face_font_or_fontset): Renamed from load_font. 7369 (load_face_font_or_fontset): Rename from load_font.
7370 (load_face_font_or_fontset): Use message2 instead of signaling. 7370 (load_face_font_or_fontset): Use message2 instead of signaling.
7371 (load_color): Likewise. 7371 (load_color): Likewise.
7372 (load_pixmap): Likewise. 7372 (load_pixmap): Likewise.
@@ -7408,8 +7408,8 @@
7408 to -1 so that it will compute the right face for the truncation 7408 to -1 so that it will compute the right face for the truncation
7409 glyphs. 7409 glyphs.
7410 7410
7411 * xfaces.c (realize_face): Set 7411 * xfaces.c (realize_face):
7412 face->fontset_chosen_for_realization_p. 7412 Set face->fontset_chosen_for_realization_p.
7413 (lookup_face_for_charset): If fontset wasn't specified originally 7413 (lookup_face_for_charset): If fontset wasn't specified originally
7414 and new charset != CHARSET_COMPOSITION, get a new face for that 7414 and new charset != CHARSET_COMPOSITION, get a new face for that
7415 charset. 7415 charset.
@@ -7461,9 +7461,9 @@
7461 (lface_hash): Add weight, slant, swidth and relief to hash value. 7461 (lface_hash): Add weight, slant, swidth and relief to hash value.
7462 (lface_equal_p): Make it faster. 7462 (lface_equal_p): Make it faster.
7463 (lface_from_symbol): Use assq_no_quit. 7463 (lface_from_symbol): Use assq_no_quit.
7464 (Fnote_default_face_changed): Removed. 7464 (Fnote_default_face_changed): Remove.
7465 (cmp_font_names): Use strcmp instead of xstricmp. 7465 (cmp_font_names): Use strcmp instead of xstricmp.
7466 (face_charset_registries): Removed. 7466 (face_charset_registries): Remove.
7467 7467
74681998-04-20 Gerd Moellmann <gerd@gnu.org> 74681998-04-20 Gerd Moellmann <gerd@gnu.org>
7469 7469
@@ -7487,8 +7487,8 @@
7487 7487
7488 * xfaces.c (Finternal_set_lisp_face_attribute): Add :bold 7488 * xfaces.c (Finternal_set_lisp_face_attribute): Add :bold
7489 and :italic for compatibility. 7489 and :italic for compatibility.
7490 (Finternal_set_lisp_face_attribute_from_resource): Handle 7490 (Finternal_set_lisp_face_attribute_from_resource):
7491 :bold and :italic. Handle boolean resource values for 7491 Handle :bold and :italic. Handle boolean resource values for
7492 :underline and :italic. 7492 :underline and :italic.
7493 7493
7494 * xfns.c (display_x_get_resource): Make it externally visible. 7494 * xfns.c (display_x_get_resource): Make it externally visible.
@@ -7500,7 +7500,7 @@
7500 definitions. 7500 definitions.
7501 (Finternal_lisp_face_equal_p): Additional frame argument. 7501 (Finternal_lisp_face_equal_p): Additional frame argument.
7502 (merge_lisp_face_vector_with_property): Ditto. 7502 (merge_lisp_face_vector_with_property): Ditto.
7503 (Frealize_basic_faces): Removed. 7503 (Frealize_basic_faces): Remove.
7504 (Finternal_get_lisp_face_attribute): Additional frame argument. 7504 (Finternal_get_lisp_face_attribute): Additional frame argument.
7505 (Finternal_lisp_face_p): Ditto. 7505 (Finternal_lisp_face_p): Ditto.
7506 (load_color) [MSDOS]: Removed because it isn't clear how 7506 (load_color) [MSDOS]: Removed because it isn't clear how
@@ -7531,8 +7531,8 @@
7531 * xdisp.c (redisplay_internal, echo_area-display): If realized 7531 * xdisp.c (redisplay_internal, echo_area-display): If realized
7532 faces have been cleared, call recompute_basic_faces. 7532 faces have been cleared, call recompute_basic_faces.
7533 7533
7534 * xfaces.c (recompute_basic_faces): Free realized faces. Reset 7534 * xfaces.c (recompute_basic_faces): Free realized faces.
7535 face_attributes_changed_p. 7535 Reset face_attributes_changed_p.
7536 (remove_all_realized_faces): Remove all realized faces on 7536 (remove_all_realized_faces): Remove all realized faces on
7537 all frames. 7537 all frames.
7538 (Finternal_set_lisp_face_attribute): Call remove_all_realized_faces. 7538 (Finternal_set_lisp_face_attribute): Call remove_all_realized_faces.
@@ -7541,7 +7541,7 @@
7541 changed since the last redisplay, recompute basic faces. 7541 changed since the last redisplay, recompute basic faces.
7542 (echo_area_display): Ditto. 7542 (echo_area_display): Ditto.
7543 7543
7544 * xfaces.c (clear_face_gcs): Renamed from clear_realized_face_cache. 7544 * xfaces.c (clear_face_gcs): Rename from clear_realized_face_cache.
7545 7545
7546 * xfaces.c (min_char_bounds): If face cache not yet present, 7546 * xfaces.c (min_char_bounds): If face cache not yet present,
7547 don't try to get font dimensions from faces. 7547 don't try to get font dimensions from faces.
@@ -7549,11 +7549,11 @@
7549 * xterm.c (x_frame_mode_line_height): If face cache not present 7549 * xterm.c (x_frame_mode_line_height): If face cache not present
7550 set, return default height. 7550 set, return default height.
7551 7551
7552 * alloc.c (mark_face_cache): Check for null faces. Correct 7552 * alloc.c (mark_face_cache): Check for null faces.
7553 index bug. 7553 Correct index bug.
7554 7554
7555 * dispextern.h (struct face): Renamed from struct rface. Member 7555 * dispextern.h (struct face): Rename from struct rface.
7556 underline renamed underline_p. Make it a bit-field. 7556 Member underline renamed underline_p. Make it a bit-field.
7557 7557
7558 * xfaces.c (init_frame_faces): Allocate face cache. 7558 * xfaces.c (init_frame_faces): Allocate face cache.
7559 (free_frame_faces): Free face cache. 7559 (free_frame_faces): Free face cache.
@@ -7562,7 +7562,7 @@
7562 7562
7563 * frame.c (make_frame): Initialze face cache with null. 7563 * frame.c (make_frame): Initialze face cache with null.
7564 7564
7565 * xfaces.c (same_size_fonts): Removed. 7565 * xfaces.c (same_size_fonts): Remove.
7566 7566
7567 * xterm.c (x_set_glyph_string_gc): Add post-condition 7567 * xterm.c (x_set_glyph_string_gc): Add post-condition
7568 s->gc != 0. 7568 s->gc != 0.
@@ -7584,56 +7584,56 @@
7584 7584
7585 * xfaces.c (syms_of_xfaces): Correct calls to defsubr. 7585 * xfaces.c (syms_of_xfaces): Correct calls to defsubr.
7586 7586
7587 * xfns.c (Fx_face_fixed_p): Removed. 7587 * xfns.c (Fx_face_fixed_p): Remove.
7588 (Fx_list_fonts): Moved to xfaces.c. 7588 (Fx_list_fonts): Move to xfaces.c.
7589 7589
7590 * xfaces.c (compute_face_at_buffer_pos): Renamed to 7590 * xfaces.c (compute_face_at_buffer_pos): Rename to
7591 face_at_buffer_position. Parameter charset removed; always 7591 face_at_buffer_position. Parameter charset removed; always
7592 compute face for CHARSET_ASCII. 7592 compute face for CHARSET_ASCII.
7593 (face_at_string_position): Renamed from 7593 (face_at_string_position): Rename from
7594 compute_face_at_string_pos. Parameter charset removed; always 7594 compute_face_at_string_pos. Parameter charset removed; always
7595 compute for CHARSET_ASCII. 7595 compute for CHARSET_ASCII.
7596 (lookup_face_for_charset): Take frame parameter instead of 7596 (lookup_face_for_charset): Take frame parameter instead of
7597 face_cache. 7597 face_cache.
7598 (lookup_face): Ditto. 7598 (lookup_face): Ditto.
7599 (compute_char_face): Renamed from compute_glyph_face. 7599 (compute_char_face): Rename from compute_glyph_face.
7600 7600
7601 * xdisp.c (init_iterator): Initialize charset member. 7601 * xdisp.c (init_iterator): Initialize charset member.
7602 (reseat_iterator_to_string): Ditto. 7602 (reseat_iterator_to_string): Ditto.
7603 (get_charset_at_buffer_position): Determine charset at 7603 (get_charset_at_buffer_position): Determine charset at
7604 buffer position in current_buffer. 7604 buffer position in current_buffer.
7605 (reseat_iterator): Call above function. 7605 (reseat_iterator): Call above function.
7606 (compute_face_at_iterator_position): Call 7606 (compute_face_at_iterator_position):
7607 compute_face_at_buffer_pos. 7607 Call compute_face_at_buffer_pos.
7608 (compute_face_at_iterator_string_position): Call 7608 (compute_face_at_iterator_string_position):
7609 compute_face_at_string_pos. 7609 Call compute_face_at_string_pos.
7610 (get_face_from_id): Removed. 7610 (get_face_from_id): Remove.
7611 (get_face_from_cursor_pos): Call compute_face_at_buffer_pos. 7611 (get_face_from_cursor_pos): Call compute_face_at_buffer_pos.
7612 Call get_charset_at_buffer_position. 7612 Call get_charset_at_buffer_position.
7613 (reseat_iterator): Determine face if charset at pos differs 7613 (reseat_iterator): Determine face if charset at pos differs
7614 from iterator's charset. 7614 from iterator's charset.
7615 (reseat_iterator_to_glyph_pos): Removed. 7615 (reseat_iterator_to_glyph_pos): Remove.
7616 7616
7617 * xfaces.c (compute_face_at_bufpos): Remove parameter charset. 7617 * xfaces.c (compute_face_at_bufpos): Remove parameter charset.
7618 Determine charset from buffer position. 7618 Determine charset from buffer position.
7619 (compute_string_char_face): Renamed to compute_face_at_string_pos. 7619 (compute_string_char_face): Rename to compute_face_at_string_pos.
7620 (compute_face_at_bufpos): Renamed to compute_face_at_buffer_pos. 7620 (compute_face_at_bufpos): Rename to compute_face_at_buffer_pos.
7621 7621
7622 * dispextern.h (struct display_iterator): Add member charset. 7622 * dispextern.h (struct display_iterator): Add member charset.
7623 7623
76241998-04-15 Gerd Moellmann <gerd@gnu.org> 76241998-04-15 Gerd Moellmann <gerd@gnu.org>
7625 7625
7626 * xfaces.c (compute_char_face): Removed. 7626 * xfaces.c (compute_char_face): Remove.
7627 7627
7628 * xdisp.c (get_overlay_arrow_glyph_row): Use compute_glyph_face 7628 * xdisp.c (get_overlay_arrow_glyph_row): Use compute_glyph_face
7629 with new parameter list. 7629 with new parameter list.
7630 7630
7631 * xfaces.c (region_face): Removed. 7631 * xfaces.c (region_face): Remove.
7632 (allocate_face): Removed. 7632 (allocate_face): Remove.
7633 (copy_face): Ditto. 7633 (copy_face): Ditto.
7634 (face_eql): Removed. 7634 (face_eql): Remove.
7635 (intern_face): Removed. 7635 (intern_face): Remove.
7636 (clear_face_cache): Removed. 7636 (clear_face_cache): Remove.
7637 (load_font): Ditto. 7637 (load_font): Ditto.
7638 (unload_font): Ditto. 7638 (unload_font): Ditto.
7639 (load_color): Ditto. 7639 (load_color): Ditto.
@@ -7644,9 +7644,9 @@
7644 (merge_faces): Ditto. 7644 (merge_faces): Ditto.
7645 (compute_base_face): Ditto. 7645 (compute_base_face): Ditto.
7646 (merge_face_list): Ditto. 7646 (merge_face_list): Ditto.
7647 (Fmake_face_internal): Removed. 7647 (Fmake_face_internal): Remove.
7648 (Fset_face_attribute_internal): Ditto. 7648 (Fset_face_attribute_internal): Ditto.
7649 (face_name_id_number): Removed. 7649 (face_name_id_number): Remove.
7650 (Fframe_face_alist): Ditto. 7650 (Fframe_face_alist): Ditto.
7651 (Fset_frame_face_alist): Ditto. 7651 (Fset_frame_face_alist): Ditto.
7652 (Finternal_next_face_id): Ditto. 7652 (Finternal_next_face_id): Ditto.
@@ -7693,7 +7693,7 @@
7693 * fontset.h: Add external declarations for Vfontset_alias_alist 7693 * fontset.h: Add external declarations for Vfontset_alias_alist
7694 and Vglobal_fontset_alist. 7694 and Vglobal_fontset_alist.
7695 7695
7696 * xfaces.c (merge_lisp_face_vector_with_property): Simplified. 7696 * xfaces.c (merge_lisp_face_vector_with_property): Simplify.
7697 (realize_default_face): If frame parameters contain an artificial 7697 (realize_default_face): If frame parameters contain an artificial
7698 font name naming a fontset, set the family of the default face to 7698 font name naming a fontset, set the family of the default face to
7699 the fontset name given by the registry. 7699 the fontset name given by the registry.
@@ -7741,11 +7741,11 @@
7741 * xdisp.c (set_cursor_from_row): If PT is not found in the 7741 * xdisp.c (set_cursor_from_row): If PT is not found in the
7742 row, display the cursor at the start of the row. 7742 row, display the cursor at the start of the row.
7743 7743
7744 * dispnew.c (direct_output_forward_char): Call 7744 * dispnew.c (direct_output_forward_char):
7745 set_cursor_from_row. 7745 Call set_cursor_from_row.
7746 7746
7747 * xdisp.c (setup_iterator_overlay_strings_from_glyph_pos): If 7747 * xdisp.c (setup_iterator_overlay_strings_from_glyph_pos):
7748 position is not in an overlay string, set iterator's position and 7748 If position is not in an overlay string, set iterator's position and
7749 method explicitly so. 7749 method explicitly so.
7750 (set_cursor_from_row): Correct cursor position calculation. 7750 (set_cursor_from_row): Correct cursor position calculation.
7751 Make it externally visible. 7751 Make it externally visible.
@@ -7907,7 +7907,7 @@
7907 * dispnew.c: Make compilable with -Wall. 7907 * dispnew.c: Make compilable with -Wall.
7908 * term.c: Ditto. 7908 * term.c: Ditto.
7909 7909
7910 * charset.h (CHAR_LEN): Moved here from dispextern.h. 7910 * charset.h (CHAR_LEN): Move here from dispextern.h.
7911 7911
79121998-03-14 Gerd Moellmann <gerd@gnu.org> 79121998-03-14 Gerd Moellmann <gerd@gnu.org>
7913 7913
@@ -7939,8 +7939,8 @@
7939 * xdisp.c (init_iterator): Increase last_visible_x by vertical 7939 * xdisp.c (init_iterator): Increase last_visible_x by vertical
7940 scroll bar width for mode lines. 7940 scroll bar width for mode lines.
7941 7941
7942 * dispnew.c (allocate_matrices_for_window_redisplay): Include 7942 * dispnew.c (allocate_matrices_for_window_redisplay):
7943 vertical scroll bar width in width calculation so that we can 7943 Include vertical scroll bar width in width calculation so that we can
7944 display mode lines wider. 7944 display mode lines wider.
7945 7945
7946 * xdisp.c (redisplay_window): Restore buffers before returning 7946 * xdisp.c (redisplay_window): Restore buffers before returning
@@ -7958,7 +7958,7 @@
7958 * dispextern.h (struct glyph_row): Member max_ascent renamed 7958 * dispextern.h (struct glyph_row): Member max_ascent renamed
7959 ascent. Member max_descent replaced by height. 7959 ascent. Member max_descent replaced by height.
7960 (struct display_iterator): Member max_descent replaced by height. 7960 (struct display_iterator): Member max_descent replaced by height.
7961 (MATRIX_ROW_PIXEL_HEIGHT): Removed. 7961 (MATRIX_ROW_PIXEL_HEIGHT): Remove.
7962 7962
7963 * xterm.c (x_alloc_lighter_color): Don't free colors if visual 7963 * xterm.c (x_alloc_lighter_color): Don't free colors if visual
7964 class makes it unnecessary or dangerous. 7964 class makes it unnecessary or dangerous.
@@ -7999,10 +7999,10 @@
7999 * xterm.c (x_scroll_run): Don't set updated_window to null. 7999 * xterm.c (x_scroll_run): Don't set updated_window to null.
8000 This resets updated_window when called from scrolling_window. 8000 This resets updated_window when called from scrolling_window.
8001 8001
8002 * dispextern.h (scroll_run_hook): Renamed from line_dance_hook. 8002 * dispextern.h (scroll_run_hook): Rename from line_dance_hook.
8003 8003
8004 * xterm.c (x_scroll_run): Additional window parameter. Set 8004 * xterm.c (x_scroll_run): Additional window parameter.
8005 and reset updated_window. 8005 Set and reset updated_window.
8006 8006
8007 * dispnew.c (line_dance_hook): Additional window parameter. 8007 * dispnew.c (line_dance_hook): Additional window parameter.
8008 8008
@@ -8016,7 +8016,7 @@
8016 * dispnew.c (Fblink_cursor): Remove call to detect_input_pending. 8016 * dispnew.c (Fblink_cursor): Remove call to detect_input_pending.
8017 Don't redraw cursor during redisplay. 8017 Don't redraw cursor during redisplay.
8018 8018
8019 * xterm.c (x_scroll_run): Renamed from do_line_dance. 8019 * xterm.c (x_scroll_run): Rename from do_line_dance.
8020 8020
8021 * xdisp.c (redisplay_window): For window-based redisplay, always 8021 * xdisp.c (redisplay_window): For window-based redisplay, always
8022 try try_window_id. 8022 try try_window_id.
@@ -8080,8 +8080,8 @@
8080 8080
8081 * xdisp.c (set_next_iterator_stop_pos): No longer static. 8081 * xdisp.c (set_next_iterator_stop_pos): No longer static.
8082 8082
8083 * dispnew.c (direct_output_for_insert): Call 8083 * dispnew.c (direct_output_for_insert):
8084 set_next_iterator_stop_pos after having changed it2.endpos. 8084 Call set_next_iterator_stop_pos after having changed it2.endpos.
8085 8085
80861998-02-17 Gerd Moellmann <gerd@gnu.org> 80861998-02-17 Gerd Moellmann <gerd@gnu.org>
8087 8087
@@ -8102,22 +8102,22 @@
8102 enough glyphs to display a mode line or menu line which draws over 8102 enough glyphs to display a mode line or menu line which draws over
8103 flags areas. 8103 flags areas.
8104 8104
8105 * xterm.c (XTset_vertical_scroll_bar): Use 8105 * xterm.c (XTset_vertical_scroll_bar):
8106 WINDOW_DISPLAY_TEXT_AREA_PIXEL_HEIGHT instead of 8106 Use WINDOW_DISPLAY_TEXT_AREA_PIXEL_HEIGHT instead of
8107 VERTICAL_SCROLL_BAR_PIXEL_HEIGHT. 8107 VERTICAL_SCROLL_BAR_PIXEL_HEIGHT.
8108 (x_draw_glyphs): Draw over flags areas when drawing a mode line 8108 (x_draw_glyphs): Draw over flags areas when drawing a mode line
8109 or menu. 8109 or menu.
8110 (x_set_glyph_string_clipping): Set clipping differently if drawing 8110 (x_set_glyph_string_clipping): Set clipping differently if drawing
8111 a mode line or menu line. 8111 a mode line or menu line.
8112 8112
8113 * xterm.h (VERTICAL_SCROLL_BAR_PIXEL_HEIGHT): Removed. 8113 * xterm.h (VERTICAL_SCROLL_BAR_PIXEL_HEIGHT): Remove.
8114 8114
8115 * xterm.c (expose_line): Don't draw bitmaps for mode lines and 8115 * xterm.c (expose_line): Don't draw bitmaps for mode lines and
8116 menu lines. 8116 menu lines.
8117 (x_scroll_bar_create): Don't clear flags areas. 8117 (x_scroll_bar_create): Don't clear flags areas.
8118 (x_draw_row_bitmaps): Clear visible row height, only. 8118 (x_draw_row_bitmaps): Clear visible row height, only.
8119 8119
8120 * dispnew.c (Fblink_cursor): Moved here from xdisp.c. 8120 * dispnew.c (Fblink_cursor): Move here from xdisp.c.
8121 8121
81221998-02-15 Gerd Moellmann <gerd@gnu.org> 81221998-02-15 Gerd Moellmann <gerd@gnu.org>
8123 8123
@@ -8137,21 +8137,21 @@
8137 * dispnew.c (update_window_line): Special handling of inverse 8137 * dispnew.c (update_window_line): Special handling of inverse
8138 lines in #if 0 removed. 8138 lines in #if 0 removed.
8139 8139
8140 * xterm.c (x_write_glyphs): Renamed from XTwrite_glyphs. 8140 * xterm.c (x_write_glyphs): Rename from XTwrite_glyphs.
8141 (x_insert_glyphs): Renamed from XTinsert_glyphs. 8141 (x_insert_glyphs): Rename from XTinsert_glyphs.
8142 (x_clear_frame): Renamed from XTclear_frame. 8142 (x_clear_frame): Rename from XTclear_frame.
8143 (x_clear_end_of_line): Renamed from XTclear_end_of_line. 8143 (x_clear_end_of_line): Rename from XTclear_end_of_line.
8144 (x_ins_del_lines): Renamed from XTins_del_lines. 8144 (x_ins_del_lines): Rename from XTins_del_lines.
8145 (x_change_line_height): Renamed from XTchange_line_height. 8145 (x_change_line_height): Rename from XTchange_line_height.
8146 (x_delete_glyphs): Renamed from XTdelete_glyphs. 8146 (x_delete_glyphs): Rename from XTdelete_glyphs.
8147 (x_clear_cursor): Renamed from clear_cursor. 8147 (x_clear_cursor): Rename from clear_cursor.
8148 (x_update_begin): Renamed from XTupdate_begin. 8148 (x_update_begin): Rename from XTupdate_begin.
8149 (x_update_end): Renamed from XTupdate_end. 8149 (x_update_end): Rename from XTupdate_end.
8150 (x_update_window_begin): Renamed from XTupdate_window_begin. 8150 (x_update_window_begin): Rename from XTupdate_window_begin.
8151 (x_update_window_end): Renamed from XTupdate_window_end. 8151 (x_update_window_end): Rename from XTupdate_window_end.
8152 (x_frame_mode_line_height): Renamed from XTframe_mode_line_height. 8152 (x_frame_mode_line_height): Rename from XTframe_mode_line_height.
8153 (x_produce_glyphs): Renamed from XTproduce_glyphs. 8153 (x_produce_glyphs): Rename from XTproduce_glyphs.
8154 (x_produce_special_glyphs): Renamed from XTproduce_special_glyphs. 8154 (x_produce_special_glyphs): Rename from XTproduce_special_glyphs.
8155 (x_produce_special_glyphs): Implementation in #if 0 removed. 8155 (x_produce_special_glyphs): Implementation in #if 0 removed.
8156 8156
8157 * xdisp.c (Fdump_redisplay_state): Display row's fill_line_p 8157 * xdisp.c (Fdump_redisplay_state): Display row's fill_line_p
@@ -8232,14 +8232,14 @@
8232 8232
8233 * dispextern.h (struct glyph_matrix): New member window_width. 8233 * dispextern.h (struct glyph_matrix): New member window_width.
8234 8234
8235 * dispnew.c (adjust_glyph_matrix): Set window_width. Optimize 8235 * dispnew.c (adjust_glyph_matrix): Set window_width.
8236 case of changing window height. 8236 Optimize case of changing window height.
8237 8237
8238 * xterm.c (x_draw_row_bitmaps): Don't clear vertical window 8238 * xterm.c (x_draw_row_bitmaps): Don't clear vertical window
8239 border to the left. 8239 border to the left.
8240 8240
8241 * dispextern.h (struct glyph_row): Remove right_to_left_p. RMS 8241 * dispextern.h (struct glyph_row): Remove right_to_left_p.
8242 says this aspect of Emacs is currently redesigned. 8242 RMS says this aspect of Emacs is currently redesigned.
8243 8243
8244 * xterm.c (x_clip_to_row): Subtract 1 from clip width if we 8244 * xterm.c (x_clip_to_row): Subtract 1 from clip width if we
8245 have to draw a vertical border. 8245 have to draw a vertical border.
@@ -8268,8 +8268,8 @@
8268 removed. 8268 removed.
8269 (struct glyph): Ditto. 8269 (struct glyph): Ditto.
8270 8270
8271 * xterm.c (x_draw_relief): Removed. 8271 * xterm.c (x_draw_relief): Remove.
8272 (x_draw_bitmap): Renamed from draw_bitmap. 8272 (x_draw_bitmap): Rename from draw_bitmap.
8273 (x_draw_glyphs): Completely new implementation of draw_glyphs 8273 (x_draw_glyphs): Completely new implementation of draw_glyphs
8274 capable of handling arbitrary lbearing and rbearing values. 8274 capable of handling arbitrary lbearing and rbearing values.
8275 Several sub-functions not mentioned here. 8275 Several sub-functions not mentioned here.
@@ -8347,11 +8347,11 @@
8347 8347
83481998-01-25 Gerd Moellmann <gerd@gnu.org> 83481998-01-25 Gerd Moellmann <gerd@gnu.org>
8349 8349
8350 * dispextern.h (DEFAULT_FACE_ID, MODE_LINE_FACE_ID): Symbolic 8350 * dispextern.h (DEFAULT_FACE_ID, MODE_LINE_FACE_ID):
8351 names for face ids of frame default face and mode line face. 8351 Symbolic names for face ids of frame default face and mode line face.
8352 8352
8353 * xdisp.c (compute_face_at_iterator_string_position): If 8353 * xdisp.c (compute_face_at_iterator_string_position):
8354 displaying a mode line use MODE_LINE_FACE_ID instead of 8354 If displaying a mode line use MODE_LINE_FACE_ID instead of
8355 DEFAULT_FACE_ID. 8355 DEFAULT_FACE_ID.
8356 8356
8357 * xdisp.c (reseat_iterator_to_string): Additional parameter start. 8357 * xdisp.c (reseat_iterator_to_string): Additional parameter start.
@@ -8405,8 +8405,8 @@
8405 (move_iterator_in_display_line_to): If to_pos specified, move 8405 (move_iterator_in_display_line_to): If to_pos specified, move
8406 over before-strings. 8406 over before-strings.
8407 8407
8408 * dispextern.h (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P): Test 8408 * dispextern.h (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P):
8409 start.string_index > 0. 8409 Test start.string_index > 0.
8410 8410
8411 * xdisp.c (redisplay_internal): Adjust glyphs if fonts_changed_p 8411 * xdisp.c (redisplay_internal): Adjust glyphs if fonts_changed_p
8412 is set. Retry redisplay if fonts_changed_p is set before update. 8412 is set. Retry redisplay if fonts_changed_p is set before update.
@@ -8415,7 +8415,7 @@
8415 8415
8416 * xfaces.c (Fset_face_attribute_internal): Set fonts_changed_p. 8416 * xfaces.c (Fset_face_attribute_internal): Set fonts_changed_p.
8417 8417
8418 * dispnew.c (adjust_glyphs_for_font_change): Removed. 8418 * dispnew.c (adjust_glyphs_for_font_change): Remove.
8419 8419
8420 * xdisp.c (try_window): Check fonts_changed_p. 8420 * xdisp.c (try_window): Check fonts_changed_p.
8421 (try_window_reusing_current_matrix): Ditto. 8421 (try_window_reusing_current_matrix): Ditto.
@@ -8468,8 +8468,8 @@
8468 * editfns.c (make_buffer_string): If PROMPT_IN_BUFFER, add prompt 8468 * editfns.c (make_buffer_string): If PROMPT_IN_BUFFER, add prompt
8469 length to start position. 8469 length to start position.
8470 8470
8471 * buffer.c (Fget_buffer_create): Initialize 8471 * buffer.c (Fget_buffer_create):
8472 minibuffer_prompt_length. 8472 Initialize minibuffer_prompt_length.
8473 (Fmake_indirect_buffer): Ditto. 8473 (Fmake_indirect_buffer): Ditto.
8474 (Fkill_buffer): Ditto. 8474 (Fkill_buffer): Ditto.
8475 8475
@@ -8489,15 +8489,15 @@
8489 * xfaces.c (compute_string_char_face): Compute face for 8489 * xfaces.c (compute_string_char_face): Compute face for
8490 arbitrary Lisp string. Renamed from compute_overlay_string_char_face. 8490 arbitrary Lisp string. Renamed from compute_overlay_string_char_face.
8491 8491
8492 * xdisp.c (next_element_from_string): Renamed from 8492 * xdisp.c (next_element_from_string): Rename from
8493 next_element_from_overlay_string. 8493 next_element_from_overlay_string.
8494 (compute_face_at_iterator_string_position): Renamed from 8494 (compute_face_at_iterator_string_position): Rename from
8495 compute_face_at_iterator_overlay_string_position. 8495 compute_face_at_iterator_overlay_string_position.
8496 8496
8497 * dispextern.h (struct display_iterator): Member overlay_string 8497 * dispextern.h (struct display_iterator): Member overlay_string
8498 renamed string. 8498 renamed string.
8499 8499
8500 * xdisp.c (next_element_from_c_string): Renamed from 8500 * xdisp.c (next_element_from_c_string): Rename from
8501 next_element_from_string. 8501 next_element_from_string.
8502 8502
8503 * dispextern.h (struct glyph_pos): Reversed meaning of 8503 * dispextern.h (struct glyph_pos): Reversed meaning of
@@ -8535,8 +8535,8 @@
8535 8535
85361998-01-17 Gerd Moellmann <gerd@gnu.org> 85361998-01-17 Gerd Moellmann <gerd@gnu.org>
8537 8537
8538 * xdisp.c (move_iterator_vertically): Check post-condition. Move 8538 * xdisp.c (move_iterator_vertically): Check post-condition.
8539 to start of line if ending at ZV and no newline in front. 8539 Move to start of line if ending at ZV and no newline in front.
8540 (move_iterator_to): If to_y specified, always first move to x = 0, 8540 (move_iterator_to): If to_y specified, always first move to x = 0,
8541 so that move stops at line start instead of line end. This is 8541 so that move stops at line start instead of line end. This is
8542 probably what callers would expect to happen. 8542 probably what callers would expect to happen.
@@ -8561,19 +8561,19 @@
8561 try_window_reusing_current_matrix if window scroll functions 8561 try_window_reusing_current_matrix if window scroll functions
8562 exist. 8562 exist.
8563 8563
8564 * dispextern.h (struct display_iterator): Member 8564 * dispextern.h (struct display_iterator):
8565 redisplay_end_trigger_p removed. 8565 Member redisplay_end_trigger_p removed.
8566 8566
8567 * dispextern.h (WINDOW_DISPLAY_PIXEL_HEIGHT_WITHOUT_MODE_LINE): 8567 * dispextern.h (WINDOW_DISPLAY_PIXEL_HEIGHT_WITHOUT_MODE_LINE):
8568 Renamed to WINDOW_DISPLAY_TEXT_AREA_PIXEL_HEIGHT. 8568 Rename to WINDOW_DISPLAY_TEXT_AREA_PIXEL_HEIGHT.
8569 8569
85701998-01-16 Gerd Moellmann <gerd@gnu.org> 85701998-01-16 Gerd Moellmann <gerd@gnu.org>
8571 8571
8572 * xdisp.c (move_iterator_by_lines): Optimize for truncate-lines 8572 * xdisp.c (move_iterator_by_lines): Optimize for truncate-lines
8573 nil. Optimize truncate-lines t and moving backward. 8573 nil. Optimize truncate-lines t and moving backward.
8574 (move_iterator_to_previous_visible_line_start): Contains the heart 8574 (move_iterator_to_previous_visible_line_start): Contains the heart
8575 of the previous set_iterator_to_previous_visible_line_end. Don't 8575 of the previous set_iterator_to_previous_visible_line_end.
8576 reseat the iterator. Used by move_iterator_by_lines. 8576 Don't reseat the iterator. Used by move_iterator_by_lines.
8577 (set_iterator_to_previous_visible_line_start): Call function 8577 (set_iterator_to_previous_visible_line_start): Call function
8578 above. 8578 above.
8579 (move_iterator_in_display_line_to): Check TO_POS before doing 8579 (move_iterator_in_display_line_to): Check TO_POS before doing
@@ -8608,8 +8608,8 @@
8608 (Fset_face_attribute_internal): Use XINT instead of XFASTINT 8608 (Fset_face_attribute_internal): Use XINT instead of XFASTINT
8609 to get a relief because they can be negative. 8609 to get a relief because they can be negative.
8610 8610
8611 * xterm.c (x_draw_relief): Correct line drawing positions. Pixel 8611 * xterm.c (x_draw_relief): Correct line drawing positions.
8612 positions are for the middle of lines under X. 8612 Pixel positions are for the middle of lines under X.
8613 8613
8614 * xdisp.c (try_window_id): Always search for the cursor by setting 8614 * xdisp.c (try_window_id): Always search for the cursor by setting
8615 w->cursor.vpos = -1. Search in unchanged rows at the top and 8615 w->cursor.vpos = -1. Search in unchanged rows at the top and
@@ -8642,16 +8642,16 @@
8642 8642
8643 * xdisp.c (display_line): Bug fix cursor positioning. 8643 * xdisp.c (display_line): Bug fix cursor positioning.
8644 8644
8645 * xfns.c (x-list-fonts): Copied from x-list-fonts.c; #include 8645 * xfns.c (x-list-fonts): Copy from x-list-fonts.c; #include
8646 removed. x-list-fonts.c is now obsolete. 8646 removed. x-list-fonts.c is now obsolete.
8647 (Qfixed, Qvariable): Moved here from xfaces.c. 8647 (Qfixed, Qvariable): Move here from xfaces.c.
8648 8648
86491998-01-14 Gerd Moellmann <gerd@gnu.org> 86491998-01-14 Gerd Moellmann <gerd@gnu.org>
8650 8650
8651 * xdisp.c (display_line): Set row->ends_at_zv_p based on 8651 * xdisp.c (display_line): Set row->ends_at_zv_p based on
8652 FETCH_BYTE for truncated lines. 8652 FETCH_BYTE for truncated lines.
8653 (display_line): Set cursor differently. 8653 (display_line): Set cursor differently.
8654 (display_line): Fixed bug setting last_pos_on_this_line wrong 8654 (display_line): Fix bug setting last_pos_on_this_line wrong
8655 for truncated lines. 8655 for truncated lines.
8656 8656
8657 * dispnew.c (adjust_glyph_matrix): Always adjust for frame-based 8657 * dispnew.c (adjust_glyph_matrix): Always adjust for frame-based
@@ -8659,8 +8659,8 @@
8659 8659
8660 * window.c (Fsplit_window): Adjust glyphs before setting buffer. 8660 * window.c (Fsplit_window): Adjust glyphs before setting buffer.
8661 8661
8662 * dispnew.c (adjust_frame_glyphs_for_window_redisplay): Add 8662 * dispnew.c (adjust_frame_glyphs_for_window_redisplay):
8663 assertion that character dimensions are not zero. 8663 Add assertion that character dimensions are not zero.
8664 8664
8665 * xterm.c (x_load_font): adjust_glyphs_for_font_change while 8665 * xterm.c (x_load_font): adjust_glyphs_for_font_change while
8666 input is blocked. 8666 input is blocked.
@@ -8680,7 +8680,7 @@
8680 8680
8681 * xterm.h (FRAME_FLAGS_BITMAP_WIDTH): Macro giving the width 8681 * xterm.h (FRAME_FLAGS_BITMAP_WIDTH): Macro giving the width
8682 in pixels of a flags area of a frame. 8682 in pixels of a flags area of a frame.
8683 (FRAME_X_FLAGS_AREA_WIDTH): Removed. 8683 (FRAME_X_FLAGS_AREA_WIDTH): Remove.
8684 (FRAME_X_FLAGS_AREA_COLS): Macro giving the number of columns 8684 (FRAME_X_FLAGS_AREA_COLS): Macro giving the number of columns
8685 occupied by a flags area. 8685 occupied by a flags area.
8686 8686
@@ -8694,7 +8694,7 @@
8694 8694
8695 * xdisp.c (display_line): Correct wrong calculation of row->x for 8695 * xdisp.c (display_line): Correct wrong calculation of row->x for
8696 the case of nglyphs == 1. 8696 the case of nglyphs == 1.
8697 (hscroll_window_tree): Renamed from hscroll_windows. 8697 (hscroll_window_tree): Rename from hscroll_windows.
8698 (hscroll_windows): New function calling hscroll_window_tree that 8698 (hscroll_windows): New function calling hscroll_window_tree that
8699 clears desired matrices on a frame when hscroll has been changed. 8699 clears desired matrices on a frame when hscroll has been changed.
8700 (redisplay_p): Global flag set during redisplay. 8700 (redisplay_p): Global flag set during redisplay.
@@ -8725,8 +8725,8 @@
8725 * xfaces.c (Qfixed, Qvariable): Symbols for use by x-list-fonts. 8725 * xfaces.c (Qfixed, Qvariable): Symbols for use by x-list-fonts.
8726 (syms_of_xfaces): Initialize them. 8726 (syms_of_xfaces): Initialize them.
8727 8727
8728 * xterm.c (x_list_fonts): Include auto-scaled fonts. Extend 8728 * xterm.c (x_list_fonts): Include auto-scaled fonts.
8729 cached information. 8729 Extend cached information.
8730 8730
87311998-01-11 Gerd Moellmann <gerd@acm.org> 87311998-01-11 Gerd Moellmann <gerd@acm.org>
8732 8732
@@ -8742,7 +8742,7 @@
8742 8742
87431998-01-05 Gerd Moellmann <gerd@acm.org> 87431998-01-05 Gerd Moellmann <gerd@acm.org>
8744 8744
8745 * xdisp.c (get_row_start_continuation_line_width): Removed. 8745 * xdisp.c (get_row_start_continuation_line_width): Remove.
8746 (init_iterator_to_row_start): Set it.current_x from row. 8746 (init_iterator_to_row_start): Set it.current_x from row.
8747 (try_window_id): Set it.continuation_lines_width directly from 8747 (try_window_id): Set it.continuation_lines_width directly from
8748 row. 8748 row.
@@ -8768,7 +8768,7 @@
8768 8768
87691998-01-02 Gerd Moellmann <gerd@acm.org> 87691998-01-02 Gerd Moellmann <gerd@acm.org>
8770 8770
8771 * xterm.c (x_get_mode_line_face_gc): Renamed from 8771 * xterm.c (x_get_mode_line_face_gc): Rename from
8772 x_get_modeline_face_gc. 8772 x_get_modeline_face_gc.
8773 8773
8774 * xdisp.c (TEXT_PROP_DISTANCE_LIMIT): Max. distance from current 8774 * xdisp.c (TEXT_PROP_DISTANCE_LIMIT): Max. distance from current
@@ -8820,22 +8820,22 @@
8820 * xterm.c (x_get_cursor_gc): Don't return cursor_gc for font == 8820 * xterm.c (x_get_cursor_gc): Don't return cursor_gc for font ==
8821 frame font if line height differs from font height. 8821 frame font if line height differs from font height.
8822 8822
8823 * xdisp.c (set_iterator_to_next): Renamed from 8823 * xdisp.c (set_iterator_to_next): Rename from
8824 move_iterator_forward to avoid confusion with other move_.* 8824 move_iterator_forward to avoid confusion with other move_.*
8825 functions. 8825 functions.
8826 8826
8827 * dispextern.h (FACE_RELIEF_P): Renamed from FACE_3D_P. 8827 * dispextern.h (FACE_RELIEF_P): Rename from FACE_3D_P.
8828 8828
88291997-12-31 Gerd Moellmann <gerd@acm.org> 88291997-12-31 Gerd Moellmann <gerd@acm.org>
8830 8830
8831 * xterm.c (x_get_cursor_gc): Renamed from x_cursor_gc to use the 8831 * xterm.c (x_get_cursor_gc): Rename from x_cursor_gc to use the
8832 same naming convention as for other GC functions. 8832 same naming convention as for other GC functions.
8833 (draw_glyphs): Don't fill background when drawing a cursor and 8833 (draw_glyphs): Don't fill background when drawing a cursor and
8834 font height is less than line height. 8834 font height is less than line height.
8835 8835
88361997-12-30 Gerd Moellmann <gerd@acm.org> 88361997-12-30 Gerd Moellmann <gerd@acm.org>
8837 8837
8838 * xdisp.c (init_display_iterator.*): Renamed to shorter names 8838 * xdisp.c (init_display_iterator.*): Rename to shorter names
8839 init_iterator_.*. 8839 init_iterator_.*.
8840 8840
8841 * xdisp.c (move_iterator_forward): Restore it->len from 8841 * xdisp.c (move_iterator_forward): Restore it->len from
@@ -8918,8 +8918,8 @@
8918 (x_get_char_font_and_encoding): Return null if font could not be 8918 (x_get_char_font_and_encoding): Return null if font could not be
8919 loaded. Reset font to null if fontset could not be loaded. 8919 loaded. Reset font to null if fontset could not be loaded.
8920 (draw_glyphs): Fill background if font not found. 8920 (draw_glyphs): Fill background if font not found.
8921 (draw_glyphs): Unused parameter just_foreground_p removed. New 8921 (draw_glyphs): Unused parameter just_foreground_p removed.
8922 parameter composite_glyph. 8922 New parameter composite_glyph.
8923 (draw_glyphs): Use enumeration for parameter hl. 8923 (draw_glyphs): Use enumeration for parameter hl.
8924 (draw_glyphs): Pass a display area relative x-position to 8924 (draw_glyphs): Pass a display area relative x-position to
8925 draw_glyphs when calling it recursively for composite chars. 8925 draw_glyphs when calling it recursively for composite chars.
@@ -8961,8 +8961,8 @@
8961 * xterm.c (x_after_update_window_line): Draw continuation line 8961 * xterm.c (x_after_update_window_line): Draw continuation line
8962 bitmap. 8962 bitmap.
8963 8963
8964 * dispnew.c (update_window_line): Call 8964 * dispnew.c (update_window_line):
8965 after_update_window_line_hook when row's continuation_line_p 8965 Call after_update_window_line_hook when row's continuation_line_p
8966 changes. 8966 changes.
8967 8967
8968 * xterm.c (draw_bitmap): Draw new bitmap CONTINUATION_LINE_BITMAP. 8968 * xterm.c (draw_bitmap): Draw new bitmap CONTINUATION_LINE_BITMAP.
@@ -8999,27 +8999,27 @@
8999 8999
90001997-12-14 Gerd Moellmann <gerd@acm.org> 90001997-12-14 Gerd Moellmann <gerd@acm.org>
9001 9001
9002 * frame.h (FRAME_MODE_LINE_PIXEL_HEIGHT): Removed. 9002 * frame.h (FRAME_MODE_LINE_PIXEL_HEIGHT): Remove.
9003 9003
9004 * window.c (coordinates_in_window): Call frame_mode_line_height. 9004 * window.c (coordinates_in_window): Call frame_mode_line_height.
9005 9005
9006 * xterm.c (x_draw_3d_border): Removed. 9006 * xterm.c (x_draw_3d_border): Remove.
9007 (x_draw_row_borders): Removed. 9007 (x_draw_row_borders): Remove.
9008 9008
9009 * dispnew.c (update_window): References to 9009 * dispnew.c (update_window): References to
9010 FRAME_MODE_LINE_BORDER_WIDTH removed. 9010 FRAME_MODE_LINE_BORDER_WIDTH removed.
9011 9011
9012 * xterm.h (FRAME_MODE_LINE_BORDER_WIDTH): Removed. 9012 * xterm.h (FRAME_MODE_LINE_BORDER_WIDTH): Remove.
9013 (FRAME_MODE_LINE_HEIGHT): Removed. 9013 (FRAME_MODE_LINE_HEIGHT): Remove.
9014 9014
9015 * xterm.c (draw_3d_borders_p): Removed. 9015 * xterm.c (draw_3d_borders_p): Remove.
9016 (draw_glyphs): Ditto. 9016 (draw_glyphs): Ditto.
9017 (XTwrite_glyphs): Ditto. 9017 (XTwrite_glyphs): Ditto.
9018 (expose_line): Ditto. 9018 (expose_line): Ditto.
9019 (x_initialize): Ditto. 9019 (x_initialize): Ditto.
9020 9020
9021 * dispextern.h (WINDOW_DISPLAY_MODE_LINE_HEIGHT): Call 9021 * dispextern.h (WINDOW_DISPLAY_MODE_LINE_HEIGHT):
9022 frame_mode_line_height. 9022 Call frame_mode_line_height.
9023 9023
9024 * term.c (frame_mode_line_height): Get the pixel height of a 9024 * term.c (frame_mode_line_height): Get the pixel height of a
9025 frame's mode line. 9025 frame's mode line.
@@ -9047,8 +9047,8 @@
9047 * xdisp.c (compute_face_at_iterator_overlay_string_position): 9047 * xdisp.c (compute_face_at_iterator_overlay_string_position):
9048 Use it. 9048 Use it.
9049 9049
9050 * xdisp.c (set_iterator_to_next_overlay_string): Formerly 9050 * xdisp.c (set_iterator_to_next_overlay_string):
9051 set_iterator_to_next_overlay. 9051 Formerly set_iterator_to_next_overlay.
9052 (struct overlay_entry): Structure used to sort overlay strings. 9052 (struct overlay_entry): Structure used to sort overlay strings.
9053 (compare_overlay_entries): Compare overlay strings. 9053 (compare_overlay_entries): Compare overlay strings.
9054 (load_iterator_with_overlay_strings): Load a chunk of overlay 9054 (load_iterator_with_overlay_strings): Load a chunk of overlay
@@ -9056,11 +9056,11 @@
9056 (get_overlay_strings_at_iterator_position): Call it. 9056 (get_overlay_strings_at_iterator_position): Call it.
9057 (next_element_from_overlay_string): Set it->object to the overlay 9057 (next_element_from_overlay_string): Set it->object to the overlay
9058 string. Prepare for setting it->position to a string position. 9058 string. Prepare for setting it->position to a string position.
9059 (get_overlay_strings_at_iterator_position): Renamed from 9059 (get_overlay_strings_at_iterator_position): Rename from
9060 get_overlays_at_iterator_position. 9060 get_overlays_at_iterator_position.
9061 (setup_iterator_overlay_strings_from_glyph_pos): Changed to load 9061 (setup_iterator_overlay_strings_from_glyph_pos): Change to load
9062 chunks of overlay strings. 9062 chunks of overlay strings.
9063 (load_overlay_strings): Renamed from load_iterator_overlay_strings. 9063 (load_overlay_strings): Rename from load_iterator_overlay_strings.
9064 9064
9065 * dispextern.h (struct display_iterator): New vector 9065 * dispextern.h (struct display_iterator): New vector
9066 overlay_strings and new member n_overlay_strings---formerly 9066 overlay_strings and new member n_overlay_strings---formerly
@@ -9072,9 +9072,9 @@
9072 9072
9073 * xdisp.c (copy_iterator): Increment n_iterator_overlay_vectors 9073 * xdisp.c (copy_iterator): Increment n_iterator_overlay_vectors
9074 when allocating a vector. 9074 when allocating a vector.
9075 (release_iterator): Removed. 9075 (release_iterator): Remove.
9076 (restore_iterator): Removed. 9076 (restore_iterator): Remove.
9077 (copy_iterator): Removed. 9077 (copy_iterator): Remove.
9078 9078
90791997-12-08 Gerd Moellmann <gerd@acm.org> 90791997-12-08 Gerd Moellmann <gerd@acm.org>
9080 9080
@@ -9087,10 +9087,10 @@
9087 9087
9088 * xterm.h (struct x_output): trunc_area_extra renamed 9088 * xterm.h (struct x_output): trunc_area_extra renamed
9089 flags_areas_extra. 9089 flags_areas_extra.
9090 (FRAME_X_FLAGS_AREA_WIDTH): Renamed from FRAME_X_TRUNC_WIDTH. 9090 (FRAME_X_FLAGS_AREA_WIDTH): Rename from FRAME_X_TRUNC_WIDTH.
9091 9091
9092 * dispnew.c (update_window_line): Call 9092 * dispnew.c (update_window_line):
9093 after_update_window_line_hook when current row is not enabled 9093 Call after_update_window_line_hook when current row is not enabled
9094 which is the case after a frame has been cleared. 9094 which is the case after a frame has been cleared.
9095 9095
9096 * xdisp.c (display_mode_line): Reset row flags for truncation 9096 * xdisp.c (display_mode_line): Reset row flags for truncation
@@ -9129,8 +9129,8 @@
9129 face changes and changes in invisible text property. 9129 face changes and changes in invisible text property.
9130 (struct glyph_pos): Former ovlen now overlay_string_index. 9130 (struct glyph_pos): Former ovlen now overlay_string_index.
9131 9131
9132 * xdisp.c (setup_iterator_overlays_from_glyph_pos): Set 9132 * xdisp.c (setup_iterator_overlays_from_glyph_pos):
9133 overlay_string. 9133 Set overlay_string.
9134 (set_iterator_to_next_overlay_string): Set overlay_string and 9134 (set_iterator_to_next_overlay_string): Set overlay_string and
9135 pos.overlay_string_index. 9135 pos.overlay_string_index.
9136 (get_overlays_at_iterator_position): Use overlay_string and 9136 (get_overlays_at_iterator_position): Use overlay_string and
@@ -9167,7 +9167,7 @@
9167 * buffer.h (overlays_at): Function prototype. 9167 * buffer.h (overlays_at): Function prototype.
9168 9168
9169 * xdisp.c (reseat_iterator_to_string): Clear iterator position. 9169 * xdisp.c (reseat_iterator_to_string): Clear iterator position.
9170 * dispextern.h (GET_NEXT_DISPLAY_ELEMENT): Removed. 9170 * dispextern.h (GET_NEXT_DISPLAY_ELEMENT): Remove.
9171 9171
9172 * xdisp.c (release_iterator): Release dynamically allocated 9172 * xdisp.c (release_iterator): Release dynamically allocated
9173 memory of a display_iterator. 9173 memory of a display_iterator.
@@ -9187,23 +9187,23 @@
9187 * buffer.c (overlays_at): Make it work when extending vectors 9187 * buffer.c (overlays_at): Make it work when extending vectors
9188 and an initial vector of zero size. 9188 and an initial vector of zero size.
9189 9189
9190 * xdisp.c (set_iterator_to_previous_visible_line_end): Renamed 9190 * xdisp.c (set_iterator_to_previous_visible_line_end):
9191 from set_cursor_to_previous_visible_line_end. 9191 Rename from set_cursor_to_previous_visible_line_end.
9192 (set_iterator_to_next_visible_line_start): Renamed from 9192 (set_iterator_to_next_visible_line_start): Rename from
9193 set_cursor_to_next_visible_line_end. 9193 set_cursor_to_next_visible_line_end.
9194 (set_next_iterator_stop_pos): Renamed from set_next_stop_pos. 9194 (set_next_iterator_stop_pos): Rename from set_next_stop_pos.
9195 (compute_face_at_iterator_position): Renamed from 9195 (compute_face_at_iterator_position): Rename from
9196 compute_cursor_face. 9196 compute_cursor_face.
9197 (set_iterator_to_next_overlay_string): Renamed from 9197 (set_iterator_to_next_overlay_string): Rename from
9198 cursor_to_next_overlay_string. 9198 cursor_to_next_overlay_string.
9199 (get_overlays_at_iterator_position): Renamed from 9199 (get_overlays_at_iterator_position): Rename from
9200 get_overlays_for_cursor. 9200 get_overlays_for_cursor.
9201 (reseat_iterator): Renamed from reseat_cursor. 9201 (reseat_iterator): Rename from reseat_cursor.
9202 (setup_iterator_overlays_from_glyph_pos): Renamed from 9202 (setup_iterator_overlays_from_glyph_pos): Rename from
9203 setup_overlays_from_pos. 9203 setup_overlays_from_pos.
9204 (init_string_iterator): Renamed from init_string_cursor. 9204 (init_string_iterator): Rename from init_string_cursor.
9205 (get_next_display_element): Renamed from next_display_element. 9205 (get_next_display_element): Rename from next_display_element.
9206 (move_iterator_forward): Renamed from advance_display_cursor. 9206 (move_iterator_forward): Rename from advance_display_cursor.
9207 (get_overlays_at_iterator_position): Allocate overlays vector 9207 (get_overlays_at_iterator_position): Allocate overlays vector
9208 dynamically. 9208 dynamically.
9209 9209
@@ -9214,7 +9214,7 @@
92141997-12-01 Gerd Moellmann <gerd@acm.org> 92141997-12-01 Gerd Moellmann <gerd@acm.org>
9215 9215
9216 * window.c (mark_window_cursors_off): Function comment added. 9216 * window.c (mark_window_cursors_off): Function comment added.
9217 (window_topmost_p, window_rightmost_p): Removed because not used. 9217 (window_topmost_p, window_rightmost_p): Remove because not used.
9218 9218
92191997-11-30 Gerd Moellmann <gerd@acm.org> 92191997-11-30 Gerd Moellmann <gerd@acm.org>
9220 9220
@@ -9229,7 +9229,7 @@
9229 frame_title_buf. 9229 frame_title_buf.
9230 (init_xdisp): Initialize frame_title_.* variables to null. 9230 (init_xdisp): Initialize frame_title_.* variables to null.
9231 9231
9232 * dispnew.c (quit_error_check): Removed. 9232 * dispnew.c (quit_error_check): Remove.
9233 9233
9234 * eval.c (Fsignal): Call to quit_error_check removed. 9234 * eval.c (Fsignal): Call to quit_error_check removed.
9235 * keyboard.c (quit_throw_to_read_char): Ditto. 9235 * keyboard.c (quit_throw_to_read_char): Ditto.
@@ -9275,8 +9275,8 @@
9275 * xterm.c (XTupdate_window_end): Don't display cursor if 9275 * xterm.c (XTupdate_window_end): Don't display cursor if
9276 pseudo_window_p. 9276 pseudo_window_p.
9277 9277
9278 * dispnew.c (adjust_frame_glyphs_for_window_redisplay): Don't 9278 * dispnew.c (adjust_frame_glyphs_for_window_redisplay):
9279 set mini_p. 9279 Don't set mini_p.
9280 (update_window): Don't set cursor if pseudo_window_p. 9280 (update_window): Don't set cursor if pseudo_window_p.
9281 9281
9282 * dispextern.h (WINDOW_WANTS_MODELINE_P): Test pseudo_window_p. 9282 * dispextern.h (WINDOW_WANTS_MODELINE_P): Test pseudo_window_p.
@@ -9307,8 +9307,8 @@
9307 f->menu_bar_window if appropriate. 9307 f->menu_bar_window if appropriate.
9308 (display_mode_line): Use MATRIX_MODE_LINE_ROW. 9308 (display_mode_line): Use MATRIX_MODE_LINE_ROW.
9309 9309
9310 * dispnew.c (adjust_frame_glyphs_for_window_redisplay): Allocate 9310 * dispnew.c (adjust_frame_glyphs_for_window_redisplay):
9311 dummy window and window matrices for f->menu_bar_window. 9311 Allocate dummy window and window matrices for f->menu_bar_window.
9312 (free_glyphs): Free the dummy window and its glyph matrices. 9312 (free_glyphs): Free the dummy window and its glyph matrices.
9313 9313
9314 * frame.h (struct frame): New member menu_bar_window. 9314 * frame.h (struct frame): New member menu_bar_window.
@@ -9323,8 +9323,8 @@
9323 first_row_to_display. The previous scheme failed if the last row 9323 first_row_to_display. The previous scheme failed if the last row
9324 was fully visible. 9324 was fully visible.
9325 9325
9326 * dispnew.c (update_window): Remove cost calculations. Remove 9326 * dispnew.c (update_window): Remove cost calculations.
9327 redundant preempt_count calculations. 9327 Remove redundant preempt_count calculations.
9328 9328
9329 * xterm.c (x_clip_to_row): Set clipping for non-text rows 9329 * xterm.c (x_clip_to_row): Set clipping for non-text rows
9330 differently. 9330 differently.
@@ -9345,7 +9345,7 @@
9345 try_window_id. 9345 try_window_id.
9346 (try_window_reusing_current_matrix): Give up for terminal frames 9346 (try_window_reusing_current_matrix): Give up for terminal frames
9347 if window is not full width or we cannot insert/delete lines. 9347 if window is not full width or we cannot insert/delete lines.
9348 (try_window_reusing_current_matrix): Fixed scrolling for terminal 9348 (try_window_reusing_current_matrix): Fix scrolling for terminal
9349 frames. 9349 frames.
9350 9350
9351 * alloc.c (mark_glyph_matrix): Bug fix - pass pointer to 9351 * alloc.c (mark_glyph_matrix): Bug fix - pass pointer to
@@ -9407,8 +9407,8 @@
9407 (update_window_line): Set it. 9407 (update_window_line): Set it.
9408 (update_marginal_area): Clear to end of line if not in text area. 9408 (update_marginal_area): Clear to end of line if not in text area.
9409 9409
9410 * window.c (Fset_window_margins): Increment 9410 * window.c (Fset_window_margins):
9411 windows_or_buffer_changed. Adjust glyphs. 9411 Increment windows_or_buffer_changed. Adjust glyphs.
9412 9412
9413 * dispextern.h (WINDOW_TEXT_TO_FRAME_PIXEL_X): Convert text 9413 * dispextern.h (WINDOW_TEXT_TO_FRAME_PIXEL_X): Convert text
9414 area X coordinates to frame coordinates. 9414 area X coordinates to frame coordinates.
@@ -9496,8 +9496,8 @@
9496 9496
94971997-10-27 Gerd Moellmann <gerd@acm.org> 94971997-10-27 Gerd Moellmann <gerd@acm.org>
9498 9498
9499 * dispnew.c (update_window_line): Call 9499 * dispnew.c (update_window_line):
9500 after_update_window_line_hook only for interesting constellations. 9500 Call after_update_window_line_hook only for interesting constellations.
9501 (free_glyph_matrix): Fix memory leak. 9501 (free_glyph_matrix): Fix memory leak.
9502 9502
9503 * window.h: Include blocker WINDOW_H_INCLUDED, include 9503 * window.h: Include blocker WINDOW_H_INCLUDED, include
@@ -9507,7 +9507,7 @@
9507 (replace_window): Ditto. 9507 (replace_window): Ditto.
9508 * dispnew.c (free_window_matrices): Remove freeing of 9508 * dispnew.c (free_window_matrices): Remove freeing of
9509 phys_cursor_glyph. 9509 phys_cursor_glyph.
9510 (check_matrix_invariants): Renamed from check_current_matrix_... 9510 (check_matrix_invariants): Rename from check_current_matrix_...
9511 * xterm.c: All references to phys_cursor_glyph changed. 9511 * xterm.c: All references to phys_cursor_glyph changed.
9512 9512
9513 * dispextern.h (DISPEXTERN_H_INCLUDED): New include blocker. 9513 * dispextern.h (DISPEXTERN_H_INCLUDED): New include blocker.
@@ -9665,8 +9665,8 @@
9665 9665
9666 * dispextern.h (MATRIX_ROW_FIRST_POS): Use row start. 9666 * dispextern.h (MATRIX_ROW_FIRST_POS): Use row start.
9667 9667
9668 * dispnew.c (increment_glyph_row_buffer_positions): Adjust 9668 * dispnew.c (increment_glyph_row_buffer_positions):
9669 start and end positions in rows. 9669 Adjust start and end positions in rows.
9670 (increment_glyph_row_buffer_positions): Stop adjusting at 9670 (increment_glyph_row_buffer_positions): Stop adjusting at
9671 glyphs with positions <= 0. 9671 glyphs with positions <= 0.
9672 9672
@@ -9682,8 +9682,8 @@
9682 9682
96831997-10-21 Gerd Moellmann <gerd@acm.org> 96831997-10-21 Gerd Moellmann <gerd@acm.org>
9684 9684
9685 * dispnew.c (update_window): Add scrolling_window again. It's 9685 * dispnew.c (update_window): Add scrolling_window again.
9686 necessary for scroll_step != 0. 9686 It's necessary for scroll_step != 0.
9687 9687
9688 * xdisp.c (redisplay_window): Use vmotion for scroll_step 9688 * xdisp.c (redisplay_window): Use vmotion for scroll_step
9689 scrolling. 9689 scrolling.
@@ -9745,7 +9745,7 @@
97451997-10-19 Gerd Moellmann <gerd@acm.org> 97451997-10-19 Gerd Moellmann <gerd@acm.org>
9746 9746
9747 * dispnew.c (update_window): Remove unused variable. 9747 * dispnew.c (update_window): Remove unused variable.
9748 (update_window_line): Simplified. 9748 (update_window_line): Simplify.
9749 9749
9750 * xterm.c (x_get_char_font_and_encoding): Handle most common 9750 * xterm.c (x_get_char_font_and_encoding): Handle most common
9751 case at the beginning. 9751 case at the beginning.
@@ -9756,8 +9756,8 @@
9756 9756
9757 * xdisp.c (try_window_id): New implementation. 9757 * xdisp.c (try_window_id): New implementation.
9758 9758
9759 * dispnew.c (increment_glyph_row_buffer_positions): Capture 9759 * dispnew.c (increment_glyph_row_buffer_positions):
9760 rows displaying a line end, only. 9760 Capture rows displaying a line end, only.
9761 9761
97621997-10-18 Gerd Moellmann <gerd@acm.org> 97621997-10-18 Gerd Moellmann <gerd@acm.org>
9763 9763
@@ -9850,8 +9850,8 @@
9850 9850
9851 * term.c: Some hooks with function prototypes. 9851 * term.c: Some hooks with function prototypes.
9852 9852
9853 * xdisp.c (reseat_cursor): Additional argument force_p. Avoid 9853 * xdisp.c (reseat_cursor): Additional argument force_p.
9854 computing face if possible. 9854 Avoid computing face if possible.
9855 9855
9856 * xdisp.c (next_display_element): Use face from glyph from display 9856 * xdisp.c (next_display_element): Use face from glyph from display
9857 table only if != 0. 9857 table only if != 0.
@@ -9883,7 +9883,7 @@
9883 (init_display_info): Subtract vertical border glyph from 9883 (init_display_info): Subtract vertical border glyph from
9884 last_visible_x. 9884 last_visible_x.
9885 9885
9886 * scroll.c (scrolling_window_1): Removed. 9886 * scroll.c (scrolling_window_1): Remove.
9887 9887
9888 * dispnew.c (adjust_frame_glyphs): Split into two functions, 9888 * dispnew.c (adjust_frame_glyphs): Split into two functions,
9889 based on redisplay method used. 9889 based on redisplay method used.
@@ -9892,7 +9892,7 @@
9892 (adjust_frame_glyphs_for_window_redisplay): Part for purely 9892 (adjust_frame_glyphs_for_window_redisplay): Part for purely
9893 window based redisplay. 9893 window based redisplay.
9894 9894
9895 * frame.h (FRAME_WINDOW_REDISPLAY_P): Changed to not depend 9895 * frame.h (FRAME_WINDOW_REDISPLAY_P): Change to not depend
9896 on data structures. 9896 on data structures.
9897 9897
9898 * dispnew.c (adjust_glyph_matrix): Additional parameter W. 9898 * dispnew.c (adjust_glyph_matrix): Additional parameter W.
@@ -9904,8 +9904,8 @@
9904 * dispextern.h (struct glyph_matrix): window_top_y, 9904 * dispextern.h (struct glyph_matrix): window_top_y,
9905 window_height. 9905 window_height.
9906 9906
9907 * dispnew.c (allocate_matrices_for_window_redisplay): Detect 9907 * dispnew.c (allocate_matrices_for_window_redisplay):
9908 and optimize some common cases of window changes. 9908 Detect and optimize some common cases of window changes.
9909 9909
9910 * emacs.c (main): Remove own profiling code because 0.95 now 9910 * emacs.c (main): Remove own profiling code because 0.95 now
9911 has it in. 9911 has it in.
@@ -9965,9 +9965,9 @@
9965 * xterm.c (x_draw_row_borders): Use FRAME_MODE_LINE_HEIGHT height 9965 * xterm.c (x_draw_row_borders): Use FRAME_MODE_LINE_HEIGHT height
9966 value. 9966 value.
9967 (x_clip_to_row): Use MATRIX_ROW_VISIBLE_HEIGHT. Simplified. 9967 (x_clip_to_row): Use MATRIX_ROW_VISIBLE_HEIGHT. Simplified.
9968 (do_line_dance): Simplified and pixel corrected. 9968 (do_line_dance): Simplify and pixel corrected.
9969 9969
9970 * dispnew.c (scrolling_window): Simplified. 9970 * dispnew.c (scrolling_window): Simplify.
9971 9971
9972 * xterm.c (x_draw_3d_border): Insert rectangle by line width. 9972 * xterm.c (x_draw_3d_border): Insert rectangle by line width.
9973 9973
@@ -10049,15 +10049,15 @@
10049 10049
10050 * xterm.h (WINDOW_COL_PIXEL_X etc.) Removed. 10050 * xterm.h (WINDOW_COL_PIXEL_X etc.) Removed.
10051 10051
10052 * dispextern.h (WINDOW_TO_FRAME_HPOS/VPOS): Moved to dispnew.c. 10052 * dispextern.h (WINDOW_TO_FRAME_HPOS/VPOS): Move to dispnew.c.
10053 10053
10054 * xfns.c (x_contour_region): Use pixel coordinates from window 10054 * xfns.c (x_contour_region): Use pixel coordinates from window
10055 cursor instead of WINDOW_TO_FRAME_H/VPOS. 10055 cursor instead of WINDOW_TO_FRAME_H/VPOS.
10056 10056
10057 * dispextern.h (FRAME_TO_WINDOW_HPOS, FRAME_TO_WINDOW_VPOS): 10057 * dispextern.h (FRAME_TO_WINDOW_HPOS, FRAME_TO_WINDOW_VPOS):
10058 Removed. 10058 Remove.
10059 10059
10060 * dispnew.c (frame_to_window_hpos, frame_to_window_vpos): Removed. 10060 * dispnew.c (frame_to_window_hpos, frame_to_window_vpos): Remove.
10061 10061
10062 * xterm.c (x_y_to_hpos_vpos): Get hpos/vpos from window relative 10062 * xterm.c (x_y_to_hpos_vpos): Get hpos/vpos from window relative
10063 pixel coordinates. 10063 pixel coordinates.
@@ -10541,16 +10541,16 @@
10541 * xfns.c (Fx_create_frame): Don't set PHYS_CURSOR_X to -1. 10541 * xfns.c (Fx_create_frame): Don't set PHYS_CURSOR_X to -1.
10542 I don't believe this is really necessary. 10542 I don't believe this is really necessary.
10543 10543
10544 * dispnew.c (build_frame_matrix_from_leaf_window): Determine 10544 * dispnew.c (build_frame_matrix_from_leaf_window):
10545 border glyph once. 10545 Determine border glyph once.
10546 10546
105471997-07-15 Gerd Moellmann <gerd@acm.org> 105471997-07-15 Gerd Moellmann <gerd@acm.org>
10548 10548
10549 * window.c (mark_window_cursors_off): Mark all cursors in 10549 * window.c (mark_window_cursors_off): Mark all cursors in
10550 window tree off. 10550 window tree off.
10551 10551
10552 * xterm.c (x_display_box_cursor): Window parameter. Use 10552 * xterm.c (x_display_box_cursor): Window parameter.
10553 window matrix. 10553 Use window matrix.
10554 (glyph_to_pixel_pos): Convert matrix pos -> pixels. 10554 (glyph_to_pixel_pos): Convert matrix pos -> pixels.
10555 (pixel_to_glyph_pos): Convert pixel pos -> matrix pos. 10555 (pixel_to_glyph_pos): Convert pixel pos -> matrix pos.
10556 (x_update_cursor): Work on windows. 10556 (x_update_cursor): Work on windows.
@@ -10576,7 +10576,7 @@
10576 10576
10577 * frame.h (struct frame): Cursor information removed. 10577 * frame.h (struct frame): Cursor information removed.
10578 10578
10579 * frame.h (FRAME_SCROLL_BAR_WIDTH): Removed because unused. 10579 * frame.h (FRAME_SCROLL_BAR_WIDTH): Remove because unused.
10580 (FRAME_WINDOW_WIDTH_ARG): Don't add scroll bar width. 10580 (FRAME_WINDOW_WIDTH_ARG): Don't add scroll bar width.
10581 10581
10582 * window.h (WINDOW_LEFT_MARGIN): Remove FRAME_LEFT_SCROLL_BAR. 10582 * window.h (WINDOW_LEFT_MARGIN): Remove FRAME_LEFT_SCROLL_BAR.
@@ -10650,7 +10650,7 @@
10650 * window.h: CURSOR_VPOS/HPOS added. 10650 * window.h: CURSOR_VPOS/HPOS added.
10651 10651
10652 * frame.h (struct frame): CURSOR_X/Y removed. 10652 * frame.h (struct frame): CURSOR_X/Y removed.
10653 (FRAME_CURSOR_X): Removed. 10653 (FRAME_CURSOR_X): Remove.
10654 (FRAME_CURSOR_Y): Ditto. 10654 (FRAME_CURSOR_Y): Ditto.
10655 10655
10656 * dispnew.c (direct_output_for_insert): LAST_POINT_X removed. 10656 * dispnew.c (direct_output_for_insert): LAST_POINT_X removed.
@@ -10687,10 +10687,10 @@
10687 10687
10688 * minibuf.c (read_minibuf): Build frame matrix. 10688 * minibuf.c (read_minibuf): Build frame matrix.
10689 10689
10690 * xdisp.c (this_line_start_hpos): Renamed to 10690 * xdisp.c (this_line_start_hpos): Rename to
10691 THIS_LINE_START_WINDOW_HPOS to make it clear that this is window 10691 THIS_LINE_START_WINDOW_HPOS to make it clear that this is window
10692 relative. 10692 relative.
10693 (this_line_vpos): Renamed to THIS_LINE_WINDOW_VPOS for the same 10693 (this_line_vpos): Rename to THIS_LINE_WINDOW_VPOS for the same
10694 reason. 10694 reason.
10695 10695
10696 * dispnew.c (build_frame_matrix): Don't clear rows of the 10696 * dispnew.c (build_frame_matrix): Don't clear rows of the
@@ -10717,7 +10717,7 @@
10717 10717
10718 * lisp.h: Prototype for SCAN_BUFFER. 10718 * lisp.h: Prototype for SCAN_BUFFER.
10719 10719
10720 * xdisp.c (redisplay_windows): Simplified. 10720 * xdisp.c (redisplay_windows): Simplify.
10721 10721
10722 * dispnew.c (window_to_frame_vpos): Convert window to frame vpos 10722 * dispnew.c (window_to_frame_vpos): Convert window to frame vpos
10723 with debug checks. 10723 with debug checks.
@@ -10739,8 +10739,8 @@
10739 * xdisp.c (try_window_id): Use CANCEL_WINDOW_LINE. 10739 * xdisp.c (try_window_id): Use CANCEL_WINDOW_LINE.
10740 (redisplay_internal): Ditto. 10740 (redisplay_internal): Ditto.
10741 10741
10742 * dispnew.c (cancel_window_line): Use window matrix. Changed 10742 * dispnew.c (cancel_window_line): Use window matrix.
10743 name to CANCEL_WINDOW_LINE. 10743 Changed name to CANCEL_WINDOW_LINE.
10744 10744
10745 * xdisp.c (try_window_id): Use DISPLAY_TEXT_LINE with window 10745 * xdisp.c (try_window_id): Use DISPLAY_TEXT_LINE with window
10746 relative VPOS. 10746 relative VPOS.
@@ -10790,7 +10790,7 @@
10790 (allocate_leaf_matrix): Add FRAME_MENU_BAR_LINES to the height of 10790 (allocate_leaf_matrix): Add FRAME_MENU_BAR_LINES to the height of
10791 top-most windows. 10791 top-most windows.
10792 10792
10793 * window.h (WINDOW_TOPMOST_P): Added. 10793 * window.h (WINDOW_TOPMOST_P): Add.
10794 10794
10795 * xdisp.c (echo_area_display): Use PREPARE_DESIRED_ROW. 10795 * xdisp.c (echo_area_display): Use PREPARE_DESIRED_ROW.
10796 (redisplay_window): Ditto. 10796 (redisplay_window): Ditto.
@@ -10860,25 +10860,25 @@
10860 10860
10861 * dispnew.c (check_matrix_pointer_lossage): Check against 10861 * dispnew.c (check_matrix_pointer_lossage): Check against
10862 pointer lossage in matrices. 10862 pointer lossage in matrices.
10863 (get_glyph_matrix_row): Removed. 10863 (get_glyph_matrix_row): Remove.
10864 10864
10865 * scroll.c (do_scrolling): Simplified. 10865 * scroll.c (do_scrolling): Simplify.
10866 (do_direct_scrolling): Simplified. 10866 (do_direct_scrolling): Simplify.
10867 (scrolling_1): Pass CURRENT_MATRIX instead of FRAME to 10867 (scrolling_1): Pass CURRENT_MATRIX instead of FRAME to
10868 DO_.*SCROLLING. 10868 DO_.*SCROLLING.
10869 10869
10870 10870
10871 * dispnew.c (ins_del_glyph_rows): Insert/delete rows in a matrix. 10871 * dispnew.c (ins_del_glyph_rows): Insert/delete rows in a matrix.
10872 (rotate_vector): Removed. 10872 (rotate_vector): Remove.
10873 (rotate_pointers): Removed. 10873 (rotate_pointers): Remove.
10874 (scroll_frame_lines): Simplified. 10874 (scroll_frame_lines): Simplify.
10875 10875
108761997-07-03 Gerd Moellmann <gerd@acm.org> 108761997-07-03 Gerd Moellmann <gerd@acm.org>
10877 10877
10878 * dispextern.h (MATRIX_ROW_SWAP_CONTENTS): Removed. 10878 * dispextern.h (MATRIX_ROW_SWAP_CONTENTS): Remove.
10879 10879
10880 * dispnew.c (increment_glyph_matrix_buffer_positions): Does 10880 * dispnew.c (increment_glyph_matrix_buffer_positions):
10881 what the name says. 10881 Does what the name says.
10882 (clear_glyph_row): Make a glyph row structure empty. 10882 (clear_glyph_row): Make a glyph row structure empty.
10883 (make_matrix_row_current): Make a glyph row current. 10883 (make_matrix_row_current): Make a glyph row current.
10884 (make_window_matrix_row_current): Perform analogous row swaps 10884 (make_window_matrix_row_current): Perform analogous row swaps
@@ -10895,11 +10895,11 @@
10895 10895
10896 * All files: Use above new names. 10896 * All files: Use above new names.
10897 10897
10898 * dispnew.c (scroll_frame_lines): Simplified. Use 10898 * dispnew.c (scroll_frame_lines): Simplify.
10899 SCROLL_GLYPH_MATRIX. 10899 Use SCROLL_GLYPH_MATRIX.
10900 (make_glyph_row_empty): Mark a glyph row empty. 10900 (make_glyph_row_empty): Mark a glyph row empty.
10901 (increment_glyph_row_buffer_positions): Increment 10901 (increment_glyph_row_buffer_positions):
10902 buffer positions in a glyph row. 10902 Increment buffer positions in a glyph row.
10903 (increment_glyph_matrix_buffer_positions): Increment buffer 10903 (increment_glyph_matrix_buffer_positions): Increment buffer
10904 positions in a range of rows. 10904 positions in a range of rows.
10905 (scroll_glyph_matrix): Scroll a glyph matrix. 10905 (scroll_glyph_matrix): Scroll a glyph matrix.
@@ -10942,7 +10942,7 @@
10942 (MATRIX_ROW_USED): Ditto. 10942 (MATRIX_ROW_USED): Ditto.
10943 (MATRIX_ROW_SET_USED): Ditto. 10943 (MATRIX_ROW_SET_USED): Ditto.
10944 10944
10945 * dispnew.c (line_hash_code): Simplified. 10945 * dispnew.c (line_hash_code): Simplify.
10946 10946
109471997-06-30 Gerd Moellmann <gerd@acm.org> 109471997-06-30 Gerd Moellmann <gerd@acm.org>
10948 10948
@@ -10966,8 +10966,8 @@
10966 DO_PENDING_WINDOW_CHANGE, CHANGE_FRAME_SIZE, BITCH_AT_USER, 10966 DO_PENDING_WINDOW_CHANGE, CHANGE_FRAME_SIZE, BITCH_AT_USER,
10967 SIT_FOR, INIT_DISPLAY, SYMS_OF_DISPLAY, 10967 SIT_FOR, INIT_DISPLAY, SYMS_OF_DISPLAY,
10968 10968
10969 * dispnew.c (redraw_frame): FRAME_PTR -> struct frame. Return 10969 * dispnew.c (redraw_frame): FRAME_PTR -> struct frame.
10970 void. 10970 Return void.
10971 (cancel_line): Return void. 10971 (cancel_line): Return void.
10972 (clear_frame_records): Return void. 10972 (clear_frame_records): Return void.
10973 10973
@@ -11085,13 +11085,13 @@
11085 WRITE_GLYPHS_HOOK, DELETE_GLYPHS_HOOK, 11085 WRITE_GLYPHS_HOOK, DELETE_GLYPHS_HOOK,
11086 11086
11087 * xdisp.c (redisplay_internal): Remove call to VERIFY_CHARSTARTS. 11087 * xdisp.c (redisplay_internal): Remove call to VERIFY_CHARSTARTS.
11088 (do_verify_charstarts): Removed. 11088 (do_verify_charstarts): Remove.
11089 11089
11090 * frame.c (Fmake_terminal_frame): Adjust glyphs. 11090 * frame.c (Fmake_terminal_frame): Adjust glyphs.
11091 (Fdelete_frame): Free glyphs. 11091 (Fdelete_frame): Free glyphs.
11092 (make_frame): Initialize matrix fields in frame. 11092 (make_frame): Initialize matrix fields in frame.
11093 11093
11094 * config.in (PROTO): Added. 11094 * config.in (PROTO): Add.
11095 11095
11096 * emacs.c (shut_down_emacs): Check glyph memory. 11096 * emacs.c (shut_down_emacs): Check glyph memory.
11097 11097
@@ -11261,7 +11261,7 @@
11261 11261
11262 * emacs.c [DOUG_LEA_MALLOC] (malloc_initialize_hook): 11262 * emacs.c [DOUG_LEA_MALLOC] (malloc_initialize_hook):
11263 Move the handling of MALLOC_CHECK_ envvar here. 11263 Move the handling of MALLOC_CHECK_ envvar here.
11264 (main): Moved from here. 11264 (main): Move from here.
11265 11265
112661999-06-29 Wolfram Gloger <wmglo@dent.med.uni-muenchen.de> 112661999-06-29 Wolfram Gloger <wmglo@dent.med.uni-muenchen.de>
11267 11267
@@ -11414,8 +11414,8 @@
11414 11414
11415 * w32console.c (clear_frame): Remember that the window width might 11415 * w32console.c (clear_frame): Remember that the window width might
11416 be smaller than the screen buffer width. 11416 be smaller than the screen buffer width.
11417 (write_glyphs): Remove redundant variable attrs. Use 11417 (write_glyphs): Remove redundant variable attrs.
11418 FillConsoleOutputAttribute instead of WriteConsoleOutputAttribute. 11418 Use FillConsoleOutputAttribute instead of WriteConsoleOutputAttribute.
11419 11419
114201999-05-20 Andrew Innes <andrewi@gnu.org> 114201999-05-20 Andrew Innes <andrewi@gnu.org>
11421 11421
@@ -11423,8 +11423,8 @@
11423 loses focus. 11423 loses focus.
11424 11424
11425 * w32fns.c (w32_wnd_proc): Ensure mouse capture is released if 11425 * w32fns.c (w32_wnd_proc): Ensure mouse capture is released if
11426 frame loses focus, and that mouse button state is reset. Ditto 11426 frame loses focus, and that mouse button state is reset.
11427 when the menu bar is activated. 11427 Ditto when the menu bar is activated.
11428 11428
114291999-05-18 Richard Stallman <rms@gnu.org> 114291999-05-18 Richard Stallman <rms@gnu.org>
11430 11430
@@ -11599,7 +11599,7 @@
11599 (w32_clear_frame, clear_cursor, x_display_bar_cursor) 11599 (w32_clear_frame, clear_cursor, x_display_bar_cursor)
11600 (x_display_box_cursor, x_set_window_size): Use phys_cursor_on 11600 (x_display_box_cursor, x_set_window_size): Use phys_cursor_on
11601 field in frame. 11601 field in frame.
11602 (do_line_dance): Updated WRT xterm.c. Use macros where possible. 11602 (do_line_dance): Update WRT xterm.c. Use macros where possible.
11603 (dumprectangle): Take into account the width of a left-side 11603 (dumprectangle): Take into account the width of a left-side
11604 scroll bar. 11604 scroll bar.
11605 11605
@@ -11617,8 +11617,8 @@
11617 11617
116181999-05-02 Kenichi HANDA <handa@etl.go.jp> 116181999-05-02 Kenichi HANDA <handa@etl.go.jp>
11619 11619
11620 * coding.c (setup_raw_text_coding_system): Call 11620 * coding.c (setup_raw_text_coding_system):
11621 setup_coding_system to initialize the fields of struct 11621 Call setup_coding_system to initialize the fields of struct
11622 coding_system correctly. 11622 coding_system correctly.
11623 11623
116241999-04-26 Kenichi HANDA <handa@etl.go.jp> 116241999-04-26 Kenichi HANDA <handa@etl.go.jp>
@@ -11773,11 +11773,11 @@
117731999-03-25 Andrew Innes <andrewi@gnu.org> 117731999-03-25 Andrew Innes <andrewi@gnu.org>
11774 11774
11775 * makefile.nt (PREPARED_HEADERS): Change name of paths.h to epaths.h. 11775 * makefile.nt (PREPARED_HEADERS): Change name of paths.h to epaths.h.
11776 (epaths.h): Renamed from paths.h. 11776 (epaths.h): Rename from paths.h.
11777 (clean): 11777 (clean):
11778 ($(BLD)\filelock.obj): 11778 ($(BLD)\filelock.obj):
11779 ($(BLD)\lread.obj): 11779 ($(BLD)\lread.obj):
11780 ($(BLD)\w32fns.obj): Renamed paths.h to epaths.h. 11780 ($(BLD)\w32fns.obj): Rename paths.h to epaths.h.
11781 11781
117821999-03-23 Ken'ichi Handa <handa@gnu.org> 117821999-03-23 Ken'ichi Handa <handa@gnu.org>
11783 11783
@@ -11791,8 +11791,8 @@
11791 11791
117921999-03-20 Kenichi HANDA <handa@etl.go.jp> 117921999-03-20 Kenichi HANDA <handa@etl.go.jp>
11793 11793
11794 * coding.c (ENCODE_ISO_CHARACTER): Check validity of CHARSET. If 11794 * coding.c (ENCODE_ISO_CHARACTER): Check validity of CHARSET.
11795 invalid, produce the buffer internal byte sequence without encoding. 11795 If invalid, produce the buffer internal byte sequence without encoding.
11796 11796
117971999-03-19 Karl Heuer <kwzh@gnu.org> 117971999-03-19 Karl Heuer <kwzh@gnu.org>
11798 11798
@@ -11965,8 +11965,8 @@
119651999-02-24 Kenichi Handa <handa@etl.go.jp> 119651999-02-24 Kenichi Handa <handa@etl.go.jp>
11966 11966
11967 * keymap.c (push_key_description): If enable-multibyte-characters 11967 * keymap.c (push_key_description): If enable-multibyte-characters
11968 is non-nil, try to convert unibyte character to multibyte. For 11968 is non-nil, try to convert unibyte character to multibyte.
11969 invalid multibyte character, show all bits by octal form. 11969 For invalid multibyte character, show all bits by octal form.
11970 (Fsingle_key_description): Check the validity of charset for a 11970 (Fsingle_key_description): Check the validity of charset for a
11971 generic character. 11971 generic character.
11972 11972
@@ -12083,8 +12083,8 @@
12083 12083
120841999-02-15 Kenichi Handa <handa@etl.go.jp> 120841999-02-15 Kenichi Handa <handa@etl.go.jp>
12085 12085
12086 * coding.c (Fdecode_sjis_char, Fencode_sjis_char): Handle 12086 * coding.c (Fdecode_sjis_char, Fencode_sjis_char):
12087 ASCII correctly. Signal error on invalid characters. 12087 Handle ASCII correctly. Signal error on invalid characters.
12088 (Fdecode_big5_char, Fencode_big5_char): Likewise. 12088 (Fdecode_big5_char, Fencode_big5_char): Likewise.
12089 12089
120901999-02-15 Eli Zaretskii <eliz@gnu.org> 120901999-02-15 Eli Zaretskii <eliz@gnu.org>
@@ -12146,8 +12146,8 @@
12146 12146
121471999-02-04 Eli Zaretskii <eliz@gnu.org> 121471999-02-04 Eli Zaretskii <eliz@gnu.org>
12148 12148
12149 * w16select.c (last_clipboard_text, clipboard_storage_size): New 12149 * w16select.c (last_clipboard_text, clipboard_storage_size):
12150 static variables. 12150 New static variables.
12151 (set_clipboard_data): Save a copy of the text we put into 12151 (set_clipboard_data): Save a copy of the text we put into
12152 clipboard in last_clipboard_text. 12152 clipboard in last_clipboard_text.
12153 (get_clipboard_data): If the clipboard text is identical to what 12153 (get_clipboard_data): If the clipboard text is identical to what
@@ -12305,8 +12305,8 @@
12305 (x_destroy_bitmap): Returns void not int. 12305 (x_destroy_bitmap): Returns void not int.
12306 (x_set_border_pixel): Returns void. 12306 (x_set_border_pixel): Returns void.
12307 (w32_load_bdf_font): New function. 12307 (w32_load_bdf_font): New function.
12308 (w32_load_system_font): New function, was w32_load_font. List 12308 (w32_load_system_font): New function, was w32_load_font.
12309 fonts before loading. Explicitly set encoding for SJIS fonts. 12309 List fonts before loading. Explicitly set encoding for SJIS fonts.
12310 Set default_ascent to 0 as comment indicates. 12310 Set default_ascent to 0 as comment indicates.
12311 (w32_load_font): Call w32_load_system_font and w32_load_bdf_font. 12311 (w32_load_font): Call w32_load_system_font and w32_load_bdf_font.
12312 (w32_unload_font): Support BDF fonts. 12312 (w32_unload_font): Support BDF fonts.
@@ -12350,7 +12350,7 @@
12350 w32_codepage_for_charset. Add cast to int where float 12350 w32_codepage_for_charset. Add cast to int where float
12351 operation is assigned to int. 12351 operation is assigned to int.
12352 (Vw32_charset_to_codepage_alist): New variable. 12352 (Vw32_charset_to_codepage_alist): New variable.
12353 (w32_codepage_for_charset): Removed. 12353 (w32_codepage_for_charset): Remove.
12354 (w32_codepage_for_font): New function, replacing 12354 (w32_codepage_for_font): New function, replacing
12355 w32_codepage_for_charset. 12355 w32_codepage_for_charset.
12356 (syms_of_w32term): Add and initialize 12356 (syms_of_w32term): Add and initialize
@@ -12369,7 +12369,7 @@
12369 12369
12370 * w32heap.h (ROUND_UP): 12370 * w32heap.h (ROUND_UP):
12371 (ROUND_DOWN): New macros. 12371 (ROUND_DOWN): New macros.
12372 (need_to_recreate_heap): Renamed to using_dynamic_heap. 12372 (need_to_recreate_heap): Rename to using_dynamic_heap.
12373 (init_heap): New extern. 12373 (init_heap): New extern.
12374 (data_region_size): 12374 (data_region_size):
12375 (recreate_heap): 12375 (recreate_heap):
@@ -12384,11 +12384,11 @@
12384 (round_to_next): Obsolete function removed. 12384 (round_to_next): Obsolete function removed.
12385 (preload_heap_section): New variable. 12385 (preload_heap_section): New variable.
12386 (data_region_size): Obsolete variable removed. 12386 (data_region_size): Obsolete variable removed.
12387 (allocate_heap): Modified to determine end of static heap section 12387 (allocate_heap): Modify to determine end of static heap section
12388 used during preload, and use that as initial base address for 12388 used during preload, and use that as initial base address for
12389 dynamic heap instead of hard-coded value. 12389 dynamic heap instead of hard-coded value.
12390 (sbrk): Remove call to allocate_heap; handled by init_heap. Skip 12390 (sbrk): Remove call to allocate_heap; handled by init_heap.
12391 calls to commit or decommit pages when allocating from static heap 12391 Skip calls to commit or decommit pages when allocating from static heap
12392 section during preload. 12392 section during preload.
12393 (recreate_heap): Obsolete function removed. 12393 (recreate_heap): Obsolete function removed.
12394 (init_heap): New function to initialize internal sbrk heap 12394 (init_heap): New function to initialize internal sbrk heap
@@ -12399,10 +12399,10 @@
12399 * unexw32.c: Major rewrite to support cleaner method of dumping; a 12399 * unexw32.c: Major rewrite to support cleaner method of dumping; a
12400 static "bss" section is used for heap space during preload, and 12400 static "bss" section is used for heap space during preload, and
12401 bss data is now written to the proper section area when dumping. 12401 bss data is now written to the proper section area when dumping.
12402 (need_to_recreate_heap): Renamed to using_dynamic_heap. 12402 (need_to_recreate_heap): Rename to using_dynamic_heap.
12403 (heap_index_in_executable): Obsolete variable removed. 12403 (heap_index_in_executable): Obsolete variable removed.
12404 (data_section): New variable. 12404 (data_section): New variable.
12405 (data_start_va): Renamed to data_start. 12405 (data_start_va): Rename to data_start.
12406 (data_start_file): Obsolete variable removed. 12406 (data_start_file): Obsolete variable removed.
12407 (bss_section): 12407 (bss_section):
12408 (extra_bss_size): 12408 (extra_bss_size):
@@ -12432,8 +12432,8 @@
12432 sections where data will be dumped. Allows for static and global 12432 sections where data will be dumped. Allows for static and global
12433 bss data to be in separate ranges. No longer relies on knowledge 12433 bss data to be in separate ranges. No longer relies on knowledge
12434 of section names. 12434 of section names.
12435 (copy_executable_and_dump_data_section): Renamed 12435 (copy_executable_and_dump_data_section):
12436 copy_executable_and_dump_data. Completely rewritten to copy 12436 Rename copy_executable_and_dump_data. Completely rewritten to copy
12437 executable section by section, so that raw data areas can be 12437 executable section by section, so that raw data areas can be
12438 expanded to hold dumped data as necessary. Allows for bss data to 12438 expanded to hold dumped data as necessary. Allows for bss data to
12439 be in same section as initialized data. Reduces size of static 12439 be in same section as initialized data. Reduces size of static
@@ -12511,8 +12511,8 @@
12511 Return zero in case of success, 1 or 2 otherwise. 12511 Return zero in case of success, 1 or 2 otherwise.
12512 (get_clipboard_data): Only bail out if the null character is in 12512 (get_clipboard_data): Only bail out if the null character is in
12513 the last 32-byte chunk of clipboard data. 12513 the last 32-byte chunk of clipboard data.
12514 (Fw16_set_clipboard_data): Make ok and put_status be unsigned. If 12514 (Fw16_set_clipboard_data): Make ok and put_status be unsigned.
12515 they save binary data, print a message in the echo area saying the 12515 If they save binary data, print a message in the echo area saying the
12516 text was not put into the clipboard. 12516 text was not put into the clipboard.
12517 12517
12518 * msdos.c (IT_write_glyphs): Move constant expression out of the loop. 12518 * msdos.c (IT_write_glyphs): Move constant expression out of the loop.
@@ -12688,8 +12688,8 @@
12688 based on VEC. 12688 based on VEC.
12689 12689
12690 * charset.c (Qunknown): New variable. 12690 * charset.c (Qunknown): New variable.
12691 (init_charset_once): Intern and staticpro Qunknown. Initialize 12691 (init_charset_once): Intern and staticpro Qunknown.
12692 all elements of Vcharset_symbol_table to Qunknown. 12692 Initialize all elements of Vcharset_symbol_table to Qunknown.
12693 (find_charset_in_str): New arg MULTIBYTE. If it is zero, check 12693 (find_charset_in_str): New arg MULTIBYTE. If it is zero, check
12694 unibyte characters only. For an invalid composition sequence, set 12694 unibyte characters only. For an invalid composition sequence, set
12695 CHARSETS[1] to 1. 12695 CHARSETS[1] to 1.
@@ -12997,8 +12997,8 @@
12997 (RIGHT_WIN_PRESSED): 12997 (RIGHT_WIN_PRESSED):
12998 (APPS_PRESSED): New console keyboard modifier flags. 12998 (APPS_PRESSED): New console keyboard modifier flags.
12999 12999
13000 * w32term.c (convert_to_key_event): Removed. 13000 * w32term.c (convert_to_key_event): Remove.
13001 (is_dead_key): Copied to w32fns.c. 13001 (is_dead_key): Copy to w32fns.c.
13002 (w32_read_socket): Generate language_change_event. Modify to work 13002 (w32_read_socket): Generate language_change_event. Modify to work
13003 with keyboard handling changes in w32_wnd_proc. 13003 with keyboard handling changes in w32_wnd_proc.
13004 13004
@@ -13037,10 +13037,10 @@
13037 code. 13037 code.
13038 (is_dead_key): Copy from w32fns.c. 13038 (is_dead_key): Copy from w32fns.c.
13039 (w32_kbd_patch_key): Comment attempt to improve handling of 13039 (w32_kbd_patch_key): Comment attempt to improve handling of
13040 dead-keys, and system bug relating to same on Windows NT. Work 13040 dead-keys, and system bug relating to same on Windows NT.
13041 around the bug by calling ToUnicode and then converting to the 13041 Work around the bug by calling ToUnicode and then converting to the
13042 correct codepage. 13042 correct codepage.
13043 (map_virt_key): Removed obsolete variable. 13043 (map_virt_key): Remove obsolete variable.
13044 (lispy_function_keys): Add extern. 13044 (lispy_function_keys): Add extern.
13045 (key_event): Major rework of keyboard input handling: optionally 13045 (key_event): Major rework of keyboard input handling: optionally
13046 recognize Windows keys and Apps key as modifiers; optionally treat 13046 recognize Windows keys and Apps key as modifiers; optionally treat
@@ -13066,7 +13066,7 @@
13066 for given key. 13066 for given key.
13067 (w32_get_modifiers): Returns modifier flags for 13067 (w32_get_modifiers): Returns modifier flags for
13068 non-keyboard input events. 13068 non-keyboard input events.
13069 (construct_console_modifiers): Renamed from construct_modifiers; 13069 (construct_console_modifiers): Rename from construct_modifiers;
13070 recognize Windows and Apps keys as modifiers. 13070 recognize Windows and Apps keys as modifiers.
13071 (w32_get_key_modifiers): New function. Returns modifier flags for 13071 (w32_get_key_modifiers): New function. Returns modifier flags for
13072 keyboard input events. 13072 keyboard input events.
@@ -13098,12 +13098,12 @@
13098 13098
130991998-11-10 Kenichi Handa <handa@etl.go.jp> 130991998-11-10 Kenichi Handa <handa@etl.go.jp>
13100 13100
13101 * category.h (CATEGORY_SET): Adjusted for the change of 13101 * category.h (CATEGORY_SET): Adjust for the change of
13102 cmpchar_component. 13102 cmpchar_component.
13103 (CATEGORY_SET): Likewise. 13103 (CATEGORY_SET): Likewise.
13104 13104
13105 * charset.c (cmpchar_component): New arg NOERROR. Check 13105 * charset.c (cmpchar_component): New arg NOERROR.
13106 composition char ID more strictly. 13106 Check composition char ID more strictly.
13107 (Fcmpchar_component): Call cmpchar_component with NOERROR arg zero. 13107 (Fcmpchar_component): Call cmpchar_component with NOERROR arg zero.
13108 (Fcmpchar_cmp_rule): If CHARACTER should be composed relatively, 13108 (Fcmpchar_cmp_rule): If CHARACTER should be composed relatively,
13109 return 255. 13109 return 255.
@@ -13303,8 +13303,8 @@
13303 (insert_from_buffer_1): Likewise. 13303 (insert_from_buffer_1): Likewise.
13304 (adjust_after_replace): Inhibit bytes combined across region 13304 (adjust_after_replace): Inhibit bytes combined across region
13305 boundary. Update end_unchanged correctly. 13305 boundary. Update end_unchanged correctly.
13306 (replace_range): Call CHECK_BYTE_COMBINING_FOR_INSERT. Update 13306 (replace_range): Call CHECK_BYTE_COMBINING_FOR_INSERT.
13307 end_unchanged correctly. 13307 Update end_unchanged correctly.
13308 (del_range_2): Inhibit bytes combined across region boundary. 13308 (del_range_2): Inhibit bytes combined across region boundary.
13309 Update end_unchanged correctly. 13309 Update end_unchanged correctly.
13310 13310
@@ -13333,8 +13333,8 @@
13333 13333
133341998-10-27 Dave Love <fx@gnu.org> 133341998-10-27 Dave Love <fx@gnu.org>
13335 13335
13336 * fns.c (Fbase64_decode_region, Fbase64_encode_region): Fix 13336 * fns.c (Fbase64_decode_region, Fbase64_encode_region):
13337 newline in doc string. 13337 Fix newline in doc string.
13338 13338
133391998-10-27 Kenichi Handa <handa@etl.go.jp> 133391998-10-27 Kenichi Handa <handa@etl.go.jp>
13340 13340
@@ -13415,28 +13415,28 @@
13415 * w32fns.c (Vx_pixel_size_width): New global variable. 13415 * w32fns.c (Vx_pixel_size_width): New global variable.
13416 (unibyte_display_via_language_environment): New global variable. 13416 (unibyte_display_via_language_environment): New global variable.
13417 (x_set_font): Add support for setting fontsets. 13417 (x_set_font): Add support for setting fontsets.
13418 (Fx_create_frame): Add check_w32(). Initialize fontsets. Fix 13418 (Fx_create_frame): Add check_w32(). Initialize fontsets.
13419 font names to match xlfd-tight-regexp. 13419 Fix font names to match xlfd-tight-regexp.
13420 (w32_load_font): Rewrite based on x_load_font. 13420 (w32_load_font): Rewrite based on x_load_font.
13421 (x_to_w32_charset, w32_to_x_charset): Add character sets. Use 13421 (x_to_w32_charset, w32_to_x_charset): Add character sets.
13422 `iso8859-1' rather than `ansi'. 13422 Use `iso8859-1' rather than `ansi'.
13423 (w32_to_x_font): Remove `-' from font name. Remove the `-' off the 13423 (w32_to_x_font): Remove `-' from font name. Remove the `-' off the
13424 end. Move charset into `charset registry' field. 13424 end. Move charset into `charset registry' field.
13425 (enum_font_cb2): Check charsets match. Include width in font list. 13425 (enum_font_cb2): Check charsets match. Include width in font list.
13426 (w32_list_fonts): Rewrite based on x_list_fonts. 13426 (w32_list_fonts): Rewrite based on x_list_fonts.
13427 Moved from w32term.c to have access to enumfont_t struct. 13427 Moved from w32term.c to have access to enumfont_t struct.
13428 (Fx_list_fonts): w32 specific version eliminated. Include 13428 (Fx_list_fonts): w32 specific version eliminated.
13429 `x-list-fonts.c'. 13429 Include `x-list-fonts.c'.
13430 (w32_get_font_info, w32_query_font, w32_find_ccl_program): New 13430 (w32_get_font_info, w32_query_font, w32_find_ccl_program):
13431 functions for fontset support - adapted from x_ equivalents. 13431 New functions for fontset support - adapted from x_ equivalents.
13432 (syms_of_w32fns): New lisp variables initialized. Function 13432 (syms_of_w32fns): New lisp variables initialized.
13433 pointers for fontset.c set up. 13433 Function pointers for fontset.c set up.
13434 13434
13435 * w32term.c: Include fontset.h. Define codepage macros. 13435 * w32term.c: Include fontset.h. Define codepage macros.
13436 Add ENCODE_BIG5 macro from coding.c. 13436 Add ENCODE_BIG5 macro from coding.c.
13437 (w32_no_unicode_output): New variable. 13437 (w32_no_unicode_output): New variable.
13438 (w32_codepage_for_charset, w32_use_unicode_for_codepage): New 13438 (w32_codepage_for_charset, w32_use_unicode_for_codepage):
13439 functions. 13439 New functions.
13440 (BUILD_WCHAR_T, BYTE1, BYTE2): New macros. 13440 (BUILD_WCHAR_T, BYTE1, BYTE2): New macros.
13441 (dumpglyphs): Rewrite based on xterm.c equivalent. 13441 (dumpglyphs): Rewrite based on xterm.c equivalent.
13442 (x_new_font): Use functionality provided in fontset.c. 13442 (x_new_font): Use functionality provided in fontset.c.
@@ -13552,8 +13552,8 @@
13552 13552
13553 * lisp.h (clear_string_char_byte_cache): Extern it. 13553 * lisp.h (clear_string_char_byte_cache): Extern it.
13554 13554
13555 * xselect.c (lisp_data_to_selection_data): Call 13555 * xselect.c (lisp_data_to_selection_data):
13556 find_charset_in_str with CMPCHARP arg 0. 13556 Call find_charset_in_str with CMPCHARP arg 0.
13557 * w16select.c (Fw16_set_clipboard_data): Likewise. 13557 * w16select.c (Fw16_set_clipboard_data): Likewise.
13558 * w32select.c (Fw32_set_clipboard_data): Likewise. 13558 * w32select.c (Fw32_set_clipboard_data): Likewise.
13559 13559
@@ -13623,7 +13623,7 @@
13623 13623
13624 * coding.c (check_composing_code): Fix previous change. Now it 13624 * coding.c (check_composing_code): Fix previous change. Now it
13625 always returns 0 or -1. 13625 always returns 0 or -1.
13626 (decode_coding_iso2022): Adjusted for the above change. 13626 (decode_coding_iso2022): Adjust for the above change.
13627 (encode_coding_iso2022): When encoding the last block, flush out 13627 (encode_coding_iso2022): When encoding the last block, flush out
13628 tailing garbage bytes. 13628 tailing garbage bytes.
13629 (setup_coding_system): Delete unnecessary code. 13629 (setup_coding_system): Delete unnecessary code.
@@ -13700,8 +13700,8 @@
13700 13700
13701 * ccl.c (CCL_WRITE_CHAR): Don't use bcopy. 13701 * ccl.c (CCL_WRITE_CHAR): Don't use bcopy.
13702 (ccl_driver): If BUFFER-MAGNIFICATION of the CCL program is 0, 13702 (ccl_driver): If BUFFER-MAGNIFICATION of the CCL program is 0,
13703 cause error if the program is going to output some bytes. When 13703 cause error if the program is going to output some bytes.
13704 outputting a string to notify an error, check the case that 13704 When outputting a string to notify an error, check the case that
13705 DST_BYTES is zero. 13705 DST_BYTES is zero.
13706 13706
13707 * coding.h (CODING_FINISH_INTERRUPT): New macro. 13707 * coding.h (CODING_FINISH_INTERRUPT): New macro.
@@ -13838,8 +13838,8 @@
13838 * w16select.c (Vnext_selection_coding_system): New variable. 13838 * w16select.c (Vnext_selection_coding_system): New variable.
13839 (syms_of_win16select): DEFVAR_LISP it. No need to staticpro 13839 (syms_of_win16select): DEFVAR_LISP it. No need to staticpro
13840 Vselection_coding_system. 13840 Vselection_coding_system.
13841 (Fw16_set_clipboard_data): Always convert multibyte strings. Use 13841 (Fw16_set_clipboard_data): Always convert multibyte strings.
13842 Vnext_selection_coding_system if non-nil. 13842 Use Vnext_selection_coding_system if non-nil.
13843 (Fw16_get_clipboard_data): Always convert a string that includes 13843 (Fw16_get_clipboard_data): Always convert a string that includes
13844 non-ASCII characters. Use Vnext_selection_coding_system if 13844 non-ASCII characters. Use Vnext_selection_coding_system if
13845 non-nil. 13845 non-nil.
@@ -13911,8 +13911,8 @@
139111998-08-28 Kenichi Handa <handa@etl.go.jp> 139111998-08-28 Kenichi Handa <handa@etl.go.jp>
13912 13912
13913 * insdel.c (adjust_after_replace): Fix the code to record undo 13913 * insdel.c (adjust_after_replace): Fix the code to record undo
13914 information for the case that `before combining' happens. Remove 13914 information for the case that `before combining' happens.
13915 text properties which are added to the new text by 13915 Remove text properties which are added to the new text by
13916 offset_intervals. 13916 offset_intervals.
13917 13917
13918 * coding.c (code_convert_region1): Remove all text properties of 13918 * coding.c (code_convert_region1): Remove all text properties of
diff --git a/src/Makefile.in b/src/Makefile.in
index 0dc48868dd8..36e145744b3 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -250,7 +250,7 @@ MSDOS_OBJ =
250MSDOS_X_OBJ = 250MSDOS_X_OBJ =
251 251
252NS_OBJ=@NS_OBJ@ 252NS_OBJ=@NS_OBJ@
253## nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macfont.o if HAVE_NS. 253## nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o ns_fontfile if HAVE_NS.
254NS_OBJC_OBJ=@NS_OBJC_OBJ@ 254NS_OBJC_OBJ=@NS_OBJC_OBJ@
255## Only set if NS_IMPL_GNUSTEP. 255## Only set if NS_IMPL_GNUSTEP.
256GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@ 256GNU_OBJC_CFLAGS=@GNU_OBJC_CFLAGS@
@@ -297,13 +297,33 @@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
297 297
298RUN_TEMACS = ./temacs 298RUN_TEMACS = ./temacs
299 299
300## Static heap size for temacs on MinGW.
301EMACS_HEAPSIZE = @EMACS_HEAPSIZE@
302
303UNEXEC_OBJ = @UNEXEC_OBJ@ 300UNEXEC_OBJ = @UNEXEC_OBJ@
304 301
305CANNOT_DUMP=@CANNOT_DUMP@ 302CANNOT_DUMP=@CANNOT_DUMP@
306 303
304# 'make' verbosity.
305AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
306
307AM_V_CC = $(am__v_CC_@AM_V@)
308am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
309am__v_CC_0 = @echo " CC " $@;
310am__v_CC_1 =
311
312AM_V_CCLD = $(am__v_CCLD_@AM_V@)
313am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
314am__v_CCLD_0 = @echo " CCLD " $@;
315am__v_CCLD_1 =
316
317AM_V_GEN = $(am__v_GEN_@AM_V@)
318am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
319am__v_GEN_0 = @echo " GEN " $@;
320am__v_GEN_1 =
321
322AM_V_at = $(am__v_at_@AM_V@)
323am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
324am__v_at_0 = @
325am__v_at_1 =
326
307DEPDIR=deps 327DEPDIR=deps
308## -MMD -MF $(DEPDIR)/$*.d if AUTO_DEPEND; else empty. 328## -MMD -MF $(DEPDIR)/$*.d if AUTO_DEPEND; else empty.
309DEPFLAGS=@DEPFLAGS@ 329DEPFLAGS=@DEPFLAGS@
@@ -334,10 +354,10 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
334.SUFFIXES: .m 354.SUFFIXES: .m
335.c.o: 355.c.o:
336 @$(MKDEPDIR) 356 @$(MKDEPDIR)
337 $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) $< 357 $(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) $<
338.m.o: 358.m.o:
339 @$(MKDEPDIR) 359 @$(MKDEPDIR)
340 $(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $(PROFILING_CFLAGS) $< 360 $(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $(PROFILING_CFLAGS) $<
341 361
342## lastfile must follow all files whose initialized data areas should 362## lastfile must follow all files whose initialized data areas should
343## be dumped as pure by dump-emacs. 363## be dumped as pure by dump-emacs.
@@ -417,8 +437,12 @@ all: emacs$(EXEEXT) $(OTHER_FILES)
417$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT) 437$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
418 $(MAKE) -C ../leim leim-list.el EMACS="$(bootstrap_exe)" 438 $(MAKE) -C ../leim leim-list.el EMACS="$(bootstrap_exe)"
419 439
440## FORCE it so that admin/unidata can decide whether these files
441## are up-to-date. Although since charprop depends on bootstrap-emacs,
442## and emacs (which recreates bootstrap-emacs) depends on charprop,
443## in practice this rule was always run anyway.
420$(srcdir)/macuvs.h $(lispsource)/international/charprop.el: \ 444$(srcdir)/macuvs.h $(lispsource)/international/charprop.el: \
421 bootstrap-emacs$(EXEEXT) 445 bootstrap-emacs$(EXEEXT) FORCE
422 $(MAKE) -C ../admin/unidata all EMACS="../$(bootstrap_exe)" 446 $(MAKE) -C ../admin/unidata all EMACS="../$(bootstrap_exe)"
423 447
424## The dumped Emacs is as functional and more efficient than 448## The dumped Emacs is as functional and more efficient than
@@ -435,7 +459,9 @@ emacs$(EXEEXT): temacs$(EXEEXT) \
435 else \ 459 else \
436 LC_ALL=C $(RUN_TEMACS) -batch -l loadup dump || exit 1; \ 460 LC_ALL=C $(RUN_TEMACS) -batch -l loadup dump || exit 1; \
437 test "X$(PAXCTL)" = X || $(PAXCTL) -zex emacs$(EXEEXT); \ 461 test "X$(PAXCTL)" = X || $(PAXCTL) -zex emacs$(EXEEXT); \
438 rm -f bootstrap-emacs$(EXEEXT); \ 462 while test -f bootstrap-emacs$(EXEEXT); do \
463 rm -f bootstrap-emacs$(EXEEXT); \
464 done; \
439 ln emacs$(EXEEXT) bootstrap-emacs$(EXEEXT); \ 465 ln emacs$(EXEEXT) bootstrap-emacs$(EXEEXT); \
440 fi 466 fi
441 467
@@ -454,29 +480,32 @@ emacs$(EXEEXT): temacs$(EXEEXT) \
454## in the contents of the DOC file. 480## in the contents of the DOC file.
455## 481##
456$(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(obj) $(lisp) 482$(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(obj) $(lisp)
457 $(MKDIR_P) $(etc) 483 $(AM_V_GEN)$(MKDIR_P) $(etc)
458 -rm -f $(etc)/DOC 484 -$(AM_V_at)rm -f $(etc)/DOC
459 $(libsrc)/make-docfile -d $(srcdir) $(SOME_MACHINE_OBJECTS) $(obj) > $(etc)/DOC 485 $(AM_V_at)$(libsrc)/make-docfile -d $(srcdir) \
460 $(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) `sed -n -e 's| \\\\||' -e 's|^[ ]*$$(lispsource)/||p' $(srcdir)/lisp.mk` 486 $(SOME_MACHINE_OBJECTS) $(obj) > $(etc)/DOC
487 $(AM_V_at)$(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) \
488 `sed -n -e 's| \\\\||' -e 's|^[ ]*$$(lispsource)/||p' \
489 $(srcdir)/lisp.mk`
461 490
462$(libsrc)/make-docfile$(EXEEXT): 491$(libsrc)/make-docfile$(EXEEXT):
463 $(MAKE) -C $(libsrc) make-docfile$(EXEEXT) 492 $(MAKE) -C $(libsrc) make-docfile$(EXEEXT)
464 493
465buildobj.h: Makefile 494buildobj.h: Makefile
466 for i in $(ALLOBJS); do \ 495 $(AM_V_GEN)for i in $(ALLOBJS); do \
467 echo "$$i" | sed 's,.*/,,; s/\.obj$$/\.o/; s/^/"/; s/$$/",/' \ 496 echo "$$i" | sed 's,.*/,,; s/\.obj$$/\.o/; s/^/"/; s/$$/",/' \
468 || exit; \ 497 || exit; \
469 done >$@.tmp 498 done >$@.tmp
470 mv $@.tmp $@ 499 $(AM_V_at)mv $@.tmp $@
471 500
472globals.h: gl-stamp; @true 501globals.h: gl-stamp; @true
473 502
474GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m) 503GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m)
475 504
476gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES) 505gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES)
477 $(libsrc)/make-docfile -d $(srcdir) -g $(obj) > gl.tmp 506 $(AM_V_GEN)$(libsrc)/make-docfile -d $(srcdir) -g $(obj) > gl.tmp
478 $(top_srcdir)/build-aux/move-if-change gl.tmp globals.h 507 $(AM_V_at)$(top_srcdir)/build-aux/move-if-change gl.tmp globals.h
479 echo timestamp > $@ 508 $(AM_V_at)echo timestamp > $@
480 509
481$(ALLOBJS): globals.h 510$(ALLOBJS): globals.h
482 511
@@ -489,7 +518,7 @@ $(lib)/libgnu.a: $(config_h)
489## to start if Vinstallation_directory has the wrong value. 518## to start if Vinstallation_directory has the wrong value.
490temacs$(EXEEXT): $(LIBXMENU) $(ALLOBJS) \ 519temacs$(EXEEXT): $(LIBXMENU) $(ALLOBJS) \
491 $(lib)/libgnu.a $(EMACSRES) 520 $(lib)/libgnu.a $(EMACSRES)
492 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \ 521 $(AM_V_CCLD)$(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
493 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES) 522 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES)
494 $(MKDIR_P) $(etc) 523 $(MKDIR_P) $(etc)
495 test "$(CANNOT_DUMP)" = "yes" || \ 524 test "$(CANNOT_DUMP)" = "yes" || \
diff --git a/src/alloc.c b/src/alloc.c
index ac154b587e6..faad0b59c87 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -80,7 +80,7 @@ static bool valgrind_p;
80 marked objects. */ 80 marked objects. */
81 81
82#if (defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC \ 82#if (defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC \
83 || defined GC_CHECK_MARKED_OBJECTS) 83 || defined HYBRID_MALLOC || defined GC_CHECK_MARKED_OBJECTS)
84#undef GC_MALLOC_CHECK 84#undef GC_MALLOC_CHECK
85#endif 85#endif
86 86
@@ -285,7 +285,7 @@ static void gc_sweep (void);
285static Lisp_Object make_pure_vector (ptrdiff_t); 285static Lisp_Object make_pure_vector (ptrdiff_t);
286static void mark_buffer (struct buffer *); 286static void mark_buffer (struct buffer *);
287 287
288#if !defined REL_ALLOC || defined SYSTEM_MALLOC 288#if !defined REL_ALLOC || defined SYSTEM_MALLOC || defined HYBRID_MALLOC
289static void refill_memory_reserve (void); 289static void refill_memory_reserve (void);
290#endif 290#endif
291static void compact_small_strings (void); 291static void compact_small_strings (void);
@@ -453,7 +453,7 @@ mmap_lisp_allowed_p (void)
453 /* If we can't store all memory addresses in our lisp objects, it's 453 /* If we can't store all memory addresses in our lisp objects, it's
454 risky to let the heap use mmap and give us addresses from all 454 risky to let the heap use mmap and give us addresses from all
455 over our address space. We also can't use mmap for lisp objects 455 over our address space. We also can't use mmap for lisp objects
456 if we might dump: unexec doesn't preserve the contents of mmaped 456 if we might dump: unexec doesn't preserve the contents of mmapped
457 regions. */ 457 regions. */
458 return pointers_fit_in_lispobj_p () && !might_dump; 458 return pointers_fit_in_lispobj_p () && !might_dump;
459} 459}
@@ -1014,10 +1014,17 @@ lisp_free (void *block)
1014 clang 3.3 anyway. */ 1014 clang 3.3 anyway. */
1015 1015
1016#if ! ADDRESS_SANITIZER 1016#if ! ADDRESS_SANITIZER
1017# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC 1017# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
1018# define USE_ALIGNED_ALLOC 1 1018# define USE_ALIGNED_ALLOC 1
1019/* Defined in gmalloc.c. */ 1019/* Defined in gmalloc.c. */
1020void *aligned_alloc (size_t, size_t); 1020void *aligned_alloc (size_t, size_t);
1021# elif defined HYBRID_MALLOC
1022# if defined ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
1023# define USE_ALIGNED_ALLOC 1
1024# define aligned_alloc hybrid_aligned_alloc
1025/* Defined in gmalloc.c. */
1026void *aligned_alloc (size_t, size_t);
1027# endif
1021# elif defined HAVE_ALIGNED_ALLOC 1028# elif defined HAVE_ALIGNED_ALLOC
1022# define USE_ALIGNED_ALLOC 1 1029# define USE_ALIGNED_ALLOC 1
1023# elif defined HAVE_POSIX_MEMALIGN 1030# elif defined HAVE_POSIX_MEMALIGN
@@ -2219,7 +2226,6 @@ make_string (const char *contents, ptrdiff_t nbytes)
2219 return val; 2226 return val;
2220} 2227}
2221 2228
2222
2223/* Make an unibyte string from LENGTH bytes at CONTENTS. */ 2229/* Make an unibyte string from LENGTH bytes at CONTENTS. */
2224 2230
2225Lisp_Object 2231Lisp_Object
@@ -2611,29 +2617,28 @@ list5 (Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, Lisp_Object arg4, L
2611Lisp_Object 2617Lisp_Object
2612listn (enum constype type, ptrdiff_t count, Lisp_Object arg, ...) 2618listn (enum constype type, ptrdiff_t count, Lisp_Object arg, ...)
2613{ 2619{
2614 va_list ap; 2620 Lisp_Object (*cons) (Lisp_Object, Lisp_Object);
2615 ptrdiff_t i; 2621 switch (type)
2616 Lisp_Object val, *objp; 2622 {
2623 case CONSTYPE_PURE: cons = pure_cons; break;
2624 case CONSTYPE_HEAP: cons = Fcons; break;
2625 default: emacs_abort ();
2626 }
2617 2627
2618 /* Change to SAFE_ALLOCA if you hit this eassert. */ 2628 eassume (0 < count);
2619 eassert (count <= MAX_ALLOCA / word_size); 2629 Lisp_Object val = cons (arg, Qnil);
2630 Lisp_Object tail = val;
2620 2631
2621 objp = alloca (count * word_size); 2632 va_list ap;
2622 objp[0] = arg;
2623 va_start (ap, arg); 2633 va_start (ap, arg);
2624 for (i = 1; i < count; i++) 2634 for (ptrdiff_t i = 1; i < count; i++)
2625 objp[i] = va_arg (ap, Lisp_Object);
2626 va_end (ap);
2627
2628 for (val = Qnil, i = count - 1; i >= 0; i--)
2629 { 2635 {
2630 if (type == CONSTYPE_PURE) 2636 Lisp_Object elem = cons (va_arg (ap, Lisp_Object), Qnil);
2631 val = pure_cons (objp[i], val); 2637 XSETCDR (tail, elem);
2632 else if (type == CONSTYPE_HEAP) 2638 tail = elem;
2633 val = Fcons (objp[i], val);
2634 else
2635 emacs_abort ();
2636 } 2639 }
2640 va_end (ap);
2641
2637 return val; 2642 return val;
2638} 2643}
2639 2644
@@ -3282,7 +3287,6 @@ See also the function `vector'. */)
3282 return vector; 3287 return vector;
3283} 3288}
3284 3289
3285
3286DEFUN ("vector", Fvector, Svector, 0, MANY, 0, 3290DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
3287 doc: /* Return a newly created vector with specified arguments as elements. 3291 doc: /* Return a newly created vector with specified arguments as elements.
3288Any number of arguments, even zero arguments, are allowed. 3292Any number of arguments, even zero arguments, are allowed.
@@ -3829,7 +3833,7 @@ memory_full (size_t nbytes)
3829void 3833void
3830refill_memory_reserve (void) 3834refill_memory_reserve (void)
3831{ 3835{
3832#ifndef SYSTEM_MALLOC 3836#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
3833 if (spare_memory[0] == 0) 3837 if (spare_memory[0] == 0)
3834 spare_memory[0] = malloc (SPARE_MEMORY); 3838 spare_memory[0] = malloc (SPARE_MEMORY);
3835 if (spare_memory[1] == 0) 3839 if (spare_memory[1] == 0)
@@ -6011,8 +6015,9 @@ mark_overlay (struct Lisp_Overlay *ptr)
6011 for (; ptr && !ptr->gcmarkbit; ptr = ptr->next) 6015 for (; ptr && !ptr->gcmarkbit; ptr = ptr->next)
6012 { 6016 {
6013 ptr->gcmarkbit = 1; 6017 ptr->gcmarkbit = 1;
6014 mark_object (ptr->start); 6018 /* These two are always markers and can be marked fast. */
6015 mark_object (ptr->end); 6019 XMARKER (ptr->start)->gcmarkbit = 1;
6020 XMARKER (ptr->end)->gcmarkbit = 1;
6016 mark_object (ptr->plist); 6021 mark_object (ptr->plist);
6017 } 6022 }
6018} 6023}
@@ -7072,7 +7077,7 @@ detect_suspicious_free (void* ptr)
7072 7077
7073DEFUN ("suspicious-object", Fsuspicious_object, Ssuspicious_object, 1, 1, 0, 7078DEFUN ("suspicious-object", Fsuspicious_object, Ssuspicious_object, 1, 1, 0,
7074 doc: /* Return OBJ, maybe marking it for extra scrutiny. 7079 doc: /* Return OBJ, maybe marking it for extra scrutiny.
7075If Emacs is compiled with suspicous object checking, capture 7080If Emacs is compiled with suspicious object checking, capture
7076a stack trace when OBJ is freed in order to help track down 7081a stack trace when OBJ is freed in order to help track down
7077garbage collection bugs. Otherwise, do nothing and return OBJ. */) 7082garbage collection bugs. Otherwise, do nothing and return OBJ. */)
7078 (Lisp_Object obj) 7083 (Lisp_Object obj)
@@ -7100,8 +7105,48 @@ die (const char *msg, const char *file, int line)
7100 file, line, msg); 7105 file, line, msg);
7101 terminate_due_to_signal (SIGABRT, INT_MAX); 7106 terminate_due_to_signal (SIGABRT, INT_MAX);
7102} 7107}
7103#endif 7108
7104 7109#endif /* ENABLE_CHECKING */
7110
7111#if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS
7112
7113/* Debugging check whether STR is ASCII-only. */
7114
7115const char *
7116verify_ascii (const char *str)
7117{
7118 const unsigned char *ptr = (unsigned char *) str, *end = ptr + strlen (str);
7119 while (ptr < end)
7120 {
7121 int c = STRING_CHAR_ADVANCE (ptr);
7122 if (!ASCII_CHAR_P (c))
7123 emacs_abort ();
7124 }
7125 return str;
7126}
7127
7128/* Stress alloca with inconveniently sized requests and check
7129 whether all allocated areas may be used for Lisp_Object. */
7130
7131NO_INLINE static void
7132verify_alloca (void)
7133{
7134 int i;
7135 enum { ALLOCA_CHECK_MAX = 256 };
7136 /* Start from size of the smallest Lisp object. */
7137 for (i = sizeof (struct Lisp_Cons); i <= ALLOCA_CHECK_MAX; i++)
7138 {
7139 void *ptr = alloca (i);
7140 make_lisp_ptr (ptr, Lisp_Cons);
7141 }
7142}
7143
7144#else /* not ENABLE_CHECKING && USE_STACK_LISP_OBJECTS */
7145
7146#define verify_alloca() ((void) 0)
7147
7148#endif /* ENABLE_CHECKING && USE_STACK_LISP_OBJECTS */
7149
7105/* Initialization. */ 7150/* Initialization. */
7106 7151
7107void 7152void
@@ -7111,6 +7156,8 @@ init_alloc_once (void)
7111 purebeg = PUREBEG; 7156 purebeg = PUREBEG;
7112 pure_size = PURESIZE; 7157 pure_size = PURESIZE;
7113 7158
7159 verify_alloca ();
7160
7114#if GC_MARK_STACK || defined GC_MALLOC_CHECK 7161#if GC_MARK_STACK || defined GC_MALLOC_CHECK
7115 mem_init (); 7162 mem_init ();
7116 Vdead = make_pure_string ("DEAD", 4, 4, 0); 7163 Vdead = make_pure_string ("DEAD", 4, 4, 0);
diff --git a/src/buffer.c b/src/buffer.c
index d2c7729d1c2..80791a1fdb1 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1134,10 +1134,7 @@ BUFFER defaults to the current buffer.
1134Return nil if BUFFER has been killed. */) 1134Return nil if BUFFER has been killed. */)
1135 (register Lisp_Object buffer) 1135 (register Lisp_Object buffer)
1136{ 1136{
1137 if (NILP (buffer)) 1137 return BVAR (decode_buffer (buffer), name);
1138 return BVAR (current_buffer, name);
1139 CHECK_BUFFER (buffer);
1140 return BVAR (XBUFFER (buffer), name);
1141} 1138}
1142 1139
1143DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0, 1140DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
@@ -1145,10 +1142,7 @@ DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
1145No argument or nil as argument means use the current buffer. */) 1142No argument or nil as argument means use the current buffer. */)
1146 (register Lisp_Object buffer) 1143 (register Lisp_Object buffer)
1147{ 1144{
1148 if (NILP (buffer)) 1145 return BVAR (decode_buffer (buffer), filename);
1149 return BVAR (current_buffer, filename);
1150 CHECK_BUFFER (buffer);
1151 return BVAR (XBUFFER (buffer), filename);
1152} 1146}
1153 1147
1154DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer, 1148DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer,
@@ -1158,21 +1152,8 @@ If BUFFER is not indirect, return nil.
1158BUFFER defaults to the current buffer. */) 1152BUFFER defaults to the current buffer. */)
1159 (register Lisp_Object buffer) 1153 (register Lisp_Object buffer)
1160{ 1154{
1161 struct buffer *base; 1155 struct buffer *base = decode_buffer (buffer)->base_buffer;
1162 Lisp_Object base_buffer; 1156 return base ? (XSETBUFFER (buffer, base), buffer) : Qnil;
1163
1164 if (NILP (buffer))
1165 base = current_buffer->base_buffer;
1166 else
1167 {
1168 CHECK_BUFFER (buffer);
1169 base = XBUFFER (buffer)->base_buffer;
1170 }
1171
1172 if (! base)
1173 return Qnil;
1174 XSETBUFFER (base_buffer, base);
1175 return base_buffer;
1176} 1157}
1177 1158
1178DEFUN ("buffer-local-value", Fbuffer_local_value, 1159DEFUN ("buffer-local-value", Fbuffer_local_value,
@@ -1295,20 +1276,10 @@ Most elements look like (SYMBOL . VALUE), describing one variable.
1295For a symbol that is locally unbound, just the symbol appears in the value. 1276For a symbol that is locally unbound, just the symbol appears in the value.
1296Note that storing new VALUEs in these elements doesn't change the variables. 1277Note that storing new VALUEs in these elements doesn't change the variables.
1297No argument or nil as argument means use current buffer as BUFFER. */) 1278No argument or nil as argument means use current buffer as BUFFER. */)
1298 (register Lisp_Object buffer) 1279 (Lisp_Object buffer)
1299{ 1280{
1300 register struct buffer *buf; 1281 struct buffer *buf = decode_buffer (buffer);
1301 register Lisp_Object result; 1282 Lisp_Object result = buffer_lisp_local_variables (buf, 0);
1302
1303 if (NILP (buffer))
1304 buf = current_buffer;
1305 else
1306 {
1307 CHECK_BUFFER (buffer);
1308 buf = XBUFFER (buffer);
1309 }
1310
1311 result = buffer_lisp_local_variables (buf, 0);
1312 1283
1313 /* Add on all the variables stored in special slots. */ 1284 /* Add on all the variables stored in special slots. */
1314 { 1285 {
@@ -1335,17 +1306,9 @@ DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
1335 0, 1, 0, 1306 0, 1, 0,
1336 doc: /* Return t if BUFFER was modified since its file was last read or saved. 1307 doc: /* Return t if BUFFER was modified since its file was last read or saved.
1337No argument or nil as argument means use current buffer as BUFFER. */) 1308No argument or nil as argument means use current buffer as BUFFER. */)
1338 (register Lisp_Object buffer) 1309 (Lisp_Object buffer)
1339{ 1310{
1340 register struct buffer *buf; 1311 struct buffer *buf = decode_buffer (buffer);
1341 if (NILP (buffer))
1342 buf = current_buffer;
1343 else
1344 {
1345 CHECK_BUFFER (buffer);
1346 buf = XBUFFER (buffer);
1347 }
1348
1349 return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil; 1312 return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil;
1350} 1313}
1351 1314
@@ -1451,16 +1414,7 @@ text in that buffer is changed. It wraps around occasionally.
1451No argument or nil as argument means use current buffer as BUFFER. */) 1414No argument or nil as argument means use current buffer as BUFFER. */)
1452 (register Lisp_Object buffer) 1415 (register Lisp_Object buffer)
1453{ 1416{
1454 register struct buffer *buf; 1417 return make_number (BUF_MODIFF (decode_buffer (buffer)));
1455 if (NILP (buffer))
1456 buf = current_buffer;
1457 else
1458 {
1459 CHECK_BUFFER (buffer);
1460 buf = XBUFFER (buffer);
1461 }
1462
1463 return make_number (BUF_MODIFF (buf));
1464} 1418}
1465 1419
1466DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick, 1420DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick,
@@ -1475,16 +1429,7 @@ between these calls. No argument or nil as argument means use current
1475buffer as BUFFER. */) 1429buffer as BUFFER. */)
1476 (register Lisp_Object buffer) 1430 (register Lisp_Object buffer)
1477{ 1431{
1478 register struct buffer *buf; 1432 return make_number (BUF_CHARS_MODIFF (decode_buffer (buffer)));
1479 if (NILP (buffer))
1480 buf = current_buffer;
1481 else
1482 {
1483 CHECK_BUFFER (buffer);
1484 buf = XBUFFER (buffer);
1485 }
1486
1487 return make_number (BUF_CHARS_MODIFF (buf));
1488} 1433}
1489 1434
1490DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2, 1435DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
@@ -1564,7 +1509,7 @@ frame's buffer list.
1564The buffer is found by scanning the selected or specified frame's buffer 1509The buffer is found by scanning the selected or specified frame's buffer
1565list first, followed by the list of all buffers. If no other buffer 1510list first, followed by the list of all buffers. If no other buffer
1566exists, return the buffer `*scratch*' (creating it if necessary). */) 1511exists, return the buffer `*scratch*' (creating it if necessary). */)
1567 (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame) 1512 (Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
1568{ 1513{
1569 struct frame *f = decode_any_frame (frame); 1514 struct frame *f = decode_any_frame (frame);
1570 Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate; 1515 Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate;
@@ -1607,10 +1552,11 @@ exists, return the buffer `*scratch*' (creating it if necessary). */)
1607 return notsogood; 1552 return notsogood;
1608 else 1553 else
1609 { 1554 {
1610 buf = Fget_buffer (build_string ("*scratch*")); 1555 AUTO_STRING (scratch, "*scratch*");
1556 buf = Fget_buffer (scratch);
1611 if (NILP (buf)) 1557 if (NILP (buf))
1612 { 1558 {
1613 buf = Fget_buffer_create (build_string ("*scratch*")); 1559 buf = Fget_buffer_create (scratch);
1614 Fset_buffer_major_mode (buf); 1560 Fset_buffer_major_mode (buf);
1615 } 1561 }
1616 return buf; 1562 return buf;
@@ -1630,10 +1576,11 @@ other_buffer_safely (Lisp_Object buffer)
1630 if (candidate_buffer (buf, buffer)) 1576 if (candidate_buffer (buf, buffer))
1631 return buf; 1577 return buf;
1632 1578
1633 buf = Fget_buffer (build_string ("*scratch*")); 1579 AUTO_STRING (scratch, "*scratch*");
1580 buf = Fget_buffer (scratch);
1634 if (NILP (buf)) 1581 if (NILP (buf))
1635 { 1582 {
1636 buf = Fget_buffer_create (build_string ("*scratch*")); 1583 buf = Fget_buffer_create (scratch);
1637 Fset_buffer_major_mode (buf); 1584 Fset_buffer_major_mode (buf);
1638 } 1585 }
1639 1586
@@ -3108,13 +3055,15 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
3108 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay)); 3055 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
3109 ptrdiff_t n, i, size; 3056 ptrdiff_t n, i, size;
3110 Lisp_Object *v, tem; 3057 Lisp_Object *v, tem;
3058 Lisp_Object vbuf[10];
3059 USE_SAFE_ALLOCA;
3111 3060
3112 size = 10; 3061 size = ARRAYELTS (vbuf);
3113 v = alloca (size * sizeof *v); 3062 v = vbuf;
3114 n = overlays_in (start, end, 0, &v, &size, NULL, NULL); 3063 n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
3115 if (n > size) 3064 if (n > size)
3116 { 3065 {
3117 v = alloca (n * sizeof *v); 3066 SAFE_NALLOCA (v, 1, n);
3118 overlays_in (start, end, 0, &v, &n, NULL, NULL); 3067 overlays_in (start, end, 0, &v, &n, NULL, NULL);
3119 } 3068 }
3120 3069
@@ -3124,6 +3073,7 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
3124 !NILP (tem))) 3073 !NILP (tem)))
3125 break; 3074 break;
3126 3075
3076 SAFE_FREE ();
3127 return i < n; 3077 return i < n;
3128} 3078}
3129 3079
@@ -4137,17 +4087,7 @@ BUFFER omitted or nil means delete all overlays of the current
4137buffer. */) 4087buffer. */)
4138 (Lisp_Object buffer) 4088 (Lisp_Object buffer)
4139{ 4089{
4140 register struct buffer *buf; 4090 delete_all_overlays (decode_buffer (buffer));
4141
4142 if (NILP (buffer))
4143 buf = current_buffer;
4144 else
4145 {
4146 CHECK_BUFFER (buffer);
4147 buf = XBUFFER (buffer);
4148 }
4149
4150 delete_all_overlays (buf);
4151 return Qnil; 4091 return Qnil;
4152} 4092}
4153 4093
@@ -4582,13 +4522,13 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4582 First copy the vector contents, in case some of these hooks 4522 First copy the vector contents, in case some of these hooks
4583 do subsequent modification of the buffer. */ 4523 do subsequent modification of the buffer. */
4584 ptrdiff_t size = last_overlay_modification_hooks_used; 4524 ptrdiff_t size = last_overlay_modification_hooks_used;
4585 Lisp_Object *copy = alloca (size * sizeof *copy); 4525 Lisp_Object *copy;
4586 ptrdiff_t i; 4526 ptrdiff_t i;
4587 4527
4528 USE_SAFE_ALLOCA;
4529 SAFE_ALLOCA_LISP (copy, size);
4588 memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents, 4530 memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
4589 size * word_size); 4531 size * word_size);
4590 gcpro1.var = copy;
4591 gcpro1.nvars = size;
4592 4532
4593 for (i = 0; i < size;) 4533 for (i = 0; i < size;)
4594 { 4534 {
@@ -4597,6 +4537,8 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4597 overlay_i = copy[i++]; 4537 overlay_i = copy[i++];
4598 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3); 4538 call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
4599 } 4539 }
4540
4541 SAFE_FREE ();
4600 } 4542 }
4601 UNGCPRO; 4543 UNGCPRO;
4602} 4544}
@@ -5346,10 +5288,11 @@ init_buffer (int initialized)
5346 } 5288 }
5347#else /* not USE_MMAP_FOR_BUFFERS */ 5289#else /* not USE_MMAP_FOR_BUFFERS */
5348 /* Avoid compiler warnings. */ 5290 /* Avoid compiler warnings. */
5349 initialized = initialized; 5291 (void) initialized;
5350#endif /* USE_MMAP_FOR_BUFFERS */ 5292#endif /* USE_MMAP_FOR_BUFFERS */
5351 5293
5352 Fset_buffer (Fget_buffer_create (build_string ("*scratch*"))); 5294 AUTO_STRING (scratch, "*scratch*");
5295 Fset_buffer (Fget_buffer_create (scratch));
5353 if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) 5296 if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
5354 Fset_buffer_multibyte (Qnil); 5297 Fset_buffer_multibyte (Qnil);
5355 5298
@@ -5386,9 +5329,12 @@ init_buffer (int initialized)
5386 However, it is not necessary to turn / into /:/. 5329 However, it is not necessary to turn / into /:/.
5387 So avoid doing that. */ 5330 So avoid doing that. */
5388 && strcmp ("/", SSDATA (BVAR (current_buffer, directory)))) 5331 && strcmp ("/", SSDATA (BVAR (current_buffer, directory))))
5389 bset_directory 5332 {
5390 (current_buffer, 5333 AUTO_STRING (slash_colon, "/:");
5391 concat2 (build_string ("/:"), BVAR (current_buffer, directory))); 5334 bset_directory (current_buffer,
5335 concat2 (slash_colon,
5336 BVAR (current_buffer, directory)));
5337 }
5392 5338
5393 temp = get_minibuffer (0); 5339 temp = get_minibuffer (0);
5394 bset_directory (XBUFFER (temp), BVAR (current_buffer, directory)); 5340 bset_directory (XBUFFER (temp), BVAR (current_buffer, directory));
@@ -5451,6 +5397,7 @@ syms_of_buffer (void)
5451 staticpro (&Qpermanent_local); 5397 staticpro (&Qpermanent_local);
5452 staticpro (&Qkill_buffer_hook); 5398 staticpro (&Qkill_buffer_hook);
5453 5399
5400 DEFSYM (Qchoice, "choice");
5454 DEFSYM (Qleft, "left"); 5401 DEFSYM (Qleft, "left");
5455 DEFSYM (Qright, "right"); 5402 DEFSYM (Qright, "right");
5456 DEFSYM (Qrange, "range"); 5403 DEFSYM (Qrange, "range");
@@ -5978,13 +5925,13 @@ in a window. To make the change take effect, call `set-window-buffer'. */);
5978 5925
5979 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width), 5926 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
5980 Qintegerp, 5927 Qintegerp,
5981 doc: /* Width of this buffer's scroll bars in pixels. 5928 doc: /* Width of this buffer's vertical scroll bars in pixels.
5982A value of nil means to use the scroll bar width from the window's frame. */); 5929A value of nil means to use the scroll bar width from the window's frame. */);
5983 5930
5984 DEFVAR_PER_BUFFER ("scroll-bar-height", &BVAR (current_buffer, scroll_bar_height), 5931 DEFVAR_PER_BUFFER ("scroll-bar-height", &BVAR (current_buffer, scroll_bar_height),
5985 Qintegerp, 5932 Qintegerp,
5986 doc: /* Height of this buffer's scroll bars in pixels. 5933 doc: /* Height of this buffer's horizontal scroll bars in pixels.
5987A value of nil means to use the scroll bar heiht from the window's frame. */); 5934A value of nil means to use the scroll bar height from the window's frame. */);
5988 5935
5989 DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type), 5936 DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type),
5990 Qvertical_scroll_bar, 5937 Qvertical_scroll_bar,
@@ -6003,7 +5950,7 @@ The value takes effect whenever you tell a window to display this buffer;
6003for instance, with `set-window-buffer' or when `display-buffer' displays it. 5950for instance, with `set-window-buffer' or when `display-buffer' displays it.
6004 5951
6005A value of `bottom' means put the horizontal scroll bar at the bottom of 5952A value of `bottom' means put the horizontal scroll bar at the bottom of
6006the window; a value of nil means don't show any horizonal scroll bars. 5953the window; a value of nil means don't show any horizontal scroll bars.
6007A value of t (the default) means do whatever the window's frame 5954A value of t (the default) means do whatever the window's frame
6008specifies. */); 5955specifies. */);
6009 5956
diff --git a/src/buffer.h b/src/buffer.h
index fd989925976..284cfa7b4a8 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1088,6 +1088,14 @@ extern void mmap_set_vars (bool);
1088extern void restore_buffer (Lisp_Object); 1088extern void restore_buffer (Lisp_Object);
1089extern void set_buffer_if_live (Lisp_Object); 1089extern void set_buffer_if_live (Lisp_Object);
1090 1090
1091/* Return B as a struct buffer pointer, defaulting to the current buffer. */
1092
1093INLINE struct buffer *
1094decode_buffer (Lisp_Object b)
1095{
1096 return NILP (b) ? current_buffer : (CHECK_BUFFER (b), XBUFFER (b));
1097}
1098
1091/* Set the current buffer to B. 1099/* Set the current buffer to B.
1092 1100
1093 We previously set windows_or_buffers_changed here to invalidate 1101 We previously set windows_or_buffers_changed here to invalidate
@@ -1120,15 +1128,15 @@ record_unwind_current_buffer (void)
1120#define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq) \ 1128#define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq) \
1121 do { \ 1129 do { \
1122 ptrdiff_t maxlen = 40; \ 1130 ptrdiff_t maxlen = 40; \
1123 overlays = alloca (maxlen * sizeof *overlays); \ 1131 SAFE_NALLOCA (overlays, 1, maxlen); \
1124 noverlays = overlays_at (posn, false, &overlays, &maxlen, \ 1132 (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \
1125 nextp, NULL, chrq); \ 1133 nextp, NULL, chrq); \
1126 if (noverlays > maxlen) \ 1134 if ((noverlays) > maxlen) \
1127 { \ 1135 { \
1128 maxlen = noverlays; \ 1136 maxlen = noverlays; \
1129 overlays = alloca (maxlen * sizeof *overlays); \ 1137 SAFE_NALLOCA (overlays, 1, maxlen); \
1130 noverlays = overlays_at (posn, false, &overlays, &maxlen, \ 1138 (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \
1131 nextp, NULL, chrq); \ 1139 nextp, NULL, chrq); \
1132 } \ 1140 } \
1133 } while (false) 1141 } while (false)
1134 1142
diff --git a/src/bytecode.c b/src/bytecode.c
index ca6681f21e9..d3c8b470cc3 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -36,8 +36,10 @@ by Hallvard:
36#include <config.h> 36#include <config.h>
37 37
38#include "lisp.h" 38#include "lisp.h"
39#include "blockinput.h"
39#include "character.h" 40#include "character.h"
40#include "buffer.h" 41#include "buffer.h"
42#include "keyboard.h"
41#include "syntax.h" 43#include "syntax.h"
42#include "window.h" 44#include "window.h"
43 45
@@ -1106,9 +1108,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1106 goto pushhandler; 1108 goto pushhandler;
1107 CASE (Bpushconditioncase): /* New in 24.4. */ 1109 CASE (Bpushconditioncase): /* New in 24.4. */
1108 { 1110 {
1109 extern EMACS_INT lisp_eval_depth;
1110 extern int poll_suppress_count;
1111 extern int interrupt_input_blocked;
1112 struct handler *c; 1111 struct handler *c;
1113 Lisp_Object tag; 1112 Lisp_Object tag;
1114 int dest; 1113 int dest;
diff --git a/src/callint.c b/src/callint.c
index 817f84d897b..9a4573c77be 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -297,6 +297,7 @@ invoke it. If KEYS is omitted or nil, the return value of
297 Lisp_Object teml; 297 Lisp_Object teml;
298 Lisp_Object up_event; 298 Lisp_Object up_event;
299 Lisp_Object enable; 299 Lisp_Object enable;
300 USE_SAFE_ALLOCA;
300 ptrdiff_t speccount = SPECPDL_INDEX (); 301 ptrdiff_t speccount = SPECPDL_INDEX ();
301 302
302 /* The index of the next element of this_command_keys to examine for 303 /* The index of the next element of this_command_keys to examine for
@@ -366,12 +367,8 @@ invoke it. If KEYS is omitted or nil, the return value of
366 wrong_type_argument (Qcommandp, function); 367 wrong_type_argument (Qcommandp, function);
367 } 368 }
368 369
369 /* If SPECS is set to a string, use it as an interactive prompt. */ 370 /* If SPECS is not a string, invent one. */
370 if (STRINGP (specs)) 371 if (! STRINGP (specs))
371 /* Make a copy of string so that if a GC relocates specs,
372 `string' will still be valid. */
373 string = xlispstrdupa (specs);
374 else
375 { 372 {
376 Lisp_Object input; 373 Lisp_Object input;
377 Lisp_Object funval = Findirect_function (function, Qt); 374 Lisp_Object funval = Findirect_function (function, Qt);
@@ -416,10 +413,16 @@ invoke it. If KEYS is omitted or nil, the return value of
416 args[0] = Qfuncall_interactively; 413 args[0] = Qfuncall_interactively;
417 args[1] = function; 414 args[1] = function;
418 args[2] = specs; 415 args[2] = specs;
419 return unbind_to (speccount, Fapply (3, args)); 416 Lisp_Object result = unbind_to (speccount, Fapply (3, args));
417 SAFE_FREE ();
418 return result;
420 } 419 }
421 } 420 }
422 421
422 /* SPECS is set to a string; use it as an interactive prompt.
423 Copy it so that STRING will be valid even if a GC relocates SPECS. */
424 SAFE_ALLOCA_STRING (string, specs);
425
423 /* Here if function specifies a string to control parsing the defaults. */ 426 /* Here if function specifies a string to control parsing the defaults. */
424 427
425 /* Set next_event to point to the first event with parameters. */ 428 /* Set next_event to point to the first event with parameters. */
@@ -507,14 +510,15 @@ invoke it. If KEYS is omitted or nil, the return value of
507 break; 510 break;
508 } 511 }
509 512
510 if (min (MOST_POSITIVE_FIXNUM, 513 if (MOST_POSITIVE_FIXNUM < min (PTRDIFF_MAX, SIZE_MAX) / word_size
511 min (PTRDIFF_MAX, SIZE_MAX) / word_size) 514 && MOST_POSITIVE_FIXNUM < nargs)
512 < nargs)
513 memory_full (SIZE_MAX); 515 memory_full (SIZE_MAX);
514 516
515 args = alloca (nargs * sizeof *args); 517 /* Allocate them all at one go. This wastes a bit of memory, but
516 visargs = alloca (nargs * sizeof *visargs); 518 it's OK to trade space for speed. */
517 varies = alloca (nargs * sizeof *varies); 519 SAFE_NALLOCA (args, 3, nargs);
520 visargs = args + nargs;
521 varies = (signed char *) (visargs + nargs);
518 522
519 for (i = 0; i < nargs; i++) 523 for (i = 0; i < nargs; i++)
520 { 524 {
@@ -871,7 +875,9 @@ invoke it. If KEYS is omitted or nil, the return value of
871 { 875 {
872 Lisp_Object val = Ffuncall (nargs, args); 876 Lisp_Object val = Ffuncall (nargs, args);
873 UNGCPRO; 877 UNGCPRO;
874 return unbind_to (speccount, val); 878 val = unbind_to (speccount, val);
879 SAFE_FREE ();
880 return val;
875 } 881 }
876} 882}
877 883
diff --git a/src/callproc.c b/src/callproc.c
index 2f68ea6f328..e3dcc7bbcca 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -129,7 +129,7 @@ encode_current_directory (void)
129 129
130 if (STRING_MULTIBYTE (dir)) 130 if (STRING_MULTIBYTE (dir))
131 dir = ENCODE_FILE (dir); 131 dir = ENCODE_FILE (dir);
132 if (! file_accessible_directory_p (SSDATA (dir))) 132 if (! file_accessible_directory_p (dir))
133 report_file_error ("Setting current directory", 133 report_file_error ("Setting current directory",
134 BVAR (current_buffer, directory)); 134 BVAR (current_buffer, directory));
135 135
@@ -466,7 +466,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
466 && SREF (path, 1) == ':') 466 && SREF (path, 1) == ':')
467 path = Fsubstring (path, make_number (2), Qnil); 467 path = Fsubstring (path, make_number (2), Qnil);
468 468
469 new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); 469 SAFE_NALLOCA (new_argv, 1, nargs < 4 ? 2 : nargs - 2);
470 470
471 { 471 {
472 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 472 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
@@ -632,6 +632,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
632 int volatile fd_error_volatile = fd_error; 632 int volatile fd_error_volatile = fd_error;
633 int volatile filefd_volatile = filefd; 633 int volatile filefd_volatile = filefd;
634 ptrdiff_t volatile count_volatile = count; 634 ptrdiff_t volatile count_volatile = count;
635 ptrdiff_t volatile sa_avail_volatile = sa_avail;
635 ptrdiff_t volatile sa_count_volatile = sa_count; 636 ptrdiff_t volatile sa_count_volatile = sa_count;
636 char **volatile new_argv_volatile = new_argv; 637 char **volatile new_argv_volatile = new_argv;
637 int volatile callproc_fd_volatile[CALLPROC_FDS]; 638 int volatile callproc_fd_volatile[CALLPROC_FDS];
@@ -648,6 +649,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
648 fd_error = fd_error_volatile; 649 fd_error = fd_error_volatile;
649 filefd = filefd_volatile; 650 filefd = filefd_volatile;
650 count = count_volatile; 651 count = count_volatile;
652 sa_avail = sa_avail_volatile;
651 sa_count = sa_count_volatile; 653 sa_count = sa_count_volatile;
652 new_argv = new_argv_volatile; 654 new_argv = new_argv_volatile;
653 655
@@ -1151,6 +1153,39 @@ add_env (char **env, char **new_env, char *string)
1151 return new_env; 1153 return new_env;
1152} 1154}
1153 1155
1156#ifndef DOS_NT
1157
1158/* 'exec' failed inside a child running NAME, with error number ERR.
1159 Possibly a vforked child needed to allocate a large vector on the
1160 stack; such a child cannot fall back on malloc because that might
1161 mess up the allocator's data structures in the parent.
1162 Report the error and exit the child. */
1163
1164static _Noreturn void
1165exec_failed (char const *name, int err)
1166{
1167 /* Avoid deadlock if the child's perror writes to a full pipe; the
1168 pipe's reader is the parent, but with vfork the parent can't
1169 run until the child exits. Truncate the diagnostic instead. */
1170 fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK);
1171
1172 errno = err;
1173 emacs_perror (name);
1174 _exit (err == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1175}
1176
1177#else
1178
1179/* Do nothing. There is no need to fail, as DOS_NT platforms do not
1180 fork and exec, and handle alloca exhaustion in a different way. */
1181
1182static void
1183exec_failed (char const *name, int err)
1184{
1185}
1186
1187#endif
1188
1154/* This is the last thing run in a newly forked inferior 1189/* This is the last thing run in a newly forked inferior
1155 either synchronous or asynchronous. 1190 either synchronous or asynchronous.
1156 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2. 1191 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
@@ -1174,8 +1209,6 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1174 int cpid; 1209 int cpid;
1175 HANDLE handles[3]; 1210 HANDLE handles[3];
1176#else 1211#else
1177 int exec_errno;
1178
1179 pid_t pid = getpid (); 1212 pid_t pid = getpid ();
1180#endif /* WINDOWSNT */ 1213#endif /* WINDOWSNT */
1181 1214
@@ -1196,11 +1229,13 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1196 on that. */ 1229 on that. */
1197 pwd_var = xmalloc (i + 5); 1230 pwd_var = xmalloc (i + 5);
1198#else 1231#else
1232 if (MAX_ALLOCA - 5 < i)
1233 exec_failed (new_argv[0], ENOMEM);
1199 pwd_var = alloca (i + 5); 1234 pwd_var = alloca (i + 5);
1200#endif 1235#endif
1201 temp = pwd_var + 4; 1236 temp = pwd_var + 4;
1202 memcpy (pwd_var, "PWD=", 4); 1237 memcpy (pwd_var, "PWD=", 4);
1203 strcpy (temp, SSDATA (current_dir)); 1238 lispstpcpy (temp, current_dir);
1204 1239
1205#ifndef DOS_NT 1240#ifndef DOS_NT
1206 /* We can't signal an Elisp error here; we're in a vfork. Since 1241 /* We can't signal an Elisp error here; we're in a vfork. Since
@@ -1262,6 +1297,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1262 } 1297 }
1263 1298
1264 /* new_length + 2 to include PWD and terminating 0. */ 1299 /* new_length + 2 to include PWD and terminating 0. */
1300 if (MAX_ALLOCA / sizeof *env - 2 < new_length)
1301 exec_failed (new_argv[0], ENOMEM);
1265 env = new_env = alloca ((new_length + 2) * sizeof *env); 1302 env = new_env = alloca ((new_length + 2) * sizeof *env);
1266 /* If we have a PWD envvar, pass one down, 1303 /* If we have a PWD envvar, pass one down,
1267 but with corrected value. */ 1304 but with corrected value. */
@@ -1270,7 +1307,11 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1270 1307
1271 if (STRINGP (display)) 1308 if (STRINGP (display))
1272 { 1309 {
1273 char *vdata = alloca (sizeof "DISPLAY=" + SBYTES (display)); 1310 char *vdata;
1311
1312 if (MAX_ALLOCA - sizeof "DISPLAY=" < SBYTES (display))
1313 exec_failed (new_argv[0], ENOMEM);
1314 vdata = alloca (sizeof "DISPLAY=" + SBYTES (display));
1274 strcpy (vdata, "DISPLAY="); 1315 strcpy (vdata, "DISPLAY=");
1275 strcat (vdata, SSDATA (display)); 1316 strcat (vdata, SSDATA (display));
1276 new_env = add_env (env, new_env, vdata); 1317 new_env = add_env (env, new_env, vdata);
@@ -1345,16 +1386,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1345 tcsetpgrp (0, pid); 1386 tcsetpgrp (0, pid);
1346 1387
1347 execve (new_argv[0], new_argv, env); 1388 execve (new_argv[0], new_argv, env);
1348 exec_errno = errno; 1389 exec_failed (new_argv[0], errno);
1349
1350 /* Avoid deadlock if the child's perror writes to a full pipe; the
1351 pipe's reader is the parent, but with vfork the parent can't
1352 run until the child exits. Truncate the diagnostic instead. */
1353 fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK);
1354
1355 errno = exec_errno;
1356 emacs_perror (new_argv[0]);
1357 _exit (exec_errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1358 1390
1359#else /* MSDOS */ 1391#else /* MSDOS */
1360 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); 1392 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
@@ -1488,14 +1520,14 @@ If optional parameter ENV is a list, then search this list instead of
1488} 1520}
1489 1521
1490/* A version of getenv that consults the Lisp environment lists, 1522/* A version of getenv that consults the Lisp environment lists,
1491 easily callable from C. */ 1523 easily callable from C. This is usually called from egetenv. */
1492char * 1524char *
1493egetenv (const char *var) 1525egetenv_internal (const char *var, ptrdiff_t len)
1494{ 1526{
1495 char *value; 1527 char *value;
1496 ptrdiff_t valuelen; 1528 ptrdiff_t valuelen;
1497 1529
1498 if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil)) 1530 if (getenv_internal (var, len, &value, &valuelen, Qnil))
1499 return value; 1531 return value;
1500 else 1532 else
1501 return 0; 1533 return 0;
@@ -1543,20 +1575,13 @@ init_callproc_1 (void)
1543void 1575void
1544init_callproc (void) 1576init_callproc (void)
1545{ 1577{
1546 char *data_dir = egetenv ("EMACSDATA"); 1578 bool data_dir = egetenv ("EMACSDATA") != 0;
1547 1579
1548 register char * sh; 1580 char *sh;
1549 Lisp_Object tempdir; 1581 Lisp_Object tempdir;
1550#ifdef HAVE_NS 1582#ifdef HAVE_NS
1551 if (data_dir == 0) 1583 if (data_dir == 0)
1552 { 1584 data_dir = ns_etc_directory () != 0;
1553 const char *etc_dir = ns_etc_directory ();
1554 if (etc_dir)
1555 {
1556 data_dir = alloca (strlen (etc_dir) + 1);
1557 strcpy (data_dir, etc_dir);
1558 }
1559 }
1560#endif 1585#endif
1561 1586
1562 if (!NILP (Vinstallation_directory)) 1587 if (!NILP (Vinstallation_directory))
@@ -1625,12 +1650,12 @@ init_callproc (void)
1625#endif 1650#endif
1626 { 1651 {
1627 tempdir = Fdirectory_file_name (Vexec_directory); 1652 tempdir = Fdirectory_file_name (Vexec_directory);
1628 if (! file_accessible_directory_p (SSDATA (tempdir))) 1653 if (! file_accessible_directory_p (tempdir))
1629 dir_warning ("arch-dependent data dir", Vexec_directory); 1654 dir_warning ("arch-dependent data dir", Vexec_directory);
1630 } 1655 }
1631 1656
1632 tempdir = Fdirectory_file_name (Vdata_directory); 1657 tempdir = Fdirectory_file_name (Vdata_directory);
1633 if (! file_accessible_directory_p (SSDATA (tempdir))) 1658 if (! file_accessible_directory_p (tempdir))
1634 dir_warning ("arch-independent data dir", Vdata_directory); 1659 dir_warning ("arch-independent data dir", Vdata_directory);
1635 1660
1636 sh = getenv ("SHELL"); 1661 sh = getenv ("SHELL");
diff --git a/src/category.c b/src/category.c
index 851ae1a4c24..a4610e4d358 100644
--- a/src/category.c
+++ b/src/category.c
@@ -96,7 +96,7 @@ those categories. */)
96 (Lisp_Object categories) 96 (Lisp_Object categories)
97{ 97{
98 Lisp_Object val; 98 Lisp_Object val;
99 int len; 99 ptrdiff_t len;
100 100
101 CHECK_STRING (categories); 101 CHECK_STRING (categories);
102 val = MAKE_CATEGORY_SET; 102 val = MAKE_CATEGORY_SET;
diff --git a/src/character.h b/src/character.h
index 66cd4e47ef8..624f4fff3f0 100644
--- a/src/character.h
+++ b/src/character.h
@@ -644,8 +644,6 @@ extern int string_char (const unsigned char *,
644 const unsigned char **, int *); 644 const unsigned char **, int *);
645 645
646extern int translate_char (Lisp_Object, int c); 646extern int translate_char (Lisp_Object, int c);
647extern void parse_str_as_multibyte (const unsigned char *,
648 ptrdiff_t, ptrdiff_t *, ptrdiff_t *);
649extern ptrdiff_t count_size_as_multibyte (const unsigned char *, ptrdiff_t); 647extern ptrdiff_t count_size_as_multibyte (const unsigned char *, ptrdiff_t);
650extern ptrdiff_t str_as_multibyte (unsigned char *, ptrdiff_t, ptrdiff_t, 648extern ptrdiff_t str_as_multibyte (unsigned char *, ptrdiff_t, ptrdiff_t,
651 ptrdiff_t *); 649 ptrdiff_t *);
diff --git a/src/charset.c b/src/charset.c
index 341ac356aff..171a00f23d1 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -485,14 +485,12 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
485 unsigned max_code = CHARSET_MAX_CODE (charset); 485 unsigned max_code = CHARSET_MAX_CODE (charset);
486 int fd; 486 int fd;
487 FILE *fp; 487 FILE *fp;
488 Lisp_Object suffixes;
489 struct charset_map_entries *head, *entries; 488 struct charset_map_entries *head, *entries;
490 int n_entries; 489 int n_entries;
491 ptrdiff_t count; 490 AUTO_STRING (map, ".map");
492 491 AUTO_STRING (txt, ".txt");
493 suffixes = list2 (build_string (".map"), build_string (".TXT")); 492 AUTO_LIST2 (suffixes, map, txt);
494 493 ptrdiff_t count = SPECPDL_INDEX ();
495 count = SPECPDL_INDEX ();
496 record_unwind_protect_nothing (); 494 record_unwind_protect_nothing ();
497 specbind (Qfile_name_handler_alist, Qnil); 495 specbind (Qfile_name_handler_alist, Qnil);
498 fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil, false); 496 fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil, false);
@@ -667,12 +665,8 @@ map_charset_for_dump (void (*c_function) (Lisp_Object, Lisp_Object),
667{ 665{
668 int from_idx = CODE_POINT_TO_INDEX (temp_charset_work->current, from); 666 int from_idx = CODE_POINT_TO_INDEX (temp_charset_work->current, from);
669 int to_idx = CODE_POINT_TO_INDEX (temp_charset_work->current, to); 667 int to_idx = CODE_POINT_TO_INDEX (temp_charset_work->current, to);
670 Lisp_Object range; 668 Lisp_Object range = Fcons (Qnil, Qnil);
671 int c, stop; 669 int c, stop;
672 struct gcpro gcpro1;
673
674 range = Fcons (Qnil, Qnil);
675 GCPRO1 (range);
676 670
677 c = temp_charset_work->min_char; 671 c = temp_charset_work->min_char;
678 stop = (temp_charset_work->max_char < 0x20000 672 stop = (temp_charset_work->max_char < 0x20000
@@ -715,7 +709,6 @@ map_charset_for_dump (void (*c_function) (Lisp_Object, Lisp_Object),
715 } 709 }
716 c++; 710 c++;
717 } 711 }
718 UNGCPRO;
719} 712}
720 713
721void 714void
@@ -1400,6 +1393,32 @@ Optional third argument DEUNIFY, if non-nil, means to de-unify CHARSET. */)
1400 return Qnil; 1393 return Qnil;
1401} 1394}
1402 1395
1396/* Check that DIMENSION, CHARS, and FINAL_CHAR specify a valid ISO charset.
1397 Return true if it's a 96-character set, false if 94. */
1398
1399static bool
1400check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars,
1401 Lisp_Object final_char)
1402{
1403 CHECK_NUMBER (dimension);
1404 CHECK_NUMBER (chars);
1405 CHECK_CHARACTER (final_char);
1406
1407 if (! (1 <= XINT (dimension) && XINT (dimension) <= 3))
1408 error ("Invalid DIMENSION %"pI"d, it should be 1, 2, or 3",
1409 XINT (dimension));
1410
1411 bool chars_flag = XINT (chars) == 96;
1412 if (! (chars_flag || XINT (chars) == 94))
1413 error ("Invalid CHARS %"pI"d, it should be 94 or 96", XINT (chars));
1414
1415 int final_ch = XFASTINT (final_char);
1416 if (! ('0' <= final_ch && final_ch <= '~'))
1417 error ("Invalid FINAL-CHAR '%c', it should be '0'..'~'", final_ch);
1418
1419 return chars_flag;
1420}
1421
1403DEFUN ("get-unused-iso-final-char", Fget_unused_iso_final_char, 1422DEFUN ("get-unused-iso-final-char", Fget_unused_iso_final_char,
1404 Sget_unused_iso_final_char, 2, 2, 0, 1423 Sget_unused_iso_final_char, 2, 2, 0,
1405 doc: /* 1424 doc: /*
@@ -1412,35 +1431,12 @@ If there's no unused final char for the specified kind of charset,
1412return nil. */) 1431return nil. */)
1413 (Lisp_Object dimension, Lisp_Object chars) 1432 (Lisp_Object dimension, Lisp_Object chars)
1414{ 1433{
1415 int final_char; 1434 bool chars_flag = check_iso_charset_parameter (dimension, chars,
1416 1435 make_number ('0'));
1417 CHECK_NUMBER (dimension); 1436 for (int final_char = '0'; final_char <= '?'; final_char++)
1418 CHECK_NUMBER (chars); 1437 if (ISO_CHARSET_TABLE (XINT (dimension), chars_flag, final_char) < 0)
1419 if (XINT (dimension) != 1 && XINT (dimension) != 2 && XINT (dimension) != 3) 1438 return make_number (final_char);
1420 args_out_of_range_3 (dimension, make_number (1), make_number (3)); 1439 return Qnil;
1421 if (XINT (chars) != 94 && XINT (chars) != 96)
1422 args_out_of_range_3 (chars, make_number (94), make_number (96));
1423 for (final_char = '0'; final_char <= '?'; final_char++)
1424 if (ISO_CHARSET_TABLE (XINT (dimension), XINT (chars), final_char) < 0)
1425 break;
1426 return (final_char <= '?' ? make_number (final_char) : Qnil);
1427}
1428
1429static void
1430check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char)
1431{
1432 CHECK_NATNUM (dimension);
1433 CHECK_NATNUM (chars);
1434 CHECK_CHARACTER (final_char);
1435
1436 if (XINT (dimension) > 3)
1437 error ("Invalid DIMENSION %"pI"d, it should be 1, 2, or 3",
1438 XINT (dimension));
1439 if (XINT (chars) != 94 && XINT (chars) != 96)
1440 error ("Invalid CHARS %"pI"d, it should be 94 or 96", XINT (chars));
1441 if (XINT (final_char) < '0' || XINT (final_char) > '~')
1442 error ("Invalid FINAL-CHAR %c, it should be `0'..`~'",
1443 (int)XINT (final_char));
1444} 1440}
1445 1441
1446 1442
@@ -1454,12 +1450,10 @@ if CHARSET is designated instead. */)
1454 (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char, Lisp_Object charset) 1450 (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char, Lisp_Object charset)
1455{ 1451{
1456 int id; 1452 int id;
1457 bool chars_flag;
1458 1453
1459 CHECK_CHARSET_GET_ID (charset, id); 1454 CHECK_CHARSET_GET_ID (charset, id);
1460 check_iso_charset_parameter (dimension, chars, final_char); 1455 bool chars_flag = check_iso_charset_parameter (dimension, chars, final_char);
1461 chars_flag = XINT (chars) == 96; 1456 ISO_CHARSET_TABLE (XINT (dimension), chars_flag, XFASTINT (final_char)) = id;
1462 ISO_CHARSET_TABLE (XINT (dimension), chars_flag, XINT (final_char)) = id;
1463 return Qnil; 1457 return Qnil;
1464} 1458}
1465 1459
@@ -2113,13 +2107,9 @@ See the documentation of the function `charset-info' for the meanings of
2113DIMENSION, CHARS, and FINAL-CHAR. */) 2107DIMENSION, CHARS, and FINAL-CHAR. */)
2114 (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char) 2108 (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char)
2115{ 2109{
2116 int id; 2110 bool chars_flag = check_iso_charset_parameter (dimension, chars, final_char);
2117 bool chars_flag; 2111 int id = ISO_CHARSET_TABLE (XINT (dimension), chars_flag,
2118 2112 XFASTINT (final_char));
2119 check_iso_charset_parameter (dimension, chars, final_char);
2120 chars_flag = XFASTINT (chars) == 96;
2121 id = ISO_CHARSET_TABLE (XFASTINT (dimension), chars_flag,
2122 XFASTINT (final_char));
2123 return (id >= 0 ? CHARSET_NAME (CHARSET_FROM_ID (id)) : Qnil); 2113 return (id >= 0 ? CHARSET_NAME (CHARSET_FROM_ID (id)) : Qnil);
2124} 2114}
2125 2115
@@ -2298,7 +2288,7 @@ init_charset (void)
2298{ 2288{
2299 Lisp_Object tempdir; 2289 Lisp_Object tempdir;
2300 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); 2290 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
2301 if (! file_accessible_directory_p (SSDATA (tempdir))) 2291 if (! file_accessible_directory_p (tempdir))
2302 { 2292 {
2303 /* This used to be non-fatal (dir_warning), but it should not 2293 /* This used to be non-fatal (dir_warning), but it should not
2304 happen, and if it does sooner or later it will cause some 2294 happen, and if it does sooner or later it will cause some
diff --git a/src/chartab.c b/src/chartab.c
index 50be063759a..bfbbf798f0c 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -1258,13 +1258,8 @@ uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value)
1258 break; 1258 break;
1259 value = make_number (i); 1259 value = make_number (i);
1260 if (i == size) 1260 if (i == size)
1261 { 1261 set_char_table_extras (table, 4, Fvconcat (2, ((Lisp_Object []) {
1262 Lisp_Object args[2]; 1262 XCHAR_TABLE (table)->extras[4], Fmake_vector (make_number (1), value) })));
1263
1264 args[0] = XCHAR_TABLE (table)->extras[4];
1265 args[1] = Fmake_vector (make_number (1), value);
1266 set_char_table_extras (table, 4, Fvconcat (2, args));
1267 }
1268 return make_number (i); 1263 return make_number (i);
1269} 1264}
1270 1265
@@ -1307,8 +1302,8 @@ uniprop_table (Lisp_Object prop)
1307 { 1302 {
1308 struct gcpro gcpro1; 1303 struct gcpro gcpro1;
1309 GCPRO1 (val); 1304 GCPRO1 (val);
1310 result = Fload (concat2 (build_string ("international/"), table), 1305 AUTO_STRING (intl, "international/");
1311 Qt, Qt, Qt, Qt); 1306 result = Fload (concat2 (intl, table), Qt, Qt, Qt, Qt);
1312 UNGCPRO; 1307 UNGCPRO;
1313 if (NILP (result)) 1308 if (NILP (result))
1314 return Qnil; 1309 return Qnil;
diff --git a/src/coding.c b/src/coding.c
index 8b620af8695..e4b52f6db48 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -642,15 +642,6 @@ static enum coding_category coding_priorities[coding_category_max];
642 Nth coding category. */ 642 Nth coding category. */
643static struct coding_system coding_categories[coding_category_max]; 643static struct coding_system coding_categories[coding_category_max];
644 644
645/*** Commonly used macros and functions ***/
646
647#ifndef min
648#define min(a, b) ((a) < (b) ? (a) : (b))
649#endif
650#ifndef max
651#define max(a, b) ((a) > (b) ? (a) : (b))
652#endif
653
654/* Encode a flag that can be nil, something else, or t as -1, 0, 1. */ 645/* Encode a flag that can be nil, something else, or t as -1, 0, 1. */
655 646
656static int 647static int
@@ -690,6 +681,14 @@ CHECK_NATNUM_CDR (Lisp_Object x)
690 XSETCDR (x, tmp); 681 XSETCDR (x, tmp);
691} 682}
692 683
684/* True if CODING's destination can be grown. */
685
686static bool
687growable_destination (struct coding_system *coding)
688{
689 return STRINGP (coding->dst_object) || BUFFERP (coding->dst_object);
690}
691
693 692
694/* Safely get one byte from the source text pointed by SRC which ends 693/* Safely get one byte from the source text pointed by SRC which ends
695 at SRC_END, and set C to that byte. If there are not enough bytes 694 at SRC_END, and set C to that byte. If there are not enough bytes
@@ -3074,8 +3073,13 @@ detect_coding_iso_2022 (struct coding_system *coding,
3074 ONE_MORE_BYTE (c1); 3073 ONE_MORE_BYTE (c1);
3075 if (c1 < ' ' || c1 >= 0x80 3074 if (c1 < ' ' || c1 >= 0x80
3076 || (id = iso_charset_table[0][c >= ','][c1]) < 0) 3075 || (id = iso_charset_table[0][c >= ','][c1]) < 0)
3077 /* Invalid designation sequence. Just ignore. */ 3076 {
3078 break; 3077 /* Invalid designation sequence. Just ignore. */
3078 if (c1 >= 0x80)
3079 rejected |= (CATEGORY_MASK_ISO_7BIT
3080 | CATEGORY_MASK_ISO_7_ELSE);
3081 break;
3082 }
3079 } 3083 }
3080 else if (c == '$') 3084 else if (c == '$')
3081 { 3085 {
@@ -3089,16 +3093,29 @@ detect_coding_iso_2022 (struct coding_system *coding,
3089 ONE_MORE_BYTE (c1); 3093 ONE_MORE_BYTE (c1);
3090 if (c1 < ' ' || c1 >= 0x80 3094 if (c1 < ' ' || c1 >= 0x80
3091 || (id = iso_charset_table[1][c >= ','][c1]) < 0) 3095 || (id = iso_charset_table[1][c >= ','][c1]) < 0)
3092 /* Invalid designation sequence. Just ignore. */ 3096 {
3093 break; 3097 /* Invalid designation sequence. Just ignore. */
3098 if (c1 >= 0x80)
3099 rejected |= (CATEGORY_MASK_ISO_7BIT
3100 | CATEGORY_MASK_ISO_7_ELSE);
3101 break;
3102 }
3094 } 3103 }
3095 else 3104 else
3096 /* Invalid designation sequence. Just ignore it. */ 3105 {
3097 break; 3106 /* Invalid designation sequence. Just ignore it. */
3107 if (c >= 0x80)
3108 rejected |= (CATEGORY_MASK_ISO_7BIT
3109 | CATEGORY_MASK_ISO_7_ELSE);
3110 break;
3111 }
3098 } 3112 }
3099 else 3113 else
3100 { 3114 {
3101 /* Invalid escape sequence. Just ignore it. */ 3115 /* Invalid escape sequence. Just ignore it. */
3116 if (c >= 0x80)
3117 rejected |= (CATEGORY_MASK_ISO_7BIT
3118 | CATEGORY_MASK_ISO_7_ELSE);
3102 break; 3119 break;
3103 } 3120 }
3104 3121
@@ -3149,7 +3166,7 @@ detect_coding_iso_2022 (struct coding_system *coding,
3149 if (inhibit_iso_escape_detection) 3166 if (inhibit_iso_escape_detection)
3150 break; 3167 break;
3151 single_shifting = 0; 3168 single_shifting = 0;
3152 rejected |= CATEGORY_MASK_ISO_7BIT; 3169 rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_7_ELSE;
3153 if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1]) 3170 if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
3154 & CODING_ISO_FLAG_SINGLE_SHIFT) 3171 & CODING_ISO_FLAG_SINGLE_SHIFT)
3155 { 3172 {
@@ -3176,9 +3193,9 @@ detect_coding_iso_2022 (struct coding_system *coding,
3176 single_shifting = 0; 3193 single_shifting = 0;
3177 break; 3194 break;
3178 } 3195 }
3196 rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_7_ELSE;
3179 if (c >= 0xA0) 3197 if (c >= 0xA0)
3180 { 3198 {
3181 rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_7_ELSE;
3182 found |= CATEGORY_MASK_ISO_8_1; 3199 found |= CATEGORY_MASK_ISO_8_1;
3183 /* Check the length of succeeding codes of the range 3200 /* Check the length of succeeding codes of the range
3184 0xA0..0FF. If the byte length is even, we include 3201 0xA0..0FF. If the byte length is even, we include
@@ -6867,6 +6884,11 @@ decode_eol (struct coding_system *coding)
6867} 6884}
6868 6885
6869 6886
6887/* MAX_LOOKUP's maximum value. MAX_LOOKUP is an int and so cannot
6888 exceed INT_MAX. Also, MAX_LOOKUP is multiplied by sizeof (int) for
6889 alloca, so it cannot exceed MAX_ALLOCA / sizeof (int). */
6890enum { MAX_LOOKUP_MAX = min (INT_MAX, MAX_ALLOCA / sizeof (int)) };
6891
6870/* Return a translation table (or list of them) from coding system 6892/* Return a translation table (or list of them) from coding system
6871 attribute vector ATTRS for encoding (if ENCODEP) or decoding (if 6893 attribute vector ATTRS for encoding (if ENCODEP) or decoding (if
6872 not ENCODEP). */ 6894 not ENCODEP). */
@@ -6919,7 +6941,7 @@ get_translation_table (Lisp_Object attrs, bool encodep, int *max_lookup)
6919 { 6941 {
6920 val = XCHAR_TABLE (translation_table)->extras[1]; 6942 val = XCHAR_TABLE (translation_table)->extras[1];
6921 if (NATNUMP (val) && *max_lookup < XFASTINT (val)) 6943 if (NATNUMP (val) && *max_lookup < XFASTINT (val))
6922 *max_lookup = XFASTINT (val); 6944 *max_lookup = min (XFASTINT (val), MAX_LOOKUP_MAX);
6923 } 6945 }
6924 else if (CONSP (translation_table)) 6946 else if (CONSP (translation_table))
6925 { 6947 {
@@ -6931,7 +6953,7 @@ get_translation_table (Lisp_Object attrs, bool encodep, int *max_lookup)
6931 { 6953 {
6932 Lisp_Object tailval = XCHAR_TABLE (XCAR (tail))->extras[1]; 6954 Lisp_Object tailval = XCHAR_TABLE (XCAR (tail))->extras[1];
6933 if (NATNUMP (tailval) && *max_lookup < XFASTINT (tailval)) 6955 if (NATNUMP (tailval) && *max_lookup < XFASTINT (tailval))
6934 *max_lookup = XFASTINT (tailval); 6956 *max_lookup = min (XFASTINT (tailval), MAX_LOOKUP_MAX);
6935 } 6957 }
6936 } 6958 }
6937 } 6959 }
@@ -7014,8 +7036,10 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7014 int *buf = coding->charbuf; 7036 int *buf = coding->charbuf;
7015 int *buf_end = buf + coding->charbuf_used; 7037 int *buf_end = buf + coding->charbuf_used;
7016 7038
7017 if (EQ (coding->src_object, coding->dst_object)) 7039 if (EQ (coding->src_object, coding->dst_object)
7040 && ! NILP (coding->dst_object))
7018 { 7041 {
7042 eassert (growable_destination (coding));
7019 coding_set_source (coding); 7043 coding_set_source (coding);
7020 dst_end = ((unsigned char *) coding->source) + coding->consumed; 7044 dst_end = ((unsigned char *) coding->source) + coding->consumed;
7021 } 7045 }
@@ -7054,6 +7078,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7054 7078
7055 if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars) 7079 if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars)
7056 { 7080 {
7081 eassert (growable_destination (coding));
7057 if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf)) 7082 if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf))
7058 / MAX_MULTIBYTE_LENGTH) 7083 / MAX_MULTIBYTE_LENGTH)
7059 < to_nchars) 7084 < to_nchars)
@@ -7098,7 +7123,10 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7098 const unsigned char *src_end = src + coding->consumed; 7123 const unsigned char *src_end = src + coding->consumed;
7099 7124
7100 if (EQ (coding->dst_object, coding->src_object)) 7125 if (EQ (coding->dst_object, coding->src_object))
7101 dst_end = (unsigned char *) src; 7126 {
7127 eassert (growable_destination (coding));
7128 dst_end = (unsigned char *) src;
7129 }
7102 if (coding->src_multibyte != coding->dst_multibyte) 7130 if (coding->src_multibyte != coding->dst_multibyte)
7103 { 7131 {
7104 if (coding->src_multibyte) 7132 if (coding->src_multibyte)
@@ -7114,6 +7142,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7114 ONE_MORE_BYTE (c); 7142 ONE_MORE_BYTE (c);
7115 if (dst == dst_end) 7143 if (dst == dst_end)
7116 { 7144 {
7145 eassert (growable_destination (coding));
7117 if (EQ (coding->src_object, coding->dst_object)) 7146 if (EQ (coding->src_object, coding->dst_object))
7118 dst_end = (unsigned char *) src; 7147 dst_end = (unsigned char *) src;
7119 if (dst == dst_end) 7148 if (dst == dst_end)
@@ -7144,6 +7173,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
7144 7173
7145 if (dst >= dst_end - 1) 7174 if (dst >= dst_end - 1)
7146 { 7175 {
7176 eassert (growable_destination (coding));
7147 if (EQ (coding->src_object, coding->dst_object)) 7177 if (EQ (coding->src_object, coding->dst_object))
7148 dst_end = (unsigned char *) src; 7178 dst_end = (unsigned char *) src;
7149 if (dst >= dst_end - 1) 7179 if (dst >= dst_end - 1)
@@ -9729,7 +9759,7 @@ DEFUN ("set-terminal-coding-system-internal", Fset_terminal_coding_system_intern
9729 doc: /* Internal use only. */) 9759 doc: /* Internal use only. */)
9730 (Lisp_Object coding_system, Lisp_Object terminal) 9760 (Lisp_Object coding_system, Lisp_Object terminal)
9731{ 9761{
9732 struct terminal *term = get_terminal (terminal, 1); 9762 struct terminal *term = decode_live_terminal (terminal);
9733 struct coding_system *terminal_coding = TERMINAL_TERMINAL_CODING (term); 9763 struct coding_system *terminal_coding = TERMINAL_TERMINAL_CODING (term);
9734 CHECK_SYMBOL (coding_system); 9764 CHECK_SYMBOL (coding_system);
9735 setup_coding_system (Fcheck_coding_system (coding_system), terminal_coding); 9765 setup_coding_system (Fcheck_coding_system (coding_system), terminal_coding);
@@ -9770,7 +9800,7 @@ frame's terminal device. */)
9770 (Lisp_Object terminal) 9800 (Lisp_Object terminal)
9771{ 9801{
9772 struct coding_system *terminal_coding 9802 struct coding_system *terminal_coding
9773 = TERMINAL_TERMINAL_CODING (get_terminal (terminal, 1)); 9803 = TERMINAL_TERMINAL_CODING (decode_live_terminal (terminal));
9774 Lisp_Object coding_system = CODING_ID_NAME (terminal_coding->id); 9804 Lisp_Object coding_system = CODING_ID_NAME (terminal_coding->id);
9775 9805
9776 /* For backward compatibility, return nil if it is `undecided'. */ 9806 /* For backward compatibility, return nil if it is `undecided'. */
@@ -9782,7 +9812,7 @@ DEFUN ("set-keyboard-coding-system-internal", Fset_keyboard_coding_system_intern
9782 doc: /* Internal use only. */) 9812 doc: /* Internal use only. */)
9783 (Lisp_Object coding_system, Lisp_Object terminal) 9813 (Lisp_Object coding_system, Lisp_Object terminal)
9784{ 9814{
9785 struct terminal *t = get_terminal (terminal, 1); 9815 struct terminal *t = decode_live_terminal (terminal);
9786 CHECK_SYMBOL (coding_system); 9816 CHECK_SYMBOL (coding_system);
9787 if (NILP (coding_system)) 9817 if (NILP (coding_system))
9788 coding_system = Qno_conversion; 9818 coding_system = Qno_conversion;
@@ -9801,7 +9831,7 @@ DEFUN ("keyboard-coding-system",
9801 (Lisp_Object terminal) 9831 (Lisp_Object terminal)
9802{ 9832{
9803 return CODING_ID_NAME (TERMINAL_KEYBOARD_CODING 9833 return CODING_ID_NAME (TERMINAL_KEYBOARD_CODING
9804 (get_terminal (terminal, 1))->id); 9834 (decode_live_terminal (terminal))->id);
9805} 9835}
9806 9836
9807 9837
@@ -10011,7 +10041,8 @@ make_subsidiaries (Lisp_Object base)
10011{ 10041{
10012 Lisp_Object subsidiaries; 10042 Lisp_Object subsidiaries;
10013 ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base)); 10043 ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base));
10014 char *buf = alloca (base_name_len + 6); 10044 USE_SAFE_ALLOCA;
10045 char *buf = SAFE_ALLOCA (base_name_len + 6);
10015 int i; 10046 int i;
10016 10047
10017 memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len); 10048 memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len);
@@ -10021,6 +10052,7 @@ make_subsidiaries (Lisp_Object base)
10021 strcpy (buf + base_name_len, suffixes[i]); 10052 strcpy (buf + base_name_len, suffixes[i]);
10022 ASET (subsidiaries, i, intern (buf)); 10053 ASET (subsidiaries, i, intern (buf));
10023 } 10054 }
10055 SAFE_FREE ();
10024 return subsidiaries; 10056 return subsidiaries;
10025} 10057}
10026 10058
diff --git a/src/composite.c b/src/composite.c
index 66a20759ec6..8982c904096 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -928,7 +928,7 @@ static bool
928char_composable_p (int c) 928char_composable_p (int c)
929{ 929{
930 Lisp_Object val; 930 Lisp_Object val;
931 return (c > ' ' 931 return (c > ' '
932 && (c == 0x200C || c == 0x200D 932 && (c == 0x200C || c == 0x200D
933 || (val = CHAR_TABLE_REF (Vunicode_category_table, c), 933 || (val = CHAR_TABLE_REF (Vunicode_category_table, c),
934 (INTEGERP (val) && (XINT (val) <= UNICODE_CATEGORY_So))))); 934 (INTEGERP (val) && (XINT (val) <= UNICODE_CATEGORY_So)))));
@@ -1016,24 +1016,19 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1016 val = CHAR_TABLE_REF (Vcomposition_function_table, c); 1016 val = CHAR_TABLE_REF (Vcomposition_function_table, c);
1017 if (! NILP (val)) 1017 if (! NILP (val))
1018 { 1018 {
1019 Lisp_Object elt; 1019 for (int ridx = 0; CONSP (val); val = XCDR (val), ridx++)
1020 int ridx;
1021
1022 for (ridx = 0; CONSP (val); val = XCDR (val), ridx++)
1023 { 1020 {
1024 elt = XCAR (val); 1021 Lisp_Object elt = XCAR (val);
1025 if (VECTORP (elt) && ASIZE (elt) == 3 1022 if (VECTORP (elt) && ASIZE (elt) == 3
1026 && NATNUMP (AREF (elt, 1)) 1023 && NATNUMP (AREF (elt, 1))
1027 && charpos - 1 - XFASTINT (AREF (elt, 1)) >= start) 1024 && charpos - 1 - XFASTINT (AREF (elt, 1)) >= start)
1028 break; 1025 {
1029 } 1026 cmp_it->rule_idx = ridx;
1030 if (CONSP (val)) 1027 cmp_it->lookback = XFASTINT (AREF (elt, 1));
1031 { 1028 cmp_it->stop_pos = charpos - 1 - cmp_it->lookback;
1032 cmp_it->rule_idx = ridx; 1029 cmp_it->ch = c;
1033 cmp_it->lookback = XFASTINT (AREF (elt, 1)); 1030 return;
1034 cmp_it->stop_pos = charpos - 1 - cmp_it->lookback; 1031 }
1035 cmp_it->ch = c;
1036 return;
1037 } 1032 }
1038 } 1033 }
1039 } 1034 }
@@ -1724,7 +1719,7 @@ should be ignored. */)
1724 if (! FONT_OBJECT_P (font_object)) 1719 if (! FONT_OBJECT_P (font_object))
1725 { 1720 {
1726 struct coding_system *coding; 1721 struct coding_system *coding;
1727 struct terminal *terminal = get_terminal (font_object, 1); 1722 struct terminal *terminal = decode_live_terminal (font_object);
1728 1723
1729 coding = ((TERMINAL_TERMINAL_CODING (terminal)->common_flags 1724 coding = ((TERMINAL_TERMINAL_CODING (terminal)->common_flags
1730 & CODING_REQUIRE_ENCODING_MASK) 1725 & CODING_REQUIRE_ENCODING_MASK)
diff --git a/src/conf_post.h b/src/conf_post.h
index a995acfd915..8667e2554cd 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -80,6 +80,23 @@ typedef bool bool_bf;
80#define vfork fork 80#define vfork fork
81#endif /* DARWIN_OS */ 81#endif /* DARWIN_OS */
82 82
83/* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use
84 gmalloc before dumping and the system malloc after dumping.
85 hybrid_malloc and friends, defined in gmalloc.c, are wrappers that
86 accomplish this. */
87#ifdef HYBRID_MALLOC
88#ifdef emacs
89#define malloc hybrid_malloc
90#define realloc hybrid_realloc
91#define calloc hybrid_calloc
92#define free hybrid_free
93#if defined HAVE_GET_CURRENT_DIR_NAME && !defined BROKEN_GET_CURRENT_DIR_NAME
94#define HYBRID_GET_CURRENT_DIR_NAME 1
95#define get_current_dir_name hybrid_get_current_dir_name
96#endif
97#endif
98#endif /* HYBRID_MALLOC */
99
83/* We have to go this route, rather than the old hpux9 approach of 100/* We have to go this route, rather than the old hpux9 approach of
84 renaming the functions via macros. The system's stdlib.h has fully 101 renaming the functions via macros. The system's stdlib.h has fully
85 prototyped declarations, which yields a conflicting definition of 102 prototyped declarations, which yields a conflicting definition of
@@ -123,13 +140,6 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */
123 so we could reuse it in readlinkat; see msdos.c. */ 140 so we could reuse it in readlinkat; see msdos.c. */
124#define opendir sys_opendir 141#define opendir sys_opendir
125 142
126/* The "portable" definition of _GL_INLINE on config.h does not work
127 with DJGPP GCC 3.4.4: it causes unresolved externals in sysdep.c,
128 although lib/execinfo.h is included and the inline functions there
129 are visible. */
130#if __GNUC__ < 4
131# define _GL_EXECINFO_INLINE inline
132#endif
133/* End of gnulib-related stuff. */ 143/* End of gnulib-related stuff. */
134 144
135#define emacs_raise(sig) msdos_fatal_signal (sig) 145#define emacs_raise(sig) msdos_fatal_signal (sig)
@@ -183,6 +193,10 @@ extern void _DebPrint (const char *fmt, ...);
183#if defined CYGWIN && defined HAVE_NTGUI 193#if defined CYGWIN && defined HAVE_NTGUI
184# define NTGUI_UNICODE /* Cygwin runs only on UNICODE-supporting systems */ 194# define NTGUI_UNICODE /* Cygwin runs only on UNICODE-supporting systems */
185# define _WIN32_WINNT 0x500 /* Win2k */ 195# define _WIN32_WINNT 0x500 /* Win2k */
196/* The following was in /usr/include/string.h prior to Cygwin 1.7.33. */
197#ifndef strnicmp
198#define strnicmp strncasecmp
199#endif
186#endif 200#endif
187 201
188#ifdef emacs /* Don't do this for lib-src. */ 202#ifdef emacs /* Don't do this for lib-src. */
diff --git a/src/data.c b/src/data.c
index 3e651414e68..9977a3aaadd 100644
--- a/src/data.c
+++ b/src/data.c
@@ -979,17 +979,21 @@ wrong_choice (Lisp_Object choice, Lisp_Object wrong)
979{ 979{
980 ptrdiff_t i = 0, len = XINT (Flength (choice)); 980 ptrdiff_t i = 0, len = XINT (Flength (choice));
981 Lisp_Object obj, *args; 981 Lisp_Object obj, *args;
982 AUTO_STRING (one_of, "One of ");
983 AUTO_STRING (comma, ", ");
984 AUTO_STRING (or, " or ");
985 AUTO_STRING (should_be_specified, " should be specified");
982 986
983 USE_SAFE_ALLOCA; 987 USE_SAFE_ALLOCA;
984 SAFE_ALLOCA_LISP (args, len * 2 + 1); 988 SAFE_ALLOCA_LISP (args, len * 2 + 1);
985 989
986 args[i++] = build_string ("One of "); 990 args[i++] = one_of;
987 991
988 for (obj = choice; !NILP (obj); obj = XCDR (obj)) 992 for (obj = choice; !NILP (obj); obj = XCDR (obj))
989 { 993 {
990 args[i++] = SYMBOL_NAME (XCAR (obj)); 994 args[i++] = SYMBOL_NAME (XCAR (obj));
991 args[i++] = build_string (NILP (XCDR (obj)) ? " should be specified" 995 args[i++] = (NILP (XCDR (obj)) ? should_be_specified
992 : (NILP (XCDR (XCDR (obj))) ? " or " : ", ")); 996 : NILP (XCDR (XCDR (obj))) ? or : comma);
993 } 997 }
994 998
995 obj = Fconcat (i, args); 999 obj = Fconcat (i, args);
@@ -1003,14 +1007,13 @@ wrong_choice (Lisp_Object choice, Lisp_Object wrong)
1003static void 1007static void
1004wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong) 1008wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong)
1005{ 1009{
1006 Lisp_Object args[4]; 1010 AUTO_STRING (value_should_be_from, "Value should be from ");
1007 1011 AUTO_STRING (to, " to ");
1008 args[0] = build_string ("Value should be from "); 1012 xsignal2 (Qerror,
1009 args[1] = Fnumber_to_string (min); 1013 Fconcat (4, ((Lisp_Object [])
1010 args[2] = build_string (" to "); 1014 {value_should_be_from, Fnumber_to_string (min),
1011 args[3] = Fnumber_to_string (max); 1015 to, Fnumber_to_string (max)})),
1012 1016 wrong);
1013 xsignal2 (Qerror, Fconcat (4, args), wrong);
1014} 1017}
1015 1018
1016/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell 1019/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell
@@ -1311,10 +1314,10 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1311 1314
1312 /* Find the new binding. */ 1315 /* Find the new binding. */
1313 XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */ 1316 XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */
1314 tem1 = Fassq (symbol, 1317 tem1 = assq_no_quit (symbol,
1315 (blv->frame_local 1318 (blv->frame_local
1316 ? XFRAME (where)->param_alist 1319 ? XFRAME (where)->param_alist
1317 : BVAR (XBUFFER (where), local_var_alist))); 1320 : BVAR (XBUFFER (where), local_var_alist)));
1318 set_blv_where (blv, where); 1321 set_blv_where (blv, where);
1319 blv->found = 1; 1322 blv->found = 1;
1320 1323
@@ -1952,19 +1955,11 @@ DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p,
1952 1, 2, 0, 1955 1, 2, 0,
1953 doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER. 1956 doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER.
1954BUFFER defaults to the current buffer. */) 1957BUFFER defaults to the current buffer. */)
1955 (register Lisp_Object variable, Lisp_Object buffer) 1958 (Lisp_Object variable, Lisp_Object buffer)
1956{ 1959{
1957 register struct buffer *buf; 1960 struct buffer *buf = decode_buffer (buffer);
1958 struct Lisp_Symbol *sym; 1961 struct Lisp_Symbol *sym;
1959 1962
1960 if (NILP (buffer))
1961 buf = current_buffer;
1962 else
1963 {
1964 CHECK_BUFFER (buffer);
1965 buf = XBUFFER (buffer);
1966 }
1967
1968 CHECK_SYMBOL (variable); 1963 CHECK_SYMBOL (variable);
1969 sym = XSYMBOL (variable); 1964 sym = XSYMBOL (variable);
1970 1965
@@ -2318,7 +2313,7 @@ bool-vector. IDX starts at 0. */)
2318 { 2313 {
2319 if (! SINGLE_BYTE_CHAR_P (c)) 2314 if (! SINGLE_BYTE_CHAR_P (c))
2320 { 2315 {
2321 int i; 2316 ptrdiff_t i;
2322 2317
2323 for (i = SBYTES (array) - 1; i >= 0; i--) 2318 for (i = SBYTES (array) - 1; i >= 0; i--)
2324 if (SREF (array, i) >= 0x80) 2319 if (SREF (array, i) >= 0x80)
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 8997e01b068..4852739d8e4 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -761,7 +761,7 @@ xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter)
761 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object))) 761 && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object)))
762 && NILP (CDR_SAFE (XD_NEXT_VALUE (object)))) 762 && NILP (CDR_SAFE (XD_NEXT_VALUE (object))))
763 { 763 {
764 strcpy (signature, SSDATA (CAR_SAFE (XD_NEXT_VALUE (object)))); 764 lispstpcpy (signature, CAR_SAFE (XD_NEXT_VALUE (object)));
765 object = CDR_SAFE (XD_NEXT_VALUE (object)); 765 object = CDR_SAFE (XD_NEXT_VALUE (object));
766 } 766 }
767 767
@@ -1054,6 +1054,7 @@ xd_remove_watch (DBusWatch *watch, void *data)
1054 1054
1055 /* Unset session environment. */ 1055 /* Unset session environment. */
1056#if 0 1056#if 0
1057 /* This is buggy, since unsetenv is not thread-safe. */
1057 if (XSYMBOL (QCdbus_session_bus) == data) 1058 if (XSYMBOL (QCdbus_session_bus) == data)
1058 { 1059 {
1059 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); 1060 XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
@@ -1219,9 +1220,6 @@ this connection to those buses. */)
1219 XSETFASTINT (val, (intptr_t) connection); 1220 XSETFASTINT (val, (intptr_t) connection);
1220 xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses); 1221 xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses);
1221 1222
1222 /* We do not want to abort. */
1223 xputenv ("DBUS_FATAL_WARNINGS=0");
1224
1225 /* Cleanup. */ 1223 /* Cleanup. */
1226 dbus_error_free (&derror); 1224 dbus_error_free (&derror);
1227 } 1225 }
@@ -1738,6 +1736,13 @@ xd_read_queued_messages (int fd, void *data)
1738 1736
1739 1737
1740void 1738void
1739init_dbusbind (void)
1740{
1741 /* We do not want to abort. */
1742 xputenv ("DBUS_FATAL_WARNINGS=0");
1743}
1744
1745void
1741syms_of_dbusbind (void) 1746syms_of_dbusbind (void)
1742{ 1747{
1743 1748
diff --git a/src/decompress.c b/src/decompress.c
index cd8a3d1e962..24ce852245c 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -60,10 +60,7 @@ init_zlib_functions (void)
60 HMODULE library = w32_delayed_load (Qzlib_dll); 60 HMODULE library = w32_delayed_load (Qzlib_dll);
61 61
62 if (!library) 62 if (!library)
63 { 63 return false;
64 message1 ("zlib library not found");
65 return false;
66 }
67 64
68 LOAD_ZLIB_FN (library, inflateInit2_); 65 LOAD_ZLIB_FN (library, inflateInit2_);
69 LOAD_ZLIB_FN (library, inflate); 66 LOAD_ZLIB_FN (library, inflate);
@@ -150,7 +147,10 @@ This function can be called only in unibyte buffers. */)
150 if (!zlib_initialized) 147 if (!zlib_initialized)
151 zlib_initialized = init_zlib_functions (); 148 zlib_initialized = init_zlib_functions ();
152 if (!zlib_initialized) 149 if (!zlib_initialized)
153 return Qnil; 150 {
151 message1 ("zlib library not found");
152 return Qnil;
153 }
154#endif 154#endif
155 155
156 /* This is a unibyte buffer, so character positions and bytes are 156 /* This is a unibyte buffer, so character positions and bytes are
diff --git a/src/dispextern.h b/src/dispextern.h
index b87ae891a37..c75eb27d635 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2541,7 +2541,9 @@ struct it
2541 2541
2542 /* First and last visible x-position in the display area. If window 2542 /* First and last visible x-position in the display area. If window
2543 is hscrolled by n columns, first_visible_x == n * FRAME_COLUMN_WIDTH 2543 is hscrolled by n columns, first_visible_x == n * FRAME_COLUMN_WIDTH
2544 (f), and last_visible_x == pixel width of W + first_visible_x. */ 2544 (f), and last_visible_x == pixel width of W + first_visible_x.
2545 When truncation or continuation glyphs are produced due to lack of
2546 fringes, last_visible_x excludes the space required for these glyphs. */
2545 int first_visible_x, last_visible_x; 2547 int first_visible_x, last_visible_x;
2546 2548
2547 /* Last visible y-position + 1 in the display area without a mode 2549 /* Last visible y-position + 1 in the display area without a mode
@@ -3192,7 +3194,6 @@ int window_box_width (struct window *, enum glyph_row_area);
3192int window_box_left (struct window *, enum glyph_row_area); 3194int window_box_left (struct window *, enum glyph_row_area);
3193int window_box_left_offset (struct window *, enum glyph_row_area); 3195int window_box_left_offset (struct window *, enum glyph_row_area);
3194int window_box_right (struct window *, enum glyph_row_area); 3196int window_box_right (struct window *, enum glyph_row_area);
3195int window_box_right_offset (struct window *, enum glyph_row_area);
3196int estimate_mode_line_height (struct frame *, enum face_id); 3197int estimate_mode_line_height (struct frame *, enum face_id);
3197int move_it_to (struct it *, ptrdiff_t, int, int, int, int); 3198int move_it_to (struct it *, ptrdiff_t, int, int, int, int);
3198void pixel_to_glyph_coords (struct frame *, int, int, int *, int *, 3199void pixel_to_glyph_coords (struct frame *, int, int, int *, int *,
@@ -3517,7 +3518,6 @@ extern void calculate_costs (struct frame *);
3517extern void produce_glyphs (struct it *); 3518extern void produce_glyphs (struct it *);
3518extern bool tty_capable_p (struct tty_display_info *, unsigned); 3519extern bool tty_capable_p (struct tty_display_info *, unsigned);
3519extern void set_tty_color_mode (struct tty_display_info *, struct frame *); 3520extern void set_tty_color_mode (struct tty_display_info *, struct frame *);
3520extern struct terminal *get_named_tty (const char *);
3521extern void create_tty_output (struct frame *); 3521extern void create_tty_output (struct frame *);
3522extern struct terminal *init_tty (const char *, const char *, bool); 3522extern struct terminal *init_tty (const char *, const char *, bool);
3523extern void tty_append_glyph (struct it *); 3523extern void tty_append_glyph (struct it *);
diff --git a/src/dispnew.c b/src/dispnew.c
index b587852fc6e..3ab8bcf3e64 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -1082,8 +1082,7 @@ prepare_desired_row (struct window *w, struct glyph_row *row, bool mode_line_p)
1082 if (w->right_margin_cols > 0) 1082 if (w->right_margin_cols > 0)
1083 row->glyphs[RIGHT_MARGIN_AREA] = row->glyphs[LAST_AREA]; 1083 row->glyphs[RIGHT_MARGIN_AREA] = row->glyphs[LAST_AREA];
1084 } 1084 }
1085 else if (row == MATRIX_MODE_LINE_ROW (w->desired_matrix) 1085 else
1086 || row == MATRIX_HEADER_LINE_ROW (w->desired_matrix))
1087 { 1086 {
1088 /* The real number of glyphs reserved for the margins is 1087 /* The real number of glyphs reserved for the margins is
1089 recorded in the glyph matrix, and can be different from 1088 recorded in the glyph matrix, and can be different from
@@ -1093,8 +1092,8 @@ prepare_desired_row (struct window *w, struct glyph_row *row, bool mode_line_p)
1093 int right = w->desired_matrix->right_margin_glyphs; 1092 int right = w->desired_matrix->right_margin_glyphs;
1094 1093
1095 /* Make sure the marginal areas of this row are in sync with 1094 /* Make sure the marginal areas of this row are in sync with
1096 what the window wants, when the 1st/last row of the matrix 1095 what the window wants, when the row actually displays text
1097 actually displays text and not header/mode line. */ 1096 and not header/mode line. */
1098 if (w->left_margin_cols > 0 1097 if (w->left_margin_cols > 0
1099 && (left != row->glyphs[TEXT_AREA] - row->glyphs[LEFT_MARGIN_AREA])) 1098 && (left != row->glyphs[TEXT_AREA] - row->glyphs[LEFT_MARGIN_AREA]))
1100 row->glyphs[TEXT_AREA] = row->glyphs[LEFT_MARGIN_AREA] + left; 1099 row->glyphs[TEXT_AREA] = row->glyphs[LEFT_MARGIN_AREA] + left;
@@ -2138,8 +2137,11 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2138static void 2137static void
2139adjust_decode_mode_spec_buffer (struct frame *f) 2138adjust_decode_mode_spec_buffer (struct frame *f)
2140{ 2139{
2140 int frame_message_buf_size = FRAME_MESSAGE_BUF_SIZE (f);
2141
2142 eassert (frame_message_buf_size >= 0);
2141 f->decode_mode_spec_buffer = xrealloc (f->decode_mode_spec_buffer, 2143 f->decode_mode_spec_buffer = xrealloc (f->decode_mode_spec_buffer,
2142 FRAME_MESSAGE_BUF_SIZE (f) + 1); 2144 frame_message_buf_size + 1);
2143} 2145}
2144 2146
2145 2147
@@ -5121,7 +5123,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5121#ifdef HAVE_WINDOW_SYSTEM 5123#ifdef HAVE_WINDOW_SYSTEM
5122 struct image *img = 0; 5124 struct image *img = 0;
5123#endif 5125#endif
5124 int x0, x1, to_x; 5126 int x0, x1, to_x, it_vpos;
5125 void *itdata = NULL; 5127 void *itdata = NULL;
5126 5128
5127 /* We used to set current_buffer directly here, but that does the 5129 /* We used to set current_buffer directly here, but that does the
@@ -5130,11 +5132,6 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5130 itdata = bidi_shelve_cache (); 5132 itdata = bidi_shelve_cache ();
5131 CLIP_TEXT_POS_FROM_MARKER (startp, w->start); 5133 CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
5132 start_display (&it, w, startp); 5134 start_display (&it, w, startp);
5133 /* start_display takes into account the header-line row, but IT's
5134 vpos still counts from the glyph row that includes the window's
5135 start position. Adjust for a possible header-line row. */
5136 it.vpos += WINDOW_WANTS_HEADER_LINE_P (w);
5137
5138 x0 = *x; 5135 x0 = *x;
5139 5136
5140 /* First, move to the beginning of the row corresponding to *Y. We 5137 /* First, move to the beginning of the row corresponding to *Y. We
@@ -5143,9 +5140,8 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5143 move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y); 5140 move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
5144 5141
5145 /* TO_X is the pixel position that the iterator will compute for the 5142 /* TO_X is the pixel position that the iterator will compute for the
5146 glyph at *X. We add it.first_visible_x because iterator 5143 glyph at *X. */
5147 positions include the hscroll. */ 5144 to_x = x0;
5148 to_x = x0 + it.first_visible_x;
5149 if (it.bidi_it.paragraph_dir == R2L) 5145 if (it.bidi_it.paragraph_dir == R2L)
5150 /* For lines in an R2L paragraph, we need to mirror TO_X wrt the 5146 /* For lines in an R2L paragraph, we need to mirror TO_X wrt the
5151 text area. This is because the iterator, even in R2L 5147 text area. This is because the iterator, even in R2L
@@ -5159,6 +5155,10 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5159 it should be mirrored into zero pixel position.) */ 5155 it should be mirrored into zero pixel position.) */
5160 to_x = window_box_width (w, TEXT_AREA) - to_x - 1; 5156 to_x = window_box_width (w, TEXT_AREA) - to_x - 1;
5161 5157
5158 /* We need to add it.first_visible_x because iterator positions
5159 include the hscroll. */
5160 to_x += it.first_visible_x;
5161
5162 /* Now move horizontally in the row to the glyph under *X. Second 5162 /* Now move horizontally in the row to the glyph under *X. Second
5163 argument is ZV to prevent move_it_in_display_line from matching 5163 argument is ZV to prevent move_it_in_display_line from matching
5164 based on buffer positions. */ 5164 based on buffer positions. */
@@ -5201,8 +5201,13 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5201 } 5201 }
5202#endif 5202#endif
5203 5203
5204 if (it.vpos < w->current_matrix->nrows 5204 /* IT's vpos counts from the glyph row that includes the window's
5205 && (row = MATRIX_ROW (w->current_matrix, it.vpos), 5205 start position, i.e. it excludes the header-line row, but
5206 MATRIX_ROW includes the header-line row. Adjust for a possible
5207 header-line row. */
5208 it_vpos = it.vpos + WINDOW_WANTS_MODELINE_P (w);
5209 if (it_vpos < w->current_matrix->nrows
5210 && (row = MATRIX_ROW (w->current_matrix, it_vpos),
5206 row->enabled_p)) 5211 row->enabled_p))
5207 { 5212 {
5208 if (it.hpos < row->used[TEXT_AREA]) 5213 if (it.hpos < row->used[TEXT_AREA])
@@ -5606,16 +5611,13 @@ the currently selected frame. In batch mode, STRING is sent to stdout
5606when TERMINAL is nil. */) 5611when TERMINAL is nil. */)
5607 (Lisp_Object string, Lisp_Object terminal) 5612 (Lisp_Object string, Lisp_Object terminal)
5608{ 5613{
5609 struct terminal *t = get_terminal (terminal, 1); 5614 struct terminal *t = decode_live_terminal (terminal);
5610 FILE *out; 5615 FILE *out;
5611 5616
5612 /* ??? Perhaps we should do something special for multibyte strings here. */ 5617 /* ??? Perhaps we should do something special for multibyte strings here. */
5613 CHECK_STRING (string); 5618 CHECK_STRING (string);
5614 block_input (); 5619 block_input ();
5615 5620
5616 if (!t)
5617 error ("Unknown terminal device");
5618
5619 if (t->type == output_initial) 5621 if (t->type == output_initial)
5620 out = stdout; 5622 out = stdout;
5621 else if (t->type != output_termcap && t->type != output_msdos_raw) 5623 else if (t->type != output_termcap && t->type != output_msdos_raw)
@@ -6095,15 +6097,12 @@ init_display (void)
6095 (*initial_terminal->delete_terminal_hook) (initial_terminal); 6097 (*initial_terminal->delete_terminal_hook) (initial_terminal);
6096 6098
6097 /* Update frame parameters to reflect the new type. */ 6099 /* Update frame parameters to reflect the new type. */
6098 Fmodify_frame_parameters 6100 AUTO_FRAME_ARG (tty_type_arg, Qtty_type, Ftty_type (selected_frame));
6099 (selected_frame, list1 (Fcons (Qtty_type, 6101 Fmodify_frame_parameters (selected_frame, tty_type_arg);
6100 Ftty_type (selected_frame)))); 6102 AUTO_FRAME_ARG (tty_arg, Qtty, (t->display_info.tty->name
6101 if (t->display_info.tty->name) 6103 ? build_string (t->display_info.tty->name)
6102 Fmodify_frame_parameters 6104 : Qnil));
6103 (selected_frame, 6105 Fmodify_frame_parameters (selected_frame, tty_arg);
6104 list1 (Fcons (Qtty, build_string (t->display_info.tty->name))));
6105 else
6106 Fmodify_frame_parameters (selected_frame, list1 (Fcons (Qtty, Qnil)));
6107 } 6106 }
6108 6107
6109 { 6108 {
diff --git a/src/doc.c b/src/doc.c
index df8cfba3f2a..1b87c23e949 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -121,8 +121,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
121 if (minsize < 8) 121 if (minsize < 8)
122 minsize = 8; 122 minsize = 8;
123 name = SAFE_ALLOCA (minsize + SCHARS (file) + 8); 123 name = SAFE_ALLOCA (minsize + SCHARS (file) + 8);
124 strcpy (name, SSDATA (docdir)); 124 char *z = lispstpcpy (name, docdir);
125 strcat (name, SSDATA (file)); 125 strcpy (z, SSDATA (file));
126 } 126 }
127 else 127 else
128 { 128 {
@@ -146,8 +146,9 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
146 if (fd < 0) 146 if (fd < 0)
147 { 147 {
148 SAFE_FREE (); 148 SAFE_FREE ();
149 return concat3 (build_string ("Cannot open doc string file \""), 149 AUTO_STRING (cannot_open, "Cannot open doc string file \"");
150 file, build_string ("\"\n")); 150 AUTO_STRING (quote_nl, "\"\n");
151 return concat3 (cannot_open, file, quote_nl);
151 } 152 }
152 } 153 }
153 count = SPECPDL_INDEX (); 154 count = SPECPDL_INDEX ();
@@ -561,6 +562,8 @@ the same file name is found in the `doc-directory'. */)
561 char *p, *name; 562 char *p, *name;
562 bool skip_file = 0; 563 bool skip_file = 0;
563 ptrdiff_t count; 564 ptrdiff_t count;
565 char const *dirname;
566 ptrdiff_t dirlen;
564 /* Preloaded defcustoms using custom-initialize-delay are added to 567 /* Preloaded defcustoms using custom-initialize-delay are added to
565 this list, but kept unbound. See http://debbugs.gnu.org/11565 */ 568 this list, but kept unbound. See http://debbugs.gnu.org/11565 */
566 Lisp_Object delayed_init = 569 Lisp_Object delayed_init =
@@ -577,15 +580,21 @@ the same file name is found in the `doc-directory'. */)
577 (0) 580 (0)
578#endif /* CANNOT_DUMP */ 581#endif /* CANNOT_DUMP */
579 { 582 {
580 name = alloca (SCHARS (filename) + 14); 583 static char const sibling_etc[] = "../etc/";
581 strcpy (name, "../etc/"); 584 dirname = sibling_etc;
585 dirlen = sizeof sibling_etc - 1;
582 } 586 }
583 else 587 else
584 { 588 {
585 CHECK_STRING (Vdoc_directory); 589 CHECK_STRING (Vdoc_directory);
586 name = alloca (SCHARS (filename) + SCHARS (Vdoc_directory) + 1); 590 dirname = SSDATA (Vdoc_directory);
587 strcpy (name, SSDATA (Vdoc_directory)); 591 dirlen = SBYTES (Vdoc_directory);
588 } 592 }
593
594 count = SPECPDL_INDEX ();
595 USE_SAFE_ALLOCA;
596 name = SAFE_ALLOCA (dirlen + SBYTES (filename) + 1);
597 strcpy (name, dirname);
589 strcat (name, SSDATA (filename)); /*** Add this line ***/ 598 strcat (name, SSDATA (filename)); /*** Add this line ***/
590 599
591 /* Vbuild_files is nil when temacs is run, and non-nil after that. */ 600 /* Vbuild_files is nil when temacs is run, and non-nil after that. */
@@ -608,7 +617,6 @@ the same file name is found in the `doc-directory'. */)
608 report_file_errno ("Opening doc string file", build_string (name), 617 report_file_errno ("Opening doc string file", build_string (name),
609 open_errno); 618 open_errno);
610 } 619 }
611 count = SPECPDL_INDEX ();
612 record_unwind_protect_int (close_file_unwind, fd); 620 record_unwind_protect_int (close_file_unwind, fd);
613 Vdoc_file_name = filename; 621 Vdoc_file_name = filename;
614 filled = 0; 622 filled = 0;
@@ -637,7 +645,7 @@ the same file name is found in the `doc-directory'. */)
637 && (end[-1] == 'o' || end[-1] == 'c')) 645 && (end[-1] == 'o' || end[-1] == 'c'))
638 { 646 {
639 ptrdiff_t len = end - p - 2; 647 ptrdiff_t len = end - p - 2;
640 char *fromfile = alloca (len + 1); 648 char *fromfile = SAFE_ALLOCA (len + 1);
641 memcpy (fromfile, &p[2], len); 649 memcpy (fromfile, &p[2], len);
642 fromfile[len] = 0; 650 fromfile[len] = 0;
643 if (fromfile[len-1] == 'c') 651 if (fromfile[len-1] == 'c')
@@ -688,6 +696,8 @@ the same file name is found in the `doc-directory'. */)
688 filled -= end - buf; 696 filled -= end - buf;
689 memmove (buf, end, filled); 697 memmove (buf, end, filled);
690 } 698 }
699
700 SAFE_FREE ();
691 return unbind_to (count, Qnil); 701 return unbind_to (count, Qnil);
692} 702}
693 703
diff --git a/src/editfns.c b/src/editfns.c
index a906aead09a..be1062dbbc5 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -64,11 +64,17 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
64extern Lisp_Object w32_get_internal_run_time (void); 64extern Lisp_Object w32_get_internal_run_time (void);
65#endif 65#endif
66 66
67static void set_time_zone_rule (char const *);
67static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec, 68static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec,
68 bool, struct tm *); 69 bool, struct tm *);
70static long int tm_gmtoff (struct tm *);
69static int tm_diff (struct tm *, struct tm *); 71static int tm_diff (struct tm *, struct tm *);
70static void update_buffer_properties (ptrdiff_t, ptrdiff_t); 72static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
71 73
74#ifndef HAVE_TM_GMTOFF
75# define HAVE_TM_GMTOFF false
76#endif
77
72static Lisp_Object Qbuffer_access_fontify_functions; 78static Lisp_Object Qbuffer_access_fontify_functions;
73 79
74/* Symbol for the text property used to mark fields. */ 80/* Symbol for the text property used to mark fields. */
@@ -79,15 +85,12 @@ Lisp_Object Qfield;
79 85
80static Lisp_Object Qboundary; 86static Lisp_Object Qboundary;
81 87
82/* The startup value of the TZ environment variable so it can be 88/* The startup value of the TZ environment variable; null if unset. */
83 restored if the user calls set-time-zone-rule with a nil
84 argument. If null, the TZ environment variable was unset. */
85static char const *initial_tz; 89static char const *initial_tz;
86 90
87/* True if the static variable tzvalbuf (defined in 91/* A valid but unlikely setting for the TZ environment variable.
88 set_time_zone_rule) is part of 'environ'. */ 92 It is OK (though a bit slower) if the user chooses this value. */
89static bool tzvalbuf_in_environ; 93static char dump_tz_string[] = "TZ=UtC0";
90
91 94
92void 95void
93init_editfns (void) 96init_editfns (void)
@@ -101,13 +104,38 @@ init_editfns (void)
101 init_system_name (); 104 init_system_name ();
102 105
103#ifndef CANNOT_DUMP 106#ifndef CANNOT_DUMP
104 /* Don't bother with this on initial start when just dumping out */ 107 /* When just dumping out, set the time zone to a known unlikely value
108 and skip the rest of this function. */
105 if (!initialized) 109 if (!initialized)
106 return; 110 {
107#endif /* not CANNOT_DUMP */ 111# ifdef HAVE_TZSET
112 xputenv (dump_tz_string);
113 tzset ();
114# endif
115 return;
116 }
117#endif
108 118
109 initial_tz = getenv ("TZ"); 119 char *tz = getenv ("TZ");
110 tzvalbuf_in_environ = 0; 120 initial_tz = tz;
121
122#if !defined CANNOT_DUMP && defined HAVE_TZSET
123 /* If the execution TZ happens to be the same as the dump TZ,
124 change it to some other value and then change it back,
125 to force the underlying implementation to reload the TZ info.
126 This is needed on implementations that load TZ info from files,
127 since the TZ file contents may differ between dump and execution. */
128 if (tz && strcmp (tz, &dump_tz_string[sizeof "TZ=" - 1]) == 0)
129 {
130 ++*tz;
131 tzset ();
132 --*tz;
133 }
134#endif
135
136 /* Call set_time_zone_rule now, so that its call to putenv is done
137 before multiple threads are active. */
138 set_time_zone_rule (tz);
111 139
112 pw = getpwuid (getuid ()); 140 pw = getpwuid (getuid ());
113#ifdef MSDOS 141#ifdef MSDOS
@@ -376,13 +404,14 @@ at POSITION. */)
376 set_buffer_temp (XBUFFER (object)); 404 set_buffer_temp (XBUFFER (object));
377 405
378 /* First try with room for 40 overlays. */ 406 /* First try with room for 40 overlays. */
379 noverlays = 40; 407 Lisp_Object overlay_vecbuf[40];
380 overlay_vec = alloca (noverlays * sizeof *overlay_vec); 408 noverlays = ARRAYELTS (overlay_vecbuf);
409 overlay_vec = overlay_vecbuf;
381 noverlays = overlays_around (posn, overlay_vec, noverlays); 410 noverlays = overlays_around (posn, overlay_vec, noverlays);
382 411
383 /* If there are more than 40, 412 /* If there are more than 40,
384 make enough space for all, and try again. */ 413 make enough space for all, and try again. */
385 if (noverlays > 40) 414 if (ARRAYELTS (overlay_vecbuf) < noverlays)
386 { 415 {
387 SAFE_ALLOCA_LISP (overlay_vec, noverlays); 416 SAFE_ALLOCA_LISP (overlay_vec, noverlays);
388 noverlays = overlays_around (posn, overlay_vec, noverlays); 417 noverlays = overlays_around (posn, overlay_vec, noverlays);
@@ -1325,17 +1354,16 @@ name, or nil if there is no such user. */)
1325 /* Substitute the login name for the &, upcasing the first character. */ 1354 /* Substitute the login name for the &, upcasing the first character. */
1326 if (q) 1355 if (q)
1327 { 1356 {
1328 register char *r; 1357 Lisp_Object login = Fuser_login_name (make_number (pw->pw_uid));
1329 Lisp_Object login; 1358 USE_SAFE_ALLOCA;
1330 1359 char *r = SAFE_ALLOCA (strlen (p) + SBYTES (login) + 1);
1331 login = Fuser_login_name (make_number (pw->pw_uid));
1332 r = alloca (strlen (p) + SCHARS (login) + 1);
1333 memcpy (r, p, q - p); 1360 memcpy (r, p, q - p);
1334 r[q - p] = 0; 1361 r[q - p] = 0;
1335 strcat (r, SSDATA (login)); 1362 strcat (r, SSDATA (login));
1336 r[q - p] = upcase ((unsigned char) r[q - p]); 1363 r[q - p] = upcase ((unsigned char) r[q - p]);
1337 strcat (r, q + 1); 1364 strcat (r, q + 1);
1338 full = build_string (r); 1365 full = build_string (r);
1366 SAFE_FREE ();
1339 } 1367 }
1340#endif /* AMPERSAND_FULL_NAME */ 1368#endif /* AMPERSAND_FULL_NAME */
1341 1369
@@ -1373,6 +1401,30 @@ time_overflow (void)
1373 error ("Specified time is not representable"); 1401 error ("Specified time is not representable");
1374} 1402}
1375 1403
1404/* A substitute for mktime_z on platforms that lack it. It's not
1405 thread-safe, but should be good enough for Emacs in typical use. */
1406#ifndef HAVE_TZALLOC
1407time_t
1408mktime_z (timezone_t tz, struct tm *tm)
1409{
1410 char *oldtz = getenv ("TZ");
1411 USE_SAFE_ALLOCA;
1412 if (oldtz)
1413 {
1414 size_t oldtzsize = strlen (oldtz) + 1;
1415 char *oldtzcopy = SAFE_ALLOCA (oldtzsize);
1416 oldtz = strcpy (oldtzcopy, oldtz);
1417 }
1418 block_input ();
1419 set_time_zone_rule (tz);
1420 time_t t = mktime (tm);
1421 set_time_zone_rule (oldtz);
1422 unblock_input ();
1423 SAFE_FREE ();
1424 return t;
1425}
1426#endif
1427
1376/* Return the upper part of the time T (everything but the bottom 16 bits). */ 1428/* Return the upper part of the time T (everything but the bottom 16 bits). */
1377static EMACS_INT 1429static EMACS_INT
1378hi_time (time_t t) 1430hi_time (time_t t)
@@ -1768,39 +1820,28 @@ format_time_string (char const *format, ptrdiff_t formatlen,
1768 size_t len; 1820 size_t len;
1769 Lisp_Object bufstring; 1821 Lisp_Object bufstring;
1770 int ns = t.tv_nsec; 1822 int ns = t.tv_nsec;
1771 struct tm *tm;
1772 USE_SAFE_ALLOCA; 1823 USE_SAFE_ALLOCA;
1773 1824
1774 while (1) 1825 tmp = ut ? gmtime_r (&t.tv_sec, tmp) : localtime_r (&t.tv_sec, tmp);
1775 { 1826 if (! tmp)
1776 time_t *taddr = &t.tv_sec; 1827 time_overflow ();
1777 block_input (); 1828 synchronize_system_time_locale ();
1778
1779 synchronize_system_time_locale ();
1780
1781 tm = ut ? gmtime (taddr) : localtime (taddr);
1782 if (! tm)
1783 {
1784 unblock_input ();
1785 time_overflow ();
1786 }
1787 *tmp = *tm;
1788 1829
1830 while (true)
1831 {
1789 buf[0] = '\1'; 1832 buf[0] = '\1';
1790 len = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns); 1833 len = emacs_nmemftime (buf, size, format, formatlen, tmp, ut, ns);
1791 if ((0 < len && len < size) || (len == 0 && buf[0] == '\0')) 1834 if ((0 < len && len < size) || (len == 0 && buf[0] == '\0'))
1792 break; 1835 break;
1793 1836
1794 /* Buffer was too small, so make it bigger and try again. */ 1837 /* Buffer was too small, so make it bigger and try again. */
1795 len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tm, ut, ns); 1838 len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, ut, ns);
1796 unblock_input ();
1797 if (STRING_BYTES_BOUND <= len) 1839 if (STRING_BYTES_BOUND <= len)
1798 string_overflow (); 1840 string_overflow ();
1799 size = len + 1; 1841 size = len + 1;
1800 buf = SAFE_ALLOCA (size); 1842 buf = SAFE_ALLOCA (size);
1801 } 1843 }
1802 1844
1803 unblock_input ();
1804 bufstring = make_unibyte_string (buf, len); 1845 bufstring = make_unibyte_string (buf, len);
1805 SAFE_FREE (); 1846 SAFE_FREE ();
1806 return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0); 1847 return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0);
@@ -1824,38 +1865,30 @@ DOW and ZONE.) */)
1824 (Lisp_Object specified_time) 1865 (Lisp_Object specified_time)
1825{ 1866{
1826 time_t time_spec = lisp_seconds_argument (specified_time); 1867 time_t time_spec = lisp_seconds_argument (specified_time);
1827 struct tm save_tm; 1868 struct tm local_tm, gmt_tm;
1828 struct tm *decoded_time;
1829 Lisp_Object list_args[9];
1830 1869
1831 block_input (); 1870 if (! (localtime_r (&time_spec, &local_tm)
1832 decoded_time = localtime (&time_spec); 1871 && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
1833 if (decoded_time) 1872 && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
1834 save_tm = *decoded_time;
1835 unblock_input ();
1836 if (! (decoded_time
1837 && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= save_tm.tm_year
1838 && save_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
1839 time_overflow (); 1873 time_overflow ();
1840 XSETFASTINT (list_args[0], save_tm.tm_sec);
1841 XSETFASTINT (list_args[1], save_tm.tm_min);
1842 XSETFASTINT (list_args[2], save_tm.tm_hour);
1843 XSETFASTINT (list_args[3], save_tm.tm_mday);
1844 XSETFASTINT (list_args[4], save_tm.tm_mon + 1);
1845 /* On 64-bit machines an int is narrower than EMACS_INT, thus the
1846 cast below avoids overflow in int arithmetics. */
1847 XSETINT (list_args[5], TM_YEAR_BASE + (EMACS_INT) save_tm.tm_year);
1848 XSETFASTINT (list_args[6], save_tm.tm_wday);
1849 list_args[7] = save_tm.tm_isdst ? Qt : Qnil;
1850 1874
1851 block_input (); 1875 /* Avoid overflow when INT_MAX < EMACS_INT_MAX. */
1852 decoded_time = gmtime (&time_spec); 1876 EMACS_INT tm_year_base = TM_YEAR_BASE;
1853 if (decoded_time == 0) 1877
1854 list_args[8] = Qnil; 1878 return Flist (9, ((Lisp_Object [])
1855 else 1879 {make_number (local_tm.tm_sec),
1856 XSETINT (list_args[8], tm_diff (&save_tm, decoded_time)); 1880 make_number (local_tm.tm_min),
1857 unblock_input (); 1881 make_number (local_tm.tm_hour),
1858 return Flist (9, list_args); 1882 make_number (local_tm.tm_mday),
1883 make_number (local_tm.tm_mon + 1),
1884 make_number (local_tm.tm_year + tm_year_base),
1885 make_number (local_tm.tm_wday),
1886 local_tm.tm_isdst ? Qt : Qnil,
1887 (HAVE_TM_GMTOFF
1888 ? make_number (tm_gmtoff (&local_tm))
1889 : gmtime_r (&time_spec, &gmt_tm)
1890 ? make_number (tm_diff (&local_tm, &gmt_tm))
1891 : Qnil)}));
1859} 1892}
1860 1893
1861/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that 1894/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that
@@ -1911,18 +1944,12 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1911 if (CONSP (zone)) 1944 if (CONSP (zone))
1912 zone = XCAR (zone); 1945 zone = XCAR (zone);
1913 if (NILP (zone)) 1946 if (NILP (zone))
1914 { 1947 value = mktime (&tm);
1915 block_input ();
1916 value = mktime (&tm);
1917 unblock_input ();
1918 }
1919 else 1948 else
1920 { 1949 {
1921 static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; 1950 static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d";
1922 char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; 1951 char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)];
1923 char *old_tzstring;
1924 const char *tzstring; 1952 const char *tzstring;
1925 USE_SAFE_ALLOCA;
1926 1953
1927 if (EQ (zone, Qt)) 1954 if (EQ (zone, Qt))
1928 tzstring = "UTC0"; 1955 tzstring = "UTC0";
@@ -1939,29 +1966,13 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1939 tzstring = tzbuf; 1966 tzstring = tzbuf;
1940 } 1967 }
1941 else 1968 else
1942 error ("Invalid time zone specification"); 1969 tzstring = 0;
1943
1944 old_tzstring = getenv ("TZ");
1945 if (old_tzstring)
1946 {
1947 char *buf = SAFE_ALLOCA (strlen (old_tzstring) + 1);
1948 old_tzstring = strcpy (buf, old_tzstring);
1949 }
1950
1951 block_input ();
1952
1953 /* Set TZ before calling mktime; merely adjusting mktime's returned
1954 value doesn't suffice, since that would mishandle leap seconds. */
1955 set_time_zone_rule (tzstring);
1956
1957 value = mktime (&tm);
1958 1970
1959 set_time_zone_rule (old_tzstring); 1971 timezone_t tz = tzstring ? tzalloc (tzstring) : 0;
1960#ifdef LOCALTIME_CACHE 1972 if (! tz)
1961 tzset (); 1973 error ("Invalid time zone specification");
1962#endif 1974 value = mktime_z (tz, &tm);
1963 unblock_input (); 1975 tzfree (tz);
1964 SAFE_FREE ();
1965 } 1976 }
1966 1977
1967 if (value == (time_t) -1) 1978 if (value == (time_t) -1)
@@ -1987,34 +1998,27 @@ but this is considered obsolete. */)
1987 (Lisp_Object specified_time) 1998 (Lisp_Object specified_time)
1988{ 1999{
1989 time_t value = lisp_seconds_argument (specified_time); 2000 time_t value = lisp_seconds_argument (specified_time);
1990 struct tm *tm;
1991 char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1];
1992 int len IF_LINT (= 0);
1993 2001
1994 /* Convert to a string in ctime format, except without the trailing 2002 /* Convert to a string in ctime format, except without the trailing
1995 newline, and without the 4-digit year limit. Don't use asctime 2003 newline, and without the 4-digit year limit. Don't use asctime
1996 or ctime, as they might dump core if the year is outside the 2004 or ctime, as they might dump core if the year is outside the
1997 range -999 .. 9999. */ 2005 range -999 .. 9999. */
1998 block_input (); 2006 struct tm tm;
1999 tm = localtime (&value); 2007 if (! localtime_r (&value, &tm))
2000 if (tm)
2001 {
2002 static char const wday_name[][4] =
2003 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
2004 static char const mon_name[][4] =
2005 { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2006 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
2007 printmax_t year_base = TM_YEAR_BASE;
2008
2009 len = sprintf (buf, "%s %s%3d %02d:%02d:%02d %"pMd,
2010 wday_name[tm->tm_wday], mon_name[tm->tm_mon], tm->tm_mday,
2011 tm->tm_hour, tm->tm_min, tm->tm_sec,
2012 tm->tm_year + year_base);
2013 }
2014 unblock_input ();
2015 if (! tm)
2016 time_overflow (); 2008 time_overflow ();
2017 2009
2010 static char const wday_name[][4] =
2011 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
2012 static char const mon_name[][4] =
2013 { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2014 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
2015 printmax_t year_base = TM_YEAR_BASE;
2016 char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1];
2017 int len = sprintf (buf, "%s %s%3d %02d:%02d:%02d %"pMd,
2018 wday_name[tm.tm_wday], mon_name[tm.tm_mon], tm.tm_mday,
2019 tm.tm_hour, tm.tm_min, tm.tm_sec,
2020 tm.tm_year + year_base);
2021
2018 return make_unibyte_string (buf, len); 2022 return make_unibyte_string (buf, len);
2019} 2023}
2020 2024
@@ -2041,6 +2045,17 @@ tm_diff (struct tm *a, struct tm *b)
2041 + (a->tm_sec - b->tm_sec)); 2045 + (a->tm_sec - b->tm_sec));
2042} 2046}
2043 2047
2048/* Yield A's UTC offset, or an unspecified value if unknown. */
2049static long int
2050tm_gmtoff (struct tm *a)
2051{
2052#if HAVE_TM_GMTOFF
2053 return a->tm_gmtoff;
2054#else
2055 return 0;
2056#endif
2057}
2058
2044DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0, 2059DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0,
2045 doc: /* Return the offset and name for the local time zone. 2060 doc: /* Return the offset and name for the local time zone.
2046This returns a list of the form (OFFSET NAME). 2061This returns a list of the form (OFFSET NAME).
@@ -2059,32 +2074,30 @@ the data it can't find. */)
2059 (Lisp_Object specified_time) 2074 (Lisp_Object specified_time)
2060{ 2075{
2061 struct timespec value; 2076 struct timespec value;
2062 int offset; 2077 struct tm local_tm, gmt_tm;
2063 struct tm *t;
2064 struct tm localtm;
2065 Lisp_Object zone_offset, zone_name; 2078 Lisp_Object zone_offset, zone_name;
2066 2079
2067 zone_offset = Qnil; 2080 zone_offset = Qnil;
2068 value = make_timespec (lisp_seconds_argument (specified_time), 0); 2081 value = make_timespec (lisp_seconds_argument (specified_time), 0);
2069 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm); 2082 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &local_tm);
2070 block_input ();
2071 t = gmtime (&value.tv_sec);
2072 if (t)
2073 offset = tm_diff (&localtm, t);
2074 unblock_input ();
2075 2083
2076 if (t) 2084 if (HAVE_TM_GMTOFF || gmtime_r (&value.tv_sec, &gmt_tm))
2077 { 2085 {
2086 long int offset = (HAVE_TM_GMTOFF
2087 ? tm_gmtoff (&local_tm)
2088 : tm_diff (&local_tm, &gmt_tm));
2078 zone_offset = make_number (offset); 2089 zone_offset = make_number (offset);
2079 if (SCHARS (zone_name) == 0) 2090 if (SCHARS (zone_name) == 0)
2080 { 2091 {
2081 /* No local time zone name is available; use "+-NNNN" instead. */ 2092 /* No local time zone name is available; use "+-NNNN" instead. */
2082 int m = offset / 60; 2093 long int m = offset / 60;
2083 int am = offset < 0 ? - m : m; 2094 long int am = offset < 0 ? - m : m;
2084 char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; 2095 long int hour = am / 60;
2085 zone_name = make_formatted_string (buf, "%c%02d%02d", 2096 int min = am % 60;
2097 char buf[sizeof "+00" + INT_STRLEN_BOUND (long int)];
2098 zone_name = make_formatted_string (buf, "%c%02ld%02d",
2086 (offset < 0 ? '-' : '+'), 2099 (offset < 0 ? '-' : '+'),
2087 am / 60, am % 60); 2100 hour, min);
2088 } 2101 }
2089 } 2102 }
2090 2103
@@ -2123,12 +2136,12 @@ only the former. */)
2123 2136
2124/* Set the local time zone rule to TZSTRING. 2137/* Set the local time zone rule to TZSTRING.
2125 2138
2126 This function is not thread-safe, partly because putenv, unsetenv 2139 This function is not thread-safe, in theory because putenv is not,
2127 and tzset are not, and partly because of the static storage it 2140 but mostly because of the static storage it updates. Other threads
2128 updates. Other threads that invoke localtime etc. may be adversely 2141 that invoke localtime etc. may be adversely affected while this
2129 affected while this function is executing. */ 2142 function is executing. */
2130 2143
2131void 2144static void
2132set_time_zone_rule (const char *tzstring) 2145set_time_zone_rule (const char *tzstring)
2133{ 2146{
2134 /* A buffer holding a string of the form "TZ=value", intended 2147 /* A buffer holding a string of the form "TZ=value", intended
@@ -2137,75 +2150,47 @@ set_time_zone_rule (const char *tzstring)
2137 static ptrdiff_t tzvalbufsize; 2150 static ptrdiff_t tzvalbufsize;
2138 2151
2139 int tzeqlen = sizeof "TZ=" - 1; 2152 int tzeqlen = sizeof "TZ=" - 1;
2153 ptrdiff_t tzstringlen = tzstring ? strlen (tzstring) : 0;
2154 char *tzval = tzvalbuf;
2155 bool new_tzvalbuf = tzvalbufsize <= tzeqlen + tzstringlen;
2140 2156
2141#ifdef LOCALTIME_CACHE 2157 if (new_tzvalbuf)
2142 /* These two values are known to load tz files in buggy implementations, 2158 {
2143 i.e., Solaris 1 executables running under either Solaris 1 or Solaris 2. 2159 /* Do not attempt to free the old tzvalbuf, since another thread
2144 Their values shouldn't matter in non-buggy implementations. 2160 may be using it. In practice, the first allocation is large
2145 We don't use string literals for these strings, 2161 enough and memory does not leak. */
2146 since if a string in the environment is in readonly 2162 tzval = xpalloc (NULL, &tzvalbufsize,
2147 storage, it runs afoul of bugs in SVR4 and Solaris 2.3. 2163 tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1);
2148 See Sun bugs 1113095 and 1114114, ``Timezone routines 2164 tzvalbuf = tzval;
2149 improperly modify environment''. */ 2165 tzval[1] = 'Z';
2150 2166 tzval[2] = '=';
2151 static char set_time_zone_rule_tz[][sizeof "TZ=GMT+0"] 2167 }
2152 = { "TZ=GMT+0", "TZ=GMT+1" };
2153
2154 /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
2155 "US/Pacific" that loads a tz file, then changes to a value like
2156 "XXX0" that does not load a tz file, and then changes back to
2157 its original value, the last change is (incorrectly) ignored.
2158 Also, if TZ changes twice in succession to values that do
2159 not load a tz file, tzset can dump core (see Sun bug#1225179).
2160 The following code works around these bugs. */
2161 2168
2162 if (tzstring) 2169 if (tzstring)
2163 { 2170 {
2164 /* Temporarily set TZ to a value that loads a tz file 2171 /* Modify TZVAL in place. Although this is dicey in a
2165 and that differs from tzstring. */ 2172 multithreaded environment, we know of no portable alternative.
2166 bool eq0 = strcmp (tzstring, set_time_zone_rule_tz[0] + tzeqlen) == 0; 2173 Calling putenv or setenv could crash some other thread. */
2167 xputenv (set_time_zone_rule_tz[eq0]); 2174 tzval[0] = 'T';
2175 strcpy (tzval + tzeqlen, tzstring);
2168 } 2176 }
2169 else 2177 else
2170 { 2178 {
2171 /* The implied tzstring is unknown, so temporarily set TZ to 2179 /* Turn 'TZ=whatever' into an empty environment variable 'tZ='.
2172 two different values that each load a tz file. */ 2180 Although this is also dicey, calling unsetenv here can crash Emacs.
2173 xputenv (set_time_zone_rule_tz[0]); 2181 See Bug#8705. */
2174 tzset (); 2182 tzval[0] = 't';
2175 xputenv (set_time_zone_rule_tz[1]); 2183 tzval[tzeqlen] = 0;
2176 } 2184 }
2177 tzset ();
2178 tzvalbuf_in_environ = 0;
2179#endif
2180 2185
2181 if (!tzstring) 2186 if (new_tzvalbuf)
2182 { 2187 {
2183 unsetenv ("TZ"); 2188 /* Although this is not thread-safe, in practice this runs only
2184 tzvalbuf_in_environ = 0; 2189 on startup when there is only one thread. */
2185 } 2190 xputenv (tzval);
2186 else
2187 {
2188 ptrdiff_t tzstringlen = strlen (tzstring);
2189
2190 if (tzvalbufsize <= tzeqlen + tzstringlen)
2191 {
2192 unsetenv ("TZ");
2193 tzvalbuf_in_environ = 0;
2194 tzvalbuf = xpalloc (tzvalbuf, &tzvalbufsize,
2195 tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1);
2196 memcpy (tzvalbuf, "TZ=", tzeqlen);
2197 }
2198
2199 strcpy (tzvalbuf + tzeqlen, tzstring);
2200
2201 if (!tzvalbuf_in_environ)
2202 {
2203 xputenv (tzvalbuf);
2204 tzvalbuf_in_environ = 1;
2205 }
2206 } 2191 }
2207 2192
2208#ifdef LOCALTIME_CACHE 2193#ifdef HAVE_TZSET
2209 tzset (); 2194 tzset ();
2210#endif 2195#endif
2211} 2196}
@@ -3012,8 +2997,12 @@ static Lisp_Object
3012check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end, 2997check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end,
3013 Lisp_Object val) 2998 Lisp_Object val)
3014{ 2999{
3015 int buf_size = 16, buf_used = 0; 3000 int initial_buf[16];
3016 int *buf = alloca (sizeof (int) * buf_size); 3001 int *buf = initial_buf;
3002 ptrdiff_t buf_size = ARRAYELTS (initial_buf);
3003 int *bufalloc = 0;
3004 ptrdiff_t buf_used = 0;
3005 Lisp_Object result = Qnil;
3017 3006
3018 for (; CONSP (val); val = XCDR (val)) 3007 for (; CONSP (val); val = XCDR (val))
3019 { 3008 {
@@ -3038,12 +3027,11 @@ check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end,
3038 3027
3039 if (buf_used == buf_size) 3028 if (buf_used == buf_size)
3040 { 3029 {
3041 int *newbuf; 3030 bufalloc = xpalloc (bufalloc, &buf_size, 1, -1,
3042 3031 sizeof *bufalloc);
3043 buf_size += 16; 3032 if (buf == initial_buf)
3044 newbuf = alloca (sizeof (int) * buf_size); 3033 memcpy (bufalloc, buf, sizeof initial_buf);
3045 memcpy (newbuf, buf, sizeof (int) * buf_used); 3034 buf = bufalloc;
3046 buf = newbuf;
3047 } 3035 }
3048 buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, len1); 3036 buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, len1);
3049 pos_byte += len1; 3037 pos_byte += len1;
@@ -3052,10 +3040,15 @@ check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end,
3052 break; 3040 break;
3053 } 3041 }
3054 if (i == len) 3042 if (i == len)
3055 return XCAR (val); 3043 {
3044 result = XCAR (val);
3045 break;
3046 }
3056 } 3047 }
3057 } 3048 }
3058 return Qnil; 3049
3050 xfree (bufalloc);
3051 return result;
3059} 3052}
3060 3053
3061 3054
@@ -4354,11 +4347,8 @@ usage: (format STRING &rest OBJECTS) */)
4354Lisp_Object 4347Lisp_Object
4355format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1) 4348format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1)
4356{ 4349{
4357 Lisp_Object args[3]; 4350 AUTO_STRING (format, string1);
4358 args[0] = build_string (string1); 4351 return Fformat (3, (Lisp_Object []) {format, arg0, arg1});
4359 args[1] = arg0;
4360 args[2] = arg1;
4361 return Fformat (3, args);
4362} 4352}
4363 4353
4364DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0, 4354DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
@@ -4617,11 +4607,11 @@ Transposing beyond buffer boundaries is an error. */)
4617 if (tmp_interval3) 4607 if (tmp_interval3)
4618 set_text_properties_1 (startr1, endr2, Qnil, buf, tmp_interval3); 4608 set_text_properties_1 (startr1, endr2, Qnil, buf, tmp_interval3);
4619 4609
4610 USE_SAFE_ALLOCA;
4611
4620 /* First region smaller than second. */ 4612 /* First region smaller than second. */
4621 if (len1_byte < len2_byte) 4613 if (len1_byte < len2_byte)
4622 { 4614 {
4623 USE_SAFE_ALLOCA;
4624
4625 temp = SAFE_ALLOCA (len2_byte); 4615 temp = SAFE_ALLOCA (len2_byte);
4626 4616
4627 /* Don't precompute these addresses. We have to compute them 4617 /* Don't precompute these addresses. We have to compute them
@@ -4633,21 +4623,19 @@ Transposing beyond buffer boundaries is an error. */)
4633 memcpy (temp, start2_addr, len2_byte); 4623 memcpy (temp, start2_addr, len2_byte);
4634 memcpy (start1_addr + len2_byte, start1_addr, len1_byte); 4624 memcpy (start1_addr + len2_byte, start1_addr, len1_byte);
4635 memcpy (start1_addr, temp, len2_byte); 4625 memcpy (start1_addr, temp, len2_byte);
4636 SAFE_FREE ();
4637 } 4626 }
4638 else 4627 else
4639 /* First region not smaller than second. */ 4628 /* First region not smaller than second. */
4640 { 4629 {
4641 USE_SAFE_ALLOCA;
4642
4643 temp = SAFE_ALLOCA (len1_byte); 4630 temp = SAFE_ALLOCA (len1_byte);
4644 start1_addr = BYTE_POS_ADDR (start1_byte); 4631 start1_addr = BYTE_POS_ADDR (start1_byte);
4645 start2_addr = BYTE_POS_ADDR (start2_byte); 4632 start2_addr = BYTE_POS_ADDR (start2_byte);
4646 memcpy (temp, start1_addr, len1_byte); 4633 memcpy (temp, start1_addr, len1_byte);
4647 memcpy (start1_addr, start2_addr, len2_byte); 4634 memcpy (start1_addr, start2_addr, len2_byte);
4648 memcpy (start1_addr + len2_byte, temp, len1_byte); 4635 memcpy (start1_addr + len2_byte, temp, len1_byte);
4649 SAFE_FREE ();
4650 } 4636 }
4637
4638 SAFE_FREE ();
4651 graft_intervals_into_buffer (tmp_interval1, start1 + len2, 4639 graft_intervals_into_buffer (tmp_interval1, start1 + len2,
4652 len1, current_buffer, 0); 4640 len1, current_buffer, 0);
4653 graft_intervals_into_buffer (tmp_interval2, start1, 4641 graft_intervals_into_buffer (tmp_interval2, start1,
diff --git a/src/emacs.c b/src/emacs.c
index a53b4cfd4ed..90182e53e70 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -83,6 +83,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
83#include "charset.h" 83#include "charset.h"
84#include "composite.h" 84#include "composite.h"
85#include "dispextern.h" 85#include "dispextern.h"
86#include "regex.h"
86#include "syntax.h" 87#include "syntax.h"
87#include "sysselect.h" 88#include "sysselect.h"
88#include "systime.h" 89#include "systime.h"
@@ -145,7 +146,7 @@ extern int malloc_set_state (void *);
145/* True if the MALLOC_CHECK_ environment variable was set while 146/* True if the MALLOC_CHECK_ environment variable was set while
146 dumping. Used to work around a bug in glibc's malloc. */ 147 dumping. Used to work around a bug in glibc's malloc. */
147static bool malloc_using_checking; 148static bool malloc_using_checking;
148#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC 149#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
149extern void malloc_enable_thread (void); 150extern void malloc_enable_thread (void);
150#endif 151#endif
151 152
@@ -395,10 +396,11 @@ terminate_due_to_signal (int sig, int backtrace_limit)
395static void 396static void
396init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd) 397init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
397{ 398{
398 register int i; 399 int i;
399 Lisp_Object name, dir, handler; 400 Lisp_Object name, dir, handler;
400 ptrdiff_t count = SPECPDL_INDEX (); 401 ptrdiff_t count = SPECPDL_INDEX ();
401 Lisp_Object raw_name; 402 Lisp_Object raw_name;
403 AUTO_STRING (slash_colon, "/:");
402 404
403 initial_argv = argv; 405 initial_argv = argv;
404 initial_argc = argc; 406 initial_argc = argc;
@@ -422,7 +424,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
422 if it would otherwise be treated as magic. */ 424 if it would otherwise be treated as magic. */
423 handler = Ffind_file_name_handler (raw_name, Qt); 425 handler = Ffind_file_name_handler (raw_name, Qt);
424 if (! NILP (handler)) 426 if (! NILP (handler))
425 raw_name = concat2 (build_string ("/:"), raw_name); 427 raw_name = concat2 (slash_colon, raw_name);
426 428
427 Vinvocation_name = Ffile_name_nondirectory (raw_name); 429 Vinvocation_name = Ffile_name_nondirectory (raw_name);
428 Vinvocation_directory = Ffile_name_directory (raw_name); 430 Vinvocation_directory = Ffile_name_directory (raw_name);
@@ -440,7 +442,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
440 if it would otherwise be treated as magic. */ 442 if it would otherwise be treated as magic. */
441 handler = Ffind_file_name_handler (found, Qt); 443 handler = Ffind_file_name_handler (found, Qt);
442 if (! NILP (handler)) 444 if (! NILP (handler))
443 found = concat2 (build_string ("/:"), found); 445 found = concat2 (slash_colon, found);
444 Vinvocation_directory = Ffile_name_directory (found); 446 Vinvocation_directory = Ffile_name_directory (found);
445 } 447 }
446 } 448 }
@@ -576,12 +578,6 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
576} 578}
577 579
578 580
579#ifdef HAVE_TZSET
580/* A valid but unlikely value for the TZ environment value.
581 It is OK (though a bit slower) if the user actually chooses this value. */
582static char const dump_tz[] = "UtC0";
583#endif
584
585/* Test whether the next argument in ARGV matches SSTR or a prefix of 581/* Test whether the next argument in ARGV matches SSTR or a prefix of
586 LSTR (at least MINLEN characters). If so, then if VALPTR is non-null 582 LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
587 (the argument is supposed to have a value) store in *VALPTR either 583 (the argument is supposed to have a value) store in *VALPTR either
@@ -734,12 +730,6 @@ main (int argc, char **argv)
734 stack_base = &dummy; 730 stack_base = &dummy;
735#endif 731#endif
736 732
737#ifdef G_SLICE_ALWAYS_MALLOC
738 /* This is used by the Cygwin build. It's not needed starting with
739 cygwin-1.7.24, but it doesn't do any harm. */
740 xputenv ("G_SLICE=always-malloc");
741#endif
742
743#ifndef CANNOT_DUMP 733#ifndef CANNOT_DUMP
744 might_dump = !initialized; 734 might_dump = !initialized;
745#endif 735#endif
@@ -747,9 +737,6 @@ main (int argc, char **argv)
747#ifdef GNU_LINUX 737#ifdef GNU_LINUX
748 if (!initialized) 738 if (!initialized)
749 { 739 {
750 extern char my_endbss[];
751 extern char *my_endbss_static;
752
753 if (my_heap_start == 0) 740 if (my_heap_start == 0)
754 my_heap_start = sbrk (0); 741 my_heap_start = sbrk (0);
755 742
@@ -878,7 +865,6 @@ main (int argc, char **argv)
878 && !getrlimit (RLIMIT_STACK, &rlim)) 865 && !getrlimit (RLIMIT_STACK, &rlim))
879 { 866 {
880 long newlim; 867 long newlim;
881 extern size_t re_max_failures;
882 /* Approximate the amount regex.c needs per unit of re_max_failures. */ 868 /* Approximate the amount regex.c needs per unit of re_max_failures. */
883 int ratio = 20 * sizeof (char *); 869 int ratio = 20 * sizeof (char *);
884 /* Then add 33% to cover the size of the smaller stacks that regex.c 870 /* Then add 33% to cover the size of the smaller stacks that regex.c
@@ -912,7 +898,7 @@ main (int argc, char **argv)
912 898
913 clearerr (stdin); 899 clearerr (stdin);
914 900
915#ifndef SYSTEM_MALLOC 901#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
916 /* Arrange to get warning messages as memory fills up. */ 902 /* Arrange to get warning messages as memory fills up. */
917 memory_warnings (0, malloc_warning); 903 memory_warnings (0, malloc_warning);
918 904
@@ -920,7 +906,7 @@ main (int argc, char **argv)
920 Also call realloc and free for consistency. */ 906 Also call realloc and free for consistency. */
921 free (realloc (malloc (4), 4)); 907 free (realloc (malloc (4), 4));
922 908
923#endif /* not SYSTEM_MALLOC */ 909#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
924 910
925#ifdef MSDOS 911#ifdef MSDOS
926 SET_BINARY (fileno (stdin)); 912 SET_BINARY (fileno (stdin));
@@ -1145,12 +1131,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1145#endif /* DOS_NT */ 1131#endif /* DOS_NT */
1146 } 1132 }
1147 1133
1148#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC 1134#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
1135 && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
1149# ifndef CANNOT_DUMP 1136# ifndef CANNOT_DUMP
1150 /* Do not make gmalloc thread-safe when creating bootstrap-emacs, as 1137 /* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
1151 that causes an infinite recursive loop with FreeBSD. But do make 1138 that causes an infinite recursive loop with FreeBSD. See
1152 it thread-safe when creating emacs, otherwise bootstrap-emacs 1139 Bug#14569. The part of this bug involving Cygwin is no longer
1153 fails on Cygwin. See Bug#14569. */ 1140 relevant, now that Cygwin defines HYBRID_MALLOC. */
1154 if (!noninteractive || initialized) 1141 if (!noninteractive || initialized)
1155# endif 1142# endif
1156 malloc_enable_thread (); 1143 malloc_enable_thread ();
@@ -1555,8 +1542,23 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1555 1542
1556 init_charset (); 1543 init_charset ();
1557 1544
1558 init_editfns (); /* init_process_emacs uses Voperating_system_release. */ 1545 /* This calls putenv and so must precede init_process_emacs. Also,
1559 init_process_emacs (); /* init_display uses add_keyboard_wait_descriptor. */ 1546 it sets Voperating_system_release, which init_process_emacs uses. */
1547 init_editfns ();
1548
1549 /* These two call putenv. */
1550#ifdef HAVE_DBUS
1551 init_dbusbind ();
1552#endif
1553#ifdef USE_GTK
1554 init_xterm ();
1555#endif
1556
1557 /* This can create a thread that may call getenv, so it must follow
1558 all calls to putenv and setenv. Also, this sets up
1559 add_keyboard_wait_descriptor, which init_display uses. */
1560 init_process_emacs ();
1561
1560 init_keyboard (); /* This too must precede init_sys_modes. */ 1562 init_keyboard (); /* This too must precede init_sys_modes. */
1561 if (!noninteractive) 1563 if (!noninteractive)
1562 init_display (); /* Determine terminal type. Calls init_sys_modes. */ 1564 init_display (); /* Determine terminal type. Calls init_sys_modes. */
@@ -1593,26 +1595,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1593 build_string ("loadup.el")); 1595 build_string ("loadup.el"));
1594 } 1596 }
1595 1597
1596 if (initialized)
1597 {
1598#ifdef HAVE_TZSET
1599 {
1600 /* If the execution TZ happens to be the same as the dump TZ,
1601 change it to some other value and then change it back,
1602 to force the underlying implementation to reload the TZ info.
1603 This is needed on implementations that load TZ info from files,
1604 since the TZ file contents may differ between dump and execution. */
1605 char *tz = getenv ("TZ");
1606 if (tz && !strcmp (tz, dump_tz))
1607 {
1608 ++*tz;
1609 tzset ();
1610 --*tz;
1611 }
1612 }
1613#endif
1614 }
1615
1616 /* Set up for profiling. This is known to work on FreeBSD, 1598 /* Set up for profiling. This is known to work on FreeBSD,
1617 GNU/Linux and MinGW. It might work on some other systems too. 1599 GNU/Linux and MinGW. It might work on some other systems too.
1618 Give it a try and tell us if it works on your system. To compile 1600 Give it a try and tell us if it works on your system. To compile
@@ -1637,15 +1619,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1637 1619
1638 initialized = 1; 1620 initialized = 1;
1639 1621
1640#ifdef LOCALTIME_CACHE
1641 /* Some versions of localtime have a bug. They cache the value of the time
1642 zone rather than looking it up every time. Since localtime() is
1643 called to bolt the undumping time into the undumped emacs, this
1644 results in localtime ignoring the TZ environment variable.
1645 This flushes the new TZ value into localtime. */
1646 tzset ();
1647#endif /* defined (LOCALTIME_CACHE) */
1648
1649 /* Enter editor command loop. This never returns. */ 1622 /* Enter editor command loop. This never returns. */
1650 Frecursive_edit (); 1623 Frecursive_edit ();
1651 /* NOTREACHED */ 1624 /* NOTREACHED */
@@ -2126,27 +2099,16 @@ You must run Emacs in batch mode in order to dump it. */)
2126 tem = Vpurify_flag; 2099 tem = Vpurify_flag;
2127 Vpurify_flag = Qnil; 2100 Vpurify_flag = Qnil;
2128 2101
2129#ifdef HAVE_TZSET
2130 set_time_zone_rule (dump_tz);
2131#ifndef LOCALTIME_CACHE
2132 /* Force a tz reload, since set_time_zone_rule doesn't. */
2133 tzset ();
2134#endif
2135#endif
2136
2137 fflush (stdout); 2102 fflush (stdout);
2138 /* Tell malloc where start of impure now is. */ 2103 /* Tell malloc where start of impure now is. */
2139 /* Also arrange for warnings when nearly out of space. */ 2104 /* Also arrange for warnings when nearly out of space. */
2140#ifndef SYSTEM_MALLOC 2105#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
2141#ifndef WINDOWSNT 2106#ifndef WINDOWSNT
2142 /* On Windows, this was done before dumping, and that once suffices. 2107 /* On Windows, this was done before dumping, and that once suffices.
2143 Meanwhile, my_edata is not valid on Windows. */ 2108 Meanwhile, my_edata is not valid on Windows. */
2144 { 2109 memory_warnings (my_edata, malloc_warning);
2145 extern char my_edata[];
2146 memory_warnings (my_edata, malloc_warning);
2147 }
2148#endif /* not WINDOWSNT */ 2110#endif /* not WINDOWSNT */
2149#endif /* not SYSTEM_MALLOC */ 2111#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
2150#ifdef DOUG_LEA_MALLOC 2112#ifdef DOUG_LEA_MALLOC
2151 malloc_state_ptr = malloc_get_state (); 2113 malloc_state_ptr = malloc_get_state ();
2152#endif 2114#endif
@@ -2334,7 +2296,10 @@ decode_env_path (const char *evarname, const char *defalt, bool empty)
2334 } 2296 }
2335 2297
2336 if (! NILP (tem)) 2298 if (! NILP (tem))
2337 element = concat2 (build_string ("/:"), element); 2299 {
2300 AUTO_STRING (slash_colon, "/:");
2301 element = concat2 (slash_colon, element);
2302 }
2338 } /* !NILP (element) */ 2303 } /* !NILP (element) */
2339 2304
2340 lpath = Fcons (element, lpath); 2305 lpath = Fcons (element, lpath);
diff --git a/src/eval.c b/src/eval.c
index 4b2e256a722..77b1db95397 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -104,7 +104,7 @@ union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE;
104union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; 104union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
105 105
106static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); 106static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
107static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); 107static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t);
108 108
109static Lisp_Object 109static Lisp_Object
110specpdl_symbol (union specbinding *pdl) 110specpdl_symbol (union specbinding *pdl)
@@ -172,17 +172,11 @@ backtrace_debug_on_exit (union specbinding *pdl)
172/* Functions to modify slots of backtrace records. */ 172/* Functions to modify slots of backtrace records. */
173 173
174static void 174static void
175set_backtrace_args (union specbinding *pdl, Lisp_Object *args) 175set_backtrace_args (union specbinding *pdl, Lisp_Object *args, ptrdiff_t nargs)
176{ 176{
177 eassert (pdl->kind == SPECPDL_BACKTRACE); 177 eassert (pdl->kind == SPECPDL_BACKTRACE);
178 pdl->bt.args = args; 178 pdl->bt.args = args;
179} 179 pdl->bt.nargs = nargs;
180
181static void
182set_backtrace_nargs (union specbinding *pdl, ptrdiff_t n)
183{
184 eassert (pdl->kind == SPECPDL_BACKTRACE);
185 pdl->bt.nargs = n;
186} 180}
187 181
188static void 182static void
@@ -334,10 +328,10 @@ call_debugger (Lisp_Object arg)
334} 328}
335 329
336static void 330static void
337do_debug_on_call (Lisp_Object code) 331do_debug_on_call (Lisp_Object code, ptrdiff_t count)
338{ 332{
339 debug_on_next_call = 0; 333 debug_on_next_call = 0;
340 set_backtrace_debug_on_exit (specpdl_ptr - 1, true); 334 set_backtrace_debug_on_exit (specpdl + count, true);
341 call_debugger (list1 (code)); 335 call_debugger (list1 (code));
342} 336}
343 337
@@ -1272,8 +1266,11 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1272 1266
1273 { /* The first clause is the one that should be checked first, so it should 1267 { /* The first clause is the one that should be checked first, so it should
1274 be added to handlerlist last. So we build in `clauses' a table that 1268 be added to handlerlist last. So we build in `clauses' a table that
1275 contains `handlers' but in reverse order. */ 1269 contains `handlers' but in reverse order. SAFE_ALLOCA won't work
1276 Lisp_Object *clauses = alloca (clausenb * sizeof (Lisp_Object *)); 1270 here due to the setjmp, so impose a MAX_ALLOCA limit. */
1271 if (MAX_ALLOCA / word_size < clausenb)
1272 memory_full (SIZE_MAX);
1273 Lisp_Object *clauses = alloca (clausenb * sizeof *clauses);
1277 Lisp_Object *volatile clauses_volatile = clauses; 1274 Lisp_Object *volatile clauses_volatile = clauses;
1278 int i = clausenb; 1275 int i = clausenb;
1279 for (val = handlers; CONSP (val); val = XCDR (val)) 1276 for (val = handlers; CONSP (val); val = XCDR (val))
@@ -1311,7 +1308,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1311 return val; 1308 return val;
1312 } 1309 }
1313 } 1310 }
1314 } 1311 }
1315 1312
1316 val = eval_sub (bodyform); 1313 val = eval_sub (bodyform);
1317 handlerlist = oldhandlerlist; 1314 handlerlist = oldhandlerlist;
@@ -2032,9 +2029,11 @@ grow_specpdl (void)
2032 } 2029 }
2033} 2030}
2034 2031
2035void 2032ptrdiff_t
2036record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) 2033record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
2037{ 2034{
2035 ptrdiff_t count = SPECPDL_INDEX ();
2036
2038 eassert (nargs >= UNEVALLED); 2037 eassert (nargs >= UNEVALLED);
2039 specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; 2038 specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
2040 specpdl_ptr->bt.debug_on_exit = false; 2039 specpdl_ptr->bt.debug_on_exit = false;
@@ -2042,6 +2041,8 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
2042 specpdl_ptr->bt.args = args; 2041 specpdl_ptr->bt.args = args;
2043 specpdl_ptr->bt.nargs = nargs; 2042 specpdl_ptr->bt.nargs = nargs;
2044 grow_specpdl (); 2043 grow_specpdl ();
2044
2045 return count;
2045} 2046}
2046 2047
2047/* Eval a sub-expression of the current expression (i.e. in the same 2048/* Eval a sub-expression of the current expression (i.e. in the same
@@ -2052,6 +2053,7 @@ eval_sub (Lisp_Object form)
2052 Lisp_Object fun, val, original_fun, original_args; 2053 Lisp_Object fun, val, original_fun, original_args;
2053 Lisp_Object funcar; 2054 Lisp_Object funcar;
2054 struct gcpro gcpro1, gcpro2, gcpro3; 2055 struct gcpro gcpro1, gcpro2, gcpro3;
2056 ptrdiff_t count;
2055 2057
2056 if (SYMBOLP (form)) 2058 if (SYMBOLP (form))
2057 { 2059 {
@@ -2089,10 +2091,10 @@ eval_sub (Lisp_Object form)
2089 original_args = XCDR (form); 2091 original_args = XCDR (form);
2090 2092
2091 /* This also protects them from gc. */ 2093 /* This also protects them from gc. */
2092 record_in_backtrace (original_fun, &original_args, UNEVALLED); 2094 count = record_in_backtrace (original_fun, &original_args, UNEVALLED);
2093 2095
2094 if (debug_on_next_call) 2096 if (debug_on_next_call)
2095 do_debug_on_call (Qt); 2097 do_debug_on_call (Qt, count);
2096 2098
2097 /* At this point, only original_fun and original_args 2099 /* At this point, only original_fun and original_args
2098 have values that will be used below. */ 2100 have values that will be used below. */
@@ -2144,8 +2146,7 @@ eval_sub (Lisp_Object form)
2144 gcpro3.nvars = argnum; 2146 gcpro3.nvars = argnum;
2145 } 2147 }
2146 2148
2147 set_backtrace_args (specpdl_ptr - 1, vals); 2149 set_backtrace_args (specpdl + count, vals, XINT (numargs));
2148 set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
2149 2150
2150 val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); 2151 val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals);
2151 UNGCPRO; 2152 UNGCPRO;
@@ -2166,8 +2167,7 @@ eval_sub (Lisp_Object form)
2166 2167
2167 UNGCPRO; 2168 UNGCPRO;
2168 2169
2169 set_backtrace_args (specpdl_ptr - 1, argvals); 2170 set_backtrace_args (specpdl + count, argvals, XINT (numargs));
2170 set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
2171 2171
2172 switch (i) 2172 switch (i)
2173 { 2173 {
@@ -2220,7 +2220,7 @@ eval_sub (Lisp_Object form)
2220 } 2220 }
2221 } 2221 }
2222 else if (COMPILEDP (fun)) 2222 else if (COMPILEDP (fun))
2223 val = apply_lambda (fun, original_args); 2223 val = apply_lambda (fun, original_args, count);
2224 else 2224 else
2225 { 2225 {
2226 if (NILP (fun)) 2226 if (NILP (fun))
@@ -2237,7 +2237,7 @@ eval_sub (Lisp_Object form)
2237 } 2237 }
2238 if (EQ (funcar, Qmacro)) 2238 if (EQ (funcar, Qmacro))
2239 { 2239 {
2240 ptrdiff_t count = SPECPDL_INDEX (); 2240 ptrdiff_t count1 = SPECPDL_INDEX ();
2241 Lisp_Object exp; 2241 Lisp_Object exp;
2242 /* Bind lexical-binding during expansion of the macro, so the 2242 /* Bind lexical-binding during expansion of the macro, so the
2243 macro can know reliably if the code it outputs will be 2243 macro can know reliably if the code it outputs will be
@@ -2245,19 +2245,19 @@ eval_sub (Lisp_Object form)
2245 specbind (Qlexical_binding, 2245 specbind (Qlexical_binding,
2246 NILP (Vinternal_interpreter_environment) ? Qnil : Qt); 2246 NILP (Vinternal_interpreter_environment) ? Qnil : Qt);
2247 exp = apply1 (Fcdr (fun), original_args); 2247 exp = apply1 (Fcdr (fun), original_args);
2248 unbind_to (count, Qnil); 2248 unbind_to (count1, Qnil);
2249 val = eval_sub (exp); 2249 val = eval_sub (exp);
2250 } 2250 }
2251 else if (EQ (funcar, Qlambda) 2251 else if (EQ (funcar, Qlambda)
2252 || EQ (funcar, Qclosure)) 2252 || EQ (funcar, Qclosure))
2253 val = apply_lambda (fun, original_args); 2253 val = apply_lambda (fun, original_args, count);
2254 else 2254 else
2255 xsignal1 (Qinvalid_function, original_fun); 2255 xsignal1 (Qinvalid_function, original_fun);
2256 } 2256 }
2257 check_cons_list (); 2257 check_cons_list ();
2258 2258
2259 lisp_eval_depth--; 2259 lisp_eval_depth--;
2260 if (backtrace_debug_on_exit (specpdl_ptr - 1)) 2260 if (backtrace_debug_on_exit (specpdl + count))
2261 val = call_debugger (list2 (Qexit, val)); 2261 val = call_debugger (list2 (Qexit, val));
2262 specpdl_ptr--; 2262 specpdl_ptr--;
2263 2263
@@ -2271,12 +2271,10 @@ Thus, (apply '+ 1 2 '(3 4)) returns 10.
2271usage: (apply FUNCTION &rest ARGUMENTS) */) 2271usage: (apply FUNCTION &rest ARGUMENTS) */)
2272 (ptrdiff_t nargs, Lisp_Object *args) 2272 (ptrdiff_t nargs, Lisp_Object *args)
2273{ 2273{
2274 ptrdiff_t i; 2274 ptrdiff_t i, numargs, funcall_nargs;
2275 EMACS_INT numargs;
2276 register Lisp_Object spread_arg; 2275 register Lisp_Object spread_arg;
2277 register Lisp_Object *funcall_args; 2276 register Lisp_Object *funcall_args;
2278 Lisp_Object fun, retval; 2277 Lisp_Object fun, retval;
2279 struct gcpro gcpro1;
2280 USE_SAFE_ALLOCA; 2278 USE_SAFE_ALLOCA;
2281 2279
2282 fun = args [0]; 2280 fun = args [0];
@@ -2317,10 +2315,9 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2317 /* Avoid making funcall cons up a yet another new vector of arguments 2315 /* Avoid making funcall cons up a yet another new vector of arguments
2318 by explicitly supplying nil's for optional values. */ 2316 by explicitly supplying nil's for optional values. */
2319 SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args); 2317 SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args);
2320 for (i = numargs; i < XSUBR (fun)->max_args;) 2318 for (i = numargs; i < XSUBR (fun)->max_args; /* nothing */)
2321 funcall_args[++i] = Qnil; 2319 funcall_args[++i] = Qnil;
2322 GCPRO1 (*funcall_args); 2320 funcall_nargs = 1 + XSUBR (fun)->max_args;
2323 gcpro1.nvars = 1 + XSUBR (fun)->max_args;
2324 } 2321 }
2325 } 2322 }
2326 funcall: 2323 funcall:
@@ -2329,8 +2326,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2329 if (!funcall_args) 2326 if (!funcall_args)
2330 { 2327 {
2331 SAFE_ALLOCA_LISP (funcall_args, 1 + numargs); 2328 SAFE_ALLOCA_LISP (funcall_args, 1 + numargs);
2332 GCPRO1 (*funcall_args); 2329 funcall_nargs = 1 + numargs;
2333 gcpro1.nvars = 1 + numargs;
2334 } 2330 }
2335 2331
2336 memcpy (funcall_args, args, nargs * word_size); 2332 memcpy (funcall_args, args, nargs * word_size);
@@ -2343,11 +2339,10 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2343 spread_arg = XCDR (spread_arg); 2339 spread_arg = XCDR (spread_arg);
2344 } 2340 }
2345 2341
2346 /* By convention, the caller needs to gcpro Ffuncall's args. */ 2342 /* Ffuncall gcpro's all of its args. */
2347 retval = Ffuncall (gcpro1.nvars, funcall_args); 2343 retval = Ffuncall (funcall_nargs, funcall_args);
2348 UNGCPRO;
2349 SAFE_FREE ();
2350 2344
2345 SAFE_FREE ();
2351 return retval; 2346 return retval;
2352} 2347}
2353 2348
@@ -2555,41 +2550,22 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
2555void 2550void
2556run_hook_with_args_2 (Lisp_Object hook, Lisp_Object arg1, Lisp_Object arg2) 2551run_hook_with_args_2 (Lisp_Object hook, Lisp_Object arg1, Lisp_Object arg2)
2557{ 2552{
2558 Lisp_Object temp[3]; 2553 Frun_hook_with_args (3, ((Lisp_Object []) { hook, arg1, arg2 }));
2559 temp[0] = hook;
2560 temp[1] = arg1;
2561 temp[2] = arg2;
2562
2563 Frun_hook_with_args (3, temp);
2564} 2554}
2565 2555
2566/* Apply fn to arg. */ 2556/* Apply fn to arg. */
2567Lisp_Object 2557Lisp_Object
2568apply1 (Lisp_Object fn, Lisp_Object arg) 2558apply1 (Lisp_Object fn, Lisp_Object arg)
2569{ 2559{
2570 struct gcpro gcpro1; 2560 return (NILP (arg) ? Ffuncall (1, &fn)
2571 2561 : Fapply (2, ((Lisp_Object []) { fn, arg })));
2572 GCPRO1 (fn);
2573 if (NILP (arg))
2574 RETURN_UNGCPRO (Ffuncall (1, &fn));
2575 gcpro1.nvars = 2;
2576 {
2577 Lisp_Object args[2];
2578 args[0] = fn;
2579 args[1] = arg;
2580 gcpro1.var = args;
2581 RETURN_UNGCPRO (Fapply (2, args));
2582 }
2583} 2562}
2584 2563
2585/* Call function fn on no arguments. */ 2564/* Call function fn on no arguments. */
2586Lisp_Object 2565Lisp_Object
2587call0 (Lisp_Object fn) 2566call0 (Lisp_Object fn)
2588{ 2567{
2589 struct gcpro gcpro1; 2568 return Ffuncall (1, &fn);
2590
2591 GCPRO1 (fn);
2592 RETURN_UNGCPRO (Ffuncall (1, &fn));
2593} 2569}
2594 2570
2595/* Call function fn with 1 argument arg1. */ 2571/* Call function fn with 1 argument arg1. */
@@ -2597,14 +2573,7 @@ call0 (Lisp_Object fn)
2597Lisp_Object 2573Lisp_Object
2598call1 (Lisp_Object fn, Lisp_Object arg1) 2574call1 (Lisp_Object fn, Lisp_Object arg1)
2599{ 2575{
2600 struct gcpro gcpro1; 2576 return Ffuncall (2, ((Lisp_Object []) { fn, arg1 }));
2601 Lisp_Object args[2];
2602
2603 args[0] = fn;
2604 args[1] = arg1;
2605 GCPRO1 (args[0]);
2606 gcpro1.nvars = 2;
2607 RETURN_UNGCPRO (Ffuncall (2, args));
2608} 2577}
2609 2578
2610/* Call function fn with 2 arguments arg1, arg2. */ 2579/* Call function fn with 2 arguments arg1, arg2. */
@@ -2612,14 +2581,7 @@ call1 (Lisp_Object fn, Lisp_Object arg1)
2612Lisp_Object 2581Lisp_Object
2613call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2) 2582call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2614{ 2583{
2615 struct gcpro gcpro1; 2584 return Ffuncall (3, ((Lisp_Object []) { fn, arg1, arg2 }));
2616 Lisp_Object args[3];
2617 args[0] = fn;
2618 args[1] = arg1;
2619 args[2] = arg2;
2620 GCPRO1 (args[0]);
2621 gcpro1.nvars = 3;
2622 RETURN_UNGCPRO (Ffuncall (3, args));
2623} 2585}
2624 2586
2625/* Call function fn with 3 arguments arg1, arg2, arg3. */ 2587/* Call function fn with 3 arguments arg1, arg2, arg3. */
@@ -2627,15 +2589,7 @@ call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2627Lisp_Object 2589Lisp_Object
2628call3 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) 2590call3 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
2629{ 2591{
2630 struct gcpro gcpro1; 2592 return Ffuncall (4, ((Lisp_Object []) { fn, arg1, arg2, arg3 }));
2631 Lisp_Object args[4];
2632 args[0] = fn;
2633 args[1] = arg1;
2634 args[2] = arg2;
2635 args[3] = arg3;
2636 GCPRO1 (args[0]);
2637 gcpro1.nvars = 4;
2638 RETURN_UNGCPRO (Ffuncall (4, args));
2639} 2593}
2640 2594
2641/* Call function fn with 4 arguments arg1, arg2, arg3, arg4. */ 2595/* Call function fn with 4 arguments arg1, arg2, arg3, arg4. */
@@ -2644,16 +2598,7 @@ Lisp_Object
2644call4 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, 2598call4 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
2645 Lisp_Object arg4) 2599 Lisp_Object arg4)
2646{ 2600{
2647 struct gcpro gcpro1; 2601 return Ffuncall (5, ((Lisp_Object []) { fn, arg1, arg2, arg3, arg4 }));
2648 Lisp_Object args[5];
2649 args[0] = fn;
2650 args[1] = arg1;
2651 args[2] = arg2;
2652 args[3] = arg3;
2653 args[4] = arg4;
2654 GCPRO1 (args[0]);
2655 gcpro1.nvars = 5;
2656 RETURN_UNGCPRO (Ffuncall (5, args));
2657} 2602}
2658 2603
2659/* Call function fn with 5 arguments arg1, arg2, arg3, arg4, arg5. */ 2604/* Call function fn with 5 arguments arg1, arg2, arg3, arg4, arg5. */
@@ -2662,17 +2607,7 @@ Lisp_Object
2662call5 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, 2607call5 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
2663 Lisp_Object arg4, Lisp_Object arg5) 2608 Lisp_Object arg4, Lisp_Object arg5)
2664{ 2609{
2665 struct gcpro gcpro1; 2610 return Ffuncall (6, ((Lisp_Object []) { fn, arg1, arg2, arg3, arg4, arg5 }));
2666 Lisp_Object args[6];
2667 args[0] = fn;
2668 args[1] = arg1;
2669 args[2] = arg2;
2670 args[3] = arg3;
2671 args[4] = arg4;
2672 args[5] = arg5;
2673 GCPRO1 (args[0]);
2674 gcpro1.nvars = 6;
2675 RETURN_UNGCPRO (Ffuncall (6, args));
2676} 2611}
2677 2612
2678/* Call function fn with 6 arguments arg1, arg2, arg3, arg4, arg5, arg6. */ 2613/* Call function fn with 6 arguments arg1, arg2, arg3, arg4, arg5, arg6. */
@@ -2681,18 +2616,8 @@ Lisp_Object
2681call6 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, 2616call6 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
2682 Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6) 2617 Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6)
2683{ 2618{
2684 struct gcpro gcpro1; 2619 return Ffuncall (7, ((Lisp_Object [])
2685 Lisp_Object args[7]; 2620 { fn, arg1, arg2, arg3, arg4, arg5, arg6 }));
2686 args[0] = fn;
2687 args[1] = arg1;
2688 args[2] = arg2;
2689 args[3] = arg3;
2690 args[4] = arg4;
2691 args[5] = arg5;
2692 args[6] = arg6;
2693 GCPRO1 (args[0]);
2694 gcpro1.nvars = 7;
2695 RETURN_UNGCPRO (Ffuncall (7, args));
2696} 2621}
2697 2622
2698/* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7. */ 2623/* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7. */
@@ -2701,19 +2626,8 @@ Lisp_Object
2701call7 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, 2626call7 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3,
2702 Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6, Lisp_Object arg7) 2627 Lisp_Object arg4, Lisp_Object arg5, Lisp_Object arg6, Lisp_Object arg7)
2703{ 2628{
2704 struct gcpro gcpro1; 2629 return Ffuncall (8, ((Lisp_Object [])
2705 Lisp_Object args[8]; 2630 { fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7 }));
2706 args[0] = fn;
2707 args[1] = arg1;
2708 args[2] = arg2;
2709 args[3] = arg3;
2710 args[4] = arg4;
2711 args[5] = arg5;
2712 args[6] = arg6;
2713 args[7] = arg7;
2714 GCPRO1 (args[0]);
2715 gcpro1.nvars = 8;
2716 RETURN_UNGCPRO (Ffuncall (8, args));
2717} 2631}
2718 2632
2719/* The caller should GCPRO all the elements of ARGS. */ 2633/* The caller should GCPRO all the elements of ARGS. */
@@ -2740,7 +2654,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2740 Lisp_Object lisp_numargs; 2654 Lisp_Object lisp_numargs;
2741 Lisp_Object val; 2655 Lisp_Object val;
2742 register Lisp_Object *internal_args; 2656 register Lisp_Object *internal_args;
2743 ptrdiff_t i; 2657 ptrdiff_t i, count;
2744 2658
2745 QUIT; 2659 QUIT;
2746 2660
@@ -2753,13 +2667,13 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2753 } 2667 }
2754 2668
2755 /* This also GCPROs them. */ 2669 /* This also GCPROs them. */
2756 record_in_backtrace (args[0], &args[1], nargs - 1); 2670 count = record_in_backtrace (args[0], &args[1], nargs - 1);
2757 2671
2758 /* Call GC after setting up the backtrace, so the latter GCPROs the args. */ 2672 /* Call GC after setting up the backtrace, so the latter GCPROs the args. */
2759 maybe_gc (); 2673 maybe_gc ();
2760 2674
2761 if (debug_on_next_call) 2675 if (debug_on_next_call)
2762 do_debug_on_call (Qlambda); 2676 do_debug_on_call (Qlambda, count);
2763 2677
2764 check_cons_list (); 2678 check_cons_list ();
2765 2679
@@ -2789,10 +2703,11 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2789 val = (XSUBR (fun)->function.aMANY) (numargs, args + 1); 2703 val = (XSUBR (fun)->function.aMANY) (numargs, args + 1);
2790 else 2704 else
2791 { 2705 {
2706 Lisp_Object internal_argbuf[8];
2792 if (XSUBR (fun)->max_args > numargs) 2707 if (XSUBR (fun)->max_args > numargs)
2793 { 2708 {
2794 internal_args = alloca (XSUBR (fun)->max_args 2709 eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf));
2795 * sizeof *internal_args); 2710 internal_args = internal_argbuf;
2796 memcpy (internal_args, args + 1, numargs * word_size); 2711 memcpy (internal_args, args + 1, numargs * word_size);
2797 for (i = numargs; i < XSUBR (fun)->max_args; i++) 2712 for (i = numargs; i < XSUBR (fun)->max_args; i++)
2798 internal_args[i] = Qnil; 2713 internal_args[i] = Qnil;
@@ -2878,14 +2793,14 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2878 } 2793 }
2879 check_cons_list (); 2794 check_cons_list ();
2880 lisp_eval_depth--; 2795 lisp_eval_depth--;
2881 if (backtrace_debug_on_exit (specpdl_ptr - 1)) 2796 if (backtrace_debug_on_exit (specpdl + count))
2882 val = call_debugger (list2 (Qexit, val)); 2797 val = call_debugger (list2 (Qexit, val));
2883 specpdl_ptr--; 2798 specpdl_ptr--;
2884 return val; 2799 return val;
2885} 2800}
2886 2801
2887static Lisp_Object 2802static Lisp_Object
2888apply_lambda (Lisp_Object fun, Lisp_Object args) 2803apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
2889{ 2804{
2890 Lisp_Object args_left; 2805 Lisp_Object args_left;
2891 ptrdiff_t i; 2806 ptrdiff_t i;
@@ -2912,15 +2827,14 @@ apply_lambda (Lisp_Object fun, Lisp_Object args)
2912 2827
2913 UNGCPRO; 2828 UNGCPRO;
2914 2829
2915 set_backtrace_args (specpdl_ptr - 1, arg_vector); 2830 set_backtrace_args (specpdl + count, arg_vector, i);
2916 set_backtrace_nargs (specpdl_ptr - 1, i);
2917 tem = funcall_lambda (fun, numargs, arg_vector); 2831 tem = funcall_lambda (fun, numargs, arg_vector);
2918 2832
2919 /* Do the debug-on-exit now, while arg_vector still exists. */ 2833 /* Do the debug-on-exit now, while arg_vector still exists. */
2920 if (backtrace_debug_on_exit (specpdl_ptr - 1)) 2834 if (backtrace_debug_on_exit (specpdl + count))
2921 { 2835 {
2922 /* Don't do it again when we return to eval. */ 2836 /* Don't do it again when we return to eval. */
2923 set_backtrace_debug_on_exit (specpdl_ptr - 1, false); 2837 set_backtrace_debug_on_exit (specpdl + count, false);
2924 tem = call_debugger (list2 (Qexit, tem)); 2838 tem = call_debugger (list2 (Qexit, tem));
2925 } 2839 }
2926 SAFE_FREE (); 2840 SAFE_FREE ();
diff --git a/src/fileio.c b/src/fileio.c
index d9c7397c2de..4ba1c5914e8 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -396,13 +396,6 @@ Otherwise return a directory name.
396Given a Unix syntax file name, returns a string ending in slash. */) 396Given a Unix syntax file name, returns a string ending in slash. */)
397 (Lisp_Object filename) 397 (Lisp_Object filename)
398{ 398{
399#ifndef DOS_NT
400 register const char *beg;
401#else
402 register char *beg;
403 Lisp_Object tem_fn;
404#endif
405 register const char *p;
406 Lisp_Object handler; 399 Lisp_Object handler;
407 400
408 CHECK_STRING (filename); 401 CHECK_STRING (filename);
@@ -417,12 +410,8 @@ Given a Unix syntax file name, returns a string ending in slash. */)
417 return STRINGP (handled_name) ? handled_name : Qnil; 410 return STRINGP (handled_name) ? handled_name : Qnil;
418 } 411 }
419 412
420#ifdef DOS_NT 413 char *beg = SSDATA (filename);
421 beg = xlispstrdupa (filename); 414 char const *p = beg + SBYTES (filename);
422#else
423 beg = SSDATA (filename);
424#endif
425 p = beg + SBYTES (filename);
426 415
427 while (p != beg && !IS_DIRECTORY_SEP (p[-1]) 416 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
428#ifdef DOS_NT 417#ifdef DOS_NT
@@ -438,6 +427,11 @@ Given a Unix syntax file name, returns a string ending in slash. */)
438 return Qnil; 427 return Qnil;
439#ifdef DOS_NT 428#ifdef DOS_NT
440 /* Expansion of "c:" to drive and default directory. */ 429 /* Expansion of "c:" to drive and default directory. */
430 Lisp_Object tem_fn;
431 USE_SAFE_ALLOCA;
432 SAFE_ALLOCA_STRING (beg, filename);
433 p = beg + (p - SSDATA (filename));
434
441 if (p[-1] == ':') 435 if (p[-1] == ':')
442 { 436 {
443 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */ 437 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
@@ -481,6 +475,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
481 dostounix_filename (beg); 475 dostounix_filename (beg);
482 tem_fn = make_specified_string (beg, -1, p - beg, 0); 476 tem_fn = make_specified_string (beg, -1, p - beg, 0);
483 } 477 }
478 SAFE_FREE ();
484 return tem_fn; 479 return tem_fn;
485#else /* DOS_NT */ 480#else /* DOS_NT */
486 return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename)); 481 return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename));
@@ -733,7 +728,7 @@ Lisp_Object
733make_temp_name (Lisp_Object prefix, bool base64_p) 728make_temp_name (Lisp_Object prefix, bool base64_p)
734{ 729{
735 Lisp_Object val, encoded_prefix; 730 Lisp_Object val, encoded_prefix;
736 int len; 731 ptrdiff_t len;
737 printmax_t pid; 732 printmax_t pid;
738 char *p, *data; 733 char *p, *data;
739 char pidbuf[INT_BUFSIZE_BOUND (printmax_t)]; 734 char pidbuf[INT_BUFSIZE_BOUND (printmax_t)];
@@ -847,8 +842,6 @@ probably use `make-temp-file' instead, except in three circumstances:
847 return make_temp_name (prefix, 0); 842 return make_temp_name (prefix, 0);
848} 843}
849 844
850
851
852DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, 845DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
853 doc: /* Convert filename NAME to absolute, and canonicalize it. 846 doc: /* Convert filename NAME to absolute, and canonicalize it.
854Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative 847Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
@@ -878,7 +871,9 @@ filesystem tree, not (expand-file-name ".." dirname). */)
878 /* These point to SDATA and need to be careful with string-relocation 871 /* These point to SDATA and need to be careful with string-relocation
879 during GC (via DECODE_FILE). */ 872 during GC (via DECODE_FILE). */
880 char *nm; 873 char *nm;
874 char *nmlim;
881 const char *newdir; 875 const char *newdir;
876 const char *newdirlim;
882 /* This should only point to alloca'd data. */ 877 /* This should only point to alloca'd data. */
883 char *target; 878 char *target;
884 879
@@ -886,10 +881,10 @@ filesystem tree, not (expand-file-name ".." dirname). */)
886 struct passwd *pw; 881 struct passwd *pw;
887#ifdef DOS_NT 882#ifdef DOS_NT
888 int drive = 0; 883 int drive = 0;
889 bool collapse_newdir = 1; 884 bool collapse_newdir = true;
890 bool is_escaped = 0; 885 bool is_escaped = 0;
891#endif /* DOS_NT */ 886#endif /* DOS_NT */
892 ptrdiff_t length; 887 ptrdiff_t length, nbytes;
893 Lisp_Object handler, result, handled_name; 888 Lisp_Object handler, result, handled_name;
894 bool multibyte; 889 bool multibyte;
895 Lisp_Object hdir; 890 Lisp_Object hdir;
@@ -1018,8 +1013,9 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1018 default_directory = Fdowncase (default_directory); 1013 default_directory = Fdowncase (default_directory);
1019#endif 1014#endif
1020 1015
1021 /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ 1016 /* Make a local copy of NAME to protect it from GC in DECODE_FILE below. */
1022 nm = xlispstrdupa (name); 1017 SAFE_ALLOCA_STRING (nm, name);
1018 nmlim = nm + SBYTES (name);
1023 1019
1024#ifdef DOS_NT 1020#ifdef DOS_NT
1025 /* Note if special escape prefix is present, but remove for now. */ 1021 /* Note if special escape prefix is present, but remove for now. */
@@ -1104,7 +1100,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1104 if (IS_DIRECTORY_SEP (nm[1])) 1100 if (IS_DIRECTORY_SEP (nm[1]))
1105 { 1101 {
1106 if (strcmp (nm, SSDATA (name)) != 0) 1102 if (strcmp (nm, SSDATA (name)) != 0)
1107 name = make_specified_string (nm, -1, strlen (nm), multibyte); 1103 name = make_specified_string (nm, -1, nmlim - nm, multibyte);
1108 } 1104 }
1109 else 1105 else
1110#endif 1106#endif
@@ -1115,18 +1111,19 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1115 1111
1116 name = make_specified_string (nm, -1, p - nm, multibyte); 1112 name = make_specified_string (nm, -1, p - nm, multibyte);
1117 temp[0] = DRIVE_LETTER (drive); 1113 temp[0] = DRIVE_LETTER (drive);
1118 name = concat2 (build_string (temp), name); 1114 AUTO_STRING (drive_prefix, temp);
1115 name = concat2 (drive_prefix, name);
1119 } 1116 }
1120#ifdef WINDOWSNT 1117#ifdef WINDOWSNT
1121 if (!NILP (Vw32_downcase_file_names)) 1118 if (!NILP (Vw32_downcase_file_names))
1122 name = Fdowncase (name); 1119 name = Fdowncase (name);
1123#endif 1120#endif
1124 return name;
1125#else /* not DOS_NT */ 1121#else /* not DOS_NT */
1126 if (strcmp (nm, SSDATA (name)) == 0) 1122 if (strcmp (nm, SSDATA (name)) != 0)
1127 return name; 1123 name = make_specified_string (nm, -1, nmlim - nm, multibyte);
1128 return make_specified_string (nm, -1, strlen (nm), multibyte);
1129#endif /* not DOS_NT */ 1124#endif /* not DOS_NT */
1125 SAFE_FREE ();
1126 return name;
1130 } 1127 }
1131 } 1128 }
1132 1129
@@ -1146,7 +1143,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1146 return an absolute name, if the final prefix is not absolute we 1143 return an absolute name, if the final prefix is not absolute we
1147 append it to the current working directory. */ 1144 append it to the current working directory. */
1148 1145
1149 newdir = 0; 1146 newdir = newdirlim = 0;
1150 1147
1151 if (nm[0] == '~') /* prefix ~ */ 1148 if (nm[0] == '~') /* prefix ~ */
1152 { 1149 {
@@ -1156,7 +1153,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1156 Lisp_Object tem; 1153 Lisp_Object tem;
1157 1154
1158 if (!(newdir = egetenv ("HOME"))) 1155 if (!(newdir = egetenv ("HOME")))
1159 newdir = ""; 1156 newdir = newdirlim = "";
1160 nm++; 1157 nm++;
1161 /* `egetenv' may return a unibyte string, which will bite us since 1158 /* `egetenv' may return a unibyte string, which will bite us since
1162 we expect the directory to be multibyte. */ 1159 we expect the directory to be multibyte. */
@@ -1171,13 +1168,15 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1171 else 1168 else
1172#endif 1169#endif
1173 tem = build_string (newdir); 1170 tem = build_string (newdir);
1171 newdirlim = newdir + SBYTES (tem);
1174 if (multibyte && !STRING_MULTIBYTE (tem)) 1172 if (multibyte && !STRING_MULTIBYTE (tem))
1175 { 1173 {
1176 hdir = DECODE_FILE (tem); 1174 hdir = DECODE_FILE (tem);
1177 newdir = SSDATA (hdir); 1175 newdir = SSDATA (hdir);
1176 newdirlim = newdir + SBYTES (hdir);
1178 } 1177 }
1179#ifdef DOS_NT 1178#ifdef DOS_NT
1180 collapse_newdir = 0; 1179 collapse_newdir = false;
1181#endif 1180#endif
1182 } 1181 }
1183 else /* ~user/filename */ 1182 else /* ~user/filename */
@@ -1201,14 +1200,16 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1201 bite us since we expect the directory to be 1200 bite us since we expect the directory to be
1202 multibyte. */ 1201 multibyte. */
1203 tem = build_string (newdir); 1202 tem = build_string (newdir);
1203 newdirlim = newdir + SBYTES (tem);
1204 if (multibyte && !STRING_MULTIBYTE (tem)) 1204 if (multibyte && !STRING_MULTIBYTE (tem))
1205 { 1205 {
1206 hdir = DECODE_FILE (tem); 1206 hdir = DECODE_FILE (tem);
1207 newdir = SSDATA (hdir); 1207 newdir = SSDATA (hdir);
1208 newdirlim = newdir + SBYTES (hdir);
1208 } 1209 }
1209 nm = p; 1210 nm = p;
1210#ifdef DOS_NT 1211#ifdef DOS_NT
1211 collapse_newdir = 0; 1212 collapse_newdir = false;
1212#endif 1213#endif
1213 } 1214 }
1214 1215
@@ -1234,8 +1235,11 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1234 Lisp_Object tem = build_string (adir); 1235 Lisp_Object tem = build_string (adir);
1235 1236
1236 tem = DECODE_FILE (tem); 1237 tem = DECODE_FILE (tem);
1238 newdirlim = adir + SBYTES (tem);
1237 memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); 1239 memcpy (adir, SSDATA (tem), SBYTES (tem) + 1);
1238 } 1240 }
1241 else
1242 newdirlim = adir + strlen (adir);
1239 } 1243 }
1240 if (!adir) 1244 if (!adir)
1241 { 1245 {
@@ -1245,6 +1249,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1245 adir[1] = ':'; 1249 adir[1] = ':';
1246 adir[2] = '/'; 1250 adir[2] = '/';
1247 adir[3] = 0; 1251 adir[3] = 0;
1252 newdirlim = adir + 3;
1248 } 1253 }
1249 newdir = adir; 1254 newdir = adir;
1250 } 1255 }
@@ -1265,6 +1270,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1265 && !newdir) 1270 && !newdir)
1266 { 1271 {
1267 newdir = SSDATA (default_directory); 1272 newdir = SSDATA (default_directory);
1273 newdirlim = newdir + SBYTES (default_directory);
1268#ifdef DOS_NT 1274#ifdef DOS_NT
1269 /* Note if special escape prefix is present, but remove for now. */ 1275 /* Note if special escape prefix is present, but remove for now. */
1270 if (newdir[0] == '/' && newdir[1] == ':') 1276 if (newdir[0] == '/' && newdir[1] == ':')
@@ -1309,12 +1315,15 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1309 } 1315 }
1310 if (!IS_DIRECTORY_SEP (nm[0])) 1316 if (!IS_DIRECTORY_SEP (nm[0]))
1311 { 1317 {
1312 ptrdiff_t newlen = strlen (newdir); 1318 ptrdiff_t nmlen = nmlim - nm;
1313 char *tmp = alloca (newlen + file_name_as_directory_slop 1319 ptrdiff_t newdirlen = newdirlim - newdir;
1314 + strlen (nm) + 1); 1320 char *tmp = alloca (newdirlen + file_name_as_directory_slop
1315 file_name_as_directory (tmp, newdir, newlen, multibyte); 1321 + nmlen + 1);
1316 strcat (tmp, nm); 1322 ptrdiff_t dlen = file_name_as_directory (tmp, newdir, newdirlen,
1323 multibyte);
1324 memcpy (tmp + dlen, nm, nmlen + 1);
1317 nm = tmp; 1325 nm = tmp;
1326 nmlim = nm + dlen + nmlen;
1318 } 1327 }
1319 adir = alloca (adir_size); 1328 adir = alloca (adir_size);
1320 if (drive) 1329 if (drive)
@@ -1329,8 +1338,11 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1329 Lisp_Object tem = build_string (adir); 1338 Lisp_Object tem = build_string (adir);
1330 1339
1331 tem = DECODE_FILE (tem); 1340 tem = DECODE_FILE (tem);
1341 newdirlim = adir + SBYTES (tem);
1332 memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); 1342 memcpy (adir, SSDATA (tem), SBYTES (tem) + 1);
1333 } 1343 }
1344 else
1345 newdirlim = adir + strlen (adir);
1334 newdir = adir; 1346 newdir = adir;
1335 } 1347 }
1336 1348
@@ -1349,35 +1361,32 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1349 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]) 1361 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])
1350 && !IS_DIRECTORY_SEP (newdir[2])) 1362 && !IS_DIRECTORY_SEP (newdir[2]))
1351 { 1363 {
1352 char *adir = strcpy (alloca (strlen (newdir) + 1), newdir); 1364 char *adir = strcpy (alloca (newdirlim - newdir + 1), newdir);
1353 char *p = adir + 2; 1365 char *p = adir + 2;
1354 while (*p && !IS_DIRECTORY_SEP (*p)) p++; 1366 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1355 p++; 1367 p++;
1356 while (*p && !IS_DIRECTORY_SEP (*p)) p++; 1368 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1357 *p = 0; 1369 *p = 0;
1358 newdir = adir; 1370 newdir = adir;
1371 newdirlim = newdir + strlen (adir);
1359 } 1372 }
1360 else 1373 else
1361#endif 1374#endif
1362 newdir = ""; 1375 newdir = newdirlim = "";
1363 } 1376 }
1364 } 1377 }
1365#endif /* DOS_NT */ 1378#endif /* DOS_NT */
1366 1379
1367 if (newdir) 1380 /* Ignore any slash at the end of newdir, unless newdir is
1368 { 1381 just "/" or "//". */
1369 /* Ignore any slash at the end of newdir, unless newdir is 1382 length = newdirlim - newdir;
1370 just "/" or "//". */ 1383 while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
1371 length = strlen (newdir); 1384 && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0])))
1372 while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) 1385 length--;
1373 && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0])))
1374 length--;
1375 }
1376 else
1377 length = 0;
1378 1386
1379 /* Now concatenate the directory and name to new space in the stack frame. */ 1387 /* Now concatenate the directory and name to new space in the stack frame. */
1380 tlen = length + file_name_as_directory_slop + strlen (nm) + 1; 1388 tlen = length + file_name_as_directory_slop + (nmlim - nm) + 1;
1389 eassert (tlen > file_name_as_directory_slop + 1);
1381#ifdef DOS_NT 1390#ifdef DOS_NT
1382 /* Reserve space for drive specifier and escape prefix, since either 1391 /* Reserve space for drive specifier and escape prefix, since either
1383 or both may need to be inserted. (The Microsoft x86 compiler 1392 or both may need to be inserted. (The Microsoft x86 compiler
@@ -1388,6 +1397,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1388 target = SAFE_ALLOCA (tlen); 1397 target = SAFE_ALLOCA (tlen);
1389#endif /* not DOS_NT */ 1398#endif /* not DOS_NT */
1390 *target = 0; 1399 *target = 0;
1400 nbytes = 0;
1391 1401
1392 if (newdir) 1402 if (newdir)
1393 { 1403 {
@@ -1405,13 +1415,14 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1405 { 1415 {
1406 memcpy (target, newdir, length); 1416 memcpy (target, newdir, length);
1407 target[length] = 0; 1417 target[length] = 0;
1418 nbytes = length;
1408 } 1419 }
1409 } 1420 }
1410 else 1421 else
1411 file_name_as_directory (target, newdir, length, multibyte); 1422 nbytes = file_name_as_directory (target, newdir, length, multibyte);
1412 } 1423 }
1413 1424
1414 strcat (target, nm); 1425 memcpy (target + nbytes, nm, nmlim - nm + 1);
1415 1426
1416 /* Now canonicalize by removing `//', `/.' and `/foo/..' if they 1427 /* Now canonicalize by removing `//', `/.' and `/foo/..' if they
1417 appear. */ 1428 appear. */
@@ -1717,7 +1728,8 @@ search_embedded_absfilename (char *nm, char *endp)
1717 for (s = p; *s && !IS_DIRECTORY_SEP (*s); s++); 1728 for (s = p; *s && !IS_DIRECTORY_SEP (*s); s++);
1718 if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */ 1729 if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */
1719 { 1730 {
1720 char *o = alloca (s - p + 1); 1731 USE_SAFE_ALLOCA;
1732 char *o = SAFE_ALLOCA (s - p + 1);
1721 struct passwd *pw; 1733 struct passwd *pw;
1722 memcpy (o, p, s - p); 1734 memcpy (o, p, s - p);
1723 o [s - p] = 0; 1735 o [s - p] = 0;
@@ -1728,6 +1740,7 @@ search_embedded_absfilename (char *nm, char *endp)
1728 block_input (); 1740 block_input ();
1729 pw = getpwnam (o + 1); 1741 pw = getpwnam (o + 1);
1730 unblock_input (); 1742 unblock_input ();
1743 SAFE_FREE ();
1731 if (pw) 1744 if (pw)
1732 return p; 1745 return p;
1733 } 1746 }
@@ -1776,7 +1789,8 @@ those `/' is discarded. */)
1776 /* Always work on a copy of the string, in case GC happens during 1789 /* Always work on a copy of the string, in case GC happens during
1777 decode of environment variables, causing the original Lisp_String 1790 decode of environment variables, causing the original Lisp_String
1778 data to be relocated. */ 1791 data to be relocated. */
1779 nm = xlispstrdupa (filename); 1792 USE_SAFE_ALLOCA;
1793 SAFE_ALLOCA_STRING (nm, filename);
1780 1794
1781#ifdef DOS_NT 1795#ifdef DOS_NT
1782 dostounix_filename (nm); 1796 dostounix_filename (nm);
@@ -1790,8 +1804,13 @@ those `/' is discarded. */)
1790 /* Start over with the new string, so we check the file-name-handler 1804 /* Start over with the new string, so we check the file-name-handler
1791 again. Important with filenames like "/home/foo//:/hello///there" 1805 again. Important with filenames like "/home/foo//:/hello///there"
1792 which would substitute to "/:/hello///there" rather than "/there". */ 1806 which would substitute to "/:/hello///there" rather than "/there". */
1793 return Fsubstitute_in_file_name 1807 {
1794 (make_specified_string (p, -1, endp - p, multibyte)); 1808 Lisp_Object result
1809 = (Fsubstitute_in_file_name
1810 (make_specified_string (p, -1, endp - p, multibyte)));
1811 SAFE_FREE ();
1812 return result;
1813 }
1795 1814
1796 /* See if any variables are substituted into the string. */ 1815 /* See if any variables are substituted into the string. */
1797 1816
@@ -1813,6 +1832,7 @@ those `/' is discarded. */)
1813 if (!NILP (Vw32_downcase_file_names)) 1832 if (!NILP (Vw32_downcase_file_names))
1814 filename = Fdowncase (filename); 1833 filename = Fdowncase (filename);
1815#endif 1834#endif
1835 SAFE_FREE ();
1816 return filename; 1836 return filename;
1817 } 1837 }
1818 1838
@@ -1831,14 +1851,14 @@ those `/' is discarded. */)
1831 { 1851 {
1832 Lisp_Object xname = make_specified_string (xnm, -1, x - xnm, multibyte); 1852 Lisp_Object xname = make_specified_string (xnm, -1, x - xnm, multibyte);
1833 1853
1834 xname = Fdowncase (xname); 1854 filename = Fdowncase (xname);
1835 return xname;
1836 } 1855 }
1837 else 1856 else
1838#endif 1857#endif
1839 return (xnm == SSDATA (filename) 1858 if (xnm != SSDATA (filename))
1840 ? filename 1859 filename = make_specified_string (xnm, -1, x - xnm, multibyte);
1841 : make_specified_string (xnm, -1, x - xnm, multibyte)); 1860 SAFE_FREE ();
1861 return filename;
1842} 1862}
1843 1863
1844/* A slightly faster and more convenient way to get 1864/* A slightly faster and more convenient way to get
@@ -2671,7 +2691,10 @@ emacs_readlinkat (int fd, char const *filename)
2671 2691
2672 val = build_unibyte_string (buf); 2692 val = build_unibyte_string (buf);
2673 if (buf[0] == '/' && strchr (buf, ':')) 2693 if (buf[0] == '/' && strchr (buf, ':'))
2674 val = concat2 (build_unibyte_string ("/:"), val); 2694 {
2695 AUTO_STRING (slash_colon, "/:");
2696 val = concat2 (slash_colon, val);
2697 }
2675 if (buf != readlink_buf) 2698 if (buf != readlink_buf)
2676 xfree (buf); 2699 xfree (buf);
2677 val = DECODE_FILE (val); 2700 val = DECODE_FILE (val);
@@ -2765,23 +2788,24 @@ searchable directory. */)
2765 } 2788 }
2766 2789
2767 absname = ENCODE_FILE (absname); 2790 absname = ENCODE_FILE (absname);
2768 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil; 2791 return file_accessible_directory_p (absname) ? Qt : Qnil;
2769} 2792}
2770 2793
2771/* If FILE is a searchable directory or a symlink to a 2794/* If FILE is a searchable directory or a symlink to a
2772 searchable directory, return true. Otherwise return 2795 searchable directory, return true. Otherwise return
2773 false and set errno to an error number. */ 2796 false and set errno to an error number. */
2774bool 2797bool
2775file_accessible_directory_p (char const *file) 2798file_accessible_directory_p (Lisp_Object file)
2776{ 2799{
2777#ifdef DOS_NT 2800#ifdef DOS_NT
2778 /* There's no need to test whether FILE is searchable, as the 2801 /* There's no need to test whether FILE is searchable, as the
2779 searchable/executable bit is invented on DOS_NT platforms. */ 2802 searchable/executable bit is invented on DOS_NT platforms. */
2780 return file_directory_p (file); 2803 return file_directory_p (SSDATA (file));
2781#else 2804#else
2782 /* On POSIXish platforms, use just one system call; this avoids a 2805 /* On POSIXish platforms, use just one system call; this avoids a
2783 race and is typically faster. */ 2806 race and is typically faster. */
2784 ptrdiff_t len = strlen (file); 2807 const char *data = SSDATA (file);
2808 ptrdiff_t len = SBYTES (file);
2785 char const *dir; 2809 char const *dir;
2786 bool ok; 2810 bool ok;
2787 int saved_errno; 2811 int saved_errno;
@@ -2793,15 +2817,15 @@ file_accessible_directory_p (char const *file)
2793 "/" and "//" are distinct on some platforms, whereas "/", "///", 2817 "/" and "//" are distinct on some platforms, whereas "/", "///",
2794 "////", etc. are all equivalent. */ 2818 "////", etc. are all equivalent. */
2795 if (! len) 2819 if (! len)
2796 dir = file; 2820 dir = data;
2797 else 2821 else
2798 { 2822 {
2799 /* Just check for trailing '/' when deciding whether to append '/'. 2823 /* Just check for trailing '/' when deciding whether to append '/'.
2800 That's simpler than testing the two special cases "/" and "//", 2824 That's simpler than testing the two special cases "/" and "//",
2801 and it's a safe optimization here. */ 2825 and it's a safe optimization here. */
2802 char *buf = SAFE_ALLOCA (len + 3); 2826 char *buf = SAFE_ALLOCA (len + 3);
2803 memcpy (buf, file, len); 2827 memcpy (buf, data, len);
2804 strcpy (buf + len, &"/."[file[len - 1] == '/']); 2828 strcpy (buf + len, &"/."[data[len - 1] == '/']);
2805 dir = buf; 2829 dir = buf;
2806 } 2830 }
2807 2831
@@ -3624,13 +3648,14 @@ by calling `format-decode', which see. */)
3624 report_file_error ("Read error", orig_filename); 3648 report_file_error ("Read error", orig_filename);
3625 else if (nread > 0) 3649 else if (nread > 0)
3626 { 3650 {
3651 AUTO_STRING (name, " *code-converting-work*");
3627 struct buffer *prev = current_buffer; 3652 struct buffer *prev = current_buffer;
3628 Lisp_Object workbuf; 3653 Lisp_Object workbuf;
3629 struct buffer *buf; 3654 struct buffer *buf;
3630 3655
3631 record_unwind_current_buffer (); 3656 record_unwind_current_buffer ();
3632 3657
3633 workbuf = Fget_buffer_create (build_string (" *code-converting-work*")); 3658 workbuf = Fget_buffer_create (name);
3634 buf = XBUFFER (workbuf); 3659 buf = XBUFFER (workbuf);
3635 3660
3636 delete_all_overlays (buf); 3661 delete_all_overlays (buf);
@@ -5292,20 +5317,12 @@ If BUF is omitted or nil, it defaults to the current buffer.
5292See Info node `(elisp)Modification Time' for more details. */) 5317See Info node `(elisp)Modification Time' for more details. */)
5293 (Lisp_Object buf) 5318 (Lisp_Object buf)
5294{ 5319{
5295 struct buffer *b; 5320 struct buffer *b = decode_buffer (buf);
5296 struct stat st; 5321 struct stat st;
5297 Lisp_Object handler; 5322 Lisp_Object handler;
5298 Lisp_Object filename; 5323 Lisp_Object filename;
5299 struct timespec mtime; 5324 struct timespec mtime;
5300 5325
5301 if (NILP (buf))
5302 b = current_buffer;
5303 else
5304 {
5305 CHECK_BUFFER (buf);
5306 b = XBUFFER (buf);
5307 }
5308
5309 if (!STRINGP (BVAR (b, filename))) return Qt; 5326 if (!STRINGP (BVAR (b, filename))) return Qt;
5310 if (b->modtime.tv_nsec == UNKNOWN_MODTIME_NSECS) return Qt; 5327 if (b->modtime.tv_nsec == UNKNOWN_MODTIME_NSECS) return Qt;
5311 5328
@@ -5399,7 +5416,7 @@ An argument specifies the modification time value to use
5399static Lisp_Object 5416static Lisp_Object
5400auto_save_error (Lisp_Object error_val) 5417auto_save_error (Lisp_Object error_val)
5401{ 5418{
5402 Lisp_Object args[3], msg; 5419 Lisp_Object msg;
5403 int i; 5420 int i;
5404 struct gcpro gcpro1; 5421 struct gcpro gcpro1;
5405 5422
@@ -5407,10 +5424,10 @@ auto_save_error (Lisp_Object error_val)
5407 5424
5408 ring_bell (XFRAME (selected_frame)); 5425 ring_bell (XFRAME (selected_frame));
5409 5426
5410 args[0] = build_string ("Auto-saving %s: %s"); 5427 AUTO_STRING (format, "Auto-saving %s: %s");
5411 args[1] = BVAR (current_buffer, name); 5428 msg = Fformat (3, ((Lisp_Object [])
5412 args[2] = Ferror_message_string (error_val); 5429 {format, BVAR (current_buffer, name),
5413 msg = Fformat (3, args); 5430 Ferror_message_string (error_val)}));
5414 GCPRO1 (msg); 5431 GCPRO1 (msg);
5415 5432
5416 for (i = 0; i < 3; ++i) 5433 for (i = 0; i < 3; ++i)
diff --git a/src/fns.c b/src/fns.c
index 33c02598359..e891fdbf1d5 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include <time.h> 24#include <time.h>
25 25
26#include <intprops.h> 26#include <intprops.h>
27#include <vla.h>
27 28
28#include "lisp.h" 29#include "lisp.h"
29#include "commands.h" 30#include "commands.h"
@@ -41,6 +42,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41#endif 42#endif
42 43
43Lisp_Object Qstring_lessp; 44Lisp_Object Qstring_lessp;
45static Lisp_Object Qstring_collate_lessp, Qstring_collate_equalp;
44static Lisp_Object Qprovide, Qrequire; 46static Lisp_Object Qprovide, Qrequire;
45static Lisp_Object Qyes_or_no_p_history; 47static Lisp_Object Qyes_or_no_p_history;
46Lisp_Object Qcursor_in_echo_area; 48Lisp_Object Qcursor_in_echo_area;
@@ -49,6 +51,8 @@ static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
49 51
50static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; 52static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512;
51 53
54static void sort_vector_copy (Lisp_Object, ptrdiff_t,
55 Lisp_Object [restrict], Lisp_Object [restrict]);
52static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object); 56static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object);
53 57
54DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, 58DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
@@ -343,6 +347,100 @@ Symbols are also allowed; their print names are used instead. */)
343 } 347 }
344 return i1 < SCHARS (s2) ? Qt : Qnil; 348 return i1 < SCHARS (s2) ? Qt : Qnil;
345} 349}
350
351DEFUN ("string-collate-lessp", Fstring_collate_lessp, Sstring_collate_lessp, 2, 4, 0,
352 doc: /* Return t if first arg string is less than second in collation order.
353Symbols are also allowed; their print names are used instead.
354
355This function obeys the conventions for collation order in your
356locale settings. For example, punctuation and whitespace characters
357might be considered less significant for sorting:
358
359\(sort '\("11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp)
360 => \("11" "1 1" "1.1" "12" "1 2" "1.2")
361
362The optional argument LOCALE, a string, overrides the setting of your
363current locale identifier for collation. The value is system
364dependent; a LOCALE \"en_US.UTF-8\" is applicable on POSIX systems,
365while it would be, e.g., \"enu_USA.1252\" on MS-Windows systems.
366
367If IGNORE-CASE is non-nil, characters are converted to lower-case
368before comparing them.
369
370To emulate Unicode-compliant collation on MS-Windows systems,
371bind `w32-collate-ignore-punctuation' to a non-nil value, since
372the codeset part of the locale cannot be \"UTF-8\" on MS-Windows.
373
374If your system does not support a locale environment, this function
375behaves like `string-lessp'. */)
376 (Lisp_Object s1, Lisp_Object s2, Lisp_Object locale, Lisp_Object ignore_case)
377{
378#if defined __STDC_ISO_10646__ || defined WINDOWSNT
379 /* Check parameters. */
380 if (SYMBOLP (s1))
381 s1 = SYMBOL_NAME (s1);
382 if (SYMBOLP (s2))
383 s2 = SYMBOL_NAME (s2);
384 CHECK_STRING (s1);
385 CHECK_STRING (s2);
386 if (!NILP (locale))
387 CHECK_STRING (locale);
388
389 return (str_collate (s1, s2, locale, ignore_case) < 0) ? Qt : Qnil;
390
391#else /* !__STDC_ISO_10646__, !WINDOWSNT */
392 return Fstring_lessp (s1, s2);
393#endif /* !__STDC_ISO_10646__, !WINDOWSNT */
394}
395
396DEFUN ("string-collate-equalp", Fstring_collate_equalp, Sstring_collate_equalp, 2, 4, 0,
397 doc: /* Return t if two strings have identical contents.
398Symbols are also allowed; their print names are used instead.
399
400This function obeys the conventions for collation order in your locale
401settings. For example, characters with different coding points but
402the same meaning might be considered as equal, like different grave
403accent Unicode characters:
404
405\(string-collate-equalp \(string ?\\uFF40) \(string ?\\u1FEF))
406 => t
407
408The optional argument LOCALE, a string, overrides the setting of your
409current locale identifier for collation. The value is system
410dependent; a LOCALE \"en_US.UTF-8\" is applicable on POSIX systems,
411while it would be \"enu_USA.1252\" on MS Windows systems.
412
413If IGNORE-CASE is non-nil, characters are converted to lower-case
414before comparing them.
415
416To emulate Unicode-compliant collation on MS-Windows systems,
417bind `w32-collate-ignore-punctuation' to a non-nil value, since
418the codeset part of the locale cannot be \"UTF-8\" on MS-Windows.
419
420If your system does not support a locale environment, this function
421behaves like `string-equal'.
422
423Do NOT use this function to compare file names for equality, only
424for sorting them. */)
425 (Lisp_Object s1, Lisp_Object s2, Lisp_Object locale, Lisp_Object ignore_case)
426{
427#if defined __STDC_ISO_10646__ || defined WINDOWSNT
428 /* Check parameters. */
429 if (SYMBOLP (s1))
430 s1 = SYMBOL_NAME (s1);
431 if (SYMBOLP (s2))
432 s2 = SYMBOL_NAME (s2);
433 CHECK_STRING (s1);
434 CHECK_STRING (s2);
435 if (!NILP (locale))
436 CHECK_STRING (locale);
437
438 return (str_collate (s1, s2, locale, ignore_case) == 0) ? Qt : Qnil;
439
440#else /* !__STDC_ISO_10646__, !WINDOWSNT */
441 return Fstring_equal (s1, s2);
442#endif /* !__STDC_ISO_10646__, !WINDOWSNT */
443}
346 444
347static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args, 445static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args,
348 enum Lisp_Type target_type, bool last_special); 446 enum Lisp_Type target_type, bool last_special);
@@ -1773,13 +1871,12 @@ See also the function `nreverse', which is used more often. */)
1773 wrong_type_argument (Qsequencep, seq); 1871 wrong_type_argument (Qsequencep, seq);
1774 return new; 1872 return new;
1775} 1873}
1776 1874
1777DEFUN ("sort", Fsort, Ssort, 2, 2, 0, 1875/* Sort LIST using PREDICATE, preserving original order of elements
1778 doc: /* Sort LIST, stably, comparing elements using PREDICATE. 1876 considered as equal. */
1779Returns the sorted list. LIST is modified by side effects. 1877
1780PREDICATE is called with two elements of LIST, and should return non-nil 1878static Lisp_Object
1781if the first element should sort before the second. */) 1879sort_list (Lisp_Object list, Lisp_Object predicate)
1782 (Lisp_Object list, Lisp_Object predicate)
1783{ 1880{
1784 Lisp_Object front, back; 1881 Lisp_Object front, back;
1785 register Lisp_Object len, tem; 1882 register Lisp_Object len, tem;
@@ -1804,6 +1901,126 @@ if the first element should sort before the second. */)
1804 return merge (front, back, predicate); 1901 return merge (front, back, predicate);
1805} 1902}
1806 1903
1904/* Using PRED to compare, return whether A and B are in order.
1905 Compare stably when A appeared before B in the input. */
1906static bool
1907inorder (Lisp_Object pred, Lisp_Object a, Lisp_Object b)
1908{
1909 return NILP (call2 (pred, b, a));
1910}
1911
1912/* Using PRED to compare, merge from ALEN-length A and BLEN-length B
1913 into DEST. Argument arrays must be nonempty and must not overlap,
1914 except that B might be the last part of DEST. */
1915static void
1916merge_vectors (Lisp_Object pred,
1917 ptrdiff_t alen, Lisp_Object const a[restrict VLA_ELEMS (alen)],
1918 ptrdiff_t blen, Lisp_Object const b[VLA_ELEMS (blen)],
1919 Lisp_Object dest[VLA_ELEMS (alen + blen)])
1920{
1921 eassume (0 < alen && 0 < blen);
1922 Lisp_Object const *alim = a + alen;
1923 Lisp_Object const *blim = b + blen;
1924
1925 while (true)
1926 {
1927 if (inorder (pred, a[0], b[0]))
1928 {
1929 *dest++ = *a++;
1930 if (a == alim)
1931 {
1932 if (dest != b)
1933 memcpy (dest, b, (blim - b) * sizeof *dest);
1934 return;
1935 }
1936 }
1937 else
1938 {
1939 *dest++ = *b++;
1940 if (b == blim)
1941 {
1942 memcpy (dest, a, (alim - a) * sizeof *dest);
1943 return;
1944 }
1945 }
1946 }
1947}
1948
1949/* Using PRED to compare, sort LEN-length VEC in place, using TMP for
1950 temporary storage. LEN must be at least 2. */
1951static void
1952sort_vector_inplace (Lisp_Object pred, ptrdiff_t len,
1953 Lisp_Object vec[restrict VLA_ELEMS (len)],
1954 Lisp_Object tmp[restrict VLA_ELEMS (len >> 1)])
1955{
1956 eassume (2 <= len);
1957 ptrdiff_t halflen = len >> 1;
1958 sort_vector_copy (pred, halflen, vec, tmp);
1959 if (1 < len - halflen)
1960 sort_vector_inplace (pred, len - halflen, vec + halflen, vec);
1961 merge_vectors (pred, halflen, tmp, len - halflen, vec + halflen, vec);
1962}
1963
1964/* Using PRED to compare, sort from LEN-length SRC into DST.
1965 Len must be positive. */
1966static void
1967sort_vector_copy (Lisp_Object pred, ptrdiff_t len,
1968 Lisp_Object src[restrict VLA_ELEMS (len)],
1969 Lisp_Object dest[restrict VLA_ELEMS (len)])
1970{
1971 eassume (0 < len);
1972 ptrdiff_t halflen = len >> 1;
1973 if (halflen < 1)
1974 dest[0] = src[0];
1975 else
1976 {
1977 if (1 < halflen)
1978 sort_vector_inplace (pred, halflen, src, dest);
1979 if (1 < len - halflen)
1980 sort_vector_inplace (pred, len - halflen, src + halflen, dest);
1981 merge_vectors (pred, halflen, src, len - halflen, src + halflen, dest);
1982 }
1983}
1984
1985/* Sort VECTOR in place using PREDICATE, preserving original order of
1986 elements considered as equal. */
1987
1988static void
1989sort_vector (Lisp_Object vector, Lisp_Object predicate)
1990{
1991 ptrdiff_t len = ASIZE (vector);
1992 if (len < 2)
1993 return;
1994 ptrdiff_t halflen = len >> 1;
1995 Lisp_Object *tmp;
1996 struct gcpro gcpro1, gcpro2;
1997 GCPRO2 (vector, predicate);
1998 USE_SAFE_ALLOCA;
1999 SAFE_ALLOCA_LISP (tmp, halflen);
2000 for (ptrdiff_t i = 0; i < halflen; i++)
2001 tmp[i] = make_number (0);
2002 sort_vector_inplace (predicate, len, XVECTOR (vector)->contents, tmp);
2003 SAFE_FREE ();
2004 UNGCPRO;
2005}
2006
2007DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
2008 doc: /* Sort SEQ, stably, comparing elements using PREDICATE.
2009Returns the sorted sequence. SEQ should be a list or vector. SEQ is
2010modified by side effects. PREDICATE is called with two elements of
2011SEQ, and should return non-nil if the first element should sort before
2012the second. */)
2013 (Lisp_Object seq, Lisp_Object predicate)
2014{
2015 if (CONSP (seq))
2016 seq = sort_list (seq, predicate);
2017 else if (VECTORP (seq))
2018 sort_vector (seq, predicate);
2019 else if (!NILP (seq))
2020 wrong_type_argument (Qsequencep, seq);
2021 return seq;
2022}
2023
1807Lisp_Object 2024Lisp_Object
1808merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred) 2025merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred)
1809{ 2026{
@@ -1841,8 +2058,7 @@ merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred)
1841 Fsetcdr (tail, l1); 2058 Fsetcdr (tail, l1);
1842 return value; 2059 return value;
1843 } 2060 }
1844 tem = call2 (pred, Fcar (l2), Fcar (l1)); 2061 if (inorder (pred, Fcar (l1), Fcar (l2)))
1845 if (NILP (tem))
1846 { 2062 {
1847 tem = l1; 2063 tem = l1;
1848 l1 = Fcdr (l1); 2064 l1 = Fcdr (l1);
@@ -2490,8 +2706,7 @@ If dialog boxes are supported, a dialog box will be used
2490if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) 2706if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */)
2491 (Lisp_Object prompt) 2707 (Lisp_Object prompt)
2492{ 2708{
2493 register Lisp_Object ans; 2709 Lisp_Object ans;
2494 Lisp_Object args[2];
2495 struct gcpro gcpro1; 2710 struct gcpro gcpro1;
2496 2711
2497 CHECK_STRING (prompt); 2712 CHECK_STRING (prompt);
@@ -2510,10 +2725,8 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */)
2510 return obj; 2725 return obj;
2511 } 2726 }
2512 2727
2513 args[0] = prompt; 2728 AUTO_STRING (yes_or_no, "(yes or no) ");
2514 args[1] = build_string ("(yes or no) "); 2729 prompt = Fconcat (2, (Lisp_Object []) {prompt, yes_or_no});
2515 prompt = Fconcat (2, args);
2516
2517 GCPRO1 (prompt); 2730 GCPRO1 (prompt);
2518 2731
2519 while (1) 2732 while (1)
@@ -3071,7 +3284,6 @@ into shorter lines. */)
3071 if (encoded_length < 0) 3284 if (encoded_length < 0)
3072 { 3285 {
3073 /* The encoding wasn't possible. */ 3286 /* The encoding wasn't possible. */
3074 SAFE_FREE ();
3075 error ("Multibyte character in data for base64 encoding"); 3287 error ("Multibyte character in data for base64 encoding");
3076 } 3288 }
3077 3289
@@ -3216,7 +3428,6 @@ If the region can't be decoded, signal an error and don't modify the buffer. */
3216 if (decoded_length < 0) 3428 if (decoded_length < 0)
3217 { 3429 {
3218 /* The decoding wasn't possible. */ 3430 /* The decoding wasn't possible. */
3219 SAFE_FREE ();
3220 error ("Invalid base64 data"); 3431 error ("Invalid base64 data");
3221 } 3432 }
3222 3433
@@ -3784,12 +3995,9 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
3784#ifdef ENABLE_CHECKING 3995#ifdef ENABLE_CHECKING
3785 if (HASH_TABLE_P (Vpurify_flag) 3996 if (HASH_TABLE_P (Vpurify_flag)
3786 && XHASH_TABLE (Vpurify_flag) == h) 3997 && XHASH_TABLE (Vpurify_flag) == h)
3787 { 3998 Fmessage (2, ((Lisp_Object [])
3788 Lisp_Object args[2]; 3999 { build_string ("Growing hash table to: %d"),
3789 args[0] = build_string ("Growing hash table to: %d"); 4000 make_number (new_size) }));
3790 args[1] = make_number (new_size);
3791 Fmessage (2, args);
3792 }
3793#endif 4001#endif
3794 4002
3795 set_hash_key_and_value (h, larger_vector (h->key_and_value, 4003 set_hash_key_and_value (h, larger_vector (h->key_and_value,
@@ -4269,13 +4477,10 @@ sxhash (Lisp_Object obj, int depth)
4269 break; 4477 break;
4270 4478
4271 case Lisp_Misc: 4479 case Lisp_Misc:
4480 case Lisp_Symbol:
4272 hash = XHASH (obj); 4481 hash = XHASH (obj);
4273 break; 4482 break;
4274 4483
4275 case Lisp_Symbol:
4276 obj = SYMBOL_NAME (obj);
4277 /* Fall through. */
4278
4279 case Lisp_String: 4484 case Lisp_String:
4280 hash = sxhash_string (SSDATA (obj), SBYTES (obj)); 4485 hash = sxhash_string (SSDATA (obj), SBYTES (obj));
4281 break; 4486 break;
@@ -4363,12 +4568,12 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4363{ 4568{
4364 Lisp_Object test, size, rehash_size, rehash_threshold, weak; 4569 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
4365 struct hash_table_test testdesc; 4570 struct hash_table_test testdesc;
4366 char *used;
4367 ptrdiff_t i; 4571 ptrdiff_t i;
4572 USE_SAFE_ALLOCA;
4368 4573
4369 /* The vector `used' is used to keep track of arguments that 4574 /* The vector `used' is used to keep track of arguments that
4370 have been consumed. */ 4575 have been consumed. */
4371 used = alloca (nargs * sizeof *used); 4576 char *used = SAFE_ALLOCA (nargs * sizeof *used);
4372 memset (used, 0, nargs * sizeof *used); 4577 memset (used, 0, nargs * sizeof *used);
4373 4578
4374 /* See if there's a `:test TEST' among the arguments. */ 4579 /* See if there's a `:test TEST' among the arguments. */
@@ -4435,6 +4640,7 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4435 if (!used[i]) 4640 if (!used[i])
4436 signal_error ("Invalid argument list", args[i]); 4641 signal_error ("Invalid argument list", args[i]);
4437 4642
4643 SAFE_FREE ();
4438 return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak); 4644 return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak);
4439} 4645}
4440 4646
@@ -4919,6 +5125,8 @@ syms_of_fns (void)
4919 defsubr (&Sdefine_hash_table_test); 5125 defsubr (&Sdefine_hash_table_test);
4920 5126
4921 DEFSYM (Qstring_lessp, "string-lessp"); 5127 DEFSYM (Qstring_lessp, "string-lessp");
5128 DEFSYM (Qstring_collate_lessp, "string-collate-lessp");
5129 DEFSYM (Qstring_collate_equalp, "string-collate-equalp");
4922 DEFSYM (Qprovide, "provide"); 5130 DEFSYM (Qprovide, "provide");
4923 DEFSYM (Qrequire, "require"); 5131 DEFSYM (Qrequire, "require");
4924 DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history"); 5132 DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history");
@@ -4972,6 +5180,8 @@ this variable. */);
4972 defsubr (&Sstring_equal); 5180 defsubr (&Sstring_equal);
4973 defsubr (&Scompare_strings); 5181 defsubr (&Scompare_strings);
4974 defsubr (&Sstring_lessp); 5182 defsubr (&Sstring_lessp);
5183 defsubr (&Sstring_collate_lessp);
5184 defsubr (&Sstring_collate_equalp);
4975 defsubr (&Sappend); 5185 defsubr (&Sappend);
4976 defsubr (&Sconcat); 5186 defsubr (&Sconcat);
4977 defsubr (&Svconcat); 5187 defsubr (&Svconcat);
diff --git a/src/font.c b/src/font.c
index 054a68bfd94..08a25455cf8 100644
--- a/src/font.c
+++ b/src/font.c
@@ -273,10 +273,8 @@ static int num_font_drivers;
273Lisp_Object 273Lisp_Object
274font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol) 274font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol)
275{ 275{
276 ptrdiff_t i; 276 ptrdiff_t i, nbytes, nchars;
277 Lisp_Object tem; 277 Lisp_Object tem, name, obarray;
278 Lisp_Object obarray;
279 ptrdiff_t nbytes, nchars;
280 278
281 if (len == 1 && *str == '*') 279 if (len == 1 && *str == '*')
282 return Qnil; 280 return Qnil;
@@ -307,12 +305,11 @@ font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol)
307 parse_str_as_multibyte ((unsigned char *) str, len, &nchars, &nbytes); 305 parse_str_as_multibyte ((unsigned char *) str, len, &nchars, &nbytes);
308 tem = oblookup (obarray, str, 306 tem = oblookup (obarray, str,
309 (len == nchars || len != nbytes) ? len : nchars, len); 307 (len == nchars || len != nbytes) ? len : nchars, len);
310
311 if (SYMBOLP (tem)) 308 if (SYMBOLP (tem))
312 return tem; 309 return tem;
313 tem = make_specified_string (str, nchars, len, 310 name = make_specified_string (str, nchars, len,
314 len != nchars && len == nbytes); 311 len != nchars && len == nbytes);
315 return Fintern (tem, obarray); 312 return intern_driver (name, obarray, XINT (tem));
316} 313}
317 314
318/* Return a pixel size of font-spec SPEC on frame F. */ 315/* Return a pixel size of font-spec SPEC on frame F. */
@@ -366,7 +363,7 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val,
366 { 363 {
367 int i, j; 364 int i, j;
368 char *s; 365 char *s;
369 Lisp_Object args[2], elt; 366 Lisp_Object elt;
370 367
371 /* At first try exact match. */ 368 /* At first try exact match. */
372 for (i = 0; i < len; i++) 369 for (i = 0; i < len; i++)
@@ -398,9 +395,9 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val,
398 eassert (len < 255); 395 eassert (len < 255);
399 elt = Fmake_vector (make_number (2), make_number (100)); 396 elt = Fmake_vector (make_number (2), make_number (100));
400 ASET (elt, 1, val); 397 ASET (elt, 1, val);
401 args[0] = table; 398 ASET (font_style_table, prop - FONT_WEIGHT_INDEX,
402 args[1] = Fmake_vector (make_number (1), elt); 399 Fvconcat (2, ((Lisp_Object [])
403 ASET (font_style_table, prop - FONT_WEIGHT_INDEX, Fvconcat (2, args)); 400 { table, Fmake_vector (make_number (1), elt) })));
404 return (100 << 8) | (i << 4); 401 return (100 << 8) | (i << 4);
405 } 402 }
406 else 403 else
@@ -1186,13 +1183,22 @@ font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font)
1186 { 1183 {
1187 val = prop[XLFD_ENCODING_INDEX]; 1184 val = prop[XLFD_ENCODING_INDEX];
1188 if (! NILP (val)) 1185 if (! NILP (val))
1189 val = concat2 (build_string ("*-"), SYMBOL_NAME (val)); 1186 {
1187 AUTO_STRING (star_dash, "*-");
1188 val = concat2 (star_dash, SYMBOL_NAME (val));
1189 }
1190 } 1190 }
1191 else if (NILP (prop[XLFD_ENCODING_INDEX])) 1191 else if (NILP (prop[XLFD_ENCODING_INDEX]))
1192 val = concat2 (SYMBOL_NAME (val), build_string ("-*")); 1192 {
1193 AUTO_STRING (dash_star, "-*");
1194 val = concat2 (SYMBOL_NAME (val), dash_star);
1195 }
1193 else 1196 else
1194 val = concat3 (SYMBOL_NAME (val), build_string ("-"), 1197 {
1195 SYMBOL_NAME (prop[XLFD_ENCODING_INDEX])); 1198 AUTO_STRING (dash, "-");
1199 val = concat3 (SYMBOL_NAME (val), dash,
1200 SYMBOL_NAME (prop[XLFD_ENCODING_INDEX]));
1201 }
1196 if (! NILP (val)) 1202 if (! NILP (val))
1197 ASET (font, FONT_REGISTRY_INDEX, Fintern (val, Qnil)); 1203 ASET (font, FONT_REGISTRY_INDEX, Fintern (val, Qnil));
1198 1204
@@ -1299,6 +1305,9 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1299 1305
1300 val = AREF (font, FONT_SIZE_INDEX); 1306 val = AREF (font, FONT_SIZE_INDEX);
1301 eassert (NUMBERP (val) || NILP (val)); 1307 eassert (NUMBERP (val) || NILP (val));
1308 char font_size_index_buf[sizeof "-*"
1309 + max (INT_STRLEN_BOUND (EMACS_INT),
1310 1 + DBL_MAX_10_EXP + 1)];
1302 if (INTEGERP (val)) 1311 if (INTEGERP (val))
1303 { 1312 {
1304 EMACS_INT v = XINT (val); 1313 EMACS_INT v = XINT (val);
@@ -1306,8 +1315,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1306 v = pixel_size; 1315 v = pixel_size;
1307 if (v > 0) 1316 if (v > 0)
1308 { 1317 {
1309 f[XLFD_PIXEL_INDEX] = p = 1318 f[XLFD_PIXEL_INDEX] = p = font_size_index_buf;
1310 alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
1311 sprintf (p, "%"pI"d-*", v); 1319 sprintf (p, "%"pI"d-*", v);
1312 } 1320 }
1313 else 1321 else
@@ -1316,21 +1324,22 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1316 else if (FLOATP (val)) 1324 else if (FLOATP (val))
1317 { 1325 {
1318 double v = XFLOAT_DATA (val) * 10; 1326 double v = XFLOAT_DATA (val) * 10;
1319 f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1); 1327 f[XLFD_PIXEL_INDEX] = p = font_size_index_buf;
1320 sprintf (p, "*-%.0f", v); 1328 sprintf (p, "*-%.0f", v);
1321 } 1329 }
1322 else 1330 else
1323 f[XLFD_PIXEL_INDEX] = "*-*"; 1331 f[XLFD_PIXEL_INDEX] = "*-*";
1324 1332
1333 char dpi_index_buf[sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT)];
1325 if (INTEGERP (AREF (font, FONT_DPI_INDEX))) 1334 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1326 { 1335 {
1327 EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX)); 1336 EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
1328 f[XLFD_RESX_INDEX] = p = 1337 f[XLFD_RESX_INDEX] = p = dpi_index_buf;
1329 alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
1330 sprintf (p, "%"pI"d-%"pI"d", v, v); 1338 sprintf (p, "%"pI"d-%"pI"d", v, v);
1331 } 1339 }
1332 else 1340 else
1333 f[XLFD_RESX_INDEX] = "*-*"; 1341 f[XLFD_RESX_INDEX] = "*-*";
1342
1334 if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) 1343 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1335 { 1344 {
1336 EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX)); 1345 EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
@@ -1342,13 +1351,16 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1342 } 1351 }
1343 else 1352 else
1344 f[XLFD_SPACING_INDEX] = "*"; 1353 f[XLFD_SPACING_INDEX] = "*";
1354
1355 char avgwidth_index_buf[INT_BUFSIZE_BOUND (EMACS_INT)];
1345 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) 1356 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1346 { 1357 {
1347 f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT)); 1358 f[XLFD_AVGWIDTH_INDEX] = p = avgwidth_index_buf;
1348 sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX))); 1359 sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
1349 } 1360 }
1350 else 1361 else
1351 f[XLFD_AVGWIDTH_INDEX] = "*"; 1362 f[XLFD_AVGWIDTH_INDEX] = "*";
1363
1352 len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", 1364 len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
1353 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], 1365 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
1354 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], 1366 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
@@ -1751,7 +1763,7 @@ font_parse_name (char *name, ptrdiff_t namelen, Lisp_Object font)
1751void 1763void
1752font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Object font_spec) 1764font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Object font_spec)
1753{ 1765{
1754 int len; 1766 ptrdiff_t len;
1755 char *p0, *p1; 1767 char *p0, *p1;
1756 1768
1757 if (! NILP (family) 1769 if (! NILP (family)
@@ -1782,10 +1794,8 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
1782 p1 = strchr (p0, '-'); 1794 p1 = strchr (p0, '-');
1783 if (! p1) 1795 if (! p1)
1784 { 1796 {
1785 if (SDATA (registry)[len - 1] == '*') 1797 AUTO_STRING (extra, ("*-*" + (len && p0[len - 1] == '*')));
1786 registry = concat2 (registry, build_string ("-*")); 1798 registry = concat2 (registry, extra);
1787 else
1788 registry = concat2 (registry, build_string ("*-*"));
1789 } 1799 }
1790 registry = Fdowncase (registry); 1800 registry = Fdowncase (registry);
1791 ASET (font_spec, FONT_REGISTRY_INDEX, Fintern (registry, Qnil)); 1801 ASET (font_spec, FONT_REGISTRY_INDEX, Fintern (registry, Qnil));
@@ -2185,13 +2195,17 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
2185static Lisp_Object 2195static Lisp_Object
2186font_vconcat_entity_vectors (Lisp_Object list) 2196font_vconcat_entity_vectors (Lisp_Object list)
2187{ 2197{
2188 int nargs = XINT (Flength (list)); 2198 EMACS_INT nargs = XFASTINT (Flength (list));
2189 Lisp_Object *args = alloca (word_size * nargs); 2199 Lisp_Object *args;
2190 int i; 2200 USE_SAFE_ALLOCA;
2201 SAFE_ALLOCA_LISP (args, nargs);
2202 ptrdiff_t i;
2191 2203
2192 for (i = 0; i < nargs; i++, list = XCDR (list)) 2204 for (i = 0; i < nargs; i++, list = XCDR (list))
2193 args[i] = XCAR (list); 2205 args[i] = XCAR (list);
2194 return Fvconcat (nargs, args); 2206 Lisp_Object result = Fvconcat (nargs, args);
2207 SAFE_FREE ();
2208 return result;
2195} 2209}
2196 2210
2197 2211
@@ -2674,7 +2688,7 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
2674{ 2688{
2675 Lisp_Object entity, val; 2689 Lisp_Object entity, val;
2676 enum font_property_index prop; 2690 enum font_property_index prop;
2677 int i; 2691 ptrdiff_t i;
2678 2692
2679 for (val = Qnil, i = ASIZE (vec) - 1; i >= 0; i--) 2693 for (val = Qnil, i = ASIZE (vec) - 1; i >= 0; i--)
2680 { 2694 {
@@ -3219,9 +3233,10 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
3219 val = attrs[LFACE_FAMILY_INDEX]; 3233 val = attrs[LFACE_FAMILY_INDEX];
3220 val = font_intern_prop (SSDATA (val), SBYTES (val), 1); 3234 val = font_intern_prop (SSDATA (val), SBYTES (val), 1);
3221 } 3235 }
3236 Lisp_Object familybuf[3];
3222 if (NILP (val)) 3237 if (NILP (val))
3223 { 3238 {
3224 family = alloca ((sizeof family[0]) * 2); 3239 family = familybuf;
3225 family[0] = Qnil; 3240 family[0] = Qnil;
3226 family[1] = zero_vector; /* terminator. */ 3241 family[1] = zero_vector; /* terminator. */
3227 } 3242 }
@@ -3242,7 +3257,7 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
3242 } 3257 }
3243 else 3258 else
3244 { 3259 {
3245 family = alloca ((sizeof family[0]) * 3); 3260 family = familybuf;
3246 i = 0; 3261 i = 0;
3247 family[i++] = val; 3262 family[i++] = val;
3248 if (NILP (AREF (spec, FONT_FAMILY_INDEX))) 3263 if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
@@ -3529,8 +3544,9 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
3529 struct font_driver_list **list_table, **next; 3544 struct font_driver_list **list_table, **next;
3530 Lisp_Object tail; 3545 Lisp_Object tail;
3531 int i; 3546 int i;
3547 USE_SAFE_ALLOCA;
3532 3548
3533 list_table = alloca (sizeof list_table[0] * (num_font_drivers + 1)); 3549 SAFE_NALLOCA (list_table, 1, num_font_drivers + 1);
3534 for (i = 0, tail = new_drivers; ! NILP (tail); tail = XCDR (tail)) 3550 for (i = 0, tail = new_drivers; ! NILP (tail); tail = XCDR (tail))
3535 { 3551 {
3536 for (list = f->font_driver_list; list; list = list->next) 3552 for (list = f->font_driver_list; list; list = list->next)
@@ -3551,6 +3567,7 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
3551 next = &(*next)->next; 3567 next = &(*next)->next;
3552 } 3568 }
3553 *next = NULL; 3569 *next = NULL;
3570 SAFE_FREE ();
3554 3571
3555 if (! f->font_driver_list->on) 3572 if (! f->font_driver_list->on)
3556 { /* None of the drivers is enabled: enable them all. 3573 { /* None of the drivers is enabled: enable them all.
@@ -4252,7 +4269,7 @@ the consecutive wildcards are folded into one. */)
4252 { 4269 {
4253 if (NILP (fold_wildcards)) 4270 if (NILP (fold_wildcards))
4254 return font_name; 4271 return font_name;
4255 strcpy (name, SSDATA (font_name)); 4272 lispstpcpy (name, font_name);
4256 namelen = SBYTES (font_name); 4273 namelen = SBYTES (font_name);
4257 goto done; 4274 goto done;
4258 } 4275 }
@@ -4670,9 +4687,10 @@ DEFUN ("font-get-glyphs", Ffont_get_glyphs, Sfont_get_glyphs, 3, 4, 0,
4670 doc: 4687 doc:
4671 /* Return a vector of FONT-OBJECT's glyphs for the specified characters. 4688 /* Return a vector of FONT-OBJECT's glyphs for the specified characters.
4672FROM and TO are positions (integers or markers) specifying a region 4689FROM and TO are positions (integers or markers) specifying a region
4673of the current buffer. 4690of the current buffer, and can be in either order. If the optional
4674If the optional fourth arg OBJECT is not nil, it is a string or a 4691fourth arg OBJECT is not nil, it is a string or a vector containing
4675vector containing the target characters. 4692the target characters between indices FROM and TO, which are treated
4693as in `substring'.
4676 4694
4677Each element is a vector containing information of a glyph in this format: 4695Each element is a vector containing information of a glyph in this format:
4678 [FROM-IDX TO-IDX C CODE WIDTH LBEARING RBEARING ASCENT DESCENT ADJUSTMENT] 4696 [FROM-IDX TO-IDX C CODE WIDTH LBEARING RBEARING ASCENT DESCENT ADJUSTMENT]
@@ -4715,45 +4733,50 @@ the corresponding element is nil. */)
4715 else if (STRINGP (object)) 4733 else if (STRINGP (object))
4716 { 4734 {
4717 const unsigned char *p; 4735 const unsigned char *p;
4736 ptrdiff_t ifrom, ito;
4718 4737
4719 CHECK_NUMBER (from); 4738 validate_subarray (object, from, to, SCHARS (object), &ifrom, &ito);
4720 CHECK_NUMBER (to); 4739 if (ifrom == ito)
4721 if (XINT (from) < 0 || XINT (from) > XINT (to)
4722 || XINT (to) > SCHARS (object))
4723 args_out_of_range_3 (object, from, to);
4724 if (EQ (from, to))
4725 return Qnil; 4740 return Qnil;
4726 len = XFASTINT (to) - XFASTINT (from); 4741 len = ito - ifrom;
4727 SAFE_ALLOCA_LISP (chars, len); 4742 SAFE_ALLOCA_LISP (chars, len);
4728 p = SDATA (object); 4743 p = SDATA (object);
4729 if (STRING_MULTIBYTE (object)) 4744 if (STRING_MULTIBYTE (object))
4730 for (i = 0; i < len; i++) 4745 {
4746 int c;
4747
4748 /* Skip IFROM characters from the beginning. */
4749 for (i = 0; i < ifrom; i++)
4750 c = STRING_CHAR_ADVANCE (p);
4751
4752 /* Now fetch an interesting characters. */
4753 for (i = 0; i < len; i++)
4731 { 4754 {
4732 int c = STRING_CHAR_ADVANCE (p); 4755 c = STRING_CHAR_ADVANCE (p);
4733 chars[i] = make_number (c); 4756 chars[i] = make_number (c);
4734 } 4757 }
4758 }
4735 else 4759 else
4736 for (i = 0; i < len; i++) 4760 for (i = 0; i < len; i++)
4737 chars[i] = make_number (p[i]); 4761 chars[i] = make_number (p[ifrom + i]);
4738 } 4762 }
4739 else 4763 else if (VECTORP (object))
4740 { 4764 {
4741 CHECK_VECTOR (object); 4765 ptrdiff_t ifrom, ito;
4742 CHECK_NUMBER (from); 4766
4743 CHECK_NUMBER (to); 4767 validate_subarray (object, from, to, ASIZE (object), &ifrom, &ito);
4744 if (XINT (from) < 0 || XINT (from) > XINT (to) 4768 if (ifrom == ito)
4745 || XINT (to) > ASIZE (object))
4746 args_out_of_range_3 (object, from, to);
4747 if (EQ (from, to))
4748 return Qnil; 4769 return Qnil;
4749 len = XFASTINT (to) - XFASTINT (from); 4770 len = ito - ifrom;
4750 for (i = 0; i < len; i++) 4771 for (i = 0; i < len; i++)
4751 { 4772 {
4752 Lisp_Object elt = AREF (object, XFASTINT (from) + i); 4773 Lisp_Object elt = AREF (object, ifrom + i);
4753 CHECK_CHARACTER (elt); 4774 CHECK_CHARACTER (elt);
4754 } 4775 }
4755 chars = aref_addr (object, XFASTINT (from)); 4776 chars = aref_addr (object, ifrom);
4756 } 4777 }
4778 else
4779 wrong_type_argument (Qarrayp, object);
4757 4780
4758 vec = make_uninit_vector (len); 4781 vec = make_uninit_vector (len);
4759 for (i = 0; i < len; i++) 4782 for (i = 0; i < len; i++)
@@ -5005,7 +5028,7 @@ font_add_log (const char *action, Lisp_Object arg, Lisp_Object result)
5005 if (FONTP (arg)) 5028 if (FONTP (arg))
5006 { 5029 {
5007 Lisp_Object tail, elt; 5030 Lisp_Object tail, elt;
5008 Lisp_Object equalstr = build_string ("="); 5031 AUTO_STRING (equal, "=");
5009 5032
5010 val = Ffont_xlfd_name (arg, Qt); 5033 val = Ffont_xlfd_name (arg, Qt);
5011 for (tail = AREF (arg, FONT_EXTRA_INDEX); CONSP (tail); 5034 for (tail = AREF (arg, FONT_EXTRA_INDEX); CONSP (tail);
@@ -5015,16 +5038,15 @@ font_add_log (const char *action, Lisp_Object arg, Lisp_Object result)
5015 if (EQ (XCAR (elt), QCscript) 5038 if (EQ (XCAR (elt), QCscript)
5016 && SYMBOLP (XCDR (elt))) 5039 && SYMBOLP (XCDR (elt)))
5017 val = concat3 (val, SYMBOL_NAME (QCscript), 5040 val = concat3 (val, SYMBOL_NAME (QCscript),
5018 concat2 (equalstr, SYMBOL_NAME (XCDR (elt)))); 5041 concat2 (equal, SYMBOL_NAME (XCDR (elt))));
5019 else if (EQ (XCAR (elt), QClang) 5042 else if (EQ (XCAR (elt), QClang)
5020 && SYMBOLP (XCDR (elt))) 5043 && SYMBOLP (XCDR (elt)))
5021 val = concat3 (val, SYMBOL_NAME (QClang), 5044 val = concat3 (val, SYMBOL_NAME (QClang),
5022 concat2 (equalstr, SYMBOL_NAME (XCDR (elt)))); 5045 concat2 (equal, SYMBOL_NAME (XCDR (elt))));
5023 else if (EQ (XCAR (elt), QCotf) 5046 else if (EQ (XCAR (elt), QCotf)
5024 && CONSP (XCDR (elt)) && SYMBOLP (XCAR (XCDR (elt)))) 5047 && CONSP (XCDR (elt)) && SYMBOLP (XCAR (XCDR (elt))))
5025 val = concat3 (val, SYMBOL_NAME (QCotf), 5048 val = concat3 (val, SYMBOL_NAME (QCotf),
5026 concat2 (equalstr, 5049 concat2 (equal, SYMBOL_NAME (XCAR (XCDR (elt)))));
5027 SYMBOL_NAME (XCAR (XCDR (elt)))));
5028 } 5050 }
5029 arg = val; 5051 arg = val;
5030 } 5052 }
@@ -5038,8 +5060,11 @@ font_add_log (const char *action, Lisp_Object arg, Lisp_Object result)
5038 { 5060 {
5039 val = Ffont_xlfd_name (result, Qt); 5061 val = Ffont_xlfd_name (result, Qt);
5040 if (! FONT_SPEC_P (result)) 5062 if (! FONT_SPEC_P (result))
5041 val = concat3 (SYMBOL_NAME (AREF (result, FONT_TYPE_INDEX)), 5063 {
5042 build_string (":"), val); 5064 AUTO_STRING (colon, ":");
5065 val = concat3 (SYMBOL_NAME (AREF (result, FONT_TYPE_INDEX)),
5066 colon, val);
5067 }
5043 result = val; 5068 result = val;
5044 } 5069 }
5045 else if (CONSP (result)) 5070 else if (CONSP (result))
diff --git a/src/font.h b/src/font.h
index cffc035cd49..52783419ebe 100644
--- a/src/font.h
+++ b/src/font.h
@@ -570,9 +570,9 @@ struct font_driver
570 /* Compute the total metrics of the NGLYPHS glyphs specified by 570 /* Compute the total metrics of the NGLYPHS glyphs specified by
571 the font FONT and the sequence of glyph codes CODE, and store the 571 the font FONT and the sequence of glyph codes CODE, and store the
572 result in METRICS. */ 572 result in METRICS. */
573 int (*text_extents) (struct font *font, 573 void (*text_extents) (struct font *font,
574 unsigned *code, int nglyphs, 574 unsigned *code, int nglyphs,
575 struct font_metrics *metrics); 575 struct font_metrics *metrics);
576 576
577#ifdef HAVE_WINDOW_SYSTEM 577#ifdef HAVE_WINDOW_SYSTEM
578 578
diff --git a/src/fontset.c b/src/fontset.c
index d99a3bcb7ef..c415fdfa8fd 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -1079,10 +1079,11 @@ fontset_pattern_regexp (Lisp_Object pattern)
1079 /* If PATTERN is not full XLFD we convert "*" to ".*". Otherwise 1079 /* If PATTERN is not full XLFD we convert "*" to ".*". Otherwise
1080 we convert "*" to "[^-]*" which is much faster in regular 1080 we convert "*" to "[^-]*" which is much faster in regular
1081 expression matching. */ 1081 expression matching. */
1082 if (ndashes < 14) 1082 ptrdiff_t regexsize = (SBYTES (pattern)
1083 p1 = regex = alloca (SBYTES (pattern) + 2 * nstars + 2 * nescs + 1); 1083 + (ndashes < 14 ? 2 : 5) * nstars
1084 else 1084 + 2 * nescs + 1);
1085 p1 = regex = alloca (SBYTES (pattern) + 5 * nstars + 2 * nescs + 1); 1085 USE_SAFE_ALLOCA;
1086 p1 = regex = SAFE_ALLOCA (regexsize);
1086 1087
1087 *p1++ = '^'; 1088 *p1++ = '^';
1088 for (p0 = SDATA (pattern); *p0; p0++) 1089 for (p0 = SDATA (pattern); *p0; p0++)
@@ -1110,6 +1111,7 @@ fontset_pattern_regexp (Lisp_Object pattern)
1110 1111
1111 Vcached_fontset_data = Fcons (build_string (SSDATA (pattern)), 1112 Vcached_fontset_data = Fcons (build_string (SSDATA (pattern)),
1112 build_string ((char *) regex)); 1113 build_string ((char *) regex));
1114 SAFE_FREE ();
1113 } 1115 }
1114 1116
1115 return CACHED_FONTSET_REGEX; 1117 return CACHED_FONTSET_REGEX;
@@ -1460,8 +1462,8 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1460 registry = AREF (font_spec, FONT_REGISTRY_INDEX); 1462 registry = AREF (font_spec, FONT_REGISTRY_INDEX);
1461 if (! NILP (registry)) 1463 if (! NILP (registry))
1462 registry = Fdowncase (SYMBOL_NAME (registry)); 1464 registry = Fdowncase (SYMBOL_NAME (registry));
1463 encoding = find_font_encoding (concat3 (family, build_string ("-"), 1465 AUTO_STRING (dash, "-");
1464 registry)); 1466 encoding = find_font_encoding (concat3 (family, dash, registry));
1465 if (NILP (encoding)) 1467 if (NILP (encoding))
1466 encoding = Qascii; 1468 encoding = Qascii;
1467 1469
@@ -1573,7 +1575,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1573 1575
1574 if (ascii_changed) 1576 if (ascii_changed)
1575 { 1577 {
1576 Lisp_Object tail, fr, alist; 1578 Lisp_Object tail, fr;
1577 int fontset_id = XINT (FONTSET_ID (fontset)); 1579 int fontset_id = XINT (FONTSET_ID (fontset));
1578 1580
1579 set_fontset_ascii (fontset, fontname); 1581 set_fontset_ascii (fontset, fontname);
@@ -1596,8 +1598,8 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
1596 if (! NILP (font_object)) 1598 if (! NILP (font_object))
1597 { 1599 {
1598 update_auto_fontset_alist (font_object, fontset); 1600 update_auto_fontset_alist (font_object, fontset);
1599 alist = list1 (Fcons (Qfont, Fcons (name, font_object))); 1601 AUTO_FRAME_ARG (arg, Qfont, Fcons (name, font_object));
1600 Fmodify_frame_parameters (fr, alist); 1602 Fmodify_frame_parameters (fr, arg);
1601 } 1603 }
1602 } 1604 }
1603 } 1605 }
@@ -1892,7 +1894,9 @@ format is the same as above. */)
1892 1894
1893 /* Recode fontsets realized on FRAME from the base fontset FONTSET 1895 /* Recode fontsets realized on FRAME from the base fontset FONTSET
1894 in the table `realized'. */ 1896 in the table `realized'. */
1895 realized[0] = alloca (word_size * ASIZE (Vfontset_table)); 1897 USE_SAFE_ALLOCA;
1898 SAFE_ALLOCA_LISP (realized[0], 2 * ASIZE (Vfontset_table));
1899 realized[1] = realized[0] + ASIZE (Vfontset_table);
1896 for (i = j = 0; i < ASIZE (Vfontset_table); i++) 1900 for (i = j = 0; i < ASIZE (Vfontset_table); i++)
1897 { 1901 {
1898 elt = FONTSET_FROM_ID (i); 1902 elt = FONTSET_FROM_ID (i);
@@ -1903,7 +1907,6 @@ format is the same as above. */)
1903 } 1907 }
1904 realized[0][j] = Qnil; 1908 realized[0][j] = Qnil;
1905 1909
1906 realized[1] = alloca (word_size * ASIZE (Vfontset_table));
1907 for (i = j = 0; ! NILP (realized[0][i]); i++) 1910 for (i = j = 0; ! NILP (realized[0][i]); i++)
1908 { 1911 {
1909 elt = FONTSET_DEFAULT (realized[0][i]); 1912 elt = FONTSET_DEFAULT (realized[0][i]);
@@ -1995,6 +1998,7 @@ format is the same as above. */)
1995 break; 1998 break;
1996 } 1999 }
1997 2000
2001 SAFE_FREE ();
1998 return tables[0]; 2002 return tables[0];
1999} 2003}
2000 2004
diff --git a/src/frame.c b/src/frame.c
index 501f01a3122..8fac06e2af7 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -219,21 +219,6 @@ frame_inhibit_resize (struct frame *f, bool horizontal)
219 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); 219 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
220} 220}
221 221
222#if 0
223bool
224frame_inhibit_resize (struct frame *f, bool horizontal)
225{
226 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
227
228 return (frame_inhibit_implied_resize
229 || EQ (fullscreen, Qfullboth)
230 || EQ (fullscreen, Qfullscreen)
231 || EQ (fullscreen, Qmaximized)
232 || (horizontal && EQ (fullscreen, Qfullwidth))
233 || (!horizontal && EQ (fullscreen, Qfullheight)));
234}
235#endif
236
237static void 222static void
238set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) 223set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
239{ 224{
@@ -351,7 +336,7 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object p
351 336
352/* Make sure windows sizes of frame F are OK. new_width and new_height 337/* Make sure windows sizes of frame F are OK. new_width and new_height
353 are in pixels. A value of -1 means no change is requested for that 338 are in pixels. A value of -1 means no change is requested for that
354 size (but the frame may still have to be resized to accomodate 339 size (but the frame may still have to be resized to accommodate
355 windows with their minimum sizes. 340 windows with their minimum sizes.
356 341
357 The argument INHIBIT can assume the following values: 342 The argument INHIBIT can assume the following values:
@@ -979,7 +964,7 @@ affects all frames on the same terminal device. */)
979 if (CONSP (terminal)) 964 if (CONSP (terminal))
980 { 965 {
981 terminal = XCDR (terminal); 966 terminal = XCDR (terminal);
982 t = get_terminal (terminal, 1); 967 t = decode_live_terminal (terminal);
983 } 968 }
984#ifdef MSDOS 969#ifdef MSDOS
985 if (t && t != the_only_display_info.terminal) 970 if (t && t != the_only_display_info.terminal)
@@ -994,22 +979,24 @@ affects all frames on the same terminal device. */)
994 { 979 {
995 char *name = 0, *type = 0; 980 char *name = 0, *type = 0;
996 Lisp_Object tty, tty_type; 981 Lisp_Object tty, tty_type;
982 USE_SAFE_ALLOCA;
997 983
998 tty = get_future_frame_param 984 tty = get_future_frame_param
999 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) 985 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
1000 ? FRAME_TTY (XFRAME (selected_frame))->name 986 ? FRAME_TTY (XFRAME (selected_frame))->name
1001 : NULL)); 987 : NULL));
1002 if (!NILP (tty)) 988 if (!NILP (tty))
1003 name = xlispstrdupa (tty); 989 SAFE_ALLOCA_STRING (name, tty);
1004 990
1005 tty_type = get_future_frame_param 991 tty_type = get_future_frame_param
1006 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) 992 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
1007 ? FRAME_TTY (XFRAME (selected_frame))->type 993 ? FRAME_TTY (XFRAME (selected_frame))->type
1008 : NULL)); 994 : NULL));
1009 if (!NILP (tty_type)) 995 if (!NILP (tty_type))
1010 type = xlispstrdupa (tty_type); 996 SAFE_ALLOCA_STRING (type, tty_type);
1011 997
1012 t = init_tty (name, type, 0); /* Errors are not fatal. */ 998 t = init_tty (name, type, 0); /* Errors are not fatal. */
999 SAFE_FREE ();
1013 } 1000 }
1014 1001
1015 f = make_terminal_frame (t); 1002 f = make_terminal_frame (t);
@@ -1804,9 +1791,9 @@ The functions are run with one argument, the frame to be deleted. */)
1804 1791
1805DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0, 1792DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1806 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position. 1793 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1807The position is given in character cells, where (0, 0) is the 1794The position is given in canonical character cells, where (0, 0) is the
1808upper-left corner of the frame, X is the horizontal offset, and Y is 1795upper-left corner of the frame, X is the horizontal offset, and Y is the
1809the vertical offset. 1796vertical offset, measured in units of the frame's default character size.
1810If Emacs is running on a mouseless terminal or hasn't been programmed 1797If Emacs is running on a mouseless terminal or hasn't been programmed
1811to read the mouse position, it returns the selected frame for FRAME 1798to read the mouse position, it returns the selected frame for FRAME
1812and nil for X and Y. 1799and nil for X and Y.
@@ -1863,7 +1850,8 @@ and nil for X and Y. */)
1863{ 1850{
1864 struct frame *f; 1851 struct frame *f;
1865 Lisp_Object lispy_dummy; 1852 Lisp_Object lispy_dummy;
1866 Lisp_Object x, y; 1853 Lisp_Object x, y, retval;
1854 struct gcpro gcpro1;
1867 1855
1868 f = SELECTED_FRAME (); 1856 f = SELECTED_FRAME ();
1869 x = y = Qnil; 1857 x = y = Qnil;
@@ -1880,7 +1868,11 @@ and nil for X and Y. */)
1880 } 1868 }
1881 1869
1882 XSETFRAME (lispy_dummy, f); 1870 XSETFRAME (lispy_dummy, f);
1883 return Fcons (lispy_dummy, Fcons (x, y)); 1871 retval = Fcons (lispy_dummy, Fcons (x, y));
1872 GCPRO1 (retval);
1873 if (!NILP (Vmouse_position_function))
1874 retval = call1 (Vmouse_position_function, retval);
1875 RETURN_UNGCPRO (retval);
1884} 1876}
1885 1877
1886#ifdef HAVE_WINDOW_SYSTEM 1878#ifdef HAVE_WINDOW_SYSTEM
@@ -1925,9 +1917,10 @@ Coordinates are relative to the frame, not a window,
1925so the coordinates of the top left character in the frame 1917so the coordinates of the top left character in the frame
1926may be nonzero due to left-hand scroll bars or the menu bar. 1918may be nonzero due to left-hand scroll bars or the menu bar.
1927 1919
1928The position is given in character cells, where (0, 0) is the 1920The position is given in canonical character cells, where (0, 0) is
1929upper-left corner of the frame, X is the horizontal offset, and Y is 1921the upper-left corner of the frame, X is the horizontal offset, and
1930the vertical offset. 1922Y is the vertical offset, measured in units of the frame's default
1923character size.
1931 1924
1932This function is a no-op for an X frame that is not visible. 1925This function is a no-op for an X frame that is not visible.
1933If you have just created a frame, you must wait for it to become visible 1926If you have just created a frame, you must wait for it to become visible
@@ -3000,7 +2993,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3000 /* If both of these parameters are present, it's more efficient to 2993 /* If both of these parameters are present, it's more efficient to
3001 set them both at once. So we wait until we've looked at the 2994 set them both at once. So we wait until we've looked at the
3002 entire list before we set them. */ 2995 entire list before we set them. */
3003 int width, height; 2996 int width IF_LINT (= 0), height IF_LINT (= 0);
3004 bool width_change = 0, height_change = 0; 2997 bool width_change = 0, height_change = 0;
3005 2998
3006 /* Same here. */ 2999 /* Same here. */
@@ -3017,14 +3010,14 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3017#ifdef HAVE_X_WINDOWS 3010#ifdef HAVE_X_WINDOWS
3018 bool icon_left_no_change = 0, icon_top_no_change = 0; 3011 bool icon_left_no_change = 0, icon_top_no_change = 0;
3019#endif 3012#endif
3020 struct gcpro gcpro1, gcpro2;
3021 3013
3022 i = 0; 3014 i = 0;
3023 for (tail = alist; CONSP (tail); tail = XCDR (tail)) 3015 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3024 i++; 3016 i++;
3025 3017
3026 parms = alloca (i * sizeof *parms); 3018 USE_SAFE_ALLOCA;
3027 values = alloca (i * sizeof *values); 3019 SAFE_ALLOCA_LISP (parms, 2 * i);
3020 values = parms + i;
3028 3021
3029 /* Extract parm names and values into those vectors. */ 3022 /* Extract parm names and values into those vectors. */
3030 3023
@@ -3041,10 +3034,6 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3041 /* TAIL and ALIST are not used again below here. */ 3034 /* TAIL and ALIST are not used again below here. */
3042 alist = tail = Qnil; 3035 alist = tail = Qnil;
3043 3036
3044 GCPRO2 (*parms, *values);
3045 gcpro1.nvars = i;
3046 gcpro2.nvars = i;
3047
3048 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP, 3037 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
3049 because their values appear in VALUES and strings are not valid. */ 3038 because their values appear in VALUES and strings are not valid. */
3050 top = left = Qunbound; 3039 top = left = Qunbound;
@@ -3273,7 +3262,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3273#endif /* HAVE_X_WINDOWS */ 3262#endif /* HAVE_X_WINDOWS */
3274 } 3263 }
3275 3264
3276 UNGCPRO; 3265 SAFE_FREE ();
3277} 3266}
3278 3267
3279 3268
@@ -3773,9 +3762,7 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3773void 3762void
3774x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 3763x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3775{ 3764{
3776#if (defined (HAVE_WINDOW_SYSTEM) \ 3765#if USE_HORIZONTAL_SCROLL_BARS
3777 && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \
3778 || defined (HAVE_NTGUI)))
3779 if ((NILP (arg) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)) 3766 if ((NILP (arg) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f))
3780 || (!NILP (arg) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f))) 3767 || (!NILP (arg) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)))
3781 { 3768 {
@@ -3825,9 +3812,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3825void 3812void
3826x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 3813x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3827{ 3814{
3828#if (defined (HAVE_WINDOW_SYSTEM) \ 3815#if USE_HORIZONTAL_SCROLL_BARS
3829 && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \
3830 || defined (HAVE_NTGUI)))
3831 int unit = FRAME_LINE_HEIGHT (f); 3816 int unit = FRAME_LINE_HEIGHT (f);
3832 3817
3833 if (NILP (arg)) 3818 if (NILP (arg))
@@ -4010,10 +3995,6 @@ validate_x_resource_name (void)
4010static Lisp_Object 3995static Lisp_Object
4011xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) 3996xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
4012{ 3997{
4013 register char *value;
4014 char *name_key;
4015 char *class_key;
4016
4017 CHECK_STRING (attribute); 3998 CHECK_STRING (attribute);
4018 CHECK_STRING (class); 3999 CHECK_STRING (class);
4019 4000
@@ -4028,22 +4009,25 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
4028 4009
4029 /* Allocate space for the components, the dots which separate them, 4010 /* Allocate space for the components, the dots which separate them,
4030 and the final '\0'. Make them big enough for the worst case. */ 4011 and the final '\0'. Make them big enough for the worst case. */
4031 name_key = alloca (SBYTES (Vx_resource_name) 4012 ptrdiff_t name_keysize = (SBYTES (Vx_resource_name)
4032 + (STRINGP (component) 4013 + (STRINGP (component)
4033 ? SBYTES (component) : 0) 4014 ? SBYTES (component) : 0)
4034 + SBYTES (attribute) 4015 + SBYTES (attribute)
4035 + 3); 4016 + 3);
4036 4017
4037 class_key = alloca (SBYTES (Vx_resource_class) 4018 ptrdiff_t class_keysize = (SBYTES (Vx_resource_class)
4038 + SBYTES (class) 4019 + SBYTES (class)
4039 + (STRINGP (subclass) 4020 + (STRINGP (subclass)
4040 ? SBYTES (subclass) : 0) 4021 ? SBYTES (subclass) : 0)
4041 + 3); 4022 + 3);
4023 USE_SAFE_ALLOCA;
4024 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
4025 char *class_key = name_key + name_keysize;
4042 4026
4043 /* Start with emacs.FRAMENAME for the name (the specific one) 4027 /* Start with emacs.FRAMENAME for the name (the specific one)
4044 and with `Emacs' for the class key (the general one). */ 4028 and with `Emacs' for the class key (the general one). */
4045 strcpy (name_key, SSDATA (Vx_resource_name)); 4029 lispstpcpy (name_key, Vx_resource_name);
4046 strcpy (class_key, SSDATA (Vx_resource_class)); 4030 lispstpcpy (class_key, Vx_resource_class);
4047 4031
4048 strcat (class_key, "."); 4032 strcat (class_key, ".");
4049 strcat (class_key, SSDATA (class)); 4033 strcat (class_key, SSDATA (class));
@@ -4060,7 +4044,8 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
4060 strcat (name_key, "."); 4044 strcat (name_key, ".");
4061 strcat (name_key, SSDATA (attribute)); 4045 strcat (name_key, SSDATA (attribute));
4062 4046
4063 value = x_get_string_resource (rdb, name_key, class_key); 4047 char *value = x_get_string_resource (rdb, name_key, class_key);
4048 SAFE_FREE();
4064 4049
4065 if (value && *value) 4050 if (value && *value)
4066 return build_string (value); 4051 return build_string (value);
@@ -4112,8 +4097,10 @@ x_get_resource_string (const char *attribute, const char *class)
4112 4097
4113 /* Allocate space for the components, the dots which separate them, 4098 /* Allocate space for the components, the dots which separate them,
4114 and the final '\0'. */ 4099 and the final '\0'. */
4115 char *name_key = SAFE_ALLOCA (invocation_namelen + strlen (attribute) + 2); 4100 ptrdiff_t name_keysize = invocation_namelen + strlen (attribute) + 2;
4116 char *class_key = alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2); 4101 ptrdiff_t class_keysize = sizeof (EMACS_CLASS) - 1 + strlen (class) + 2;
4102 char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
4103 char *class_key = name_key + name_keysize;
4117 4104
4118 esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); 4105 esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
4119 sprintf (class_key, "%s.%s", EMACS_CLASS, class); 4106 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
@@ -4140,7 +4127,7 @@ Lisp_Object
4140x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param, 4127x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
4141 const char *attribute, const char *class, enum resource_types type) 4128 const char *attribute, const char *class, enum resource_types type)
4142{ 4129{
4143 register Lisp_Object tem; 4130 Lisp_Object tem;
4144 4131
4145 tem = Fassq (param, alist); 4132 tem = Fassq (param, alist);
4146 4133
@@ -4166,10 +4153,9 @@ x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
4166 { 4153 {
4167 if (attribute && dpyinfo) 4154 if (attribute && dpyinfo)
4168 { 4155 {
4169 tem = display_x_get_resource (dpyinfo, 4156 AUTO_STRING (at, attribute);
4170 build_string (attribute), 4157 AUTO_STRING (cl, class);
4171 build_string (class), 4158 tem = display_x_get_resource (dpyinfo, at, cl, Qnil, Qnil);
4172 Qnil, Qnil);
4173 4159
4174 if (NILP (tem)) 4160 if (NILP (tem))
4175 return Qunbound; 4161 return Qunbound;
@@ -4279,7 +4265,8 @@ x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
4279 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type); 4265 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
4280 if (EQ (tem, Qunbound)) 4266 if (EQ (tem, Qunbound))
4281 tem = deflt; 4267 tem = deflt;
4282 x_set_frame_parameters (f, list1 (Fcons (prop, tem))); 4268 AUTO_FRAME_ARG (arg, prop, tem);
4269 x_set_frame_parameters (f, arg);
4283 return tem; 4270 return tem;
4284} 4271}
4285 4272
@@ -4872,16 +4859,6 @@ Setting this variable does not affect existing frames, only new ones. */);
4872 Vdefault_frame_scroll_bars = Qnil; 4859 Vdefault_frame_scroll_bars = Qnil;
4873#endif 4860#endif
4874 4861
4875 DEFVAR_LISP ("default-frame-horizontal-scroll-bars", Vdefault_frame_horizontal_scroll_bars,
4876 doc: /* Default value for horizontal scroll bars on this window-system. */);
4877#if (defined (HAVE_WINDOW_SYSTEM) \
4878 && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \
4879 || defined (HAVE_NTGUI)))
4880 Vdefault_frame_horizontal_scroll_bars = Qt;
4881#else
4882 Vdefault_frame_horizontal_scroll_bars = Qnil;
4883#endif
4884
4885 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion", 4862 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
4886 scroll_bar_adjust_thumb_portion_p, 4863 scroll_bar_adjust_thumb_portion_p,
4887 doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF. 4864 doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
@@ -4897,8 +4874,8 @@ is visible. In this case you can not overscroll. */);
4897 4874
4898 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function, 4875 DEFVAR_LISP ("mouse-position-function", Vmouse_position_function,
4899 doc: /* If non-nil, function to transform normal value of `mouse-position'. 4876 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4900`mouse-position' calls this function, passing its usual return value as 4877`mouse-position' and `mouse-pixel-position' call this function, passing their
4901argument, and returns whatever this function returns. 4878usual return value as argument, and return whatever this function returns.
4902This abnormal hook exists for the benefit of packages like `xt-mouse.el' 4879This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4903which need to do mouse handling at the Lisp level. */); 4880which need to do mouse handling at the Lisp level. */);
4904 Vmouse_position_function = Qnil; 4881 Vmouse_position_function = Qnil;
diff --git a/src/frame.h b/src/frame.h
index 0f34770d9b4..22f2fa7a24c 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -868,9 +868,7 @@ default_pixels_per_inch_y (void)
868#endif /* HAVE_WINDOW_SYSTEM */ 868#endif /* HAVE_WINDOW_SYSTEM */
869 869
870/* Whether horizontal scroll bars are currently enabled for frame F. */ 870/* Whether horizontal scroll bars are currently enabled for frame F. */
871#if (defined (HAVE_WINDOW_SYSTEM) \ 871#if USE_HORIZONTAL_SCROLL_BARS
872 && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \
873 || defined (HAVE_NTGUI)))
874#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \ 872#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \
875 ((f)->horizontal_scroll_bars) 873 ((f)->horizontal_scroll_bars)
876#else 874#else
@@ -1062,6 +1060,11 @@ default_pixels_per_inch_y (void)
1062 } \ 1060 } \
1063 } while (false) 1061 } while (false)
1064 1062
1063/* Handy macro to construct an argument to Fmodify_frame_parameters. */
1064
1065#define AUTO_FRAME_ARG(name, parameter, value) \
1066 AUTO_LIST1 (name, AUTO_CONS_EXPR (parameter, value))
1067
1065/* False means there are no visible garbaged frames. */ 1068/* False means there are no visible garbaged frames. */
1066extern bool frame_garbaged; 1069extern bool frame_garbaged;
1067 1070
@@ -1290,7 +1293,7 @@ extern Lisp_Object Vframe_list;
1290 / FRAME_LINE_HEIGHT (f)) 1293 / FRAME_LINE_HEIGHT (f))
1291 1294
1292/* Return the pixel width/height of frame F with a text size of 1295/* Return the pixel width/height of frame F with a text size of
1293 width/heigh. */ 1296 width/height. */
1294#define FRAME_TEXT_TO_PIXEL_WIDTH(f, width) \ 1297#define FRAME_TEXT_TO_PIXEL_WIDTH(f, width) \
1295 ((width) \ 1298 ((width) \
1296 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \ 1299 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
@@ -1501,4 +1504,11 @@ extern Lisp_Object make_monitor_attribute_list (struct MonitorInfo *monitors,
1501 1504
1502INLINE_HEADER_END 1505INLINE_HEADER_END
1503 1506
1507/* Suppress -Wsuggest-attribute=const if there are no scroll bars.
1508 This is for functions like x_set_horizontal_scroll_bars that have
1509 no effect in this case. */
1510#if ! USE_HORIZONTAL_SCROLL_BARS && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
1511# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
1512#endif
1513
1504#endif /* not EMACS_FRAME_H */ 1514#endif /* not EMACS_FRAME_H */
diff --git a/src/ftfont.c b/src/ftfont.c
index 419274a30aa..4c12ef5d3af 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include <fontconfig/fontconfig.h> 24#include <fontconfig/fontconfig.h>
25#include <fontconfig/fcfreetype.h> 25#include <fontconfig/fcfreetype.h>
26 26
27#include <c-strcase.h>
28
27#include "lisp.h" 29#include "lisp.h"
28#include "dispextern.h" 30#include "dispextern.h"
29#include "frame.h" 31#include "frame.h"
@@ -140,6 +142,12 @@ static struct
140 { NULL } 142 { NULL }
141 }; 143 };
142 144
145static bool
146matching_prefix (char const *str, ptrdiff_t len, char const *pat)
147{
148 return len == strlen (pat) && c_strncasecmp (str, pat, len) == 0;
149}
150
143/* Dirty hack for handing ADSTYLE property. 151/* Dirty hack for handing ADSTYLE property.
144 152
145 Fontconfig (actually the underlying FreeType) gives such ADSTYLE 153 Fontconfig (actually the underlying FreeType) gives such ADSTYLE
@@ -171,18 +179,10 @@ get_adstyle_property (FcPattern *p)
171 return Qnil; 179 return Qnil;
172 str = (char *) fcstr; 180 str = (char *) fcstr;
173 for (end = str; *end && *end != ' '; end++); 181 for (end = str; *end && *end != ' '; end++);
174 if (*end) 182 if (matching_prefix (str, end - str, "Regular")
175 { 183 || matching_prefix (str, end - str, "Bold")
176 char *newstr = alloca (end - str + 1); 184 || matching_prefix (str, end - str, "Oblique")
177 memcpy (newstr, str, end - str); 185 || matching_prefix (str, end - str, "Italic"))
178 newstr[end - str] = '\0';
179 end = newstr + (end - str);
180 str = newstr;
181 }
182 if (xstrcasecmp (str, "Regular") == 0
183 || xstrcasecmp (str, "Bold") == 0
184 || xstrcasecmp (str, "Oblique") == 0
185 || xstrcasecmp (str, "Italic") == 0)
186 return Qnil; 186 return Qnil;
187 adstyle = font_intern_prop (str, end - str, 1); 187 adstyle = font_intern_prop (str, end - str, 1);
188 if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0) 188 if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
@@ -499,8 +499,8 @@ static Lisp_Object ftfont_open (struct frame *, Lisp_Object, int);
499static void ftfont_close (struct font *); 499static void ftfont_close (struct font *);
500static int ftfont_has_char (Lisp_Object, int); 500static int ftfont_has_char (Lisp_Object, int);
501static unsigned ftfont_encode_char (struct font *, int); 501static unsigned ftfont_encode_char (struct font *, int);
502static int ftfont_text_extents (struct font *, unsigned *, int, 502static void ftfont_text_extents (struct font *, unsigned *, int,
503 struct font_metrics *); 503 struct font_metrics *);
504static int ftfont_get_bitmap (struct font *, unsigned, 504static int ftfont_get_bitmap (struct font *, unsigned,
505 struct font_bitmap *, int); 505 struct font_bitmap *, int);
506static int ftfont_anchor_point (struct font *, unsigned, int, 506static int ftfont_anchor_point (struct font *, unsigned, int,
@@ -573,7 +573,8 @@ static int
573ftfont_get_charset (Lisp_Object registry) 573ftfont_get_charset (Lisp_Object registry)
574{ 574{
575 char *str = SSDATA (SYMBOL_NAME (registry)); 575 char *str = SSDATA (SYMBOL_NAME (registry));
576 char *re = alloca (SBYTES (SYMBOL_NAME (registry)) * 2 + 1); 576 USE_SAFE_ALLOCA;
577 char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
577 Lisp_Object regexp; 578 Lisp_Object regexp;
578 int i, j; 579 int i, j;
579 580
@@ -589,6 +590,7 @@ ftfont_get_charset (Lisp_Object registry)
589 } 590 }
590 re[j] = '\0'; 591 re[j] = '\0';
591 regexp = make_unibyte_string (re, j); 592 regexp = make_unibyte_string (re, j);
593 SAFE_FREE ();
592 for (i = 0; fc_charset_table[i].name; i++) 594 for (i = 0; fc_charset_table[i].name; i++)
593 if (fast_c_string_match_ignore_case 595 if (fast_c_string_match_ignore_case
594 (regexp, fc_charset_table[i].name, 596 (regexp, fc_charset_table[i].name,
@@ -802,7 +804,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
802 *otspec = ftfont_get_open_type_spec (val); 804 *otspec = ftfont_get_open_type_spec (val);
803 if (! *otspec) 805 if (! *otspec)
804 return NULL; 806 return NULL;
805 strcat (otlayout, "otlayout:"); 807 strcpy (otlayout, "otlayout:");
806 OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9); 808 OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9);
807 script = (*otspec)->script; 809 script = (*otspec)->script;
808 } 810 }
@@ -1371,19 +1373,18 @@ ftfont_encode_char (struct font *font, int c)
1371 return (code > 0 ? code : FONT_INVALID_CODE); 1373 return (code > 0 ? code : FONT_INVALID_CODE);
1372} 1374}
1373 1375
1374static int 1376static void
1375ftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics) 1377ftfont_text_extents (struct font *font, unsigned int *code,
1378 int nglyphs, struct font_metrics *metrics)
1376{ 1379{
1377 struct ftfont_info *ftfont_info = (struct ftfont_info *) font; 1380 struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1378 FT_Face ft_face = ftfont_info->ft_size->face; 1381 FT_Face ft_face = ftfont_info->ft_size->face;
1379 int width = 0; 1382 int i, width = 0;
1380 int i;
1381 bool first; 1383 bool first;
1382 1384
1383 if (ftfont_info->ft_size != ft_face->size) 1385 if (ftfont_info->ft_size != ft_face->size)
1384 FT_Activate_Size (ftfont_info->ft_size); 1386 FT_Activate_Size (ftfont_info->ft_size);
1385 if (metrics) 1387
1386 memset (metrics, 0, sizeof (struct font_metrics));
1387 for (i = 0, first = 1; i < nglyphs; i++) 1388 for (i = 0, first = 1; i < nglyphs; i++)
1388 { 1389 {
1389 if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0) 1390 if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0)
@@ -1392,39 +1393,28 @@ ftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct
1392 1393
1393 if (first) 1394 if (first)
1394 { 1395 {
1395 if (metrics) 1396 metrics->lbearing = m->horiBearingX >> 6;
1396 { 1397 metrics->rbearing = (m->horiBearingX + m->width) >> 6;
1397 metrics->lbearing = m->horiBearingX >> 6; 1398 metrics->ascent = m->horiBearingY >> 6;
1398 metrics->rbearing = (m->horiBearingX + m->width) >> 6; 1399 metrics->descent = (m->height - m->horiBearingY) >> 6;
1399 metrics->ascent = m->horiBearingY >> 6;
1400 metrics->descent = (m->height - m->horiBearingY) >> 6;
1401 }
1402 first = 0; 1400 first = 0;
1403 } 1401 }
1404 if (metrics) 1402 if (metrics->lbearing > width + (m->horiBearingX >> 6))
1405 { 1403 metrics->lbearing = width + (m->horiBearingX >> 6);
1406 if (metrics->lbearing > width + (m->horiBearingX >> 6)) 1404 if (metrics->rbearing
1407 metrics->lbearing = width + (m->horiBearingX >> 6); 1405 < width + ((m->horiBearingX + m->width) >> 6))
1408 if (metrics->rbearing 1406 metrics->rbearing
1409 < width + ((m->horiBearingX + m->width) >> 6)) 1407 = width + ((m->horiBearingX + m->width) >> 6);
1410 metrics->rbearing 1408 if (metrics->ascent < (m->horiBearingY >> 6))
1411 = width + ((m->horiBearingX + m->width) >> 6); 1409 metrics->ascent = m->horiBearingY >> 6;
1412 if (metrics->ascent < (m->horiBearingY >> 6)) 1410 if (metrics->descent > ((m->height - m->horiBearingY) >> 6))
1413 metrics->ascent = m->horiBearingY >> 6; 1411 metrics->descent = (m->height - m->horiBearingY) >> 6;
1414 if (metrics->descent > ((m->height - m->horiBearingY) >> 6))
1415 metrics->descent = (m->height - m->horiBearingY) >> 6;
1416 }
1417 width += m->horiAdvance >> 6; 1412 width += m->horiAdvance >> 6;
1418 } 1413 }
1419 else 1414 else
1420 { 1415 width += font->space_width;
1421 width += font->space_width;
1422 }
1423 } 1416 }
1424 if (metrics) 1417 metrics->width = width;
1425 metrics->width = width;
1426
1427 return width;
1428} 1418}
1429 1419
1430static int 1420static int
@@ -1700,7 +1690,8 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1700 else if (! otf) 1690 else if (! otf)
1701 return 0; 1691 return 0;
1702 for (n = 1; spec->features[i][n]; n++); 1692 for (n = 1; spec->features[i][n]; n++);
1703 tags = alloca (sizeof (OTF_Tag) * n); 1693 USE_SAFE_ALLOCA;
1694 SAFE_NALLOCA (tags, 1, n);
1704 for (n = 0, negative = 0; spec->features[i][n]; n++) 1695 for (n = 0, negative = 0; spec->features[i][n]; n++)
1705 { 1696 {
1706 if (spec->features[i][n] == 0xFFFFFFFF) 1697 if (spec->features[i][n] == 0xFFFFFFFF)
@@ -1710,16 +1701,17 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1710 else 1701 else
1711 tags[n] = spec->features[i][n]; 1702 tags[n] = spec->features[i][n];
1712 } 1703 }
1713#ifdef M17N_FLT_USE_NEW_FEATURE 1704 bool passed = true;
1714 if (OTF_check_features (otf, i == 0, spec->script, spec->langsys, 1705#ifndef M17N_FLT_USE_NEW_FEATURE
1715 tags, n - negative) != 1) 1706 passed = n - negative > 0;
1716 return 0; 1707#endif
1717#else /* not M17N_FLT_USE_NEW_FEATURE */ 1708 if (passed)
1718 if (n - negative > 0 1709 passed = (OTF_check_features (otf, i == 0, spec->script,
1719 && OTF_check_features (otf, i == 0, spec->script, spec->langsys, 1710 spec->langsys, tags, n - negative)
1720 tags, n - negative) != 1) 1711 != 1);
1712 SAFE_FREE ();
1713 if (passed)
1721 return 0; 1714 return 0;
1722#endif /* not M17N_FLT_USE_NEW_FEATURE */
1723 } 1715 }
1724 return 1; 1716 return 1;
1725#undef FEATURE_NONE 1717#undef FEATURE_NONE
@@ -1811,11 +1803,15 @@ ftfont_drive_otf (MFLTFont *font,
1811 if (len == 0) 1803 if (len == 0)
1812 return from; 1804 return from;
1813 OTF_tag_name (spec->script, script); 1805 OTF_tag_name (spec->script, script);
1806
1807 char langsysbuf[5];
1814 if (spec->langsys) 1808 if (spec->langsys)
1815 { 1809 {
1816 langsys = alloca (5); 1810 langsys = langsysbuf;
1817 OTF_tag_name (spec->langsys, langsys); 1811 OTF_tag_name (spec->langsys, langsys);
1818 } 1812 }
1813
1814 USE_SAFE_ALLOCA;
1819 for (i = 0; i < 2; i++) 1815 for (i = 0; i < 2; i++)
1820 { 1816 {
1821 char *p; 1817 char *p;
@@ -1823,10 +1819,11 @@ ftfont_drive_otf (MFLTFont *font,
1823 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) 1819 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
1824 { 1820 {
1825 for (j = 0; spec->features[i][j]; j++); 1821 for (j = 0; spec->features[i][j]; j++);
1822 SAFE_NALLOCA (p, 6, j);
1826 if (i == 0) 1823 if (i == 0)
1827 p = gsub_features = alloca (6 * j); 1824 gsub_features = p;
1828 else 1825 else
1829 p = gpos_features = alloca (6 * j); 1826 gpos_features = p;
1830 for (j = 0; spec->features[i][j]; j++) 1827 for (j = 0; spec->features[i][j]; j++)
1831 { 1828 {
1832 if (spec->features[i][j] == 0xFFFFFFFF) 1829 if (spec->features[i][j] == 0xFFFFFFFF)
@@ -1858,7 +1855,10 @@ ftfont_drive_otf (MFLTFont *font,
1858 gsub_features) < 0) 1855 gsub_features) < 0)
1859 goto simple_copy; 1856 goto simple_copy;
1860 if (out->allocated < out->used + otf_gstring.used) 1857 if (out->allocated < out->used + otf_gstring.used)
1861 return -2; 1858 {
1859 SAFE_FREE ();
1860 return -2;
1861 }
1862 features = otf->gsub->FeatureList.Feature; 1862 features = otf->gsub->FeatureList.Feature;
1863 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) 1863 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
1864 { 1864 {
@@ -1947,7 +1947,10 @@ ftfont_drive_otf (MFLTFont *font,
1947 else if (out) 1947 else if (out)
1948 { 1948 {
1949 if (out->allocated < out->used + len) 1949 if (out->allocated < out->used + len)
1950 return -2; 1950 {
1951 SAFE_FREE ();
1952 return -2;
1953 }
1951 for (i = 0; i < len; i++) 1954 for (i = 0; i < len; i++)
1952 out->glyphs[out->used++] = in->glyphs[from + i]; 1955 out->glyphs[out->used++] = in->glyphs[from + i];
1953 } 1956 }
@@ -1959,7 +1962,10 @@ ftfont_drive_otf (MFLTFont *font,
1959 1962
1960 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, 1963 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
1961 gpos_features) < 0) 1964 gpos_features) < 0)
1962 return to; 1965 {
1966 SAFE_FREE ();
1967 return to;
1968 }
1963 features = otf->gpos->FeatureList.Feature; 1969 features = otf->gpos->FeatureList.Feature;
1964 x_ppem = ft_face->size->metrics.x_ppem; 1970 x_ppem = ft_face->size->metrics.x_ppem;
1965 y_ppem = ft_face->size->metrics.y_ppem; 1971 y_ppem = ft_face->size->metrics.y_ppem;
@@ -2081,7 +2087,10 @@ ftfont_drive_otf (MFLTFont *font,
2081 { 2087 {
2082 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, 2088 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
2083 gpos_features) < 0) 2089 gpos_features) < 0)
2084 return to; 2090 {
2091 SAFE_FREE ();
2092 return to;
2093 }
2085 features = otf->gpos->FeatureList.Feature; 2094 features = otf->gpos->FeatureList.Feature;
2086 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; 2095 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used;
2087 i++, otfg++) 2096 i++, otfg++)
@@ -2101,9 +2110,11 @@ ftfont_drive_otf (MFLTFont *font,
2101 } 2110 }
2102 } 2111 }
2103 } 2112 }
2113 SAFE_FREE ();
2104 return to; 2114 return to;
2105 2115
2106 simple_copy: 2116 simple_copy:
2117 SAFE_FREE ();
2107 if (! out) 2118 if (! out)
2108 return to; 2119 return to;
2109 if (out->allocated < out->used + len) 2120 if (out->allocated < out->used + len)
@@ -2141,11 +2152,15 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2141 if (len == 0) 2152 if (len == 0)
2142 return from; 2153 return from;
2143 OTF_tag_name (spec->script, script); 2154 OTF_tag_name (spec->script, script);
2155
2156 char langsysbuf[5];
2144 if (spec->langsys) 2157 if (spec->langsys)
2145 { 2158 {
2146 langsys = alloca (5); 2159 langsys = langsysbuf;
2147 OTF_tag_name (spec->langsys, langsys); 2160 OTF_tag_name (spec->langsys, langsys);
2148 } 2161 }
2162
2163 USE_SAFE_ALLOCA;
2149 for (i = 0; i < 2; i++) 2164 for (i = 0; i < 2; i++)
2150 { 2165 {
2151 char *p; 2166 char *p;
@@ -2153,10 +2168,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2153 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) 2168 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
2154 { 2169 {
2155 for (j = 0; spec->features[i][j]; j++); 2170 for (j = 0; spec->features[i][j]; j++);
2171 SAFE_NALLOCA (p, 6, j);
2156 if (i == 0) 2172 if (i == 0)
2157 p = gsub_features = alloca (6 * j); 2173 gsub_features = p;
2158 else 2174 else
2159 p = gpos_features = alloca (6 * j); 2175 gpos_features = p;
2160 for (j = 0; spec->features[i][j]; j++) 2176 for (j = 0; spec->features[i][j]; j++)
2161 { 2177 {
2162 if (spec->features[i][j] == 0xFFFFFFFF) 2178 if (spec->features[i][j] == 0xFFFFFFFF)
@@ -2188,7 +2204,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2188 < 0) 2204 < 0)
2189 goto simple_copy; 2205 goto simple_copy;
2190 if (out->allocated < out->used + otf_gstring.used) 2206 if (out->allocated < out->used + otf_gstring.used)
2191 return -2; 2207 {
2208 SAFE_FREE ();
2209 return -2;
2210 }
2192 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) 2211 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
2193 { 2212 {
2194 MFLTGlyph *g; 2213 MFLTGlyph *g;
@@ -2239,7 +2258,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2239 else 2258 else
2240 { 2259 {
2241 if (out->allocated < out->used + len) 2260 if (out->allocated < out->used + len)
2242 return -2; 2261 {
2262 SAFE_FREE ();
2263 return -2;
2264 }
2243 for (i = 0; i < len; i++) 2265 for (i = 0; i < len; i++)
2244 out->glyphs[out->used++] = in->glyphs[from + i]; 2266 out->glyphs[out->used++] = in->glyphs[from + i];
2245 } 2267 }
@@ -2251,7 +2273,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2251 2273
2252 if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features) 2274 if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features)
2253 < 0) 2275 < 0)
2254 return to; 2276 {
2277 SAFE_FREE ();
2278 return to;
2279 }
2255 2280
2256 x_ppem = ft_face->size->metrics.x_ppem; 2281 x_ppem = ft_face->size->metrics.x_ppem;
2257 y_ppem = ft_face->size->metrics.y_ppem; 2282 y_ppem = ft_face->size->metrics.y_ppem;
@@ -2361,9 +2386,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2361 base = g; 2386 base = g;
2362 } 2387 }
2363 } 2388 }
2389 SAFE_FREE ();
2364 return to; 2390 return to;
2365 2391
2366 simple_copy: 2392 simple_copy:
2393 SAFE_FREE ();
2367 if (out->allocated < out->used + len) 2394 if (out->allocated < out->used + len)
2368 return -2; 2395 return -2;
2369 font->get_metrics (font, in, from, to); 2396 font->get_metrics (font, in, from, to);
diff --git a/src/ftxfont.c b/src/ftxfont.c
index 63e3477ebf4..7e4608b9b85 100644
--- a/src/ftxfont.c
+++ b/src/ftxfont.c
@@ -271,10 +271,11 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
271 271
272 n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0; 272 n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0;
273 273
274 USE_SAFE_ALLOCA;
275 SAFE_NALLOCA (code, 1, len);
274 block_input (); 276 block_input ();
275 if (with_background) 277 if (with_background)
276 ftxfont_draw_background (f, font, s->gc, x, y, s->width); 278 ftxfont_draw_background (f, font, s->gc, x, y, s->width);
277 code = alloca (sizeof (unsigned) * len);
278 for (i = 0; i < len; i++) 279 for (i = 0; i < len; i++)
279 code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8) 280 code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
280 | XCHAR2B_BYTE2 (s->char2b + from + i)); 281 | XCHAR2B_BYTE2 (s->char2b + from + i));
@@ -322,6 +323,7 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
322 } 323 }
323 324
324 unblock_input (); 325 unblock_input ();
326 SAFE_FREE ();
325 327
326 return len; 328 return len;
327} 329}
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 27965e37539..3456ff0ec6f 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -21,13 +21,18 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 21
22#include <config.h> 22#include <config.h>
23 23
24#ifdef HAVE_PTHREAD 24#if defined HAVE_PTHREAD && !defined HYBRID_MALLOC
25#define USE_PTHREAD 25#define USE_PTHREAD
26#endif 26#endif
27 27
28#include <string.h> 28#include <string.h>
29#include <limits.h> 29#include <limits.h>
30#include <stdint.h> 30#include <stdint.h>
31
32#ifdef HYBRID_GET_CURRENT_DIR_NAME
33#undef get_current_dir_name
34#endif
35
31#include <unistd.h> 36#include <unistd.h>
32 37
33#ifdef USE_PTHREAD 38#ifdef USE_PTHREAD
@@ -42,6 +47,41 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
42extern void emacs_abort (void); 47extern void emacs_abort (void);
43#endif 48#endif
44 49
50/* If HYBRID_MALLOC is defined, then temacs will use malloc,
51 realloc... as defined in this file (and renamed gmalloc,
52 grealloc... via the macros that follow). The dumped emacs,
53 however, will use the system malloc, realloc.... In other source
54 files, malloc, realloc... are renamed hybrid_malloc,
55 hybrid_realloc... via macros in conf_post.h. hybrid_malloc and
56 friends are wrapper functions defined later in this file.
57 aligned_alloc is defined as a macro only in alloc.c.
58
59 As of this writing (August 2014), Cygwin is the only platform on
60 which HYBRID_MACRO is defined. Any other platform that wants to
61 define it will have to define the macros DUMPED and
62 ALLOCATED_BEFORE_DUMPING, defined below for Cygwin. */
63#ifdef HYBRID_MALLOC
64#undef malloc
65#undef realloc
66#undef calloc
67#undef free
68#define malloc gmalloc
69#define realloc grealloc
70#define calloc gcalloc
71#define aligned_alloc galigned_alloc
72#define free gfree
73#endif /* HYBRID_MALLOC */
74
75#ifdef CYGWIN
76extern void *bss_sbrk (ptrdiff_t size);
77extern int bss_sbrk_did_unexec;
78extern char bss_sbrk_buffer[];
79extern void *bss_sbrk_buffer_end;
80#define DUMPED bss_sbrk_did_unexec
81#define ALLOCATED_BEFORE_DUMPING(P) \
82 ((P) < bss_sbrk_buffer_end && (P) >= (void *) bss_sbrk_buffer)
83#endif
84
45#ifdef __cplusplus 85#ifdef __cplusplus
46extern "C" 86extern "C"
47{ 87{
@@ -306,22 +346,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
306 346
307#include <errno.h> 347#include <errno.h>
308 348
309/* On Cygwin there are two heaps. temacs uses the static heap
310 (defined in sheap.c and managed with bss_sbrk), and the dumped
311 emacs uses the Cygwin heap (managed with sbrk). When emacs starts
312 on Cygwin, it reinitializes malloc, and we save the old info for
313 use by free and realloc if they're called with a pointer into the
314 static heap.
315
316 Currently (2011-08-16) the Cygwin build doesn't use ralloc.c; if
317 this is changed in the future, we'll have to similarly deal with
318 reinitializing ralloc. */
319#ifdef CYGWIN
320extern void *bss_sbrk (ptrdiff_t size);
321extern int bss_sbrk_did_unexec;
322char *bss_sbrk_heapbase; /* _heapbase for static heap */
323malloc_info *bss_sbrk_heapinfo; /* _heapinfo for static heap */
324#endif
325void *(*__morecore) (ptrdiff_t size) = __default_morecore; 349void *(*__morecore) (ptrdiff_t size) = __default_morecore;
326 350
327/* Debugging hook for `malloc'. */ 351/* Debugging hook for `malloc'. */
@@ -490,18 +514,8 @@ register_heapinfo (void)
490} 514}
491 515
492#ifdef USE_PTHREAD 516#ifdef USE_PTHREAD
493/* On Cygwin prior to 1.7.31, pthread_mutexes were ERRORCHECK mutexes
494 by default. When the default changed to NORMAL in Cygwin-1.7.31,
495 deadlocks occurred (bug#18222). As a temporary workaround, we
496 explicitly set the mutexes to be of ERRORCHECK type, restoring the
497 previous behavior. */
498#ifdef CYGWIN
499pthread_mutex_t _malloc_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
500pthread_mutex_t _aligned_blocks_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
501#else /* not CYGWIN */
502pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER; 517pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
503pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER; 518pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER;
504#endif /* not CYGWIN */
505int _malloc_thread_enabled_p; 519int _malloc_thread_enabled_p;
506 520
507static void 521static void
@@ -536,17 +550,8 @@ malloc_enable_thread (void)
536 initialized mutexes when they are used first. To avoid such a 550 initialized mutexes when they are used first. To avoid such a
537 situation, we initialize mutexes here while their use is 551 situation, we initialize mutexes here while their use is
538 disabled in malloc etc. */ 552 disabled in malloc etc. */
539#ifdef CYGWIN
540 /* Use ERRORCHECK mutexes; see comment above. */
541 pthread_mutexattr_t attr;
542 pthread_mutexattr_init (&attr);
543 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
544 pthread_mutex_init (&_malloc_mutex, &attr);
545 pthread_mutex_init (&_aligned_blocks_mutex, &attr);
546#else /* not CYGWIN */
547 pthread_mutex_init (&_malloc_mutex, NULL); 553 pthread_mutex_init (&_malloc_mutex, NULL);
548 pthread_mutex_init (&_aligned_blocks_mutex, NULL); 554 pthread_mutex_init (&_aligned_blocks_mutex, NULL);
549#endif /* not CYGWIN */
550 pthread_atfork (malloc_atfork_handler_prepare, 555 pthread_atfork (malloc_atfork_handler_prepare,
551 malloc_atfork_handler_parent, 556 malloc_atfork_handler_parent,
552 malloc_atfork_handler_child); 557 malloc_atfork_handler_child);
@@ -561,16 +566,6 @@ malloc_initialize_1 (void)
561 mcheck (NULL); 566 mcheck (NULL);
562#endif 567#endif
563 568
564#ifdef CYGWIN
565 if (bss_sbrk_did_unexec)
566 /* we're reinitializing the dumped emacs */
567 {
568 bss_sbrk_heapbase = _heapbase;
569 bss_sbrk_heapinfo = _heapinfo;
570 memset (_fraghead, 0, BLOCKLOG * sizeof (struct list));
571 }
572#endif
573
574 if (__malloc_initialize_hook) 569 if (__malloc_initialize_hook)
575 (*__malloc_initialize_hook) (); 570 (*__malloc_initialize_hook) ();
576 571
@@ -1027,12 +1022,6 @@ _free_internal_nolock (void *ptr)
1027 if (ptr == NULL) 1022 if (ptr == NULL)
1028 return; 1023 return;
1029 1024
1030#ifdef CYGWIN
1031 if ((char *) ptr < _heapbase)
1032 /* We're being asked to free something in the static heap. */
1033 return;
1034#endif
1035
1036 PROTECT_MALLOC_STATE (0); 1025 PROTECT_MALLOC_STATE (0);
1037 1026
1038 LOCK_ALIGNED_BLOCKS (); 1027 LOCK_ALIGNED_BLOCKS ();
@@ -1314,30 +1303,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
1314 or (US mail) as Mike Haertel c/o Free Software Foundation. */ 1303 or (US mail) as Mike Haertel c/o Free Software Foundation. */
1315 1304
1316#ifndef min 1305#ifndef min
1317#define min(A, B) ((A) < (B) ? (A) : (B)) 1306#define min(a, b) ((a) < (b) ? (a) : (b))
1318#endif
1319
1320/* On Cygwin the dumped emacs may try to realloc storage allocated in
1321 the static heap. We just malloc space in the new heap and copy the
1322 data. */
1323#ifdef CYGWIN
1324void *
1325special_realloc (void *ptr, size_t size)
1326{
1327 void *result;
1328 int type;
1329 size_t block, oldsize;
1330
1331 block = ((char *) ptr - bss_sbrk_heapbase) / BLOCKSIZE + 1;
1332 type = bss_sbrk_heapinfo[block].busy.type;
1333 oldsize =
1334 type == 0 ? bss_sbrk_heapinfo[block].busy.info.size * BLOCKSIZE
1335 : (size_t) 1 << type;
1336 result = _malloc_internal_nolock (size);
1337 if (result)
1338 return memcpy (result, ptr, min (oldsize, size));
1339 return result;
1340}
1341#endif 1307#endif
1342 1308
1343/* Debugging hook for realloc. */ 1309/* Debugging hook for realloc. */
@@ -1364,12 +1330,6 @@ _realloc_internal_nolock (void *ptr, size_t size)
1364 else if (ptr == NULL) 1330 else if (ptr == NULL)
1365 return _malloc_internal_nolock (size); 1331 return _malloc_internal_nolock (size);
1366 1332
1367#ifdef CYGWIN
1368 if ((char *) ptr < _heapbase)
1369 /* ptr points into the static heap */
1370 return special_realloc (ptr, size);
1371#endif
1372
1373 block = BLOCK (ptr); 1333 block = BLOCK (ptr);
1374 1334
1375 PROTECT_MALLOC_STATE (0); 1335 PROTECT_MALLOC_STATE (0);
@@ -1566,7 +1526,7 @@ __default_morecore (ptrdiff_t increment)
1566{ 1526{
1567 void *result; 1527 void *result;
1568#if defined (CYGWIN) 1528#if defined (CYGWIN)
1569 if (!bss_sbrk_did_unexec) 1529 if (!DUMPED)
1570 { 1530 {
1571 return bss_sbrk (increment); 1531 return bss_sbrk (increment);
1572 } 1532 }
@@ -1689,6 +1649,9 @@ memalign (size_t alignment, size_t size)
1689 return aligned_alloc (alignment, size); 1649 return aligned_alloc (alignment, size);
1690} 1650}
1691 1651
1652/* If HYBRID_MALLOC is defined, we may want to use the system
1653 posix_memalign below. */
1654#ifndef HYBRID_MALLOC
1692int 1655int
1693posix_memalign (void **memptr, size_t alignment, size_t size) 1656posix_memalign (void **memptr, size_t alignment, size_t size)
1694{ 1657{
@@ -1707,6 +1670,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size)
1707 1670
1708 return 0; 1671 return 0;
1709} 1672}
1673#endif
1710 1674
1711/* Allocate memory on a page boundary. 1675/* Allocate memory on a page boundary.
1712 Copyright (C) 1991, 92, 93, 94, 96 Free Software Foundation, Inc. 1676 Copyright (C) 1991, 92, 93, 94, 96 Free Software Foundation, Inc.
@@ -1747,6 +1711,113 @@ valloc (size_t size)
1747 return aligned_alloc (pagesize, size); 1711 return aligned_alloc (pagesize, size);
1748} 1712}
1749 1713
1714#ifdef HYBRID_MALLOC
1715#undef malloc
1716#undef realloc
1717#undef calloc
1718#undef aligned_alloc
1719#undef free
1720
1721/* Declare system malloc and friends. */
1722extern void *malloc (size_t size);
1723extern void *realloc (void *ptr, size_t size);
1724extern void *calloc (size_t nmemb, size_t size);
1725extern void free (void *ptr);
1726#ifdef HAVE_ALIGNED_ALLOC
1727extern void *aligned_alloc (size_t alignment, size_t size);
1728#elif defined HAVE_POSIX_MEMALIGN
1729extern int posix_memalign (void **memptr, size_t alignment, size_t size);
1730#endif
1731
1732/* See the comments near the beginning of this file for explanations
1733 of the following functions. */
1734
1735void *
1736hybrid_malloc (size_t size)
1737{
1738 if (DUMPED)
1739 return malloc (size);
1740 return gmalloc (size);
1741}
1742
1743void *
1744hybrid_calloc (size_t nmemb, size_t size)
1745{
1746 if (DUMPED)
1747 return calloc (nmemb, size);
1748 return gcalloc (nmemb, size);
1749}
1750
1751void
1752hybrid_free (void *ptr)
1753{
1754 if (!DUMPED)
1755 gfree (ptr);
1756 else if (!ALLOCATED_BEFORE_DUMPING (ptr))
1757 free (ptr);
1758 /* Otherwise the dumped emacs is trying to free something allocated
1759 before dumping; do nothing. */
1760 return;
1761}
1762
1763#if defined HAVE_ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
1764void *
1765hybrid_aligned_alloc (size_t alignment, size_t size)
1766{
1767 if (!DUMPED)
1768 return galigned_alloc (alignment, size);
1769 /* The following is copied from alloc.c */
1770#ifdef HAVE_ALIGNED_ALLOC
1771 return aligned_alloc (alignment, size);
1772#else /* HAVE_POSIX_MEMALIGN */
1773 void *p;
1774 return posix_memalign (&p, alignment, size) == 0 ? p : 0;
1775#endif
1776}
1777#endif
1778
1779void *
1780hybrid_realloc (void *ptr, size_t size)
1781{
1782 void *result;
1783 int type;
1784 size_t block, oldsize;
1785
1786 if (!DUMPED)
1787 return grealloc (ptr, size);
1788 if (!ALLOCATED_BEFORE_DUMPING (ptr))
1789 return realloc (ptr, size);
1790
1791 /* The dumped emacs is trying to realloc storage allocated before
1792 dumping. We just malloc new space and copy the data. */
1793 if (size == 0 || ptr == NULL)
1794 return malloc (size);
1795 block = ((char *) ptr - _heapbase) / BLOCKSIZE + 1;
1796 type = _heapinfo[block].busy.type;
1797 oldsize =
1798 type == 0 ? _heapinfo[block].busy.info.size * BLOCKSIZE
1799 : (size_t) 1 << type;
1800 result = malloc (size);
1801 if (result)
1802 return memcpy (result, ptr, min (oldsize, size));
1803 return result;
1804}
1805
1806#ifdef HYBRID_GET_CURRENT_DIR_NAME
1807/* Defined in sysdep.c. */
1808char *gget_current_dir_name (void);
1809
1810char *
1811hybrid_get_current_dir_name (void)
1812{
1813 if (DUMPED)
1814 return get_current_dir_name ();
1815 return gget_current_dir_name ();
1816}
1817#endif
1818
1819#endif /* HYBRID_MALLOC */
1820
1750#ifdef GC_MCHECK 1821#ifdef GC_MCHECK
1751 1822
1752/* Standard debugging hooks for `malloc'. 1823/* Standard debugging hooks for `malloc'.
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 7e7d68d80d4..445e59c335d 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -508,16 +508,16 @@ get_utf8_string (const char *str)
508 && err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) 508 && err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE)
509 { 509 {
510 memcpy (up, p, bytes_written); 510 memcpy (up, p, bytes_written);
511 sprintf (up + bytes_written, "\\%03o", p[bytes_written]); 511 up += bytes_written;
512 up += bytes_written+4; 512 up += sprintf (up, "\\%03o", p[bytes_written]);
513 p += bytes_written+1; 513 p += bytes_written + 1;
514 g_error_free (err); 514 g_error_free (err);
515 err = NULL; 515 err = NULL;
516 } 516 }
517 517
518 if (cp) 518 if (cp)
519 { 519 {
520 strcat (utf8_str, cp); 520 strcpy (up, cp);
521 g_free (cp); 521 g_free (cp);
522 } 522 }
523 if (err) 523 if (err)
@@ -1324,7 +1324,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
1324 1324
1325 size_hints.base_width = base_width; 1325 size_hints.base_width = base_width;
1326 size_hints.base_height = base_height; 1326 size_hints.base_height = base_height;
1327 size_hints.min_width = base_width + min_cols * FRAME_COLUMN_WIDTH (f);; 1327 size_hints.min_width = base_width + min_cols * FRAME_COLUMN_WIDTH (f);
1328 size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f); 1328 size_hints.min_height = base_height + min_rows * FRAME_LINE_HEIGHT (f);
1329 1329
1330 /* These currently have a one to one mapping with the X values, but I 1330 /* These currently have a one to one mapping with the X values, but I
@@ -2554,11 +2554,18 @@ create_menus (widget_value *data,
2554#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW 2554#ifdef HAVE_GTK_TEAROFF_MENU_ITEM_NEW
2555 if (! menu_bar_p && add_tearoff_p) 2555 if (! menu_bar_p && add_tearoff_p)
2556 { 2556 {
2557 GtkWidget *tearoff = gtk_tearoff_menu_item_new (); 2557 // Only add tearoff if menu is empty.
2558 gtk_menu_shell_append (GTK_MENU_SHELL (wmenu), tearoff); 2558 GList *list = gtk_container_get_children (GTK_CONTAINER (wmenu));
2559 if (! list)
2560 {
2561 GtkWidget *tearoff = gtk_tearoff_menu_item_new ();
2562 gtk_menu_shell_append (GTK_MENU_SHELL (wmenu), tearoff);
2559 2563
2560 g_signal_connect (G_OBJECT (tearoff), "activate", 2564 g_signal_connect (G_OBJECT (tearoff), "activate",
2561 G_CALLBACK (tearoff_activate), 0); 2565 G_CALLBACK (tearoff_activate), 0);
2566 }
2567 else
2568 g_list_free (list);
2562 } 2569 }
2563#endif 2570#endif
2564 2571
@@ -3088,7 +3095,6 @@ xg_update_submenu (GtkWidget *submenu,
3088 GList *list = 0; 3095 GList *list = 0;
3089 GList *iter; 3096 GList *iter;
3090 widget_value *cur; 3097 widget_value *cur;
3091 bool has_tearoff_p = 0;
3092 GList *first_radio = 0; 3098 GList *first_radio = 0;
3093 3099
3094 if (submenu) 3100 if (submenu)
@@ -3104,7 +3110,6 @@ xg_update_submenu (GtkWidget *submenu,
3104 /* Skip tearoff items, they have no counterpart in val. */ 3110 /* Skip tearoff items, they have no counterpart in val. */
3105 if (GTK_IS_TEAROFF_MENU_ITEM (w)) 3111 if (GTK_IS_TEAROFF_MENU_ITEM (w))
3106 { 3112 {
3107 has_tearoff_p = 1;
3108 iter = g_list_next (iter); 3113 iter = g_list_next (iter);
3109 if (iter) w = GTK_WIDGET (iter->data); 3114 if (iter) w = GTK_WIDGET (iter->data);
3110 else break; 3115 else break;
@@ -3198,7 +3203,7 @@ xg_update_submenu (GtkWidget *submenu,
3198 highlight_cb, 3203 highlight_cb,
3199 0, 3204 0,
3200 0, 3205 0,
3201 ! has_tearoff_p, 3206 1,
3202 submenu, 3207 submenu,
3203 cl_data, 3208 cl_data,
3204 0); 3209 0);
@@ -3993,17 +3998,18 @@ xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
3993 3998
3994 block_input (); 3999 block_input ();
3995 adj = gtk_range_get_adjustment (GTK_RANGE (wscroll)); 4000 adj = gtk_range_get_adjustment (GTK_RANGE (wscroll));
3996 4001#if GTK_CHECK_VERSION (2, 3, 16)
3997 /* gtk_adjustment_set_lower (adj, (gdouble) lower); 4002 gtk_adjustment_configure (adj, (gdouble) value, (gdouble) lower,
4003 (gdouble) upper, (gdouble) step_increment,
4004 (gdouble) page_increment, (gdouble) pagesize);
4005#else
4006 gtk_adjustment_set_lower (adj, (gdouble) lower);
3998 gtk_adjustment_set_upper (adj, (gdouble) upper); 4007 gtk_adjustment_set_upper (adj, (gdouble) upper);
3999 gtk_adjustment_set_page_size (adj, (gdouble) pagesize); 4008 gtk_adjustment_set_page_size (adj, (gdouble) pagesize);
4000 gtk_adjustment_set_value (adj, (gdouble) value); 4009 gtk_adjustment_set_value (adj, (gdouble) value);
4001 gtk_adjustment_set_page_increment (adj, (gdouble) page_increment); 4010 gtk_adjustment_set_page_increment (adj, (gdouble) page_increment);
4002 gtk_adjustment_set_step_increment (adj, (gdouble) 4011 gtk_adjustment_set_step_increment (adj, (gdouble) step_increment);
4003 step_increment); */ 4012#endif
4004 gtk_adjustment_configure (adj, (gdouble) value, (gdouble) lower,
4005 (gdouble) upper, (gdouble) step_increment,
4006 (gdouble) page_increment, (gdouble) pagesize);
4007 gtk_adjustment_changed (adj); 4013 gtk_adjustment_changed (adj);
4008 unblock_input (); 4014 unblock_input ();
4009 } 4015 }
diff --git a/src/image.c b/src/image.c
index 804da436ee9..4b73a5fe80c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3037,13 +3037,16 @@ xbm_load (struct frame *f, struct image *img)
3037 + SBYTES (data))); 3037 + SBYTES (data)));
3038 else 3038 else
3039 { 3039 {
3040 USE_SAFE_ALLOCA;
3041
3040 if (VECTORP (data)) 3042 if (VECTORP (data))
3041 { 3043 {
3042 int i; 3044 int i;
3043 char *p; 3045 char *p;
3044 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; 3046 int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3045 3047
3046 p = bits = alloca (nbytes * img->height); 3048 SAFE_NALLOCA (bits, nbytes, img->height);
3049 p = bits;
3047 for (i = 0; i < img->height; ++i, p += nbytes) 3050 for (i = 0; i < img->height; ++i, p += nbytes)
3048 { 3051 {
3049 Lisp_Object line = AREF (data, i); 3052 Lisp_Object line = AREF (data, i);
@@ -3064,9 +3067,8 @@ xbm_load (struct frame *f, struct image *img)
3064 int nbytes, i; 3067 int nbytes, i;
3065 /* Windows mono bitmaps are reversed compared with X. */ 3068 /* Windows mono bitmaps are reversed compared with X. */
3066 invertedBits = bits; 3069 invertedBits = bits;
3067 nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR 3070 nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
3068 * img->height; 3071 SAFE_NALLOCA (bits, nbytes, img->height);
3069 bits = alloca (nbytes);
3070 for (i = 0; i < nbytes; i++) 3072 for (i = 0; i < nbytes; i++)
3071 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]); 3073 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
3072 } 3074 }
@@ -3088,6 +3090,8 @@ xbm_load (struct frame *f, struct image *img)
3088 img->spec, Qnil); 3090 img->spec, Qnil);
3089 x_clear_image (f, img); 3091 x_clear_image (f, img);
3090 } 3092 }
3093
3094 SAFE_FREE ();
3091 } 3095 }
3092 } 3096 }
3093 3097
@@ -3494,6 +3498,8 @@ xpm_load (struct frame *f, struct image *img)
3494 int rc; 3498 int rc;
3495 XpmAttributes attrs; 3499 XpmAttributes attrs;
3496 Lisp_Object specified_file, color_symbols; 3500 Lisp_Object specified_file, color_symbols;
3501 USE_SAFE_ALLOCA;
3502
3497#ifdef HAVE_NTGUI 3503#ifdef HAVE_NTGUI
3498 HDC hdc; 3504 HDC hdc;
3499 xpm_XImage * xpm_image = NULL, * xpm_mask = NULL; 3505 xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
@@ -3536,7 +3542,7 @@ xpm_load (struct frame *f, struct image *img)
3536 { 3542 {
3537 Lisp_Object tail; 3543 Lisp_Object tail;
3538 XpmColorSymbol *xpm_syms; 3544 XpmColorSymbol *xpm_syms;
3539 int i, size; 3545 ptrdiff_t i, size;
3540 3546
3541 attrs.valuemask |= XpmColorSymbols; 3547 attrs.valuemask |= XpmColorSymbols;
3542 3548
@@ -3546,8 +3552,8 @@ xpm_load (struct frame *f, struct image *img)
3546 ++attrs.numsymbols; 3552 ++attrs.numsymbols;
3547 3553
3548 /* Allocate an XpmColorSymbol array. */ 3554 /* Allocate an XpmColorSymbol array. */
3555 SAFE_NALLOCA (xpm_syms, 1, attrs.numsymbols);
3549 size = attrs.numsymbols * sizeof *xpm_syms; 3556 size = attrs.numsymbols * sizeof *xpm_syms;
3550 xpm_syms = alloca (size);
3551 memset (xpm_syms, 0, size); 3557 memset (xpm_syms, 0, size);
3552 attrs.colorsymbols = xpm_syms; 3558 attrs.colorsymbols = xpm_syms;
3553 3559
@@ -3569,17 +3575,11 @@ xpm_load (struct frame *f, struct image *img)
3569 name = XCAR (XCAR (tail)); 3575 name = XCAR (XCAR (tail));
3570 color = XCDR (XCAR (tail)); 3576 color = XCDR (XCAR (tail));
3571 if (STRINGP (name)) 3577 if (STRINGP (name))
3572 { 3578 SAFE_ALLOCA_STRING (xpm_syms[i].name, name);
3573 xpm_syms[i].name = alloca (SCHARS (name) + 1);
3574 strcpy (xpm_syms[i].name, SSDATA (name));
3575 }
3576 else 3579 else
3577 xpm_syms[i].name = empty_string; 3580 xpm_syms[i].name = empty_string;
3578 if (STRINGP (color)) 3581 if (STRINGP (color))
3579 { 3582 SAFE_ALLOCA_STRING (xpm_syms[i].value, color);
3580 xpm_syms[i].value = alloca (SCHARS (color) + 1);
3581 strcpy (xpm_syms[i].value, SSDATA (color));
3582 }
3583 else 3583 else
3584 xpm_syms[i].value = empty_string; 3584 xpm_syms[i].value = empty_string;
3585 } 3585 }
@@ -3610,6 +3610,7 @@ xpm_load (struct frame *f, struct image *img)
3610#ifdef ALLOC_XPM_COLORS 3610#ifdef ALLOC_XPM_COLORS
3611 xpm_free_color_cache (); 3611 xpm_free_color_cache ();
3612#endif 3612#endif
3613 SAFE_FREE ();
3613 return 0; 3614 return 0;
3614 } 3615 }
3615 3616
@@ -3640,6 +3641,7 @@ xpm_load (struct frame *f, struct image *img)
3640#ifdef ALLOC_XPM_COLORS 3641#ifdef ALLOC_XPM_COLORS
3641 xpm_free_color_cache (); 3642 xpm_free_color_cache ();
3642#endif 3643#endif
3644 SAFE_FREE ();
3643 return 0; 3645 return 0;
3644 } 3646 }
3645#ifdef HAVE_NTGUI 3647#ifdef HAVE_NTGUI
@@ -3782,6 +3784,7 @@ xpm_load (struct frame *f, struct image *img)
3782#ifdef ALLOC_XPM_COLORS 3784#ifdef ALLOC_XPM_COLORS
3783 xpm_free_color_cache (); 3785 xpm_free_color_cache ();
3784#endif 3786#endif
3787 SAFE_FREE ();
3785 return rc == XpmSuccess; 3788 return rc == XpmSuccess;
3786} 3789}
3787 3790
@@ -6580,6 +6583,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6580 colors generated, and mgr->cinfo.colormap is a two-dimensional array 6583 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6581 of color indices in the range 0..mgr->cinfo.actual_number_of_colors. 6584 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6582 No more than 255 colors will be generated. */ 6585 No more than 255 colors will be generated. */
6586 USE_SAFE_ALLOCA;
6583 { 6587 {
6584 int i, ir, ig, ib; 6588 int i, ir, ig, ib;
6585 6589
@@ -6595,7 +6599,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6595 a default color, and we don't have to care about which colors 6599 a default color, and we don't have to care about which colors
6596 can be freed safely, and which can't. */ 6600 can be freed safely, and which can't. */
6597 init_color_table (); 6601 init_color_table ();
6598 colors = alloca (mgr->cinfo.actual_number_of_colors * sizeof *colors); 6602 SAFE_NALLOCA (colors, 1, mgr->cinfo.actual_number_of_colors);
6599 6603
6600 for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i) 6604 for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i)
6601 { 6605 {
@@ -6638,6 +6642,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6638 6642
6639 /* Put ximg into the image. */ 6643 /* Put ximg into the image. */
6640 image_put_x_image (f, img, ximg, 0); 6644 image_put_x_image (f, img, ximg, 0);
6645 SAFE_FREE ();
6641 return 1; 6646 return 1;
6642} 6647}
6643 6648
@@ -8226,6 +8231,12 @@ imagemagick_load_image (struct frame *f, struct image *img,
8226 return 0; 8231 return 0;
8227 } 8232 }
8228 8233
8234 if (MagickGetImageDelay (image_wand) > 0)
8235 img->lisp_data =
8236 Fcons (Qdelay,
8237 Fcons (make_float (MagickGetImageDelay (image_wand) / 100.0),
8238 img->lisp_data));
8239
8229 if (MagickGetNumberImages (image_wand) > 1) 8240 if (MagickGetNumberImages (image_wand) > 1)
8230 img->lisp_data = 8241 img->lisp_data =
8231 Fcons (Qcount, 8242 Fcons (Qcount,
diff --git a/src/indent.c b/src/indent.c
index 79af42c5f7e..e6b267a3891 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2004,6 +2004,8 @@ whether or not it is currently displayed in some window. */)
2004 int first_x; 2004 int first_x;
2005 bool overshoot_handled = 0; 2005 bool overshoot_handled = 0;
2006 bool disp_string_at_start_p = 0; 2006 bool disp_string_at_start_p = 0;
2007 ptrdiff_t nlines = XINT (lines);
2008 int vpos_init = 0;
2007 2009
2008 itdata = bidi_shelve_cache (); 2010 itdata = bidi_shelve_cache ();
2009 SET_TEXT_POS (pt, PT, PT_BYTE); 2011 SET_TEXT_POS (pt, PT, PT_BYTE);
@@ -2093,18 +2095,31 @@ whether or not it is currently displayed in some window. */)
2093 2095
2094 overshoot_handled = 1; 2096 overshoot_handled = 1;
2095 } 2097 }
2096 if (XINT (lines) <= 0) 2098 else if (IT_CHARPOS (it) == PT - 1
2099 && FETCH_BYTE (PT - 1) == '\n'
2100 && nlines < 0)
2097 { 2101 {
2098 it.vpos = 0; 2102 /* The position we started from was covered by a display
2103 property, so we moved to position before the string, and
2104 backed up one line, because the character at PT - 1 is a
2105 newline. So we need one less line to go up. */
2106 nlines++;
2107 /* But we still need to record that one line, in order to
2108 return the correct value to the caller. */
2109 vpos_init = -1;
2110 }
2111 if (nlines <= 0)
2112 {
2113 it.vpos = vpos_init;
2099 /* Do this even if LINES is 0, so that we move back to the 2114 /* Do this even if LINES is 0, so that we move back to the
2100 beginning of the current line as we ought. */ 2115 beginning of the current line as we ought. */
2101 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0) 2116 if (nlines == 0 || IT_CHARPOS (it) > 0)
2102 move_it_by_lines (&it, max (PTRDIFF_MIN, XINT (lines))); 2117 move_it_by_lines (&it, max (PTRDIFF_MIN, nlines));
2103 } 2118 }
2104 else if (overshoot_handled) 2119 else if (overshoot_handled)
2105 { 2120 {
2106 it.vpos = 0; 2121 it.vpos = 0;
2107 move_it_by_lines (&it, min (PTRDIFF_MAX, XINT (lines))); 2122 move_it_by_lines (&it, min (PTRDIFF_MAX, nlines));
2108 } 2123 }
2109 else 2124 else
2110 { 2125 {
@@ -2119,13 +2134,13 @@ whether or not it is currently displayed in some window. */)
2119 it.vpos = 0; 2134 it.vpos = 0;
2120 move_it_by_lines (&it, 1); 2135 move_it_by_lines (&it, 1);
2121 } 2136 }
2122 if (XINT (lines) > 1) 2137 if (nlines > 1)
2123 move_it_by_lines (&it, min (PTRDIFF_MAX, XINT (lines) - 1)); 2138 move_it_by_lines (&it, min (PTRDIFF_MAX, nlines - 1));
2124 } 2139 }
2125 else 2140 else
2126 { 2141 {
2127 it.vpos = 0; 2142 it.vpos = 0;
2128 move_it_by_lines (&it, min (PTRDIFF_MAX, XINT (lines))); 2143 move_it_by_lines (&it, min (PTRDIFF_MAX, nlines));
2129 } 2144 }
2130 } 2145 }
2131 2146
diff --git a/src/keyboard.c b/src/keyboard.c
index 9b0b19ada2f..e8143f26681 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -133,6 +133,19 @@ static ptrdiff_t this_single_command_key_start;
133static ptrdiff_t before_command_key_count; 133static ptrdiff_t before_command_key_count;
134static ptrdiff_t before_command_echo_length; 134static ptrdiff_t before_command_echo_length;
135 135
136#ifdef HAVE_STACK_OVERFLOW_HANDLING
137
138/* For longjmp to recover from C stack overflow. */
139sigjmp_buf return_to_command_loop;
140
141/* Message displayed by Vtop_level when recovering from C stack overflow. */
142static Lisp_Object recover_top_level_message;
143
144#endif /* HAVE_STACK_OVERFLOW_HANDLING */
145
146/* Message normally displayed by Vtop_level. */
147static Lisp_Object regular_top_level_message;
148
136/* For longjmp to where kbd input is being done. */ 149/* For longjmp to where kbd input is being done. */
137 150
138static sys_jmp_buf getcjmp; 151static sys_jmp_buf getcjmp;
@@ -487,10 +500,12 @@ kset_system_key_syms (struct kboard *kb, Lisp_Object val)
487static void 500static void
488echo_add_key (Lisp_Object c) 501echo_add_key (Lisp_Object c)
489{ 502{
490 int size = KEY_DESCRIPTION_SIZE + 100; 503 char initbuf[KEY_DESCRIPTION_SIZE + 100];
491 char *buffer = alloca (size); 504 ptrdiff_t size = sizeof initbuf;
505 char *buffer = initbuf;
492 char *ptr = buffer; 506 char *ptr = buffer;
493 Lisp_Object echo_string; 507 Lisp_Object echo_string;
508 USE_SAFE_ALLOCA;
494 509
495 echo_string = KVAR (current_kboard, echo_string); 510 echo_string = KVAR (current_kboard, echo_string);
496 511
@@ -502,13 +517,13 @@ echo_add_key (Lisp_Object c)
502 else if (SYMBOLP (c)) 517 else if (SYMBOLP (c))
503 { 518 {
504 Lisp_Object name = SYMBOL_NAME (c); 519 Lisp_Object name = SYMBOL_NAME (c);
505 int nbytes = SBYTES (name); 520 ptrdiff_t nbytes = SBYTES (name);
506 521
507 if (size - (ptr - buffer) < nbytes) 522 if (size - (ptr - buffer) < nbytes)
508 { 523 {
509 int offset = ptr - buffer; 524 ptrdiff_t offset = ptr - buffer;
510 size = max (2 * size, size + nbytes); 525 size = max (2 * size, size + nbytes);
511 buffer = alloca (size); 526 buffer = SAFE_ALLOCA (size);
512 ptr = buffer + offset; 527 ptr = buffer + offset;
513 } 528 }
514 529
@@ -519,14 +534,14 @@ echo_add_key (Lisp_Object c)
519 if ((NILP (echo_string) || SCHARS (echo_string) == 0) 534 if ((NILP (echo_string) || SCHARS (echo_string) == 0)
520 && help_char_p (c)) 535 && help_char_p (c))
521 { 536 {
522 const char *text = " (Type ? for further options)"; 537 static const char text[] = " (Type ? for further options)";
523 int len = strlen (text); 538 int len = sizeof text - 1;
524 539
525 if (size - (ptr - buffer) < len) 540 if (size - (ptr - buffer) < len)
526 { 541 {
527 int offset = ptr - buffer; 542 ptrdiff_t offset = ptr - buffer;
528 size += len; 543 size += len;
529 buffer = alloca (size); 544 buffer = SAFE_ALLOCA (size);
530 ptr = buffer + offset; 545 ptr = buffer + offset;
531 } 546 }
532 547
@@ -536,6 +551,7 @@ echo_add_key (Lisp_Object c)
536 551
537 /* Replace a dash from echo_dash with a space, otherwise add a space 552 /* Replace a dash from echo_dash with a space, otherwise add a space
538 at the end as a separator between keys. */ 553 at the end as a separator between keys. */
554 AUTO_STRING (space, " ");
539 if (STRINGP (echo_string) && SCHARS (echo_string) > 1) 555 if (STRINGP (echo_string) && SCHARS (echo_string) > 1)
540 { 556 {
541 Lisp_Object last_char, prev_char, idx; 557 Lisp_Object last_char, prev_char, idx;
@@ -551,14 +567,15 @@ echo_add_key (Lisp_Object c)
551 if (XINT (last_char) == '-' && XINT (prev_char) != ' ') 567 if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
552 Faset (echo_string, idx, make_number (' ')); 568 Faset (echo_string, idx, make_number (' '));
553 else 569 else
554 echo_string = concat2 (echo_string, build_string (" ")); 570 echo_string = concat2 (echo_string, space);
555 } 571 }
556 else if (STRINGP (echo_string) && SCHARS (echo_string) > 0) 572 else if (STRINGP (echo_string) && SCHARS (echo_string) > 0)
557 echo_string = concat2 (echo_string, build_string (" ")); 573 echo_string = concat2 (echo_string, space);
558 574
559 kset_echo_string 575 kset_echo_string
560 (current_kboard, 576 (current_kboard,
561 concat2 (echo_string, make_string (buffer, ptr - buffer))); 577 concat2 (echo_string, make_string (buffer, ptr - buffer)));
578 SAFE_FREE ();
562} 579}
563 580
564/* Add C to the echo string, if echoing is going on. C can be a 581/* Add C to the echo string, if echoing is going on. C can be a
@@ -614,9 +631,9 @@ echo_dash (void)
614 631
615 /* Put a dash at the end of the buffer temporarily, 632 /* Put a dash at the end of the buffer temporarily,
616 but make it go away when the next character is added. */ 633 but make it go away when the next character is added. */
617 kset_echo_string 634 AUTO_STRING (dash, "-");
618 (current_kboard, 635 kset_echo_string (current_kboard,
619 concat2 (KVAR (current_kboard, echo_string), build_string ("-"))); 636 concat2 (KVAR (current_kboard, echo_string), dash));
620 echo_now (); 637 echo_now ();
621} 638}
622 639
@@ -1109,7 +1126,7 @@ Default value of `command-error-function'. */)
1109 { 1126 {
1110 print_error_message (data, Qexternal_debugging_output, 1127 print_error_message (data, Qexternal_debugging_output,
1111 SSDATA (context), signal); 1128 SSDATA (context), signal);
1112 Fterpri (Qexternal_debugging_output); 1129 Fterpri (Qexternal_debugging_output, Qnil);
1113 Fkill_emacs (make_number (-1)); 1130 Fkill_emacs (make_number (-1));
1114 } 1131 }
1115 else 1132 else
@@ -1134,6 +1151,17 @@ static Lisp_Object top_level_1 (Lisp_Object);
1134Lisp_Object 1151Lisp_Object
1135command_loop (void) 1152command_loop (void)
1136{ 1153{
1154#ifdef HAVE_STACK_OVERFLOW_HANDLING
1155 /* At least on GNU/Linux, saving signal mask is important here. */
1156 if (sigsetjmp (return_to_command_loop, 1) != 0)
1157 {
1158 /* Comes here from handle_sigsegv, see sysdep.c. */
1159 init_eval ();
1160 Vinternal__top_level_message = recover_top_level_message;
1161 }
1162 else
1163 Vinternal__top_level_message = regular_top_level_message;
1164#endif /* HAVE_STACK_OVERFLOW_HANDLING */
1137 if (command_loop_level > 0 || minibuf_level > 0) 1165 if (command_loop_level > 0 || minibuf_level > 0)
1138 { 1166 {
1139 Lisp_Object val; 1167 Lisp_Object val;
@@ -1258,13 +1286,9 @@ tracking_off (Lisp_Object old_value)
1258 } 1286 }
1259} 1287}
1260 1288
1261DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, 1289DEFUN ("internal--track-mouse", Ftrack_mouse, Strack_mouse, 1, 1, 0,
1262 doc: /* Evaluate BODY with mouse movement events enabled. 1290 doc: /* Call BODYFUN with mouse movement events enabled. */)
1263Within a `track-mouse' form, mouse motion generates input events that 1291 (Lisp_Object bodyfun)
1264you can read with `read-event'.
1265Normally, mouse motion is ignored.
1266usage: (track-mouse BODY...) */)
1267 (Lisp_Object args)
1268{ 1292{
1269 ptrdiff_t count = SPECPDL_INDEX (); 1293 ptrdiff_t count = SPECPDL_INDEX ();
1270 Lisp_Object val; 1294 Lisp_Object val;
@@ -1273,7 +1297,7 @@ usage: (track-mouse BODY...) */)
1273 1297
1274 do_mouse_tracking = Qt; 1298 do_mouse_tracking = Qt;
1275 1299
1276 val = Fprogn (args); 1300 val = call0 (bodyfun);
1277 return unbind_to (count, val); 1301 return unbind_to (count, val);
1278} 1302}
1279 1303
@@ -1867,16 +1891,11 @@ safe_run_hooks_1 (ptrdiff_t nargs, Lisp_Object *args)
1867static Lisp_Object 1891static Lisp_Object
1868safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) 1892safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args)
1869{ 1893{
1870 Lisp_Object hook, fun, msgargs[4];
1871
1872 eassert (nargs == 2); 1894 eassert (nargs == 2);
1873 hook = args[0]; 1895 AUTO_STRING (format, "Error in %s (%S): %S");
1874 fun = args[1]; 1896 Lisp_Object hook = args[0];
1875 msgargs[0] = build_string ("Error in %s (%S): %S"); 1897 Lisp_Object fun = args[1];
1876 msgargs[1] = hook; 1898 Fmessage (4, (Lisp_Object []) {format, hook, fun, error});
1877 msgargs[2] = fun;
1878 msgargs[3] = error;
1879 Fmessage (4, msgargs);
1880 1899
1881 if (SYMBOLP (hook)) 1900 if (SYMBOLP (hook))
1882 { 1901 {
@@ -2327,15 +2346,16 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
2327 { /* An encoded byte sequence, let's try to decode it. */ 2346 { /* An encoded byte sequence, let's try to decode it. */
2328 struct coding_system *coding 2347 struct coding_system *coding
2329 = TERMINAL_KEYBOARD_CODING (terminal); 2348 = TERMINAL_KEYBOARD_CODING (terminal);
2330 unsigned char *src = alloca (n); 2349 unsigned char src[MAX_ENCODED_BYTES];
2350 unsigned char dest[MAX_ENCODED_BYTES * MAX_MULTIBYTE_LENGTH];
2331 int i; 2351 int i;
2332 for (i = 0; i < n; i++) 2352 for (i = 0; i < n; i++)
2333 src[i] = XINT (events[i]); 2353 src[i] = XINT (events[i]);
2334 if (meta_key != 2) 2354 if (meta_key != 2)
2335 for (i = 0; i < n; i++) 2355 for (i = 0; i < n; i++)
2336 src[i] &= ~0x80; 2356 src[i] &= ~0x80;
2337 coding->destination = alloca (n * 4); 2357 coding->destination = dest;
2338 coding->dst_bytes = n * 4; 2358 coding->dst_bytes = sizeof dest;
2339 decode_coding_c_string (coding, src, n, Qnil); 2359 decode_coding_c_string (coding, src, n, Qnil);
2340 eassert (coding->produced_char <= n); 2360 eassert (coding->produced_char <= n);
2341 if (coding->produced_char == 0) 2361 if (coding->produced_char == 0)
@@ -3704,6 +3724,34 @@ kbd_buffer_unget_event (register struct input_event *event)
3704 } 3724 }
3705} 3725}
3706 3726
3727/* Limit help event positions to this range, to avoid overflow problems. */
3728#define INPUT_EVENT_POS_MAX \
3729 ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \
3730 MOST_POSITIVE_FIXNUM)))
3731#define INPUT_EVENT_POS_MIN (-1 - INPUT_EVENT_POS_MAX)
3732
3733/* Return a Time that encodes position POS. POS must be in range. */
3734
3735static Time
3736position_to_Time (ptrdiff_t pos)
3737{
3738 eassert (INPUT_EVENT_POS_MIN <= pos && pos <= INPUT_EVENT_POS_MAX);
3739 return pos;
3740}
3741
3742/* Return the position that ENCODED_POS encodes.
3743 Avoid signed integer overflow. */
3744
3745static ptrdiff_t
3746Time_to_position (Time encoded_pos)
3747{
3748 if (encoded_pos <= INPUT_EVENT_POS_MAX)
3749 return encoded_pos;
3750 Time encoded_pos_min = INPUT_EVENT_POS_MIN;
3751 eassert (encoded_pos_min <= encoded_pos);
3752 ptrdiff_t notpos = -1 - encoded_pos;
3753 return -1 - notpos;
3754}
3707 3755
3708/* Generate a HELP_EVENT input_event and store it in the keyboard 3756/* Generate a HELP_EVENT input_event and store it in the keyboard
3709 buffer. 3757 buffer.
@@ -3722,14 +3770,12 @@ gen_help_event (Lisp_Object help, Lisp_Object frame, Lisp_Object window,
3722{ 3770{
3723 struct input_event event; 3771 struct input_event event;
3724 3772
3725 EVENT_INIT (event);
3726
3727 event.kind = HELP_EVENT; 3773 event.kind = HELP_EVENT;
3728 event.frame_or_window = frame; 3774 event.frame_or_window = frame;
3729 event.arg = object; 3775 event.arg = object;
3730 event.x = WINDOWP (window) ? window : frame; 3776 event.x = WINDOWP (window) ? window : frame;
3731 event.y = help; 3777 event.y = help;
3732 event.code = pos; 3778 event.timestamp = position_to_Time (pos);
3733 kbd_buffer_store_event (&event); 3779 kbd_buffer_store_event (&event);
3734} 3780}
3735 3781
@@ -3746,7 +3792,7 @@ kbd_buffer_store_help_event (Lisp_Object frame, Lisp_Object help)
3746 event.arg = Qnil; 3792 event.arg = Qnil;
3747 event.x = Qnil; 3793 event.x = Qnil;
3748 event.y = help; 3794 event.y = help;
3749 event.code = 0; 3795 event.timestamp = 0;
3750 kbd_buffer_store_event (&event); 3796 kbd_buffer_store_event (&event);
3751} 3797}
3752 3798
@@ -4061,7 +4107,7 @@ kbd_buffer_get_event (KBOARD **kbp,
4061 4107
4062 frame = event->frame_or_window; 4108 frame = event->frame_or_window;
4063 object = event->arg; 4109 object = event->arg;
4064 position = make_number (event->code); 4110 position = make_number (Time_to_position (event->timestamp));
4065 window = event->x; 4111 window = event->x;
4066 help = event->y; 4112 help = event->y;
4067 clear_event (event); 4113 clear_event (event);
@@ -5171,14 +5217,15 @@ static const char *const lispy_drag_n_drop_names[] =
5171static Lisp_Object Qabove_handle, Qhandle, Qbelow_handle; 5217static Lisp_Object Qabove_handle, Qhandle, Qbelow_handle;
5172static Lisp_Object Qbefore_handle, Qhorizontal_handle, Qafter_handle; 5218static Lisp_Object Qbefore_handle, Qhorizontal_handle, Qafter_handle;
5173Lisp_Object Qup, Qdown, Qtop, Qbottom; 5219Lisp_Object Qup, Qdown, Qtop, Qbottom;
5174Lisp_Object Qleft, Qright;
5175static Lisp_Object Qleftmost, Qrightmost; 5220static Lisp_Object Qleftmost, Qrightmost;
5176static Lisp_Object Qend_scroll; 5221static Lisp_Object Qend_scroll;
5177static Lisp_Object Qratio; 5222static Lisp_Object Qratio;
5178 5223
5179/* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */ 5224/* An array of scroll bar parts, indexed by an enum scroll_bar_part value.
5225 Note that Qnil corresponds to scroll_bar_nowhere and should not appear
5226 in Lisp events. */
5180static Lisp_Object *const scroll_bar_parts[] = { 5227static Lisp_Object *const scroll_bar_parts[] = {
5181 &Qabove_handle, &Qhandle, &Qbelow_handle, 5228 &Qnil, &Qabove_handle, &Qhandle, &Qbelow_handle,
5182 &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio, 5229 &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio,
5183 &Qbefore_handle, &Qhorizontal_handle, &Qafter_handle, 5230 &Qbefore_handle, &Qhorizontal_handle, &Qafter_handle,
5184 &Qleft, &Qright, &Qleftmost, &Qrightmost, &Qend_scroll, &Qratio 5231 &Qleft, &Qright, &Qleftmost, &Qrightmost, &Qend_scroll, &Qratio
@@ -5425,6 +5472,16 @@ toolkit_menubar_in_use (struct frame *f)
5425#endif 5472#endif
5426} 5473}
5427 5474
5475/* Build the part of Lisp event which represents scroll bar state from
5476 EV. TYPE is one of Qvertical_scroll_bar or Qhorizontal_scroll_bar. */
5477
5478static Lisp_Object
5479make_scroll_bar_position (struct input_event *ev, Lisp_Object type)
5480{
5481 return list5 (ev->frame_or_window, type, Fcons (ev->x, ev->y),
5482 make_number (ev->timestamp), *scroll_bar_parts[ev->part]);
5483}
5484
5428/* Given a struct input_event, build the lisp event which represents 5485/* Given a struct input_event, build the lisp event which represents
5429 it. If EVENT is 0, build a mouse movement event from the mouse 5486 it. If EVENT is 0, build a mouse movement event from the mouse
5430 movement buffer, which should have a movement event in it. 5487 movement buffer, which should have a movement event in it.
@@ -5513,30 +5570,27 @@ make_lispy_event (struct input_event *event)
5513 ARRAYELTS (iso_lispy_function_keys)); 5570 ARRAYELTS (iso_lispy_function_keys));
5514#endif 5571#endif
5515 5572
5516 /* Handle system-specific or unknown keysyms. */ 5573 if ((FUNCTION_KEY_OFFSET <= event->code
5517 if (event->code & (1 << 28) 5574 && (event->code
5518 || event->code - FUNCTION_KEY_OFFSET < 0 5575 < FUNCTION_KEY_OFFSET + ARRAYELTS (lispy_function_keys)))
5519 || (event->code - FUNCTION_KEY_OFFSET 5576 && lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
5520 >= ARRAYELTS (lispy_function_keys)) 5577 return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
5521 || !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET]) 5578 event->modifiers,
5522 { 5579 Qfunction_key, Qnil,
5523 /* We need to use an alist rather than a vector as the cache 5580 lispy_function_keys, &func_key_syms,
5524 since we can't make a vector long enough. */ 5581 ARRAYELTS (lispy_function_keys));
5525 if (NILP (KVAR (current_kboard, system_key_syms))) 5582
5526 kset_system_key_syms (current_kboard, Fcons (Qnil, Qnil)); 5583 /* Handle system-specific or unknown keysyms.
5527 return modify_event_symbol (event->code, 5584 We need to use an alist rather than a vector as the cache
5528 event->modifiers, 5585 since we can't make a vector long enough. */
5529 Qfunction_key, 5586 if (NILP (KVAR (current_kboard, system_key_syms)))
5530 KVAR (current_kboard, Vsystem_key_alist), 5587 kset_system_key_syms (current_kboard, Fcons (Qnil, Qnil));
5531 0, &KVAR (current_kboard, system_key_syms), 5588 return modify_event_symbol (event->code,
5532 PTRDIFF_MAX);
5533 }
5534
5535 return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
5536 event->modifiers, 5589 event->modifiers,
5537 Qfunction_key, Qnil, 5590 Qfunction_key,
5538 lispy_function_keys, &func_key_syms, 5591 KVAR (current_kboard, Vsystem_key_alist),
5539 ARRAYELTS (lispy_function_keys)); 5592 0, &KVAR (current_kboard, system_key_syms),
5593 PTRDIFF_MAX);
5540 5594
5541#ifdef HAVE_NTGUI 5595#ifdef HAVE_NTGUI
5542 case MULTIMEDIA_KEY_EVENT: 5596 case MULTIMEDIA_KEY_EVENT:
@@ -5642,20 +5696,8 @@ make_lispy_event (struct input_event *event)
5642 } 5696 }
5643#ifndef USE_TOOLKIT_SCROLL_BARS 5697#ifndef USE_TOOLKIT_SCROLL_BARS
5644 else 5698 else
5645 { 5699 /* It's a scrollbar click. */
5646 /* It's a scrollbar click. */ 5700 position = make_scroll_bar_position (event, Qvertical_scroll_bar);
5647 Lisp_Object window;
5648 Lisp_Object portion_whole;
5649 Lisp_Object part;
5650
5651 window = event->frame_or_window;
5652 portion_whole = Fcons (event->x, event->y);
5653 part = *scroll_bar_parts[(int) event->part];
5654
5655 position = list5 (window, Qvertical_scroll_bar,
5656 portion_whole, make_number (event->timestamp),
5657 part);
5658 }
5659#endif /* not USE_TOOLKIT_SCROLL_BARS */ 5701#endif /* not USE_TOOLKIT_SCROLL_BARS */
5660 5702
5661 if (button >= ASIZE (button_down_location)) 5703 if (button >= ASIZE (button_down_location))
@@ -5932,14 +5974,9 @@ make_lispy_event (struct input_event *event)
5932 5974
5933 case SCROLL_BAR_CLICK_EVENT: 5975 case SCROLL_BAR_CLICK_EVENT:
5934 { 5976 {
5935 Lisp_Object position, head, window, portion_whole, part; 5977 Lisp_Object position, head;
5936
5937 window = event->frame_or_window;
5938 portion_whole = Fcons (event->x, event->y);
5939 part = *scroll_bar_parts[(int) event->part];
5940 5978
5941 position = list5 (window, Qvertical_scroll_bar, portion_whole, 5979 position = make_scroll_bar_position (event, Qvertical_scroll_bar);
5942 make_number (event->timestamp), part);
5943 5980
5944 /* Always treat scroll bar events as clicks. */ 5981 /* Always treat scroll bar events as clicks. */
5945 event->modifiers |= click_modifier; 5982 event->modifiers |= click_modifier;
@@ -5962,14 +5999,9 @@ make_lispy_event (struct input_event *event)
5962 5999
5963 case HORIZONTAL_SCROLL_BAR_CLICK_EVENT: 6000 case HORIZONTAL_SCROLL_BAR_CLICK_EVENT:
5964 { 6001 {
5965 Lisp_Object position, head, window, portion_whole, part; 6002 Lisp_Object position, head;
5966 6003
5967 window = event->frame_or_window; 6004 position = make_scroll_bar_position (event, Qhorizontal_scroll_bar);
5968 portion_whole = Fcons (event->x, event->y);
5969 part = *scroll_bar_parts[(int) event->part];
5970
5971 position = list5 (window, Qhorizontal_scroll_bar, portion_whole,
5972 make_number (event->timestamp), part);
5973 6005
5974 /* Always treat scroll bar events as clicks. */ 6006 /* Always treat scroll bar events as clicks. */
5975 event->modifiers |= click_modifier; 6007 event->modifiers |= click_modifier;
@@ -7410,11 +7442,14 @@ menu_bar_items (Lisp_Object old)
7410 in the current keymaps, or nil where it is not a prefix. */ 7442 in the current keymaps, or nil where it is not a prefix. */
7411 Lisp_Object *maps; 7443 Lisp_Object *maps;
7412 7444
7445 Lisp_Object mapsbuf[3];
7413 Lisp_Object def, tail; 7446 Lisp_Object def, tail;
7414 7447
7415 ptrdiff_t mapno; 7448 ptrdiff_t mapno;
7416 Lisp_Object oquit; 7449 Lisp_Object oquit;
7417 7450
7451 USE_SAFE_ALLOCA;
7452
7418 /* In order to build the menus, we need to call the keymap 7453 /* In order to build the menus, we need to call the keymap
7419 accessors. They all call QUIT. But this function is called 7454 accessors. They all call QUIT. But this function is called
7420 during redisplay, during which a quit is fatal. So inhibit 7455 during redisplay, during which a quit is fatal. So inhibit
@@ -7443,7 +7478,7 @@ menu_bar_items (Lisp_Object old)
7443 && !NILP (Voverriding_local_map)) 7478 && !NILP (Voverriding_local_map))
7444 { 7479 {
7445 /* Yes, use them (if non-nil) as well as the global map. */ 7480 /* Yes, use them (if non-nil) as well as the global map. */
7446 maps = alloca (3 * sizeof (maps[0])); 7481 maps = mapsbuf;
7447 nmaps = 0; 7482 nmaps = 0;
7448 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) 7483 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
7449 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map); 7484 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
@@ -7460,7 +7495,7 @@ menu_bar_items (Lisp_Object old)
7460 Lisp_Object tem; 7495 Lisp_Object tem;
7461 ptrdiff_t nminor; 7496 ptrdiff_t nminor;
7462 nminor = current_minor_maps (NULL, &tmaps); 7497 nminor = current_minor_maps (NULL, &tmaps);
7463 maps = alloca ((nminor + 4) * sizeof *maps); 7498 SAFE_NALLOCA (maps, 1, nminor + 4);
7464 nmaps = 0; 7499 nmaps = 0;
7465 tem = KVAR (current_kboard, Voverriding_terminal_local_map); 7500 tem = KVAR (current_kboard, Voverriding_terminal_local_map);
7466 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag)) 7501 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
@@ -7532,6 +7567,7 @@ menu_bar_items (Lisp_Object old)
7532 } 7567 }
7533 7568
7534 Vinhibit_quit = oquit; 7569 Vinhibit_quit = oquit;
7570 SAFE_FREE ();
7535 return menu_bar_items_vector; 7571 return menu_bar_items_vector;
7536} 7572}
7537 7573
@@ -7847,11 +7883,12 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7847 7883
7848 { /* This is a command. See if there is an equivalent key binding. */ 7884 { /* This is a command. See if there is an equivalent key binding. */
7849 Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ); 7885 Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
7886 AUTO_STRING (space_space, " ");
7850 7887
7851 /* The previous code preferred :key-sequence to :keys, so we 7888 /* The previous code preferred :key-sequence to :keys, so we
7852 preserve this behavior. */ 7889 preserve this behavior. */
7853 if (STRINGP (keyeq) && !CONSP (keyhint)) 7890 if (STRINGP (keyeq) && !CONSP (keyhint))
7854 keyeq = concat2 (build_string (" "), Fsubstitute_command_keys (keyeq)); 7891 keyeq = concat2 (space_space, Fsubstitute_command_keys (keyeq));
7855 else 7892 else
7856 { 7893 {
7857 Lisp_Object prefix = keyeq; 7894 Lisp_Object prefix = keyeq;
@@ -7894,8 +7931,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7894 if (STRINGP (XCDR (prefix))) 7931 if (STRINGP (XCDR (prefix)))
7895 tem = concat2 (tem, XCDR (prefix)); 7932 tem = concat2 (tem, XCDR (prefix));
7896 } 7933 }
7897 keyeq = concat2 (build_string (" "), tem); 7934 keyeq = concat2 (space_space, tem);
7898 /* keyeq = concat3(build_string(" ("),tem,build_string(")")); */
7899 } 7935 }
7900 else 7936 else
7901 keyeq = Qnil; 7937 keyeq = Qnil;
@@ -7968,9 +8004,11 @@ Lisp_Object
7968tool_bar_items (Lisp_Object reuse, int *nitems) 8004tool_bar_items (Lisp_Object reuse, int *nitems)
7969{ 8005{
7970 Lisp_Object *maps; 8006 Lisp_Object *maps;
8007 Lisp_Object mapsbuf[3];
7971 ptrdiff_t nmaps, i; 8008 ptrdiff_t nmaps, i;
7972 Lisp_Object oquit; 8009 Lisp_Object oquit;
7973 Lisp_Object *tmaps; 8010 Lisp_Object *tmaps;
8011 USE_SAFE_ALLOCA;
7974 8012
7975 *nitems = 0; 8013 *nitems = 0;
7976 8014
@@ -7994,7 +8032,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
7994 && !NILP (Voverriding_local_map)) 8032 && !NILP (Voverriding_local_map))
7995 { 8033 {
7996 /* Yes, use them (if non-nil) as well as the global map. */ 8034 /* Yes, use them (if non-nil) as well as the global map. */
7997 maps = alloca (3 * sizeof *maps); 8035 maps = mapsbuf;
7998 nmaps = 0; 8036 nmaps = 0;
7999 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) 8037 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
8000 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map); 8038 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
@@ -8011,7 +8049,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
8011 Lisp_Object tem; 8049 Lisp_Object tem;
8012 ptrdiff_t nminor; 8050 ptrdiff_t nminor;
8013 nminor = current_minor_maps (NULL, &tmaps); 8051 nminor = current_minor_maps (NULL, &tmaps);
8014 maps = alloca ((nminor + 4) * sizeof *maps); 8052 SAFE_NALLOCA (maps, 1, nminor + 4);
8015 nmaps = 0; 8053 nmaps = 0;
8016 tem = KVAR (current_kboard, Voverriding_terminal_local_map); 8054 tem = KVAR (current_kboard, Voverriding_terminal_local_map);
8017 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag)) 8055 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
@@ -8040,6 +8078,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
8040 8078
8041 Vinhibit_quit = oquit; 8079 Vinhibit_quit = oquit;
8042 *nitems = ntool_bar_items / TOOL_BAR_ITEM_NSLOTS; 8080 *nitems = ntool_bar_items / TOOL_BAR_ITEM_NSLOTS;
8081 SAFE_FREE ();
8043 return tool_bar_items_vector; 8082 return tool_bar_items_vector;
8044} 8083}
8045 8084
@@ -8478,7 +8517,7 @@ static Lisp_Object
8478read_char_minibuf_menu_prompt (int commandflag, 8517read_char_minibuf_menu_prompt (int commandflag,
8479 Lisp_Object map) 8518 Lisp_Object map)
8480{ 8519{
8481 register Lisp_Object name; 8520 Lisp_Object name;
8482 ptrdiff_t nlength; 8521 ptrdiff_t nlength;
8483 /* FIXME: Use the minibuffer's frame width. */ 8522 /* FIXME: Use the minibuffer's frame width. */
8484 ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4; 8523 ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
@@ -8596,10 +8635,14 @@ read_char_minibuf_menu_prompt (int commandflag,
8596 /* Insert button prefix. */ 8635 /* Insert button prefix. */
8597 Lisp_Object selected 8636 Lisp_Object selected
8598 = AREF (item_properties, ITEM_PROPERTY_SELECTED); 8637 = AREF (item_properties, ITEM_PROPERTY_SELECTED);
8638 AUTO_STRING (radio_yes, "(*) ");
8639 AUTO_STRING (radio_no , "( ) ");
8640 AUTO_STRING (check_yes, "[X] ");
8641 AUTO_STRING (check_no , "[ ] ");
8599 if (EQ (tem, QCradio)) 8642 if (EQ (tem, QCradio))
8600 tem = build_string (NILP (selected) ? "(*) " : "( ) "); 8643 tem = NILP (selected) ? radio_yes : radio_no;
8601 else 8644 else
8602 tem = build_string (NILP (selected) ? "[X] " : "[ ] "); 8645 tem = NILP (selected) ? check_yes : check_no;
8603 s = concat2 (tem, s); 8646 s = concat2 (tem, s);
8604 } 8647 }
8605 8648
@@ -10306,7 +10349,7 @@ static void
10306handle_interrupt_signal (int sig) 10349handle_interrupt_signal (int sig)
10307{ 10350{
10308 /* See if we have an active terminal on our controlling tty. */ 10351 /* See if we have an active terminal on our controlling tty. */
10309 struct terminal *terminal = get_named_tty ("/dev/tty"); 10352 struct terminal *terminal = get_named_terminal ("/dev/tty");
10310 if (!terminal) 10353 if (!terminal)
10311 { 10354 {
10312 /* If there are no frames there, let's pretend that we are a 10355 /* If there are no frames there, let's pretend that we are a
@@ -10360,7 +10403,7 @@ handle_interrupt (bool in_signal_handler)
10360 cancel_echoing (); 10403 cancel_echoing ();
10361 10404
10362 /* XXX This code needs to be revised for multi-tty support. */ 10405 /* XXX This code needs to be revised for multi-tty support. */
10363 if (!NILP (Vquit_flag) && get_named_tty ("/dev/tty")) 10406 if (!NILP (Vquit_flag) && get_named_terminal ("/dev/tty"))
10364 { 10407 {
10365 if (! in_signal_handler) 10408 if (! in_signal_handler)
10366 { 10409 {
@@ -10572,9 +10615,10 @@ Emacs reads input in CBREAK mode; see `set-input-interrupt-mode'.
10572See also `current-input-mode'. */) 10615See also `current-input-mode'. */)
10573 (Lisp_Object flow, Lisp_Object terminal) 10616 (Lisp_Object flow, Lisp_Object terminal)
10574{ 10617{
10575 struct terminal *t = get_terminal (terminal, 1); 10618 struct terminal *t = decode_tty_terminal (terminal);
10576 struct tty_display_info *tty; 10619 struct tty_display_info *tty;
10577 if (t == NULL || (t->type != output_termcap && t->type != output_msdos_raw)) 10620
10621 if (!t)
10578 return Qnil; 10622 return Qnil;
10579 tty = t->display_info.tty; 10623 tty = t->display_info.tty;
10580 10624
@@ -10614,11 +10658,11 @@ the currently selected frame.
10614See also `current-input-mode'. */) 10658See also `current-input-mode'. */)
10615 (Lisp_Object meta, Lisp_Object terminal) 10659 (Lisp_Object meta, Lisp_Object terminal)
10616{ 10660{
10617 struct terminal *t = get_terminal (terminal, 1); 10661 struct terminal *t = decode_tty_terminal (terminal);
10618 struct tty_display_info *tty; 10662 struct tty_display_info *tty;
10619 int new_meta; 10663 int new_meta;
10620 10664
10621 if (t == NULL || (t->type != output_termcap && t->type != output_msdos_raw)) 10665 if (!t)
10622 return Qnil; 10666 return Qnil;
10623 tty = t->display_info.tty; 10667 tty = t->display_info.tty;
10624 10668
@@ -10655,9 +10699,10 @@ process.
10655See also `current-input-mode'. */) 10699See also `current-input-mode'. */)
10656 (Lisp_Object quit) 10700 (Lisp_Object quit)
10657{ 10701{
10658 struct terminal *t = get_named_tty ("/dev/tty"); 10702 struct terminal *t = get_named_terminal ("/dev/tty");
10659 struct tty_display_info *tty; 10703 struct tty_display_info *tty;
10660 if (t == NULL || (t->type != output_termcap && t->type != output_msdos_raw)) 10704
10705 if (!t)
10661 return Qnil; 10706 return Qnil;
10662 tty = t->display_info.tty; 10707 tty = t->display_info.tty;
10663 10708
@@ -11000,6 +11045,15 @@ syms_of_keyboard (void)
11000 Vlispy_mouse_stem = build_pure_c_string ("mouse"); 11045 Vlispy_mouse_stem = build_pure_c_string ("mouse");
11001 staticpro (&Vlispy_mouse_stem); 11046 staticpro (&Vlispy_mouse_stem);
11002 11047
11048 regular_top_level_message = build_pure_c_string ("Back to top level");
11049#ifdef HAVE_STACK_OVERFLOW_HANDLING
11050 recover_top_level_message
11051 = build_pure_c_string ("Re-entering top level after C stack overflow");
11052#endif
11053 DEFVAR_LISP ("internal--top-level-message", Vinternal__top_level_message,
11054 doc: /* Message displayed by `normal-top-level'. */);
11055 Vinternal__top_level_message = regular_top_level_message;
11056
11003 /* Tool-bars. */ 11057 /* Tool-bars. */
11004 DEFSYM (QCimage, ":image"); 11058 DEFSYM (QCimage, ":image");
11005 DEFSYM (Qhelp_echo, "help-echo"); 11059 DEFSYM (Qhelp_echo, "help-echo");
diff --git a/src/keymap.c b/src/keymap.c
index f4dd644aebd..c7c7d196c22 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1299,11 +1299,8 @@ define_as_prefix (Lisp_Object keymap, Lisp_Object c)
1299static Lisp_Object 1299static Lisp_Object
1300append_key (Lisp_Object key_sequence, Lisp_Object key) 1300append_key (Lisp_Object key_sequence, Lisp_Object key)
1301{ 1301{
1302 Lisp_Object args[2]; 1302 AUTO_LIST1 (key_list, key);
1303 1303 return Fvconcat (2, ((Lisp_Object []) { key_sequence, key_list }));
1304 args[0] = key_sequence;
1305 args[1] = list1 (key);
1306 return Fvconcat (2, args);
1307} 1304}
1308 1305
1309/* Given a event type C which is a symbol, 1306/* Given a event type C which is a symbol,
@@ -1342,7 +1339,8 @@ silly_event_symbol_error (Lisp_Object c)
1342 *p = 0; 1339 *p = 0;
1343 1340
1344 c = reorder_modifiers (c); 1341 c = reorder_modifiers (c);
1345 keystring = concat2 (build_string (new_mods), XCDR (assoc)); 1342 AUTO_STRING (new_mods_string, new_mods);
1343 keystring = concat2 (new_mods_string, XCDR (assoc));
1346 1344
1347 error ("To bind the key %s, use [?%s], not [%s]", 1345 error ("To bind the key %s, use [?%s], not [%s]",
1348 SDATA (SYMBOL_NAME (c)), SDATA (keystring), 1346 SDATA (SYMBOL_NAME (c)), SDATA (keystring),
@@ -2239,14 +2237,19 @@ Optional argument NO-ANGLES non-nil means don't put angle brackets
2239around function keys and event symbols. */) 2237around function keys and event symbols. */)
2240 (Lisp_Object key, Lisp_Object no_angles) 2238 (Lisp_Object key, Lisp_Object no_angles)
2241{ 2239{
2240 USE_SAFE_ALLOCA;
2241
2242 if (CONSP (key) && lucid_event_type_list_p (key)) 2242 if (CONSP (key) && lucid_event_type_list_p (key))
2243 key = Fevent_convert_list (key); 2243 key = Fevent_convert_list (key);
2244 2244
2245 if (CONSP (key) && INTEGERP (XCAR (key)) && INTEGERP (XCDR (key))) 2245 if (CONSP (key) && INTEGERP (XCAR (key)) && INTEGERP (XCDR (key)))
2246 /* An interval from a map-char-table. */ 2246 /* An interval from a map-char-table. */
2247 return concat3 (Fsingle_key_description (XCAR (key), no_angles), 2247 {
2248 build_string (".."), 2248 AUTO_STRING (dot_dot, "..");
2249 Fsingle_key_description (XCDR (key), no_angles)); 2249 return concat3 (Fsingle_key_description (XCAR (key), no_angles),
2250 dot_dot,
2251 Fsingle_key_description (XCDR (key), no_angles));
2252 }
2250 2253
2251 key = EVENT_HEAD (key); 2254 key = EVENT_HEAD (key);
2252 2255
@@ -2262,7 +2265,6 @@ around function keys and event symbols. */)
2262 if (NILP (no_angles)) 2265 if (NILP (no_angles))
2263 { 2266 {
2264 Lisp_Object result; 2267 Lisp_Object result;
2265 USE_SAFE_ALLOCA;
2266 char *buffer = SAFE_ALLOCA (sizeof "<>" 2268 char *buffer = SAFE_ALLOCA (sizeof "<>"
2267 + SBYTES (SYMBOL_NAME (key))); 2269 + SBYTES (SYMBOL_NAME (key)));
2268 esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); 2270 esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key)));
@@ -2883,13 +2885,14 @@ You type Translation\n\
2883 if (!SYMBOLP (modes[i])) 2885 if (!SYMBOLP (modes[i]))
2884 emacs_abort (); 2886 emacs_abort ();
2885 2887
2886 p = title = alloca (42 + SCHARS (SYMBOL_NAME (modes[i]))); 2888 USE_SAFE_ALLOCA;
2889 p = title = SAFE_ALLOCA (42 + SBYTES (SYMBOL_NAME (modes[i])));
2887 *p++ = '\f'; 2890 *p++ = '\f';
2888 *p++ = '\n'; 2891 *p++ = '\n';
2889 *p++ = '`'; 2892 *p++ = '`';
2890 memcpy (p, SDATA (SYMBOL_NAME (modes[i])), 2893 memcpy (p, SDATA (SYMBOL_NAME (modes[i])),
2891 SCHARS (SYMBOL_NAME (modes[i]))); 2894 SBYTES (SYMBOL_NAME (modes[i])));
2892 p += SCHARS (SYMBOL_NAME (modes[i])); 2895 p += SBYTES (SYMBOL_NAME (modes[i]));
2893 *p++ = '\''; 2896 *p++ = '\'';
2894 memcpy (p, " Minor Mode Bindings", strlen (" Minor Mode Bindings")); 2897 memcpy (p, " Minor Mode Bindings", strlen (" Minor Mode Bindings"));
2895 p += strlen (" Minor Mode Bindings"); 2898 p += strlen (" Minor Mode Bindings");
@@ -2898,6 +2901,7 @@ You type Translation\n\
2898 describe_map_tree (maps[i], 1, shadow, prefix, 2901 describe_map_tree (maps[i], 1, shadow, prefix,
2899 title, nomenu, 0, 0, 0); 2902 title, nomenu, 0, 0, 0);
2900 shadow = Fcons (maps[i], shadow); 2903 shadow = Fcons (maps[i], shadow);
2904 SAFE_FREE ();
2901 } 2905 }
2902 2906
2903 start1 = get_local_map (BUF_PT (XBUFFER (buffer)), 2907 start1 = get_local_map (BUF_PT (XBUFFER (buffer)),
@@ -3184,10 +3188,10 @@ describe_map (Lisp_Object map, Lisp_Object prefix,
3184 3188
3185 /* These accumulate the values from sparse keymap bindings, 3189 /* These accumulate the values from sparse keymap bindings,
3186 so we can sort them and handle them in order. */ 3190 so we can sort them and handle them in order. */
3187 int length_needed = 0; 3191 ptrdiff_t length_needed = 0;
3188 struct describe_map_elt *vect; 3192 struct describe_map_elt *vect;
3189 int slots_used = 0; 3193 ptrdiff_t slots_used = 0;
3190 int i; 3194 ptrdiff_t i;
3191 3195
3192 suppress = Qnil; 3196 suppress = Qnil;
3193 3197
@@ -3207,7 +3211,8 @@ describe_map (Lisp_Object map, Lisp_Object prefix,
3207 for (tail = map; CONSP (tail); tail = XCDR (tail)) 3211 for (tail = map; CONSP (tail); tail = XCDR (tail))
3208 length_needed++; 3212 length_needed++;
3209 3213
3210 vect = alloca (length_needed * sizeof *vect); 3214 USE_SAFE_ALLOCA;
3215 SAFE_NALLOCA (vect, 1, length_needed);
3211 3216
3212 for (tail = map; CONSP (tail); tail = XCDR (tail)) 3217 for (tail = map; CONSP (tail); tail = XCDR (tail))
3213 { 3218 {
@@ -3350,6 +3355,7 @@ describe_map (Lisp_Object map, Lisp_Object prefix,
3350 } 3355 }
3351 } 3356 }
3352 3357
3358 SAFE_FREE ();
3353 UNGCPRO; 3359 UNGCPRO;
3354} 3360}
3355 3361
@@ -3358,7 +3364,7 @@ describe_vector_princ (Lisp_Object elt, Lisp_Object fun)
3358{ 3364{
3359 Findent_to (make_number (16), make_number (1)); 3365 Findent_to (make_number (16), make_number (1));
3360 call1 (fun, elt); 3366 call1 (fun, elt);
3361 Fterpri (Qnil); 3367 Fterpri (Qnil, Qnil);
3362} 3368}
3363 3369
3364DEFUN ("describe-vector", Fdescribe_vector, Sdescribe_vector, 1, 2, 0, 3370DEFUN ("describe-vector", Fdescribe_vector, Sdescribe_vector, 1, 2, 0,
@@ -3438,9 +3444,9 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
3438 /* Call Fkey_description first, to avoid GC bug for the other string. */ 3444 /* Call Fkey_description first, to avoid GC bug for the other string. */
3439 if (!NILP (prefix) && XFASTINT (Flength (prefix)) > 0) 3445 if (!NILP (prefix) && XFASTINT (Flength (prefix)) > 0)
3440 { 3446 {
3441 Lisp_Object tem; 3447 Lisp_Object tem = Fkey_description (prefix, Qnil);
3442 tem = Fkey_description (prefix, Qnil); 3448 AUTO_STRING (space, " ");
3443 elt_prefix = concat2 (tem, build_string (" ")); 3449 elt_prefix = concat2 (tem, space);
3444 } 3450 }
3445 prefix = Qnil; 3451 prefix = Qnil;
3446 } 3452 }
diff --git a/src/lastfile.c b/src/lastfile.c
index a900e9541c8..84b28b0311b 100644
--- a/src/lastfile.c
+++ b/src/lastfile.c
@@ -36,6 +36,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
36 36
37#include <config.h> 37#include <config.h>
38 38
39#include "lisp.h"
40
39char my_edata[] = "End of Emacs initialized data"; 41char my_edata[] = "End of Emacs initialized data";
40 42
41/* Help unexec locate the end of the .bss area used by Emacs (which 43/* Help unexec locate the end of the .bss area used by Emacs (which
diff --git a/src/lisp.h b/src/lisp.h
index 67299706c6b..89f29ea268b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -36,31 +36,15 @@ INLINE_HEADER_BEGIN
36 36
37/* Define a TYPE constant ID as an externally visible name. Use like this: 37/* Define a TYPE constant ID as an externally visible name. Use like this:
38 38
39 #define ID_val (some integer preprocessor expression)
40 #if ENUMABLE (ID_val)
41 DEFINE_GDB_SYMBOL_ENUM (ID)
42 #else
43 DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID) 39 DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID)
44 # define ID ID_val 40 # define ID (some integer preprocessor expression of type TYPE)
45 DEFINE_GDB_SYMBOL_END (ID) 41 DEFINE_GDB_SYMBOL_END (ID)
46 #endif
47 42
48 This hack is for the benefit of compilers that do not make macro 43 This hack is for the benefit of compilers that do not make macro
49 definitions visible to the debugger. It's used for symbols that 44 definitions or enums visible to the debugger. It's used for symbols
50 .gdbinit needs, symbols whose values may not fit in 'int' (where an 45 that .gdbinit needs. */
51 enum would suffice).
52 46
53 Some GCC versions before GCC 4.2 omit enums in debugging output; 47#ifdef MAIN_PROGRAM
54 see GCC bug 23336. So don't use enums with older GCC. */
55
56#if !defined __GNUC__ || 4 < __GNUC__ + (2 <= __GNUC_MINOR__)
57# define ENUMABLE(val) (INT_MIN <= (val) && (val) <= INT_MAX)
58#else
59# define ENUMABLE(val) 0
60#endif
61
62#define DEFINE_GDB_SYMBOL_ENUM(id) enum { id = id##_val };
63#if defined MAIN_PROGRAM
64# define DEFINE_GDB_SYMBOL_BEGIN(type, id) type const id EXTERNALLY_VISIBLE 48# define DEFINE_GDB_SYMBOL_BEGIN(type, id) type const id EXTERNALLY_VISIBLE
65# define DEFINE_GDB_SYMBOL_END(id) = id; 49# define DEFINE_GDB_SYMBOL_END(id) = id;
66#else 50#else
@@ -88,7 +72,8 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
88 2. We know malloc returns a multiple of 8. */ 72 2. We know malloc returns a multiple of 8. */
89#if (defined alignas \ 73#if (defined alignas \
90 && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ 74 && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \
91 || defined DARWIN_OS || defined __sun || defined __MINGW32__)) 75 || defined DARWIN_OS || defined __sun || defined __MINGW32__ \
76 || defined CYGWIN))
92# define NONPOINTER_BITS 0 77# define NONPOINTER_BITS 0
93#else 78#else
94# define NONPOINTER_BITS GCTYPEBITS 79# define NONPOINTER_BITS GCTYPEBITS
@@ -297,6 +282,11 @@ error !;
297# endif 282# endif
298#endif 283#endif
299 284
285#ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED
286# define GCALIGNED __attribute__ ((aligned (GCALIGNMENT)))
287#else
288# define GCALIGNED /* empty */
289#endif
300 290
301/* Some operations are so commonly executed that they are implemented 291/* Some operations are so commonly executed that they are implemented
302 as macros, not functions, because otherwise runtime performance would 292 as macros, not functions, because otherwise runtime performance would
@@ -590,25 +580,15 @@ LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i))
590 580
591/* In the size word of a vector, this bit means the vector has been marked. */ 581/* In the size word of a vector, this bit means the vector has been marked. */
592 582
593#define ARRAY_MARK_FLAG_val PTRDIFF_MIN
594#if ENUMABLE (ARRAY_MARK_FLAG_val)
595DEFINE_GDB_SYMBOL_ENUM (ARRAY_MARK_FLAG)
596#else
597DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG) 583DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
598# define ARRAY_MARK_FLAG ARRAY_MARK_FLAG_val 584# define ARRAY_MARK_FLAG PTRDIFF_MIN
599DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG) 585DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
600#endif
601 586
602/* In the size word of a struct Lisp_Vector, this bit means it's really 587/* In the size word of a struct Lisp_Vector, this bit means it's really
603 some other vector-like object. */ 588 some other vector-like object. */
604#define PSEUDOVECTOR_FLAG_val (PTRDIFF_MAX - PTRDIFF_MAX / 2)
605#if ENUMABLE (PSEUDOVECTOR_FLAG_val)
606DEFINE_GDB_SYMBOL_ENUM (PSEUDOVECTOR_FLAG)
607#else
608DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG) 589DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
609# define PSEUDOVECTOR_FLAG PSEUDOVECTOR_FLAG_val 590# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
610DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG) 591DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
611#endif
612 592
613/* In a pseudovector, the size field actually contains a word with one 593/* In a pseudovector, the size field actually contains a word with one
614 PSEUDOVECTOR_FLAG bit set, and one of the following values extracted 594 PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
@@ -661,14 +641,9 @@ enum More_Lisp_Bits
661 that cons. */ 641 that cons. */
662 642
663/* Mask for the value (as opposed to the type bits) of a Lisp object. */ 643/* Mask for the value (as opposed to the type bits) of a Lisp object. */
664#define VALMASK_val (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
665#if ENUMABLE (VALMASK_val)
666DEFINE_GDB_SYMBOL_ENUM (VALMASK)
667#else
668DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK) 644DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
669# define VALMASK VALMASK_val 645# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
670DEFINE_GDB_SYMBOL_END (VALMASK) 646DEFINE_GDB_SYMBOL_END (VALMASK)
671#endif
672 647
673/* Largest and smallest representable fixnum values. These are the C 648/* Largest and smallest representable fixnum values. These are the C
674 values. They are macros for use in static initializers. */ 649 values. They are macros for use in static initializers. */
@@ -1015,7 +990,7 @@ LISP_MACRO_DEFUN_VOID (CHECK_TYPE,
1015 990
1016typedef struct interval *INTERVAL; 991typedef struct interval *INTERVAL;
1017 992
1018struct Lisp_Cons 993struct GCALIGNED Lisp_Cons
1019 { 994 {
1020 /* Car of this cons cell. */ 995 /* Car of this cons cell. */
1021 Lisp_Object car; 996 Lisp_Object car;
@@ -1097,7 +1072,7 @@ CDR_SAFE (Lisp_Object c)
1097 1072
1098/* In a string or vector, the sign bit of the `size' is the gc mark bit. */ 1073/* In a string or vector, the sign bit of the `size' is the gc mark bit. */
1099 1074
1100struct Lisp_String 1075struct GCALIGNED Lisp_String
1101 { 1076 {
1102 ptrdiff_t size; 1077 ptrdiff_t size;
1103 ptrdiff_t size_byte; 1078 ptrdiff_t size_byte;
@@ -3036,6 +3011,16 @@ struct gcpro
3036 ptrdiff_t nvars; 3011 ptrdiff_t nvars;
3037 3012
3038#ifdef DEBUG_GCPRO 3013#ifdef DEBUG_GCPRO
3014 /* File name where this record is used. */
3015 const char *name;
3016
3017 /* Line number in this file. */
3018 int lineno;
3019
3020 /* Index in the local chain of records. */
3021 int idx;
3022
3023 /* Nesting level. */
3039 int level; 3024 int level;
3040#endif 3025#endif
3041}; 3026};
@@ -3091,122 +3076,150 @@ struct gcpro
3091 3076
3092#ifndef DEBUG_GCPRO 3077#ifndef DEBUG_GCPRO
3093 3078
3094#define GCPRO1(varname) \ 3079#define GCPRO1(a) \
3095 {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \ 3080 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3096 gcprolist = &gcpro1; } 3081 gcprolist = &gcpro1; }
3097 3082
3098#define GCPRO2(varname1, varname2) \ 3083#define GCPRO2(a, b) \
3099 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3084 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3100 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3085 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3101 gcprolist = &gcpro2; } 3086 gcprolist = &gcpro2; }
3087
3088#define GCPRO3(a, b, c) \
3089 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3090 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3091 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3092 gcprolist = &gcpro3; }
3093
3094#define GCPRO4(a, b, c, d) \
3095 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3096 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3097 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3098 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3099 gcprolist = &gcpro4; }
3100
3101#define GCPRO5(a, b, c, d, e) \
3102 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3103 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3104 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3105 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3106 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \
3107 gcprolist = &gcpro5; }
3108
3109#define GCPRO6(a, b, c, d, e, f) \
3110 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3111 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3112 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3113 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3114 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \
3115 gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \
3116 gcprolist = &gcpro6; }
3102 3117
3103#define GCPRO3(varname1, varname2, varname3) \ 3118#define GCPRO7(a, b, c, d, e, f, g) \
3104 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3119 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3105 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3120 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3106 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ 3121 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3107 gcprolist = &gcpro3; } 3122 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3108 3123 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \
3109#define GCPRO4(varname1, varname2, varname3, varname4) \ 3124 gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \
3110 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3125 gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \
3111 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3126 gcprolist = &gcpro7; }
3112 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \
3113 gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \
3114 gcprolist = &gcpro4; }
3115
3116#define GCPRO5(varname1, varname2, varname3, varname4, varname5) \
3117 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \
3118 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \
3119 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \
3120 gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \
3121 gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \
3122 gcprolist = &gcpro5; }
3123
3124#define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \
3125 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \
3126 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \
3127 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \
3128 gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \
3129 gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \
3130 gcpro6.next = &gcpro5; gcpro6.var = &varname6; gcpro6.nvars = 1; \
3131 gcprolist = &gcpro6; }
3132
3133#define GCPRO7(a, b, c, d, e, f, g) \
3134 {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3135 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3136 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3137 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3138 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \
3139 gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \
3140 gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \
3141 gcprolist = &gcpro7; }
3142 3127
3143#define UNGCPRO (gcprolist = gcpro1.next) 3128#define UNGCPRO (gcprolist = gcpro1.next)
3144 3129
3145#else 3130#else /* !DEBUG_GCPRO */
3146 3131
3147extern int gcpro_level; 3132extern int gcpro_level;
3148 3133
3149#define GCPRO1(varname) \ 3134#define GCPRO1(a) \
3150 {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \ 3135 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3151 gcpro1.level = gcpro_level++; \ 3136 gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \
3152 gcprolist = &gcpro1; } 3137 gcpro1.level = gcpro_level++; \
3153 3138 gcprolist = &gcpro1; }
3154#define GCPRO2(varname1, varname2) \ 3139
3155 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3140#define GCPRO2(a, b) \
3156 gcpro1.level = gcpro_level; \ 3141 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3157 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3142 gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \
3158 gcpro2.level = gcpro_level++; \ 3143 gcpro1.level = gcpro_level; \
3159 gcprolist = &gcpro2; } 3144 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3160 3145 gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \
3161#define GCPRO3(varname1, varname2, varname3) \ 3146 gcpro2.level = gcpro_level++; \
3162 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3147 gcprolist = &gcpro2; }
3163 gcpro1.level = gcpro_level; \ 3148
3164 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3149#define GCPRO3(a, b, c) \
3165 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ 3150 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3166 gcpro3.level = gcpro_level++; \ 3151 gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \
3167 gcprolist = &gcpro3; } 3152 gcpro1.level = gcpro_level; \
3168 3153 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3169#define GCPRO4(varname1, varname2, varname3, varname4) \ 3154 gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \
3170 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3155 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3171 gcpro1.level = gcpro_level; \ 3156 gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \
3172 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3157 gcpro3.level = gcpro_level++; \
3173 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ 3158 gcprolist = &gcpro3; }
3174 gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ 3159
3175 gcpro4.level = gcpro_level++; \ 3160#define GCPRO4(a, b, c, d) \
3176 gcprolist = &gcpro4; } 3161 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3177 3162 gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \
3178#define GCPRO5(varname1, varname2, varname3, varname4, varname5) \ 3163 gcpro1.level = gcpro_level; \
3179 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3164 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3180 gcpro1.level = gcpro_level; \ 3165 gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \
3181 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3166 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3182 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ 3167 gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \
3183 gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ 3168 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3184 gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ 3169 gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \
3185 gcpro5.level = gcpro_level++; \ 3170 gcpro4.level = gcpro_level++; \
3186 gcprolist = &gcpro5; } 3171 gcprolist = &gcpro4; }
3187 3172
3188#define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \ 3173#define GCPRO5(a, b, c, d, e) \
3189 {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ 3174 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3190 gcpro1.level = gcpro_level; \ 3175 gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \
3191 gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ 3176 gcpro1.level = gcpro_level; \
3192 gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ 3177 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3193 gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ 3178 gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \
3194 gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ 3179 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3195 gcpro6.next = &gcpro5; gcpro6.var = &varname6; gcpro6.nvars = 1; \ 3180 gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \
3196 gcpro6.level = gcpro_level++; \ 3181 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3197 gcprolist = &gcpro6; } 3182 gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \
3183 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \
3184 gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \
3185 gcpro5.level = gcpro_level++; \
3186 gcprolist = &gcpro5; }
3187
3188#define GCPRO6(a, b, c, d, e, f) \
3189 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3190 gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \
3191 gcpro1.level = gcpro_level; \
3192 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3193 gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \
3194 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3195 gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \
3196 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3197 gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \
3198 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \
3199 gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \
3200 gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \
3201 gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6; \
3202 gcpro6.level = gcpro_level++; \
3203 gcprolist = &gcpro6; }
3198 3204
3199#define GCPRO7(a, b, c, d, e, f, g) \ 3205#define GCPRO7(a, b, c, d, e, f, g) \
3200 {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ 3206 { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \
3201 gcpro1.level = gcpro_level; \ 3207 gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \
3202 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ 3208 gcpro1.level = gcpro_level; \
3203 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ 3209 gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \
3204 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ 3210 gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \
3205 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ 3211 gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \
3206 gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ 3212 gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \
3207 gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ 3213 gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \
3208 gcpro7.level = gcpro_level++; \ 3214 gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \
3209 gcprolist = &gcpro7; } 3215 gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \
3216 gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \
3217 gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \
3218 gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6; \
3219 gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \
3220 gcpro7.name = __FILE__; gcpro7.lineno = __LINE__; gcpro7.idx = 7; \
3221 gcpro7.level = gcpro_level++; \
3222 gcprolist = &gcpro7; }
3210 3223
3211#define UNGCPRO \ 3224#define UNGCPRO \
3212 (--gcpro_level != gcpro1.level \ 3225 (--gcpro_level != gcpro1.level \
@@ -3620,6 +3633,10 @@ extern void syms_of_xsettings (void);
3620/* Defined in vm-limit.c. */ 3633/* Defined in vm-limit.c. */
3621extern void memory_warnings (void *, void (*warnfun) (const char *)); 3634extern void memory_warnings (void *, void (*warnfun) (const char *));
3622 3635
3636/* Defined in character.c. */
3637extern void parse_str_as_multibyte (const unsigned char *, ptrdiff_t,
3638 ptrdiff_t *, ptrdiff_t *);
3639
3623/* Defined in alloc.c. */ 3640/* Defined in alloc.c. */
3624extern void check_pure_size (void); 3641extern void check_pure_size (void);
3625extern void free_misc (Lisp_Object); 3642extern void free_misc (Lisp_Object);
@@ -3629,7 +3646,7 @@ extern _Noreturn void memory_full (size_t);
3629extern _Noreturn void buffer_memory_full (ptrdiff_t); 3646extern _Noreturn void buffer_memory_full (ptrdiff_t);
3630extern bool survives_gc_p (Lisp_Object); 3647extern bool survives_gc_p (Lisp_Object);
3631extern void mark_object (Lisp_Object); 3648extern void mark_object (Lisp_Object);
3632#if defined REL_ALLOC && !defined SYSTEM_MALLOC 3649#if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
3633extern void refill_memory_reserve (void); 3650extern void refill_memory_reserve (void);
3634#endif 3651#endif
3635extern const char *pending_malloc_warning; 3652extern const char *pending_malloc_warning;
@@ -3852,6 +3869,7 @@ extern Lisp_Object Qlexical_binding;
3852extern Lisp_Object check_obarray (Lisp_Object); 3869extern Lisp_Object check_obarray (Lisp_Object);
3853extern Lisp_Object intern_1 (const char *, ptrdiff_t); 3870extern Lisp_Object intern_1 (const char *, ptrdiff_t);
3854extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); 3871extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t);
3872extern Lisp_Object intern_driver (Lisp_Object, Lisp_Object, ptrdiff_t);
3855extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); 3873extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t);
3856INLINE void 3874INLINE void
3857LOADHIST_ATTACH (Lisp_Object x) 3875LOADHIST_ATTACH (Lisp_Object x)
@@ -3882,6 +3900,7 @@ intern_c_string (const char *str)
3882} 3900}
3883 3901
3884/* Defined in eval.c. */ 3902/* Defined in eval.c. */
3903extern EMACS_INT lisp_eval_depth;
3885extern Lisp_Object Qexit, Qinteractive, Qcommandp, Qmacro; 3904extern Lisp_Object Qexit, Qinteractive, Qcommandp, Qmacro;
3886extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure; 3905extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure;
3887extern Lisp_Object Qand_rest; 3906extern Lisp_Object Qand_rest;
@@ -3949,8 +3968,7 @@ extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
3949extern void init_eval (void); 3968extern void init_eval (void);
3950extern void syms_of_eval (void); 3969extern void syms_of_eval (void);
3951extern void unwind_body (Lisp_Object); 3970extern void unwind_body (Lisp_Object);
3952extern void record_in_backtrace (Lisp_Object function, 3971extern ptrdiff_t record_in_backtrace (Lisp_Object, Lisp_Object *, ptrdiff_t);
3953 Lisp_Object *args, ptrdiff_t nargs);
3954extern void mark_specpdl (void); 3972extern void mark_specpdl (void);
3955extern void get_backtrace (Lisp_Object array); 3973extern void get_backtrace (Lisp_Object array);
3956Lisp_Object backtrace_top_function (void); 3974Lisp_Object backtrace_top_function (void);
@@ -3972,7 +3990,6 @@ extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
3972 ptrdiff_t, bool); 3990 ptrdiff_t, bool);
3973extern void init_editfns (void); 3991extern void init_editfns (void);
3974extern void syms_of_editfns (void); 3992extern void syms_of_editfns (void);
3975extern void set_time_zone_rule (const char *);
3976 3993
3977/* Defined in buffer.c. */ 3994/* Defined in buffer.c. */
3978extern bool mouse_face_overlay_overlaps (Lisp_Object); 3995extern bool mouse_face_overlay_overlaps (Lisp_Object);
@@ -4025,7 +4042,7 @@ extern _Noreturn void report_file_error (const char *, Lisp_Object);
4025extern bool internal_delete_file (Lisp_Object); 4042extern bool internal_delete_file (Lisp_Object);
4026extern Lisp_Object emacs_readlinkat (int, const char *); 4043extern Lisp_Object emacs_readlinkat (int, const char *);
4027extern bool file_directory_p (const char *); 4044extern bool file_directory_p (const char *);
4028extern bool file_accessible_directory_p (const char *); 4045extern bool file_accessible_directory_p (Lisp_Object);
4029extern void init_fileio (void); 4046extern void init_fileio (void);
4030extern void syms_of_fileio (void); 4047extern void syms_of_fileio (void);
4031extern Lisp_Object make_temp_name (Lisp_Object, bool); 4048extern Lisp_Object make_temp_name (Lisp_Object, bool);
@@ -4093,6 +4110,9 @@ extern Lisp_Object Qdisabled, QCfilter;
4093extern Lisp_Object Qup, Qdown; 4110extern Lisp_Object Qup, Qdown;
4094extern Lisp_Object last_undo_boundary; 4111extern Lisp_Object last_undo_boundary;
4095extern bool input_pending; 4112extern bool input_pending;
4113#ifdef HAVE_STACK_OVERFLOW_HANDLING
4114extern sigjmp_buf return_to_command_loop;
4115#endif
4096extern Lisp_Object menu_bar_items (Lisp_Object); 4116extern Lisp_Object menu_bar_items (Lisp_Object);
4097extern Lisp_Object tool_bar_items (Lisp_Object, int *); 4117extern Lisp_Object tool_bar_items (Lisp_Object, int *);
4098extern void discard_mouse_events (void); 4118extern void discard_mouse_events (void);
@@ -4295,6 +4315,7 @@ extern void lock_file (Lisp_Object);
4295extern void unlock_file (Lisp_Object); 4315extern void unlock_file (Lisp_Object);
4296extern void unlock_buffer (struct buffer *); 4316extern void unlock_buffer (struct buffer *);
4297extern void syms_of_filelock (void); 4317extern void syms_of_filelock (void);
4318extern int str_collate (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
4298 4319
4299/* Defined in sound.c. */ 4320/* Defined in sound.c. */
4300extern void syms_of_sound (void); 4321extern void syms_of_sound (void);
@@ -4376,6 +4397,7 @@ extern void syms_of_xsmfns (void);
4376extern void syms_of_xselect (void); 4397extern void syms_of_xselect (void);
4377 4398
4378/* Defined in xterm.c. */ 4399/* Defined in xterm.c. */
4400extern void init_xterm (void);
4379extern void syms_of_xterm (void); 4401extern void syms_of_xterm (void);
4380#endif /* HAVE_X_WINDOWS */ 4402#endif /* HAVE_X_WINDOWS */
4381 4403
@@ -4397,6 +4419,7 @@ extern void syms_of_decompress (void);
4397 4419
4398#ifdef HAVE_DBUS 4420#ifdef HAVE_DBUS
4399/* Defined in dbusbind.c. */ 4421/* Defined in dbusbind.c. */
4422void init_dbusbind (void);
4400void syms_of_dbusbind (void); 4423void syms_of_dbusbind (void);
4401#endif 4424#endif
4402 4425
@@ -4412,6 +4435,11 @@ extern void syms_of_profiler (void);
4412extern char *emacs_root_dir (void); 4435extern char *emacs_root_dir (void);
4413#endif /* DOS_NT */ 4436#endif /* DOS_NT */
4414 4437
4438/* Defined in lastfile.c. */
4439extern char my_edata[];
4440extern char my_endbss[];
4441extern char *my_endbss_static;
4442
4415/* True means ^G can quit instantly. */ 4443/* True means ^G can quit instantly. */
4416extern bool immediate_quit; 4444extern bool immediate_quit;
4417 4445
@@ -4427,15 +4455,28 @@ extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
4427extern char *xstrdup (const char *) ATTRIBUTE_MALLOC; 4455extern char *xstrdup (const char *) ATTRIBUTE_MALLOC;
4428extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC; 4456extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC;
4429extern void dupstring (char **, char const *); 4457extern void dupstring (char **, char const *);
4430extern void xputenv (const char *);
4431 4458
4432extern char *egetenv (const char *); 4459/* Make DEST a copy of STRING's data. Return a pointer to DEST's terminating
4460 null byte. This is like stpcpy, except the source is a Lisp string. */
4461
4462INLINE char *
4463lispstpcpy (char *dest, Lisp_Object string)
4464{
4465 ptrdiff_t len = SBYTES (string);
4466 memcpy (dest, SDATA (string), len + 1);
4467 return dest + len;
4468}
4469
4470extern void xputenv (const char *);
4433 4471
4434/* Copy Lisp string to temporary (allocated on stack) C string. */ 4472extern char *egetenv_internal (const char *, ptrdiff_t);
4435 4473
4436#define xlispstrdupa(string) \ 4474INLINE char *
4437 memcpy (alloca (SBYTES (string) + 1), \ 4475egetenv (const char *var)
4438 SSDATA (string), SBYTES (string) + 1) 4476{
4477 /* When VAR is a string literal, strlen can be optimized away. */
4478 return egetenv_internal (var, strlen (var));
4479}
4439 4480
4440/* Set up the name of the machine we're running on. */ 4481/* Set up the name of the machine we're running on. */
4441extern void init_system_name (void); 4482extern void init_system_name (void);
@@ -4460,12 +4501,15 @@ enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 };
4460extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); 4501extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4461 4502
4462#define USE_SAFE_ALLOCA \ 4503#define USE_SAFE_ALLOCA \
4504 ptrdiff_t sa_avail = MAX_ALLOCA; \
4463 ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false 4505 ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
4464 4506
4507#define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size))
4508
4465/* SAFE_ALLOCA allocates a simple buffer. */ 4509/* SAFE_ALLOCA allocates a simple buffer. */
4466 4510
4467#define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \ 4511#define SAFE_ALLOCA(size) ((size) <= sa_avail \
4468 ? alloca (size) \ 4512 ? AVAIL_ALLOCA (size) \
4469 : (sa_must_free = true, record_xmalloc (size))) 4513 : (sa_must_free = true, record_xmalloc (size)))
4470 4514
4471/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * 4515/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
@@ -4474,8 +4518,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4474 4518
4475#define SAFE_NALLOCA(buf, multiplier, nitems) \ 4519#define SAFE_NALLOCA(buf, multiplier, nitems) \
4476 do { \ 4520 do { \
4477 if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ 4521 if ((nitems) <= sa_avail / sizeof *(buf) / (multiplier)) \
4478 (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ 4522 (buf) = AVAIL_ALLOCA (sizeof *(buf) * (multiplier) * (nitems)); \
4479 else \ 4523 else \
4480 { \ 4524 { \
4481 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ 4525 (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
@@ -4484,6 +4528,14 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4484 } \ 4528 } \
4485 } while (false) 4529 } while (false)
4486 4530
4531/* SAFE_ALLOCA_STRING allocates a C copy of a Lisp string. */
4532
4533#define SAFE_ALLOCA_STRING(ptr, string) \
4534 do { \
4535 (ptr) = SAFE_ALLOCA (SBYTES (string) + 1); \
4536 memcpy (ptr, SDATA (string), SBYTES (string) + 1); \
4537 } while (false)
4538
4487/* SAFE_FREE frees xmalloced memory and enables GC as needed. */ 4539/* SAFE_FREE frees xmalloced memory and enables GC as needed. */
4488 4540
4489#define SAFE_FREE() \ 4541#define SAFE_FREE() \
@@ -4495,13 +4547,29 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4495 } while (false) 4547 } while (false)
4496 4548
4497 4549
4550/* Return floor (NBYTES / WORD_SIZE). */
4551
4552INLINE ptrdiff_t
4553lisp_word_count (ptrdiff_t nbytes)
4554{
4555 if (-1 >> 1 == -1)
4556 switch (word_size)
4557 {
4558 case 2: return nbytes >> 1;
4559 case 4: return nbytes >> 2;
4560 case 8: return nbytes >> 3;
4561 case 16: return nbytes >> 4;
4562 }
4563 return nbytes / word_size - (nbytes % word_size < 0);
4564}
4565
4498/* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ 4566/* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */
4499 4567
4500#define SAFE_ALLOCA_LISP(buf, nelt) \ 4568#define SAFE_ALLOCA_LISP(buf, nelt) \
4501 do { \ 4569 do { \
4502 if ((nelt) < MAX_ALLOCA / word_size) \ 4570 if ((nelt) <= lisp_word_count (sa_avail)) \
4503 (buf) = alloca ((nelt) * word_size); \ 4571 (buf) = AVAIL_ALLOCA ((nelt) * word_size); \
4504 else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ 4572 else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
4505 { \ 4573 { \
4506 Lisp_Object arg_; \ 4574 Lisp_Object arg_; \
4507 (buf) = xmalloc ((nelt) * word_size); \ 4575 (buf) = xmalloc ((nelt) * word_size); \
@@ -4513,6 +4581,107 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
4513 memory_full (SIZE_MAX); \ 4581 memory_full (SIZE_MAX); \
4514 } while (false) 4582 } while (false)
4515 4583
4584
4585/* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate
4586 block-scoped conses and strings. These objects are not
4587 managed by the garbage collector, so they are dangerous: passing them
4588 out of their scope (e.g., to user code) results in undefined behavior.
4589 Conversely, they have better performance because GC is not involved.
4590
4591 This feature is experimental and requires careful debugging.
4592 Build with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=0' to disable it. */
4593
4594#ifndef USE_STACK_LISP_OBJECTS
4595# define USE_STACK_LISP_OBJECTS true
4596#endif
4597
4598/* USE_STACK_LISP_OBJECTS requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS. */
4599
4600#if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS
4601# undef USE_STACK_LISP_OBJECTS
4602# define USE_STACK_LISP_OBJECTS false
4603#endif
4604
4605/* Struct inside unions that are typically no larger and aligned enough. */
4606
4607union Aligned_Cons
4608{
4609 struct Lisp_Cons s;
4610 double d; intmax_t i; void *p;
4611};
4612
4613union Aligned_String
4614{
4615 struct Lisp_String s;
4616 double d; intmax_t i; void *p;
4617};
4618
4619/* True for stack-based cons and string implementations, respectively.
4620 Use stack-based strings only if stack-based cons also works.
4621 Otherwise, STACK_CONS would create heap-based cons cells that
4622 could point to stack-based strings, which is a no-no. */
4623
4624enum
4625 {
4626 USE_STACK_CONS = (USE_STACK_LISP_OBJECTS
4627 && alignof (union Aligned_Cons) % GCALIGNMENT == 0),
4628 USE_STACK_STRING = (USE_STACK_CONS
4629 && alignof (union Aligned_String) % GCALIGNMENT == 0)
4630 };
4631
4632/* Auxiliary macros used for auto allocation of Lisp objects. Please
4633 use these only in macros like AUTO_CONS that declare a local
4634 variable whose lifetime will be clear to the programmer. */
4635#define STACK_CONS(a, b) \
4636 make_lisp_ptr (&(union Aligned_Cons) { { a, { b } } }.s, Lisp_Cons)
4637#define AUTO_CONS_EXPR(a, b) \
4638 (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b))
4639
4640/* Declare NAME as an auto Lisp cons or short list if possible, a
4641 GC-based one otherwise. This is in the sense of the C keyword
4642 'auto'; i.e., the object has the lifetime of the containing block.
4643 The resulting object should not be made visible to user Lisp code. */
4644
4645#define AUTO_CONS(name, a, b) Lisp_Object name = AUTO_CONS_EXPR (a, b)
4646#define AUTO_LIST1(name, a) \
4647 Lisp_Object name = (USE_STACK_CONS ? STACK_CONS (a, Qnil) : list1 (a))
4648#define AUTO_LIST2(name, a, b) \
4649 Lisp_Object name = (USE_STACK_CONS \
4650 ? STACK_CONS (a, STACK_CONS (b, Qnil)) \
4651 : list2 (a, b))
4652#define AUTO_LIST3(name, a, b, c) \
4653 Lisp_Object name = (USE_STACK_CONS \
4654 ? STACK_CONS (a, STACK_CONS (b, STACK_CONS (c, Qnil))) \
4655 : list3 (a, b, c))
4656#define AUTO_LIST4(name, a, b, c, d) \
4657 Lisp_Object name \
4658 = (USE_STACK_CONS \
4659 ? STACK_CONS (a, STACK_CONS (b, STACK_CONS (c, \
4660 STACK_CONS (d, Qnil)))) \
4661 : list4 (a, b, c, d))
4662
4663/* Check whether stack-allocated strings are ASCII-only. */
4664
4665#if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS
4666extern const char *verify_ascii (const char *);
4667#else
4668# define verify_ascii(str) (str)
4669#endif
4670
4671/* Declare NAME as an auto Lisp string if possible, a GC-based one if not.
4672 Take its value from STR. STR is not necessarily copied and should
4673 contain only ASCII characters. The resulting Lisp string should
4674 not be modified or made visible to user code. */
4675
4676#define AUTO_STRING(name, str) \
4677 Lisp_Object name = \
4678 (USE_STACK_STRING \
4679 ? (make_lisp_ptr \
4680 ((&(union Aligned_String) \
4681 {{strlen (str), -1, 0, (unsigned char *) verify_ascii (str)}}.s), \
4682 Lisp_String)) \
4683 : build_string (verify_ascii (str)))
4684
4516/* Loop over all tails of a list, checking for cycles. 4685/* Loop over all tails of a list, checking for cycles.
4517 FIXME: Make tortoise and n internal declarations. 4686 FIXME: Make tortoise and n internal declarations.
4518 FIXME: Unroll the loop body so we don't need `n'. */ 4687 FIXME: Unroll the loop body so we don't need `n'. */
diff --git a/src/lisp.mk b/src/lisp.mk
index 59d5b86c33a..642e9af225f 100644
--- a/src/lisp.mk
+++ b/src/lisp.mk
@@ -132,6 +132,7 @@ lisp = \
132 $(lispsource)/textmodes/paragraphs.elc \ 132 $(lispsource)/textmodes/paragraphs.elc \
133 $(lispsource)/progmodes/prog-mode.elc \ 133 $(lispsource)/progmodes/prog-mode.elc \
134 $(lispsource)/emacs-lisp/lisp-mode.elc \ 134 $(lispsource)/emacs-lisp/lisp-mode.elc \
135 $(lispsource)/progmodes/elisp-mode.elc \
135 $(lispsource)/textmodes/text-mode.elc \ 136 $(lispsource)/textmodes/text-mode.elc \
136 $(lispsource)/textmodes/fill.elc \ 137 $(lispsource)/textmodes/fill.elc \
137 $(lispsource)/newcomment.elc \ 138 $(lispsource)/newcomment.elc \
@@ -152,7 +153,6 @@ lisp = \
152 $(lispsource)/term/w32-win.elc \ 153 $(lispsource)/term/w32-win.elc \
153 $(lispsource)/ls-lisp.elc \ 154 $(lispsource)/ls-lisp.elc \
154 $(lispsource)/disp-table.elc \ 155 $(lispsource)/disp-table.elc \
155 $(lispsource)/w32-common-fns.elc \
156 $(lispsource)/dos-w32.elc \ 156 $(lispsource)/dos-w32.elc \
157 $(lispsource)/w32-fns.elc \ 157 $(lispsource)/w32-fns.elc \
158 $(lispsource)/dos-fns.elc \ 158 $(lispsource)/dos-fns.elc \
diff --git a/src/lread.c b/src/lread.c
index 639d574ac6b..171a51acb3f 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -970,10 +970,8 @@ load_warn_old_style_backquotes (Lisp_Object file)
970{ 970{
971 if (!NILP (Vold_style_backquotes)) 971 if (!NILP (Vold_style_backquotes))
972 { 972 {
973 Lisp_Object args[2]; 973 AUTO_STRING (format, "Loading `%s': old-style backquotes detected!");
974 args[0] = build_string ("Loading `%s': old-style backquotes detected!"); 974 Fmessage (2, (Lisp_Object []) {format, file});
975 args[1] = file;
976 Fmessage (2, args);
977 } 975 }
978} 976}
979 977
@@ -1473,6 +1471,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1473 ptrdiff_t max_suffix_len = 0; 1471 ptrdiff_t max_suffix_len = 0;
1474 int last_errno = ENOENT; 1472 int last_errno = ENOENT;
1475 int save_fd = -1; 1473 int save_fd = -1;
1474 USE_SAFE_ALLOCA;
1476 1475
1477 /* The last-modified time of the newest matching file found. 1476 /* The last-modified time of the newest matching file found.
1478 Initialize it to something less than all valid timestamps. */ 1477 Initialize it to something less than all valid timestamps. */
@@ -1513,7 +1512,10 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1513 this path element/specified file name and any possible suffix. */ 1512 this path element/specified file name and any possible suffix. */
1514 want_length = max_suffix_len + SBYTES (filename); 1513 want_length = max_suffix_len + SBYTES (filename);
1515 if (fn_size <= want_length) 1514 if (fn_size <= want_length)
1516 fn = alloca (fn_size = 100 + want_length); 1515 {
1516 fn_size = 100 + want_length;
1517 fn = SAFE_ALLOCA (fn_size);
1518 }
1517 1519
1518 /* Loop over suffixes. */ 1520 /* Loop over suffixes. */
1519 for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes; 1521 for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
@@ -1579,6 +1581,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1579 /* We succeeded; return this descriptor and filename. */ 1581 /* We succeeded; return this descriptor and filename. */
1580 if (storeptr) 1582 if (storeptr)
1581 *storeptr = string; 1583 *storeptr = string;
1584 SAFE_FREE ();
1582 UNGCPRO; 1585 UNGCPRO;
1583 return -2; 1586 return -2;
1584 } 1587 }
@@ -1651,6 +1654,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1651 /* We succeeded; return this descriptor and filename. */ 1654 /* We succeeded; return this descriptor and filename. */
1652 if (storeptr) 1655 if (storeptr)
1653 *storeptr = string; 1656 *storeptr = string;
1657 SAFE_FREE ();
1654 UNGCPRO; 1658 UNGCPRO;
1655 return fd; 1659 return fd;
1656 } 1660 }
@@ -1661,6 +1665,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1661 { 1665 {
1662 if (storeptr) 1666 if (storeptr)
1663 *storeptr = save_string; 1667 *storeptr = save_string;
1668 SAFE_FREE ();
1664 UNGCPRO; 1669 UNGCPRO;
1665 return save_fd; 1670 return save_fd;
1666 } 1671 }
@@ -1670,6 +1675,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1670 break; 1675 break;
1671 } 1676 }
1672 1677
1678 SAFE_FREE ();
1673 UNGCPRO; 1679 UNGCPRO;
1674 errno = last_errno; 1680 errno = last_errno;
1675 return -1; 1681 return -1;
@@ -1774,15 +1780,17 @@ readevalloop_eager_expand_eval (Lisp_Object val, Lisp_Object macroexpand)
1774 val = call2 (macroexpand, val, Qnil); 1780 val = call2 (macroexpand, val, Qnil);
1775 if (EQ (CAR_SAFE (val), Qprogn)) 1781 if (EQ (CAR_SAFE (val), Qprogn))
1776 { 1782 {
1783 struct gcpro gcpro1;
1777 Lisp_Object subforms = XCDR (val); 1784 Lisp_Object subforms = XCDR (val);
1778 val = Qnil; 1785
1779 for (; CONSP (subforms); subforms = XCDR (subforms)) 1786 GCPRO1 (subforms);
1787 for (val = Qnil; CONSP (subforms); subforms = XCDR (subforms))
1780 val = readevalloop_eager_expand_eval (XCAR (subforms), 1788 val = readevalloop_eager_expand_eval (XCAR (subforms),
1781 macroexpand); 1789 macroexpand);
1790 UNGCPRO;
1782 } 1791 }
1783 else 1792 else
1784 val = eval_sub (call2 (macroexpand, val, Qt)); 1793 val = eval_sub (call2 (macroexpand, val, Qt));
1785
1786 return val; 1794 return val;
1787} 1795}
1788 1796
@@ -2088,9 +2096,10 @@ DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0,
2088 doc: /* Read one Lisp expression which is represented as text by STRING. 2096 doc: /* Read one Lisp expression which is represented as text by STRING.
2089Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX). 2097Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX).
2090FINAL-STRING-INDEX is an integer giving the position of the next 2098FINAL-STRING-INDEX is an integer giving the position of the next
2091 remaining character in STRING. 2099remaining character in STRING. START and END optionally delimit
2092START and END optionally delimit a substring of STRING from which to read; 2100a substring of STRING from which to read; they default to 0 and
2093 they default to 0 and (length STRING) respectively. */) 2101(length STRING) respectively. Negative values are counted from
2102the end of STRING. */)
2094 (Lisp_Object string, Lisp_Object start, Lisp_Object end) 2103 (Lisp_Object string, Lisp_Object start, Lisp_Object end)
2095{ 2104{
2096 Lisp_Object ret; 2105 Lisp_Object ret;
@@ -2101,10 +2110,9 @@ START and END optionally delimit a substring of STRING from which to read;
2101} 2110}
2102 2111
2103/* Function to set up the global context we need in toplevel read 2112/* Function to set up the global context we need in toplevel read
2104 calls. */ 2113 calls. START and END only used when STREAM is a string. */
2105static Lisp_Object 2114static Lisp_Object
2106read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end) 2115read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end)
2107/* `start', `end' only used when stream is a string. */
2108{ 2116{
2109 Lisp_Object retval; 2117 Lisp_Object retval;
2110 2118
@@ -2126,25 +2134,9 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end)
2126 else 2134 else
2127 string = XCAR (stream); 2135 string = XCAR (stream);
2128 2136
2129 if (NILP (end)) 2137 validate_subarray (string, start, end, SCHARS (string),
2130 endval = SCHARS (string); 2138 &startval, &endval);
2131 else
2132 {
2133 CHECK_NUMBER (end);
2134 if (! (0 <= XINT (end) && XINT (end) <= SCHARS (string)))
2135 args_out_of_range (string, end);
2136 endval = XINT (end);
2137 }
2138 2139
2139 if (NILP (start))
2140 startval = 0;
2141 else
2142 {
2143 CHECK_NUMBER (start);
2144 if (! (0 <= XINT (start) && XINT (start) <= endval))
2145 args_out_of_range (string, start);
2146 startval = XINT (start);
2147 }
2148 read_from_string_index = startval; 2140 read_from_string_index = startval;
2149 read_from_string_index_byte = string_char_to_byte (string, startval); 2141 read_from_string_index_byte = string_char_to_byte (string, startval);
2150 read_from_string_limit = endval; 2142 read_from_string_limit = endval;
@@ -2881,11 +2873,8 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2881 if (c == '=') 2873 if (c == '=')
2882 { 2874 {
2883 /* Make a placeholder for #n# to use temporarily. */ 2875 /* Make a placeholder for #n# to use temporarily. */
2884 Lisp_Object placeholder; 2876 AUTO_CONS (placeholder, Qnil, Qnil);
2885 Lisp_Object cell; 2877 Lisp_Object cell = Fcons (make_number (n), placeholder);
2886
2887 placeholder = Fcons (Qnil, Qnil);
2888 cell = Fcons (make_number (n), placeholder);
2889 read_objects = Fcons (cell, read_objects); 2878 read_objects = Fcons (cell, read_objects);
2890 2879
2891 /* Read the object itself. */ 2880 /* Read the object itself. */
@@ -3364,7 +3353,7 @@ substitute_object_recurse (Lisp_Object object, Lisp_Object placeholder, Lisp_Obj
3364 substitute_in_interval contains part of the logic. */ 3353 substitute_in_interval contains part of the logic. */
3365 3354
3366 INTERVAL root_interval = string_intervals (subtree); 3355 INTERVAL root_interval = string_intervals (subtree);
3367 Lisp_Object arg = Fcons (object, placeholder); 3356 AUTO_CONS (arg, object, placeholder);
3368 3357
3369 traverse_intervals_noorder (root_interval, 3358 traverse_intervals_noorder (root_interval,
3370 &substitute_in_interval, arg); 3359 &substitute_in_interval, arg);
@@ -3671,8 +3660,10 @@ read_list (bool flag, Lisp_Object readcharfun)
3671 in the installed Lisp directory. 3660 in the installed Lisp directory.
3672 We don't use Fexpand_file_name because that would make 3661 We don't use Fexpand_file_name because that would make
3673 the directory absolute now. */ 3662 the directory absolute now. */
3674 elt = concat2 (build_string ("../lisp/"), 3663 {
3675 Ffile_name_nondirectory (elt)); 3664 AUTO_STRING (dot_dot_lisp, "../lisp/");
3665 elt = concat2 (dot_dot_lisp, Ffile_name_nondirectory (elt));
3666 }
3676 } 3667 }
3677 else if (EQ (elt, Vload_file_name) 3668 else if (EQ (elt, Vload_file_name)
3678 && ! NILP (elt) 3669 && ! NILP (elt)
@@ -3800,6 +3791,30 @@ check_obarray (Lisp_Object obarray)
3800 return obarray; 3791 return obarray;
3801} 3792}
3802 3793
3794/* Intern a symbol with name STRING in OBARRAY using bucket INDEX. */
3795
3796Lisp_Object
3797intern_driver (Lisp_Object string, Lisp_Object obarray, ptrdiff_t index)
3798{
3799 Lisp_Object *ptr, sym = Fmake_symbol (string);
3800
3801 XSYMBOL (sym)->interned = (EQ (obarray, initial_obarray)
3802 ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY
3803 : SYMBOL_INTERNED);
3804
3805 if ((SREF (string, 0) == ':') && EQ (obarray, initial_obarray))
3806 {
3807 XSYMBOL (sym)->constant = 1;
3808 XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL;
3809 SET_SYMBOL_VAL (XSYMBOL (sym), sym);
3810 }
3811
3812 ptr = aref_addr (obarray, index);
3813 set_symbol_next (sym, SYMBOLP (*ptr) ? XSYMBOL (*ptr) : NULL);
3814 *ptr = sym;
3815 return sym;
3816}
3817
3803/* Intern the C string STR: return a symbol with that name, 3818/* Intern the C string STR: return a symbol with that name,
3804 interned in the current obarray. */ 3819 interned in the current obarray. */
3805 3820
@@ -3809,7 +3824,8 @@ intern_1 (const char *str, ptrdiff_t len)
3809 Lisp_Object obarray = check_obarray (Vobarray); 3824 Lisp_Object obarray = check_obarray (Vobarray);
3810 Lisp_Object tem = oblookup (obarray, str, len, len); 3825 Lisp_Object tem = oblookup (obarray, str, len, len);
3811 3826
3812 return SYMBOLP (tem) ? tem : Fintern (make_string (str, len), obarray); 3827 return SYMBOLP (tem) ? tem : intern_driver (make_string (str, len),
3828 obarray, XINT (tem));
3813} 3829}
3814 3830
3815Lisp_Object 3831Lisp_Object
@@ -3818,16 +3834,14 @@ intern_c_string_1 (const char *str, ptrdiff_t len)
3818 Lisp_Object obarray = check_obarray (Vobarray); 3834 Lisp_Object obarray = check_obarray (Vobarray);
3819 Lisp_Object tem = oblookup (obarray, str, len, len); 3835 Lisp_Object tem = oblookup (obarray, str, len, len);
3820 3836
3821 if (SYMBOLP (tem)) 3837 if (!SYMBOLP (tem))
3822 return tem; 3838 {
3823 3839 /* Creating a non-pure string from a string literal not implemented yet.
3824 if (NILP (Vpurify_flag)) 3840 We could just use make_string here and live with the extra copy. */
3825 /* Creating a non-pure string from a string literal not 3841 eassert (!NILP (Vpurify_flag));
3826 implemented yet. We could just use make_string here and live 3842 tem = intern_driver (make_pure_c_string (str, len), obarray, XINT (tem));
3827 with the extra copy. */ 3843 }
3828 emacs_abort (); 3844 return tem;
3829
3830 return Fintern (make_pure_c_string (str, len), obarray);
3831} 3845}
3832 3846
3833DEFUN ("intern", Fintern, Sintern, 1, 2, 0, 3847DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
@@ -3837,43 +3851,16 @@ A second optional argument specifies the obarray to use;
3837it defaults to the value of `obarray'. */) 3851it defaults to the value of `obarray'. */)
3838 (Lisp_Object string, Lisp_Object obarray) 3852 (Lisp_Object string, Lisp_Object obarray)
3839{ 3853{
3840 register Lisp_Object tem, sym, *ptr; 3854 Lisp_Object tem;
3841
3842 if (NILP (obarray)) obarray = Vobarray;
3843 obarray = check_obarray (obarray);
3844 3855
3856 obarray = check_obarray (NILP (obarray) ? Vobarray : obarray);
3845 CHECK_STRING (string); 3857 CHECK_STRING (string);
3846 3858
3847 tem = oblookup (obarray, SSDATA (string), 3859 tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string));
3848 SCHARS (string), 3860 if (!SYMBOLP (tem))
3849 SBYTES (string)); 3861 tem = intern_driver (NILP (Vpurify_flag) ? string
3850 if (!INTEGERP (tem)) 3862 : Fpurecopy (string), obarray, XINT (tem));
3851 return tem; 3863 return tem;
3852
3853 if (!NILP (Vpurify_flag))
3854 string = Fpurecopy (string);
3855 sym = Fmake_symbol (string);
3856
3857 if (EQ (obarray, initial_obarray))
3858 XSYMBOL (sym)->interned = SYMBOL_INTERNED_IN_INITIAL_OBARRAY;
3859 else
3860 XSYMBOL (sym)->interned = SYMBOL_INTERNED;
3861
3862 if ((SREF (string, 0) == ':')
3863 && EQ (obarray, initial_obarray))
3864 {
3865 XSYMBOL (sym)->constant = 1;
3866 XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL;
3867 SET_SYMBOL_VAL (XSYMBOL (sym), sym);
3868 }
3869
3870 ptr = aref_addr (obarray, XINT (tem));
3871 if (SYMBOLP (*ptr))
3872 set_symbol_next (sym, XSYMBOL (*ptr));
3873 else
3874 set_symbol_next (sym, NULL);
3875 *ptr = sym;
3876 return sym;
3877} 3864}
3878 3865
3879DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0, 3866DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0,
@@ -4213,7 +4200,7 @@ load_path_check (Lisp_Object lpath)
4213 if (STRINGP (dirfile)) 4200 if (STRINGP (dirfile))
4214 { 4201 {
4215 dirfile = Fdirectory_file_name (dirfile); 4202 dirfile = Fdirectory_file_name (dirfile);
4216 if (! file_accessible_directory_p (SSDATA (dirfile))) 4203 if (! file_accessible_directory_p (dirfile))
4217 dir_warning ("Lisp directory", XCAR (path_tail)); 4204 dir_warning ("Lisp directory", XCAR (path_tail));
4218 } 4205 }
4219 } 4206 }
diff --git a/src/macfont.h b/src/macfont.h
index 7421cd63a79..e6e45ab152c 100644
--- a/src/macfont.h
+++ b/src/macfont.h
@@ -57,11 +57,7 @@ typedef CTCharacterCollection CharacterCollection;
57#define MAC_FONT_CASCADE_LIST_ATTRIBUTE kCTFontCascadeListAttribute 57#define MAC_FONT_CASCADE_LIST_ATTRIBUTE kCTFontCascadeListAttribute
58#define MAC_FONT_CHARACTER_SET_ATTRIBUTE kCTFontCharacterSetAttribute 58#define MAC_FONT_CHARACTER_SET_ATTRIBUTE kCTFontCharacterSetAttribute
59#define MAC_FONT_LANGUAGES_ATTRIBUTE kCTFontLanguagesAttribute 59#define MAC_FONT_LANGUAGES_ATTRIBUTE kCTFontLanguagesAttribute
60#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
61#define MAC_FONT_FORMAT_ATTRIBUTE kCTFontFormatAttribute 60#define MAC_FONT_FORMAT_ATTRIBUTE kCTFontFormatAttribute
62#else
63#define MAC_FONT_FORMAT_ATTRIBUTE (CFSTR ("NSCTFontFormatAttribute"))
64#endif
65#define MAC_FONT_SYMBOLIC_TRAIT kCTFontSymbolicTrait 61#define MAC_FONT_SYMBOLIC_TRAIT kCTFontSymbolicTrait
66#define MAC_FONT_WEIGHT_TRAIT kCTFontWeightTrait 62#define MAC_FONT_WEIGHT_TRAIT kCTFontWeightTrait
67#define MAC_FONT_WIDTH_TRAIT kCTFontWidthTrait 63#define MAC_FONT_WIDTH_TRAIT kCTFontWidthTrait
@@ -79,11 +75,7 @@ enum {
79}; 75};
80 76
81enum { 77enum {
82#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
83 MAC_FONT_FORMAT_BITMAP = kCTFontFormatBitmap 78 MAC_FONT_FORMAT_BITMAP = kCTFontFormatBitmap
84#else
85 MAC_FONT_FORMAT_BITMAP = 5
86#endif
87}; 79};
88 80
89enum { 81enum {
@@ -112,13 +104,8 @@ enum {
112#define mac_font_get_underline_position CTFontGetUnderlinePosition 104#define mac_font_get_underline_position CTFontGetUnderlinePosition
113#define mac_font_get_underline_thickness CTFontGetUnderlineThickness 105#define mac_font_get_underline_thickness CTFontGetUnderlineThickness
114#define mac_font_copy_graphics_font(font) CTFontCopyGraphicsFont (font, NULL) 106#define mac_font_copy_graphics_font(font) CTFontCopyGraphicsFont (font, NULL)
115#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
116#define mac_font_copy_non_synthetic_table(font, table) \ 107#define mac_font_copy_non_synthetic_table(font, table) \
117 CTFontCopyTable (font, table, kCTFontTableOptionNoOptions) 108 CTFontCopyTable (font, table, kCTFontTableOptionNoOptions)
118#else
119#define mac_font_copy_non_synthetic_table(font, table) \
120 CTFontCopyTable (font, table, kCTFontTableOptionExcludeSynthetic)
121#endif
122 109
123#define mac_font_create_preferred_family_for_attributes \ 110#define mac_font_create_preferred_family_for_attributes \
124 mac_ctfont_create_preferred_family_for_attributes 111 mac_ctfont_create_preferred_family_for_attributes
diff --git a/src/macfont.m b/src/macfont.m
index 0d702873220..366d087f8c2 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -36,13 +36,11 @@ Original author: YAMAMOTO Mitsuharu
36#include "macfont.h" 36#include "macfont.h"
37#include "macuvs.h" 37#include "macuvs.h"
38 38
39#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
40
41#include <libkern/OSByteOrder.h> 39#include <libkern/OSByteOrder.h>
42 40
43static struct font_driver macfont_driver; 41static struct font_driver macfont_driver;
44 42
45/* Core Text, for Mac OS X 10.5 and later. */ 43/* Core Text, for Mac OS X. */
46static Lisp_Object Qmac_ct; 44static Lisp_Object Qmac_ct;
47 45
48static double mac_ctfont_get_advance_width_for_glyph (CTFontRef, CGGlyph); 46static double mac_ctfont_get_advance_width_for_glyph (CTFontRef, CGGlyph);
@@ -50,25 +48,25 @@ static CGRect mac_ctfont_get_bounding_rect_for_glyph (CTFontRef, CGGlyph);
50static CFArrayRef mac_ctfont_create_available_families (void); 48static CFArrayRef mac_ctfont_create_available_families (void);
51static Boolean mac_ctfont_equal_in_postscript_name (CTFontRef, CTFontRef); 49static Boolean mac_ctfont_equal_in_postscript_name (CTFontRef, CTFontRef);
52static CTLineRef mac_ctfont_create_line_with_string_and_font (CFStringRef, 50static CTLineRef mac_ctfont_create_line_with_string_and_font (CFStringRef,
53 CTFontRef); 51 CTFontRef);
54static CFComparisonResult mac_font_family_compare (const void *, 52static CFComparisonResult mac_font_family_compare (const void *,
55 const void *, void *); 53 const void *, void *);
56static Boolean mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef, 54static Boolean mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef,
57 CFArrayRef); 55 CFArrayRef);
58static CFStringRef mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef); 56static CFStringRef mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef);
59static CFIndex mac_ctfont_shape (CTFontRef, CFStringRef, 57static CFIndex mac_ctfont_shape (CTFontRef, CFStringRef,
60 struct mac_glyph_layout *, CFIndex); 58 struct mac_glyph_layout *, CFIndex);
61static CFArrayRef 59static CFArrayRef
62mac_font_copy_default_descriptors_for_language (CFStringRef language); 60mac_font_copy_default_descriptors_for_language (CFStringRef language);
63 61
64static CFStringRef 62static CFStringRef
65mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, 63mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset,
66 CFArrayRef languages); 64 CFArrayRef languages);
67 65
68#if USE_CT_GLYPH_INFO 66#if USE_CT_GLYPH_INFO
69static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef, 67static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef,
70 CTCharacterCollection, 68 CTCharacterCollection,
71 CGFontIndex); 69 CGFontIndex);
72#endif 70#endif
73 71
74/* The font property key specifying the font design destination. The 72/* The font property key specifying the font design destination. The
@@ -129,26 +127,26 @@ static const CGAffineTransform synthetic_italic_atfm = {1, 0, 0.25, 1, 0, 0};
129static const CGFloat synthetic_bold_factor = 0.024; 127static const CGFloat synthetic_bold_factor = 0.024;
130 128
131static Boolean cfnumber_get_font_symbolic_traits_value (CFNumberRef, 129static Boolean cfnumber_get_font_symbolic_traits_value (CFNumberRef,
132 FontSymbolicTraits *); 130 FontSymbolicTraits *);
133static void macfont_store_descriptor_attributes (FontDescriptorRef, 131static void macfont_store_descriptor_attributes (FontDescriptorRef,
134 Lisp_Object); 132 Lisp_Object);
135static Lisp_Object macfont_descriptor_entity (FontDescriptorRef, 133static Lisp_Object macfont_descriptor_entity (FontDescriptorRef,
136 Lisp_Object, 134 Lisp_Object,
137 FontSymbolicTraits); 135 FontSymbolicTraits);
138static CFStringRef macfont_create_family_with_symbol (Lisp_Object); 136static CFStringRef macfont_create_family_with_symbol (Lisp_Object);
139static int macfont_glyph_extents (struct font *, CGGlyph, 137static int macfont_glyph_extents (struct font *, CGGlyph,
140 struct font_metrics *, CGFloat *, int); 138 struct font_metrics *, CGFloat *, int);
141static CFMutableDictionaryRef macfont_create_attributes_with_spec (Lisp_Object); 139static CFMutableDictionaryRef macfont_create_attributes_with_spec (Lisp_Object);
142static Boolean macfont_supports_charset_and_languages_p (FontDescriptorRef, 140static Boolean macfont_supports_charset_and_languages_p (FontDescriptorRef,
143 CFCharacterSetRef, 141 CFCharacterSetRef,
144 Lisp_Object, 142 Lisp_Object,
145 CFArrayRef); 143 CFArrayRef);
146static CFIndex macfont_closest_traits_index (CFArrayRef, 144static Boolean macfont_closest_traits_index_p (CFArrayRef, FontSymbolicTraits,
147 FontSymbolicTraits); 145 CFIndex);
148static CFDataRef mac_font_copy_uvs_table (FontRef); 146static CFDataRef mac_font_copy_uvs_table (FontRef);
149static void mac_font_get_glyphs_for_variants (CFDataRef, UTF32Char, 147static void mac_font_get_glyphs_for_variants (CFDataRef, UTF32Char,
150 const UTF32Char [], 148 const UTF32Char [],
151 CGGlyph [], CFIndex); 149 CGGlyph [], CFIndex);
152 150
153/* From CFData to a lisp string. Always returns a unibyte string. */ 151/* From CFData to a lisp string. Always returns a unibyte string. */
154 152
@@ -180,15 +178,15 @@ cfstring_to_lisp_nodecode (CFStringRef string)
180 CFIndex i, length = CFStringGetLength (string); 178 CFIndex i, length = CFStringGetLength (string);
181 179
182 for (i = 0; i < length; i++) 180 for (i = 0; i < length; i++)
183 if (CFStringGetCharacterAtIndex (string, i) == 0) 181 if (CFStringGetCharacterAtIndex (string, i) == 0)
184 break; 182 break;
185 183
186 if (i == length) 184 if (i == length)
187 return make_unibyte_string (s, strlen (s)); 185 return make_unibyte_string (s, strlen (s));
188 } 186 }
189 187
190 data = CFStringCreateExternalRepresentation (NULL, string, 188 data = CFStringCreateExternalRepresentation (NULL, string,
191 kCFStringEncodingUTF8, '?'); 189 kCFStringEncodingUTF8, '?');
192 if (data) 190 if (data)
193 { 191 {
194 result = cfdata_to_lisp (data); 192 result = cfdata_to_lisp (data);
@@ -206,12 +204,12 @@ static CFStringRef
206cfstring_create_with_string_noencode (Lisp_Object s) 204cfstring_create_with_string_noencode (Lisp_Object s)
207{ 205{
208 CFStringRef string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s), 206 CFStringRef string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s),
209 kCFStringEncodingUTF8, false); 207 kCFStringEncodingUTF8, false);
210 208
211 if (string == NULL) 209 if (string == NULL)
212 /* Failed to interpret as UTF 8. Fall back on Mac Roman. */ 210 /* Failed to interpret as UTF 8. Fall back on Mac Roman. */
213 string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s), 211 string = CFStringCreateWithBytes (NULL, SDATA (s), SBYTES (s),
214 kCFStringEncodingMacRoman, false); 212 kCFStringEncodingMacRoman, false);
215 213
216 return string; 214 return string;
217} 215}
@@ -226,7 +224,7 @@ mac_screen_font_get_advance_width_for_glyph (ScreenFontRef font, CGGlyph glyph)
226 224
227static CGGlyph 225static CGGlyph
228mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection, 226mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection,
229 CGFontIndex cid) 227 CGFontIndex cid)
230{ 228{
231#if USE_CT_GLYPH_INFO 229#if USE_CT_GLYPH_INFO
232 return mac_ctfont_get_glyph_for_cid ((CTFontRef) font, collection, cid); 230 return mac_ctfont_get_glyph_for_cid ((CTFontRef) font, collection, cid);
@@ -237,17 +235,17 @@ mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection,
237 unichar characters[] = {0xfffd}; 235 unichar characters[] = {0xfffd};
238 NSString *string = 236 NSString *string =
239 [NSString stringWithCharacters:characters 237 [NSString stringWithCharacters:characters
240 length:ARRAYELTS (characters)]; 238 length:ARRAYELTS (characters)];
241 NSGlyphInfo *glyphInfo = 239 NSGlyphInfo *glyphInfo =
242 [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid 240 [NSGlyphInfo glyphInfoWithCharacterIdentifier:cid
243 collection:collection 241 collection:collection
244 baseString:string]; 242 baseString:string];
245 NSDictionary *attributes = 243 NSDictionary *attributes =
246 [NSDictionary dictionaryWithObjectsAndKeys:nsFont,NSFontAttributeName, 244 [NSDictionary dictionaryWithObjectsAndKeys:nsFont,NSFontAttributeName,
247 glyphInfo,NSGlyphInfoAttributeName,nil]; 245 glyphInfo,NSGlyphInfoAttributeName,nil];
248 NSTextStorage *textStorage = 246 NSTextStorage *textStorage =
249 [[NSTextStorage alloc] initWithString:string 247 [[NSTextStorage alloc] initWithString:string
250 attributes:attributes]; 248 attributes:attributes];
251 NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; 249 NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
252 NSTextContainer *textContainer = [[NSTextContainer alloc] init]; 250 NSTextContainer *textContainer = [[NSTextContainer alloc] init];
253 NSFont *fontInTextStorage; 251 NSFont *fontInTextStorage;
@@ -261,14 +259,14 @@ mac_font_get_glyph_for_cid (FontRef font, CharacterCollection collection,
261 (void) [layoutManager glyphRangeForTextContainer:textContainer]; 259 (void) [layoutManager glyphRangeForTextContainer:textContainer];
262 260
263 fontInTextStorage = [textStorage attribute:NSFontAttributeName atIndex:0 261 fontInTextStorage = [textStorage attribute:NSFontAttributeName atIndex:0
264 effectiveRange:NULL]; 262 effectiveRange:NULL];
265 if (fontInTextStorage == nsFont 263 if (fontInTextStorage == nsFont
266 || [[fontInTextStorage fontName] isEqualToString:[nsFont fontName]]) 264 || [[fontInTextStorage fontName] isEqualToString:[nsFont fontName]])
267 { 265 {
268 NSGlyph glyph = [layoutManager glyphAtIndex:0]; 266 NSGlyph glyph = [layoutManager glyphAtIndex:0];
269 267
270 if (glyph < [nsFont numberOfGlyphs]) 268 if (glyph < [nsFont numberOfGlyphs])
271 result = glyph; 269 result = glyph;
272 } 270 }
273 271
274 [textStorage release]; 272 [textStorage release];
@@ -292,7 +290,7 @@ mac_screen_font_create_with_name (CFStringRef name, CGFloat size)
292 290
293static Boolean 291static Boolean
294mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent, 292mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent,
295 CGFloat *descent, CGFloat *leading) 293 CGFloat *descent, CGFloat *leading)
296{ 294{
297 NSFont *nsFont = [(NSFont *)font printerFont]; 295 NSFont *nsFont = [(NSFont *)font printerFont];
298 NSTextStorage *textStorage; 296 NSTextStorage *textStorage;
@@ -323,7 +321,7 @@ mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent,
323 } 321 }
324 322
325 usedRect = [layoutManager lineFragmentUsedRectForGlyphAtIndex:0 323 usedRect = [layoutManager lineFragmentUsedRectForGlyphAtIndex:0
326 effectiveRange:NULL]; 324 effectiveRange:NULL];
327 spaceLocation = [layoutManager locationForGlyphAtIndex:0]; 325 spaceLocation = [layoutManager locationForGlyphAtIndex:0];
328 [textStorage release]; 326 [textStorage release];
329 327
@@ -342,8 +340,8 @@ mac_screen_font_get_metrics (ScreenFontRef font, CGFloat *ascent,
342 340
343static CFIndex 341static CFIndex
344mac_font_shape_1 (NSFont *font, NSString *string, 342mac_font_shape_1 (NSFont *font, NSString *string,
345 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len, 343 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len,
346 BOOL screen_font_p) 344 BOOL screen_font_p)
347{ 345{
348 NSUInteger i; 346 NSUInteger i;
349 CFIndex result = 0; 347 CFIndex result = 0;
@@ -360,7 +358,7 @@ mac_font_shape_1 (NSFont *font, NSString *string,
360 358
361 /* Append a trailing space to measure baseline position. */ 359 /* Append a trailing space to measure baseline position. */
362 [textStorage appendAttributedString:([[[NSAttributedString alloc] 360 [textStorage appendAttributedString:([[[NSAttributedString alloc]
363 initWithString:@" "] autorelease])]; 361 initWithString:@" "] autorelease])];
364 [textStorage setFont:font]; 362 [textStorage setFont:font];
365 [textContainer setLineFragmentPadding:0]; 363 [textContainer setLineFragmentPadding:0];
366 [layoutManager setUsesScreenFonts:screen_font_p]; 364 [layoutManager setUsesScreenFonts:screen_font_p];
@@ -396,13 +394,13 @@ mac_font_shape_1 (NSFont *font, NSString *string,
396 { 394 {
397 NSRange range; 395 NSRange range;
398 NSFont *fontInTextStorage = 396 NSFont *fontInTextStorage =
399 [textStorage attribute:NSFontAttributeName atIndex:i 397 [textStorage attribute:NSFontAttributeName atIndex:i
400 longestEffectiveRange:&range 398 longestEffectiveRange:&range
401 inRange:(NSMakeRange (0, stringLength))]; 399 inRange:(NSMakeRange (0, stringLength))];
402 400
403 if (!(fontInTextStorage == font 401 if (!(fontInTextStorage == font
404 || [[fontInTextStorage fontName] isEqualToString:[font fontName]])) 402 || [[fontInTextStorage fontName] isEqualToString:[font fontName]]))
405 break; 403 break;
406 i = NSMaxRange (range); 404 i = NSMaxRange (range);
407 } 405 }
408 if (i < stringLength) 406 if (i < stringLength)
@@ -414,12 +412,12 @@ mac_font_shape_1 (NSFont *font, NSString *string,
414 NSRange range = NSMakeRange (0, stringLength); 412 NSRange range = NSMakeRange (0, stringLength);
415 413
416 range = [layoutManager glyphRangeForCharacterRange:range 414 range = [layoutManager glyphRangeForCharacterRange:range
417 actualCharacterRange:NULL]; 415 actualCharacterRange:NULL];
418 numberOfGlyphs = NSMaxRange (range); 416 numberOfGlyphs = NSMaxRange (range);
419 used = numberOfGlyphs; 417 used = numberOfGlyphs;
420 for (i = 0; i < numberOfGlyphs; i++) 418 for (i = 0; i < numberOfGlyphs; i++)
421 if ([layoutManager notShownAttributeForGlyphAtIndex:i]) 419 if ([layoutManager notShownAttributeForGlyphAtIndex:i])
422 used--; 420 used--;
423 } 421 }
424 422
425 if (0 < used && used <= glyph_len) 423 if (0 < used && used <= glyph_len)
@@ -432,186 +430,186 @@ mac_font_shape_1 (NSFont *font, NSString *string,
432 430
433 glyphIndex = 0; 431 glyphIndex = 0;
434 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex]) 432 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
435 glyphIndex++; 433 glyphIndex++;
436 434
437 /* For now we assume the direction is not changed within the 435 /* For now we assume the direction is not changed within the
438 string. */ 436 string. */
439 [layoutManager getGlyphsInRange:(NSMakeRange (glyphIndex, 1)) 437 [layoutManager getGlyphsInRange:(NSMakeRange (glyphIndex, 1))
440 glyphs:NULL characterIndexes:NULL 438 glyphs:NULL characterIndexes:NULL
441 glyphInscriptions:NULL elasticBits:NULL 439 glyphInscriptions:NULL elasticBits:NULL
442 bidiLevels:&bidiLevel]; 440 bidiLevels:&bidiLevel];
443 if (bidiLevel & 1) 441 if (bidiLevel & 1)
444 permutation = xmalloc (sizeof (NSUInteger) * used); 442 permutation = xmalloc (sizeof (NSUInteger) * used);
445 else 443 else
446 permutation = NULL; 444 permutation = NULL;
447 445
448#define RIGHT_TO_LEFT_P permutation 446#define RIGHT_TO_LEFT_P permutation
449 447
450 /* Fill the `comp_range' member of struct mac_glyph_layout, and 448 /* Fill the `comp_range' member of struct mac_glyph_layout, and
451 setup a permutation for right-to-left text. */ 449 setup a permutation for right-to-left text. */
452 compRange = NSMakeRange (0, 0); 450 compRange = NSMakeRange (0, 0);
453 for (range = NSMakeRange (0, 0); NSMaxRange (range) < used; 451 for (range = NSMakeRange (0, 0); NSMaxRange (range) < used;
454 range.length++) 452 range.length++)
455 { 453 {
456 struct mac_glyph_layout *gl = glyph_layouts + NSMaxRange (range); 454 struct mac_glyph_layout *gl = glyph_layouts + NSMaxRange (range);
457 NSUInteger characterIndex = 455 NSUInteger characterIndex =
458 [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; 456 [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
459 457
460 gl->string_index = characterIndex; 458 gl->string_index = characterIndex;
461 459
462 if (characterIndex >= NSMaxRange (compRange)) 460 if (characterIndex >= NSMaxRange (compRange))
463 { 461 {
464 compRange.location = NSMaxRange (compRange); 462 compRange.location = NSMaxRange (compRange);
465 do 463 do
466 { 464 {
467 NSRange characterRange = 465 NSRange characterRange =
468 [string 466 [string
469 rangeOfComposedCharacterSequenceAtIndex:characterIndex]; 467 rangeOfComposedCharacterSequenceAtIndex:characterIndex];
470 468
471 compRange.length = 469 compRange.length =
472 NSMaxRange (characterRange) - compRange.location; 470 NSMaxRange (characterRange) - compRange.location;
473 [layoutManager glyphRangeForCharacterRange:compRange 471 [layoutManager glyphRangeForCharacterRange:compRange
474 actualCharacterRange:&characterRange]; 472 actualCharacterRange:&characterRange];
475 characterIndex = NSMaxRange (characterRange) - 1; 473 characterIndex = NSMaxRange (characterRange) - 1;
476 } 474 }
477 while (characterIndex >= NSMaxRange (compRange)); 475 while (characterIndex >= NSMaxRange (compRange));
478 476
479 if (RIGHT_TO_LEFT_P) 477 if (RIGHT_TO_LEFT_P)
480 for (i = 0; i < range.length; i++) 478 for (i = 0; i < range.length; i++)
481 permutation[range.location + i] = NSMaxRange (range) - i - 1; 479 permutation[range.location + i] = NSMaxRange (range) - i - 1;
482 480
483 range = NSMakeRange (NSMaxRange (range), 0); 481 range = NSMakeRange (NSMaxRange (range), 0);
484 } 482 }
485 483
486 gl->comp_range.location = compRange.location; 484 gl->comp_range.location = compRange.location;
487 gl->comp_range.length = compRange.length; 485 gl->comp_range.length = compRange.length;
488 486
489 while (++glyphIndex < numberOfGlyphs) 487 while (++glyphIndex < numberOfGlyphs)
490 if (![layoutManager notShownAttributeForGlyphAtIndex:glyphIndex]) 488 if (![layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
491 break; 489 break;
492 } 490 }
493 if (RIGHT_TO_LEFT_P) 491 if (RIGHT_TO_LEFT_P)
494 for (i = 0; i < range.length; i++) 492 for (i = 0; i < range.length; i++)
495 permutation[range.location + i] = NSMaxRange (range) - i - 1; 493 permutation[range.location + i] = NSMaxRange (range) - i - 1;
496 494
497 /* Then fill the remaining members. */ 495 /* Then fill the remaining members. */
498 glyphIndex = prevGlyphIndex = 0; 496 glyphIndex = prevGlyphIndex = 0;
499 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex]) 497 while ([layoutManager notShownAttributeForGlyphAtIndex:glyphIndex])
500 glyphIndex++; 498 glyphIndex++;
501 499
502 if (!RIGHT_TO_LEFT_P) 500 if (!RIGHT_TO_LEFT_P)
503 totalAdvance = 0; 501 totalAdvance = 0;
504 else 502 else
505 { 503 {
506 NSUInteger nrects; 504 NSUInteger nrects;
507 NSRect *glyphRects = 505 NSRect *glyphRects =
508 [layoutManager 506 [layoutManager
509 rectArrayForGlyphRange:(NSMakeRange (0, numberOfGlyphs)) 507 rectArrayForGlyphRange:(NSMakeRange (0, numberOfGlyphs))
510 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0)) 508 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
511 inTextContainer:textContainer rectCount:&nrects]; 509 inTextContainer:textContainer rectCount:&nrects];
512 510
513 totalAdvance = NSMaxX (glyphRects[0]); 511 totalAdvance = NSMaxX (glyphRects[0]);
514 } 512 }
515 513
516 for (i = 0; i < used; i++) 514 for (i = 0; i < used; i++)
517 { 515 {
518 struct mac_glyph_layout *gl; 516 struct mac_glyph_layout *gl;
519 NSPoint location; 517 NSPoint location;
520 NSUInteger nextGlyphIndex; 518 NSUInteger nextGlyphIndex;
521 NSRange glyphRange; 519 NSRange glyphRange;
522 NSRect *glyphRects; 520 NSRect *glyphRects;
523 NSUInteger nrects; 521 NSUInteger nrects;
524 522
525 if (!RIGHT_TO_LEFT_P) 523 if (!RIGHT_TO_LEFT_P)
526 gl = glyph_layouts + i; 524 gl = glyph_layouts + i;
527 else 525 else
528 { 526 {
529 NSUInteger dest = permutation[i]; 527 NSUInteger dest = permutation[i];
530 528
531 gl = glyph_layouts + dest; 529 gl = glyph_layouts + dest;
532 if (i < dest) 530 if (i < dest)
533 { 531 {
534 CFIndex tmp = gl->string_index; 532 CFIndex tmp = gl->string_index;
535 533
536 gl->string_index = glyph_layouts[i].string_index; 534 gl->string_index = glyph_layouts[i].string_index;
537 glyph_layouts[i].string_index = tmp; 535 glyph_layouts[i].string_index = tmp;
538 } 536 }
539 } 537 }
540 gl->glyph_id = [layoutManager glyphAtIndex:glyphIndex]; 538 gl->glyph_id = [layoutManager glyphAtIndex:glyphIndex];
541 539
542 location = [layoutManager locationForGlyphAtIndex:glyphIndex]; 540 location = [layoutManager locationForGlyphAtIndex:glyphIndex];
543 gl->baseline_delta = spaceLocation.y - location.y; 541 gl->baseline_delta = spaceLocation.y - location.y;
544 542
545 for (nextGlyphIndex = glyphIndex + 1; nextGlyphIndex < numberOfGlyphs; 543 for (nextGlyphIndex = glyphIndex + 1; nextGlyphIndex < numberOfGlyphs;
546 nextGlyphIndex++) 544 nextGlyphIndex++)
547 if (![layoutManager 545 if (![layoutManager
548 notShownAttributeForGlyphAtIndex:nextGlyphIndex]) 546 notShownAttributeForGlyphAtIndex:nextGlyphIndex])
549 break; 547 break;
550 548
551 if (!RIGHT_TO_LEFT_P) 549 if (!RIGHT_TO_LEFT_P)
552 { 550 {
553 CGFloat maxX; 551 CGFloat maxX;
554 552
555 if (prevGlyphIndex == 0) 553 if (prevGlyphIndex == 0)
556 glyphRange = NSMakeRange (0, nextGlyphIndex); 554 glyphRange = NSMakeRange (0, nextGlyphIndex);
557 else 555 else
558 glyphRange = NSMakeRange (glyphIndex, 556 glyphRange = NSMakeRange (glyphIndex,
559 nextGlyphIndex - glyphIndex); 557 nextGlyphIndex - glyphIndex);
560 glyphRects = 558 glyphRects =
561 [layoutManager 559 [layoutManager
562 rectArrayForGlyphRange:glyphRange 560 rectArrayForGlyphRange:glyphRange
563 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0)) 561 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
564 inTextContainer:textContainer rectCount:&nrects]; 562 inTextContainer:textContainer rectCount:&nrects];
565 maxX = max (NSMaxX (glyphRects[0]), totalAdvance); 563 maxX = max (NSMaxX (glyphRects[0]), totalAdvance);
566 gl->advance_delta = location.x - totalAdvance; 564 gl->advance_delta = location.x - totalAdvance;
567 gl->advance = maxX - totalAdvance; 565 gl->advance = maxX - totalAdvance;
568 totalAdvance = maxX; 566 totalAdvance = maxX;
569 } 567 }
570 else 568 else
571 { 569 {
572 CGFloat minX; 570 CGFloat minX;
573 571
574 if (nextGlyphIndex == numberOfGlyphs) 572 if (nextGlyphIndex == numberOfGlyphs)
575 glyphRange = NSMakeRange (prevGlyphIndex, 573 glyphRange = NSMakeRange (prevGlyphIndex,
576 numberOfGlyphs - prevGlyphIndex); 574 numberOfGlyphs - prevGlyphIndex);
577 else 575 else
578 glyphRange = NSMakeRange (prevGlyphIndex, 576 glyphRange = NSMakeRange (prevGlyphIndex,
579 glyphIndex + 1 - prevGlyphIndex); 577 glyphIndex + 1 - prevGlyphIndex);
580 glyphRects = 578 glyphRects =
581 [layoutManager 579 [layoutManager
582 rectArrayForGlyphRange:glyphRange 580 rectArrayForGlyphRange:glyphRange
583 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0)) 581 withinSelectedGlyphRange:(NSMakeRange (NSNotFound, 0))
584 inTextContainer:textContainer rectCount:&nrects]; 582 inTextContainer:textContainer rectCount:&nrects];
585 minX = min (NSMinX (glyphRects[0]), totalAdvance); 583 minX = min (NSMinX (glyphRects[0]), totalAdvance);
586 gl->advance = totalAdvance - minX; 584 gl->advance = totalAdvance - minX;
587 totalAdvance = minX; 585 totalAdvance = minX;
588 gl->advance_delta = location.x - totalAdvance; 586 gl->advance_delta = location.x - totalAdvance;
589 } 587 }
590 588
591 prevGlyphIndex = glyphIndex + 1; 589 prevGlyphIndex = glyphIndex + 1;
592 glyphIndex = nextGlyphIndex; 590 glyphIndex = nextGlyphIndex;
593 } 591 }
594 592
595 if (RIGHT_TO_LEFT_P) 593 if (RIGHT_TO_LEFT_P)
596 xfree (permutation); 594 xfree (permutation);
597 595
598#undef RIGHT_TO_LEFT_P 596#undef RIGHT_TO_LEFT_P
599 597
600 result = used; 598 result = used;
601 } 599 }
602 [textStorage release]; 600 [textStorage release];
603 601
604 return result; 602 return result;
605} 603}
606 604
607static CFIndex 605static CFIndex
608mac_screen_font_shape (ScreenFontRef font, CFStringRef string, 606mac_screen_font_shape (ScreenFontRef font, CFStringRef string,
609 struct mac_glyph_layout *glyph_layouts, 607 struct mac_glyph_layout *glyph_layouts,
610 CFIndex glyph_len) 608 CFIndex glyph_len)
611{ 609{
612 return mac_font_shape_1 ([(NSFont *)font printerFont], 610 return mac_font_shape_1 ([(NSFont *)font printerFont],
613 (NSString *) string, 611 (NSString *) string,
614 glyph_layouts, glyph_len, YES); 612 glyph_layouts, glyph_len, YES);
615} 613}
616 614
617static CGColorRef 615static CGColorRef
@@ -649,6 +647,7 @@ get_cgcolor(unsigned long idx, struct frame *f)
649 CGColorRelease (refcol_); \ 647 CGColorRelease (refcol_); \
650 } while (0) 648 } while (0)
651 649
650
652 651
653/* Mac font driver. */ 652/* Mac font driver. */
654 653
@@ -711,17 +710,17 @@ static const struct
711 CFStringRef font_names[3]; 710 CFStringRef font_names[3];
712} macfont_language_default_font_names[] = { 711} macfont_language_default_font_names[] = {
713 { CFSTR ("ja"), { CFSTR ("HiraKakuProN-W3"), /* 10.5 - 10.9 */ 712 { CFSTR ("ja"), { CFSTR ("HiraKakuProN-W3"), /* 10.5 - 10.9 */
714 CFSTR ("HiraKakuPro-W3"), /* 10.4 */ 713 CFSTR ("HiraKakuPro-W3"), /* 10.4 */
715 NULL }}, 714 NULL }},
716 { CFSTR ("ko"), { CFSTR ("AppleSDGothicNeo-Regular"), /* 10.8 - 10.9 */ 715 { CFSTR ("ko"), { CFSTR ("AppleSDGothicNeo-Regular"), /* 10.8 - 10.9 */
717 CFSTR ("AppleGothic"), /* 10.4 - 10.7 */ 716 CFSTR ("AppleGothic"), /* 10.4 - 10.7 */
718 NULL }}, 717 NULL }},
719 { CFSTR ("zh-Hans"), { CFSTR ("STHeitiSC-Light"), /* 10.6 - 10.9 */ 718 { CFSTR ("zh-Hans"), { CFSTR ("STHeitiSC-Light"), /* 10.6 - 10.9 */
720 CFSTR ("STXihei"), /* 10.4 - 10.5 */ 719 CFSTR ("STXihei"), /* 10.4 - 10.5 */
721 NULL }}, 720 NULL }},
722 { CFSTR ("zh-Hant"), { CFSTR ("STHeitiTC-Light"), /* 10.6 - 10.9 */ 721 { CFSTR ("zh-Hant"), { CFSTR ("STHeitiTC-Light"), /* 10.6 - 10.9 */
723 CFSTR ("LiHeiPro"), /* 10.4 - 10.5 */ 722 CFSTR ("LiHeiPro"), /* 10.4 - 10.5 */
724 NULL }}, 723 NULL }},
725 { NULL } 724 { NULL }
726}; 725};
727#endif 726#endif
@@ -736,8 +735,8 @@ macfont_update_antialias_threshold (void)
736 735
737 threshold = 736 threshold =
738 CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"), 737 CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"),
739 kCFPreferencesCurrentApplication, 738 kCFPreferencesCurrentApplication,
740 &valid_p); 739 &valid_p);
741 if (valid_p) 740 if (valid_p)
742 macfont_antialias_threshold = threshold; 741 macfont_antialias_threshold = threshold;
743} 742}
@@ -771,7 +770,7 @@ macfont_store_utf32char_to_unichars (UTF32Char c, UniChar *unichars)
771 770
772static Boolean 771static Boolean
773cfnumber_get_font_symbolic_traits_value (CFNumberRef number, 772cfnumber_get_font_symbolic_traits_value (CFNumberRef number,
774 FontSymbolicTraits *sym_traits) 773 FontSymbolicTraits *sym_traits)
775{ 774{
776 SInt64 sint64_value; 775 SInt64 sint64_value;
777 776
@@ -789,7 +788,7 @@ cfnumber_get_font_symbolic_traits_value (CFNumberRef number,
789 788
790static void 789static void
791macfont_store_descriptor_attributes (FontDescriptorRef desc, 790macfont_store_descriptor_attributes (FontDescriptorRef desc,
792 Lisp_Object spec_or_entity) 791 Lisp_Object spec_or_entity)
793{ 792{
794 CFStringRef str; 793 CFStringRef str;
795 CFDictionaryRef dict; 794 CFDictionaryRef dict;
@@ -797,66 +796,66 @@ macfont_store_descriptor_attributes (FontDescriptorRef desc,
797 CGFloat floatval; 796 CGFloat floatval;
798 797
799 str = mac_font_descriptor_copy_attribute (desc, 798 str = mac_font_descriptor_copy_attribute (desc,
800 MAC_FONT_FAMILY_NAME_ATTRIBUTE); 799 MAC_FONT_FAMILY_NAME_ATTRIBUTE);
801 if (str) 800 if (str)
802 { 801 {
803 ASET (spec_or_entity, FONT_FAMILY_INDEX, 802 ASET (spec_or_entity, FONT_FAMILY_INDEX,
804 macfont_intern_prop_cfstring (str)); 803 macfont_intern_prop_cfstring (str));
805 CFRelease (str); 804 CFRelease (str);
806 } 805 }
807 dict = mac_font_descriptor_copy_attribute (desc, MAC_FONT_TRAITS_ATTRIBUTE); 806 dict = mac_font_descriptor_copy_attribute (desc, MAC_FONT_TRAITS_ATTRIBUTE);
808 if (dict) 807 if (dict)
809 { 808 {
810 struct { 809 struct {
811 enum font_property_index index; 810 enum font_property_index index;
812 CFStringRef trait; 811 CFStringRef trait;
813 CGPoint points[6]; 812 CGPoint points[6];
814 } numeric_traits[] = 813 } numeric_traits[] =
815 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT, 814 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT,
816 {{-0.4, 50}, /* light */ 815 {{-0.4, 50}, /* light */
817 {-0.24, 87.5}, /* (semi-light + normal) / 2 */ 816 {-0.24, 87.5}, /* (semi-light + normal) / 2 */
818 {0, 100}, /* normal */ 817 {0, 100}, /* normal */
819 {0.24, 140}, /* (semi-bold + normal) / 2 */ 818 {0.24, 140}, /* (semi-bold + normal) / 2 */
820 {0.4, 200}, /* bold */ 819 {0.4, 200}, /* bold */
821 {CGFLOAT_MAX, CGFLOAT_MAX}}}, 820 {CGFLOAT_MAX, CGFLOAT_MAX}}},
822 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT, 821 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT,
823 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}, 822 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}},
824 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT, 823 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT,
825 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}}; 824 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}};
826 int i; 825 int i;
827 826
828 for (i = 0; i < ARRAYELTS (numeric_traits); i++) 827 for (i = 0; i < ARRAYELTS (numeric_traits); i++)
829 { 828 {
830 num = CFDictionaryGetValue (dict, numeric_traits[i].trait); 829 num = CFDictionaryGetValue (dict, numeric_traits[i].trait);
831 if (num && CFNumberGetValue (num, kCFNumberCGFloatType, &floatval)) 830 if (num && CFNumberGetValue (num, kCFNumberCGFloatType, &floatval))
832 { 831 {
833 CGPoint *point = numeric_traits[i].points; 832 CGPoint *point = numeric_traits[i].points;
834 833
835 while (point->x < floatval) 834 while (point->x < floatval)
836 point++; 835 point++;
837 if (point == numeric_traits[i].points) 836 if (point == numeric_traits[i].points)
838 point++; 837 point++;
839 else if (point->x == CGFLOAT_MAX) 838 else if (point->x == CGFLOAT_MAX)
840 point--; 839 point--;
841 floatval = (point - 1)->y + ((floatval - (point - 1)->x) 840 floatval = (point - 1)->y + ((floatval - (point - 1)->x)
842 * ((point->y - (point - 1)->y) 841 * ((point->y - (point - 1)->y)
843 / (point->x - (point - 1)->x))); 842 / (point->x - (point - 1)->x)));
844 FONT_SET_STYLE (spec_or_entity, numeric_traits[i].index, 843 FONT_SET_STYLE (spec_or_entity, numeric_traits[i].index,
845 make_number (lround (floatval))); 844 make_number (lround (floatval)));
846 } 845 }
847 } 846 }
848 847
849 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT); 848 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT);
850 if (num) 849 if (num)
851 { 850 {
852 FontSymbolicTraits sym_traits; 851 FontSymbolicTraits sym_traits;
853 int spacing; 852 int spacing;
854 853
855 cfnumber_get_font_symbolic_traits_value (num, &sym_traits); 854 cfnumber_get_font_symbolic_traits_value (num, &sym_traits);
856 spacing = (sym_traits & MAC_FONT_TRAIT_MONO_SPACE 855 spacing = (sym_traits & MAC_FONT_TRAIT_MONO_SPACE
857 ? FONT_SPACING_MONO : FONT_SPACING_PROPORTIONAL); 856 ? FONT_SPACING_MONO : FONT_SPACING_PROPORTIONAL);
858 ASET (spec_or_entity, FONT_SPACING_INDEX, make_number (spacing)); 857 ASET (spec_or_entity, FONT_SPACING_INDEX, make_number (spacing));
859 } 858 }
860 859
861 CFRelease (dict); 860 CFRelease (dict);
862 } 861 }
@@ -871,7 +870,7 @@ macfont_store_descriptor_attributes (FontDescriptorRef desc,
871 870
872static Lisp_Object 871static Lisp_Object
873macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra, 872macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra,
874 FontSymbolicTraits synth_sym_traits) 873 FontSymbolicTraits synth_sym_traits)
875{ 874{
876 Lisp_Object entity; 875 Lisp_Object entity;
877 CFDictionaryRef dict; 876 CFDictionaryRef dict;
@@ -891,7 +890,7 @@ macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra,
891 CFNumberRef num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT); 890 CFNumberRef num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT);
892 891
893 if (num) 892 if (num)
894 cfnumber_get_font_symbolic_traits_value (num, &sym_traits); 893 cfnumber_get_font_symbolic_traits_value (num, &sym_traits);
895 CFRelease (dict); 894 CFRelease (dict);
896 } 895 }
897 if (EQ (AREF (entity, FONT_SIZE_INDEX), make_number (0))) 896 if (EQ (AREF (entity, FONT_SIZE_INDEX), make_number (0)))
@@ -899,16 +898,16 @@ macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra,
899 ASET (entity, FONT_EXTRA_INDEX, Fcopy_sequence (extra)); 898 ASET (entity, FONT_EXTRA_INDEX, Fcopy_sequence (extra));
900 name = mac_font_descriptor_copy_attribute (desc, MAC_FONT_NAME_ATTRIBUTE); 899 name = mac_font_descriptor_copy_attribute (desc, MAC_FONT_NAME_ATTRIBUTE);
901 font_put_extra (entity, QCfont_entity, 900 font_put_extra (entity, QCfont_entity,
902 make_save_ptr_int ((void *) name, sym_traits)); 901 make_save_ptr_int ((void *) name, sym_traits));
903 if (synth_sym_traits & MAC_FONT_TRAIT_ITALIC) 902 if (synth_sym_traits & MAC_FONT_TRAIT_ITALIC)
904 FONT_SET_STYLE (entity, FONT_SLANT_INDEX, 903 FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
905 make_number (FONT_SLANT_SYNTHETIC_ITALIC)); 904 make_number (FONT_SLANT_SYNTHETIC_ITALIC));
906 if (synth_sym_traits & MAC_FONT_TRAIT_BOLD) 905 if (synth_sym_traits & MAC_FONT_TRAIT_BOLD)
907 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, 906 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
908 make_number (FONT_WEIGHT_SYNTHETIC_BOLD)); 907 make_number (FONT_WEIGHT_SYNTHETIC_BOLD));
909 if (synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE) 908 if (synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE)
910 ASET (entity, FONT_SPACING_INDEX, 909 ASET (entity, FONT_SPACING_INDEX,
911 make_number (FONT_SPACING_SYNTHETIC_MONO)); 910 make_number (FONT_SPACING_SYNTHETIC_MONO));
912 911
913 return entity; 912 return entity;
914} 913}
@@ -925,22 +924,9 @@ macfont_create_family_with_symbol (Lisp_Object symbol)
925 if (family_name == NULL) 924 if (family_name == NULL)
926 return NULL; 925 return NULL;
927 926
928#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
929#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
930 if (CTFontManagerCompareFontFamilyNames != NULL)
931#endif
932 { 927 {
933 family_name_comparator = CTFontManagerCompareFontFamilyNames; 928 family_name_comparator = CTFontManagerCompareFontFamilyNames;
934 } 929 }
935#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
936 else /* CTFontManagerCompareFontFamilyNames == NULL */
937#endif
938#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 */
939#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
940 {
941 family_name_comparator = mac_font_family_compare;
942 }
943#endif
944 930
945 if ((*family_name_comparator) (family_name, CFSTR ("LastResort"), NULL) 931 if ((*family_name_comparator) (family_name, CFSTR ("LastResort"), NULL)
946 == kCFCompareEqualTo) 932 == kCFCompareEqualTo)
@@ -948,36 +934,36 @@ macfont_create_family_with_symbol (Lisp_Object symbol)
948 else 934 else
949 while (1) 935 while (1)
950 { 936 {
951 CFIndex i, count; 937 CFIndex i, count;
952 938
953 if (families == NULL) 939 if (families == NULL)
954 { 940 {
955 families = mac_font_create_available_families (); 941 families = mac_font_create_available_families ();
956 using_cache_p = 0; 942 using_cache_p = 0;
957 if (families == NULL) 943 if (families == NULL)
958 break; 944 break;
959 } 945 }
960 946
961 count = CFArrayGetCount (families); 947 count = CFArrayGetCount (families);
962 i = CFArrayBSearchValues (families, CFRangeMake (0, count), 948 i = CFArrayBSearchValues (families, CFRangeMake (0, count),
963 (const void *) family_name, 949 (const void *) family_name,
964 family_name_comparator, NULL); 950 family_name_comparator, NULL);
965 if (i < count) 951 if (i < count)
966 { 952 {
967 CFStringRef name = CFArrayGetValueAtIndex (families, i); 953 CFStringRef name = CFArrayGetValueAtIndex (families, i);
968 954
969 if ((*family_name_comparator) (name, family_name, NULL) 955 if ((*family_name_comparator) (name, family_name, NULL)
970 == kCFCompareEqualTo) 956 == kCFCompareEqualTo)
971 result = CFRetain (name); 957 result = CFRetain (name);
972 } 958 }
973 959
974 if (result || !using_cache_p) 960 if (result || !using_cache_p)
975 break; 961 break;
976 else 962 else
977 { 963 {
978 CFRelease (families); 964 CFRelease (families);
979 families = NULL; 965 families = NULL;
980 } 966 }
981 } 967 }
982 968
983 CFRelease (family_name); 969 CFRelease (family_name);
@@ -1004,23 +990,23 @@ struct macfont_metrics
1004 signed width_frac : WIDTH_FRAC_BITS, width_int : 16 - WIDTH_FRAC_BITS; 990 signed width_frac : WIDTH_FRAC_BITS, width_int : 16 - WIDTH_FRAC_BITS;
1005}; 991};
1006 992
1007#define METRICS_VALUE(metrics, member) \ 993#define METRICS_VALUE(metrics, member) \
1008 (((metrics)->member##_high << 8) | (metrics)->member##_low) 994 (((metrics)->member##_high << 8) | (metrics)->member##_low)
1009#define METRICS_SET_VALUE(metrics, member, value) \ 995#define METRICS_SET_VALUE(metrics, member, value) \
1010 do {short tmp = (value); (metrics)->member##_low = tmp & 0xff; \ 996 do {short tmp = (value); (metrics)->member##_low = tmp & 0xff; \
1011 (metrics)->member##_high = tmp >> 8;} while (0) 997 (metrics)->member##_high = tmp >> 8;} while (0)
1012 998
1013enum metrics_status 999enum metrics_status
1014 { 1000{
1015 METRICS_INVALID = -1, /* metrics entry is invalid */ 1001 METRICS_INVALID = -1, /* metrics entry is invalid */
1016 METRICS_WIDTH_VALID = -2 /* width is valid but others are invalid */ 1002 METRICS_WIDTH_VALID = -2 /* width is valid but others are invalid */
1017 }; 1003};
1018 1004
1019#define METRICS_STATUS(metrics) \ 1005#define METRICS_STATUS(metrics) \
1020 (METRICS_VALUE (metrics, ascent) + METRICS_VALUE (metrics, descent)) 1006 (METRICS_VALUE (metrics, ascent) + METRICS_VALUE (metrics, descent))
1021#define METRICS_SET_STATUS(metrics, status) \ 1007#define METRICS_SET_STATUS(metrics, status) \
1022 do {METRICS_SET_VALUE (metrics, ascent, 0); \ 1008 do {METRICS_SET_VALUE (metrics, ascent, 0); \
1023 METRICS_SET_VALUE (metrics, descent, status);} while (0) 1009 METRICS_SET_VALUE (metrics, descent, status);} while (0)
1024 1010
1025#define METRICS_NCOLS_PER_ROW (128) 1011#define METRICS_NCOLS_PER_ROW (128)
1026#define LCD_FONT_SMOOTHING_LEFT_MARGIN (0.396f) 1012#define LCD_FONT_SMOOTHING_LEFT_MARGIN (0.396f)
@@ -1028,8 +1014,8 @@ enum metrics_status
1028 1014
1029static int 1015static int
1030macfont_glyph_extents (struct font *font, CGGlyph glyph, 1016macfont_glyph_extents (struct font *font, CGGlyph glyph,
1031 struct font_metrics *metrics, CGFloat *advance_delta, 1017 struct font_metrics *metrics, CGFloat *advance_delta,
1032 int force_integral_p) 1018 int force_integral_p)
1033{ 1019{
1034 struct macfont_info *macfont_info = (struct macfont_info *) font; 1020 struct macfont_info *macfont_info = (struct macfont_info *) font;
1035 FontRef macfont = macfont_info->macfont; 1021 FontRef macfont = macfont_info->macfont;
@@ -1042,11 +1028,11 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1042 if (row >= macfont_info->metrics_nrows) 1028 if (row >= macfont_info->metrics_nrows)
1043 { 1029 {
1044 macfont_info->metrics = 1030 macfont_info->metrics =
1045 xrealloc (macfont_info->metrics, 1031 xrealloc (macfont_info->metrics,
1046 sizeof (struct macfont_metrics *) * (row + 1)); 1032 sizeof (struct macfont_metrics *) * (row + 1));
1047 memset (macfont_info->metrics + macfont_info->metrics_nrows, 0, 1033 memset (macfont_info->metrics + macfont_info->metrics_nrows, 0,
1048 (sizeof (struct macfont_metrics *) 1034 (sizeof (struct macfont_metrics *)
1049 * (row + 1 - macfont_info->metrics_nrows))); 1035 * (row + 1 - macfont_info->metrics_nrows)));
1050 macfont_info->metrics_nrows = row + 1; 1036 macfont_info->metrics_nrows = row + 1;
1051 } 1037 }
1052 if (macfont_info->metrics[row] == NULL) 1038 if (macfont_info->metrics[row] == NULL)
@@ -1056,7 +1042,7 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1056 1042
1057 new = xmalloc (sizeof (struct macfont_metrics) * METRICS_NCOLS_PER_ROW); 1043 new = xmalloc (sizeof (struct macfont_metrics) * METRICS_NCOLS_PER_ROW);
1058 for (i = 0; i < METRICS_NCOLS_PER_ROW; i++) 1044 for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
1059 METRICS_SET_STATUS (new + i, METRICS_INVALID); 1045 METRICS_SET_STATUS (new + i, METRICS_INVALID);
1060 macfont_info->metrics[row] = new; 1046 macfont_info->metrics[row] = new;
1061 } 1047 }
1062 cache = macfont_info->metrics[row] + col; 1048 cache = macfont_info->metrics[row] + col;
@@ -1066,17 +1052,17 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1066 CGFloat fwidth; 1052 CGFloat fwidth;
1067 1053
1068 if (macfont_info->screen_font) 1054 if (macfont_info->screen_font)
1069 fwidth = mac_screen_font_get_advance_width_for_glyph (macfont_info->screen_font, glyph); 1055 fwidth = mac_screen_font_get_advance_width_for_glyph (macfont_info->screen_font, glyph);
1070 else 1056 else
1071 fwidth = mac_font_get_advance_width_for_glyph (macfont, glyph); 1057 fwidth = mac_font_get_advance_width_for_glyph (macfont, glyph);
1072 1058
1073 /* For synthetic mono fonts, cache->width_{int,frac} holds the 1059 /* For synthetic mono fonts, cache->width_{int,frac} holds the
1074 advance delta value. */ 1060 advance delta value. */
1075 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO) 1061 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO)
1076 fwidth = (font->pixel_size - fwidth) / 2; 1062 fwidth = (font->pixel_size - fwidth) / 2;
1077 cache->width_int = lround (fwidth); 1063 cache->width_int = lround (fwidth);
1078 cache->width_frac = lround ((fwidth - cache->width_int) 1064 cache->width_frac = lround ((fwidth - cache->width_int)
1079 * WIDTH_FRAC_SCALE); 1065 * WIDTH_FRAC_SCALE);
1080 METRICS_SET_STATUS (cache, METRICS_WIDTH_VALID); 1066 METRICS_SET_STATUS (cache, METRICS_WIDTH_VALID);
1081 } 1067 }
1082 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO) 1068 if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO)
@@ -1087,52 +1073,52 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1087 if (metrics) 1073 if (metrics)
1088 { 1074 {
1089 if (METRICS_STATUS (cache) == METRICS_WIDTH_VALID) 1075 if (METRICS_STATUS (cache) == METRICS_WIDTH_VALID)
1090 { 1076 {
1091 CGRect bounds = mac_font_get_bounding_rect_for_glyph (macfont, glyph); 1077 CGRect bounds = mac_font_get_bounding_rect_for_glyph (macfont, glyph);
1092 1078
1093 if (macfont_info->synthetic_italic_p) 1079 if (macfont_info->synthetic_italic_p)
1094 { 1080 {
1095 /* We assume the members a, b, c, and d in 1081 /* We assume the members a, b, c, and d in
1096 synthetic_italic_atfm are non-negative. */ 1082 synthetic_italic_atfm are non-negative. */
1097 bounds.origin = 1083 bounds.origin =
1098 CGPointApplyAffineTransform (bounds.origin, 1084 CGPointApplyAffineTransform (bounds.origin,
1099 synthetic_italic_atfm); 1085 synthetic_italic_atfm);
1100 bounds.size = 1086 bounds.size =
1101 CGSizeApplyAffineTransform (bounds.size, synthetic_italic_atfm); 1087 CGSizeApplyAffineTransform (bounds.size, synthetic_italic_atfm);
1102 } 1088 }
1103 if (macfont_info->synthetic_bold_p) 1089 if (macfont_info->synthetic_bold_p)
1104 { 1090 {
1105 CGFloat d = 1091 CGFloat d =
1106 - synthetic_bold_factor * mac_font_get_size (macfont) / 2; 1092 - synthetic_bold_factor * mac_font_get_size (macfont) / 2;
1107 1093
1108 bounds = CGRectInset (bounds, d, d); 1094 bounds = CGRectInset (bounds, d, d);
1109 } 1095 }
1110 switch (macfont_info->spacing) 1096 switch (macfont_info->spacing)
1111 { 1097 {
1112 case MACFONT_SPACING_PROPORTIONAL: 1098 case MACFONT_SPACING_PROPORTIONAL:
1113 bounds.origin.x += - (cache->width_frac 1099 bounds.origin.x += - (cache->width_frac
1114 / (CGFloat) (WIDTH_FRAC_SCALE * 2)); 1100 / (CGFloat) (WIDTH_FRAC_SCALE * 2));
1115 break; 1101 break;
1116 case MACFONT_SPACING_MONO: 1102 case MACFONT_SPACING_MONO:
1117 break; 1103 break;
1118 case MACFONT_SPACING_SYNTHETIC_MONO: 1104 case MACFONT_SPACING_SYNTHETIC_MONO:
1119 bounds.origin.x += (cache->width_int 1105 bounds.origin.x += (cache->width_int
1120 + (cache->width_frac 1106 + (cache->width_frac
1121 / (CGFloat) WIDTH_FRAC_SCALE)); 1107 / (CGFloat) WIDTH_FRAC_SCALE));
1122 break; 1108 break;
1123 } 1109 }
1124 if (bounds.size.width > 0) 1110 if (bounds.size.width > 0)
1125 { 1111 {
1126 bounds.origin.x -= LCD_FONT_SMOOTHING_LEFT_MARGIN; 1112 bounds.origin.x -= LCD_FONT_SMOOTHING_LEFT_MARGIN;
1127 bounds.size.width += (LCD_FONT_SMOOTHING_LEFT_MARGIN 1113 bounds.size.width += (LCD_FONT_SMOOTHING_LEFT_MARGIN
1128 + LCD_FONT_SMOOTHING_RIGHT_MARGIN); 1114 + LCD_FONT_SMOOTHING_RIGHT_MARGIN);
1129 } 1115 }
1130 bounds = CGRectIntegral (bounds); 1116 bounds = CGRectIntegral (bounds);
1131 METRICS_SET_VALUE (cache, lbearing, CGRectGetMinX (bounds)); 1117 METRICS_SET_VALUE (cache, lbearing, CGRectGetMinX (bounds));
1132 METRICS_SET_VALUE (cache, rbearing, CGRectGetMaxX (bounds)); 1118 METRICS_SET_VALUE (cache, rbearing, CGRectGetMaxX (bounds));
1133 METRICS_SET_VALUE (cache, ascent, CGRectGetMaxY (bounds)); 1119 METRICS_SET_VALUE (cache, ascent, CGRectGetMaxY (bounds));
1134 METRICS_SET_VALUE (cache, descent, -CGRectGetMinY (bounds)); 1120 METRICS_SET_VALUE (cache, descent, -CGRectGetMinY (bounds));
1135 } 1121 }
1136 metrics->lbearing = METRICS_VALUE (cache, lbearing); 1122 metrics->lbearing = METRICS_VALUE (cache, lbearing);
1137 metrics->rbearing = METRICS_VALUE (cache, rbearing); 1123 metrics->rbearing = METRICS_VALUE (cache, rbearing);
1138 metrics->width = width; 1124 metrics->width = width;
@@ -1143,22 +1129,22 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph,
1143 if (advance_delta) 1129 if (advance_delta)
1144 { 1130 {
1145 switch (macfont_info->spacing) 1131 switch (macfont_info->spacing)
1146 { 1132 {
1147 case MACFONT_SPACING_PROPORTIONAL: 1133 case MACFONT_SPACING_PROPORTIONAL:
1148 *advance_delta = (force_integral_p ? 0 1134 *advance_delta = (force_integral_p ? 0
1149 : - (cache->width_frac 1135 : - (cache->width_frac
1150 / (CGFloat) (WIDTH_FRAC_SCALE * 2))); 1136 / (CGFloat) (WIDTH_FRAC_SCALE * 2)));
1151 break; 1137 break;
1152 case MACFONT_SPACING_MONO: 1138 case MACFONT_SPACING_MONO:
1153 *advance_delta = 0; 1139 *advance_delta = 0;
1154 break; 1140 break;
1155 case MACFONT_SPACING_SYNTHETIC_MONO: 1141 case MACFONT_SPACING_SYNTHETIC_MONO:
1156 *advance_delta = (force_integral_p ? cache->width_int 1142 *advance_delta = (force_integral_p ? cache->width_int
1157 : (cache->width_int 1143 : (cache->width_int
1158 + (cache->width_frac 1144 + (cache->width_frac
1159 / (CGFloat) WIDTH_FRAC_SCALE))); 1145 / (CGFloat) WIDTH_FRAC_SCALE)));
1160 break; 1146 break;
1161 } 1147 }
1162 } 1148 }
1163 1149
1164 return width; 1150 return width;
@@ -1220,7 +1206,7 @@ static CFCharacterSetRef macfont_get_cf_charset (struct font *);
1220static CFCharacterSetRef macfont_get_cf_charset_for_name (CFStringRef); 1206static CFCharacterSetRef macfont_get_cf_charset_for_name (CFStringRef);
1221static CGGlyph macfont_get_glyph_for_character (struct font *, UTF32Char); 1207static CGGlyph macfont_get_glyph_for_character (struct font *, UTF32Char);
1222static CGGlyph macfont_get_glyph_for_cid (struct font *font, 1208static CGGlyph macfont_get_glyph_for_cid (struct font *font,
1223 CharacterCollection, CGFontIndex); 1209 CharacterCollection, CGFontIndex);
1224static CFDataRef macfont_get_uvs_table (struct font *, CharacterCollection *); 1210static CFDataRef macfont_get_uvs_table (struct font *, CharacterCollection *);
1225 1211
1226static struct macfont_cache * 1212static struct macfont_cache *
@@ -1231,39 +1217,39 @@ macfont_lookup_cache (CFStringRef key)
1231 if (macfont_cache_dictionary == NULL) 1217 if (macfont_cache_dictionary == NULL)
1232 { 1218 {
1233 macfont_cache_dictionary = 1219 macfont_cache_dictionary =
1234 CFDictionaryCreateMutable (NULL, 0, 1220 CFDictionaryCreateMutable (NULL, 0,
1235 &kCFTypeDictionaryKeyCallBacks, NULL); 1221 &kCFTypeDictionaryKeyCallBacks, NULL);
1236 cache = NULL; 1222 cache = NULL;
1237 } 1223 }
1238 else 1224 else
1239 cache = ((struct macfont_cache *) 1225 cache = ((struct macfont_cache *)
1240 CFDictionaryGetValue (macfont_cache_dictionary, key)); 1226 CFDictionaryGetValue (macfont_cache_dictionary, key));
1241 1227
1242 if (cache == NULL) 1228 if (cache == NULL)
1243 { 1229 {
1244 FontRef macfont = mac_font_create_with_name (key, 0); 1230 FontRef macfont = mac_font_create_with_name (key, 0);
1245 1231
1246 if (macfont) 1232 if (macfont)
1247 { 1233 {
1248 cache = xzalloc (sizeof (struct macfont_cache)); 1234 cache = xzalloc (sizeof (struct macfont_cache));
1249 /* Treat the LastResort font as if it contained glyphs for 1235 /* Treat the LastResort font as if it contained glyphs for
1250 all characters. This may look too rough, but neither 1236 all characters. This may look too rough, but neither
1251 CTFontCopyCharacterSet nor -[NSFont coveredCharacterSet] 1237 CTFontCopyCharacterSet nor -[NSFont coveredCharacterSet]
1252 for this font is correct for non-BMP characters on Mac OS 1238 for this font is correct for non-BMP characters on Mac OS
1253 X 10.5, anyway. */ 1239 X 10.5, anyway. */
1254 if (CFEqual (key, CFSTR ("LastResort"))) 1240 if (CFEqual (key, CFSTR ("LastResort")))
1255 { 1241 {
1256 CFRange range = CFRangeMake (0, MAX_UNICODE_CHAR + 1); 1242 CFRange range = CFRangeMake (0, MAX_UNICODE_CHAR + 1);
1257 1243
1258 cache->cf_charset = 1244 cache->cf_charset =
1259 CFCharacterSetCreateWithCharactersInRange (NULL, range); 1245 CFCharacterSetCreateWithCharactersInRange (NULL, range);
1260 } 1246 }
1261 if (cache->cf_charset == NULL) 1247 if (cache->cf_charset == NULL)
1262 cache->cf_charset = mac_font_copy_character_set (macfont); 1248 cache->cf_charset = mac_font_copy_character_set (macfont);
1263 CFDictionaryAddValue (macfont_cache_dictionary, key, 1249 CFDictionaryAddValue (macfont_cache_dictionary, key,
1264 (const void *) cache); 1250 (const void *) cache);
1265 CFRelease (macfont); 1251 CFRelease (macfont);
1266 } 1252 }
1267 } 1253 }
1268 1254
1269 return cache; 1255 return cache;
@@ -1285,13 +1271,13 @@ macfont_release_cache (struct macfont_cache *cache)
1285 int i; 1271 int i;
1286 1272
1287 for (i = 0; i < cache->glyph.nrows; i++) 1273 for (i = 0; i < cache->glyph.nrows; i++)
1288 xfree (cache->glyph.matrix[i]); 1274 xfree (cache->glyph.matrix[i]);
1289 xfree (cache->glyph.matrix); 1275 xfree (cache->glyph.matrix);
1290 if (cache->glyph.dictionary) 1276 if (cache->glyph.dictionary)
1291 CFRelease (cache->glyph.dictionary); 1277 CFRelease (cache->glyph.dictionary);
1292 memset (&cache->glyph, 0, sizeof (cache->glyph)); 1278 memset (&cache->glyph, 0, sizeof (cache->glyph));
1293 if (cache->uvs.table) 1279 if (cache->uvs.table)
1294 CFRelease (cache->uvs.table); 1280 CFRelease (cache->uvs.table);
1295 memset (&cache->uvs, 0, sizeof (cache->uvs)); 1281 memset (&cache->uvs, 0, sizeof (cache->uvs));
1296 } 1282 }
1297} 1283}
@@ -1325,124 +1311,114 @@ macfont_get_glyph_for_character (struct font *font, UTF32Char c)
1325 int nkeys_or_perm = cache->glyph.row_nkeys_or_perm[row]; 1311 int nkeys_or_perm = cache->glyph.row_nkeys_or_perm[row];
1326 1312
1327 if (nkeys_or_perm < ROW_PERM_OFFSET) 1313 if (nkeys_or_perm < ROW_PERM_OFFSET)
1328 { 1314 {
1329 UniChar unichars[256], ch; 1315 UniChar unichars[256], ch;
1330 CGGlyph *glyphs; 1316 CGGlyph *glyphs;
1331 int i, len; 1317 int i, len;
1332 int nrows; 1318 int nrows;
1333#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 1319 dispatch_queue_t queue;
1334 dispatch_queue_t queue; 1320 dispatch_group_t group = NULL;
1335 dispatch_group_t group = NULL; 1321
1336#else 1322 if (row != 0)
1337 int nkeys; 1323 {
1338#endif 1324 CFMutableDictionaryRef dictionary;
1339 1325 uintptr_t key, value;
1340 if (row != 0) 1326 int nshifts;
1341 { 1327 CGGlyph glyph;
1342 CFMutableDictionaryRef dictionary; 1328
1343 uintptr_t key, value; 1329 if (cache->glyph.dictionary == NULL)
1344 int nshifts; 1330 cache->glyph.dictionary =
1345 CGGlyph glyph; 1331 CFDictionaryCreateMutable (NULL, 0, NULL, NULL);
1346 1332 dictionary = cache->glyph.dictionary;
1347 if (cache->glyph.dictionary == NULL) 1333 key = c / NGLYPHS_IN_VALUE;
1348 cache->glyph.dictionary = 1334 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8);
1349 CFDictionaryCreateMutable (NULL, 0, NULL, NULL); 1335 value = ((uintptr_t)
1350 dictionary = cache->glyph.dictionary; 1336 CFDictionaryGetValue (dictionary, (const void *) key));
1351 key = c / NGLYPHS_IN_VALUE; 1337 glyph = (value >> nshifts);
1352 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8); 1338 if (glyph)
1353 value = ((uintptr_t) 1339 return glyph;
1354 CFDictionaryGetValue (dictionary, (const void *) key)); 1340
1355 glyph = (value >> nshifts); 1341 if (nkeys_or_perm + 1 != ROW_PERM_OFFSET)
1356 if (glyph) 1342 {
1357 return glyph; 1343 ch = c;
1358 1344 if (!mac_font_get_glyphs_for_characters (macfont, &ch,
1359 if (nkeys_or_perm + 1 != ROW_PERM_OFFSET) 1345 &glyph, 1)
1360 { 1346 || glyph == 0)
1361 ch = c; 1347 glyph = kCGFontIndexInvalid;
1362 if (!mac_font_get_glyphs_for_characters (macfont, &ch, 1348
1363 &glyph, 1) 1349 if (value == 0)
1364 || glyph == 0) 1350 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm + 1;
1365 glyph = kCGFontIndexInvalid; 1351 value |= ((uintptr_t) glyph << nshifts);
1366 1352 CFDictionarySetValue (dictionary, (const void *) key,
1367 if (value == 0) 1353 (const void *) value);
1368 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm + 1; 1354
1369 value |= ((uintptr_t) glyph << nshifts); 1355 return glyph;
1370 CFDictionarySetValue (dictionary, (const void *) key, 1356 }
1371 (const void *) value); 1357
1372 1358 queue =
1373 return glyph; 1359 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1374 } 1360 group = dispatch_group_create ();
1375 1361 dispatch_group_async (group, queue, ^{
1376#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 1362 int nkeys;
1377 queue = 1363 uintptr_t key;
1378 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 1364 nkeys = nkeys_or_perm;
1379 group = dispatch_group_create (); 1365 for (key = row * (256 / NGLYPHS_IN_VALUE); ; key++)
1380 dispatch_group_async (group, queue, ^{ 1366 if (CFDictionaryContainsKey (dictionary,
1381 int nkeys; 1367 (const void *) key))
1382 uintptr_t key; 1368 {
1383#endif 1369 CFDictionaryRemoveValue (dictionary,
1384 nkeys = nkeys_or_perm; 1370 (const void *) key);
1385 for (key = row * (256 / NGLYPHS_IN_VALUE); ; key++) 1371 if (--nkeys == 0)
1386 if (CFDictionaryContainsKey (dictionary, 1372 break;
1387 (const void *) key)) 1373 }
1388 { 1374 });
1389 CFDictionaryRemoveValue (dictionary, 1375 }
1390 (const void *) key); 1376
1391 if (--nkeys == 0) 1377 len = 0;
1392 break; 1378 for (i = 0; i < 256; i++)
1393 } 1379 {
1394#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 1380 ch = row * 256 + i;
1395 }); 1381 if (CFCharacterSetIsLongCharacterMember (cache->cf_charset, ch))
1396#endif 1382 unichars[len++] = ch;
1397 } 1383 }
1398 1384
1399 len = 0; 1385 glyphs = xmalloc (sizeof (CGGlyph) * 256);
1400 for (i = 0; i < 256; i++) 1386 if (len > 0)
1401 { 1387 {
1402 ch = row * 256 + i; 1388 mac_font_get_glyphs_for_characters (macfont, unichars,
1403 if (CFCharacterSetIsLongCharacterMember (cache->cf_charset, ch)) 1389 glyphs, len);
1404 unichars[len++] = ch; 1390 while (i > len)
1405 } 1391 {
1406 1392 int next = unichars[len - 1] % 256;
1407 glyphs = xmalloc (sizeof (CGGlyph) * 256); 1393
1408 if (len > 0) 1394 while (--i > next)
1409 { 1395 glyphs[i] = kCGFontIndexInvalid;
1410 mac_font_get_glyphs_for_characters (macfont, unichars, 1396
1411 glyphs, len); 1397 len--;
1412 while (i > len) 1398 glyphs[i] = glyphs[len];
1413 { 1399 if (len == 0)
1414 int next = unichars[len - 1] % 256; 1400 break;
1415 1401 }
1416 while (--i > next) 1402 }
1417 glyphs[i] = kCGFontIndexInvalid; 1403 if (i > len)
1418 1404 while (i-- > 0)
1419 len--; 1405 glyphs[i] = kCGFontIndexInvalid;
1420 glyphs[i] = glyphs[len]; 1406
1421 if (len == 0) 1407 nrows = cache->glyph.nrows;
1422 break; 1408 nkeys_or_perm = nrows + ROW_PERM_OFFSET;
1423 } 1409 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm;
1424 } 1410 nrows++;
1425 if (i > len) 1411 cache->glyph.matrix = xrealloc (cache->glyph.matrix,
1426 while (i-- > 0) 1412 sizeof (CGGlyph *) * nrows);
1427 glyphs[i] = kCGFontIndexInvalid; 1413 cache->glyph.matrix[nrows - 1] = glyphs;
1428 1414 cache->glyph.nrows = nrows;
1429 nrows = cache->glyph.nrows; 1415
1430 nkeys_or_perm = nrows + ROW_PERM_OFFSET; 1416 if (group)
1431 cache->glyph.row_nkeys_or_perm[row] = nkeys_or_perm; 1417 {
1432 nrows++; 1418 dispatch_group_wait (group, DISPATCH_TIME_FOREVER);
1433 cache->glyph.matrix = xrealloc (cache->glyph.matrix, 1419 dispatch_release (group);
1434 sizeof (CGGlyph *) * nrows); 1420 }
1435 cache->glyph.matrix[nrows - 1] = glyphs; 1421 }
1436 cache->glyph.nrows = nrows;
1437
1438#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
1439 if (group)
1440 {
1441 dispatch_group_wait (group, DISPATCH_TIME_FOREVER);
1442 dispatch_release (group);
1443 }
1444#endif
1445 }
1446 1422
1447 return cache->glyph.matrix[nkeys_or_perm - ROW_PERM_OFFSET][c % 256]; 1423 return cache->glyph.matrix[nkeys_or_perm - ROW_PERM_OFFSET][c % 256];
1448 } 1424 }
@@ -1453,29 +1429,29 @@ macfont_get_glyph_for_character (struct font *font, UTF32Char c)
1453 CGGlyph glyph; 1429 CGGlyph glyph;
1454 1430
1455 if (cache->glyph.dictionary == NULL) 1431 if (cache->glyph.dictionary == NULL)
1456 cache->glyph.dictionary = 1432 cache->glyph.dictionary =
1457 CFDictionaryCreateMutable (NULL, 0, NULL, NULL); 1433 CFDictionaryCreateMutable (NULL, 0, NULL, NULL);
1458 key = c / NGLYPHS_IN_VALUE; 1434 key = c / NGLYPHS_IN_VALUE;
1459 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8); 1435 nshifts = ((c % NGLYPHS_IN_VALUE) * sizeof (CGGlyph) * 8);
1460 value = (uintptr_t) CFDictionaryGetValue (cache->glyph.dictionary, 1436 value = (uintptr_t) CFDictionaryGetValue (cache->glyph.dictionary,
1461 (const void *) key); 1437 (const void *) key);
1462 glyph = (value >> nshifts); 1438 glyph = (value >> nshifts);
1463 if (glyph == 0) 1439 if (glyph == 0)
1464 { 1440 {
1465 UniChar unichars[2]; 1441 UniChar unichars[2];
1466 CGGlyph glyphs[2]; 1442 CGGlyph glyphs[2];
1467 CFIndex count = macfont_store_utf32char_to_unichars (c, unichars); 1443 CFIndex count = macfont_store_utf32char_to_unichars (c, unichars);
1468 1444
1469 if (mac_font_get_glyphs_for_characters (macfont, unichars, glyphs, 1445 if (mac_font_get_glyphs_for_characters (macfont, unichars, glyphs,
1470 count)) 1446 count))
1471 glyph = glyphs[0]; 1447 glyph = glyphs[0];
1472 if (glyph == 0) 1448 if (glyph == 0)
1473 glyph = kCGFontIndexInvalid; 1449 glyph = kCGFontIndexInvalid;
1474 1450
1475 value |= ((uintptr_t) glyph << nshifts); 1451 value |= ((uintptr_t) glyph << nshifts);
1476 CFDictionarySetValue (cache->glyph.dictionary, 1452 CFDictionarySetValue (cache->glyph.dictionary,
1477 (const void *) key, (const void *) value); 1453 (const void *) key, (const void *) value);
1478 } 1454 }
1479 1455
1480 return glyph; 1456 return glyph;
1481 } 1457 }
@@ -1483,7 +1459,7 @@ macfont_get_glyph_for_character (struct font *font, UTF32Char c)
1483 1459
1484static CGGlyph 1460static CGGlyph
1485macfont_get_glyph_for_cid (struct font *font, CharacterCollection collection, 1461macfont_get_glyph_for_cid (struct font *font, CharacterCollection collection,
1486 CGFontIndex cid) 1462 CGFontIndex cid)
1487{ 1463{
1488 struct macfont_info *macfont_info = (struct macfont_info *) font; 1464 struct macfont_info *macfont_info = (struct macfont_info *) font;
1489 FontRef macfont = macfont_info->macfont; 1465 FontRef macfont = macfont_info->macfont;
@@ -1504,34 +1480,34 @@ macfont_get_uvs_table (struct font *font, CharacterCollection *collection)
1504 { 1480 {
1505 CFDataRef uvs_table = mac_font_copy_uvs_table (macfont); 1481 CFDataRef uvs_table = mac_font_copy_uvs_table (macfont);
1506 CharacterCollection uvs_collection = 1482 CharacterCollection uvs_collection =
1507 MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING; 1483 MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING;
1508 1484
1509 if (uvs_table == NULL 1485 if (uvs_table == NULL
1510 && mac_font_get_glyph_for_cid (macfont, 1486 && mac_font_get_glyph_for_cid (macfont,
1511 MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1, 1487 MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1,
1512 6480) != kCGFontIndexInvalid) 1488 6480) != kCGFontIndexInvalid)
1513 { 1489 {
1514 /* If the glyph for U+4E55 is accessible via its CID 6480, 1490 /* If the glyph for U+4E55 is accessible via its CID 6480,
1515 then we use the Adobe-Japan1 UVS table, which maps a 1491 then we use the Adobe-Japan1 UVS table, which maps a
1516 variation sequence to a CID, as a fallback. */ 1492 variation sequence to a CID, as a fallback. */
1517 static CFDataRef mac_uvs_table_adobe_japan1 = NULL; 1493 static CFDataRef mac_uvs_table_adobe_japan1 = NULL;
1518 1494
1519 if (mac_uvs_table_adobe_japan1 == NULL) 1495 if (mac_uvs_table_adobe_japan1 == NULL)
1520 mac_uvs_table_adobe_japan1 = 1496 mac_uvs_table_adobe_japan1 =
1521 CFDataCreateWithBytesNoCopy (NULL, 1497 CFDataCreateWithBytesNoCopy (NULL,
1522 mac_uvs_table_adobe_japan1_bytes, 1498 mac_uvs_table_adobe_japan1_bytes,
1523 sizeof (mac_uvs_table_adobe_japan1_bytes), 1499 sizeof (mac_uvs_table_adobe_japan1_bytes),
1524 kCFAllocatorNull); 1500 kCFAllocatorNull);
1525 if (mac_uvs_table_adobe_japan1) 1501 if (mac_uvs_table_adobe_japan1)
1526 { 1502 {
1527 uvs_table = CFRetain (mac_uvs_table_adobe_japan1); 1503 uvs_table = CFRetain (mac_uvs_table_adobe_japan1);
1528 uvs_collection = MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1; 1504 uvs_collection = MAC_CHARACTER_COLLECTION_ADOBE_JAPAN1;
1529 } 1505 }
1530 } 1506 }
1531 if (uvs_table == NULL) 1507 if (uvs_table == NULL)
1532 cache->uvs.table = kCFNull; 1508 cache->uvs.table = kCFNull;
1533 else 1509 else
1534 cache->uvs.table = uvs_table; 1510 cache->uvs.table = uvs_table;
1535 cache->uvs.collection = uvs_collection; 1511 cache->uvs.collection = uvs_collection;
1536 } 1512 }
1537 1513
@@ -1553,12 +1529,12 @@ static Lisp_Object macfont_open (struct frame *, Lisp_Object, int);
1553static void macfont_close (struct font *); 1529static void macfont_close (struct font *);
1554static int macfont_has_char (Lisp_Object, int); 1530static int macfont_has_char (Lisp_Object, int);
1555static unsigned macfont_encode_char (struct font *, int); 1531static unsigned macfont_encode_char (struct font *, int);
1556static int macfont_text_extents (struct font *, unsigned int *, int, 1532static void macfont_text_extents (struct font *, unsigned int *, int,
1557 struct font_metrics *); 1533 struct font_metrics *);
1558static int macfont_draw (struct glyph_string *, int, int, int, int, bool); 1534static int macfont_draw (struct glyph_string *, int, int, int, int, bool);
1559static Lisp_Object macfont_shape (Lisp_Object); 1535static Lisp_Object macfont_shape (Lisp_Object);
1560static int macfont_variation_glyphs (struct font *, int c, 1536static int macfont_variation_glyphs (struct font *, int c,
1561 unsigned variations[256]); 1537 unsigned variations[256]);
1562static void macfont_filter_properties (Lisp_Object, Lisp_Object); 1538static void macfont_filter_properties (Lisp_Object, Lisp_Object);
1563 1539
1564static struct font_driver macfont_driver = 1540static struct font_driver macfont_driver =
@@ -1610,19 +1586,19 @@ macfont_get_charset (Lisp_Object registry)
1610 for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++) 1586 for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
1611 { 1587 {
1612 if (str[i] == '.') 1588 if (str[i] == '.')
1613 re[j++] = '\\'; 1589 re[j++] = '\\';
1614 else if (str[i] == '*') 1590 else if (str[i] == '*')
1615 re[j++] = '.'; 1591 re[j++] = '.';
1616 re[j] = str[i]; 1592 re[j] = str[i];
1617 if (re[j] == '?') 1593 if (re[j] == '?')
1618 re[j] = '.'; 1594 re[j] = '.';
1619 } 1595 }
1620 re[j] = '\0'; 1596 re[j] = '\0';
1621 regexp = make_unibyte_string (re, j); 1597 regexp = make_unibyte_string (re, j);
1622 for (i = 0; cf_charset_table[i].name; i++) 1598 for (i = 0; cf_charset_table[i].name; i++)
1623 if (fast_c_string_match_ignore_case 1599 if (fast_c_string_match_ignore_case
1624 (regexp, cf_charset_table[i].name, 1600 (regexp, cf_charset_table[i].name,
1625 strlen (cf_charset_table[i].name)) >= 0) 1601 strlen (cf_charset_table[i].name)) >= 0)
1626 break; 1602 break;
1627 if (! cf_charset_table[i].name) 1603 if (! cf_charset_table[i].name)
1628 return -1; 1604 return -1;
@@ -1635,27 +1611,27 @@ macfont_get_charset (Lisp_Object registry)
1635 CFMutableCharacterSetRef charset = CFCharacterSetCreateMutable (NULL); 1611 CFMutableCharacterSetRef charset = CFCharacterSetCreateMutable (NULL);
1636 1612
1637 if (! charset) 1613 if (! charset)
1638 return -1; 1614 return -1;
1639 for (j = 0; uniquifier[j]; j++) 1615 for (j = 0; uniquifier[j]; j++)
1640 { 1616 {
1641 count += macfont_store_utf32char_to_unichars (uniquifier[j], 1617 count += macfont_store_utf32char_to_unichars (uniquifier[j],
1642 unichars + count); 1618 unichars + count);
1643 CFCharacterSetAddCharactersInRange (charset, 1619 CFCharacterSetAddCharactersInRange (charset,
1644 CFRangeMake (uniquifier[j], 1)); 1620 CFRangeMake (uniquifier[j], 1));
1645 } 1621 }
1646 1622
1647 string = CFStringCreateWithCharacters (NULL, unichars, count); 1623 string = CFStringCreateWithCharacters (NULL, unichars, count);
1648 if (! string) 1624 if (! string)
1649 { 1625 {
1650 CFRelease (charset); 1626 CFRelease (charset);
1651 return -1; 1627 return -1;
1652 } 1628 }
1653 cf_charset_table[i].cf_charset = CFCharacterSetCreateCopy (NULL, 1629 cf_charset_table[i].cf_charset = CFCharacterSetCreateCopy (NULL,
1654 charset); 1630 charset);
1655 CFRelease (charset); 1631 CFRelease (charset);
1656 /* CFCharacterSetCreateWithCharactersInString does not handle 1632 /* CFCharacterSetCreateWithCharactersInString does not handle
1657 surrogate pairs properly as of Mac OS X 10.5. */ 1633 surrogate pairs properly as of Mac OS X 10.5. */
1658 cf_charset_table[i].cf_charset_string = string; 1634 cf_charset_table[i].cf_charset_string = string;
1659 } 1635 }
1660 return i; 1636 return i;
1661} 1637}
@@ -1668,19 +1644,19 @@ struct OpenTypeSpec
1668 unsigned int *features[2]; 1644 unsigned int *features[2];
1669}; 1645};
1670 1646
1671#define OTF_SYM_TAG(SYM, TAG) \ 1647#define OTF_SYM_TAG(SYM, TAG) \
1672 do { \ 1648 do { \
1673 unsigned char *p = SDATA (SYMBOL_NAME (SYM)); \ 1649 unsigned char *p = SDATA (SYMBOL_NAME (SYM)); \
1674 TAG = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; \ 1650 TAG = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; \
1675 } while (0) 1651 } while (0)
1676 1652
1677#define OTF_TAG_STR(TAG, P) \ 1653#define OTF_TAG_STR(TAG, P) \
1678 do { \ 1654 do { \
1679 (P)[0] = (char) (TAG >> 24); \ 1655 (P)[0] = (char) (TAG >> 24); \
1680 (P)[1] = (char) ((TAG >> 16) & 0xFF); \ 1656 (P)[1] = (char) ((TAG >> 16) & 0xFF); \
1681 (P)[2] = (char) ((TAG >> 8) & 0xFF); \ 1657 (P)[2] = (char) ((TAG >> 8) & 0xFF); \
1682 (P)[3] = (char) (TAG & 0xFF); \ 1658 (P)[3] = (char) (TAG & 0xFF); \
1683 (P)[4] = '\0'; \ 1659 (P)[4] = '\0'; \
1684 } while (0) 1660 } while (0)
1685 1661
1686static struct OpenTypeSpec * 1662static struct OpenTypeSpec *
@@ -1699,9 +1675,9 @@ macfont_get_open_type_spec (Lisp_Object otf_spec)
1699 OTF_SYM_TAG (spec->script, spec->script_tag); 1675 OTF_SYM_TAG (spec->script, spec->script_tag);
1700 val = assq_no_quit (spec->script, Votf_script_alist); 1676 val = assq_no_quit (spec->script, Votf_script_alist);
1701 if (CONSP (val) && SYMBOLP (XCDR (val))) 1677 if (CONSP (val) && SYMBOLP (XCDR (val)))
1702 spec->script = XCDR (val); 1678 spec->script = XCDR (val);
1703 else 1679 else
1704 spec->script = Qnil; 1680 spec->script = Qnil;
1705 } 1681 }
1706 else 1682 else
1707 spec->script_tag = 0x44464C54; /* "DFLT" */ 1683 spec->script_tag = 0x44464C54; /* "DFLT" */
@@ -1711,7 +1687,7 @@ macfont_get_open_type_spec (Lisp_Object otf_spec)
1711 { 1687 {
1712 val = XCAR (otf_spec); 1688 val = XCAR (otf_spec);
1713 if (! NILP (val)) 1689 if (! NILP (val))
1714 OTF_SYM_TAG (val, spec->langsys_tag); 1690 OTF_SYM_TAG (val, spec->langsys_tag);
1715 otf_spec = XCDR (otf_spec); 1691 otf_spec = XCDR (otf_spec);
1716 } 1692 }
1717 spec->nfeatures[0] = spec->nfeatures[1] = 0; 1693 spec->nfeatures[0] = spec->nfeatures[1] = 0;
@@ -1721,31 +1697,31 @@ macfont_get_open_type_spec (Lisp_Object otf_spec)
1721 1697
1722 val = XCAR (otf_spec); 1698 val = XCAR (otf_spec);
1723 if (NILP (val)) 1699 if (NILP (val))
1724 continue; 1700 continue;
1725 len = Flength (val); 1701 len = Flength (val);
1726 spec->features[i] = 1702 spec->features[i] =
1727 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len) 1703 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len)
1728 ? 0 1704 ? 0
1729 : malloc (XINT (len) * sizeof *spec->features[i])); 1705 : malloc (XINT (len) * sizeof *spec->features[i]));
1730 if (! spec->features[i]) 1706 if (! spec->features[i])
1731 { 1707 {
1732 if (i > 0 && spec->features[0]) 1708 if (i > 0 && spec->features[0])
1733 free (spec->features[0]); 1709 free (spec->features[0]);
1734 free (spec); 1710 free (spec);
1735 return NULL; 1711 return NULL;
1736 } 1712 }
1737 for (j = 0, negative = 0; CONSP (val); val = XCDR (val)) 1713 for (j = 0, negative = 0; CONSP (val); val = XCDR (val))
1738 { 1714 {
1739 if (NILP (XCAR (val))) 1715 if (NILP (XCAR (val)))
1740 negative = 1; 1716 negative = 1;
1741 else 1717 else
1742 { 1718 {
1743 unsigned int tag; 1719 unsigned int tag;
1744 1720
1745 OTF_SYM_TAG (XCAR (val), tag); 1721 OTF_SYM_TAG (XCAR (val), tag);
1746 spec->features[i][j++] = negative ? tag & 0x80000000 : tag; 1722 spec->features[i][j++] = negative ? tag & 0x80000000 : tag;
1747 } 1723 }
1748 } 1724 }
1749 spec->nfeatures[i] = j; 1725 spec->nfeatures[i] = j;
1750 } 1726 }
1751 return spec; 1727 return spec;
@@ -1769,16 +1745,16 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1769 CGPoint points[6]; 1745 CGPoint points[6];
1770 } numeric_traits[] = 1746 } numeric_traits[] =
1771 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT, 1747 {{FONT_WEIGHT_INDEX, MAC_FONT_WEIGHT_TRAIT,
1772 {{-0.4, 50}, /* light */ 1748 {{-0.4, 50}, /* light */
1773 {-0.24, 87.5}, /* (semi-light + normal) / 2 */ 1749 {-0.24, 87.5}, /* (semi-light + normal) / 2 */
1774 {0, 100}, /* normal */ 1750 {0, 100}, /* normal */
1775 {0.24, 140}, /* (semi-bold + normal) / 2 */ 1751 {0.24, 140}, /* (semi-bold + normal) / 2 */
1776 {0.4, 200}, /* bold */ 1752 {0.4, 200}, /* bold */
1777 {CGFLOAT_MAX, CGFLOAT_MAX}}}, 1753 {CGFLOAT_MAX, CGFLOAT_MAX}}},
1778 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT, 1754 {FONT_SLANT_INDEX, MAC_FONT_SLANT_TRAIT,
1779 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}, 1755 {{0, 100}, {0.1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}},
1780 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT, 1756 {FONT_WIDTH_INDEX, MAC_FONT_WIDTH_TRAIT,
1781 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}}; 1757 {{0, 100}, {1, 200}, {CGFLOAT_MAX, CGFLOAT_MAX}}}};
1782 1758
1783 registry = AREF (spec, FONT_REGISTRY_INDEX); 1759 registry = AREF (spec, FONT_REGISTRY_INDEX);
1784 if (NILP (registry) 1760 if (NILP (registry)
@@ -1792,17 +1768,17 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1792 1768
1793 cf_charset_idx = macfont_get_charset (registry); 1769 cf_charset_idx = macfont_get_charset (registry);
1794 if (cf_charset_idx < 0) 1770 if (cf_charset_idx < 0)
1795 goto err; 1771 goto err;
1796 charset = cf_charset_table[cf_charset_idx].cf_charset; 1772 charset = cf_charset_table[cf_charset_idx].cf_charset;
1797 charset_string = cf_charset_table[cf_charset_idx].cf_charset_string; 1773 charset_string = cf_charset_table[cf_charset_idx].cf_charset_string;
1798 lang = cf_charset_table[cf_charset_idx].lang; 1774 lang = cf_charset_table[cf_charset_idx].lang;
1799 if (lang) 1775 if (lang)
1800 { 1776 {
1801 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks); 1777 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks);
1802 if (! langarray) 1778 if (! langarray)
1803 goto err; 1779 goto err;
1804 CFArrayAppendValue (langarray, lang); 1780 CFArrayAppendValue (langarray, lang);
1805 } 1781 }
1806 } 1782 }
1807 1783
1808 for (extra = AREF (spec, FONT_EXTRA_INDEX); 1784 for (extra = AREF (spec, FONT_EXTRA_INDEX);
@@ -1813,35 +1789,35 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1813 tmp = XCAR (extra); 1789 tmp = XCAR (extra);
1814 key = XCAR (tmp), val = XCDR (tmp); 1790 key = XCAR (tmp), val = XCDR (tmp);
1815 if (EQ (key, QClang)) 1791 if (EQ (key, QClang))
1816 { 1792 {
1817 if (! langarray) 1793 if (! langarray)
1818 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks); 1794 langarray = CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks);
1819 if (! langarray) 1795 if (! langarray)
1820 goto err; 1796 goto err;
1821 if (SYMBOLP (val)) 1797 if (SYMBOLP (val))
1822 val = list1 (val); 1798 val = list1 (val);
1823 for (; CONSP (val); val = XCDR (val)) 1799 for (; CONSP (val); val = XCDR (val))
1824 if (SYMBOLP (XCAR (val))) 1800 if (SYMBOLP (XCAR (val)))
1825 { 1801 {
1826 CFStringRef lang = 1802 CFStringRef lang =
1827 cfstring_create_with_string_noencode (SYMBOL_NAME 1803 cfstring_create_with_string_noencode (SYMBOL_NAME
1828 (XCAR (val))); 1804 (XCAR (val)));
1829 1805
1830 if (lang == NULL) 1806 if (lang == NULL)
1831 goto err; 1807 goto err;
1832 CFArrayAppendValue (langarray, lang); 1808 CFArrayAppendValue (langarray, lang);
1833 CFRelease (lang); 1809 CFRelease (lang);
1834 } 1810 }
1835 } 1811 }
1836 else if (EQ (key, QCotf)) 1812 else if (EQ (key, QCotf))
1837 { 1813 {
1838 otspec = macfont_get_open_type_spec (val); 1814 otspec = macfont_get_open_type_spec (val);
1839 if (! otspec) 1815 if (! otspec)
1840 goto err; 1816 goto err;
1841 script = otspec->script; 1817 script = otspec->script;
1842 } 1818 }
1843 else if (EQ (key, QCscript)) 1819 else if (EQ (key, QCscript))
1844 script = val; 1820 script = val;
1845 } 1821 }
1846 1822
1847 if (! NILP (script) && ! charset) 1823 if (! NILP (script) && ! charset)
@@ -1849,40 +1825,40 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1849 Lisp_Object chars = assq_no_quit (script, Vscript_representative_chars); 1825 Lisp_Object chars = assq_no_quit (script, Vscript_representative_chars);
1850 1826
1851 if (CONSP (chars) && CONSP (CDR (chars))) 1827 if (CONSP (chars) && CONSP (CDR (chars)))
1852 { 1828 {
1853 CFMutableStringRef string = CFStringCreateMutable (NULL, 0); 1829 CFMutableStringRef string = CFStringCreateMutable (NULL, 0);
1854 CFMutableCharacterSetRef cs = CFCharacterSetCreateMutable (NULL); 1830 CFMutableCharacterSetRef cs = CFCharacterSetCreateMutable (NULL);
1855 1831
1856 if (! string || !cs) 1832 if (! string || !cs)
1857 { 1833 {
1858 if (string) 1834 if (string)
1859 CFRelease (string); 1835 CFRelease (string);
1860 else if (cs) 1836 else if (cs)
1861 CFRelease (cs); 1837 CFRelease (cs);
1862 goto err; 1838 goto err;
1863 } 1839 }
1864 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) 1840 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars))
1865 if (CHARACTERP (XCAR (chars))) 1841 if (CHARACTERP (XCAR (chars)))
1866 { 1842 {
1867 UniChar unichars[2]; 1843 UniChar unichars[2];
1868 CFIndex count = 1844 CFIndex count =
1869 macfont_store_utf32char_to_unichars (XFASTINT (XCAR (chars)), 1845 macfont_store_utf32char_to_unichars (XFASTINT (XCAR (chars)),
1870 unichars); 1846 unichars);
1871 CFRange range = CFRangeMake (XFASTINT (XCAR (chars)), 1); 1847 CFRange range = CFRangeMake (XFASTINT (XCAR (chars)), 1);
1872 1848
1873 CFStringAppendCharacters (string, unichars, count); 1849 CFStringAppendCharacters (string, unichars, count);
1874 CFCharacterSetAddCharactersInRange (cs, range); 1850 CFCharacterSetAddCharactersInRange (cs, range);
1875 } 1851 }
1876 charset = cs; 1852 charset = cs;
1877 /* CFCharacterSetCreateWithCharactersInString does not 1853 /* CFCharacterSetCreateWithCharactersInString does not
1878 handle surrogate pairs properly as of Mac OS X 10.5. */ 1854 handle surrogate pairs properly as of Mac OS X 10.5. */
1879 charset_string = string; 1855 charset_string = string;
1880 } 1856 }
1881 } 1857 }
1882 1858
1883 attributes = CFDictionaryCreateMutable (NULL, 0, 1859 attributes = CFDictionaryCreateMutable (NULL, 0,
1884 &kCFTypeDictionaryKeyCallBacks, 1860 &kCFTypeDictionaryKeyCallBacks,
1885 &kCFTypeDictionaryValueCallBacks); 1861 &kCFTypeDictionaryValueCallBacks);
1886 if (! attributes) 1862 if (! attributes)
1887 goto err; 1863 goto err;
1888 1864
@@ -1892,15 +1868,15 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1892 CFStringRef family = macfont_create_family_with_symbol (tmp); 1868 CFStringRef family = macfont_create_family_with_symbol (tmp);
1893 1869
1894 if (! family) 1870 if (! family)
1895 goto err; 1871 goto err;
1896 CFDictionaryAddValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE, 1872 CFDictionaryAddValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE,
1897 family); 1873 family);
1898 CFRelease (family); 1874 CFRelease (family);
1899 } 1875 }
1900 1876
1901 traits = CFDictionaryCreateMutable (NULL, 4, 1877 traits = CFDictionaryCreateMutable (NULL, 4,
1902 &kCFTypeDictionaryKeyCallBacks, 1878 &kCFTypeDictionaryKeyCallBacks,
1903 &kCFTypeDictionaryValueCallBacks); 1879 &kCFTypeDictionaryValueCallBacks);
1904 if (! traits) 1880 if (! traits)
1905 goto err; 1881 goto err;
1906 1882
@@ -1908,40 +1884,40 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1908 { 1884 {
1909 tmp = AREF (spec, numeric_traits[i].index); 1885 tmp = AREF (spec, numeric_traits[i].index);
1910 if (INTEGERP (tmp)) 1886 if (INTEGERP (tmp))
1911 { 1887 {
1912 CGPoint *point = numeric_traits[i].points; 1888 CGPoint *point = numeric_traits[i].points;
1913 CGFloat floatval = (XINT (tmp) >> 8); // XXX 1889 CGFloat floatval = (XINT (tmp) >> 8); // XXX
1914 CFNumberRef num; 1890 CFNumberRef num;
1915 1891
1916 while (point->y < floatval) 1892 while (point->y < floatval)
1917 point++; 1893 point++;
1918 if (point == numeric_traits[i].points) 1894 if (point == numeric_traits[i].points)
1919 point++; 1895 point++;
1920 else if (point->y == CGFLOAT_MAX) 1896 else if (point->y == CGFLOAT_MAX)
1921 point--; 1897 point--;
1922 floatval = (point - 1)->x + ((floatval - (point - 1)->y) 1898 floatval = (point - 1)->x + ((floatval - (point - 1)->y)
1923 * ((point->x - (point - 1)->x) 1899 * ((point->x - (point - 1)->x)
1924 / (point->y - (point - 1)->y))); 1900 / (point->y - (point - 1)->y)));
1925 if (floatval > 1.0) 1901 if (floatval > 1.0)
1926 floatval = 1.0; 1902 floatval = 1.0;
1927 else if (floatval < -1.0) 1903 else if (floatval < -1.0)
1928 floatval = -1.0; 1904 floatval = -1.0;
1929 num = CFNumberCreate (NULL, kCFNumberCGFloatType, &floatval); 1905 num = CFNumberCreate (NULL, kCFNumberCGFloatType, &floatval);
1930 if (! num) 1906 if (! num)
1931 goto err; 1907 goto err;
1932 CFDictionaryAddValue (traits, numeric_traits[i].trait, num); 1908 CFDictionaryAddValue (traits, numeric_traits[i].trait, num);
1933 CFRelease (num); 1909 CFRelease (num);
1934 } 1910 }
1935 } 1911 }
1936 if (CFDictionaryGetCount (traits)) 1912 if (CFDictionaryGetCount (traits))
1937 CFDictionaryAddValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE, traits); 1913 CFDictionaryAddValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE, traits);
1938 1914
1939 if (charset) 1915 if (charset)
1940 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_ATTRIBUTE, 1916 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_ATTRIBUTE,
1941 charset); 1917 charset);
1942 if (charset_string) 1918 if (charset_string)
1943 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_STRING_ATTRIBUTE, 1919 CFDictionaryAddValue (attributes, MAC_FONT_CHARACTER_SET_STRING_ATTRIBUTE,
1944 charset_string); 1920 charset_string);
1945 if (langarray) 1921 if (langarray)
1946 CFDictionaryAddValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE, langarray); 1922 CFDictionaryAddValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE, langarray);
1947 1923
@@ -1962,9 +1938,9 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1962 if (otspec) 1938 if (otspec)
1963 { 1939 {
1964 if (otspec->nfeatures[0] > 0) 1940 if (otspec->nfeatures[0] > 0)
1965 free (otspec->features[0]); 1941 free (otspec->features[0]);
1966 if (otspec->nfeatures[1] > 0) 1942 if (otspec->nfeatures[1] > 0)
1967 free (otspec->features[1]); 1943 free (otspec->features[1]);
1968 free (otspec); 1944 free (otspec);
1969 } 1945 }
1970 1946
@@ -1973,38 +1949,38 @@ macfont_create_attributes_with_spec (Lisp_Object spec)
1973 1949
1974static Boolean 1950static Boolean
1975macfont_supports_charset_and_languages_p (FontDescriptorRef desc, 1951macfont_supports_charset_and_languages_p (FontDescriptorRef desc,
1976 CFCharacterSetRef charset, 1952 CFCharacterSetRef charset,
1977 Lisp_Object chars, 1953 Lisp_Object chars,
1978 CFArrayRef languages) 1954 CFArrayRef languages)
1979{ 1955{
1980 Boolean result = true; 1956 Boolean result = true;
1981 1957
1982 if (charset || VECTORP (chars)) 1958 if (charset || VECTORP (chars))
1983 { 1959 {
1984 CFCharacterSetRef desc_charset = 1960 CFCharacterSetRef desc_charset =
1985 mac_font_descriptor_copy_attribute (desc, 1961 mac_font_descriptor_copy_attribute (desc,
1986 MAC_FONT_CHARACTER_SET_ATTRIBUTE); 1962 MAC_FONT_CHARACTER_SET_ATTRIBUTE);
1987 1963
1988 if (desc_charset == NULL) 1964 if (desc_charset == NULL)
1989 result = false; 1965 result = false;
1990 else 1966 else
1991 { 1967 {
1992 if (charset) 1968 if (charset)
1993 result = CFCharacterSetIsSupersetOfSet (desc_charset, charset); 1969 result = CFCharacterSetIsSupersetOfSet (desc_charset, charset);
1994 else /* VECTORP (chars) */ 1970 else /* VECTORP (chars) */
1995 { 1971 {
1996 ptrdiff_t j; 1972 ptrdiff_t j;
1997 1973
1998 for (j = 0; j < ASIZE (chars); j++) 1974 for (j = 0; j < ASIZE (chars); j++)
1999 if (TYPE_RANGED_INTEGERP (UTF32Char, AREF (chars, j)) 1975 if (TYPE_RANGED_INTEGERP (UTF32Char, AREF (chars, j))
2000 && CFCharacterSetIsLongCharacterMember (desc_charset, 1976 && CFCharacterSetIsLongCharacterMember (desc_charset,
2001 XFASTINT (AREF (chars, j)))) 1977 XFASTINT (AREF (chars, j))))
2002 break; 1978 break;
2003 if (j == ASIZE (chars)) 1979 if (j == ASIZE (chars))
2004 result = false; 1980 result = false;
2005 } 1981 }
2006 CFRelease (desc_charset); 1982 CFRelease (desc_charset);
2007 } 1983 }
2008 } 1984 }
2009 if (result && languages) 1985 if (result && languages)
2010 result = mac_font_descriptor_supports_languages (desc, languages); 1986 result = mac_font_descriptor_supports_languages (desc, languages);
@@ -2012,38 +1988,49 @@ macfont_supports_charset_and_languages_p (FontDescriptorRef desc,
2012 return result; 1988 return result;
2013} 1989}
2014 1990
2015static CFIndex 1991static int
2016macfont_closest_traits_index (CFArrayRef traits_array, 1992macfont_traits_distance (FontSymbolicTraits sym_traits1,
2017 FontSymbolicTraits target) 1993 FontSymbolicTraits sym_traits2)
1994{
1995 FontSymbolicTraits diff = (sym_traits1 ^ sym_traits2);
1996 int distance = 0;
1997
1998 /* We prefer synthetic bold of italic to synthetic italic of bold
1999 when both bold and italic are available but bold-italic is not
2000 available. */
2001 if (diff & MAC_FONT_TRAIT_BOLD)
2002 distance |= (1 << 0);
2003 if (diff & MAC_FONT_TRAIT_ITALIC)
2004 distance |= (1 << 1);
2005 if (diff & MAC_FONT_TRAIT_MONO_SPACE)
2006 distance |= (1 << 2);
2007
2008 return distance;
2009}
2010
2011static Boolean
2012macfont_closest_traits_index_p (CFArrayRef traits_array,
2013 FontSymbolicTraits target,
2014 CFIndex index)
2018{ 2015{
2019 CFIndex i, result = -1, count = CFArrayGetCount (traits_array); 2016 CFIndex i, count = CFArrayGetCount (traits_array);
2020 int min_distance = (1 << 3); 2017 FontSymbolicTraits traits;
2018 int my_distance;
2019
2020 traits = ((FontSymbolicTraits) (uintptr_t)
2021 CFArrayGetValueAtIndex (traits_array, index));
2022 my_distance = macfont_traits_distance (target, traits);
2021 2023
2022 for (i = 0; i < count; i++) 2024 for (i = 0; i < count; i++)
2023 { 2025 if (i != index)
2024 FontSymbolicTraits traits, diff; 2026 {
2025 int distance = 0; 2027 traits = ((FontSymbolicTraits) (uintptr_t)
2026 2028 CFArrayGetValueAtIndex (traits_array, i));
2027 traits = ((FontSymbolicTraits) (uintptr_t) 2029 if (macfont_traits_distance (target, traits) < my_distance)
2028 CFArrayGetValueAtIndex (traits_array, i)); 2030 return false;
2029 diff = (target ^ traits); 2031 }
2030 /* We prefer synthetic bold of italic to synthetic italic of
2031 bold when both bold and italic are available but bold-italic
2032 is not available. */
2033 if (diff & MAC_FONT_TRAIT_BOLD)
2034 distance |= (1 << 0);
2035 if (diff & MAC_FONT_TRAIT_ITALIC)
2036 distance |= (1 << 1);
2037 if (diff & MAC_FONT_TRAIT_MONO_SPACE)
2038 distance |= (1 << 2);
2039 if (distance < min_distance)
2040 {
2041 min_distance = distance;
2042 result = i;
2043 }
2044 }
2045 2032
2046 return result; 2033 return true;
2047} 2034}
2048 2035
2049static Lisp_Object 2036static Lisp_Object
@@ -2068,7 +2055,7 @@ macfont_list (struct frame *f, Lisp_Object spec)
2068 { 2055 {
2069 family_name = macfont_create_family_with_symbol (family); 2056 family_name = macfont_create_family_with_symbol (family);
2070 if (family_name == NULL) 2057 if (family_name == NULL)
2071 goto finish; 2058 goto finish;
2072 } 2059 }
2073 2060
2074 attributes = macfont_create_attributes_with_spec (spec); 2061 attributes = macfont_create_attributes_with_spec (spec);
@@ -2081,14 +2068,14 @@ macfont_list (struct frame *f, Lisp_Object spec)
2081 spacing = XINT (AREF (spec, FONT_SPACING_INDEX)); 2068 spacing = XINT (AREF (spec, FONT_SPACING_INDEX));
2082 2069
2083 traits = ((CFMutableDictionaryRef) 2070 traits = ((CFMutableDictionaryRef)
2084 CFDictionaryGetValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE)); 2071 CFDictionaryGetValue (attributes, MAC_FONT_TRAITS_ATTRIBUTE));
2085 2072
2086 n = FONT_SLANT_NUMERIC (spec); 2073 n = FONT_SLANT_NUMERIC (spec);
2087 if (n < 0 || n == FONT_SLANT_SYNTHETIC_ITALIC) 2074 if (n < 0 || n == FONT_SLANT_SYNTHETIC_ITALIC)
2088 { 2075 {
2089 synth_sym_traits |= MAC_FONT_TRAIT_ITALIC; 2076 synth_sym_traits |= MAC_FONT_TRAIT_ITALIC;
2090 if (traits) 2077 if (traits)
2091 CFDictionaryRemoveValue (traits, MAC_FONT_SLANT_TRAIT); 2078 CFDictionaryRemoveValue (traits, MAC_FONT_SLANT_TRAIT);
2092 } 2079 }
2093 2080
2094 n = FONT_WEIGHT_NUMERIC (spec); 2081 n = FONT_WEIGHT_NUMERIC (spec);
@@ -2096,7 +2083,7 @@ macfont_list (struct frame *f, Lisp_Object spec)
2096 { 2083 {
2097 synth_sym_traits |= MAC_FONT_TRAIT_BOLD; 2084 synth_sym_traits |= MAC_FONT_TRAIT_BOLD;
2098 if (traits) 2085 if (traits)
2099 CFDictionaryRemoveValue (traits, MAC_FONT_WEIGHT_TRAIT); 2086 CFDictionaryRemoveValue (traits, MAC_FONT_WEIGHT_TRAIT);
2100 } 2087 }
2101 2088
2102 if (languages 2089 if (languages
@@ -2105,15 +2092,15 @@ macfont_list (struct frame *f, Lisp_Object spec)
2105 CFStringRef language = CFArrayGetValueAtIndex (languages, 0); 2092 CFStringRef language = CFArrayGetValueAtIndex (languages, 0);
2106 2093
2107 if (CFStringHasPrefix (language, CFSTR ("ja")) 2094 if (CFStringHasPrefix (language, CFSTR ("ja"))
2108 || CFStringHasPrefix (language, CFSTR ("ko")) 2095 || CFStringHasPrefix (language, CFSTR ("ko"))
2109 || CFStringHasPrefix (language, CFSTR ("zh"))) 2096 || CFStringHasPrefix (language, CFSTR ("zh")))
2110 synth_sym_traits |= MAC_FONT_TRAIT_MONO_SPACE; 2097 synth_sym_traits |= MAC_FONT_TRAIT_MONO_SPACE;
2111 } 2098 }
2112 2099
2113 /* Create array of families. */ 2100 /* Create array of families. */
2114 if (family_name) 2101 if (family_name)
2115 families = CFArrayCreate (NULL, (const void **) &family_name, 2102 families = CFArrayCreate (NULL, (const void **) &family_name,
2116 1, &kCFTypeArrayCallBacks); 2103 1, &kCFTypeArrayCallBacks);
2117 else 2104 else
2118 { 2105 {
2119 CFStringRef pref_family; 2106 CFStringRef pref_family;
@@ -2121,46 +2108,46 @@ macfont_list (struct frame *f, Lisp_Object spec)
2121 2108
2122 families = mac_font_create_available_families (); 2109 families = mac_font_create_available_families ();
2123 if (families == NULL) 2110 if (families == NULL)
2124 goto err; 2111 goto err;
2125 2112
2126 families_count = CFArrayGetCount (families); 2113 families_count = CFArrayGetCount (families);
2127 2114
2128 /* Move preferred family to the front if exists. */ 2115 /* Move preferred family to the front if exists. */
2129 pref_family = 2116 pref_family =
2130 mac_font_create_preferred_family_for_attributes (attributes); 2117 mac_font_create_preferred_family_for_attributes (attributes);
2131 if (pref_family) 2118 if (pref_family)
2132 { 2119 {
2133 pref_family_index = 2120 pref_family_index =
2134 CFArrayGetFirstIndexOfValue (families, 2121 CFArrayGetFirstIndexOfValue (families,
2135 CFRangeMake (0, families_count), 2122 CFRangeMake (0, families_count),
2136 pref_family); 2123 pref_family);
2137 CFRelease (pref_family); 2124 CFRelease (pref_family);
2138 } 2125 }
2139 if (pref_family_index > 0) 2126 if (pref_family_index > 0)
2140 { 2127 {
2141 CFMutableArrayRef mutable_families = 2128 CFMutableArrayRef mutable_families =
2142 CFArrayCreateMutable (NULL, families_count, &kCFTypeArrayCallBacks); 2129 CFArrayCreateMutable (NULL, families_count, &kCFTypeArrayCallBacks);
2143 2130
2144 if (mutable_families) 2131 if (mutable_families)
2145 { 2132 {
2146 CFArrayAppendValue (mutable_families, 2133 CFArrayAppendValue (mutable_families,
2147 CFArrayGetValueAtIndex (families, 2134 CFArrayGetValueAtIndex (families,
2148 pref_family_index)); 2135 pref_family_index));
2149 CFArrayAppendArray (mutable_families, families, 2136 CFArrayAppendArray (mutable_families, families,
2150 CFRangeMake (0, pref_family_index)); 2137 CFRangeMake (0, pref_family_index));
2151 if (pref_family_index + 1 < families_count) 2138 if (pref_family_index + 1 < families_count)
2152 CFArrayAppendArray (mutable_families, families, 2139 CFArrayAppendArray (mutable_families, families,
2153 CFRangeMake (pref_family_index + 1, 2140 CFRangeMake (pref_family_index + 1,
2154 families_count 2141 families_count
2155 - (pref_family_index + 1))); 2142 - (pref_family_index + 1)));
2156 CFRelease (families); 2143 CFRelease (families);
2157 families = mutable_families; 2144 families = mutable_families;
2158 } 2145 }
2159 } 2146 }
2160 } 2147 }
2161 2148
2162 charset = CFDictionaryGetValue (attributes, 2149 charset = CFDictionaryGetValue (attributes,
2163 MAC_FONT_CHARACTER_SET_ATTRIBUTE); 2150 MAC_FONT_CHARACTER_SET_ATTRIBUTE);
2164 if (charset) 2151 if (charset)
2165 { 2152 {
2166 CFRetain (charset); 2153 CFRetain (charset);
@@ -2170,11 +2157,11 @@ macfont_list (struct frame *f, Lisp_Object spec)
2170 { 2157 {
2171 val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX)); 2158 val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX));
2172 if (! NILP (val)) 2159 if (! NILP (val))
2173 { 2160 {
2174 val = assq_no_quit (XCDR (val), Vscript_representative_chars); 2161 val = assq_no_quit (XCDR (val), Vscript_representative_chars);
2175 if (CONSP (val) && VECTORP (XCDR (val))) 2162 if (CONSP (val) && VECTORP (XCDR (val)))
2176 chars = XCDR (val); 2163 chars = XCDR (val);
2177 } 2164 }
2178 val = Qnil; 2165 val = Qnil;
2179 } 2166 }
2180 2167
@@ -2198,151 +2185,152 @@ macfont_list (struct frame *f, Lisp_Object spec)
2198 int j; 2185 int j;
2199 2186
2200 CFDictionarySetValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE, 2187 CFDictionarySetValue (attributes, MAC_FONT_FAMILY_NAME_ATTRIBUTE,
2201 family_name); 2188 family_name);
2202 pat_desc = mac_font_descriptor_create_with_attributes (attributes); 2189 pat_desc = mac_font_descriptor_create_with_attributes (attributes);
2203 if (! pat_desc) 2190 if (! pat_desc)
2204 goto err; 2191 goto err;
2205 2192
2206 /* CTFontDescriptorCreateMatchingFontDescriptors on Mac OS X 2193 /* CTFontDescriptorCreateMatchingFontDescriptors on Mac OS X
2207 10.7 returns NULL if pat_desc represents the LastResort font. 2194 10.7 returns NULL if pat_desc represents the LastResort font.
2208 So we use CTFontDescriptorCreateMatchingFontDescriptor (no 2195 So we use CTFontDescriptorCreateMatchingFontDescriptor (no
2209 trailing "s") for such a font. */ 2196 trailing "s") for such a font. */
2210 if (!CFEqual (family_name, CFSTR ("LastResort"))) 2197 if (!CFEqual (family_name, CFSTR ("LastResort")))
2211 descs = mac_font_descriptor_create_matching_font_descriptors (pat_desc, 2198 descs = mac_font_descriptor_create_matching_font_descriptors (pat_desc,
2212 NULL); 2199 NULL);
2213 else 2200 else
2214 { 2201 {
2215 FontDescriptorRef lr_desc = 2202 FontDescriptorRef lr_desc =
2216 mac_font_descriptor_create_matching_font_descriptor (pat_desc, 2203 mac_font_descriptor_create_matching_font_descriptor (pat_desc,
2217 NULL); 2204 NULL);
2218 if (lr_desc) 2205 if (lr_desc)
2219 { 2206 {
2220 descs = CFArrayCreate (NULL, (const void **) &lr_desc, 1, 2207 descs = CFArrayCreate (NULL, (const void **) &lr_desc, 1,
2221 &kCFTypeArrayCallBacks); 2208 &kCFTypeArrayCallBacks);
2222 CFRelease (lr_desc); 2209 CFRelease (lr_desc);
2223 } 2210 }
2224 else 2211 else
2225 descs = NULL; 2212 descs = NULL;
2226 } 2213 }
2227 CFRelease (pat_desc); 2214 CFRelease (pat_desc);
2228 if (! descs) 2215 if (! descs)
2229 goto err; 2216 goto err;
2230 2217
2231 descs_count = CFArrayGetCount (descs); 2218 descs_count = CFArrayGetCount (descs);
2232 if (descs_count == 0 2219 if (descs_count == 0
2233 || !macfont_supports_charset_and_languages_p (CFArrayGetValueAtIndex (descs, 0), 2220 || !macfont_supports_charset_and_languages_p (CFArrayGetValueAtIndex (descs, 0),
2234 charset, chars, 2221 charset, chars,
2235 languages)) 2222 languages))
2236 { 2223 {
2237 CFRelease (descs); 2224 CFRelease (descs);
2238 continue; 2225 continue;
2239 } 2226 }
2240 2227
2241 filtered_descs = 2228 filtered_descs =
2242 CFArrayCreateMutable (NULL, descs_count, &kCFTypeArrayCallBacks); 2229 CFArrayCreateMutable (NULL, descs_count, &kCFTypeArrayCallBacks);
2243 traits_array = CFArrayCreateMutable (NULL, descs_count, NULL); 2230 traits_array = CFArrayCreateMutable (NULL, descs_count, NULL);
2244 for (j = 0; j < descs_count; j++) 2231 for (j = 0; j < descs_count; j++)
2245 { 2232 {
2246 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j); 2233 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j);
2247 CFDictionaryRef dict; 2234 CFDictionaryRef dict;
2248 CFNumberRef num; 2235 CFNumberRef num;
2249 FontSymbolicTraits sym_traits; 2236 FontSymbolicTraits sym_traits;
2250 2237
2251 dict = mac_font_descriptor_copy_attribute (desc, 2238 dict = mac_font_descriptor_copy_attribute (desc,
2252 MAC_FONT_TRAITS_ATTRIBUTE); 2239 MAC_FONT_TRAITS_ATTRIBUTE);
2253 if (dict == NULL) 2240 if (dict == NULL)
2254 continue; 2241 continue;
2255 2242
2256 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT); 2243 num = CFDictionaryGetValue (dict, MAC_FONT_SYMBOLIC_TRAIT);
2257 CFRelease (dict); 2244 CFRelease (dict);
2258 if (num == NULL 2245 if (num == NULL
2259 || !cfnumber_get_font_symbolic_traits_value (num, &sym_traits)) 2246 || !cfnumber_get_font_symbolic_traits_value (num, &sym_traits))
2260 continue; 2247 continue;
2261 2248
2262 if (spacing >= 0 2249 if (spacing >= 0
2263 && !(synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE) 2250 && !(synth_sym_traits & MAC_FONT_TRAIT_MONO_SPACE)
2264 && (((sym_traits & MAC_FONT_TRAIT_MONO_SPACE) != 0) 2251 && (((sym_traits & MAC_FONT_TRAIT_MONO_SPACE) != 0)
2265 != (spacing >= FONT_SPACING_MONO))) 2252 != (spacing >= FONT_SPACING_MONO)))
2266 continue; 2253 continue;
2267 2254
2268 /* Don't use a color bitmap font unless its family is 2255 /* Don't use a color bitmap font unless its family is
2269 explicitly specified. */ 2256 explicitly specified. */
2270 if ((sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS) && NILP (family)) 2257 if ((sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS) && NILP (family))
2271 continue; 2258 continue;
2272 2259
2273 if (j > 0 2260 if (j > 0
2274 && !macfont_supports_charset_and_languages_p (desc, charset, 2261 && !macfont_supports_charset_and_languages_p (desc, charset,
2275 chars, languages)) 2262 chars, languages))
2276 continue; 2263 continue;
2277 2264
2278 CFArrayAppendValue (filtered_descs, desc); 2265 CFArrayAppendValue (filtered_descs, desc);
2279 CFArrayAppendValue (traits_array, 2266 CFArrayAppendValue (traits_array,
2280 (const void *) (uintptr_t) sym_traits); 2267 (const void *) (uintptr_t) sym_traits);
2281 } 2268 }
2282 2269
2283 CFRelease (descs); 2270 CFRelease (descs);
2284 descs = filtered_descs; 2271 descs = filtered_descs;
2285 descs_count = CFArrayGetCount (descs); 2272 descs_count = CFArrayGetCount (descs);
2286 2273
2287 for (j = 0; j < descs_count; j++) 2274 for (j = 0; j < descs_count; j++)
2288 { 2275 {
2289 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j); 2276 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j);
2290 FontSymbolicTraits sym_traits = 2277 FontSymbolicTraits sym_traits =
2291 ((FontSymbolicTraits) (uintptr_t) 2278 ((FontSymbolicTraits) (uintptr_t)
2292 CFArrayGetValueAtIndex (traits_array, j)); 2279 CFArrayGetValueAtIndex (traits_array, j));
2293 FontSymbolicTraits mask_min, mask_max, imask, bmask, mmask; 2280 FontSymbolicTraits mask_min, mask_max, imask, bmask, mmask;
2294 2281
2295 mask_min = ((synth_sym_traits ^ sym_traits) 2282 mask_min = ((synth_sym_traits ^ sym_traits)
2296 & (MAC_FONT_TRAIT_ITALIC | MAC_FONT_TRAIT_BOLD)); 2283 & (MAC_FONT_TRAIT_ITALIC | MAC_FONT_TRAIT_BOLD));
2297 if (FONT_SLANT_NUMERIC (spec) < 0) 2284 if (FONT_SLANT_NUMERIC (spec) < 0)
2298 mask_min &= ~MAC_FONT_TRAIT_ITALIC; 2285 mask_min &= ~MAC_FONT_TRAIT_ITALIC;
2299 if (FONT_WEIGHT_NUMERIC (spec) < 0) 2286 if (FONT_WEIGHT_NUMERIC (spec) < 0)
2300 mask_min &= ~MAC_FONT_TRAIT_BOLD; 2287 mask_min &= ~MAC_FONT_TRAIT_BOLD;
2301 2288
2302 mask_max = (synth_sym_traits & ~sym_traits); 2289 mask_max = (synth_sym_traits & ~sym_traits);
2303 /* Synthetic bold does not work for bitmap-only fonts on Mac 2290 /* Synthetic bold does not work for bitmap-only fonts on Mac
2304 OS X 10.6. */ 2291 OS X 10.6. */
2305 if ((mask_min ^ mask_max) & MAC_FONT_TRAIT_BOLD) 2292 if ((mask_min ^ mask_max) & MAC_FONT_TRAIT_BOLD)
2306 { 2293 {
2307 CFNumberRef format = 2294 CFNumberRef format =
2308 mac_font_descriptor_copy_attribute (desc, 2295 mac_font_descriptor_copy_attribute (desc,
2309 MAC_FONT_FORMAT_ATTRIBUTE); 2296 MAC_FONT_FORMAT_ATTRIBUTE);
2310 2297
2311 if (format) 2298 if (format)
2312 { 2299 {
2313 uint32_t format_val; 2300 uint32_t format_val;
2314 2301
2315 if (CFNumberGetValue (format, kCFNumberSInt32Type, 2302 if (CFNumberGetValue (format, kCFNumberSInt32Type,
2316 &format_val) 2303 &format_val)
2317 && format_val == MAC_FONT_FORMAT_BITMAP) 2304 && format_val == MAC_FONT_FORMAT_BITMAP)
2318 mask_max &= ~MAC_FONT_TRAIT_BOLD; 2305 mask_max &= ~MAC_FONT_TRAIT_BOLD;
2319 } 2306 }
2320 } 2307 }
2321 if (spacing >= 0) 2308 if (spacing >= 0)
2322 mask_min |= (mask_max & MAC_FONT_TRAIT_MONO_SPACE); 2309 mask_min |= (mask_max & MAC_FONT_TRAIT_MONO_SPACE);
2323 2310
2324 for (mmask = (mask_min & MAC_FONT_TRAIT_MONO_SPACE); 2311 for (mmask = (mask_min & MAC_FONT_TRAIT_MONO_SPACE);
2325 mmask <= (mask_max & MAC_FONT_TRAIT_MONO_SPACE); 2312 mmask <= (mask_max & MAC_FONT_TRAIT_MONO_SPACE);
2326 mmask += MAC_FONT_TRAIT_MONO_SPACE) 2313 mmask += MAC_FONT_TRAIT_MONO_SPACE)
2327 for (bmask = (mask_min & MAC_FONT_TRAIT_BOLD); 2314 for (bmask = (mask_min & MAC_FONT_TRAIT_BOLD);
2328 bmask <= (mask_max & MAC_FONT_TRAIT_BOLD); 2315 bmask <= (mask_max & MAC_FONT_TRAIT_BOLD);
2329 bmask += MAC_FONT_TRAIT_BOLD) 2316 bmask += MAC_FONT_TRAIT_BOLD)
2330 for (imask = (mask_min & MAC_FONT_TRAIT_ITALIC); 2317 for (imask = (mask_min & MAC_FONT_TRAIT_ITALIC);
2331 imask <= (mask_max & MAC_FONT_TRAIT_ITALIC); 2318 imask <= (mask_max & MAC_FONT_TRAIT_ITALIC);
2332 imask += MAC_FONT_TRAIT_ITALIC) 2319 imask += MAC_FONT_TRAIT_ITALIC)
2333 { 2320 {
2334 FontSymbolicTraits synth = (imask | bmask | mmask); 2321 FontSymbolicTraits synth = (imask | bmask | mmask);
2335 2322
2336 if (synth == 0 2323 if (synth == 0
2337 || j == macfont_closest_traits_index (traits_array, 2324 || macfont_closest_traits_index_p (traits_array,
2338 (sym_traits | synth))) 2325 (sym_traits | synth),
2339 { 2326 j))
2340 entity = macfont_descriptor_entity (desc, extra, synth); 2327 {
2341 if (! NILP (entity)) 2328 entity = macfont_descriptor_entity (desc, extra, synth);
2342 val = Fcons (entity, val); 2329 if (! NILP (entity))
2343 } 2330 val = Fcons (entity, val);
2344 } 2331 }
2345 } 2332 }
2333 }
2346 2334
2347 CFRelease (traits_array); 2335 CFRelease (traits_array);
2348 CFRelease (descs); 2336 CFRelease (descs);
@@ -2384,13 +2372,13 @@ macfont_match (struct frame * frame, Lisp_Object spec)
2384 if (pat_desc) 2372 if (pat_desc)
2385 { 2373 {
2386 desc = mac_font_descriptor_create_matching_font_descriptor (pat_desc, 2374 desc = mac_font_descriptor_create_matching_font_descriptor (pat_desc,
2387 NULL); 2375 NULL);
2388 CFRelease (pat_desc); 2376 CFRelease (pat_desc);
2389 } 2377 }
2390 if (desc) 2378 if (desc)
2391 { 2379 {
2392 entity = macfont_descriptor_entity (desc, AREF (spec, FONT_EXTRA_INDEX), 2380 entity = macfont_descriptor_entity (desc, AREF (spec, FONT_EXTRA_INDEX),
2393 0); 2381 0);
2394 CFRelease (desc); 2382 CFRelease (desc);
2395 } 2383 }
2396 unblock_input (); 2384 unblock_input ();
@@ -2413,7 +2401,7 @@ macfont_list_family (struct frame *frame)
2413 CFIndex i, count = CFArrayGetCount (families); 2401 CFIndex i, count = CFArrayGetCount (families);
2414 2402
2415 for (i = 0; i < count; i++) 2403 for (i = 0; i < count; i++)
2416 list = Fcons (macfont_intern_prop_cfstring (CFArrayGetValueAtIndex (families, i)), list); 2404 list = Fcons (macfont_intern_prop_cfstring (CFArrayGetValueAtIndex (families, i)), list);
2417 CFRelease (families); 2405 CFRelease (families);
2418 } 2406 }
2419 2407
@@ -2426,7 +2414,7 @@ static void
2426macfont_free_entity (Lisp_Object entity) 2414macfont_free_entity (Lisp_Object entity)
2427{ 2415{
2428 Lisp_Object val = assq_no_quit (QCfont_entity, 2416 Lisp_Object val = assq_no_quit (QCfont_entity,
2429 AREF (entity, FONT_EXTRA_INDEX)); 2417 AREF (entity, FONT_EXTRA_INDEX));
2430 CFStringRef name = XSAVE_POINTER (XCDR (val), 0); 2418 CFStringRef name = XSAVE_POINTER (XCDR (val), 0);
2431 2419
2432 block_input (); 2420 block_input ();
@@ -2444,7 +2432,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2444 int size; 2432 int size;
2445 FontRef macfont; 2433 FontRef macfont;
2446 FontSymbolicTraits sym_traits; 2434 FontSymbolicTraits sym_traits;
2447 int i, total_width; 2435 char name[256];
2436 int len, i, total_width;
2448 CGGlyph glyph; 2437 CGGlyph glyph;
2449 CGFloat ascent, descent, leading; 2438 CGFloat ascent, descent, leading;
2450 2439
@@ -2472,7 +2461,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2472 return Qnil; 2461 return Qnil;
2473 2462
2474 font_object = font_build_object (VECSIZE (struct macfont_info), 2463 font_object = font_build_object (VECSIZE (struct macfont_info),
2475 Qmac_ct, entity, size); 2464 Qmac_ct, entity, size);
2476 font = XFONT_OBJECT (font_object); 2465 font = XFONT_OBJECT (font_object);
2477 font->pixel_size = size; 2466 font->pixel_size = size;
2478 font->driver = &macfont_driver; 2467 font->driver = &macfont_driver;
@@ -2487,7 +2476,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2487 val = assq_no_quit (QCdestination, AREF (entity, FONT_EXTRA_INDEX)); 2476 val = assq_no_quit (QCdestination, AREF (entity, FONT_EXTRA_INDEX));
2488 if (CONSP (val) && EQ (XCDR (val), make_number (1))) 2477 if (CONSP (val) && EQ (XCDR (val), make_number (1)))
2489 macfont_info->screen_font = mac_screen_font_create_with_name (font_name, 2478 macfont_info->screen_font = mac_screen_font_create_with_name (font_name,
2490 size); 2479 size);
2491 else 2480 else
2492 macfont_info->screen_font = NULL; 2481 macfont_info->screen_font = NULL;
2493 macfont_info->cache = macfont_lookup_cache (font_name); 2482 macfont_info->cache = macfont_lookup_cache (font_name);
@@ -2507,8 +2496,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2507 if (sym_traits & MAC_FONT_TRAIT_MONO_SPACE) 2496 if (sym_traits & MAC_FONT_TRAIT_MONO_SPACE)
2508 macfont_info->spacing = MACFONT_SPACING_MONO; 2497 macfont_info->spacing = MACFONT_SPACING_MONO;
2509 else if (INTEGERP (AREF (entity, FONT_SPACING_INDEX)) 2498 else if (INTEGERP (AREF (entity, FONT_SPACING_INDEX))
2510 && (XINT (AREF (entity, FONT_SPACING_INDEX)) 2499 && (XINT (AREF (entity, FONT_SPACING_INDEX))
2511 == FONT_SPACING_SYNTHETIC_MONO)) 2500 == FONT_SPACING_SYNTHETIC_MONO))
2512 macfont_info->spacing = MACFONT_SPACING_SYNTHETIC_MONO; 2501 macfont_info->spacing = MACFONT_SPACING_SYNTHETIC_MONO;
2513 if (macfont_info->synthetic_italic_p || macfont_info->synthetic_bold_p) 2502 if (macfont_info->synthetic_italic_p || macfont_info->synthetic_bold_p)
2514 macfont_info->antialias = MACFONT_ANTIALIAS_ON; 2503 macfont_info->antialias = MACFONT_ANTIALIAS_ON;
@@ -2516,8 +2505,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2516 { 2505 {
2517 val = assq_no_quit (QCantialias, AREF (entity, FONT_EXTRA_INDEX)); 2506 val = assq_no_quit (QCantialias, AREF (entity, FONT_EXTRA_INDEX));
2518 if (CONSP (val)) 2507 if (CONSP (val))
2519 macfont_info->antialias = 2508 macfont_info->antialias =
2520 NILP (XCDR (val)) ? MACFONT_ANTIALIAS_OFF : MACFONT_ANTIALIAS_ON; 2509 NILP (XCDR (val)) ? MACFONT_ANTIALIAS_OFF : MACFONT_ANTIALIAS_ON;
2521 } 2510 }
2522 macfont_info->color_bitmap_p = 0; 2511 macfont_info->color_bitmap_p = 0;
2523 if (sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS) 2512 if (sym_traits & MAC_FONT_TRAIT_COLOR_GLYPHS)
@@ -2535,7 +2524,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2535 { 2524 {
2536 glyph = macfont_get_glyph_for_character (font, ' ' + i); 2525 glyph = macfont_get_glyph_for_character (font, ' ' + i);
2537 if (glyph == kCGFontIndexInvalid) 2526 if (glyph == kCGFontIndexInvalid)
2538 break; 2527 break;
2539 total_width += macfont_glyph_extents (font, glyph, NULL, NULL, 0); 2528 total_width += macfont_glyph_extents (font, glyph, NULL, NULL, 0);
2540 } 2529 }
2541 if (i == 95) 2530 if (i == 95)
@@ -2544,8 +2533,8 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2544 font->average_width = font->space_width; /* XXX */ 2533 font->average_width = font->space_width; /* XXX */
2545 2534
2546 if (!(macfont_info->screen_font 2535 if (!(macfont_info->screen_font
2547 && mac_screen_font_get_metrics (macfont_info->screen_font, 2536 && mac_screen_font_get_metrics (macfont_info->screen_font,
2548 &ascent, &descent, &leading))) 2537 &ascent, &descent, &leading)))
2549 { 2538 {
2550 CFStringRef family_name; 2539 CFStringRef family_name;
2551 2540
@@ -2553,21 +2542,21 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
2553 descent = mac_font_get_descent (macfont); 2542 descent = mac_font_get_descent (macfont);
2554 leading = mac_font_get_leading (macfont); 2543 leading = mac_font_get_leading (macfont);
2555 /* AppKit and WebKit do some adjustment to the heights of 2544 /* AppKit and WebKit do some adjustment to the heights of
2556 Courier, Helvetica, and Times. */ 2545 Courier, Helvetica, and Times. */
2557 family_name = mac_font_copy_family_name (macfont); 2546 family_name = mac_font_copy_family_name (macfont);
2558 if (family_name) 2547 if (family_name)
2559 { 2548 {
2560 if (CFEqual (family_name, CFSTR ("Courier")) 2549 if (CFEqual (family_name, CFSTR ("Courier"))
2561 || CFEqual (family_name, CFSTR ("Helvetica")) 2550 || CFEqual (family_name, CFSTR ("Helvetica"))
2562 || CFEqual (family_name, CFSTR ("Times"))) 2551 || CFEqual (family_name, CFSTR ("Times")))
2563 ascent += (ascent + descent) * .15f; 2552 ascent += (ascent + descent) * .15f;
2564 else if (CFStringHasPrefix (family_name, CFSTR ("Hiragino"))) 2553 else if (CFStringHasPrefix (family_name, CFSTR ("Hiragino")))
2565 { 2554 {
2566 leading *= .25f; 2555 leading *= .25f;
2567 ascent += leading; 2556 ascent += leading;
2568 } 2557 }
2569 CFRelease (family_name); 2558 CFRelease (family_name);
2570 } 2559 }
2571 } 2560 }
2572 font->ascent = ascent + 0.5f; 2561 font->ascent = ascent + 0.5f;
2573 val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX)); 2562 val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));
@@ -2598,20 +2587,25 @@ static void
2598macfont_close (struct font *font) 2587macfont_close (struct font *font)
2599{ 2588{
2600 struct macfont_info *macfont_info = (struct macfont_info *) font; 2589 struct macfont_info *macfont_info = (struct macfont_info *) font;
2601 int i;
2602 2590
2603 block_input (); 2591 if (macfont_info->cache)
2604 CFRelease (macfont_info->macfont); 2592 {
2605 CGFontRelease (macfont_info->cgfont); 2593 int i;
2606 if (macfont_info->screen_font) 2594
2607 CFRelease (macfont_info->screen_font); 2595 block_input ();
2608 macfont_release_cache (macfont_info->cache); 2596 CFRelease (macfont_info->macfont);
2609 for (i = 0; i < macfont_info->metrics_nrows; i++) 2597 CGFontRelease (macfont_info->cgfont);
2610 if (macfont_info->metrics[i]) 2598 if (macfont_info->screen_font)
2611 xfree (macfont_info->metrics[i]); 2599 CFRelease (macfont_info->screen_font);
2612 if (macfont_info->metrics) 2600 macfont_release_cache (macfont_info->cache);
2613 xfree (macfont_info->metrics); 2601 for (i = 0; i < macfont_info->metrics_nrows; i++)
2614 unblock_input (); 2602 if (macfont_info->metrics[i])
2603 xfree (macfont_info->metrics[i]);
2604 if (macfont_info->metrics)
2605 xfree (macfont_info->metrics);
2606 macfont_info->cache = NULL;
2607 unblock_input ();
2608 }
2615} 2609}
2616 2610
2617static int 2611static int
@@ -2653,9 +2647,9 @@ macfont_encode_char (struct font *font, int c)
2653 return glyph != kCGFontIndexInvalid ? glyph : FONT_INVALID_CODE; 2647 return glyph != kCGFontIndexInvalid ? glyph : FONT_INVALID_CODE;
2654} 2648}
2655 2649
2656static int 2650static void
2657macfont_text_extents (struct font *font, unsigned int *code, int nglyphs, 2651macfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
2658 struct font_metrics *metrics) 2652 struct font_metrics *metrics)
2659{ 2653{
2660 int width, i; 2654 int width, i;
2661 2655
@@ -2665,32 +2659,30 @@ macfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
2665 { 2659 {
2666 struct font_metrics m; 2660 struct font_metrics m;
2667 int w = macfont_glyph_extents (font, code[i], metrics ? &m : NULL, 2661 int w = macfont_glyph_extents (font, code[i], metrics ? &m : NULL,
2668 NULL, 0); 2662 NULL, 0);
2669 2663
2670 if (metrics) 2664 if (metrics)
2671 { 2665 {
2672 if (width + m.lbearing < metrics->lbearing) 2666 if (width + m.lbearing < metrics->lbearing)
2673 metrics->lbearing = width + m.lbearing; 2667 metrics->lbearing = width + m.lbearing;
2674 if (width + m.rbearing > metrics->rbearing) 2668 if (width + m.rbearing > metrics->rbearing)
2675 metrics->rbearing = width + m.rbearing; 2669 metrics->rbearing = width + m.rbearing;
2676 if (m.ascent > metrics->ascent) 2670 if (m.ascent > metrics->ascent)
2677 metrics->ascent = m.ascent; 2671 metrics->ascent = m.ascent;
2678 if (m.descent > metrics->descent) 2672 if (m.descent > metrics->descent)
2679 metrics->descent = m.descent; 2673 metrics->descent = m.descent;
2680 } 2674 }
2681 width += w; 2675 width += w;
2682 } 2676 }
2683 unblock_input (); 2677 unblock_input ();
2684 2678
2685 if (metrics) 2679 if (metrics)
2686 metrics->width = width; 2680 metrics->width = width;
2687
2688 return width;
2689} 2681}
2690 2682
2691static int 2683static int
2692macfont_draw (struct glyph_string *s, int from, int to, int x, int y, 2684macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2693 bool with_background) 2685 bool with_background)
2694{ 2686{
2695 struct frame * f = s->f; 2687 struct frame * f = s->f;
2696 struct macfont_info *macfont_info = (struct macfont_info *) s->font; 2688 struct macfont_info *macfont_info = (struct macfont_info *) s->font;
@@ -2702,7 +2694,7 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2702 bool no_antialias_p = 2694 bool no_antialias_p =
2703 (macfont_info->antialias == MACFONT_ANTIALIAS_OFF 2695 (macfont_info->antialias == MACFONT_ANTIALIAS_OFF
2704 || (macfont_info->antialias == MACFONT_ANTIALIAS_DEFAULT 2696 || (macfont_info->antialias == MACFONT_ANTIALIAS_DEFAULT
2705 && font_size <= macfont_antialias_threshold)); 2697 && font_size <= macfont_antialias_threshold));
2706 int len = to - from; 2698 int len = to - from;
2707 struct face *face = s->face; 2699 struct face *face = s->face;
2708 CGContextRef context; 2700 CGContextRef context;
@@ -2712,29 +2704,29 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2712 if (with_background) 2704 if (with_background)
2713 background_rect = CGRectMake (x, y - FONT_BASE (s->font), 2705 background_rect = CGRectMake (x, y - FONT_BASE (s->font),
2714 s->width, FONT_HEIGHT (s->font)); 2706 s->width, FONT_HEIGHT (s->font));
2715 else 2707 else
2716 background_rect = CGRectNull; 2708 background_rect = CGRectNull;
2717 2709
2718 text_position = CGPointMake (x, -y); 2710 text_position = CGPointMake (x, -y);
2719 glyphs = xmalloc (sizeof (CGGlyph) * len); 2711 glyphs = xmalloc (sizeof (CGGlyph) * len);
2720 { 2712 {
2721 CGFloat advance_delta; 2713 CGFloat advance_delta = 0;
2722 int i; 2714 int i;
2723 CGFloat total_width = 0; 2715 CGFloat total_width = 0;
2724 2716
2725 positions = xmalloc (sizeof (CGPoint) * len); 2717 positions = xmalloc (sizeof (CGPoint) * len);
2726 for (i = 0; i < len; i++) 2718 for (i = 0; i < len; i++)
2727 { 2719 {
2728 int width; 2720 int width;
2729 2721
2730 glyphs[i] = s->char2b[from + i]; 2722 glyphs[i] = s->char2b[from + i];
2731 width = (s->padding_p ? 1 2723 width = (s->padding_p ? 1
2732 : macfont_glyph_extents (s->font, glyphs[i], 2724 : macfont_glyph_extents (s->font, glyphs[i],
2733 NULL, &advance_delta, 2725 NULL, &advance_delta,
2734 no_antialias_p)); 2726 no_antialias_p));
2735 positions[i].x = total_width + advance_delta; 2727 positions[i].x = total_width + advance_delta;
2736 positions[i].y = 0; 2728 positions[i].y = 0;
2737 total_width += width; 2729 total_width += width;
2738 } 2730 }
2739 } 2731 }
2740 2732
@@ -2743,7 +2735,7 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2743 2735
2744 if (!CGRectIsNull (background_rect)) 2736 if (!CGRectIsNull (background_rect))
2745 { 2737 {
2746 if (s->hl == DRAW_MOUSE_FACE) 2738 if (s->hl == DRAW_MOUSE_FACE)
2747 { 2739 {
2748 face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); 2740 face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
2749 if (!face) 2741 if (!face)
@@ -2756,20 +2748,21 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2756 if (macfont_info->cgfont) 2748 if (macfont_info->cgfont)
2757 { 2749 {
2758 CGAffineTransform atfm; 2750 CGAffineTransform atfm;
2751
2759 CGContextScaleCTM (context, 1, -1); 2752 CGContextScaleCTM (context, 1, -1);
2760 CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f); 2753 CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face, s->f);
2761 if (macfont_info->synthetic_italic_p) 2754 if (macfont_info->synthetic_italic_p)
2762 atfm = synthetic_italic_atfm; 2755 atfm = synthetic_italic_atfm;
2763 else 2756 else
2764 atfm = CGAffineTransformIdentity; 2757 atfm = CGAffineTransformIdentity;
2765 if (macfont_info->synthetic_bold_p) 2758 if (macfont_info->synthetic_bold_p)
2766 { 2759 {
2767 CGContextSetTextDrawingMode (context, kCGTextFillStroke); 2760 CGContextSetTextDrawingMode (context, kCGTextFillStroke);
2768 CGContextSetLineWidth (context, synthetic_bold_factor * font_size); 2761 CGContextSetLineWidth (context, synthetic_bold_factor * font_size);
2769 CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND (context, face, f); 2762 CG_SET_STROKE_COLOR_WITH_FACE_FOREGROUND (context, face, f);
2770 } 2763 }
2771 if (no_antialias_p) 2764 if (no_antialias_p)
2772 CGContextSetShouldAntialias (context, false); 2765 CGContextSetShouldAntialias (context, false);
2773 2766
2774 CGContextSetTextMatrix (context, atfm); 2767 CGContextSetTextMatrix (context, atfm);
2775 CGContextSetTextPosition (context, text_position.x, text_position.y); 2768 CGContextSetTextPosition (context, text_position.x, text_position.y);
@@ -2777,23 +2770,23 @@ macfont_draw (struct glyph_string *s, int from, int to, int x, int y,
2777#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 2770#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
2778 if (macfont_info->color_bitmap_p 2771 if (macfont_info->color_bitmap_p
2779#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 2772#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
2780 && CTFontDrawGlyphs != NULL 2773 && CTFontDrawGlyphs != NULL
2781#endif 2774#endif
2782 ) 2775 )
2783 { 2776 {
2784 if (len > 0) 2777 if (len > 0)
2785 { 2778 {
2786 CTFontDrawGlyphs (macfont_info->macfont, glyphs, positions, len, 2779 CTFontDrawGlyphs (macfont_info->macfont, glyphs, positions, len,
2787 context); 2780 context);
2788 } 2781 }
2789 } 2782 }
2790 else 2783 else
2791#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */ 2784#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
2792 { 2785 {
2793 CGContextSetFont (context, macfont_info->cgfont); 2786 CGContextSetFont (context, macfont_info->cgfont);
2794 CGContextSetFontSize (context, font_size); 2787 CGContextSetFontSize (context, font_size);
2795 CGContextShowGlyphsAtPositions (context, glyphs, positions, len); 2788 CGContextShowGlyphsAtPositions (context, glyphs, positions, len);
2796 } 2789 }
2797 } 2790 }
2798 2791
2799 2792
@@ -2831,9 +2824,9 @@ macfont_shape (Lisp_Object lgstring)
2831 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i); 2824 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
2832 2825
2833 if (NILP (lglyph)) 2826 if (NILP (lglyph))
2834 break; 2827 break;
2835 if (LGLYPH_CHAR (lglyph) >= 0x10000) 2828 if (LGLYPH_CHAR (lglyph) >= 0x10000)
2836 nonbmp_len++; 2829 nonbmp_len++;
2837 } 2830 }
2838 2831
2839 len = i; 2832 len = i;
@@ -2848,25 +2841,25 @@ macfont_shape (Lisp_Object lgstring)
2848 UTF32Char c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i)); 2841 UTF32Char c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i));
2849 2842
2850 if (macfont_store_utf32char_to_unichars (c, unichars + i + j) > 1) 2843 if (macfont_store_utf32char_to_unichars (c, unichars + i + j) > 1)
2851 { 2844 {
2852 nonbmp_indices[j] = i + j; 2845 nonbmp_indices[j] = i + j;
2853 j++; 2846 j++;
2854 } 2847 }
2855 } 2848 }
2856 nonbmp_indices[j] = len + j; /* sentinel */ 2849 nonbmp_indices[j] = len + j; /* sentinel */
2857 2850
2858 block_input (); 2851 block_input ();
2859 2852
2860 string = CFStringCreateWithCharactersNoCopy (NULL, unichars, len + nonbmp_len, 2853 string = CFStringCreateWithCharactersNoCopy (NULL, unichars, len + nonbmp_len,
2861 kCFAllocatorNull); 2854 kCFAllocatorNull);
2862 if (string) 2855 if (string)
2863 { 2856 {
2864 glyph_layouts = alloca (sizeof (struct mac_glyph_layout) * glyph_len); 2857 glyph_layouts = alloca (sizeof (struct mac_glyph_layout) * glyph_len);
2865 if (macfont_info->screen_font) 2858 if (macfont_info->screen_font)
2866 used = mac_screen_font_shape (macfont_info->screen_font, string, 2859 used = mac_screen_font_shape (macfont_info->screen_font, string,
2867 glyph_layouts, glyph_len); 2860 glyph_layouts, glyph_len);
2868 else 2861 else
2869 used = mac_font_shape (macfont, string, glyph_layouts, glyph_len); 2862 used = mac_font_shape (macfont, string, glyph_layouts, glyph_len);
2870 CFRelease (string); 2863 CFRelease (string);
2871 } 2864 }
2872 2865
@@ -2886,40 +2879,40 @@ macfont_shape (Lisp_Object lgstring)
2886 int xoff, yoff, wadjust; 2879 int xoff, yoff, wadjust;
2887 2880
2888 if (NILP (lglyph)) 2881 if (NILP (lglyph))
2889 { 2882 {
2890 lglyph = Fmake_vector (make_number (LGLYPH_SIZE), Qnil); 2883 lglyph = Fmake_vector (make_number (LGLYPH_SIZE), Qnil);
2891 LGSTRING_SET_GLYPH (lgstring, i, lglyph); 2884 LGSTRING_SET_GLYPH (lgstring, i, lglyph);
2892 } 2885 }
2893 2886
2894 from = gl->comp_range.location; 2887 from = gl->comp_range.location;
2895 /* Convert UTF-16 index to UTF-32. */ 2888 /* Convert UTF-16 index to UTF-32. */
2896 j = 0; 2889 j = 0;
2897 while (nonbmp_indices[j] < from) 2890 while (nonbmp_indices[j] < from)
2898 j++; 2891 j++;
2899 from -= j; 2892 from -= j;
2900 LGLYPH_SET_FROM (lglyph, from); 2893 LGLYPH_SET_FROM (lglyph, from);
2901 2894
2902 to = gl->comp_range.location + gl->comp_range.length; 2895 to = gl->comp_range.location + gl->comp_range.length;
2903 /* Convert UTF-16 index to UTF-32. */ 2896 /* Convert UTF-16 index to UTF-32. */
2904 while (nonbmp_indices[j] < to) 2897 while (nonbmp_indices[j] < to)
2905 j++; 2898 j++;
2906 to -= j; 2899 to -= j;
2907 LGLYPH_SET_TO (lglyph, to - 1); 2900 LGLYPH_SET_TO (lglyph, to - 1);
2908 2901
2909 /* LGLYPH_CHAR is used in `describe-char' for checking whether 2902 /* LGLYPH_CHAR is used in `describe-char' for checking whether
2910 the composition is trivial. */ 2903 the composition is trivial. */
2911 { 2904 {
2912 UTF32Char c; 2905 UTF32Char c;
2913 2906
2914 if (unichars[gl->string_index] >= 0xD800 2907 if (unichars[gl->string_index] >= 0xD800
2915 && unichars[gl->string_index] < 0xDC00) 2908 && unichars[gl->string_index] < 0xDC00)
2916 c = (((unichars[gl->string_index] - 0xD800) << 10) 2909 c = (((unichars[gl->string_index] - 0xD800) << 10)
2917 + (unichars[gl->string_index + 1] - 0xDC00) + 0x10000); 2910 + (unichars[gl->string_index + 1] - 0xDC00) + 0x10000);
2918 else 2911 else
2919 c = unichars[gl->string_index]; 2912 c = unichars[gl->string_index];
2920 if (macfont_get_glyph_for_character (font, c) != gl->glyph_id) 2913 if (macfont_get_glyph_for_character (font, c) != gl->glyph_id)
2921 c = 0; 2914 c = 0;
2922 LGLYPH_SET_CHAR (lglyph, c); 2915 LGLYPH_SET_CHAR (lglyph, c);
2923 } 2916 }
2924 2917
2925 { 2918 {
@@ -2938,15 +2931,15 @@ macfont_shape (Lisp_Object lgstring)
2938 yoff = lround (- gl->baseline_delta); 2931 yoff = lround (- gl->baseline_delta);
2939 wadjust = lround (gl->advance); 2932 wadjust = lround (gl->advance);
2940 if (xoff != 0 || yoff != 0 || wadjust != metrics.width) 2933 if (xoff != 0 || yoff != 0 || wadjust != metrics.width)
2941 { 2934 {
2942 Lisp_Object vec; 2935 Lisp_Object vec;
2943 2936
2944 vec = Fmake_vector (make_number (3), Qnil); 2937 vec = Fmake_vector (make_number (3), Qnil);
2945 ASET (vec, 0, make_number (xoff)); 2938 ASET (vec, 0, make_number (xoff));
2946 ASET (vec, 1, make_number (yoff)); 2939 ASET (vec, 1, make_number (yoff));
2947 ASET (vec, 2, make_number (wadjust)); 2940 ASET (vec, 2, make_number (wadjust));
2948 LGLYPH_SET_ADJUSTMENT (lglyph, vec); 2941 LGLYPH_SET_ADJUSTMENT (lglyph, vec);
2949 } 2942 }
2950 } 2943 }
2951 2944
2952 unblock_input (); 2945 unblock_input ();
@@ -2969,7 +2962,7 @@ struct uvs_table
2969 UInt32 length, num_var_selector_records; 2962 UInt32 length, num_var_selector_records;
2970 struct variation_selector_record variation_selector_records[1]; 2963 struct variation_selector_record variation_selector_records[1];
2971}; 2964};
2972#define SIZEOF_UVS_TABLE_HEADER \ 2965#define SIZEOF_UVS_TABLE_HEADER \
2973 (sizeof (struct uvs_table) - sizeof (struct variation_selector_record)) 2966 (sizeof (struct uvs_table) - sizeof (struct variation_selector_record))
2974 2967
2975struct unicode_value_range 2968struct unicode_value_range
@@ -2981,7 +2974,7 @@ struct default_uvs_table {
2981 UInt32 num_unicode_value_ranges; 2974 UInt32 num_unicode_value_ranges;
2982 struct unicode_value_range unicode_value_ranges[1]; 2975 struct unicode_value_range unicode_value_ranges[1];
2983}; 2976};
2984#define SIZEOF_DEFAULT_UVS_TABLE_HEADER \ 2977#define SIZEOF_DEFAULT_UVS_TABLE_HEADER \
2985 (sizeof (struct default_uvs_table) - sizeof (struct unicode_value_range)) 2978 (sizeof (struct default_uvs_table) - sizeof (struct unicode_value_range))
2986 2979
2987struct uvs_mapping 2980struct uvs_mapping
@@ -2994,7 +2987,7 @@ struct non_default_uvs_table
2994 UInt32 num_uvs_mappings; 2987 UInt32 num_uvs_mappings;
2995 struct uvs_mapping uvs_mappings[1]; 2988 struct uvs_mapping uvs_mappings[1];
2996}; 2989};
2997#define SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER \ 2990#define SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER \
2998 (sizeof (struct non_default_uvs_table) - sizeof (struct uvs_mapping)) 2991 (sizeof (struct non_default_uvs_table) - sizeof (struct uvs_mapping))
2999#pragma pack(pop) 2992#pragma pack(pop)
3000 2993
@@ -3026,98 +3019,98 @@ mac_font_copy_uvs_table (FontRef font)
3026 3019
3027#if __LP64__ 3020#if __LP64__
3028 if (CFDataGetLength (cmap_table) > UINT32_MAX) 3021 if (CFDataGetLength (cmap_table) > UINT32_MAX)
3029 goto finish; 3022 goto finish;
3030#endif 3023#endif
3031 3024
3032 cmap_len = CFDataGetLength (cmap_table); 3025 cmap_len = CFDataGetLength (cmap_table);
3033 if (sizeof_sfntCMapHeader > cmap_len) 3026 if (sizeof_sfntCMapHeader > cmap_len)
3034 goto finish; 3027 goto finish;
3035 3028
3036 ntables = BUINT16_VALUE (cmap->numTables); 3029 ntables = BUINT16_VALUE (cmap->numTables);
3037 if (ntables > ((cmap_len - sizeof_sfntCMapHeader) 3030 if (ntables > ((cmap_len - sizeof_sfntCMapHeader)
3038 / sizeof_sfntCMapEncoding)) 3031 / sizeof_sfntCMapEncoding))
3039 goto finish; 3032 goto finish;
3040 3033
3041 for (i = 0; i < ntables; i++) 3034 for (i = 0; i < ntables; i++)
3042 if ((BUINT16_VALUE (cmap->encoding[i].platformID) 3035 if ((BUINT16_VALUE (cmap->encoding[i].platformID)
3043 == kFontUnicodePlatform) 3036 == kFontUnicodePlatform)
3044 && (BUINT16_VALUE (cmap->encoding[i].scriptID) 3037 && (BUINT16_VALUE (cmap->encoding[i].scriptID)
3045 == 5)) /* kFontUnicodeV4_0VariationSequenceSemantics */ 3038 == 5)) /* kFontUnicodeV4_0VariationSequenceSemantics */
3046 { 3039 {
3047 uvs_offset = BUINT32_VALUE (cmap->encoding[i].offset); 3040 uvs_offset = BUINT32_VALUE (cmap->encoding[i].offset);
3048 break; 3041 break;
3049 } 3042 }
3050 if (i == ntables 3043 if (i == ntables
3051 || uvs_offset > cmap_len 3044 || uvs_offset > cmap_len
3052 || SIZEOF_UVS_TABLE_HEADER > cmap_len - uvs_offset) 3045 || SIZEOF_UVS_TABLE_HEADER > cmap_len - uvs_offset)
3053 goto finish; 3046 goto finish;
3054 3047
3055 uvs = (struct uvs_table *) ((UInt8 *) cmap + uvs_offset); 3048 uvs = (struct uvs_table *) ((UInt8 *) cmap + uvs_offset);
3056 uvs_len = BUINT32_VALUE (uvs->length); 3049 uvs_len = BUINT32_VALUE (uvs->length);
3057 if (uvs_len > cmap_len - uvs_offset 3050 if (uvs_len > cmap_len - uvs_offset
3058 || SIZEOF_UVS_TABLE_HEADER > uvs_len) 3051 || SIZEOF_UVS_TABLE_HEADER > uvs_len)
3059 goto finish; 3052 goto finish;
3060 3053
3061 if (BUINT16_VALUE (uvs->format) != 14) 3054 if (BUINT16_VALUE (uvs->format) != 14)
3062 goto finish; 3055 goto finish;
3063 3056
3064 nrecords = BUINT32_VALUE (uvs->num_var_selector_records); 3057 nrecords = BUINT32_VALUE (uvs->num_var_selector_records);
3065 if (nrecords > ((uvs_len - SIZEOF_UVS_TABLE_HEADER) 3058 if (nrecords > ((uvs_len - SIZEOF_UVS_TABLE_HEADER)
3066 / sizeof (struct variation_selector_record))) 3059 / sizeof (struct variation_selector_record)))
3067 goto finish; 3060 goto finish;
3068 3061
3069 records = uvs->variation_selector_records; 3062 records = uvs->variation_selector_records;
3070 for (i = 0; i < nrecords; i++) 3063 for (i = 0; i < nrecords; i++)
3071 { 3064 {
3072 UInt32 default_uvs_offset, non_default_uvs_offset; 3065 UInt32 default_uvs_offset, non_default_uvs_offset;
3073 3066
3074 default_uvs_offset = BUINT32_VALUE (records[i].default_uvs_offset); 3067 default_uvs_offset = BUINT32_VALUE (records[i].default_uvs_offset);
3075 if (default_uvs_offset) 3068 if (default_uvs_offset)
3076 { 3069 {
3077 struct default_uvs_table *default_uvs; 3070 struct default_uvs_table *default_uvs;
3078 UInt32 nranges; 3071 UInt32 nranges;
3079 3072
3080 if (default_uvs_offset > uvs_len 3073 if (default_uvs_offset > uvs_len
3081 || (SIZEOF_DEFAULT_UVS_TABLE_HEADER 3074 || (SIZEOF_DEFAULT_UVS_TABLE_HEADER
3082 > uvs_len - default_uvs_offset)) 3075 > uvs_len - default_uvs_offset))
3083 goto finish; 3076 goto finish;
3084 3077
3085 default_uvs = ((struct default_uvs_table *) 3078 default_uvs = ((struct default_uvs_table *)
3086 ((UInt8 *) uvs + default_uvs_offset)); 3079 ((UInt8 *) uvs + default_uvs_offset));
3087 nranges = BUINT32_VALUE (default_uvs->num_unicode_value_ranges); 3080 nranges = BUINT32_VALUE (default_uvs->num_unicode_value_ranges);
3088 if (nranges > ((uvs_len - default_uvs_offset 3081 if (nranges > ((uvs_len - default_uvs_offset
3089 - SIZEOF_DEFAULT_UVS_TABLE_HEADER) 3082 - SIZEOF_DEFAULT_UVS_TABLE_HEADER)
3090 / sizeof (struct unicode_value_range))) 3083 / sizeof (struct unicode_value_range)))
3091 goto finish; 3084 goto finish;
3092 /* Now 2 * nranges can't overflow, so we can safely use 3085 /* Now 2 * nranges can't overflow, so we can safely use
3093 `(lo + hi) / 2' instead of `lo + (hi - lo) / 2' in 3086 `(lo + hi) / 2' instead of `lo + (hi - lo) / 2' in
3094 mac_font_get_glyphs_for_variants. */ 3087 mac_font_get_glyphs_for_variants. */
3095 } 3088 }
3096 3089
3097 non_default_uvs_offset = 3090 non_default_uvs_offset =
3098 BUINT32_VALUE (records[i].non_default_uvs_offset); 3091 BUINT32_VALUE (records[i].non_default_uvs_offset);
3099 if (non_default_uvs_offset) 3092 if (non_default_uvs_offset)
3100 { 3093 {
3101 struct non_default_uvs_table *non_default_uvs; 3094 struct non_default_uvs_table *non_default_uvs;
3102 UInt32 nmappings; 3095 UInt32 nmappings;
3103 3096
3104 if (non_default_uvs_offset > uvs_len 3097 if (non_default_uvs_offset > uvs_len
3105 || (SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER 3098 || (SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER
3106 > uvs_len - non_default_uvs_offset)) 3099 > uvs_len - non_default_uvs_offset))
3107 goto finish; 3100 goto finish;
3108 3101
3109 non_default_uvs = ((struct non_default_uvs_table *) 3102 non_default_uvs = ((struct non_default_uvs_table *)
3110 ((UInt8 *) uvs + non_default_uvs_offset)); 3103 ((UInt8 *) uvs + non_default_uvs_offset));
3111 nmappings = BUINT32_VALUE (non_default_uvs->num_uvs_mappings); 3104 nmappings = BUINT32_VALUE (non_default_uvs->num_uvs_mappings);
3112 if (nmappings > ((uvs_len - non_default_uvs_offset 3105 if (nmappings > ((uvs_len - non_default_uvs_offset
3113 - SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER) 3106 - SIZEOF_NON_DEFAULT_UVS_TABLE_HEADER)
3114 / sizeof (struct uvs_mapping))) 3107 / sizeof (struct uvs_mapping)))
3115 goto finish; 3108 goto finish;
3116 /* Now 2 * nmappings can't overflow, so we can safely 3109 /* Now 2 * nmappings can't overflow, so we can safely
3117 use `(lo + hi) / 2' instead of `lo + (hi - lo) / 2' 3110 use `(lo + hi) / 2' instead of `lo + (hi - lo) / 2'
3118 in mac_font_get_glyphs_for_variants. */ 3111 in mac_font_get_glyphs_for_variants. */
3119 } 3112 }
3120 } 3113 }
3121 3114
3122 uvs_table = CFDataCreate (NULL, (UInt8 *) uvs, uvs_len); 3115 uvs_table = CFDataCreate (NULL, (UInt8 *) uvs, uvs_len);
3123 3116
@@ -3140,18 +3133,16 @@ mac_font_copy_uvs_table (FontRef font)
3140 3133
3141static void 3134static void
3142mac_font_get_glyphs_for_variants (CFDataRef uvs_table, UTF32Char c, 3135mac_font_get_glyphs_for_variants (CFDataRef uvs_table, UTF32Char c,
3143 const UTF32Char selectors[], CGGlyph glyphs[], 3136 const UTF32Char selectors[], CGGlyph glyphs[],
3144 CFIndex count) 3137 CFIndex count)
3145{ 3138{
3146 struct uvs_table *uvs = (struct uvs_table *) CFDataGetBytePtr (uvs_table); 3139 struct uvs_table *uvs = (struct uvs_table *) CFDataGetBytePtr (uvs_table);
3147 struct variation_selector_record *records = uvs->variation_selector_records; 3140 struct variation_selector_record *records = uvs->variation_selector_records;
3148 CFIndex i; 3141 CFIndex i;
3149 UInt32 ir, nrecords; 3142 UInt32 ir, nrecords;
3150#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3151 dispatch_queue_t queue = 3143 dispatch_queue_t queue =
3152 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 3144 dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3153 dispatch_group_t group = dispatch_group_create (); 3145 dispatch_group_t group = dispatch_group_create ();
3154#endif
3155 3146
3156 nrecords = BUINT32_VALUE (uvs->num_var_selector_records); 3147 nrecords = BUINT32_VALUE (uvs->num_var_selector_records);
3157 i = 0; 3148 i = 0;
@@ -3161,86 +3152,80 @@ mac_font_get_glyphs_for_variants (CFDataRef uvs_table, UTF32Char c,
3161 UInt32 default_uvs_offset, non_default_uvs_offset; 3152 UInt32 default_uvs_offset, non_default_uvs_offset;
3162 3153
3163 if (selectors[i] < BUINT24_VALUE (records[ir].var_selector)) 3154 if (selectors[i] < BUINT24_VALUE (records[ir].var_selector))
3164 { 3155 {
3165 glyphs[i++] = kCGFontIndexInvalid; 3156 glyphs[i++] = kCGFontIndexInvalid;
3166 continue; 3157 continue;
3167 } 3158 }
3168 else if (selectors[i] > BUINT24_VALUE (records[ir].var_selector)) 3159 else if (selectors[i] > BUINT24_VALUE (records[ir].var_selector))
3169 { 3160 {
3170 ir++; 3161 ir++;
3171 continue; 3162 continue;
3172 } 3163 }
3173 3164
3174 /* selectors[i] == BUINT24_VALUE (records[ir].var_selector) */ 3165 /* selectors[i] == BUINT24_VALUE (records[ir].var_selector) */
3175 default_uvs_offset = BUINT32_VALUE (records[ir].default_uvs_offset); 3166 default_uvs_offset = BUINT32_VALUE (records[ir].default_uvs_offset);
3176 non_default_uvs_offset = 3167 non_default_uvs_offset =
3177 BUINT32_VALUE (records[ir].non_default_uvs_offset); 3168 BUINT32_VALUE (records[ir].non_default_uvs_offset);
3178#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3179 dispatch_group_async (group, queue, ^{ 3169 dispatch_group_async (group, queue, ^{
3180#endif 3170 glyphs[i] = kCGFontIndexInvalid;
3181 glyphs[i] = kCGFontIndexInvalid; 3171
3182 3172 if (default_uvs_offset)
3183 if (default_uvs_offset) 3173 {
3184 { 3174 struct default_uvs_table *default_uvs =
3185 struct default_uvs_table *default_uvs = 3175 (struct default_uvs_table *) ((UInt8 *) uvs
3186 (struct default_uvs_table *) ((UInt8 *) uvs 3176 + default_uvs_offset);
3187 + default_uvs_offset); 3177 struct unicode_value_range *ranges =
3188 struct unicode_value_range *ranges = 3178 default_uvs->unicode_value_ranges;
3189 default_uvs->unicode_value_ranges; 3179 UInt32 lo, hi;
3190 UInt32 lo, hi; 3180
3191 3181 lo = 0;
3192 lo = 0; 3182 hi = BUINT32_VALUE (default_uvs->num_unicode_value_ranges);
3193 hi = BUINT32_VALUE (default_uvs->num_unicode_value_ranges); 3183 while (lo < hi)
3194 while (lo < hi) 3184 {
3195 { 3185 UInt32 mid = (lo + hi) / 2;
3196 UInt32 mid = (lo + hi) / 2; 3186
3197 3187 if (c < BUINT24_VALUE (ranges[mid].start_unicode_value))
3198 if (c < BUINT24_VALUE (ranges[mid].start_unicode_value)) 3188 hi = mid;
3199 hi = mid; 3189 else
3200 else 3190 lo = mid + 1;
3201 lo = mid + 1; 3191 }
3202 } 3192 if (hi > 0
3203 if (hi > 0 3193 && (c <= (BUINT24_VALUE (ranges[hi - 1].start_unicode_value)
3204 && (c <= (BUINT24_VALUE (ranges[hi - 1].start_unicode_value) 3194 + BUINT8_VALUE (ranges[hi - 1].additional_count))))
3205 + BUINT8_VALUE (ranges[hi - 1].additional_count)))) 3195 glyphs[i] = 0;
3206 glyphs[i] = 0; 3196 }
3207 } 3197
3208 3198 if (glyphs[i] == kCGFontIndexInvalid && non_default_uvs_offset)
3209 if (glyphs[i] == kCGFontIndexInvalid && non_default_uvs_offset) 3199 {
3210 { 3200 struct non_default_uvs_table *non_default_uvs =
3211 struct non_default_uvs_table *non_default_uvs = 3201 (struct non_default_uvs_table *) ((UInt8 *) uvs
3212 (struct non_default_uvs_table *) ((UInt8 *) uvs 3202 + non_default_uvs_offset);
3213 + non_default_uvs_offset); 3203 struct uvs_mapping *mappings = non_default_uvs->uvs_mappings;
3214 struct uvs_mapping *mappings = non_default_uvs->uvs_mappings; 3204 UInt32 lo, hi;
3215 UInt32 lo, hi; 3205
3216 3206 lo = 0;
3217 lo = 0; 3207 hi = BUINT32_VALUE (non_default_uvs->num_uvs_mappings);
3218 hi = BUINT32_VALUE (non_default_uvs->num_uvs_mappings); 3208 while (lo < hi)
3219 while (lo < hi) 3209 {
3220 { 3210 UInt32 mid = (lo + hi) / 2;
3221 UInt32 mid = (lo + hi) / 2; 3211
3222 3212 if (c < BUINT24_VALUE (mappings[mid].unicode_value))
3223 if (c < BUINT24_VALUE (mappings[mid].unicode_value)) 3213 hi = mid;
3224 hi = mid; 3214 else
3225 else 3215 lo = mid + 1;
3226 lo = mid + 1; 3216 }
3227 } 3217 if (hi > 0 &&
3228 if (hi > 0 && 3218 BUINT24_VALUE (mappings[hi - 1].unicode_value) == c)
3229 BUINT24_VALUE (mappings[hi - 1].unicode_value) == c) 3219 glyphs[i] = BUINT16_VALUE (mappings[hi - 1].glyph_id);
3230 glyphs[i] = BUINT16_VALUE (mappings[hi - 1].glyph_id); 3220 }
3231 } 3221 });
3232#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3233 });
3234#endif
3235 i++; 3222 i++;
3236 ir++; 3223 ir++;
3237 } 3224 }
3238 while (i < count) 3225 while (i < count)
3239 glyphs[i++] = kCGFontIndexInvalid; 3226 glyphs[i++] = kCGFontIndexInvalid;
3240#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
3241 dispatch_group_wait (group, DISPATCH_TIME_FOREVER); 3227 dispatch_group_wait (group, DISPATCH_TIME_FOREVER);
3242 dispatch_release (group); 3228 dispatch_release (group);
3243#endif
3244} 3229}
3245 3230
3246static int 3231static int
@@ -3259,26 +3244,26 @@ macfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
3259 CGGlyph glyphs[256]; 3244 CGGlyph glyphs[256];
3260 3245
3261 for (i = 0; i < 16; i++) 3246 for (i = 0; i < 16; i++)
3262 selectors[i] = 0xFE00 + i; 3247 selectors[i] = 0xFE00 + i;
3263 for (; i < 256; i++) 3248 for (; i < 256; i++)
3264 selectors[i] = 0xE0100 + (i - 16); 3249 selectors[i] = 0xE0100 + (i - 16);
3265 mac_font_get_glyphs_for_variants (uvs_table, c, selectors, glyphs, 256); 3250 mac_font_get_glyphs_for_variants (uvs_table, c, selectors, glyphs, 256);
3266 for (i = 0; i < 256; i++) 3251 for (i = 0; i < 256; i++)
3267 { 3252 {
3268 CGGlyph glyph = glyphs[i]; 3253 CGGlyph glyph = glyphs[i];
3269 3254
3270 if (uvs_collection != MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING 3255 if (uvs_collection != MAC_CHARACTER_COLLECTION_IDENTITY_MAPPING
3271 && glyph != kCGFontIndexInvalid) 3256 && glyph != kCGFontIndexInvalid)
3272 glyph = macfont_get_glyph_for_cid (font, uvs_collection, glyph); 3257 glyph = macfont_get_glyph_for_cid (font, uvs_collection, glyph);
3273 if (glyph == kCGFontIndexInvalid) 3258 if (glyph == kCGFontIndexInvalid)
3274 variations[i] = 0; 3259 variations[i] = 0;
3275 else 3260 else
3276 { 3261 {
3277 variations[i] = (glyph ? glyph 3262 variations[i] = (glyph ? glyph
3278 : macfont_get_glyph_for_character (font, c)); 3263 : macfont_get_glyph_for_character (font, c));
3279 n++; 3264 n++;
3280 } 3265 }
3281 } 3266 }
3282 } 3267 }
3283 unblock_input (); 3268 unblock_input ();
3284 3269
@@ -3306,7 +3291,7 @@ macfont_filter_properties (Lisp_Object font, Lisp_Object alist)
3306 3291
3307static Boolean 3292static Boolean
3308mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef descriptor, 3293mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef descriptor,
3309 CFArrayRef languages) 3294 CFArrayRef languages)
3310{ 3295{
3311 Boolean result = true; 3296 Boolean result = true;
3312 CFArrayRef desc_languages = 3297 CFArrayRef desc_languages =
@@ -3321,13 +3306,13 @@ mac_ctfont_descriptor_supports_languages (CTFontDescriptorRef descriptor,
3321 desc_languages_count = CFArrayGetCount (desc_languages); 3306 desc_languages_count = CFArrayGetCount (desc_languages);
3322 languages_count = CFArrayGetCount (languages); 3307 languages_count = CFArrayGetCount (languages);
3323 for (i = 0; i < languages_count; i++) 3308 for (i = 0; i < languages_count; i++)
3324 if (!CFArrayContainsValue (desc_languages, 3309 if (!CFArrayContainsValue (desc_languages,
3325 CFRangeMake (0, desc_languages_count), 3310 CFRangeMake (0, desc_languages_count),
3326 CFArrayGetValueAtIndex (languages, i))) 3311 CFArrayGetValueAtIndex (languages, i)))
3327 { 3312 {
3328 result = false; 3313 result = false;
3329 break; 3314 break;
3330 } 3315 }
3331 CFRelease (desc_languages); 3316 CFRelease (desc_languages);
3332 } 3317 }
3333 3318
@@ -3345,79 +3330,79 @@ mac_ctfont_create_preferred_family_for_attributes (CFDictionaryRef attributes)
3345 { 3330 {
3346 CFStringRef keys[] = { 3331 CFStringRef keys[] = {
3347#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 3332#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
3348 kCTLanguageAttributeName 3333 kCTLanguageAttributeName
3349#else 3334#else
3350 CFSTR ("NSLanguage") 3335 CFSTR ("NSLanguage")
3351#endif 3336#endif
3352 }; 3337 };
3353 CFTypeRef values[] = {NULL}; 3338 CFTypeRef values[] = {NULL};
3354 CFIndex num_values = 0; 3339 CFIndex num_values = 0;
3355 CFArrayRef languages 3340 CFArrayRef languages
3356 = CFDictionaryGetValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE); 3341 = CFDictionaryGetValue (attributes, MAC_FONT_LANGUAGES_ATTRIBUTE);
3357 3342
3358 if (languages && CFArrayGetCount (languages) > 0) 3343 if (languages && CFArrayGetCount (languages) > 0)
3359 { 3344 {
3360 if (CTGetCoreTextVersion () >= kCTVersionNumber10_9) 3345 if (CTGetCoreTextVersion () >= kCTVersionNumber10_9)
3361 values[num_values++] = CFArrayGetValueAtIndex (languages, 0); 3346 values[num_values++] = CFArrayGetValueAtIndex (languages, 0);
3362 else 3347 else
3363 { 3348 {
3364 CFCharacterSetRef charset = 3349 CFCharacterSetRef charset =
3365 CFDictionaryGetValue (attributes, 3350 CFDictionaryGetValue (attributes,
3366 MAC_FONT_CHARACTER_SET_ATTRIBUTE); 3351 MAC_FONT_CHARACTER_SET_ATTRIBUTE);
3367 3352
3368 result = mac_font_copy_default_name_for_charset_and_languages (charset, languages); 3353 result = mac_font_copy_default_name_for_charset_and_languages (charset, languages);
3369 } 3354 }
3370 } 3355 }
3371 if (result == NULL) 3356 if (result == NULL)
3372 { 3357 {
3373 CFAttributedStringRef attr_string = NULL; 3358 CFAttributedStringRef attr_string = NULL;
3374 CTLineRef ctline = NULL; 3359 CTLineRef ctline = NULL;
3375 CFDictionaryRef attrs 3360 CFDictionaryRef attrs
3376 = CFDictionaryCreate (NULL, (const void **) keys, 3361 = CFDictionaryCreate (NULL, (const void **) keys,
3377 (const void **) values, num_values, 3362 (const void **) values, num_values,
3378 &kCFTypeDictionaryKeyCallBacks, 3363 &kCFTypeDictionaryKeyCallBacks,
3379 &kCFTypeDictionaryValueCallBacks); 3364 &kCFTypeDictionaryValueCallBacks);
3380 3365
3381 if (attrs) 3366 if (attrs)
3382 { 3367 {
3383 attr_string = CFAttributedStringCreate (NULL, charset_string, 3368 attr_string = CFAttributedStringCreate (NULL, charset_string,
3384 attrs); 3369 attrs);
3385 CFRelease (attrs); 3370 CFRelease (attrs);
3386 } 3371 }
3387 if (attr_string) 3372 if (attr_string)
3388 { 3373 {
3389 ctline = CTLineCreateWithAttributedString (attr_string); 3374 ctline = CTLineCreateWithAttributedString (attr_string);
3390 CFRelease (attr_string); 3375 CFRelease (attr_string);
3391 } 3376 }
3392 if (ctline) 3377 if (ctline)
3393 { 3378 {
3394 CFArrayRef runs = CTLineGetGlyphRuns (ctline); 3379 CFArrayRef runs = CTLineGetGlyphRuns (ctline);
3395 CFIndex i, nruns = CFArrayGetCount (runs); 3380 CFIndex i, nruns = CFArrayGetCount (runs);
3396 CTFontRef font; 3381 CTFontRef font;
3397 3382
3398 for (i = 0; i < nruns; i++) 3383 for (i = 0; i < nruns; i++)
3399 { 3384 {
3400 CTRunRef run = CFArrayGetValueAtIndex (runs, i); 3385 CTRunRef run = CFArrayGetValueAtIndex (runs, i);
3401 CFDictionaryRef attributes = CTRunGetAttributes (run); 3386 CFDictionaryRef attributes = CTRunGetAttributes (run);
3402 CTFontRef font_in_run; 3387 CTFontRef font_in_run;
3403 3388
3404 if (attributes == NULL) 3389 if (attributes == NULL)
3405 break; 3390 break;
3406 font_in_run = 3391 font_in_run =
3407 CFDictionaryGetValue (attributes, kCTFontAttributeName); 3392 CFDictionaryGetValue (attributes, kCTFontAttributeName);
3408 if (font_in_run == NULL) 3393 if (font_in_run == NULL)
3409 break; 3394 break;
3410 if (i == 0) 3395 if (i == 0)
3411 font = font_in_run; 3396 font = font_in_run;
3412 else if (!mac_ctfont_equal_in_postscript_name (font, 3397 else if (!mac_ctfont_equal_in_postscript_name (font,
3413 font_in_run)) 3398 font_in_run))
3414 break; 3399 break;
3415 } 3400 }
3416 if (nruns > 0 && i == nruns) 3401 if (nruns > 0 && i == nruns)
3417 result = CTFontCopyAttribute (font, kCTFontFamilyNameAttribute); 3402 result = CTFontCopyAttribute (font, kCTFontFamilyNameAttribute);
3418 CFRelease (ctline); 3403 CFRelease (ctline);
3419 } 3404 }
3420 } 3405 }
3421 } 3406 }
3422 3407
3423 return result; 3408 return result;
@@ -3427,14 +3412,14 @@ static inline double
3427mac_ctfont_get_advance_width_for_glyph (CTFontRef font, CGGlyph glyph) 3412mac_ctfont_get_advance_width_for_glyph (CTFontRef font, CGGlyph glyph)
3428{ 3413{
3429 return CTFontGetAdvancesForGlyphs (font, kCTFontDefaultOrientation, 3414 return CTFontGetAdvancesForGlyphs (font, kCTFontDefaultOrientation,
3430 &glyph, NULL, 1); 3415 &glyph, NULL, 1);
3431} 3416}
3432 3417
3433static inline CGRect 3418static inline CGRect
3434mac_ctfont_get_bounding_rect_for_glyph (CTFontRef font, CGGlyph glyph) 3419mac_ctfont_get_bounding_rect_for_glyph (CTFontRef font, CGGlyph glyph)
3435{ 3420{
3436 return CTFontGetBoundingRectsForGlyphs (font, kCTFontDefaultOrientation, 3421 return CTFontGetBoundingRectsForGlyphs (font, kCTFontDefaultOrientation,
3437 &glyph, NULL, 1); 3422 &glyph, NULL, 1);
3438} 3423}
3439 3424
3440static CFArrayRef 3425static CFArrayRef
@@ -3442,83 +3427,31 @@ mac_ctfont_create_available_families (void)
3442{ 3427{
3443 CFMutableArrayRef families = NULL; 3428 CFMutableArrayRef families = NULL;
3444 3429
3445#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
3446#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3447 if (CTFontManagerCopyAvailableFontFamilyNames != NULL)
3448#endif
3449 { 3430 {
3450 CFArrayRef orig_families = CTFontManagerCopyAvailableFontFamilyNames (); 3431 CFArrayRef orig_families = CTFontManagerCopyAvailableFontFamilyNames ();
3451 3432
3452 if (orig_families) 3433 if (orig_families)
3453 { 3434 {
3454 CFIndex i, count = CFArrayGetCount (orig_families); 3435 CFIndex i, count = CFArrayGetCount (orig_families);
3455 3436
3456 families = CFArrayCreateMutable (NULL, count, &kCFTypeArrayCallBacks); 3437 families = CFArrayCreateMutable (NULL, count, &kCFTypeArrayCallBacks);
3457 if (families) 3438 if (families)
3458 for (i = 0; i < count; i++) 3439 for (i = 0; i < count; i++)
3459 { 3440 {
3460 CFStringRef family = CFArrayGetValueAtIndex (orig_families, i); 3441 CFStringRef family = CFArrayGetValueAtIndex (orig_families, i);
3461 3442
3462 if (!CFStringHasPrefix (family, CFSTR (".")) 3443 if (!CFStringHasPrefix (family, CFSTR ("."))
3463 && (CTFontManagerCompareFontFamilyNames (family, 3444 && (CTFontManagerCompareFontFamilyNames (family,
3464 CFSTR ("LastResort"), 3445 CFSTR ("LastResort"),
3465 NULL) 3446 NULL)
3466 != kCFCompareEqualTo)) 3447 != kCFCompareEqualTo))
3467 CFArrayAppendValue (families, family); 3448 CFArrayAppendValue (families, family);
3468 } 3449 }
3469 CFRelease (orig_families); 3450 CFRelease (orig_families);
3470 } 3451 }
3471 }
3472#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3473 else /* CTFontManagerCopyAvailableFontFamilyNames == NULL */
3474#endif
3475#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 */
3476#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3477 {
3478 CTFontCollectionRef collection;
3479 CFArrayRef descs = NULL;
3480
3481 collection = CTFontCollectionCreateFromAvailableFonts (NULL);
3482 if (collection)
3483 {
3484 descs = CTFontCollectionCreateMatchingFontDescriptors (collection);
3485 CFRelease (collection);
3486 }
3487 if (descs)
3488 {
3489 CFIndex i, count = CFArrayGetCount (descs);
3490
3491 families = CFArrayCreateMutable (NULL, count, &kCFTypeArrayCallBacks);
3492 if (families)
3493 for (i = 0; i < count; i++)
3494 {
3495 FontDescriptorRef desc = CFArrayGetValueAtIndex (descs, i);
3496 CFStringRef name =
3497 mac_font_descriptor_copy_attribute (desc,
3498 MAC_FONT_FAMILY_NAME_ATTRIBUTE);
3499
3500 if (name)
3501 {
3502 CFIndex p, limit = CFArrayGetCount (families);
3503
3504 p = CFArrayBSearchValues (families, CFRangeMake (0, limit),
3505 (const void *) name,
3506 mac_font_family_compare, NULL);
3507 if (p >= limit)
3508 CFArrayAppendValue (families, name);
3509 else if (mac_font_family_compare
3510 (CFArrayGetValueAtIndex (families, p),
3511 name, NULL) != kCFCompareEqualTo)
3512 CFArrayInsertValueAtIndex (families, p, name);
3513 CFRelease (name);
3514 }
3515 }
3516 CFRelease (descs);
3517 }
3518 } 3452 }
3519#endif
3520 3453
3521 return families; 3454 return families;
3522} 3455}
3523 3456
3524static Boolean 3457static Boolean
@@ -3536,10 +3469,10 @@ mac_ctfont_equal_in_postscript_name (CTFontRef font1, CTFontRef font2)
3536 { 3469 {
3537 name2 = CTFontCopyPostScriptName (font2); 3470 name2 = CTFontCopyPostScriptName (font2);
3538 if (name2) 3471 if (name2)
3539 { 3472 {
3540 result = CFEqual (name1, name2); 3473 result = CFEqual (name1, name2);
3541 CFRelease (name2); 3474 CFRelease (name2);
3542 } 3475 }
3543 CFRelease (name1); 3476 CFRelease (name1);
3544 } 3477 }
3545 3478
@@ -3548,7 +3481,7 @@ mac_ctfont_equal_in_postscript_name (CTFontRef font1, CTFontRef font2)
3548 3481
3549static CTLineRef 3482static CTLineRef
3550mac_ctfont_create_line_with_string_and_font (CFStringRef string, 3483mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3551 CTFontRef macfont) 3484 CTFontRef macfont)
3552{ 3485{
3553 CFStringRef keys[] = {kCTFontAttributeName, kCTKernAttributeName}; 3486 CFStringRef keys[] = {kCTFontAttributeName, kCTKernAttributeName};
3554 CFTypeRef values[] = {NULL, NULL}; 3487 CFTypeRef values[] = {NULL, NULL};
@@ -3562,10 +3495,10 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3562 if (values[1]) 3495 if (values[1])
3563 { 3496 {
3564 attributes = CFDictionaryCreate (NULL, (const void **) keys, 3497 attributes = CFDictionaryCreate (NULL, (const void **) keys,
3565 (const void **) values, 3498 (const void **) values,
3566 ARRAYELTS (keys), 3499 ARRAYELTS (keys),
3567 &kCFTypeDictionaryKeyCallBacks, 3500 &kCFTypeDictionaryKeyCallBacks,
3568 &kCFTypeDictionaryValueCallBacks); 3501 &kCFTypeDictionaryValueCallBacks);
3569 CFRelease (values[1]); 3502 CFRelease (values[1]);
3570 } 3503 }
3571 if (attributes) 3504 if (attributes)
@@ -3581,30 +3514,30 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3581 if (ctline) 3514 if (ctline)
3582 { 3515 {
3583 /* Abandon if ctline contains some fonts other than the 3516 /* Abandon if ctline contains some fonts other than the
3584 specified one. */ 3517 specified one. */
3585 CFArrayRef runs = CTLineGetGlyphRuns (ctline); 3518 CFArrayRef runs = CTLineGetGlyphRuns (ctline);
3586 CFIndex i, nruns = CFArrayGetCount (runs); 3519 CFIndex i, nruns = CFArrayGetCount (runs);
3587 3520
3588 for (i = 0; i < nruns; i++) 3521 for (i = 0; i < nruns; i++)
3589 { 3522 {
3590 CTRunRef run = CFArrayGetValueAtIndex (runs, i); 3523 CTRunRef run = CFArrayGetValueAtIndex (runs, i);
3591 CFDictionaryRef attributes = CTRunGetAttributes (run); 3524 CFDictionaryRef attributes = CTRunGetAttributes (run);
3592 CTFontRef font_in_run; 3525 CTFontRef font_in_run;
3593 3526
3594 if (attributes == NULL) 3527 if (attributes == NULL)
3595 break; 3528 break;
3596 font_in_run = 3529 font_in_run =
3597 CFDictionaryGetValue (attributes, kCTFontAttributeName); 3530 CFDictionaryGetValue (attributes, kCTFontAttributeName);
3598 if (font_in_run == NULL) 3531 if (font_in_run == NULL)
3599 break; 3532 break;
3600 if (!mac_ctfont_equal_in_postscript_name (macfont, font_in_run)) 3533 if (!mac_ctfont_equal_in_postscript_name (macfont, font_in_run))
3601 break; 3534 break;
3602 } 3535 }
3603 if (i < nruns) 3536 if (i < nruns)
3604 { 3537 {
3605 CFRelease (ctline); 3538 CFRelease (ctline);
3606 ctline = NULL; 3539 ctline = NULL;
3607 } 3540 }
3608 } 3541 }
3609 3542
3610 return ctline; 3543 return ctline;
@@ -3612,7 +3545,7 @@ mac_ctfont_create_line_with_string_and_font (CFStringRef string,
3612 3545
3613static CFIndex 3546static CFIndex
3614mac_ctfont_shape (CTFontRef font, CFStringRef string, 3547mac_ctfont_shape (CTFontRef font, CFStringRef string,
3615 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len) 3548 struct mac_glyph_layout *glyph_layouts, CFIndex glyph_len)
3616{ 3549{
3617 CFIndex used, result = 0; 3550 CFIndex used, result = 0;
3618 CTLineRef ctline = mac_ctfont_create_line_with_string_and_font (string, font); 3551 CTLineRef ctline = mac_ctfont_create_line_with_string_and_font (string, font);
@@ -3629,128 +3562,128 @@ mac_ctfont_shape (CTFontRef font, CFStringRef string,
3629 CFIndex total_glyph_count = 0; 3562 CFIndex total_glyph_count = 0;
3630 3563
3631 for (k = 0; k < ctrun_count; k++) 3564 for (k = 0; k < ctrun_count; k++)
3632 { 3565 {
3633 CTRunRef ctrun = CFArrayGetValueAtIndex (ctruns, k); 3566 CTRunRef ctrun = CFArrayGetValueAtIndex (ctruns, k);
3634 CFIndex i, min_location, glyph_count = CTRunGetGlyphCount (ctrun); 3567 CFIndex i, min_location, glyph_count = CTRunGetGlyphCount (ctrun);
3635 struct mac_glyph_layout *glbuf = glyph_layouts + total_glyph_count; 3568 struct mac_glyph_layout *glbuf = glyph_layouts + total_glyph_count;
3636 CFRange string_range, comp_range, range; 3569 CFRange string_range, comp_range, range;
3637 CFIndex *permutation; 3570 CFIndex *permutation;
3638 3571
3639 if (CTRunGetStatus (ctrun) & kCTRunStatusRightToLeft) 3572 if (CTRunGetStatus (ctrun) & kCTRunStatusRightToLeft)
3640 permutation = xmalloc (sizeof (CFIndex) * glyph_count); 3573 permutation = xmalloc (sizeof (CFIndex) * glyph_count);
3641 else 3574 else
3642 permutation = NULL; 3575 permutation = NULL;
3643 3576
3644#define RIGHT_TO_LEFT_P permutation 3577#define RIGHT_TO_LEFT_P permutation
3645 3578
3646 /* Now the `comp_range' member of struct mac_glyph_layout is 3579 /* Now the `comp_range' member of struct mac_glyph_layout is
3647 temporarily used as a work area such that: 3580 temporarily used as a work area such that:
3648 glbuf[i].comp_range.location = 3581 glbuf[i].comp_range.location =
3649 min {compRange[i + 1].location, ..., 3582 min {compRange[i + 1].location, ...,
3650 compRange[glyph_count - 1].location, 3583 compRange[glyph_count - 1].location,
3651 maxRange (stringRangeForCTRun)} 3584 maxRange (stringRangeForCTRun)}
3652 glbuf[i].comp_range.length = maxRange (compRange[i]) 3585 glbuf[i].comp_range.length = maxRange (compRange[i])
3653 where compRange[i] is the range of composed characters 3586 where compRange[i] is the range of composed characters
3654 containing i-th glyph. */ 3587 containing i-th glyph. */
3655 string_range = CTRunGetStringRange (ctrun); 3588 string_range = CTRunGetStringRange (ctrun);
3656 min_location = string_range.location + string_range.length; 3589 min_location = string_range.location + string_range.length;
3657 for (i = 0; i < glyph_count; i++) 3590 for (i = 0; i < glyph_count; i++)
3658 { 3591 {
3659 struct mac_glyph_layout *gl = glbuf + glyph_count - i - 1; 3592 struct mac_glyph_layout *gl = glbuf + glyph_count - i - 1;
3660 CFIndex glyph_index; 3593 CFIndex glyph_index;
3661 CFRange rng; 3594 CFRange rng;
3662 3595
3663 if (!RIGHT_TO_LEFT_P) 3596 if (!RIGHT_TO_LEFT_P)
3664 glyph_index = glyph_count - i - 1; 3597 glyph_index = glyph_count - i - 1;
3665 else 3598 else
3666 glyph_index = i; 3599 glyph_index = i;
3667 CTRunGetStringIndices (ctrun, CFRangeMake (glyph_index, 1), 3600 CTRunGetStringIndices (ctrun, CFRangeMake (glyph_index, 1),
3668 &gl->string_index); 3601 &gl->string_index);
3669 rng = 3602 rng =
3670 CFStringGetRangeOfComposedCharactersAtIndex (string, 3603 CFStringGetRangeOfComposedCharactersAtIndex (string,
3671 gl->string_index); 3604 gl->string_index);
3672 gl->comp_range.location = min_location; 3605 gl->comp_range.location = min_location;
3673 gl->comp_range.length = rng.location + rng.length; 3606 gl->comp_range.length = rng.location + rng.length;
3674 if (rng.location < min_location) 3607 if (rng.location < min_location)
3675 min_location = rng.location; 3608 min_location = rng.location;
3676 } 3609 }
3677 3610
3678 /* Fill the `comp_range' member of struct mac_glyph_layout, 3611 /* Fill the `comp_range' member of struct mac_glyph_layout,
3679 and setup a permutation for right-to-left text. */ 3612 and setup a permutation for right-to-left text. */
3680 comp_range = CFRangeMake (string_range.location, 0); 3613 comp_range = CFRangeMake (string_range.location, 0);
3681 range = CFRangeMake (0, 0); 3614 range = CFRangeMake (0, 0);
3682 while (1) 3615 while (1)
3683 { 3616 {
3684 struct mac_glyph_layout *gl = 3617 struct mac_glyph_layout *gl =
3685 glbuf + range.location + range.length; 3618 glbuf + range.location + range.length;
3686 3619
3687 if (gl->comp_range.length 3620 if (gl->comp_range.length
3688 > comp_range.location + comp_range.length) 3621 > comp_range.location + comp_range.length)
3689 comp_range.length = gl->comp_range.length - comp_range.location; 3622 comp_range.length = gl->comp_range.length - comp_range.location;
3690 min_location = gl->comp_range.location; 3623 min_location = gl->comp_range.location;
3691 range.length++; 3624 range.length++;
3692 3625
3693 if (min_location >= comp_range.location + comp_range.length) 3626 if (min_location >= comp_range.location + comp_range.length)
3694 { 3627 {
3695 comp_range.length = min_location - comp_range.location; 3628 comp_range.length = min_location - comp_range.location;
3696 for (i = 0; i < range.length; i++) 3629 for (i = 0; i < range.length; i++)
3697 { 3630 {
3698 glbuf[range.location + i].comp_range = comp_range; 3631 glbuf[range.location + i].comp_range = comp_range;
3699 if (RIGHT_TO_LEFT_P) 3632 if (RIGHT_TO_LEFT_P)
3700 permutation[range.location + i] = 3633 permutation[range.location + i] =
3701 range.location + range.length - i - 1; 3634 range.location + range.length - i - 1;
3702 } 3635 }
3703 3636
3704 comp_range = CFRangeMake (min_location, 0); 3637 comp_range = CFRangeMake (min_location, 0);
3705 range.location += range.length; 3638 range.location += range.length;
3706 range.length = 0; 3639 range.length = 0;
3707 if (range.location == glyph_count) 3640 if (range.location == glyph_count)
3708 break; 3641 break;
3709 } 3642 }
3710 } 3643 }
3711 3644
3712 /* Then fill the remaining members. */ 3645 /* Then fill the remaining members. */
3713 for (range = CFRangeMake (0, 1); range.location < glyph_count; 3646 for (range = CFRangeMake (0, 1); range.location < glyph_count;
3714 range.location++) 3647 range.location++)
3715 { 3648 {
3716 struct mac_glyph_layout *gl; 3649 struct mac_glyph_layout *gl;
3717 CGPoint position; 3650 CGPoint position;
3718 3651
3719 if (!RIGHT_TO_LEFT_P) 3652 if (!RIGHT_TO_LEFT_P)
3720 gl = glbuf + range.location; 3653 gl = glbuf + range.location;
3721 else 3654 else
3722 { 3655 {
3723 CFIndex src, dest; 3656 CFIndex src, dest;
3724 3657
3725 src = glyph_count - 1 - range.location; 3658 src = glyph_count - 1 - range.location;
3726 dest = permutation[src]; 3659 dest = permutation[src];
3727 gl = glbuf + dest; 3660 gl = glbuf + dest;
3728 if (src < dest) 3661 if (src < dest)
3729 { 3662 {
3730 CFIndex tmp = gl->string_index; 3663 CFIndex tmp = gl->string_index;
3731 3664
3732 gl->string_index = glbuf[src].string_index; 3665 gl->string_index = glbuf[src].string_index;
3733 glbuf[src].string_index = tmp; 3666 glbuf[src].string_index = tmp;
3734 } 3667 }
3735 } 3668 }
3736 CTRunGetGlyphs (ctrun, range, &gl->glyph_id); 3669 CTRunGetGlyphs (ctrun, range, &gl->glyph_id);
3737 3670
3738 CTRunGetPositions (ctrun, range, &position); 3671 CTRunGetPositions (ctrun, range, &position);
3739 gl->advance_delta = position.x - total_advance; 3672 gl->advance_delta = position.x - total_advance;
3740 gl->baseline_delta = position.y; 3673 gl->baseline_delta = position.y;
3741 gl->advance = (gl->advance_delta 3674 gl->advance = (gl->advance_delta
3742 + CTRunGetTypographicBounds (ctrun, range, 3675 + CTRunGetTypographicBounds (ctrun, range,
3743 NULL, NULL, NULL)); 3676 NULL, NULL, NULL));
3744 total_advance += gl->advance; 3677 total_advance += gl->advance;
3745 } 3678 }
3746 3679
3747 if (RIGHT_TO_LEFT_P) 3680 if (RIGHT_TO_LEFT_P)
3748 xfree (permutation); 3681 xfree (permutation);
3749 3682
3750#undef RIGHT_TO_LEFT_P 3683#undef RIGHT_TO_LEFT_P
3751 3684
3752 total_glyph_count += glyph_count; 3685 total_glyph_count += glyph_count;
3753 } 3686 }
3754 3687
3755 result = used; 3688 result = used;
3756 } 3689 }
@@ -3765,7 +3698,7 @@ mac_ctfont_shape (CTFontRef font, CFStringRef string,
3765#if USE_CT_GLYPH_INFO 3698#if USE_CT_GLYPH_INFO
3766static CGGlyph 3699static CGGlyph
3767mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection, 3700mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3768 CGFontIndex cid) 3701 CGFontIndex cid)
3769{ 3702{
3770 CGGlyph result = kCGFontIndexInvalid; 3703 CGGlyph result = kCGFontIndexInvalid;
3771 UniChar characters[] = {0xfffd}; 3704 UniChar characters[] = {0xfffd};
@@ -3779,27 +3712,27 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3779 if (string) 3712 if (string)
3780 { 3713 {
3781 CTGlyphInfoRef glyph_info = 3714 CTGlyphInfoRef glyph_info =
3782 CTGlyphInfoCreateWithCharacterIdentifier (cid, collection, string); 3715 CTGlyphInfoCreateWithCharacterIdentifier (cid, collection, string);
3783 CFDictionaryRef attributes = NULL; 3716 CFDictionaryRef attributes = NULL;
3784 3717
3785 if (glyph_info) 3718 if (glyph_info)
3786 { 3719 {
3787 CFStringRef keys[] = {kCTFontAttributeName, 3720 CFStringRef keys[] = {kCTFontAttributeName,
3788 kCTGlyphInfoAttributeName}; 3721 kCTGlyphInfoAttributeName};
3789 CFTypeRef values[] = {font, glyph_info}; 3722 CFTypeRef values[] = {font, glyph_info};
3790 3723
3791 attributes = CFDictionaryCreate (NULL, (const void **) keys, 3724 attributes = CFDictionaryCreate (NULL, (const void **) keys,
3792 (const void **) values, 3725 (const void **) values,
3793 ARRAYELTS (keys), 3726 ARRAYELTS (keys),
3794 &kCFTypeDictionaryKeyCallBacks, 3727 &kCFTypeDictionaryKeyCallBacks,
3795 &kCFTypeDictionaryValueCallBacks); 3728 &kCFTypeDictionaryValueCallBacks);
3796 CFRelease (glyph_info); 3729 CFRelease (glyph_info);
3797 } 3730 }
3798 if (attributes) 3731 if (attributes)
3799 { 3732 {
3800 attr_string = CFAttributedStringCreate (NULL, string, attributes); 3733 attr_string = CFAttributedStringCreate (NULL, string, attributes);
3801 CFRelease (attributes); 3734 CFRelease (attributes);
3802 } 3735 }
3803 CFRelease (string); 3736 CFRelease (string);
3804 } 3737 }
3805 if (attr_string) 3738 if (attr_string)
@@ -3812,24 +3745,24 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3812 CFArrayRef runs = CTLineGetGlyphRuns (ctline); 3745 CFArrayRef runs = CTLineGetGlyphRuns (ctline);
3813 3746
3814 if (CFArrayGetCount (runs) > 0) 3747 if (CFArrayGetCount (runs) > 0)
3815 { 3748 {
3816 CTRunRef run = CFArrayGetValueAtIndex (runs, 0); 3749 CTRunRef run = CFArrayGetValueAtIndex (runs, 0);
3817 CFDictionaryRef attributes = CTRunGetAttributes (run); 3750 CFDictionaryRef attributes = CTRunGetAttributes (run);
3818 3751
3819 if (attributes) 3752 if (attributes)
3820 { 3753 {
3821 CTFontRef font_in_run = 3754 CTFontRef font_in_run =
3822 CFDictionaryGetValue (attributes, kCTFontAttributeName); 3755 CFDictionaryGetValue (attributes, kCTFontAttributeName);
3823 3756
3824 if (font_in_run 3757 if (font_in_run
3825 && mac_ctfont_equal_in_postscript_name (font_in_run, font)) 3758 && mac_ctfont_equal_in_postscript_name (font_in_run, font))
3826 { 3759 {
3827 CTRunGetGlyphs (run, CFRangeMake (0, 1), &result); 3760 CTRunGetGlyphs (run, CFRangeMake (0, 1), &result);
3828 if (result >= CTFontGetGlyphCount (font)) 3761 if (result >= CTFontGetGlyphCount (font))
3829 result = kCGFontIndexInvalid; 3762 result = kCGFontIndexInvalid;
3830 } 3763 }
3831 } 3764 }
3832 } 3765 }
3833 CFRelease (ctline); 3766 CFRelease (ctline);
3834 } 3767 }
3835 3768
@@ -3837,41 +3770,6 @@ mac_ctfont_get_glyph_for_cid (CTFontRef font, CTCharacterCollection collection,
3837} 3770}
3838#endif 3771#endif
3839 3772
3840#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
3841static inline int
3842mac_font_family_group (CFStringRef family)
3843{
3844 if (CFStringHasPrefix (family, CFSTR ("#")))
3845 return 2;
3846 else
3847 {
3848 CFRange range;
3849
3850 range = CFStringFind (family, CFSTR ("Apple"),
3851 kCFCompareCaseInsensitive | kCFCompareAnchored);
3852 if (range.location != kCFNotFound)
3853 return 1;
3854
3855 return 0;
3856 }
3857}
3858
3859static CFComparisonResult
3860mac_font_family_compare (const void *val1, const void *val2, void *context)
3861{
3862 CFStringRef family1 = (CFStringRef) val1, family2 = (CFStringRef) val2;
3863 int group1, group2;
3864
3865 group1 = mac_font_family_group (family1);
3866 group2 = mac_font_family_group (family2);
3867 if (group1 < group2)
3868 return kCFCompareLessThan;
3869 if (group1 > group2)
3870 return kCFCompareGreaterThan;
3871 return CFStringCompare (family1, family2, kCFCompareCaseInsensitive);
3872}
3873#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */
3874
3875static CFArrayRef 3773static CFArrayRef
3876mac_font_copy_default_descriptors_for_language (CFStringRef language) 3774mac_font_copy_default_descriptors_for_language (CFStringRef language)
3877{ 3775{
@@ -3883,22 +3781,22 @@ mac_font_copy_default_descriptors_for_language (CFStringRef language)
3883#endif 3781#endif
3884 { 3782 {
3885 CTFontRef user_font = 3783 CTFontRef user_font =
3886 CTFontCreateUIFontForLanguage (kCTFontUserFontType, 0, language); 3784 CTFontCreateUIFontForLanguage (kCTFontUserFontType, 0, language);
3887 3785
3888 if (user_font) 3786 if (user_font)
3889 { 3787 {
3890 CFArrayRef languages = 3788 CFArrayRef languages =
3891 CFArrayCreate (NULL, (const void **) &language, 1, 3789 CFArrayCreate (NULL, (const void **) &language, 1,
3892 &kCFTypeArrayCallBacks); 3790 &kCFTypeArrayCallBacks);
3893 3791
3894 if (languages) 3792 if (languages)
3895 { 3793 {
3896 result = CTFontCopyDefaultCascadeListForLanguages (user_font, 3794 result = CTFontCopyDefaultCascadeListForLanguages (user_font,
3897 languages); 3795 languages);
3898 CFRelease (languages); 3796 CFRelease (languages);
3899 } 3797 }
3900 CFRelease (user_font); 3798 CFRelease (user_font);
3901 } 3799 }
3902 } 3800 }
3903#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 3801#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
3904 else /* CTFontCopyDefaultCascadeListForLanguages == NULL */ 3802 else /* CTFontCopyDefaultCascadeListForLanguages == NULL */
@@ -3909,55 +3807,55 @@ mac_font_copy_default_descriptors_for_language (CFStringRef language)
3909 CFIndex i; 3807 CFIndex i;
3910 3808
3911 for (i = 0; macfont_language_default_font_names[i].language; i++) 3809 for (i = 0; macfont_language_default_font_names[i].language; i++)
3912 { 3810 {
3913 if (CFEqual (macfont_language_default_font_names[i].language, 3811 if (CFEqual (macfont_language_default_font_names[i].language,
3914 language)) 3812 language))
3915 { 3813 {
3916 CFMutableArrayRef descriptors = 3814 CFMutableArrayRef descriptors =
3917 CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks); 3815 CFArrayCreateMutable (NULL, 0, &kCFTypeArrayCallBacks);
3918 3816
3919 if (descriptors) 3817 if (descriptors)
3920 { 3818 {
3921 CFIndex j; 3819 CFIndex j;
3922 3820
3923 for (j = 0; 3821 for (j = 0;
3924 macfont_language_default_font_names[i].font_names[j]; 3822 macfont_language_default_font_names[i].font_names[j];
3925 j++) 3823 j++)
3926 { 3824 {
3927 CFDictionaryRef attributes = 3825 CFDictionaryRef attributes =
3928 CFDictionaryCreate (NULL, 3826 CFDictionaryCreate (NULL,
3929 ((const void **) 3827 ((const void **)
3930 &MAC_FONT_NAME_ATTRIBUTE), 3828 &MAC_FONT_NAME_ATTRIBUTE),
3931 ((const void **) 3829 ((const void **)
3932 &macfont_language_default_font_names[i].font_names[j]), 3830 &macfont_language_default_font_names[i].font_names[j]),
3933 1, &kCFTypeDictionaryKeyCallBacks, 3831 1, &kCFTypeDictionaryKeyCallBacks,
3934 &kCFTypeDictionaryValueCallBacks); 3832 &kCFTypeDictionaryValueCallBacks);
3935 3833
3936 if (attributes) 3834 if (attributes)
3937 { 3835 {
3938 FontDescriptorRef pat_desc = 3836 FontDescriptorRef pat_desc =
3939 mac_font_descriptor_create_with_attributes (attributes); 3837 mac_font_descriptor_create_with_attributes (attributes);
3940 3838
3941 if (pat_desc) 3839 if (pat_desc)
3942 { 3840 {
3943 FontDescriptorRef descriptor = 3841 FontDescriptorRef descriptor =
3944 mac_font_descriptor_create_matching_font_descriptor (pat_desc, NULL); 3842 mac_font_descriptor_create_matching_font_descriptor (pat_desc, NULL);
3945 3843
3946 if (descriptor) 3844 if (descriptor)
3947 { 3845 {
3948 CFArrayAppendValue (descriptors, descriptor); 3846 CFArrayAppendValue (descriptors, descriptor);
3949 CFRelease (descriptor); 3847 CFRelease (descriptor);
3950 } 3848 }
3951 CFRelease (pat_desc); 3849 CFRelease (pat_desc);
3952 } 3850 }
3953 CFRelease (attributes); 3851 CFRelease (attributes);
3954 } 3852 }
3955 } 3853 }
3956 result = descriptors; 3854 result = descriptors;
3957 } 3855 }
3958 break; 3856 break;
3959 } 3857 }
3960 } 3858 }
3961 } 3859 }
3962#endif 3860#endif
3963 3861
@@ -3966,7 +3864,7 @@ mac_font_copy_default_descriptors_for_language (CFStringRef language)
3966 3864
3967static CFStringRef 3865static CFStringRef
3968mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset, 3866mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset,
3969 CFArrayRef languages) 3867 CFArrayRef languages)
3970{ 3868{
3971 CFStringRef result = NULL; 3869 CFStringRef result = NULL;
3972 CFStringRef language = CFArrayGetValueAtIndex (languages, 0); 3870 CFStringRef language = CFArrayGetValueAtIndex (languages, 0);
@@ -3978,29 +3876,29 @@ mac_font_copy_default_name_for_charset_and_languages (CFCharacterSetRef charset,
3978 CFIndex i, count = CFArrayGetCount (descriptors); 3876 CFIndex i, count = CFArrayGetCount (descriptors);
3979 3877
3980 for (i = 0; i < count; i++) 3878 for (i = 0; i < count; i++)
3981 { 3879 {
3982 FontDescriptorRef descriptor = 3880 FontDescriptorRef descriptor =
3983 CFArrayGetValueAtIndex (descriptors, i); 3881 CFArrayGetValueAtIndex (descriptors, i);
3984 3882
3985 if (macfont_supports_charset_and_languages_p (descriptor, charset, 3883 if (macfont_supports_charset_and_languages_p (descriptor, charset,
3986 Qnil, languages)) 3884 Qnil, languages))
3987 { 3885 {
3988 CFStringRef family = 3886 CFStringRef family =
3989 mac_font_descriptor_copy_attribute (descriptor, 3887 mac_font_descriptor_copy_attribute (descriptor,
3990 MAC_FONT_FAMILY_NAME_ATTRIBUTE); 3888 MAC_FONT_FAMILY_NAME_ATTRIBUTE);
3991 if (family) 3889 if (family)
3992 { 3890 {
3993 if (!CFStringHasPrefix (family, CFSTR (".")) 3891 if (!CFStringHasPrefix (family, CFSTR ("."))
3994 && !CFEqual (family, CFSTR ("LastResort"))) 3892 && !CFEqual (family, CFSTR ("LastResort")))
3995 { 3893 {
3996 result = family; 3894 result = family;
3997 break; 3895 break;
3998 } 3896 }
3999 else 3897 else
4000 CFRelease (family); 3898 CFRelease (family);
4001 } 3899 }
4002 } 3900 }
4003 } 3901 }
4004 CFRelease (descriptors); 3902 CFRelease (descriptors);
4005 } 3903 }
4006 3904
@@ -4022,13 +3920,10 @@ mac_register_font_driver (struct frame *f)
4022 register_font_driver (&macfont_driver, f); 3920 register_font_driver (&macfont_driver, f);
4023} 3921}
4024 3922
4025#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
4026
4027 3923
4028void 3924void
4029syms_of_macfont (void) 3925syms_of_macfont (void)
4030{ 3926{
4031#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
4032 static struct font_driver mac_font_driver; 3927 static struct font_driver mac_font_driver;
4033 3928
4034 DEFSYM (Qmac_ct, "mac-ct"); 3929 DEFSYM (Qmac_ct, "mac-ct");
@@ -4037,5 +3932,4 @@ syms_of_macfont (void)
4037 3932
4038 DEFSYM (QCdestination, ":destination"); 3933 DEFSYM (QCdestination, ":destination");
4039 DEFSYM (QCminspace, ":minspace"); 3934 DEFSYM (QCminspace, ":minspace");
4040#endif
4041} 3935}
diff --git a/src/marker.c b/src/marker.c
index 91fcea5f25f..d377efbc4fa 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -455,21 +455,8 @@ attach_marker (struct Lisp_Marker *m, struct buffer *b,
455static struct buffer * 455static struct buffer *
456live_buffer (Lisp_Object buffer) 456live_buffer (Lisp_Object buffer)
457{ 457{
458 struct buffer *b; 458 struct buffer *b = decode_buffer (buffer);
459 459 return BUFFER_LIVE_P (b) ? b : NULL;
460 if (NILP (buffer))
461 {
462 b = current_buffer;
463 eassert (BUFFER_LIVE_P (b));
464 }
465 else
466 {
467 CHECK_BUFFER (buffer);
468 b = XBUFFER (buffer);
469 if (!BUFFER_LIVE_P (b))
470 b = NULL;
471 }
472 return b;
473} 460}
474 461
475/* Internal function to set MARKER in BUFFER at POSITION. Non-zero 462/* Internal function to set MARKER in BUFFER at POSITION. Non-zero
diff --git a/src/menu.c b/src/menu.c
index 66247c713a2..61163ae0216 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -354,7 +354,7 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
354 front of them. */ 354 front of them. */
355 if (!have_boxes ()) 355 if (!have_boxes ())
356 { 356 {
357 Lisp_Object prefix = Qnil; 357 char const *prefix = 0;
358 Lisp_Object type = AREF (item_properties, ITEM_PROPERTY_TYPE); 358 Lisp_Object type = AREF (item_properties, ITEM_PROPERTY_TYPE);
359 if (!NILP (type)) 359 if (!NILP (type))
360 { 360 {
@@ -389,8 +389,11 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
389 { 389 {
390 if (!submenu && SREF (tem, 0) != '\0' 390 if (!submenu && SREF (tem, 0) != '\0'
391 && SREF (tem, 0) != '-') 391 && SREF (tem, 0) != '-')
392 ASET (menu_items, idx + MENU_ITEMS_ITEM_NAME, 392 {
393 concat2 (build_string (" "), tem)); 393 AUTO_STRING (spaces, " ");
394 ASET (menu_items, idx + MENU_ITEMS_ITEM_NAME,
395 concat2 (spaces, tem));
396 }
394 idx += MENU_ITEMS_ITEM_LENGTH; 397 idx += MENU_ITEMS_ITEM_LENGTH;
395 } 398 }
396 } 399 }
@@ -399,24 +402,30 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
399 402
400 /* Calculate prefix, if any, for this item. */ 403 /* Calculate prefix, if any, for this item. */
401 if (EQ (type, QCtoggle)) 404 if (EQ (type, QCtoggle))
402 prefix = build_string (NILP (selected) ? "[ ] " : "[X] "); 405 prefix = NILP (selected) ? "[ ] " : "[X] ";
403 else if (EQ (type, QCradio)) 406 else if (EQ (type, QCradio))
404 prefix = build_string (NILP (selected) ? "( ) " : "(*) "); 407 prefix = NILP (selected) ? "( ) " : "(*) ";
405 } 408 }
406 /* Not a button. If we have earlier buttons, then we need a prefix. */ 409 /* Not a button. If we have earlier buttons, then we need a prefix. */
407 else if (!skp->notbuttons && SREF (item_string, 0) != '\0' 410 else if (!skp->notbuttons && SREF (item_string, 0) != '\0'
408 && SREF (item_string, 0) != '-') 411 && SREF (item_string, 0) != '-')
409 prefix = build_string (" "); 412 prefix = " ";
410 413
411 if (!NILP (prefix)) 414 if (prefix)
412 item_string = concat2 (prefix, item_string); 415 {
416 AUTO_STRING (prefix_obj, prefix);
417 item_string = concat2 (prefix_obj, item_string);
418 }
413 } 419 }
414 420
415 if ((FRAME_TERMCAP_P (XFRAME (Vmenu_updating_frame)) 421 if ((FRAME_TERMCAP_P (XFRAME (Vmenu_updating_frame))
416 || FRAME_MSDOS_P (XFRAME (Vmenu_updating_frame))) 422 || FRAME_MSDOS_P (XFRAME (Vmenu_updating_frame)))
417 && !NILP (map)) 423 && !NILP (map))
418 /* Indicate visually that this is a submenu. */ 424 /* Indicate visually that this is a submenu. */
419 item_string = concat2 (item_string, build_string (" >")); 425 {
426 AUTO_STRING (space_gt, " >");
427 item_string = concat2 (item_string, space_gt);
428 }
420 429
421 push_menu_item (item_string, enabled, key, 430 push_menu_item (item_string, enabled, key,
422 AREF (item_properties, ITEM_PROPERTY_DEF), 431 AREF (item_properties, ITEM_PROPERTY_DEF),
@@ -632,8 +641,9 @@ digest_single_submenu (int start, int end, bool top_level_items)
632 widget_value **submenu_stack; 641 widget_value **submenu_stack;
633 bool panes_seen = 0; 642 bool panes_seen = 0;
634 struct frame *f = XFRAME (Vmenu_updating_frame); 643 struct frame *f = XFRAME (Vmenu_updating_frame);
644 USE_SAFE_ALLOCA;
635 645
636 submenu_stack = alloca (menu_items_used * sizeof *submenu_stack); 646 SAFE_NALLOCA (submenu_stack, 1, menu_items_used);
637 wv = make_widget_value ("menu", NULL, true, Qnil); 647 wv = make_widget_value ("menu", NULL, true, Qnil);
638 wv->button_type = BUTTON_TYPE_NONE; 648 wv->button_type = BUTTON_TYPE_NONE;
639 first_wv = wv; 649 first_wv = wv;
@@ -835,11 +845,12 @@ digest_single_submenu (int start, int end, bool top_level_items)
835 that was originally a button, return it by itself. */ 845 that was originally a button, return it by itself. */
836 if (top_level_items && first_wv->contents && first_wv->contents->next == 0) 846 if (top_level_items && first_wv->contents && first_wv->contents->next == 0)
837 { 847 {
838 wv = first_wv->contents; 848 wv = first_wv;
839 xfree (first_wv); 849 first_wv = first_wv->contents;
840 return wv; 850 xfree (wv);
841 } 851 }
842 852
853 SAFE_FREE ();
843 return first_wv; 854 return first_wv;
844} 855}
845 856
@@ -890,9 +901,10 @@ find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
890 Lisp_Object *subprefix_stack; 901 Lisp_Object *subprefix_stack;
891 int submenu_depth = 0; 902 int submenu_depth = 0;
892 int i; 903 int i;
904 USE_SAFE_ALLOCA;
893 905
894 entry = Qnil; 906 entry = Qnil;
895 subprefix_stack = alloca (menu_bar_items_used * sizeof *subprefix_stack); 907 SAFE_NALLOCA (subprefix_stack, 1, menu_bar_items_used);
896 prefix = Qnil; 908 prefix = Qnil;
897 i = 0; 909 i = 0;
898 910
@@ -954,11 +966,13 @@ find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
954 buf.arg = entry; 966 buf.arg = entry;
955 kbd_buffer_store_event (&buf); 967 kbd_buffer_store_event (&buf);
956 968
957 return; 969 break;
958 } 970 }
959 i += MENU_ITEMS_ITEM_LENGTH; 971 i += MENU_ITEMS_ITEM_LENGTH;
960 } 972 }
961 } 973 }
974
975 SAFE_FREE ();
962} 976}
963 977
964#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */ 978#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
@@ -973,10 +987,11 @@ find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data
973 int i; 987 int i;
974 Lisp_Object *subprefix_stack; 988 Lisp_Object *subprefix_stack;
975 int submenu_depth = 0; 989 int submenu_depth = 0;
990 USE_SAFE_ALLOCA;
976 991
977 prefix = entry = Qnil; 992 prefix = entry = Qnil;
978 i = 0; 993 i = 0;
979 subprefix_stack = alloca (menu_items_used * word_size); 994 SAFE_ALLOCA_LISP (subprefix_stack, menu_items_used);
980 995
981 while (i < menu_items_used) 996 while (i < menu_items_used)
982 { 997 {
@@ -1018,11 +1033,13 @@ find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data
1018 if (!NILP (subprefix_stack[j])) 1033 if (!NILP (subprefix_stack[j]))
1019 entry = Fcons (subprefix_stack[j], entry); 1034 entry = Fcons (subprefix_stack[j], entry);
1020 } 1035 }
1036 SAFE_FREE ();
1021 return entry; 1037 return entry;
1022 } 1038 }
1023 i += MENU_ITEMS_ITEM_LENGTH; 1039 i += MENU_ITEMS_ITEM_LENGTH;
1024 } 1040 }
1025 } 1041 }
1042 SAFE_FREE ();
1026 return Qnil; 1043 return Qnil;
1027} 1044}
1028#endif /* HAVE_NS */ 1045#endif /* HAVE_NS */
diff --git a/src/minibuf.c b/src/minibuf.c
index 93e19d5c120..0b455157d52 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1123,7 +1123,7 @@ If `read-buffer-function' is non-nil, this works by calling it as a
1123function, instead of the usual behavior. */) 1123function, instead of the usual behavior. */)
1124 (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match) 1124 (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match)
1125{ 1125{
1126 Lisp_Object args[4], result; 1126 Lisp_Object result;
1127 char *s; 1127 char *s;
1128 ptrdiff_t len; 1128 ptrdiff_t len;
1129 ptrdiff_t count = SPECPDL_INDEX (); 1129 ptrdiff_t count = SPECPDL_INDEX ();
@@ -1157,10 +1157,10 @@ function, instead of the usual behavior. */)
1157 STRING_MULTIBYTE (prompt)); 1157 STRING_MULTIBYTE (prompt));
1158 } 1158 }
1159 1159
1160 args[0] = build_string ("%s (default %s): "); 1160 AUTO_STRING (format, "%s (default %s): ");
1161 args[1] = prompt; 1161 prompt = Fformat (3, ((Lisp_Object [])
1162 args[2] = CONSP (def) ? XCAR (def) : def; 1162 {format, prompt,
1163 prompt = Fformat (3, args); 1163 CONSP (def) ? XCAR (def) : def}));
1164 } 1164 }
1165 1165
1166 result = Fcompleting_read (prompt, intern ("internal-complete-buffer"), 1166 result = Fcompleting_read (prompt, intern ("internal-complete-buffer"),
@@ -1168,13 +1168,8 @@ function, instead of the usual behavior. */)
1168 Qbuffer_name_history, def, Qnil); 1168 Qbuffer_name_history, def, Qnil);
1169 } 1169 }
1170 else 1170 else
1171 { 1171 result = Ffuncall (4, ((Lisp_Object [])
1172 args[0] = Vread_buffer_function; 1172 { Vread_buffer_function, prompt, def, require_match }));
1173 args[1] = prompt;
1174 args[2] = def;
1175 args[3] = require_match;
1176 result = Ffuncall (4, args);
1177 }
1178 return unbind_to (count, result); 1173 return unbind_to (count, result);
1179} 1174}
1180 1175
diff --git a/src/msdos.c b/src/msdos.c
index dae86b5a3b2..14c2624114d 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -1792,7 +1792,7 @@ internal_terminal_init (void)
1792 } 1792 }
1793 1793
1794 Vinitial_window_system = Qpc; 1794 Vinitial_window_system = Qpc;
1795 Vwindow_system_version = make_number (24); /* RE Emacs version */ 1795 Vwindow_system_version = make_number (25); /* RE Emacs version */
1796 tty->terminal->type = output_msdos_raw; 1796 tty->terminal->type = output_msdos_raw;
1797 1797
1798 /* If Emacs was dumped on DOS/V machine, forget the stale VRAM 1798 /* If Emacs was dumped on DOS/V machine, forget the stale VRAM
diff --git a/src/nsfns.m b/src/nsfns.m
index ca8f4922ccd..a93b2724403 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -46,10 +46,8 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
46 46
47#ifdef NS_IMPL_COCOA 47#ifdef NS_IMPL_COCOA
48#include <IOKit/graphics/IOGraphicsLib.h> 48#include <IOKit/graphics/IOGraphicsLib.h>
49#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
50#include "macfont.h" 49#include "macfont.h"
51#endif 50#endif
52#endif
53 51
54#if 0 52#if 0
55int fns_trace_num = 1; 53int fns_trace_num = 1;
@@ -135,7 +133,7 @@ check_ns_display_info (Lisp_Object object)
135 } 133 }
136 else if (TERMINALP (object)) 134 else if (TERMINALP (object))
137 { 135 {
138 struct terminal *t = get_terminal (object, 1); 136 struct terminal *t = decode_live_terminal (object);
139 137
140 if (t->type != output_ns) 138 if (t->type != output_ns)
141 error ("Terminal %d is not a Nextstep display", t->id); 139 error ("Terminal %d is not a Nextstep display", t->id);
@@ -197,7 +195,7 @@ ns_display_info_for_name (Lisp_Object name)
197static NSString * 195static NSString *
198ns_filename_from_panel (NSSavePanel *panel) 196ns_filename_from_panel (NSSavePanel *panel)
199{ 197{
200#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 198#ifdef NS_IMPL_COCOA
201 NSURL *url = [panel URL]; 199 NSURL *url = [panel URL];
202 NSString *str = [url path]; 200 NSString *str = [url path];
203 return str; 201 return str;
@@ -209,7 +207,7 @@ ns_filename_from_panel (NSSavePanel *panel)
209static NSString * 207static NSString *
210ns_directory_from_panel (NSSavePanel *panel) 208ns_directory_from_panel (NSSavePanel *panel)
211{ 209{
212#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 210#ifdef NS_IMPL_COCOA
213 NSURL *url = [panel directoryURL]; 211 NSURL *url = [panel directoryURL];
214 NSString *str = [url path]; 212 NSString *str = [url path];
215 return str; 213 return str;
@@ -1197,13 +1195,10 @@ This function is an internal primitive--use `make-frame' instead. */)
1197 block_input (); 1195 block_input ();
1198 1196
1199#ifdef NS_IMPL_COCOA 1197#ifdef NS_IMPL_COCOA
1200#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
1201 if (CTGetCoreTextVersion != NULL
1202 && CTGetCoreTextVersion () >= kCTVersionNumber10_5)
1203 mac_register_font_driver (f); 1198 mac_register_font_driver (f);
1199#else
1200 register_font_driver (&nsfont_driver, f);
1204#endif 1201#endif
1205#endif
1206 register_font_driver (&nsfont_driver, f);
1207 1202
1208 x_default_parameter (f, parms, Qfont_backend, Qnil, 1203 x_default_parameter (f, parms, Qfont_backend, Qnil,
1209 "fontBackend", "FontBackend", RES_TYPE_STRING); 1204 "fontBackend", "FontBackend", RES_TYPE_STRING);
@@ -1244,7 +1239,7 @@ This function is an internal primitive--use `make-frame' instead. */)
1244 "verticalScrollBars", "VerticalScrollBars", 1239 "verticalScrollBars", "VerticalScrollBars",
1245 RES_TYPE_SYMBOL); 1240 RES_TYPE_SYMBOL);
1246 } 1241 }
1247 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qt, 1242 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
1248 "horizontalScrollBars", "HorizontalScrollBars", 1243 "horizontalScrollBars", "HorizontalScrollBars",
1249 RES_TYPE_SYMBOL); 1244 RES_TYPE_SYMBOL);
1250 x_default_parameter (f, parms, Qforeground_color, build_string ("Black"), 1245 x_default_parameter (f, parms, Qforeground_color, build_string ("Black"),
@@ -1414,13 +1409,11 @@ DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
1414 id fm = [NSFontManager sharedFontManager]; 1409 id fm = [NSFontManager sharedFontManager];
1415 struct font *font = f->output_data.ns->font; 1410 struct font *font = f->output_data.ns->font;
1416 NSFont *nsfont; 1411 NSFont *nsfont;
1417 if (EQ (font->driver->type, Qns)) 1412#ifdef NS_IMPL_GNUSTEP
1418 nsfont = ((struct nsfont_info *)font)->nsfont; 1413 nsfont = ((struct nsfont_info *)font)->nsfont;
1419#ifdef NS_IMPL_COCOA
1420#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
1421 else
1422 nsfont = (NSFont *) macfont_get_nsctfont (font);
1423#endif 1414#endif
1415#ifdef NS_IMPL_COCOA
1416 nsfont = (NSFont *) macfont_get_nsctfont (font);
1424#endif 1417#endif
1425 [fm setSelectedFont: nsfont isMultiple: NO]; 1418 [fm setSelectedFont: nsfont isMultiple: NO];
1426 [fm orderFrontFontPanel: NSApp]; 1419 [fm orderFrontFontPanel: NSApp];
@@ -1442,8 +1435,7 @@ static struct
1442{ 1435{
1443 id panel; 1436 id panel;
1444 BOOL ret; 1437 BOOL ret;
1445#if ! defined (NS_IMPL_COCOA) || \ 1438#ifdef NS_IMPL_GNUSTEP
1446 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
1447 NSString *dirS, *initS; 1439 NSString *dirS, *initS;
1448 BOOL no_types; 1440 BOOL no_types;
1449#endif 1441#endif
@@ -1453,8 +1445,7 @@ void
1453ns_run_file_dialog (void) 1445ns_run_file_dialog (void)
1454{ 1446{
1455 if (ns_fd_data.panel == nil) return; 1447 if (ns_fd_data.panel == nil) return;
1456#if defined (NS_IMPL_COCOA) && \ 1448#ifdef NS_IMPL_COCOA
1457 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
1458 ns_fd_data.ret = [ns_fd_data.panel runModal]; 1449 ns_fd_data.ret = [ns_fd_data.panel runModal];
1459#else 1450#else
1460 if (ns_fd_data.no_types) 1451 if (ns_fd_data.no_types)
@@ -1534,8 +1525,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1534 block_input (); 1525 block_input ();
1535 ns_fd_data.panel = panel; 1526 ns_fd_data.panel = panel;
1536 ns_fd_data.ret = NO; 1527 ns_fd_data.ret = NO;
1537#if defined (NS_IMPL_COCOA) && \ 1528#ifdef NS_IMPL_COCOA
1538 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
1539 if (! NILP (mustmatch) || ! NILP (dir_only_p)) 1529 if (! NILP (mustmatch) || ! NILP (dir_only_p))
1540 [panel setAllowedFileTypes: nil]; 1530 [panel setAllowedFileTypes: nil];
1541 if (dirS) [panel setDirectoryURL: [NSURL fileURLWithPath: dirS]]; 1531 if (dirS) [panel setDirectoryURL: [NSURL fileURLWithPath: dirS]];
@@ -1995,7 +1985,7 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
1995 doc: /* List available Nextstep services by querying NSApp. */) 1985 doc: /* List available Nextstep services by querying NSApp. */)
1996 (void) 1986 (void)
1997{ 1987{
1998#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 1988#ifdef NS_IMPL_COCOA
1999 /* You can't get services like this in 10.6+. */ 1989 /* You can't get services like this in 10.6+. */
2000 return Qnil; 1990 return Qnil;
2001#else 1991#else
@@ -2551,7 +2541,7 @@ the attributes:
2551Internal use only, use `display-monitor-attributes-list' instead. */) 2541Internal use only, use `display-monitor-attributes-list' instead. */)
2552 (Lisp_Object terminal) 2542 (Lisp_Object terminal)
2553{ 2543{
2554 struct terminal *term = get_terminal (terminal, 1); 2544 struct terminal *term = decode_live_terminal (terminal);
2555 NSArray *screens; 2545 NSArray *screens;
2556 NSUInteger i, n_monitors; 2546 NSUInteger i, n_monitors;
2557 struct MonitorInfo *monitors; 2547 struct MonitorInfo *monitors;
diff --git a/src/nsfont.m b/src/nsfont.m
index 98c25fcdedd..13c7b0bce2c 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -627,8 +627,8 @@ static Lisp_Object nsfont_open (struct frame *f, Lisp_Object font_entity,
627static void nsfont_close (struct font *font); 627static void nsfont_close (struct font *font);
628static int nsfont_has_char (Lisp_Object entity, int c); 628static int nsfont_has_char (Lisp_Object entity, int c);
629static unsigned int nsfont_encode_char (struct font *font, int c); 629static unsigned int nsfont_encode_char (struct font *font, int c);
630static int nsfont_text_extents (struct font *font, unsigned int *code, 630static void nsfont_text_extents (struct font *font, unsigned int *code,
631 int nglyphs, struct font_metrics *metrics); 631 int nglyphs, struct font_metrics *metrics);
632static int nsfont_draw (struct glyph_string *s, int from, int to, int x, int y, 632static int nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
633 bool with_background); 633 bool with_background);
634 634
@@ -988,9 +988,9 @@ nsfont_encode_char (struct font *font, int c)
988/* Perform the size computation of glyphs of FONT and fill in members 988/* Perform the size computation of glyphs of FONT and fill in members
989 of METRICS. The glyphs are specified by their glyph codes in 989 of METRICS. The glyphs are specified by their glyph codes in
990 CODE (length NGLYPHS). */ 990 CODE (length NGLYPHS). */
991static int 991static void
992nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs, 992nsfont_text_extents (struct font *font, unsigned int *code,
993 struct font_metrics *metrics) 993 int nglyphs, struct font_metrics *metrics)
994{ 994{
995 struct nsfont_info *font_info = (struct nsfont_info *)font; 995 struct nsfont_info *font_info = (struct nsfont_info *)font;
996 struct font_metrics *pcm; 996 struct font_metrics *pcm;
@@ -1000,7 +1000,7 @@ nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
1000 1000
1001 memset (metrics, 0, sizeof (struct font_metrics)); 1001 memset (metrics, 0, sizeof (struct font_metrics));
1002 1002
1003 for (i =0; i<nglyphs; i++) 1003 for (i = 0; i < nglyphs; i++)
1004 { 1004 {
1005 /* get metrics for this glyph, filling cache if need be */ 1005 /* get metrics for this glyph, filling cache if need be */
1006 /* TODO: get metrics for whole string from an NSLayoutManager 1006 /* TODO: get metrics for whole string from an NSLayoutManager
@@ -1024,8 +1024,6 @@ nsfont_text_extents (struct font *font, unsigned int *code, int nglyphs,
1024 } 1024 }
1025 1025
1026 metrics->width = totalWidth; 1026 metrics->width = totalWidth;
1027
1028 return totalWidth; /* not specified in doc, but xfont.c does it */
1029} 1027}
1030 1028
1031 1029
@@ -1041,8 +1039,13 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1041 static unsigned char cbuf[1024]; 1039 static unsigned char cbuf[1024];
1042 unsigned char *c = cbuf; 1040 unsigned char *c = cbuf;
1043#ifdef NS_IMPL_GNUSTEP 1041#ifdef NS_IMPL_GNUSTEP
1042#if GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION > 22
1043 static CGFloat advances[1024];
1044 CGFloat *adv = advances;
1045#else
1044 static float advances[1024]; 1046 static float advances[1024];
1045 float *adv = advances; 1047 float *adv = advances;
1048#endif
1046#else 1049#else
1047 static CGSize advances[1024]; 1050 static CGSize advances[1024];
1048 CGSize *adv = advances; 1051 CGSize *adv = advances;
diff --git a/src/nsimage.m b/src/nsimage.m
index 6b68072b87a..71e5f8aa5c6 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -188,7 +188,7 @@ static EmacsImage *ImageList = nil;
188 image = [[EmacsImage alloc] initByReferencingFile: 188 image = [[EmacsImage alloc] initByReferencingFile:
189 [NSString stringWithUTF8String: SSDATA (found)]]; 189 [NSString stringWithUTF8String: SSDATA (found)]];
190 190
191#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 191#ifdef NS_IMPL_COCOA
192 imgRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]]; 192 imgRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
193#else 193#else
194 imgRep = [image bestRepresentationForDevice: nil]; 194 imgRep = [image bestRepresentationForDevice: nil];
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 778b068ef8b..a90cb970874 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -492,11 +492,9 @@ void
492x_activate_menubar (struct frame *f) 492x_activate_menubar (struct frame *f)
493{ 493{
494#ifdef NS_IMPL_COCOA 494#ifdef NS_IMPL_COCOA
495#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
496 ns_update_menubar (f, true, nil); 495 ns_update_menubar (f, true, nil);
497 ns_check_pending_open_menu (); 496 ns_check_pending_open_menu ();
498#endif 497#endif
499#endif
500} 498}
501 499
502 500
@@ -542,23 +540,14 @@ x_activate_menubar (struct frame *f)
542} 540}
543 541
544#ifdef NS_IMPL_COCOA 542#ifdef NS_IMPL_COCOA
545#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
546extern NSString *NSMenuDidBeginTrackingNotification;
547#endif
548#endif
549
550#ifdef NS_IMPL_COCOA
551-(void)trackingNotification:(NSNotification *)notification 543-(void)trackingNotification:(NSNotification *)notification
552{ 544{
553 /* Update menu in menuNeedsUpdate only while tracking menus. */ 545 /* Update menu in menuNeedsUpdate only while tracking menus. */
554 trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification 546 trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
555 ? 1 : 0); 547 ? 1 : 0);
556#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
557 if (! trackingMenu) ns_check_menu_open (nil); 548 if (! trackingMenu) ns_check_menu_open (nil);
558#endif
559} 549}
560 550
561#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
562- (void)menuWillOpen:(NSMenu *)menu 551- (void)menuWillOpen:(NSMenu *)menu
563{ 552{
564 ++trackingMenu; 553 ++trackingMenu;
@@ -579,7 +568,6 @@ extern NSString *NSMenuDidBeginTrackingNotification;
579{ 568{
580 --trackingMenu; 569 --trackingMenu;
581} 570}
582#endif /* OSX >= 10.5 */
583 571
584#endif /* NS_IMPL_COCOA */ 572#endif /* NS_IMPL_COCOA */
585 573
@@ -608,8 +596,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
608 if (trackingMenu == 0) 596 if (trackingMenu == 0)
609 return; 597 return;
610/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ 598/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
611#if (! defined (NS_IMPL_COCOA) \ 599#ifdef NS_IMPL_GNUSTEP
612 || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
613 /* Don't know how to do this for anything other than OSX >= 10.5 600 /* Don't know how to do this for anything other than OSX >= 10.5
614 This is wrong, as it might run Lisp code in the event loop. */ 601 This is wrong, as it might run Lisp code in the event loop. */
615 ns_update_menubar (frame, true, self); 602 ns_update_menubar (frame, true, self);
@@ -706,9 +693,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
706 { 693 {
707 NSMenuItem *item = [self itemAtIndex: n]; 694 NSMenuItem *item = [self itemAtIndex: n];
708 NSString *title = [item title]; 695 NSString *title = [item title];
709 if (([title length] == 0 /* OSX 10.5 */ 696 if ([ns_app_name isEqualToString: title]
710 || [ns_app_name isEqualToString: title] /* from 10.6 on */
711 || [@"Apple" isEqualToString: title]) /* older */
712 && ![item isSeparatorItem]) 697 && ![item isSeparatorItem])
713 continue; 698 continue;
714 [self removeItemAtIndex: n]; 699 [self removeItemAtIndex: n];
diff --git a/src/nsselect.m b/src/nsselect.m
index 038849c0aed..3712ba064e7 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -328,19 +328,14 @@ ns_string_to_pasteboard (id pb, Lisp_Object str)
328 ========================================================================== */ 328 ========================================================================== */
329 329
330 330
331DEFUN ("x-own-selection-internal", Fx_own_selection_internal, 331DEFUN ("ns-own-selection-internal", Fns_own_selection_internal,
332 Sx_own_selection_internal, 2, 3, 0, 332 Sns_own_selection_internal, 2, 2, 0,
333 doc: /* Assert an X selection of type SELECTION and value VALUE. 333 doc: /* Assert an X selection of type SELECTION and value VALUE.
334SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. 334SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
335\(Those are literal upper-case symbol names, since that's what X expects.) 335\(Those are literal upper-case symbol names, since that's what X expects.)
336VALUE is typically a string, or a cons of two markers, but may be 336VALUE is typically a string, or a cons of two markers, but may be
337anything that the functions on `selection-converter-alist' know about. 337anything that the functions on `selection-converter-alist' know about. */)
338 338 (Lisp_Object selection, Lisp_Object value)
339FRAME should be a frame that should own the selection. If omitted or
340nil, it defaults to the selected frame.
341
342On Nextstep, FRAME is unused. */)
343 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
344{ 339{
345 id pb; 340 id pb;
346 Lisp_Object old_value, new_value; 341 Lisp_Object old_value, new_value;
@@ -385,21 +380,11 @@ On Nextstep, FRAME is unused. */)
385} 380}
386 381
387 382
388DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal, 383DEFUN ("ns-disown-selection-internal", Fns_disown_selection_internal,
389 Sx_disown_selection_internal, 1, 3, 0, 384 Sns_disown_selection_internal, 1, 1, 0,
390 doc: /* If we own the selection SELECTION, disown it. 385 doc: /* If we own the selection SELECTION, disown it.
391Disowning it means there is no such selection. 386Disowning it means there is no such selection. */)
392 387 (Lisp_Object selection)
393Sets the last-change time for the selection to TIME-OBJECT (by default
394the time of the last event).
395
396TERMINAL should be a terminal object or a frame specifying the X
397server to query. If omitted or nil, that stands for the selected
398frame's display, or the first available X display.
399
400On Nextstep, the TIME-OBJECT and TERMINAL arguments are unused.
401On MS-DOS, all this does is return non-nil if we own the selection. */)
402 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
403{ 388{
404 id pb; 389 id pb;
405 check_window_system (NULL); 390 check_window_system (NULL);
@@ -443,7 +428,7 @@ On Nextstep, TERMINAL is unused. */)
443} 428}
444 429
445 430
446DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p, 431DEFUN ("ns-selection-owner-p", Fns_selection_owner_p, Sns_selection_owner_p,
447 0, 2, 0, 432 0, 2, 0,
448 doc: /* Whether the current Emacs process owns the given X Selection. 433 doc: /* Whether the current Emacs process owns the given X Selection.
449The arg should be the name of the selection in question, typically one of 434The arg should be the name of the selection in question, typically one of
@@ -507,7 +492,7 @@ On Nextstep, TIME-STAMP and TERMINAL are unused. */)
507DEFUN ("ns-get-selection-internal", Fns_get_selection_internal, 492DEFUN ("ns-get-selection-internal", Fns_get_selection_internal,
508 Sns_get_selection_internal, 1, 1, 0, 493 Sns_get_selection_internal, 1, 1, 0,
509 doc: /* Returns the value of SELECTION as a string. 494 doc: /* Returns the value of SELECTION as a string.
510SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */) 495SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
511 (Lisp_Object selection) 496 (Lisp_Object selection)
512{ 497{
513 id pb; 498 id pb;
@@ -520,7 +505,7 @@ SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
520DEFUN ("ns-store-selection-internal", Fns_store_selection_internal, 505DEFUN ("ns-store-selection-internal", Fns_store_selection_internal,
521 Sns_store_selection_internal, 2, 2, 0, 506 Sns_store_selection_internal, 2, 2, 0,
522 doc: /* Sets the string value of SELECTION. 507 doc: /* Sets the string value of SELECTION.
523SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */) 508SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
524 (Lisp_Object selection, Lisp_Object string) 509 (Lisp_Object selection, Lisp_Object string)
525{ 510{
526 id pb; 511 id pb;
@@ -546,11 +531,11 @@ syms_of_nsselect (void)
546 QTEXT = intern_c_string ("TEXT"); staticpro (&QTEXT); 531 QTEXT = intern_c_string ("TEXT"); staticpro (&QTEXT);
547 QFILE_NAME = intern_c_string ("FILE_NAME"); staticpro (&QFILE_NAME); 532 QFILE_NAME = intern_c_string ("FILE_NAME"); staticpro (&QFILE_NAME);
548 533
549 defsubr (&Sx_disown_selection_internal); 534 defsubr (&Sns_disown_selection_internal);
550 defsubr (&Sx_get_selection_internal); 535 defsubr (&Sx_get_selection_internal);
551 defsubr (&Sx_own_selection_internal); 536 defsubr (&Sns_own_selection_internal);
552 defsubr (&Sx_selection_exists_p); 537 defsubr (&Sx_selection_exists_p);
553 defsubr (&Sx_selection_owner_p); 538 defsubr (&Sns_selection_owner_p);
554 defsubr (&Sns_get_selection_internal); 539 defsubr (&Sns_get_selection_internal);
555 defsubr (&Sns_store_selection_internal); 540 defsubr (&Sns_store_selection_internal);
556 541
diff --git a/src/nsterm.h b/src/nsterm.h
index 00a0b54add9..f59405fe9af 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -27,12 +27,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
27#ifdef HAVE_NS 27#ifdef HAVE_NS
28 28
29#ifdef NS_IMPL_COCOA 29#ifdef NS_IMPL_COCOA
30#ifndef MAC_OS_X_VERSION_10_4
31#define MAC_OS_X_VERSION_10_4 1040
32#endif
33#ifndef MAC_OS_X_VERSION_10_5
34#define MAC_OS_X_VERSION_10_5 1050
35#endif
36#ifndef MAC_OS_X_VERSION_10_6 30#ifndef MAC_OS_X_VERSION_10_6
37#define MAC_OS_X_VERSION_10_6 1060 31#define MAC_OS_X_VERSION_10_6 1060
38#endif 32#endif
@@ -58,21 +52,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
58 versions. 52 versions.
59 On Cocoa >= 10.5, functions expect CGFloat*. Make compatible type. */ 53 On Cocoa >= 10.5, functions expect CGFloat*. Make compatible type. */
60#ifdef NS_IMPL_COCOA 54#ifdef NS_IMPL_COCOA
61
62#ifndef NS_HAVE_NSINTEGER
63#if defined (__LP64__) && __LP64__
64typedef double CGFloat;
65typedef long NSInteger;
66typedef unsigned long NSUInteger;
67#else
68typedef float CGFloat;
69typedef int NSInteger;
70typedef unsigned int NSUInteger;
71#endif /* not LP64 */
72#endif /* not NS_HAVE_NSINTEGER */
73
74typedef CGFloat EmacsCGFloat; 55typedef CGFloat EmacsCGFloat;
75
76#elif GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION >= 22 56#elif GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION >= 22
77typedef CGFloat EmacsCGFloat; 57typedef CGFloat EmacsCGFloat;
78#else 58#else
@@ -139,7 +119,7 @@ typedef float EmacsCGFloat;
139 119
140@class EmacsToolbar; 120@class EmacsToolbar;
141 121
142#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 122#ifdef NS_IMPL_COCOA
143@interface EmacsView : NSView <NSTextInput, NSWindowDelegate> 123@interface EmacsView : NSView <NSTextInput, NSWindowDelegate>
144#else 124#else
145@interface EmacsView : NSView <NSTextInput> 125@interface EmacsView : NSView <NSTextInput>
@@ -217,7 +197,7 @@ typedef float EmacsCGFloat;
217 197
218 ========================================================================== */ 198 ========================================================================== */
219 199
220#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 200#ifdef NS_IMPL_COCOA
221@interface EmacsMenu : NSMenu <NSMenuDelegate> 201@interface EmacsMenu : NSMenu <NSMenuDelegate>
222#else 202#else
223@interface EmacsMenu : NSMenu 203@interface EmacsMenu : NSMenu
@@ -249,7 +229,7 @@ typedef float EmacsCGFloat;
249 229
250@class EmacsImage; 230@class EmacsImage;
251 231
252#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 232#ifdef NS_IMPL_COCOA
253@interface EmacsToolbar : NSToolbar <NSToolbarDelegate> 233@interface EmacsToolbar : NSToolbar <NSToolbarDelegate>
254#else 234#else
255@interface EmacsToolbar : NSToolbar 235@interface EmacsToolbar : NSToolbar
@@ -305,7 +285,7 @@ typedef float EmacsCGFloat;
305- (void)timeout_handler: (NSTimer *)timedEntry; 285- (void)timeout_handler: (NSTimer *)timedEntry;
306@end 286@end
307 287
308#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 288#ifdef NS_IMPL_COCOA
309@interface EmacsTooltip : NSObject <NSWindowDelegate> 289@interface EmacsTooltip : NSObject <NSWindowDelegate>
310#else 290#else
311@interface EmacsTooltip : NSObject 291@interface EmacsTooltip : NSObject
@@ -401,7 +381,7 @@ typedef float EmacsCGFloat;
401 CGFloat last_mouse_offset; 381 CGFloat last_mouse_offset;
402 float min_portion; 382 float min_portion;
403 int pixel_height; 383 int pixel_height;
404 int last_hit_part; 384 enum scroll_bar_part last_hit_part;
405 385
406 BOOL condemned; 386 BOOL condemned;
407 387
diff --git a/src/nsterm.m b/src/nsterm.m
index 47ad28aaa61..3ae4146dc20 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -65,10 +65,8 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
65#endif 65#endif
66 66
67#ifdef NS_IMPL_COCOA 67#ifdef NS_IMPL_COCOA
68#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
69#include "macfont.h" 68#include "macfont.h"
70#endif 69#endif
71#endif
72 70
73/* call tracing */ 71/* call tracing */
74#if 0 72#if 0
@@ -706,7 +704,6 @@ static void
706ns_update_auto_hide_menu_bar (void) 704ns_update_auto_hide_menu_bar (void)
707{ 705{
708#ifdef NS_IMPL_COCOA 706#ifdef NS_IMPL_COCOA
709#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
710 block_input (); 707 block_input ();
711 708
712 NSTRACE (ns_update_auto_hide_menu_bar); 709 NSTRACE (ns_update_auto_hide_menu_bar);
@@ -739,7 +736,6 @@ ns_update_auto_hide_menu_bar (void)
739 736
740 unblock_input (); 737 unblock_input ();
741#endif 738#endif
742#endif
743} 739}
744 740
745 741
@@ -1930,10 +1926,9 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
1930 position = [view convertPoint: position fromView: nil]; 1926 position = [view convertPoint: position fromView: nil];
1931 remember_mouse_glyph (f, position.x, position.y, 1927 remember_mouse_glyph (f, position.x, position.y,
1932 &dpyinfo->last_mouse_glyph); 1928 &dpyinfo->last_mouse_glyph);
1933/*fprintf (stderr, "ns_mouse_position: %.0f, %.0f\n", position.x, position.y); */
1934 1929
1935 if (bar_window) *bar_window = Qnil; 1930 if (bar_window) *bar_window = Qnil;
1936 if (part) *part = 0; /*scroll_bar_handle; */ 1931 if (part) *part = scroll_bar_above_handle;
1937 1932
1938 if (x) XSETINT (*x, lrint (position.x)); 1933 if (x) XSETINT (*x, lrint (position.x));
1939 if (y) XSETINT (*y, lrint (position.y)); 1934 if (y) XSETINT (*y, lrint (position.y));
@@ -2347,8 +2342,19 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2347 to erase the whole background. */ 2342 to erase the whole background. */
2348 [ns_lookup_indexed_color(face->background, f) set]; 2343 [ns_lookup_indexed_color(face->background, f) set];
2349 NSRectFill (r); 2344 NSRectFill (r);
2350 [img setXBMColor: ns_lookup_indexed_color(face->foreground, f)]; 2345
2351#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 2346 {
2347 NSColor *bm_color;
2348 if (!p->cursor_p)
2349 bm_color = ns_lookup_indexed_color(face->foreground, f);
2350 else if (p->overlay_p)
2351 bm_color = ns_lookup_indexed_color(face->background, f);
2352 else
2353 bm_color = f->output_data.ns->cursor_color;
2354 [img setXBMColor: bm_color];
2355 }
2356
2357#ifdef NS_IMPL_COCOA
2352 [img drawInRect: r 2358 [img drawInRect: r
2353 fromRect: NSZeroRect 2359 fromRect: NSZeroRect
2354 operation: NSCompositeSourceOver 2360 operation: NSCompositeSourceOver
@@ -2431,7 +2437,10 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2431 else if (cursor_type == HBAR_CURSOR) 2437 else if (cursor_type == HBAR_CURSOR)
2432 { 2438 {
2433 cursor_height = (cursor_width < 1) ? lrint (0.25 * h) : cursor_width; 2439 cursor_height = (cursor_width < 1) ? lrint (0.25 * h) : cursor_width;
2434 fy += h - cursor_height; 2440 if (cursor_height > glyph_row->height)
2441 cursor_height = glyph_row->height;
2442 if (h > cursor_height) // Cursor smaller than line height, move down
2443 fy += h - cursor_height;
2435 h = cursor_height; 2444 h = cursor_height;
2436 } 2445 }
2437 2446
@@ -3024,7 +3033,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
3024 /* Draw the image.. do we need to draw placeholder if img ==nil? */ 3033 /* Draw the image.. do we need to draw placeholder if img ==nil? */
3025 if (img != nil) 3034 if (img != nil)
3026 { 3035 {
3027#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 3036#ifdef NS_IMPL_COCOA
3028 NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height); 3037 NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height);
3029 NSRect ir = NSMakeRect (s->slice.x, s->slice.y, 3038 NSRect ir = NSMakeRect (s->slice.x, s->slice.y,
3030 s->slice.width, s->slice.height); 3039 s->slice.width, s->slice.height);
@@ -3436,9 +3445,8 @@ check_native_fs ()
3436} 3445}
3437#endif 3446#endif
3438 3447
3439/* GNUstep and OSX <= 10.4 does not have cancelTracking. */ 3448/* GNUstep does not have cancelTracking. */
3440#if defined (NS_IMPL_COCOA) && \ 3449#ifdef NS_IMPL_COCOA
3441 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
3442/* Check if menu open should be canceled or continued as normal. */ 3450/* Check if menu open should be canceled or continued as normal. */
3443void 3451void
3444ns_check_menu_open (NSMenu *menu) 3452ns_check_menu_open (NSMenu *menu)
@@ -3501,7 +3509,16 @@ ns_check_pending_open_menu ()
3501 menu_will_open_state = MENU_OPENING; 3509 menu_will_open_state = MENU_OPENING;
3502 } 3510 }
3503} 3511}
3504#endif /* NS_IMPL_COCOA) && >= MAC_OS_X_VERSION_10_5 */ 3512#endif /* NS_IMPL_COCOA */
3513
3514static void
3515unwind_apploopnr (Lisp_Object not_used)
3516{
3517 --apploopnr;
3518 n_emacs_events_pending = 0;
3519 ns_finish_events ();
3520 q_event_ptr = NULL;
3521}
3505 3522
3506static int 3523static int
3507ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) 3524ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
@@ -3560,6 +3577,7 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3560 } 3577 }
3561 else 3578 else
3562 { 3579 {
3580 ptrdiff_t specpdl_count = SPECPDL_INDEX ();
3563 /* Run and wait for events. We must always send one NX_APPDEFINED event 3581 /* Run and wait for events. We must always send one NX_APPDEFINED event
3564 to ourself, otherwise [NXApp run] will never exit. */ 3582 to ourself, otherwise [NXApp run] will never exit. */
3565 send_appdefined = YES; 3583 send_appdefined = YES;
@@ -3569,8 +3587,9 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3569 { 3587 {
3570 emacs_abort (); 3588 emacs_abort ();
3571 } 3589 }
3590 record_unwind_protect (unwind_apploopnr, Qt);
3572 [NSApp run]; 3591 [NSApp run];
3573 --apploopnr; 3592 unbind_to (specpdl_count, Qnil); /* calls unwind_apploopnr */
3574 } 3593 }
3575 3594
3576 nevents = n_emacs_events_pending; 3595 nevents = n_emacs_events_pending;
@@ -3677,8 +3696,14 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3677 { 3696 {
3678 emacs_abort (); 3697 emacs_abort ();
3679 } 3698 }
3680 [NSApp run]; 3699
3681 --apploopnr; 3700 {
3701 ptrdiff_t specpdl_count = SPECPDL_INDEX ();
3702 record_unwind_protect (unwind_apploopnr, Qt);
3703 [NSApp run];
3704 unbind_to (specpdl_count, Qnil); /* calls unwind_apploopnr */
3705 }
3706
3682 ns_finish_events (); 3707 ns_finish_events ();
3683 if (nr > 0 && readfds) 3708 if (nr > 0 && readfds)
3684 { 3709 {
@@ -4493,7 +4518,7 @@ ns_term_shutdown (int sig)
4493#define NSAppKitVersionNumber10_8 1187 4518#define NSAppKitVersionNumber10_8 1187
4494#endif 4519#endif
4495 4520
4496 if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_8) 4521 if (NSAppKitVersionNumber <= NSAppKitVersionNumber10_8)
4497 { 4522 {
4498 [super run]; 4523 [super run];
4499 return; 4524 return;
@@ -4690,14 +4715,12 @@ ns_term_shutdown (int sig)
4690 4715
4691 [self antialiasThresholdDidChange:nil]; 4716 [self antialiasThresholdDidChange:nil];
4692#ifdef NS_IMPL_COCOA 4717#ifdef NS_IMPL_COCOA
4693#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
4694 [[NSNotificationCenter defaultCenter] 4718 [[NSNotificationCenter defaultCenter]
4695 addObserver:self 4719 addObserver:self
4696 selector:@selector(antialiasThresholdDidChange:) 4720 selector:@selector(antialiasThresholdDidChange:)
4697 name:NSAntialiasThresholdChangedNotification 4721 name:NSAntialiasThresholdChangedNotification
4698 object:nil]; 4722 object:nil];
4699#endif 4723#endif
4700#endif
4701 4724
4702 ns_send_appdefined (-2); 4725 ns_send_appdefined (-2);
4703} 4726}
@@ -4705,10 +4728,8 @@ ns_term_shutdown (int sig)
4705- (void)antialiasThresholdDidChange:(NSNotification *)notification 4728- (void)antialiasThresholdDidChange:(NSNotification *)notification
4706{ 4729{
4707#ifdef NS_IMPL_COCOA 4730#ifdef NS_IMPL_COCOA
4708#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
4709 macfont_update_antialias_threshold (); 4731 macfont_update_antialias_threshold ();
4710#endif 4732#endif
4711#endif
4712} 4733}
4713 4734
4714 4735
@@ -5048,13 +5069,11 @@ not_in_argv (NSString *arg)
5048 if (!emacs_event) 5069 if (!emacs_event)
5049 return; 5070 return;
5050 5071
5051 if (EQ (font->driver->type, Qns)) 5072#ifdef NS_IMPL_GNUSTEP
5052 nsfont = ((struct nsfont_info *)font)->nsfont; 5073 nsfont = ((struct nsfont_info *)font)->nsfont;
5053#ifdef NS_IMPL_COCOA
5054#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
5055 else
5056 nsfont = (NSFont *) macfont_get_nsctfont (font);
5057#endif 5074#endif
5075#ifdef NS_IMPL_COCOA
5076 nsfont = (NSFont *) macfont_get_nsctfont (font);
5058#endif 5077#endif
5059 5078
5060 if ((newFont = [sender convertFont: nsfont])) 5079 if ((newFont = [sender convertFont: nsfont]))
@@ -5106,7 +5125,7 @@ not_in_argv (NSString *arg)
5106 int code; 5125 int code;
5107 unsigned fnKeysym = 0; 5126 unsigned fnKeysym = 0;
5108 static NSMutableArray *nsEvArray; 5127 static NSMutableArray *nsEvArray;
5109#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 5128#ifdef NS_IMPL_GNUSTEP
5110 static BOOL firstTime = YES; 5129 static BOOL firstTime = YES;
5111#endif 5130#endif
5112 int left_is_none; 5131 int left_is_none;
@@ -5337,7 +5356,7 @@ not_in_argv (NSString *arg)
5337 } 5356 }
5338 5357
5339 5358
5340#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 5359#ifdef NS_IMPL_GNUSTEP
5341 /* if we get here we should send the key for input manager processing */ 5360 /* if we get here we should send the key for input manager processing */
5342 /* Disable warning, there is nothing a user can do about it anyway, and 5361 /* Disable warning, there is nothing a user can do about it anyway, and
5343 it does not seem to matter. */ 5362 it does not seem to matter. */
@@ -5797,7 +5816,8 @@ not_in_argv (NSString *arg)
5797 { 5816 {
5798#ifdef NS_IMPL_GNUSTEP 5817#ifdef NS_IMPL_GNUSTEP
5799 // GNUstep does not always update the tool bar height. Force it. 5818 // GNUstep does not always update the tool bar height. Force it.
5800 if (toolbar) update_frame_tool_bar (emacsframe); 5819 if (toolbar && [toolbar isVisible])
5820 update_frame_tool_bar (emacsframe);
5801#endif 5821#endif
5802 5822
5803 extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) 5823 extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
@@ -5838,10 +5858,13 @@ not_in_argv (NSString *arg)
5838 5858
5839 // Did resize increments change because of a font change? 5859 // Did resize increments change because of a font change?
5840 if (sz.width != FRAME_COLUMN_WIDTH (emacsframe) || 5860 if (sz.width != FRAME_COLUMN_WIDTH (emacsframe) ||
5841 sz.height != FRAME_LINE_HEIGHT (emacsframe)) 5861 sz.height != FRAME_LINE_HEIGHT (emacsframe) ||
5862 (frame_resize_pixelwise && sz.width != 1))
5842 { 5863 {
5843 sz.width = FRAME_COLUMN_WIDTH (emacsframe); 5864 sz.width = frame_resize_pixelwise
5844 sz.height = FRAME_LINE_HEIGHT (emacsframe); 5865 ? 1 : FRAME_COLUMN_WIDTH (emacsframe);
5866 sz.height = frame_resize_pixelwise
5867 ? 1 : FRAME_LINE_HEIGHT (emacsframe);
5845 [win setResizeIncrements: sz]; 5868 [win setResizeIncrements: sz];
5846 5869
5847 NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); 5870 NSTRACE_SIZE ("New size", NSMakeSize (neww, newh));
@@ -6111,8 +6134,8 @@ if (cols > 0 && rows > 0)
6111 [win setDelegate: self]; 6134 [win setDelegate: self];
6112 [win useOptimizedDrawing: YES]; 6135 [win useOptimizedDrawing: YES];
6113 6136
6114 sz.width = FRAME_COLUMN_WIDTH (f); 6137 sz.width = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
6115 sz.height = FRAME_LINE_HEIGHT (f); 6138 sz.height = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
6116 [win setResizeIncrements: sz]; 6139 [win setResizeIncrements: sz];
6117 6140
6118 [[win contentView] addSubview: self]; 6141 [[win contentView] addSubview: self];
@@ -6459,8 +6482,8 @@ if (cols > 0 && rows > 0)
6459 (FRAME_DEFAULT_FACE (f)), 6482 (FRAME_DEFAULT_FACE (f)),
6460 f); 6483 f);
6461 6484
6462 sz.width = FRAME_COLUMN_WIDTH (f); 6485 sz.width = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
6463 sz.height = FRAME_LINE_HEIGHT (f); 6486 sz.height = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
6464 6487
6465 if (fs_state != FULLSCREEN_BOTH) 6488 if (fs_state != FULLSCREEN_BOTH)
6466 { 6489 {
@@ -6475,8 +6498,7 @@ if (cols > 0 && rows > 0)
6475 /* Hide dock and menubar if we are on the primary screen. */ 6498 /* Hide dock and menubar if we are on the primary screen. */
6476 if (onFirstScreen) 6499 if (onFirstScreen)
6477 { 6500 {
6478#if defined (NS_IMPL_COCOA) && \ 6501#ifdef NS_IMPL_COCOA
6479 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
6480 NSApplicationPresentationOptions options 6502 NSApplicationPresentationOptions options
6481 = NSApplicationPresentationAutoHideDock 6503 = NSApplicationPresentationAutoHideDock
6482 | NSApplicationPresentationAutoHideMenuBar; 6504 | NSApplicationPresentationAutoHideMenuBar;
@@ -6516,7 +6538,7 @@ if (cols > 0 && rows > 0)
6516 [fw makeFirstResponder:self]; 6538 [fw makeFirstResponder:self];
6517 [w orderOut:self]; 6539 [w orderOut:self];
6518 r = [fw frameRectForContentRect:[screen frame]]; 6540 r = [fw frameRectForContentRect:[screen frame]];
6519 [fw setFrame: r display:YES animate:YES]; 6541 [fw setFrame: r display:YES animate:ns_use_fullscreen_animation];
6520 [self windowDidEnterFullScreen:nil]; 6542 [self windowDidEnterFullScreen:nil];
6521 [fw display]; 6543 [fw display];
6522 } 6544 }
@@ -6528,8 +6550,7 @@ if (cols > 0 && rows > 0)
6528 6550
6529 if (onFirstScreen) 6551 if (onFirstScreen)
6530 { 6552 {
6531#if defined (NS_IMPL_COCOA) && \ 6553#ifdef NS_IMPL_COCOA
6532 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
6533 [NSApp setPresentationOptions: NSApplicationPresentationDefault]; 6554 [NSApp setPresentationOptions: NSApplicationPresentationDefault];
6534#else 6555#else
6535 [NSMenu setMenuBarVisible:YES]; 6556 [NSMenu setMenuBarVisible:YES];
@@ -6548,7 +6569,7 @@ if (cols > 0 && rows > 0)
6548 FRAME_TOOLBAR_HEIGHT (f) = tobar_height; 6569 FRAME_TOOLBAR_HEIGHT (f) = tobar_height;
6549 6570
6550 [self windowWillExitFullScreen:nil]; 6571 [self windowWillExitFullScreen:nil];
6551 [fw setFrame: [w frame] display:YES animate:YES]; 6572 [fw setFrame: [w frame] display:YES animate:ns_use_fullscreen_animation];
6552 [fw close]; 6573 [fw close];
6553 [w makeKeyAndOrderFront:NSApp]; 6574 [w makeKeyAndOrderFront:NSApp];
6554 [self windowDidExitFullScreen:nil]; 6575 [self windowDidExitFullScreen:nil];
@@ -6854,7 +6875,7 @@ if (cols > 0 && rows > 0)
6854 } 6875 }
6855 else 6876 else
6856 { 6877 {
6857 error ("Invalid data type in dragging pasteboard"); 6878 fprintf (stderr, "Invalid data type in dragging pasteboard");
6858 return NO; 6879 return NO;
6859 } 6880 }
6860} 6881}
@@ -7044,7 +7065,7 @@ if (cols > 0 && rows > 0)
7044#endif 7065#endif
7045#endif 7066#endif
7046 7067
7047 for (i = 0; i < nr_screens; ++i) 7068 for (i = 0; i < nr_screens; ++i)
7048 { 7069 {
7049 NSScreen *s = [screens objectAtIndex: i]; 7070 NSScreen *s = [screens objectAtIndex: i];
7050 NSRect scrrect = [s frame]; 7071 NSRect scrrect = [s frame];
@@ -7251,7 +7272,7 @@ if (cols > 0 && rows > 0)
7251 7272
7252 if (portion >= whole) 7273 if (portion >= whole)
7253 { 7274 {
7254#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 7275#ifdef NS_IMPL_COCOA
7255 [self setKnobProportion: 1.0]; 7276 [self setKnobProportion: 1.0];
7256 [self setDoubleValue: 1.0]; 7277 [self setDoubleValue: 1.0];
7257#else 7278#else
@@ -7265,7 +7286,7 @@ if (cols > 0 && rows > 0)
7265 portion = max ((float)whole*min_portion/pixel_height, portion); 7286 portion = max ((float)whole*min_portion/pixel_height, portion);
7266 pos = (float)position / (whole - portion); 7287 pos = (float)position / (whole - portion);
7267 por = (CGFloat)portion/whole; 7288 por = (CGFloat)portion/whole;
7268#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 7289#ifdef NS_IMPL_COCOA
7269 [self setKnobProportion: por]; 7290 [self setKnobProportion: por];
7270 [self setDoubleValue: pos]; 7291 [self setDoubleValue: pos];
7271#else 7292#else
@@ -7491,7 +7512,7 @@ if (cols > 0 && rows > 0)
7491 [scroll_repeat_entry release]; 7512 [scroll_repeat_entry release];
7492 scroll_repeat_entry = nil; 7513 scroll_repeat_entry = nil;
7493 } 7514 }
7494 last_hit_part = 0; 7515 last_hit_part = scroll_bar_above_handle;
7495} 7516}
7496 7517
7497 7518
@@ -7752,6 +7773,12 @@ Default is t for OSX >= 10.7, nil otherwise. */);
7752#endif 7773#endif
7753 ns_last_use_native_fullscreen = ns_use_native_fullscreen; 7774 ns_last_use_native_fullscreen = ns_use_native_fullscreen;
7754 7775
7776 DEFVAR_BOOL ("ns-use-fullscreen-animation", ns_use_fullscreen_animation,
7777 doc: /*Non-nil means use animation on non-native fullscreen.
7778For native fullscreen, this does nothing.
7779Default is nil. */);
7780 ns_use_fullscreen_animation = NO;
7781
7755 DEFVAR_BOOL ("ns-use-srgb-colorspace", ns_use_srgb_colorspace, 7782 DEFVAR_BOOL ("ns-use-srgb-colorspace", ns_use_srgb_colorspace,
7756 doc: /*Non-nil means to use sRGB colorspace on OSX >= 10.7. 7783 doc: /*Non-nil means to use sRGB colorspace on OSX >= 10.7.
7757Note that this does not apply to images. 7784Note that this does not apply to images.
@@ -7789,14 +7816,12 @@ baseline level. The default value is nil. */);
7789 DEFSYM (Qcocoa, "cocoa"); 7816 DEFSYM (Qcocoa, "cocoa");
7790 DEFSYM (Qgnustep, "gnustep"); 7817 DEFSYM (Qgnustep, "gnustep");
7791 7818
7792 syms_of_nsfont ();
7793#ifdef NS_IMPL_COCOA 7819#ifdef NS_IMPL_COCOA
7794 Fprovide (Qcocoa, Qnil); 7820 Fprovide (Qcocoa, Qnil);
7795#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
7796 syms_of_macfont (); 7821 syms_of_macfont ();
7797#endif
7798#else 7822#else
7799 Fprovide (Qgnustep, Qnil); 7823 Fprovide (Qgnustep, Qnil);
7824 syms_of_nsfont ();
7800#endif 7825#endif
7801 7826
7802} 7827}
diff --git a/src/print.c b/src/print.c
index 57fac7af378..49331ef0984 100644
--- a/src/print.c
+++ b/src/print.c
@@ -58,6 +58,9 @@ static ptrdiff_t new_backquote_output;
58#define PRINT_CIRCLE 200 58#define PRINT_CIRCLE 200
59static Lisp_Object being_printed[PRINT_CIRCLE]; 59static Lisp_Object being_printed[PRINT_CIRCLE];
60 60
61/* Last char printed to stdout by printchar. */
62static unsigned int printchar_stdout_last;
63
61/* When printing into a buffer, first we put the text in this 64/* When printing into a buffer, first we put the text in this
62 block, then insert it all at once. */ 65 block, then insert it all at once. */
63static char *print_buffer; 66static char *print_buffer;
@@ -169,11 +172,13 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
169 if (print_buffer_pos != print_buffer_pos_byte \ 172 if (print_buffer_pos != print_buffer_pos_byte \
170 && NILP (BVAR (current_buffer, enable_multibyte_characters)))\ 173 && NILP (BVAR (current_buffer, enable_multibyte_characters)))\
171 { \ 174 { \
172 unsigned char *temp = alloca (print_buffer_pos + 1); \ 175 USE_SAFE_ALLOCA; \
176 unsigned char *temp = SAFE_ALLOCA (print_buffer_pos + 1); \
173 copy_text ((unsigned char *) print_buffer, temp, \ 177 copy_text ((unsigned char *) print_buffer, temp, \
174 print_buffer_pos_byte, 1, 0); \ 178 print_buffer_pos_byte, 1, 0); \
175 insert_1_both ((char *) temp, print_buffer_pos, \ 179 insert_1_both ((char *) temp, print_buffer_pos, \
176 print_buffer_pos, 0, 1, 0); \ 180 print_buffer_pos, 0, 1, 0); \
181 SAFE_FREE (); \
177 } \ 182 } \
178 else \ 183 else \
179 insert_1_both (print_buffer, print_buffer_pos, \ 184 insert_1_both (print_buffer, print_buffer_pos, \
@@ -236,6 +241,7 @@ printchar (unsigned int ch, Lisp_Object fun)
236 } 241 }
237 else if (noninteractive) 242 else if (noninteractive)
238 { 243 {
244 printchar_stdout_last = ch;
239 fwrite (str, 1, len, stdout); 245 fwrite (str, 1, len, stdout);
240 noninteractive_need_newline = 1; 246 noninteractive_need_newline = 1;
241 } 247 }
@@ -513,19 +519,33 @@ static void print_preprocess (Lisp_Object);
513static void print_preprocess_string (INTERVAL, Lisp_Object); 519static void print_preprocess_string (INTERVAL, Lisp_Object);
514static void print_object (Lisp_Object, Lisp_Object, bool); 520static void print_object (Lisp_Object, Lisp_Object, bool);
515 521
516DEFUN ("terpri", Fterpri, Sterpri, 0, 1, 0, 522DEFUN ("terpri", Fterpri, Sterpri, 0, 2, 0,
517 doc: /* Output a newline to stream PRINTCHARFUN. 523 doc: /* Output a newline to stream PRINTCHARFUN.
524If ENSURE is non-nil only output a newline if not already at the
525beginning of a line. Value is non-nil if a newline is printed.
518If PRINTCHARFUN is omitted or nil, the value of `standard-output' is used. */) 526If PRINTCHARFUN is omitted or nil, the value of `standard-output' is used. */)
519 (Lisp_Object printcharfun) 527 (Lisp_Object printcharfun, Lisp_Object ensure)
520{ 528{
521 PRINTDECLARE; 529 Lisp_Object val = Qnil;
522 530
531 PRINTDECLARE;
523 if (NILP (printcharfun)) 532 if (NILP (printcharfun))
524 printcharfun = Vstandard_output; 533 printcharfun = Vstandard_output;
525 PRINTPREPARE; 534 PRINTPREPARE;
526 PRINTCHAR ('\n'); 535
536 if (NILP (ensure))
537 val = Qt;
538 /* Difficult to check if at line beginning so abort. */
539 else if (FUNCTIONP (printcharfun))
540 signal_error ("Unsupported function argument", printcharfun);
541 else if (noninteractive && !NILP (printcharfun))
542 val = printchar_stdout_last == 10 ? Qnil : Qt;
543 else if (NILP (Fbolp ()))
544 val = Qt;
545
546 if (!NILP (val)) PRINTCHAR ('\n');
527 PRINTFINISH; 547 PRINTFINISH;
528 return Qt; 548 return val;
529} 549}
530 550
531DEFUN ("prin1", Fprin1, Sprin1, 1, 2, 0, 551DEFUN ("prin1", Fprin1, Sprin1, 1, 2, 0,
@@ -581,7 +601,6 @@ A printed representation of an object is text which describes that object. */)
581{ 601{
582 Lisp_Object printcharfun; 602 Lisp_Object printcharfun;
583 bool prev_abort_on_gc; 603 bool prev_abort_on_gc;
584 /* struct gcpro gcpro1, gcpro2; */
585 Lisp_Object save_deactivate_mark; 604 Lisp_Object save_deactivate_mark;
586 ptrdiff_t count = SPECPDL_INDEX (); 605 ptrdiff_t count = SPECPDL_INDEX ();
587 struct buffer *previous; 606 struct buffer *previous;
@@ -595,7 +614,6 @@ A printed representation of an object is text which describes that object. */)
595 but we don't want to deactivate the mark just for that. 614 but we don't want to deactivate the mark just for that.
596 No need for specbind, since errors deactivate the mark. */ 615 No need for specbind, since errors deactivate the mark. */
597 save_deactivate_mark = Vdeactivate_mark; 616 save_deactivate_mark = Vdeactivate_mark;
598 /* GCPRO2 (object, save_deactivate_mark); */
599 prev_abort_on_gc = abort_on_gc; 617 prev_abort_on_gc = abort_on_gc;
600 abort_on_gc = 1; 618 abort_on_gc = 1;
601 619
@@ -619,7 +637,6 @@ A printed representation of an object is text which describes that object. */)
619 set_buffer_internal (previous); 637 set_buffer_internal (previous);
620 638
621 Vdeactivate_mark = save_deactivate_mark; 639 Vdeactivate_mark = save_deactivate_mark;
622 /* UNGCPRO; */
623 640
624 abort_on_gc = prev_abort_on_gc; 641 abort_on_gc = prev_abort_on_gc;
625 return unbind_to (count, object); 642 return unbind_to (count, object);
diff --git a/src/process.c b/src/process.c
index 0d6994bdab1..06fc918cf54 100644
--- a/src/process.c
+++ b/src/process.c
@@ -173,6 +173,9 @@ close_on_exec (int fd)
173 return fd; 173 return fd;
174} 174}
175 175
176# undef accept4
177# define accept4(sockfd, addr, addrlen, flags) \
178 process_accept4 (sockfd, addr, addrlen, flags)
176static int 179static int
177accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) 180accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
178{ 181{
@@ -596,7 +599,7 @@ status_message (struct Lisp_Process *p)
596 Lisp_Object symbol; 599 Lisp_Object symbol;
597 int code; 600 int code;
598 bool coredump; 601 bool coredump;
599 Lisp_Object string, string2; 602 Lisp_Object string;
600 603
601 decode_status (status, &symbol, &code, &coredump); 604 decode_status (status, &symbol, &code, &coredump);
602 605
@@ -620,8 +623,8 @@ status_message (struct Lisp_Process *p)
620 if (c1 != c2) 623 if (c1 != c2)
621 Faset (string, make_number (0), make_number (c2)); 624 Faset (string, make_number (0), make_number (c2));
622 } 625 }
623 string2 = build_string (coredump ? " (core dumped)\n" : "\n"); 626 AUTO_STRING (suffix, coredump ? " (core dumped)\n" : "\n");
624 return concat2 (string, string2); 627 return concat2 (string, suffix);
625 } 628 }
626 else if (EQ (symbol, Qexit)) 629 else if (EQ (symbol, Qexit))
627 { 630 {
@@ -629,17 +632,17 @@ status_message (struct Lisp_Process *p)
629 return build_string (code == 0 ? "deleted\n" : "connection broken by remote peer\n"); 632 return build_string (code == 0 ? "deleted\n" : "connection broken by remote peer\n");
630 if (code == 0) 633 if (code == 0)
631 return build_string ("finished\n"); 634 return build_string ("finished\n");
635 AUTO_STRING (prefix, "exited abnormally with code ");
632 string = Fnumber_to_string (make_number (code)); 636 string = Fnumber_to_string (make_number (code));
633 string2 = build_string (coredump ? " (core dumped)\n" : "\n"); 637 AUTO_STRING (suffix, coredump ? " (core dumped)\n" : "\n");
634 return concat3 (build_string ("exited abnormally with code "), 638 return concat3 (prefix, string, suffix);
635 string, string2);
636 } 639 }
637 else if (EQ (symbol, Qfailed)) 640 else if (EQ (symbol, Qfailed))
638 { 641 {
642 AUTO_STRING (prefix, "failed with code ");
639 string = Fnumber_to_string (make_number (code)); 643 string = Fnumber_to_string (make_number (code));
640 string2 = build_string ("\n"); 644 AUTO_STRING (suffix, "\n");
641 return concat3 (build_string ("failed with code "), 645 return concat3 (prefix, string, suffix);
642 string, string2);
643 } 646 }
644 else 647 else
645 return Fcopy_sequence (Fsymbol_name (symbol)); 648 return Fcopy_sequence (Fsymbol_name (symbol));
@@ -1302,30 +1305,34 @@ Returns nil if format of ADDRESS is invalid. */)
1302 ptrdiff_t size = p->header.size; 1305 ptrdiff_t size = p->header.size;
1303 Lisp_Object args[10]; 1306 Lisp_Object args[10];
1304 int nargs, i; 1307 int nargs, i;
1308 char const *format;
1305 1309
1306 if (size == 4 || (size == 5 && !NILP (omit_port))) 1310 if (size == 4 || (size == 5 && !NILP (omit_port)))
1307 { 1311 {
1308 args[0] = build_string ("%d.%d.%d.%d"); 1312 format = "%d.%d.%d.%d";
1309 nargs = 4; 1313 nargs = 4;
1310 } 1314 }
1311 else if (size == 5) 1315 else if (size == 5)
1312 { 1316 {
1313 args[0] = build_string ("%d.%d.%d.%d:%d"); 1317 format = "%d.%d.%d.%d:%d";
1314 nargs = 5; 1318 nargs = 5;
1315 } 1319 }
1316 else if (size == 8 || (size == 9 && !NILP (omit_port))) 1320 else if (size == 8 || (size == 9 && !NILP (omit_port)))
1317 { 1321 {
1318 args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); 1322 format = "%x:%x:%x:%x:%x:%x:%x:%x";
1319 nargs = 8; 1323 nargs = 8;
1320 } 1324 }
1321 else if (size == 9) 1325 else if (size == 9)
1322 { 1326 {
1323 args[0] = build_string ("[%x:%x:%x:%x:%x:%x:%x:%x]:%d"); 1327 format = "[%x:%x:%x:%x:%x:%x:%x:%x]:%d";
1324 nargs = 9; 1328 nargs = 9;
1325 } 1329 }
1326 else 1330 else
1327 return Qnil; 1331 return Qnil;
1328 1332
1333 AUTO_STRING (format_obj, format);
1334 args[0] = format_obj;
1335
1329 for (i = 0; i < nargs; i++) 1336 for (i = 0; i < nargs; i++)
1330 { 1337 {
1331 if (! RANGED_INTEGERP (0, p->contents[i], 65535)) 1338 if (! RANGED_INTEGERP (0, p->contents[i], 65535))
@@ -1339,15 +1346,13 @@ Returns nil if format of ADDRESS is invalid. */)
1339 args[i+1] = p->contents[i]; 1346 args[i+1] = p->contents[i];
1340 } 1347 }
1341 1348
1342 return Fformat (nargs+1, args); 1349 return Fformat (nargs + 1, args);
1343 } 1350 }
1344 1351
1345 if (CONSP (address)) 1352 if (CONSP (address))
1346 { 1353 {
1347 Lisp_Object args[2]; 1354 AUTO_STRING (format, "<Family %d>");
1348 args[0] = build_string ("<Family %d>"); 1355 return Fformat (2, (Lisp_Object []) {format, Fcar (address)});
1349 args[1] = Fcar (address);
1350 return Fformat (2, args);
1351 } 1356 }
1352 1357
1353 return Qnil; 1358 return Qnil;
@@ -1386,9 +1391,10 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1386 (ptrdiff_t nargs, Lisp_Object *args) 1391 (ptrdiff_t nargs, Lisp_Object *args)
1387{ 1392{
1388 Lisp_Object buffer, name, program, proc, current_dir, tem; 1393 Lisp_Object buffer, name, program, proc, current_dir, tem;
1389 register unsigned char **new_argv; 1394 unsigned char **new_argv;
1390 ptrdiff_t i; 1395 ptrdiff_t i;
1391 ptrdiff_t count = SPECPDL_INDEX (); 1396 ptrdiff_t count = SPECPDL_INDEX ();
1397 USE_SAFE_ALLOCA;
1392 1398
1393 buffer = args[1]; 1399 buffer = args[1];
1394 if (!NILP (buffer)) 1400 if (!NILP (buffer))
@@ -1464,7 +1470,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1464 val = Vcoding_system_for_read; 1470 val = Vcoding_system_for_read;
1465 if (NILP (val)) 1471 if (NILP (val))
1466 { 1472 {
1467 args2 = alloca ((nargs + 1) * sizeof *args2); 1473 SAFE_ALLOCA_LISP (args2, nargs + 1);
1468 args2[0] = Qstart_process; 1474 args2[0] = Qstart_process;
1469 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1475 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
1470 GCPRO2 (proc, current_dir); 1476 GCPRO2 (proc, current_dir);
@@ -1483,7 +1489,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1483 { 1489 {
1484 if (EQ (coding_systems, Qt)) 1490 if (EQ (coding_systems, Qt))
1485 { 1491 {
1486 args2 = alloca ((nargs + 1) * sizeof *args2); 1492 SAFE_ALLOCA_LISP (args2, nargs + 1);
1487 args2[0] = Qstart_process; 1493 args2[0] = Qstart_process;
1488 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1494 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
1489 GCPRO2 (proc, current_dir); 1495 GCPRO2 (proc, current_dir);
@@ -1578,7 +1584,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1578 1584
1579 /* Now that everything is encoded we can collect the strings into 1585 /* Now that everything is encoded we can collect the strings into
1580 NEW_ARGV. */ 1586 NEW_ARGV. */
1581 new_argv = alloca ((nargs - 1) * sizeof *new_argv); 1587 SAFE_NALLOCA (new_argv, 1, nargs - 1);
1582 new_argv[nargs - 2] = 0; 1588 new_argv[nargs - 2] = 0;
1583 1589
1584 for (i = nargs - 2; i-- != 0; ) 1590 for (i = nargs - 2; i-- != 0; )
@@ -1592,6 +1598,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1592 else 1598 else
1593 create_pty (proc); 1599 create_pty (proc);
1594 1600
1601 SAFE_FREE ();
1595 return unbind_to (count, proc); 1602 return unbind_to (count, proc);
1596} 1603}
1597 1604
@@ -2071,8 +2078,10 @@ get_lisp_to_sockaddr_size (Lisp_Object address, int *familyp)
2071 && VECTORP (XCDR (address))) 2078 && VECTORP (XCDR (address)))
2072 { 2079 {
2073 struct sockaddr *sa; 2080 struct sockaddr *sa;
2074 *familyp = XINT (XCAR (address));
2075 p = XVECTOR (XCDR (address)); 2081 p = XVECTOR (XCDR (address));
2082 if (MAX_ALLOCA - sizeof sa->sa_family < p->header.size)
2083 return 0;
2084 *familyp = XINT (XCAR (address));
2076 return p->header.size + sizeof (sa->sa_family); 2085 return p->header.size + sizeof (sa->sa_family);
2077 } 2086 }
2078 return 0; 2087 return 0;
@@ -2989,7 +2998,7 @@ usage: (make-network-process &rest ARGS) */)
2989 address_un.sun_family = AF_LOCAL; 2998 address_un.sun_family = AF_LOCAL;
2990 if (sizeof address_un.sun_path <= SBYTES (service)) 2999 if (sizeof address_un.sun_path <= SBYTES (service))
2991 error ("Service name too long"); 3000 error ("Service name too long");
2992 strcpy (address_un.sun_path, SSDATA (service)); 3001 lispstpcpy (address_un.sun_path, service);
2993 ai.ai_addr = (struct sockaddr *) &address_un; 3002 ai.ai_addr = (struct sockaddr *) &address_un;
2994 ai.ai_addrlen = sizeof address_un; 3003 ai.ai_addrlen = sizeof address_un;
2995 goto open_socket; 3004 goto open_socket;
@@ -3680,7 +3689,7 @@ network_interface_info (Lisp_Object ifname)
3680 3689
3681 if (sizeof rq.ifr_name <= SBYTES (ifname)) 3690 if (sizeof rq.ifr_name <= SBYTES (ifname))
3682 error ("interface name too long"); 3691 error ("interface name too long");
3683 strcpy (rq.ifr_name, SSDATA (ifname)); 3692 lispstpcpy (rq.ifr_name, ifname);
3684 3693
3685 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 3694 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3686 if (s < 0) 3695 if (s < 0)
@@ -4057,20 +4066,15 @@ server_accept_connection (Lisp_Object server, int channel)
4057 { 4066 {
4058 case AF_INET: 4067 case AF_INET:
4059 { 4068 {
4060 Lisp_Object args[5];
4061 unsigned char *ip = (unsigned char *)&saddr.in.sin_addr.s_addr; 4069 unsigned char *ip = (unsigned char *)&saddr.in.sin_addr.s_addr;
4062 args[0] = build_string ("%d.%d.%d.%d");
4063 args[1] = make_number (*ip++);
4064 args[2] = make_number (*ip++);
4065 args[3] = make_number (*ip++);
4066 args[4] = make_number (*ip++);
4067 host = Fformat (5, args);
4068 service = make_number (ntohs (saddr.in.sin_port));
4069 4070
4070 args[0] = build_string (" <%s:%d>"); 4071 AUTO_STRING (ipv4_format, "%d.%d.%d.%d");
4071 args[1] = host; 4072 host = Fformat (5, ((Lisp_Object [])
4072 args[2] = service; 4073 { ipv4_format, make_number (ip[0]),
4073 caller = Fformat (3, args); 4074 make_number (ip[1]), make_number (ip[2]), make_number (ip[3]) }));
4075 service = make_number (ntohs (saddr.in.sin_port));
4076 AUTO_STRING (caller_format, " <%s:%d>");
4077 caller = Fformat (3, (Lisp_Object []) {caller_format, host, service});
4074 } 4078 }
4075 break; 4079 break;
4076 4080
@@ -4080,16 +4084,15 @@ server_accept_connection (Lisp_Object server, int channel)
4080 Lisp_Object args[9]; 4084 Lisp_Object args[9];
4081 uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr; 4085 uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr;
4082 int i; 4086 int i;
4083 args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x"); 4087
4088 AUTO_STRING (ipv6_format, "%x:%x:%x:%x:%x:%x:%x:%x");
4089 args[0] = ipv6_format;
4084 for (i = 0; i < 8; i++) 4090 for (i = 0; i < 8; i++)
4085 args[i+1] = make_number (ntohs (ip6[i])); 4091 args[i + 1] = make_number (ntohs (ip6[i]));
4086 host = Fformat (9, args); 4092 host = Fformat (9, args);
4087 service = make_number (ntohs (saddr.in.sin_port)); 4093 service = make_number (ntohs (saddr.in.sin_port));
4088 4094 AUTO_STRING (caller_format, " <[%s]:%d>");
4089 args[0] = build_string (" <[%s]:%d>"); 4095 caller = Fformat (3, (Lisp_Object []) {caller_format, host, service});
4090 args[1] = host;
4091 args[2] = service;
4092 caller = Fformat (3, args);
4093 } 4096 }
4094 break; 4097 break;
4095#endif 4098#endif
@@ -4099,7 +4102,9 @@ server_accept_connection (Lisp_Object server, int channel)
4099#endif 4102#endif
4100 default: 4103 default:
4101 caller = Fnumber_to_string (make_number (connect_counter)); 4104 caller = Fnumber_to_string (make_number (connect_counter));
4102 caller = concat3 (build_string (" <"), caller, build_string (">")); 4105 AUTO_STRING (space_less_than, " <");
4106 AUTO_STRING (greater_than, ">");
4107 caller = concat3 (space_less_than, caller, greater_than);
4103 break; 4108 break;
4104 } 4109 }
4105 4110
@@ -4196,16 +4201,18 @@ server_accept_connection (Lisp_Object server, int channel)
4196 p->inherit_coding_system_flag 4201 p->inherit_coding_system_flag
4197 = (NILP (buffer) ? 0 : ps->inherit_coding_system_flag); 4202 = (NILP (buffer) ? 0 : ps->inherit_coding_system_flag);
4198 4203
4204 AUTO_STRING (dash, "-");
4205 AUTO_STRING (nl, "\n");
4206 Lisp_Object host_string = STRINGP (host) ? host : dash;
4207
4199 if (!NILP (ps->log)) 4208 if (!NILP (ps->log))
4200 call3 (ps->log, server, proc, 4209 {
4201 concat3 (build_string ("accept from "), 4210 AUTO_STRING (accept_from, "accept from ");
4202 (STRINGP (host) ? host : build_string ("-")), 4211 call3 (ps->log, server, proc, concat3 (accept_from, host_string, nl));
4203 build_string ("\n"))); 4212 }
4204 4213
4205 exec_sentinel (proc, 4214 AUTO_STRING (open_from, "open from ");
4206 concat3 (build_string ("open from "), 4215 exec_sentinel (proc, concat3 (open_from, host_string, nl));
4207 (STRINGP (host) ? host : build_string ("-")),
4208 build_string ("\n")));
4209} 4216}
4210 4217
4211/* This variable is different from waiting_for_input in keyboard.c. 4218/* This variable is different from waiting_for_input in keyboard.c.
@@ -4973,18 +4980,17 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
4973 for decoding. */ 4980 for decoding. */
4974 4981
4975static int 4982static int
4976read_process_output (Lisp_Object proc, register int channel) 4983read_process_output (Lisp_Object proc, int channel)
4977{ 4984{
4978 register ssize_t nbytes; 4985 ssize_t nbytes;
4979 char *chars; 4986 struct Lisp_Process *p = XPROCESS (proc);
4980 register struct Lisp_Process *p = XPROCESS (proc);
4981 struct coding_system *coding = proc_decode_coding_system[channel]; 4987 struct coding_system *coding = proc_decode_coding_system[channel];
4982 int carryover = p->decoding_carryover; 4988 int carryover = p->decoding_carryover;
4983 int readmax = 4096; 4989 enum { readmax = 4096 };
4984 ptrdiff_t count = SPECPDL_INDEX (); 4990 ptrdiff_t count = SPECPDL_INDEX ();
4985 Lisp_Object odeactivate; 4991 Lisp_Object odeactivate;
4992 char chars[sizeof coding->carryover + readmax];
4986 4993
4987 chars = alloca (carryover + readmax);
4988 if (carryover) 4994 if (carryover)
4989 /* See the comment above. */ 4995 /* See the comment above. */
4990 memcpy (chars, SDATA (p->decoding_buf), carryover); 4996 memcpy (chars, SDATA (p->decoding_buf), carryover);
@@ -6837,7 +6843,7 @@ add_timer_wait_descriptor (int fd)
6837{ 6843{
6838 FD_SET (fd, &input_wait_mask); 6844 FD_SET (fd, &input_wait_mask);
6839 FD_SET (fd, &non_keyboard_wait_mask); 6845 FD_SET (fd, &non_keyboard_wait_mask);
6840 FD_SET (fd, &non_process_wait_mask); 6846 FD_SET (fd, &non_process_wait_mask);
6841 fd_callback_info[fd].func = timerfd_callback; 6847 fd_callback_info[fd].func = timerfd_callback;
6842 fd_callback_info[fd].data = NULL; 6848 fd_callback_info[fd].data = NULL;
6843 fd_callback_info[fd].condition |= FOR_READ; 6849 fd_callback_info[fd].condition |= FOR_READ;
diff --git a/src/ralloc.c b/src/ralloc.c
index c82cd4548d2..e63ed34c89b 100644
--- a/src/ralloc.c
+++ b/src/ralloc.c
@@ -35,9 +35,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35#define M_TOP_PAD -2 35#define M_TOP_PAD -2
36extern int mallopt (int, int); 36extern int mallopt (int, int);
37#else /* not DOUG_LEA_MALLOC */ 37#else /* not DOUG_LEA_MALLOC */
38#ifndef SYSTEM_MALLOC 38#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
39extern size_t __malloc_extra_blocks; 39extern size_t __malloc_extra_blocks;
40#endif /* SYSTEM_MALLOC */ 40#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
41#endif /* not DOUG_LEA_MALLOC */ 41#endif /* not DOUG_LEA_MALLOC */
42 42
43#else /* not emacs */ 43#else /* not emacs */
@@ -95,7 +95,7 @@ static int extra_bytes;
95/* The hook `malloc' uses for the function which gets more space 95/* The hook `malloc' uses for the function which gets more space
96 from the system. */ 96 from the system. */
97 97
98#ifndef SYSTEM_MALLOC 98#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
99extern void *(*__morecore) (ptrdiff_t); 99extern void *(*__morecore) (ptrdiff_t);
100#endif 100#endif
101 101
@@ -1179,7 +1179,7 @@ r_alloc_init (void)
1179 r_alloc_initialized = 1; 1179 r_alloc_initialized = 1;
1180 1180
1181 page_size = PAGE; 1181 page_size = PAGE;
1182#ifndef SYSTEM_MALLOC 1182#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
1183 real_morecore = __morecore; 1183 real_morecore = __morecore;
1184 __morecore = r_alloc_sbrk; 1184 __morecore = r_alloc_sbrk;
1185 1185
@@ -1198,7 +1198,7 @@ r_alloc_init (void)
1198 mallopt (M_TOP_PAD, 64 * 4096); 1198 mallopt (M_TOP_PAD, 64 * 4096);
1199 unblock_input (); 1199 unblock_input ();
1200#else 1200#else
1201#ifndef SYSTEM_MALLOC 1201#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
1202 /* Give GNU malloc's morecore some hysteresis so that we move all 1202 /* Give GNU malloc's morecore some hysteresis so that we move all
1203 the relocatable blocks much less often. The number used to be 1203 the relocatable blocks much less often. The number used to be
1204 64, but alloc.c would override that with 32 in code that was 1204 64, but alloc.c would override that with 32 in code that was
@@ -1211,7 +1211,7 @@ r_alloc_init (void)
1211#endif 1211#endif
1212#endif 1212#endif
1213 1213
1214#ifndef SYSTEM_MALLOC 1214#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
1215 first_heap->end = (void *) PAGE_ROUNDUP (first_heap->start); 1215 first_heap->end = (void *) PAGE_ROUNDUP (first_heap->start);
1216 1216
1217 /* The extra call to real_morecore guarantees that the end of the 1217 /* The extra call to real_morecore guarantees that the end of the
diff --git a/src/regex.c b/src/regex.c
index 1c1164da57d..766ad26e709 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -457,11 +457,17 @@ init_syntax_once (void)
457 457
458# endif /* not alloca */ 458# endif /* not alloca */
459 459
460# define REGEX_ALLOCATE alloca 460# ifdef emacs
461# define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
462# define REGEX_SAFE_FREE() SAFE_FREE ()
463# define REGEX_ALLOCATE SAFE_ALLOCA
464# else
465# define REGEX_ALLOCATE alloca
466# endif
461 467
462/* Assumes a `char *destination' variable. */ 468/* Assumes a `char *destination' variable. */
463# define REGEX_REALLOCATE(source, osize, nsize) \ 469# define REGEX_REALLOCATE(source, osize, nsize) \
464 (destination = alloca (nsize), \ 470 (destination = REGEX_ALLOCATE (nsize), \
465 memcpy (destination, source, osize)) 471 memcpy (destination, source, osize))
466 472
467/* No need to do anything to free, after alloca. */ 473/* No need to do anything to free, after alloca. */
@@ -469,6 +475,11 @@ init_syntax_once (void)
469 475
470#endif /* not REGEX_MALLOC */ 476#endif /* not REGEX_MALLOC */
471 477
478#ifndef REGEX_USE_SAFE_ALLOCA
479# define REGEX_USE_SAFE_ALLOCA ((void) 0)
480# define REGEX_SAFE_FREE() ((void) 0)
481#endif
482
472/* Define how to allocate the failure stack. */ 483/* Define how to allocate the failure stack. */
473 484
474#if defined REL_ALLOC && defined REGEX_MALLOC 485#if defined REL_ALLOC && defined REGEX_MALLOC
@@ -482,22 +493,10 @@ init_syntax_once (void)
482 493
483#else /* not using relocating allocator */ 494#else /* not using relocating allocator */
484 495
485# ifdef REGEX_MALLOC 496# define REGEX_ALLOCATE_STACK(size) REGEX_ALLOCATE (size)
486 497# define REGEX_REALLOCATE_STACK(source, o, n) REGEX_REALLOCATE (source, o, n)
487# define REGEX_ALLOCATE_STACK malloc 498# define REGEX_FREE_STACK(ptr) REGEX_FREE (ptr)
488# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
489# define REGEX_FREE_STACK free
490 499
491# else /* not REGEX_MALLOC */
492
493# define REGEX_ALLOCATE_STACK alloca
494
495# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
496 REGEX_REALLOCATE (source, osize, nsize)
497/* No need to explicitly free anything. */
498# define REGEX_FREE_STACK(arg) ((void)0)
499
500# endif /* not REGEX_MALLOC */
501#endif /* not using relocating allocator */ 500#endif /* not using relocating allocator */
502 501
503 502
@@ -516,10 +515,12 @@ init_syntax_once (void)
516 515
517#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) 516#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
518 517
519#undef MAX 518#ifndef emacs
520#undef MIN 519# undef max
521#define MAX(a, b) ((a) > (b) ? (a) : (b)) 520# undef min
522#define MIN(a, b) ((a) < (b) ? (a) : (b)) 521# define max(a, b) ((a) > (b) ? (a) : (b))
522# define min(a, b) ((a) < (b) ? (a) : (b))
523#endif
523 524
524/* Type of source-pattern and string chars. */ 525/* Type of source-pattern and string chars. */
525#ifdef _MSC_VER 526#ifdef _MSC_VER
@@ -1395,14 +1396,14 @@ typedef struct
1395 : ((fail_stack).stack \ 1396 : ((fail_stack).stack \
1396 = REGEX_REALLOCATE_STACK ((fail_stack).stack, \ 1397 = REGEX_REALLOCATE_STACK ((fail_stack).stack, \
1397 (fail_stack).size * sizeof (fail_stack_elt_t), \ 1398 (fail_stack).size * sizeof (fail_stack_elt_t), \
1398 MIN (re_max_failures * TYPICAL_FAILURE_SIZE, \ 1399 min (re_max_failures * TYPICAL_FAILURE_SIZE, \
1399 ((fail_stack).size * sizeof (fail_stack_elt_t) \ 1400 ((fail_stack).size * sizeof (fail_stack_elt_t) \
1400 * FAIL_STACK_GROWTH_FACTOR))), \ 1401 * FAIL_STACK_GROWTH_FACTOR))), \
1401 \ 1402 \
1402 (fail_stack).stack == NULL \ 1403 (fail_stack).stack == NULL \
1403 ? 0 \ 1404 ? 0 \
1404 : ((fail_stack).size \ 1405 : ((fail_stack).size \
1405 = (MIN (re_max_failures * TYPICAL_FAILURE_SIZE, \ 1406 = (min (re_max_failures * TYPICAL_FAILURE_SIZE, \
1406 ((fail_stack).size * sizeof (fail_stack_elt_t) \ 1407 ((fail_stack).size * sizeof (fail_stack_elt_t) \
1407 * FAIL_STACK_GROWTH_FACTOR)) \ 1408 * FAIL_STACK_GROWTH_FACTOR)) \
1408 / sizeof (fail_stack_elt_t)), \ 1409 / sizeof (fail_stack_elt_t)), \
@@ -2310,8 +2311,8 @@ set_image_of_range (struct range_table_work_area *work_area,
2310 cmin = c, cmax = c; 2311 cmin = c, cmax = c;
2311 else 2312 else
2312 { 2313 {
2313 cmin = MIN (cmin, c); 2314 cmin = min (cmin, c);
2314 cmax = MAX (cmax, c); 2315 cmax = max (cmax, c);
2315 } 2316 }
2316 } 2317 }
2317 } 2318 }
@@ -2990,7 +2991,7 @@ regex_compile (const_re_char *pattern, size_t size, reg_syntax_t syntax,
2990#else /* emacs */ 2991#else /* emacs */
2991 if (c < 128) 2992 if (c < 128)
2992 { 2993 {
2993 ch = MIN (127, c1); 2994 ch = min (127, c1);
2994 SETUP_ASCII_RANGE (range_table_work, c, ch); 2995 SETUP_ASCII_RANGE (range_table_work, c, ch);
2995 c = ch + 1; 2996 c = ch + 1;
2996 if (CHAR_BYTE8_P (c1)) 2997 if (CHAR_BYTE8_P (c1))
@@ -4579,6 +4580,7 @@ static int bcmp_translate (re_char *s1, re_char *s2,
4579 FREE_VAR (regend); \ 4580 FREE_VAR (regend); \
4580 FREE_VAR (best_regstart); \ 4581 FREE_VAR (best_regstart); \
4581 FREE_VAR (best_regend); \ 4582 FREE_VAR (best_regend); \
4583 REGEX_SAFE_FREE (); \
4582 } while (0) 4584 } while (0)
4583#else 4585#else
4584# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ 4586# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
@@ -5018,6 +5020,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
5018 5020
5019 DEBUG_PRINT ("\n\nEntering re_match_2.\n"); 5021 DEBUG_PRINT ("\n\nEntering re_match_2.\n");
5020 5022
5023 REGEX_USE_SAFE_ALLOCA;
5024
5021 INIT_FAIL_STACK (); 5025 INIT_FAIL_STACK ();
5022 5026
5023#ifdef MATCH_MAY_ALLOCATE 5027#ifdef MATCH_MAY_ALLOCATE
@@ -5208,7 +5212,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
5208 { /* No. So allocate them with malloc. We need one 5212 { /* No. So allocate them with malloc. We need one
5209 extra element beyond `num_regs' for the `-1' marker 5213 extra element beyond `num_regs' for the `-1' marker
5210 GNU code uses. */ 5214 GNU code uses. */
5211 regs->num_regs = MAX (RE_NREGS, num_regs + 1); 5215 regs->num_regs = max (RE_NREGS, num_regs + 1);
5212 regs->start = TALLOC (regs->num_regs, regoff_t); 5216 regs->start = TALLOC (regs->num_regs, regoff_t);
5213 regs->end = TALLOC (regs->num_regs, regoff_t); 5217 regs->end = TALLOC (regs->num_regs, regoff_t);
5214 if (regs->start == NULL || regs->end == NULL) 5218 if (regs->start == NULL || regs->end == NULL)
@@ -5252,7 +5256,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
5252 5256
5253 /* Go through the first `min (num_regs, regs->num_regs)' 5257 /* Go through the first `min (num_regs, regs->num_regs)'
5254 registers, since that is all we initialized. */ 5258 registers, since that is all we initialized. */
5255 for (reg = 1; reg < MIN (num_regs, regs->num_regs); reg++) 5259 for (reg = 1; reg < min (num_regs, regs->num_regs); reg++)
5256 { 5260 {
5257 if (REG_UNSET (regstart[reg]) || REG_UNSET (regend[reg])) 5261 if (REG_UNSET (regstart[reg]) || REG_UNSET (regend[reg]))
5258 regs->start[reg] = regs->end[reg] = -1; 5262 regs->start[reg] = regs->end[reg] = -1;
diff --git a/src/regex.h b/src/regex.h
index 1b064987eb7..0e25723a85e 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -172,6 +172,9 @@ extern reg_syntax_t re_syntax_options;
172extern Lisp_Object re_match_object; 172extern Lisp_Object re_match_object;
173#endif 173#endif
174 174
175/* Roughly the maximum number of failure points on the stack. */
176extern size_t re_max_failures;
177
175 178
176/* Define combinations of the above bits for the standard possibilities. 179/* Define combinations of the above bits for the standard possibilities.
177 (The [[[ comments delimit what gets put into the Texinfo file, so 180 (The [[[ comments delimit what gets put into the Texinfo file, so
diff --git a/src/scroll.c b/src/scroll.c
index 6c559663f80..7cb683c4577 100644
--- a/src/scroll.c
+++ b/src/scroll.c
@@ -245,18 +245,20 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
245{ 245{
246 struct matrix_elt *p; 246 struct matrix_elt *p;
247 int i, j, k; 247 int i, j, k;
248 USE_SAFE_ALLOCA;
248 249
249 /* True if we have set a terminal window with set_terminal_window. */ 250 /* True if we have set a terminal window with set_terminal_window. */
250 bool terminal_window_p = 0; 251 bool terminal_window_p = 0;
251 252
252 /* A queue for line insertions to be done. */ 253 /* A queue for line insertions to be done. */
253 struct queue { int count, pos; }; 254 struct queue { int count, pos; };
254 struct queue *queue_start 255 struct queue *queue_start;
255 = alloca (current_matrix->nrows * sizeof *queue_start); 256 SAFE_NALLOCA (queue_start, 1, current_matrix->nrows);
256 struct queue *queue = queue_start; 257 struct queue *queue = queue_start;
257 258
258 char *retained_p = alloca (window_size * sizeof *retained_p); 259 char *retained_p = SAFE_ALLOCA (window_size);
259 int *copy_from = alloca (window_size * sizeof *copy_from); 260 int *copy_from;
261 SAFE_NALLOCA (copy_from, 1, window_size);
260 262
261 /* Zero means line is empty. */ 263 /* Zero means line is empty. */
262 memset (retained_p, 0, window_size * sizeof (char)); 264 memset (retained_p, 0, window_size * sizeof (char));
@@ -378,6 +380,7 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
378 380
379 if (terminal_window_p) 381 if (terminal_window_p)
380 set_terminal_window (frame, 0); 382 set_terminal_window (frame, 0);
383 SAFE_FREE ();
381} 384}
382 385
383 386
@@ -649,10 +652,12 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
649{ 652{
650 struct matrix_elt *p; 653 struct matrix_elt *p;
651 int i, j; 654 int i, j;
655 USE_SAFE_ALLOCA;
652 656
653 /* A queue of deletions and insertions to be performed. */ 657 /* A queue of deletions and insertions to be performed. */
654 struct alt_queue { int count, pos, window; }; 658 struct alt_queue { int count, pos, window; };
655 struct alt_queue *queue_start = alloca (window_size * sizeof *queue_start); 659 struct alt_queue *queue_start;
660 SAFE_NALLOCA (queue_start, 1, window_size);
656 struct alt_queue *queue = queue_start; 661 struct alt_queue *queue = queue_start;
657 662
658 /* True if a terminal window has been set with set_terminal_window. */ 663 /* True if a terminal window has been set with set_terminal_window. */
@@ -667,11 +672,12 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
667 bool write_follows_p = 1; 672 bool write_follows_p = 1;
668 673
669 /* For each row in the new matrix what row of the old matrix it is. */ 674 /* For each row in the new matrix what row of the old matrix it is. */
670 int *copy_from = alloca (window_size * sizeof *copy_from); 675 int *copy_from;
676 SAFE_NALLOCA (copy_from, 1, window_size);
671 677
672 /* Non-zero for each row in the new matrix that is retained from the 678 /* Non-zero for each row in the new matrix that is retained from the
673 old matrix. Lines not retained are empty. */ 679 old matrix. Lines not retained are empty. */
674 char *retained_p = alloca (window_size * sizeof *retained_p); 680 char *retained_p = SAFE_ALLOCA (window_size);
675 681
676 memset (retained_p, 0, window_size * sizeof (char)); 682 memset (retained_p, 0, window_size * sizeof (char));
677 683
@@ -787,6 +793,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
787 793
788 if (terminal_window_p) 794 if (terminal_window_p)
789 set_terminal_window (frame, 0); 795 set_terminal_window (frame, 0);
796 SAFE_FREE ();
790} 797}
791 798
792 799
@@ -796,8 +803,9 @@ scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top,
796 int unchanged_at_bottom, int *draw_cost, int *old_draw_cost, 803 int unchanged_at_bottom, int *draw_cost, int *old_draw_cost,
797 unsigned *old_hash, unsigned *new_hash, int free_at_end) 804 unsigned *old_hash, unsigned *new_hash, int free_at_end)
798{ 805{
799 struct matrix_elt *matrix 806 USE_SAFE_ALLOCA;
800 = alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix); 807 struct matrix_elt *matrix;
808 SAFE_NALLOCA (matrix, window_size + 1, window_size + 1);
801 809
802 if (FRAME_SCROLL_REGION_OK (frame)) 810 if (FRAME_SCROLL_REGION_OK (frame))
803 { 811 {
@@ -817,6 +825,8 @@ scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top,
817 frame->current_matrix, matrix, window_size, 825 frame->current_matrix, matrix, window_size,
818 unchanged_at_top); 826 unchanged_at_top);
819 } 827 }
828
829 SAFE_FREE ();
820} 830}
821 831
822 832
diff --git a/src/search.c b/src/search.c
index ecfb2352144..9eed390244f 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1318,6 +1318,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1318 translation. Otherwise set to zero later. */ 1318 translation. Otherwise set to zero later. */
1319 int char_base = -1; 1319 int char_base = -1;
1320 bool boyer_moore_ok = 1; 1320 bool boyer_moore_ok = 1;
1321 USE_SAFE_ALLOCA;
1321 1322
1322 /* MULTIBYTE says whether the text to be searched is multibyte. 1323 /* MULTIBYTE says whether the text to be searched is multibyte.
1323 We must convert PATTERN to match that, or we will not really 1324 We must convert PATTERN to match that, or we will not really
@@ -1335,7 +1336,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1335 raw_pattern_size_byte 1336 raw_pattern_size_byte
1336 = count_size_as_multibyte (SDATA (string), 1337 = count_size_as_multibyte (SDATA (string),
1337 raw_pattern_size); 1338 raw_pattern_size);
1338 raw_pattern = alloca (raw_pattern_size_byte + 1); 1339 raw_pattern = SAFE_ALLOCA (raw_pattern_size_byte + 1);
1339 copy_text (SDATA (string), raw_pattern, 1340 copy_text (SDATA (string), raw_pattern,
1340 SCHARS (string), 0, 1); 1341 SCHARS (string), 0, 1);
1341 } 1342 }
@@ -1349,7 +1350,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1349 the chosen single-byte character set can possibly match. */ 1350 the chosen single-byte character set can possibly match. */
1350 raw_pattern_size = SCHARS (string); 1351 raw_pattern_size = SCHARS (string);
1351 raw_pattern_size_byte = SCHARS (string); 1352 raw_pattern_size_byte = SCHARS (string);
1352 raw_pattern = alloca (raw_pattern_size + 1); 1353 raw_pattern = SAFE_ALLOCA (raw_pattern_size + 1);
1353 copy_text (SDATA (string), raw_pattern, 1354 copy_text (SDATA (string), raw_pattern,
1354 SBYTES (string), 1, 0); 1355 SBYTES (string), 1, 0);
1355 } 1356 }
@@ -1357,7 +1358,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1357 /* Copy and optionally translate the pattern. */ 1358 /* Copy and optionally translate the pattern. */
1358 len = raw_pattern_size; 1359 len = raw_pattern_size;
1359 len_byte = raw_pattern_size_byte; 1360 len_byte = raw_pattern_size_byte;
1360 patbuf = alloca (len * MAX_MULTIBYTE_LENGTH); 1361 SAFE_NALLOCA (patbuf, MAX_MULTIBYTE_LENGTH, len);
1361 pat = patbuf; 1362 pat = patbuf;
1362 base_pat = raw_pattern; 1363 base_pat = raw_pattern;
1363 if (multibyte) 1364 if (multibyte)
@@ -1497,13 +1498,15 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1497 len_byte = pat - patbuf; 1498 len_byte = pat - patbuf;
1498 pat = base_pat = patbuf; 1499 pat = base_pat = patbuf;
1499 1500
1500 if (boyer_moore_ok) 1501 EMACS_INT result
1501 return boyer_moore (n, pat, len_byte, trt, inverse_trt, 1502 = (boyer_moore_ok
1502 pos_byte, lim_byte, 1503 ? boyer_moore (n, pat, len_byte, trt, inverse_trt,
1503 char_base); 1504 pos_byte, lim_byte,
1504 else 1505 char_base)
1505 return simple_search (n, pat, raw_pattern_size, len_byte, trt, 1506 : simple_search (n, pat, raw_pattern_size, len_byte, trt,
1506 pos, pos_byte, lim, lim_byte); 1507 pos, pos_byte, lim, lim_byte));
1508 SAFE_FREE ();
1509 return result;
1507 } 1510 }
1508} 1511}
1509 1512
@@ -2809,7 +2812,8 @@ Return value is undefined if the last search failed. */)
2809 2812
2810 prev = Qnil; 2813 prev = Qnil;
2811 2814
2812 data = alloca ((2 * search_regs.num_regs + 1) * sizeof *data); 2815 USE_SAFE_ALLOCA;
2816 SAFE_NALLOCA (data, 1, 2 * search_regs.num_regs + 1);
2813 2817
2814 len = 0; 2818 len = 0;
2815 for (i = 0; i < search_regs.num_regs; i++) 2819 for (i = 0; i < search_regs.num_regs; i++)
@@ -2852,25 +2856,28 @@ Return value is undefined if the last search failed. */)
2852 2856
2853 /* If REUSE is not usable, cons up the values and return them. */ 2857 /* If REUSE is not usable, cons up the values and return them. */
2854 if (! CONSP (reuse)) 2858 if (! CONSP (reuse))
2855 return Flist (len, data); 2859 reuse = Flist (len, data);
2856 2860 else
2857 /* If REUSE is a list, store as many value elements as will fit
2858 into the elements of REUSE. */
2859 for (i = 0, tail = reuse; CONSP (tail);
2860 i++, tail = XCDR (tail))
2861 { 2861 {
2862 /* If REUSE is a list, store as many value elements as will fit
2863 into the elements of REUSE. */
2864 for (i = 0, tail = reuse; CONSP (tail);
2865 i++, tail = XCDR (tail))
2866 {
2867 if (i < len)
2868 XSETCAR (tail, data[i]);
2869 else
2870 XSETCAR (tail, Qnil);
2871 prev = tail;
2872 }
2873
2874 /* If we couldn't fit all value elements into REUSE,
2875 cons up the rest of them and add them to the end of REUSE. */
2862 if (i < len) 2876 if (i < len)
2863 XSETCAR (tail, data[i]); 2877 XSETCDR (prev, Flist (len - i, data + i));
2864 else
2865 XSETCAR (tail, Qnil);
2866 prev = tail;
2867 } 2878 }
2868 2879
2869 /* If we couldn't fit all value elements into REUSE, 2880 SAFE_FREE ();
2870 cons up the rest of them and add them to the end of REUSE. */
2871 if (i < len)
2872 XSETCDR (prev, Flist (len - i, data + i));
2873
2874 return reuse; 2881 return reuse;
2875} 2882}
2876 2883
@@ -3075,7 +3082,8 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
3075 3082
3076 CHECK_STRING (string); 3083 CHECK_STRING (string);
3077 3084
3078 temp = alloca (SBYTES (string) * 2); 3085 USE_SAFE_ALLOCA;
3086 SAFE_NALLOCA (temp, 2, SBYTES (string));
3079 3087
3080 /* Now copy the data into the new string, inserting escapes. */ 3088 /* Now copy the data into the new string, inserting escapes. */
3081 3089
@@ -3093,10 +3101,13 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
3093 *out++ = *in; 3101 *out++ = *in;
3094 } 3102 }
3095 3103
3096 return make_specified_string (temp, 3104 Lisp_Object result
3097 SCHARS (string) + backslashes_added, 3105 = make_specified_string (temp,
3098 out - temp, 3106 SCHARS (string) + backslashes_added,
3099 STRING_MULTIBYTE (string)); 3107 out - temp,
3108 STRING_MULTIBYTE (string));
3109 SAFE_FREE ();
3110 return result;
3100} 3111}
3101 3112
3102/* Like find_newline, but doesn't use the cache, and only searches forward. */ 3113/* Like find_newline, but doesn't use the cache, and only searches forward. */
diff --git a/src/sheap.c b/src/sheap.c
index 5069744435b..956faa36aa1 100644
--- a/src/sheap.c
+++ b/src/sheap.c
@@ -44,6 +44,8 @@ int debug_sheap = 0;
44#define BLOCKSIZE 4096 44#define BLOCKSIZE 4096
45 45
46char bss_sbrk_buffer[STATIC_HEAP_SIZE]; 46char bss_sbrk_buffer[STATIC_HEAP_SIZE];
47/* The following is needed in gmalloc.c */
48void *bss_sbrk_buffer_end = bss_sbrk_buffer + STATIC_HEAP_SIZE;
47char *bss_sbrk_ptr; 49char *bss_sbrk_ptr;
48char *max_bss_sbrk_ptr; 50char *max_bss_sbrk_ptr;
49int bss_sbrk_did_unexec; 51int bss_sbrk_did_unexec;
diff --git a/src/sound.c b/src/sound.c
index 7046f4e8e32..b49348f1256 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -86,8 +86,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
86/* BEGIN: Windows Specific Includes */ 86/* BEGIN: Windows Specific Includes */
87#include <stdio.h> 87#include <stdio.h>
88#include <limits.h> 88#include <limits.h>
89#include <mbstring.h>
89#include <windows.h> 90#include <windows.h>
90#include <mmsystem.h> 91#include <mmsystem.h>
92
93#include "coding.h"
94#include "w32common.h"
95#include "w32.h"
91/* END: Windows Specific Includes */ 96/* END: Windows Specific Includes */
92 97
93#endif /* WINDOWSNT */ 98#endif /* WINDOWSNT */
@@ -564,12 +569,11 @@ wav_play (struct sound *s, struct sound_device *sd)
564 SBYTES (s->data) - sizeof *header); 569 SBYTES (s->data) - sizeof *header);
565 else 570 else
566 { 571 {
567 char *buffer;
568 ptrdiff_t nbytes = 0; 572 ptrdiff_t nbytes = 0;
569 ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048; 573 ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
570 ptrdiff_t data_left = header->data_length; 574 ptrdiff_t data_left = header->data_length;
571 575 USE_SAFE_ALLOCA;
572 buffer = alloca (blksize); 576 char *buffer = SAFE_ALLOCA (blksize);
573 lseek (s->fd, sizeof *header, SEEK_SET); 577 lseek (s->fd, sizeof *header, SEEK_SET);
574 while (data_left > 0 578 while (data_left > 0
575 && (nbytes = emacs_read (s->fd, buffer, blksize)) > 0) 579 && (nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
@@ -582,6 +586,7 @@ wav_play (struct sound *s, struct sound_device *sd)
582 586
583 if (nbytes < 0) 587 if (nbytes < 0)
584 sound_perror ("Error reading sound file"); 588 sound_perror ("Error reading sound file");
589 SAFE_FREE ();
585 } 590 }
586} 591}
587 592
@@ -656,19 +661,20 @@ au_play (struct sound *s, struct sound_device *sd)
656 else 661 else
657 { 662 {
658 ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048; 663 ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
659 char *buffer;
660 ptrdiff_t nbytes; 664 ptrdiff_t nbytes;
661 665
662 /* Seek */ 666 /* Seek */
663 lseek (s->fd, header->data_offset, SEEK_SET); 667 lseek (s->fd, header->data_offset, SEEK_SET);
664 668
665 /* Copy sound data to the device. */ 669 /* Copy sound data to the device. */
666 buffer = alloca (blksize); 670 USE_SAFE_ALLOCA;
671 char *buffer = SAFE_ALLOCA (blksize);
667 while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0) 672 while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
668 sd->write (sd, buffer, nbytes); 673 sd->write (sd, buffer, nbytes);
669 674
670 if (nbytes < 0) 675 if (nbytes < 0)
671 sound_perror ("Error reading sound file"); 676 sound_perror ("Error reading sound file");
677 SAFE_FREE ();
672 } 678 }
673} 679}
674 680
@@ -1203,38 +1209,83 @@ alsa_init (struct sound_device *sd)
1203 1209
1204/* BEGIN: Windows specific functions */ 1210/* BEGIN: Windows specific functions */
1205 1211
1206#define SOUND_WARNING(fun, error, text) \ 1212#define SOUND_WARNING(func, error, text) \
1207 { \ 1213 do { \
1208 char buf[1024]; \ 1214 char buf[1024]; \
1209 char err_string[MAXERRORLENGTH]; \ 1215 char err_string[MAXERRORLENGTH]; \
1210 fun (error, err_string, sizeof (err_string)); \ 1216 func (error, err_string, sizeof (err_string)); \
1211 _snprintf (buf, sizeof (buf), "%s\nError: %s", \ 1217 _snprintf (buf, sizeof (buf), "%s\nMCI Error: %s", \
1212 text, err_string); \ 1218 text, err_string); \
1213 sound_warning (buf); \ 1219 message_with_string ("%s", build_string (buf), 1); \
1214 } 1220 } while (0)
1215 1221
1216static int 1222static int
1217do_play_sound (const char *psz_file, unsigned long ui_volume) 1223do_play_sound (const char *psz_file, unsigned long ui_volume)
1218{ 1224{
1219 int i_result = 0; 1225 int i_result = 0;
1220 MCIERROR mci_error = 0; 1226 MCIERROR mci_error = 0;
1221 char sz_cmd_buf[520] = {0}; 1227 char sz_cmd_buf_a[520];
1222 char sz_ret_buf[520] = {0}; 1228 char sz_ret_buf_a[520];
1223 MMRESULT mm_result = MMSYSERR_NOERROR; 1229 MMRESULT mm_result = MMSYSERR_NOERROR;
1224 unsigned long ui_volume_org = 0; 1230 unsigned long ui_volume_org = 0;
1225 BOOL b_reset_volume = FALSE; 1231 BOOL b_reset_volume = FALSE;
1232 char warn_text[560];
1233
1234 /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we
1235 need to encode the file in the ANSI codepage on Windows 9X even
1236 if w32_unicode_filenames is non-zero. */
1237 if (w32_major_version <= 4 || !w32_unicode_filenames)
1238 {
1239 char fname_a[MAX_PATH], shortname[MAX_PATH], *fname_to_use;
1240
1241 filename_to_ansi (psz_file, fname_a);
1242 fname_to_use = fname_a;
1243 /* If the file name is not encodable in ANSI, try its short 8+3
1244 alias. This will only work if w32_unicode_filenames is
1245 non-zero. */
1246 if (_mbspbrk ((const unsigned char *)fname_a,
1247 (const unsigned char *)"?"))
1248 {
1249 if (w32_get_short_filename (psz_file, shortname, MAX_PATH))
1250 fname_to_use = shortname;
1251 else
1252 mci_error = MCIERR_FILE_NOT_FOUND;
1253 }
1226 1254
1227 memset (sz_cmd_buf, 0, sizeof (sz_cmd_buf)); 1255 if (!mci_error)
1228 memset (sz_ret_buf, 0, sizeof (sz_ret_buf)); 1256 {
1229 sprintf (sz_cmd_buf, 1257 memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
1230 "open \"%s\" alias GNUEmacs_PlaySound_Device wait", 1258 memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
1231 psz_file); 1259 sprintf (sz_cmd_buf_a,
1232 mci_error = mciSendString (sz_cmd_buf, sz_ret_buf, sizeof (sz_ret_buf), NULL); 1260 "open \"%s\" alias GNUEmacs_PlaySound_Device wait",
1261 fname_to_use);
1262 mci_error = mciSendStringA (sz_cmd_buf_a,
1263 sz_ret_buf_a, sizeof (sz_ret_buf_a), NULL);
1264 }
1265 }
1266 else
1267 {
1268 wchar_t sz_cmd_buf_w[520];
1269 wchar_t sz_ret_buf_w[520];
1270 wchar_t fname_w[MAX_PATH];
1271
1272 filename_to_utf16 (psz_file, fname_w);
1273 memset (sz_cmd_buf_w, 0, sizeof (sz_cmd_buf_w));
1274 memset (sz_ret_buf_w, 0, sizeof (sz_ret_buf_w));
1275 /* _swprintf is not available on Windows 9X, so we construct the
1276 UTF-16 command string by hand. */
1277 wcscpy (sz_cmd_buf_w, L"open \"");
1278 wcscat (sz_cmd_buf_w, fname_w);
1279 wcscat (sz_cmd_buf_w, L"\" alias GNUEmacs_PlaySound_Device wait");
1280 mci_error = mciSendStringW (sz_cmd_buf_w,
1281 sz_ret_buf_w, ARRAYELTS (sz_ret_buf_w) , NULL);
1282 }
1233 if (mci_error != 0) 1283 if (mci_error != 0)
1234 { 1284 {
1235 SOUND_WARNING (mciGetErrorString, mci_error, 1285 strcpy (warn_text,
1236 "The open mciSendString command failed to open " 1286 "mciSendString: 'open' command failed to open sound file ");
1237 "the specified sound file."); 1287 strcat (warn_text, psz_file);
1288 SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
1238 i_result = (int) mci_error; 1289 i_result = (int) mci_error;
1239 return i_result; 1290 return i_result;
1240 } 1291 }
@@ -1248,44 +1299,47 @@ do_play_sound (const char *psz_file, unsigned long ui_volume)
1248 if (mm_result != MMSYSERR_NOERROR) 1299 if (mm_result != MMSYSERR_NOERROR)
1249 { 1300 {
1250 SOUND_WARNING (waveOutGetErrorText, mm_result, 1301 SOUND_WARNING (waveOutGetErrorText, mm_result,
1251 "waveOutSetVolume failed to set the volume level " 1302 "waveOutSetVolume: failed to set the volume level"
1252 "of the WAVE_MAPPER device.\n" 1303 " of the WAVE_MAPPER device.\n"
1253 "As a result, the user selected volume level will " 1304 "As a result, the user selected volume level will"
1254 "not be used."); 1305 " not be used.");
1255 } 1306 }
1256 } 1307 }
1257 else 1308 else
1258 { 1309 {
1259 SOUND_WARNING (waveOutGetErrorText, mm_result, 1310 SOUND_WARNING (waveOutGetErrorText, mm_result,
1260 "waveOutGetVolume failed to obtain the original " 1311 "waveOutGetVolume: failed to obtain the original"
1261 "volume level of the WAVE_MAPPER device.\n" 1312 " volume level of the WAVE_MAPPER device.\n"
1262 "As a result, the user selected volume level will " 1313 "As a result, the user selected volume level will"
1263 "not be used."); 1314 " not be used.");
1264 } 1315 }
1265 } 1316 }
1266 memset (sz_cmd_buf, 0, sizeof (sz_cmd_buf)); 1317 memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
1267 memset (sz_ret_buf, 0, sizeof (sz_ret_buf)); 1318 memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
1268 strcpy (sz_cmd_buf, "play GNUEmacs_PlaySound_Device wait"); 1319 strcpy (sz_cmd_buf_a, "play GNUEmacs_PlaySound_Device wait");
1269 mci_error = mciSendString (sz_cmd_buf, sz_ret_buf, sizeof (sz_ret_buf), NULL); 1320 mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
1321 NULL);
1270 if (mci_error != 0) 1322 if (mci_error != 0)
1271 { 1323 {
1272 SOUND_WARNING (mciGetErrorString, mci_error, 1324 strcpy (warn_text,
1273 "The play mciSendString command failed to play the " 1325 "mciSendString: 'play' command failed to play sound file ");
1274 "opened sound file."); 1326 strcat (warn_text, psz_file);
1327 SOUND_WARNING (mciGetErrorString, mci_error, warn_text);
1275 i_result = (int) mci_error; 1328 i_result = (int) mci_error;
1276 } 1329 }
1277 memset (sz_cmd_buf, 0, sizeof (sz_cmd_buf)); 1330 memset (sz_cmd_buf_a, 0, sizeof (sz_cmd_buf_a));
1278 memset (sz_ret_buf, 0, sizeof (sz_ret_buf)); 1331 memset (sz_ret_buf_a, 0, sizeof (sz_ret_buf_a));
1279 strcpy (sz_cmd_buf, "close GNUEmacs_PlaySound_Device wait"); 1332 strcpy (sz_cmd_buf_a, "close GNUEmacs_PlaySound_Device wait");
1280 mci_error = mciSendString (sz_cmd_buf, sz_ret_buf, sizeof (sz_ret_buf), NULL); 1333 mci_error = mciSendStringA (sz_cmd_buf_a, sz_ret_buf_a, sizeof (sz_ret_buf_a),
1334 NULL);
1281 if (b_reset_volume == TRUE) 1335 if (b_reset_volume == TRUE)
1282 { 1336 {
1283 mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org); 1337 mm_result = waveOutSetVolume ((HWAVEOUT) WAVE_MAPPER, ui_volume_org);
1284 if (mm_result != MMSYSERR_NOERROR) 1338 if (mm_result != MMSYSERR_NOERROR)
1285 { 1339 {
1286 SOUND_WARNING (waveOutGetErrorText, mm_result, 1340 SOUND_WARNING (waveOutGetErrorText, mm_result,
1287 "waveOutSetVolume failed to reset the original volume " 1341 "waveOutSetVolume: failed to reset the original"
1288 "level of the WAVE_MAPPER device."); 1342 " volume level of the WAVE_MAPPER device.");
1289 } 1343 }
1290 } 1344 }
1291 return i_result; 1345 return i_result;
@@ -1303,15 +1357,11 @@ Internal use only, use `play-sound' instead. */)
1303{ 1357{
1304 Lisp_Object attrs[SOUND_ATTR_SENTINEL]; 1358 Lisp_Object attrs[SOUND_ATTR_SENTINEL];
1305 ptrdiff_t count = SPECPDL_INDEX (); 1359 ptrdiff_t count = SPECPDL_INDEX ();
1306
1307#ifndef WINDOWSNT
1308 Lisp_Object file; 1360 Lisp_Object file;
1309 struct gcpro gcpro1, gcpro2;
1310 Lisp_Object args[2]; 1361 Lisp_Object args[2];
1311#else /* WINDOWSNT */ 1362 struct gcpro gcpro1, gcpro2;
1312 int len = 0; 1363
1313 Lisp_Object lo_file = {0}; 1364#ifdef WINDOWSNT
1314 char * psz_file = NULL;
1315 unsigned long ui_volume_tmp = UINT_MAX; 1365 unsigned long ui_volume_tmp = UINT_MAX;
1316 unsigned long ui_volume = UINT_MAX; 1366 unsigned long ui_volume = UINT_MAX;
1317#endif /* WINDOWSNT */ 1367#endif /* WINDOWSNT */
@@ -1326,7 +1376,8 @@ Internal use only, use `play-sound' instead. */)
1326 current_sound_device = xzalloc (sizeof *current_sound_device); 1376 current_sound_device = xzalloc (sizeof *current_sound_device);
1327 current_sound = xzalloc (sizeof *current_sound); 1377 current_sound = xzalloc (sizeof *current_sound);
1328 record_unwind_protect_void (sound_cleanup); 1378 record_unwind_protect_void (sound_cleanup);
1329 current_sound->header = alloca (MAX_SOUND_HEADER_BYTES); 1379 char headerbuf[MAX_SOUND_HEADER_BYTES];
1380 current_sound->header = headerbuf;
1330 1381
1331 if (STRINGP (attrs[SOUND_FILE])) 1382 if (STRINGP (attrs[SOUND_FILE]))
1332 { 1383 {
@@ -1383,10 +1434,8 @@ Internal use only, use `play-sound' instead. */)
1383 1434
1384#else /* WINDOWSNT */ 1435#else /* WINDOWSNT */
1385 1436
1386 lo_file = Fexpand_file_name (attrs[SOUND_FILE], Qnil); 1437 file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
1387 len = XSTRING (lo_file)->size; 1438 file = ENCODE_FILE (file);
1388 psz_file = alloca (len + 1);
1389 strcpy (psz_file, XSTRING (lo_file)->data);
1390 if (INTEGERP (attrs[SOUND_VOLUME])) 1439 if (INTEGERP (attrs[SOUND_VOLUME]))
1391 { 1440 {
1392 ui_volume_tmp = XFASTINT (attrs[SOUND_VOLUME]); 1441 ui_volume_tmp = XFASTINT (attrs[SOUND_VOLUME]);
@@ -1395,6 +1444,13 @@ Internal use only, use `play-sound' instead. */)
1395 { 1444 {
1396 ui_volume_tmp = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100; 1445 ui_volume_tmp = XFLOAT_DATA (attrs[SOUND_VOLUME]) * 100;
1397 } 1446 }
1447
1448 GCPRO2 (sound, file);
1449
1450 args[0] = Qplay_sound_functions;
1451 args[1] = sound;
1452 Frun_hook_with_args (2, args);
1453
1398 /* 1454 /*
1399 Based on some experiments I have conducted, a value of 100 or less 1455 Based on some experiments I have conducted, a value of 100 or less
1400 for the sound volume is much too low. You cannot even hear it. 1456 for the sound volume is much too low. You cannot even hear it.
@@ -1408,7 +1464,9 @@ Internal use only, use `play-sound' instead. */)
1408 { 1464 {
1409 ui_volume = ui_volume_tmp * (UINT_MAX / 100); 1465 ui_volume = ui_volume_tmp * (UINT_MAX / 100);
1410 } 1466 }
1411 do_play_sound (psz_file, ui_volume); 1467 (void)do_play_sound (SSDATA (file), ui_volume);
1468
1469 UNGCPRO;
1412 1470
1413#endif /* WINDOWSNT */ 1471#endif /* WINDOWSNT */
1414 1472
diff --git a/src/syntax.c b/src/syntax.c
index 4166ee211c7..9f5ef754e2a 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1231,7 +1231,7 @@ DEFUN ("internal-describe-syntax-value", Finternal_describe_syntax_value,
1231 syntax_code = XINT (first) & INT_MAX; 1231 syntax_code = XINT (first) & INT_MAX;
1232 code = syntax_code & 0377; 1232 code = syntax_code & 0377;
1233 start1 = SYNTAX_FLAGS_COMSTART_FIRST (syntax_code); 1233 start1 = SYNTAX_FLAGS_COMSTART_FIRST (syntax_code);
1234 start2 = SYNTAX_FLAGS_COMSTART_SECOND (syntax_code);; 1234 start2 = SYNTAX_FLAGS_COMSTART_SECOND (syntax_code);
1235 end1 = SYNTAX_FLAGS_COMEND_FIRST (syntax_code); 1235 end1 = SYNTAX_FLAGS_COMEND_FIRST (syntax_code);
1236 end2 = SYNTAX_FLAGS_COMEND_SECOND (syntax_code); 1236 end2 = SYNTAX_FLAGS_COMEND_SECOND (syntax_code);
1237 prefix = SYNTAX_FLAGS_PREFIX (syntax_code); 1237 prefix = SYNTAX_FLAGS_PREFIX (syntax_code);
@@ -1567,6 +1567,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1567 const unsigned char *str; 1567 const unsigned char *str;
1568 int len; 1568 int len;
1569 Lisp_Object iso_classes; 1569 Lisp_Object iso_classes;
1570 USE_SAFE_ALLOCA;
1570 1571
1571 CHECK_STRING (string); 1572 CHECK_STRING (string);
1572 iso_classes = Qnil; 1573 iso_classes = Qnil;
@@ -1699,7 +1700,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1699 memcpy (himap, fastmap + 0200, 0200); 1700 memcpy (himap, fastmap + 0200, 0200);
1700 himap[0200] = 0; 1701 himap[0200] = 0;
1701 memset (fastmap + 0200, 0, 0200); 1702 memset (fastmap + 0200, 0, 0200);
1702 char_ranges = alloca (sizeof *char_ranges * 128 * 2); 1703 SAFE_NALLOCA (char_ranges, 2, 128);
1703 i = 0; 1704 i = 0;
1704 1705
1705 while ((p1 = memchr (himap + i, 1, 0200 - i))) 1706 while ((p1 = memchr (himap + i, 1, 0200 - i)))
@@ -1723,7 +1724,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1723 } 1724 }
1724 else /* STRING is multibyte */ 1725 else /* STRING is multibyte */
1725 { 1726 {
1726 char_ranges = alloca (sizeof *char_ranges * SCHARS (string) * 2); 1727 SAFE_NALLOCA (char_ranges, 2, SCHARS (string));
1727 1728
1728 while (i_byte < size_byte) 1729 while (i_byte < size_byte)
1729 { 1730 {
@@ -2032,6 +2033,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
2032 SET_PT_BOTH (pos, pos_byte); 2033 SET_PT_BOTH (pos, pos_byte);
2033 immediate_quit = 0; 2034 immediate_quit = 0;
2034 2035
2036 SAFE_FREE ();
2035 return make_number (PT - start_point); 2037 return make_number (PT - start_point);
2036 } 2038 }
2037} 2039}
@@ -2857,10 +2859,13 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2857 case Smath: 2859 case Smath:
2858 if (!sexpflag) 2860 if (!sexpflag)
2859 break; 2861 break;
2860 temp_pos = dec_bytepos (from_byte); 2862 if (from > BEGV)
2861 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2863 {
2862 if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (temp_pos)) 2864 temp_pos = dec_bytepos (from_byte);
2863 DEC_BOTH (from, from_byte); 2865 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2866 if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (temp_pos))
2867 DEC_BOTH (from, from_byte);
2868 }
2864 if (mathexit) 2869 if (mathexit)
2865 { 2870 {
2866 mathexit = 0; 2871 mathexit = 0;
diff --git a/src/sysdep.c b/src/sysdep.c
index d5cfd5b88cf..24cc5cb0b40 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -19,6 +19,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20#include <config.h> 20#include <config.h>
21 21
22/* If HYBRID_GET_CURRENT_DIR_NAME is defined in conf_post.h, then we
23 need the following before including unistd.h, in order to pick up
24 the right prototype for gget_current_dir_name. */
25#ifdef HYBRID_GET_CURRENT_DIR_NAME
26#undef get_current_dir_name
27#define get_current_dir_name gget_current_dir_name
28#endif
29
22#include <execinfo.h> 30#include <execinfo.h>
23#include "sysstdio.h" 31#include "sysstdio.h"
24#ifdef HAVE_PWD_H 32#ifdef HAVE_PWD_H
@@ -46,7 +54,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
46# include <sys/user.h> 54# include <sys/user.h>
47# undef frame 55# undef frame
48 56
49# include <sys/resource.h>
50# include <math.h> 57# include <math.h>
51#endif 58#endif
52 59
@@ -72,6 +79,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
72#include "msdos.h" 79#include "msdos.h"
73#endif 80#endif
74 81
82#ifdef HAVE_SYS_RESOURCE_H
83#include <sys/resource.h>
84#endif
75#include <sys/param.h> 85#include <sys/param.h>
76#include <sys/file.h> 86#include <sys/file.h>
77#include <fcntl.h> 87#include <fcntl.h>
@@ -119,9 +129,8 @@ static const int baud_convert[] =
119 1800, 2400, 4800, 9600, 19200, 38400 129 1800, 2400, 4800, 9600, 19200, 38400
120 }; 130 };
121 131
122 132#if !defined HAVE_GET_CURRENT_DIR_NAME || defined BROKEN_GET_CURRENT_DIR_NAME \
123#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME) 133 || (defined HYBRID_GET_CURRENT_DIR_NAME)
124
125/* Return the current working directory. Returns NULL on errors. 134/* Return the current working directory. Returns NULL on errors.
126 Any other returned value must be freed with free. This is used 135 Any other returned value must be freed with free. This is used
127 only when get_current_dir_name is not defined on the system. */ 136 only when get_current_dir_name is not defined on the system. */
@@ -1716,6 +1725,83 @@ handle_arith_signal (int sig)
1716 xsignal0 (Qarith_error); 1725 xsignal0 (Qarith_error);
1717} 1726}
1718 1727
1728#ifdef HAVE_STACK_OVERFLOW_HANDLING
1729
1730/* -1 if stack grows down as expected on most OS/ABI variants, 1 otherwise. */
1731
1732static int stack_direction;
1733
1734/* Alternate stack used by SIGSEGV handler below. */
1735
1736static unsigned char sigsegv_stack[SIGSTKSZ];
1737
1738/* Attempt to recover from SIGSEGV caused by C stack overflow. */
1739
1740static void
1741handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
1742{
1743 /* Hard GC error may lead to stack overflow caused by
1744 too nested calls to mark_object. No way to survive. */
1745 if (!gc_in_progress)
1746 {
1747 struct rlimit rlim;
1748
1749 if (!getrlimit (RLIMIT_STACK, &rlim))
1750 {
1751 enum { STACK_DANGER_ZONE = 16 * 1024 };
1752 char *beg, *end, *addr;
1753
1754 beg = stack_bottom;
1755 end = stack_bottom + stack_direction * rlim.rlim_cur;
1756 if (beg > end)
1757 addr = beg, beg = end, end = addr;
1758 addr = (char *) siginfo->si_addr;
1759 /* If we're somewhere on stack and too close to
1760 one of its boundaries, most likely this is it. */
1761 if (beg < addr && addr < end
1762 && (addr - beg < STACK_DANGER_ZONE
1763 || end - addr < STACK_DANGER_ZONE))
1764 siglongjmp (return_to_command_loop, 1);
1765 }
1766 }
1767
1768 /* Otherwise we can't do anything with this. */
1769 deliver_fatal_thread_signal (sig);
1770}
1771
1772/* Return true if we have successfully set up SIGSEGV handler on alternate
1773 stack. Otherwise we just treat SIGSEGV among the rest of fatal signals. */
1774
1775static bool
1776init_sigsegv (void)
1777{
1778 struct sigaction sa;
1779 stack_t ss;
1780
1781 stack_direction = ((char *) &ss < stack_bottom) ? -1 : 1;
1782
1783 ss.ss_sp = sigsegv_stack;
1784 ss.ss_size = sizeof (sigsegv_stack);
1785 ss.ss_flags = 0;
1786 if (sigaltstack (&ss, NULL) < 0)
1787 return 0;
1788
1789 sigfillset (&sa.sa_mask);
1790 sa.sa_sigaction = handle_sigsegv;
1791 sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags ();
1792 return sigaction (SIGSEGV, &sa, NULL) < 0 ? 0 : 1;
1793}
1794
1795#else /* not HAVE_STACK_OVERFLOW_HANDLING */
1796
1797static bool
1798init_sigsegv (void)
1799{
1800 return 0;
1801}
1802
1803#endif /* HAVE_STACK_OVERFLOW_HANDLING */
1804
1719static void 1805static void
1720deliver_arith_signal (int sig) 1806deliver_arith_signal (int sig)
1721{ 1807{
@@ -1982,7 +2068,8 @@ init_signals (bool dumping)
1982#ifdef SIGBUS 2068#ifdef SIGBUS
1983 sigaction (SIGBUS, &thread_fatal_action, 0); 2069 sigaction (SIGBUS, &thread_fatal_action, 0);
1984#endif 2070#endif
1985 sigaction (SIGSEGV, &thread_fatal_action, 0); 2071 if (!init_sigsegv ())
2072 sigaction (SIGSEGV, &thread_fatal_action, 0);
1986#ifdef SIGSYS 2073#ifdef SIGSYS
1987 sigaction (SIGSYS, &thread_fatal_action, 0); 2074 sigaction (SIGSYS, &thread_fatal_action, 0);
1988#endif 2075#endif
@@ -2370,7 +2457,7 @@ emacs_full_write (int fildes, char const *buf, ptrdiff_t nbyte,
2370 { 2457 {
2371 if (errno == EINTR) 2458 if (errno == EINTR)
2372 { 2459 {
2373 /* I originally used `QUIT' but that might causes files to 2460 /* I originally used `QUIT' but that might cause files to
2374 be truncated if you hit C-g in the middle of it. --Stef */ 2461 be truncated if you hit C-g in the middle of it. --Stef */
2375 if (process_signals && pending_signals) 2462 if (process_signals && pending_signals)
2376 process_pending_signals (); 2463 process_pending_signals ();
@@ -3513,3 +3600,208 @@ system_process_attributes (Lisp_Object pid)
3513} 3600}
3514 3601
3515#endif /* !defined (WINDOWSNT) */ 3602#endif /* !defined (WINDOWSNT) */
3603
3604/* Wide character string collation. */
3605
3606#ifdef __STDC_ISO_10646__
3607# include <wchar.h>
3608# include <wctype.h>
3609
3610# if defined HAVE_NEWLOCALE || defined HAVE_SETLOCALE
3611# include <locale.h>
3612# endif
3613# ifndef LC_COLLATE
3614# define LC_COLLATE 0
3615# endif
3616# ifndef LC_COLLATE_MASK
3617# define LC_COLLATE_MASK 0
3618# endif
3619# ifndef LC_CTYPE
3620# define LC_CTYPE 0
3621# endif
3622# ifndef LC_CTYPE_MASK
3623# define LC_CTYPE_MASK 0
3624# endif
3625
3626# ifndef HAVE_NEWLOCALE
3627# undef freelocale
3628# undef locale_t
3629# undef newlocale
3630# undef wcscoll_l
3631# undef towlower_l
3632# define freelocale emacs_freelocale
3633# define locale_t emacs_locale_t
3634# define newlocale emacs_newlocale
3635# define wcscoll_l emacs_wcscoll_l
3636# define towlower_l emacs_towlower_l
3637
3638typedef char const *locale_t;
3639
3640static locale_t
3641newlocale (int category_mask, char const *locale, locale_t loc)
3642{
3643 return locale;
3644}
3645
3646static void
3647freelocale (locale_t loc)
3648{
3649}
3650
3651static char *
3652emacs_setlocale (int category, char const *locale)
3653{
3654# ifdef HAVE_SETLOCALE
3655 errno = 0;
3656 char *loc = setlocale (category, locale);
3657 if (loc || errno)
3658 return loc;
3659 errno = EINVAL;
3660# else
3661 errno = ENOTSUP;
3662# endif
3663 return 0;
3664}
3665
3666static int
3667wcscoll_l (wchar_t const *a, wchar_t const *b, locale_t loc)
3668{
3669 int result = 0;
3670 char *oldloc = emacs_setlocale (LC_COLLATE, NULL);
3671 int err;
3672
3673 if (! oldloc)
3674 err = errno;
3675 else
3676 {
3677 USE_SAFE_ALLOCA;
3678 char *oldcopy = SAFE_ALLOCA (strlen (oldloc) + 1);
3679 strcpy (oldcopy, oldloc);
3680 if (! emacs_setlocale (LC_COLLATE, loc))
3681 err = errno;
3682 else
3683 {
3684 errno = 0;
3685 result = wcscoll (a, b);
3686 err = errno;
3687 if (! emacs_setlocale (LC_COLLATE, oldcopy))
3688 err = errno;
3689 }
3690 SAFE_FREE ();
3691 }
3692
3693 errno = err;
3694 return result;
3695}
3696
3697static wint_t
3698towlower_l (wint_t wc, locale_t loc)
3699{
3700 wint_t result = wc;
3701 char *oldloc = emacs_setlocale (LC_CTYPE, NULL);
3702
3703 if (oldloc)
3704 {
3705 USE_SAFE_ALLOCA;
3706 char *oldcopy = SAFE_ALLOCA (strlen (oldloc) + 1);
3707 strcpy (oldcopy, oldloc);
3708 if (emacs_setlocale (LC_CTYPE, loc))
3709 {
3710 result = towlower (wc);
3711 emacs_setlocale (LC_COLLATE, oldcopy);
3712 }
3713 SAFE_FREE ();
3714 }
3715
3716 return result;
3717}
3718# endif
3719
3720int
3721str_collate (Lisp_Object s1, Lisp_Object s2,
3722 Lisp_Object locale, Lisp_Object ignore_case)
3723{
3724 int res, err;
3725 ptrdiff_t len, i, i_byte;
3726 wchar_t *p1, *p2;
3727
3728 USE_SAFE_ALLOCA;
3729
3730 /* Convert byte stream to code points. */
3731 len = SCHARS (s1); i = i_byte = 0;
3732 SAFE_NALLOCA (p1, 1, len + 1);
3733 while (i < len)
3734 FETCH_STRING_CHAR_ADVANCE (*(p1+i-1), s1, i, i_byte);
3735 *(p1+len) = 0;
3736
3737 len = SCHARS (s2); i = i_byte = 0;
3738 SAFE_NALLOCA (p2, 1, len + 1);
3739 while (i < len)
3740 FETCH_STRING_CHAR_ADVANCE (*(p2+i-1), s2, i, i_byte);
3741 *(p2+len) = 0;
3742
3743 if (STRINGP (locale))
3744 {
3745 locale_t loc = newlocale (LC_COLLATE_MASK | LC_CTYPE_MASK,
3746 SSDATA (locale), 0);
3747 if (!loc)
3748 error ("Invalid locale %s: %s", SSDATA (locale), strerror (errno));
3749
3750 if (! NILP (ignore_case))
3751 for (int i = 1; i < 3; i++)
3752 {
3753 wchar_t *p = (i == 1) ? p1 : p2;
3754 for (; *p; p++)
3755 *p = towlower_l (*p, loc);
3756 }
3757
3758 errno = 0;
3759 res = wcscoll_l (p1, p2, loc);
3760 err = errno;
3761 freelocale (loc);
3762 }
3763 else
3764 {
3765 if (! NILP (ignore_case))
3766 for (int i = 1; i < 3; i++)
3767 {
3768 wchar_t *p = (i == 1) ? p1 : p2;
3769 for (; *p; p++)
3770 *p = towlower (*p);
3771 }
3772
3773 errno = 0;
3774 res = wcscoll (p1, p2);
3775 err = errno;
3776 }
3777# ifndef HAVE_NEWLOCALE
3778 if (err)
3779 error ("Invalid locale or string for collation: %s", strerror (err));
3780# else
3781 if (err)
3782 error ("Invalid string for collation: %s", strerror (err));
3783# endif
3784
3785 SAFE_FREE ();
3786 return res;
3787}
3788#endif /* __STDC_ISO_10646__ */
3789
3790#ifdef WINDOWSNT
3791int
3792str_collate (Lisp_Object s1, Lisp_Object s2,
3793 Lisp_Object locale, Lisp_Object ignore_case)
3794{
3795
3796 char *loc = STRINGP (locale) ? SSDATA (locale) : NULL;
3797 int res, err = errno;
3798
3799 errno = 0;
3800 res = w32_compare_strings (SDATA (s1), SDATA (s2), loc, !NILP (ignore_case));
3801 if (errno)
3802 error ("Invalid string for collation: %s", strerror (errno));
3803
3804 errno = err;
3805 return res;
3806}
3807#endif /* WINDOWSNT */
diff --git a/src/systime.h b/src/systime.h
index a834bce76dc..8f018044660 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -93,6 +93,22 @@ extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
93extern struct timespec lisp_time_argument (Lisp_Object); 93extern struct timespec lisp_time_argument (Lisp_Object);
94#endif 94#endif
95 95
96#ifndef HAVE_TZALLOC
97# undef mktime_z
98# undef timezone_t
99# undef tzalloc
100# undef tzfree
101# define mktime_z emacs_mktime_z
102# define timezone_t emacs_timezone_t
103# define tzalloc emacs_tzalloc
104# define tzfree emacs_tzfree
105typedef char const *timezone_t;
106INLINE timezone_t tzalloc (char const *name) { return name; }
107INLINE void tzfree (timezone_t tz) { }
108/* Defined in editfns.c. */
109extern time_t mktime_z (timezone_t, struct tm *);
110#endif
111
96INLINE_HEADER_END 112INLINE_HEADER_END
97 113
98#endif /* EMACS_SYSTIME_H */ 114#endif /* EMACS_SYSTIME_H */
diff --git a/src/term.c b/src/term.c
index c8ff6f31575..04f6e3318a0 100644
--- a/src/term.c
+++ b/src/term.c
@@ -77,7 +77,6 @@ static void tty_turn_off_highlight (struct tty_display_info *);
77static void tty_show_cursor (struct tty_display_info *); 77static void tty_show_cursor (struct tty_display_info *);
78static void tty_hide_cursor (struct tty_display_info *); 78static void tty_hide_cursor (struct tty_display_info *);
79static void tty_background_highlight (struct tty_display_info *tty); 79static void tty_background_highlight (struct tty_display_info *tty);
80static struct terminal *get_tty_terminal (Lisp_Object, bool);
81static void clear_tty_hooks (struct terminal *terminal); 80static void clear_tty_hooks (struct terminal *terminal);
82static void set_tty_hooks (struct terminal *terminal); 81static void set_tty_hooks (struct terminal *terminal);
83static void dissociate_if_controlling_tty (int fd); 82static void dissociate_if_controlling_tty (int fd);
@@ -2029,11 +2028,9 @@ selected frame's terminal). This function always returns nil if
2029TERMINAL does not refer to a text terminal. */) 2028TERMINAL does not refer to a text terminal. */)
2030 (Lisp_Object terminal) 2029 (Lisp_Object terminal)
2031{ 2030{
2032 struct terminal *t = get_tty_terminal (terminal, 0); 2031 struct terminal *t = decode_tty_terminal (terminal);
2033 if (!t) 2032
2034 return Qnil; 2033 return (t && t->display_info.tty->TN_max_colors > 0) ? Qt : Qnil;
2035 else
2036 return t->display_info.tty->TN_max_colors > 0 ? Qt : Qnil;
2037} 2034}
2038 2035
2039/* Return the number of supported colors. */ 2036/* Return the number of supported colors. */
@@ -2046,11 +2043,9 @@ selected frame's terminal). This function always returns 0 if
2046TERMINAL does not refer to a text terminal. */) 2043TERMINAL does not refer to a text terminal. */)
2047 (Lisp_Object terminal) 2044 (Lisp_Object terminal)
2048{ 2045{
2049 struct terminal *t = get_tty_terminal (terminal, 0); 2046 struct terminal *t = decode_tty_terminal (terminal);
2050 if (!t) 2047
2051 return make_number (0); 2048 return make_number (t ? t->display_info.tty->TN_max_colors : 0);
2052 else
2053 return make_number (t->display_info.tty->TN_max_colors);
2054} 2049}
2055 2050
2056#ifndef DOS_NT 2051#ifndef DOS_NT
@@ -2165,52 +2160,6 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
2165 2160
2166#endif /* !DOS_NT */ 2161#endif /* !DOS_NT */
2167 2162
2168
2169
2170/* Return the tty display object specified by TERMINAL. */
2171
2172static struct terminal *
2173get_tty_terminal (Lisp_Object terminal, bool throw)
2174{
2175 struct terminal *t = get_terminal (terminal, throw);
2176
2177 if (t && t->type != output_termcap && t->type != output_msdos_raw)
2178 {
2179 if (throw)
2180 error ("Device %d is not a termcap terminal device", t->id);
2181 else
2182 return NULL;
2183 }
2184
2185 return t;
2186}
2187
2188/* Return an active termcap device that uses the tty device with the
2189 given name.
2190
2191 This function ignores suspended devices.
2192
2193 Returns NULL if the named terminal device is not opened. */
2194
2195struct terminal *
2196get_named_tty (const char *name)
2197{
2198 struct terminal *t;
2199
2200 eassert (name);
2201
2202 for (t = terminal_list; t; t = t->next_terminal)
2203 {
2204 if ((t->type == output_termcap || t->type == output_msdos_raw)
2205 && !strcmp (t->display_info.tty->name, name)
2206 && TERMINAL_ACTIVE_P (t))
2207 return t;
2208 }
2209
2210 return 0;
2211}
2212
2213
2214DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0, 2163DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0,
2215 doc: /* Return the type of the tty device that TERMINAL uses. 2164 doc: /* Return the type of the tty device that TERMINAL uses.
2216Returns nil if TERMINAL is not on a tty device. 2165Returns nil if TERMINAL is not on a tty device.
@@ -2219,15 +2168,10 @@ TERMINAL can be a terminal object, a frame, or nil (meaning the
2219selected frame's terminal). */) 2168selected frame's terminal). */)
2220 (Lisp_Object terminal) 2169 (Lisp_Object terminal)
2221{ 2170{
2222 struct terminal *t = get_terminal (terminal, 1); 2171 struct terminal *t = decode_tty_terminal (terminal);
2223
2224 if (t->type != output_termcap && t->type != output_msdos_raw)
2225 return Qnil;
2226 2172
2227 if (t->display_info.tty->type) 2173 return (t && t->display_info.tty->type
2228 return build_string (t->display_info.tty->type); 2174 ? build_string (t->display_info.tty->type) : Qnil);
2229 else
2230 return Qnil;
2231} 2175}
2232 2176
2233DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0, 2177DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0,
@@ -2238,13 +2182,9 @@ selected frame's terminal). This function always returns nil if
2238TERMINAL is not on a tty device. */) 2182TERMINAL is not on a tty device. */)
2239 (Lisp_Object terminal) 2183 (Lisp_Object terminal)
2240{ 2184{
2241 struct terminal *t = get_terminal (terminal, 1); 2185 struct terminal *t = decode_tty_terminal (terminal);
2242 2186
2243 if ((t->type != output_termcap && t->type != output_msdos_raw) 2187 return (t && !strcmp (t->display_info.tty->name, DEV_TTY) ? Qt : Qnil);
2244 || strcmp (t->display_info.tty->name, DEV_TTY) != 0)
2245 return Qnil;
2246 else
2247 return Qt;
2248} 2188}
2249 2189
2250DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 1, 0, 2190DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 1, 0,
@@ -2258,7 +2198,7 @@ selected frame's terminal). This function always returns nil if
2258TERMINAL does not refer to a text terminal. */) 2198TERMINAL does not refer to a text terminal. */)
2259 (Lisp_Object terminal) 2199 (Lisp_Object terminal)
2260{ 2200{
2261 struct terminal *t = get_terminal (terminal, 1); 2201 struct terminal *t = decode_live_terminal (terminal);
2262 2202
2263 if (t->type == output_termcap) 2203 if (t->type == output_termcap)
2264 t->display_info.tty->TS_enter_underline_mode = 0; 2204 t->display_info.tty->TS_enter_underline_mode = 0;
@@ -2273,7 +2213,7 @@ does not refer to a text terminal. Otherwise, it returns the
2273top-most frame on the text terminal. */) 2213top-most frame on the text terminal. */)
2274 (Lisp_Object terminal) 2214 (Lisp_Object terminal)
2275{ 2215{
2276 struct terminal *t = get_terminal (terminal, 1); 2216 struct terminal *t = decode_live_terminal (terminal);
2277 2217
2278 if (t->type == output_termcap) 2218 if (t->type == output_termcap)
2279 return t->display_info.tty->top_frame; 2219 return t->display_info.tty->top_frame;
@@ -2303,11 +2243,11 @@ suspended.
2303A suspended tty may be resumed by calling `resume-tty' on it. */) 2243A suspended tty may be resumed by calling `resume-tty' on it. */)
2304 (Lisp_Object tty) 2244 (Lisp_Object tty)
2305{ 2245{
2306 struct terminal *t = get_tty_terminal (tty, 1); 2246 struct terminal *t = decode_tty_terminal (tty);
2307 FILE *f; 2247 FILE *f;
2308 2248
2309 if (!t) 2249 if (!t)
2310 error ("Unknown tty device"); 2250 error ("Attempt to suspend a non-text terminal device");
2311 2251
2312 f = t->display_info.tty->input; 2252 f = t->display_info.tty->input;
2313 2253
@@ -2363,15 +2303,15 @@ TTY may be a terminal object, a frame, or nil (meaning the selected
2363frame's terminal). */) 2303frame's terminal). */)
2364 (Lisp_Object tty) 2304 (Lisp_Object tty)
2365{ 2305{
2366 struct terminal *t = get_tty_terminal (tty, 1); 2306 struct terminal *t = decode_tty_terminal (tty);
2367 int fd; 2307 int fd;
2368 2308
2369 if (!t) 2309 if (!t)
2370 error ("Unknown tty device"); 2310 error ("Attempt to resume a non-text terminal device");
2371 2311
2372 if (!t->display_info.tty->input) 2312 if (!t->display_info.tty->input)
2373 { 2313 {
2374 if (get_named_tty (t->display_info.tty->name)) 2314 if (get_named_terminal (t->display_info.tty->name))
2375 error ("Cannot resume display while another display is active on the same device"); 2315 error ("Cannot resume display while another display is active on the same device");
2376 2316
2377#ifdef MSDOS 2317#ifdef MSDOS
@@ -2537,7 +2477,7 @@ term_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
2537 (*fp)->mouse_moved = 0; 2477 (*fp)->mouse_moved = 0;
2538 2478
2539 *bar_window = Qnil; 2479 *bar_window = Qnil;
2540 *part = 0; 2480 *part = scroll_bar_above_handle;
2541 2481
2542 XSETINT (*x, last_mouse_x); 2482 XSETINT (*x, last_mouse_x);
2543 XSETINT (*y, last_mouse_y); 2483 XSETINT (*y, last_mouse_y);
@@ -3188,6 +3128,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3188 Lisp_Object selectface; 3128 Lisp_Object selectface;
3189 int first_item = 0; 3129 int first_item = 0;
3190 int col, row; 3130 int col, row;
3131 USE_SAFE_ALLOCA;
3191 3132
3192 /* Don't allow non-positive x0 and y0, lest the menu will wrap 3133 /* Don't allow non-positive x0 and y0, lest the menu will wrap
3193 around the display. */ 3134 around the display. */
@@ -3196,7 +3137,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3196 if (y0 <= 0) 3137 if (y0 <= 0)
3197 y0 = 1; 3138 y0 = 1;
3198 3139
3199 state = alloca (menu->panecount * sizeof (struct tty_menu_state)); 3140 SAFE_NALLOCA (state, 1, menu->panecount);
3200 memset (state, 0, sizeof (*state)); 3141 memset (state, 0, sizeof (*state));
3201 faces[0] 3142 faces[0]
3202 = lookup_derived_face (sf, intern ("tty-menu-disabled-face"), 3143 = lookup_derived_face (sf, intern ("tty-menu-disabled-face"),
@@ -3418,6 +3359,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
3418 discard_mouse_events (); 3359 discard_mouse_events ();
3419 if (!kbd_buffer_events_waiting ()) 3360 if (!kbd_buffer_events_waiting ())
3420 clear_input_pending (); 3361 clear_input_pending ();
3362 SAFE_FREE ();
3421 return result; 3363 return result;
3422} 3364}
3423 3365
@@ -3603,6 +3545,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
3603 item_y = y += f->top_pos; 3545 item_y = y += f->top_pos;
3604 3546
3605 /* Create all the necessary panes and their items. */ 3547 /* Create all the necessary panes and their items. */
3548 USE_SAFE_ALLOCA;
3606 maxwidth = maxlines = lines = i = 0; 3549 maxwidth = maxlines = lines = i = 0;
3607 lpane = TTYM_FAILURE; 3550 lpane = TTYM_FAILURE;
3608 while (i < menu_items_used) 3551 while (i < menu_items_used)
@@ -3671,9 +3614,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
3671 3614
3672 if (!NILP (descrip)) 3615 if (!NILP (descrip))
3673 { 3616 {
3674 /* If alloca is fast, use that to make the space, 3617 item_data = SAFE_ALLOCA (maxwidth + SBYTES (descrip) + 1);
3675 to reduce gc needs. */
3676 item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1);
3677 memcpy (item_data, SSDATA (item_name), SBYTES (item_name)); 3618 memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
3678 for (j = SCHARS (item_name); j < maxwidth; j++) 3619 for (j = SCHARS (item_name); j < maxwidth; j++)
3679 item_data[j] = ' '; 3620 item_data[j] = ' ';
@@ -3826,6 +3767,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
3826 3767
3827 tty_menu_end: 3768 tty_menu_end:
3828 3769
3770 SAFE_FREE ();
3829 unbind_to (specpdl_count, Qnil); 3771 unbind_to (specpdl_count, Qnil);
3830 return entry; 3772 return entry;
3831} 3773}
@@ -4002,7 +3944,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
4002 /* XXX Perhaps this should be made explicit by having init_tty 3944 /* XXX Perhaps this should be made explicit by having init_tty
4003 always create a new terminal and separating terminal and frame 3945 always create a new terminal and separating terminal and frame
4004 creation on Lisp level. */ 3946 creation on Lisp level. */
4005 terminal = get_named_tty (name); 3947 terminal = get_named_terminal (name);
4006 if (terminal) 3948 if (terminal)
4007 return terminal; 3949 return terminal;
4008 3950
diff --git a/src/termhooks.h b/src/termhooks.h
index 04104eb41e9..9cab853ed3d 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -28,7 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28INLINE_HEADER_BEGIN 28INLINE_HEADER_BEGIN
29 29
30enum scroll_bar_part { 30enum scroll_bar_part {
31 scroll_bar_nowhere = -1, 31 scroll_bar_nowhere,
32 scroll_bar_above_handle, 32 scroll_bar_above_handle,
33 scroll_bar_handle, 33 scroll_bar_handle,
34 scroll_bar_below_handle, 34 scroll_bar_below_handle,
@@ -255,28 +255,36 @@ enum event_kind
255struct input_event 255struct input_event
256{ 256{
257 /* What kind of event was this? */ 257 /* What kind of event was this? */
258 enum event_kind kind; 258 ENUM_BF (event_kind) kind : 16;
259
260 /* Used in scroll back click events. */
261 ENUM_BF (scroll_bar_part) part : 16;
259 262
260 /* For an ASCII_KEYSTROKE_EVENT and MULTIBYTE_CHAR_KEYSTROKE_EVENT, 263 /* For an ASCII_KEYSTROKE_EVENT and MULTIBYTE_CHAR_KEYSTROKE_EVENT,
261 this is the character. 264 this is the character.
262 For a NON_ASCII_KEYSTROKE_EVENT, this is the keysym code. 265 For a NON_ASCII_KEYSTROKE_EVENT, this is the keysym code.
263 For a mouse event, this is the button number. 266 For a mouse event, this is the button number. */
264 For a HELP_EVENT, this is the position within the object 267 unsigned code;
265 (stored in ARG below) where the help was found. */
266 ptrdiff_t code;
267 enum scroll_bar_part part;
268 268
269 int modifiers; /* See enum below for interpretation. */ 269 /* See enum below for interpretation. */
270 unsigned modifiers;
270 271
272 /* One would prefer C integers, but HELP_EVENT uses these to
273 record frame or window object and a help form, respectively. */
271 Lisp_Object x, y; 274 Lisp_Object x, y;
275
276 /* Usually a time as reported by window system-specific event loop.
277 For a HELP_EVENT, this is the position within the object (stored
278 in ARG below) where the help was found. */
272 Time timestamp; 279 Time timestamp;
273 280
274 /* This field is copied into a vector while the event is in 281 /* This field is copied into a vector while the event is in
275 the queue, so that garbage collections won't kill it. */ 282 the queue, so that garbage collections won't kill it. */
276 Lisp_Object frame_or_window; 283 Lisp_Object frame_or_window;
277 284
278 /* Additional event argument. This is used for TOOL_BAR_EVENTs and 285 /* This additional argument is used in attempt to avoid extra consing
279 HELP_EVENTs and avoids calling Fcons during signal handling. */ 286 when building events. Unfortunately some events have to pass much
287 more data than it's reasonable to pack directly into this structure. */
280 Lisp_Object arg; 288 Lisp_Object arg;
281}; 289};
282 290
@@ -673,7 +681,9 @@ extern struct terminal *terminal_list;
673 (t->type == output_ns ? t->display_info.ns->name_list_element : Qnil) 681 (t->type == output_ns ? t->display_info.ns->name_list_element : Qnil)
674#endif 682#endif
675 683
676extern struct terminal *get_terminal (Lisp_Object terminal, bool); 684extern struct terminal *decode_live_terminal (Lisp_Object);
685extern struct terminal *decode_tty_terminal (Lisp_Object);
686extern struct terminal *get_named_terminal (const char *);
677extern struct terminal *create_terminal (enum output_method, 687extern struct terminal *create_terminal (enum output_method,
678 struct redisplay_interface *); 688 struct redisplay_interface *);
679extern void delete_terminal (struct terminal *); 689extern void delete_terminal (struct terminal *);
diff --git a/src/terminal.c b/src/terminal.c
index a827677a58d..0cd6a0bf602 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -37,7 +37,9 @@ static int next_terminal_id;
37/* The initial terminal device, created by initial_term_init. */ 37/* The initial terminal device, created by initial_term_init. */
38struct terminal *initial_terminal; 38struct terminal *initial_terminal;
39 39
40Lisp_Object Qrun_hook_with_args;
40static Lisp_Object Qterminal_live_p; 41static Lisp_Object Qterminal_live_p;
42static Lisp_Object Qdelete_terminal_functions;
41 43
42static void delete_initial_terminal (struct terminal *); 44static void delete_initial_terminal (struct terminal *);
43 45
@@ -194,34 +196,66 @@ ins_del_lines (struct frame *f, int vpos, int n)
194 (*FRAME_TERMINAL (f)->ins_del_lines_hook) (f, vpos, n); 196 (*FRAME_TERMINAL (f)->ins_del_lines_hook) (f, vpos, n);
195} 197}
196 198
199/* Return the terminal object specified by TERMINAL. TERMINAL may
200 be a terminal object, a frame, or nil for the terminal device of
201 the current frame. If TERMINAL is neither from the above or the
202 resulting terminal object is deleted, return NULL. */
197 203
198 204static struct terminal *
199 205decode_terminal (Lisp_Object terminal)
200/* Return the terminal object specified by TERMINAL. TERMINAL may be
201 a terminal object, a frame, or nil for the terminal device of the
202 current frame. If THROW is false, return NULL for failure,
203 otherwise throw an error. */
204
205struct terminal *
206get_terminal (Lisp_Object terminal, bool throw)
207{ 206{
208 struct terminal *result = NULL; 207 struct terminal *t;
209 208
210 if (NILP (terminal)) 209 if (NILP (terminal))
211 terminal = selected_frame; 210 terminal = selected_frame;
211 t = (TERMINALP (terminal)
212 ? XTERMINAL (terminal)
213 : FRAMEP (terminal) ? FRAME_TERMINAL (XFRAME (terminal)) : NULL);
214 return t && t->name ? t : NULL;
215}
212 216
213 if (TERMINALP (terminal)) 217/* Like above, but throw an error if TERMINAL is not valid or deleted. */
214 result = XTERMINAL (terminal);
215 else if (FRAMEP (terminal))
216 result = FRAME_TERMINAL (XFRAME (terminal));
217 218
218 if (result && !result->name) 219struct terminal *
219 result = NULL; 220decode_live_terminal (Lisp_Object terminal)
221{
222 struct terminal *t = decode_terminal (terminal);
220 223
221 if (result == NULL && throw) 224 if (!t)
222 wrong_type_argument (Qterminal_live_p, terminal); 225 wrong_type_argument (Qterminal_live_p, terminal);
226 return t;
227}
228
229/* Like decode_terminal, but ensure that the resulting terminal object refers
230 to a text-based terminal device. */
231
232struct terminal *
233decode_tty_terminal (Lisp_Object terminal)
234{
235 struct terminal *t = decode_live_terminal (terminal);
223 236
224 return result; 237 return (t->type == output_termcap || t->type == output_msdos_raw) ? t : NULL;
238}
239
240/* Return an active (not suspended) text-based terminal device that uses
241 the tty device with the given NAME, or NULL if the named terminal device
242 is not opened. */
243
244struct terminal *
245get_named_terminal (const char *name)
246{
247 struct terminal *t;
248
249 eassert (name);
250
251 for (t = terminal_list; t; t = t->next_terminal)
252 {
253 if ((t->type == output_termcap || t->type == output_msdos_raw)
254 && !strcmp (t->display_info.tty->name, name)
255 && TERMINAL_ACTIVE_P (t))
256 return t;
257 }
258 return NULL;
225} 259}
226 260
227/* Create a new terminal object of TYPE and add it to the terminal list. RIF 261/* Create a new terminal object of TYPE and add it to the terminal list. RIF
@@ -308,8 +342,6 @@ delete_terminal (struct terminal *terminal)
308 } 342 }
309} 343}
310 344
311Lisp_Object Qrun_hook_with_args;
312static Lisp_Object Qdelete_terminal_functions;
313DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0, 345DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
314 doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal. 346 doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal.
315TERMINAL may be a terminal object, a frame, or nil (meaning the 347TERMINAL may be a terminal object, a frame, or nil (meaning the
@@ -319,7 +351,7 @@ Normally, you may not delete a display if all other displays are suspended,
319but if the second argument FORCE is non-nil, you may do so. */) 351but if the second argument FORCE is non-nil, you may do so. */)
320 (Lisp_Object terminal, Lisp_Object force) 352 (Lisp_Object terminal, Lisp_Object force)
321{ 353{
322 struct terminal *t = get_terminal (terminal, 0); 354 struct terminal *t = decode_terminal (terminal);
323 355
324 if (!t) 356 if (!t)
325 return Qnil; 357 return Qnil;
@@ -380,9 +412,7 @@ sort of output terminal it uses. See the documentation of `framep' for
380possible return values. */) 412possible return values. */)
381 (Lisp_Object object) 413 (Lisp_Object object)
382{ 414{
383 struct terminal *t; 415 struct terminal *t = decode_terminal (object);
384
385 t = get_terminal (object, 0);
386 416
387 if (!t) 417 if (!t)
388 return Qnil; 418 return Qnil;
@@ -429,8 +459,7 @@ TERMINAL may be a terminal object, a frame, or nil (meaning the
429selected frame's terminal). */) 459selected frame's terminal). */)
430 (Lisp_Object terminal) 460 (Lisp_Object terminal)
431{ 461{
432 struct terminal *t 462 struct terminal *t = decode_live_terminal (terminal);
433 = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
434 463
435 return t->name ? build_string (t->name) : Qnil; 464 return t->name ? build_string (t->name) : Qnil;
436} 465}
@@ -467,9 +496,7 @@ TERMINAL can be a terminal object, a frame, or nil (meaning the
467selected frame's terminal). */) 496selected frame's terminal). */)
468 (Lisp_Object terminal) 497 (Lisp_Object terminal)
469{ 498{
470 struct terminal *t 499 return Fcopy_alist (decode_live_terminal (terminal)->param_alist);
471 = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
472 return Fcopy_alist (t->param_alist);
473} 500}
474 501
475DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0, 502DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0,
@@ -478,12 +505,8 @@ TERMINAL can be a terminal object, a frame, or nil (meaning the
478selected frame's terminal). */) 505selected frame's terminal). */)
479 (Lisp_Object terminal, Lisp_Object parameter) 506 (Lisp_Object terminal, Lisp_Object parameter)
480{ 507{
481 Lisp_Object value;
482 struct terminal *t
483 = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
484 CHECK_SYMBOL (parameter); 508 CHECK_SYMBOL (parameter);
485 value = Fcdr (Fassq (parameter, t->param_alist)); 509 return Fcdr (Fassq (parameter, decode_live_terminal (terminal)->param_alist));
486 return value;
487} 510}
488 511
489DEFUN ("set-terminal-parameter", Fset_terminal_parameter, 512DEFUN ("set-terminal-parameter", Fset_terminal_parameter,
@@ -495,9 +518,7 @@ TERMINAL can be a terminal object, a frame or nil (meaning the
495selected frame's terminal). */) 518selected frame's terminal). */)
496 (Lisp_Object terminal, Lisp_Object parameter, Lisp_Object value) 519 (Lisp_Object terminal, Lisp_Object parameter, Lisp_Object value)
497{ 520{
498 struct terminal *t 521 return store_terminal_param (decode_live_terminal (terminal), parameter, value);
499 = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
500 return store_terminal_param (t, parameter, value);
501} 522}
502 523
503/* Initial frame has no device-dependent output data, but has 524/* Initial frame has no device-dependent output data, but has
diff --git a/src/textprop.c b/src/textprop.c
index bd09304ba3b..91ade8ae298 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -660,6 +660,7 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop,
660 660
661 set_buffer_temp (XBUFFER (object)); 661 set_buffer_temp (XBUFFER (object));
662 662
663 USE_SAFE_ALLOCA;
663 GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, 0); 664 GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, 0);
664 noverlays = sort_overlays (overlay_vec, noverlays, w); 665 noverlays = sort_overlays (overlay_vec, noverlays, w);
665 666
@@ -674,9 +675,11 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop,
674 if (overlay) 675 if (overlay)
675 /* Return the overlay we got the property from. */ 676 /* Return the overlay we got the property from. */
676 *overlay = overlay_vec[noverlays]; 677 *overlay = overlay_vec[noverlays];
678 SAFE_FREE ();
677 return tem; 679 return tem;
678 } 680 }
679 } 681 }
682 SAFE_FREE ();
680 } 683 }
681 684
682 if (overlay) 685 if (overlay)
@@ -1314,9 +1317,11 @@ specify the property to add.
1314If the optional fifth argument OBJECT is a buffer (or nil, which means 1317If the optional fifth argument OBJECT is a buffer (or nil, which means
1315the current buffer), START and END are buffer positions (integers or 1318the current buffer), START and END are buffer positions (integers or
1316markers). If OBJECT is a string, START and END are 0-based indices into it. */) 1319markers). If OBJECT is a string, START and END are 0-based indices into it. */)
1317 (Lisp_Object start, Lisp_Object end, Lisp_Object property, Lisp_Object value, Lisp_Object object) 1320 (Lisp_Object start, Lisp_Object end, Lisp_Object property,
1321 Lisp_Object value, Lisp_Object object)
1318{ 1322{
1319 Fadd_text_properties (start, end, list2 (property, value), object); 1323 AUTO_LIST2 (properties, property, value);
1324 Fadd_text_properties (start, end, properties, object);
1320 return Qnil; 1325 return Qnil;
1321} 1326}
1322 1327
@@ -1357,7 +1362,8 @@ into it. */)
1357 (Lisp_Object start, Lisp_Object end, Lisp_Object face, 1362 (Lisp_Object start, Lisp_Object end, Lisp_Object face,
1358 Lisp_Object append, Lisp_Object object) 1363 Lisp_Object append, Lisp_Object object)
1359{ 1364{
1360 add_text_properties_1 (start, end, list2 (Qface, face), object, 1365 AUTO_LIST2 (properties, Qface, face);
1366 add_text_properties_1 (start, end, properties, object,
1361 (NILP (append) 1367 (NILP (append)
1362 ? TEXT_PROPERTY_PREPEND 1368 ? TEXT_PROPERTY_PREPEND
1363 : TEXT_PROPERTY_APPEND)); 1369 : TEXT_PROPERTY_APPEND));
@@ -1906,7 +1912,8 @@ text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer)
1906/* Note this can GC when DEST is a buffer. */ 1912/* Note this can GC when DEST is a buffer. */
1907 1913
1908Lisp_Object 1914Lisp_Object
1909copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, Lisp_Object pos, Lisp_Object dest, Lisp_Object prop) 1915copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src,
1916 Lisp_Object pos, Lisp_Object dest, Lisp_Object prop)
1910{ 1917{
1911 INTERVAL i; 1918 INTERVAL i;
1912 Lisp_Object res; 1919 Lisp_Object res;
@@ -1959,12 +1966,10 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, Lisp_
1959 plist = Fcdr (Fcdr (plist)); 1966 plist = Fcdr (Fcdr (plist));
1960 } 1967 }
1961 if (! NILP (plist)) 1968 if (! NILP (plist))
1962 { 1969 /* Must defer modifications to the interval tree in case
1963 /* Must defer modifications to the interval tree in case src 1970 src and dest refer to the same string or buffer. */
1964 and dest refer to the same string or buffer. */ 1971 stuff = Fcons (list3 (make_number (p), make_number (p + len), plist),
1965 stuff = Fcons (list3 (make_number (p), make_number (p + len), plist), 1972 stuff);
1966 stuff);
1967 }
1968 1973
1969 i = next_interval (i); 1974 i = next_interval (i);
1970 if (!i) 1975 if (!i)
diff --git a/src/unexcw.c b/src/unexcw.c
index 7636b05a12e..cdeb899fd30 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -34,12 +34,6 @@ extern void report_sheap_usage (int);
34 34
35extern int bss_sbrk_did_unexec; 35extern int bss_sbrk_did_unexec;
36 36
37extern int __malloc_initialized;
38
39/* emacs symbols that indicate where bss and data end for emacs internals */
40extern char my_endbss[];
41extern char my_edata[];
42
43/* 37/*
44** header for Windows executable files 38** header for Windows executable files
45*/ 39*/
@@ -233,12 +227,9 @@ fixup_executable (int fd)
233 lseek (fd, (long) (exe_header->section_header[i].s_scnptr), 227 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
234 SEEK_SET); 228 SEEK_SET);
235 assert (ret != -1); 229 assert (ret != -1);
236 /* force the dumped emacs to reinitialize malloc */
237 __malloc_initialized = 0;
238 ret = 230 ret =
239 write (fd, (char *) start_address, 231 write (fd, (char *) start_address,
240 my_endbss - (char *) start_address); 232 my_endbss - (char *) start_address);
241 __malloc_initialized = 1;
242 assert (ret == (my_endbss - (char *) start_address)); 233 assert (ret == (my_endbss - (char *) start_address));
243 if (debug_unexcw) 234 if (debug_unexcw)
244 printf (" .bss, mem start %#lx mem length %d\n", 235 printf (" .bss, mem start %#lx mem length %d\n",
diff --git a/src/unexhp9k800.c b/src/unexhp9k800.c
index 55db8071b76..cbf1835b9ee 100644
--- a/src/unexhp9k800.c
+++ b/src/unexhp9k800.c
@@ -72,7 +72,6 @@ run_time_remap (char *ignored)
72 72
73#undef roundup 73#undef roundup
74#define roundup(x,n) (((x) + ((n) - 1)) & ~((n) - 1)) /* n is power of 2 */ 74#define roundup(x,n) (((x) + ((n) - 1)) & ~((n) - 1)) /* n is power of 2 */
75#define min(x,y) (((x) < (y)) ? (x) : (y))
76 75
77/* Report a fatal error and exit. */ 76/* Report a fatal error and exit. */
78static _Noreturn void 77static _Noreturn void
diff --git a/src/unexmacosx.c b/src/unexmacosx.c
index 8cd80a7a544..2e1ac880d2a 100644
--- a/src/unexmacosx.c
+++ b/src/unexmacosx.c
@@ -107,9 +107,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
107#include <mach/mach.h> 107#include <mach/mach.h>
108#include <mach-o/loader.h> 108#include <mach-o/loader.h>
109#include <mach-o/reloc.h> 109#include <mach-o/reloc.h>
110#if defined (__ppc__)
111#include <mach-o/ppc/reloc.h>
112#endif
113#ifdef HAVE_MALLOC_MALLOC_H 110#ifdef HAVE_MALLOC_MALLOC_H
114#include <malloc/malloc.h> 111#include <malloc/malloc.h>
115#else 112#else
@@ -826,7 +823,6 @@ copy_data_segment (struct load_command *lc)
826 file. */ 823 file. */
827 if (strncmp (sectp->sectname, SECT_DATA, 16) == 0) 824 if (strncmp (sectp->sectname, SECT_DATA, 16) == 0)
828 { 825 {
829 extern char my_edata[];
830 unsigned long my_size; 826 unsigned long my_size;
831 827
832 /* The __data section is basically dumped from memory. But 828 /* The __data section is basically dumped from memory. But
@@ -857,7 +853,6 @@ copy_data_segment (struct load_command *lc)
857 } 853 }
858 else if (strncmp (sectp->sectname, SECT_BSS, 16) == 0) 854 else if (strncmp (sectp->sectname, SECT_BSS, 16) == 0)
859 { 855 {
860 extern char *my_endbss_static;
861 unsigned long my_size; 856 unsigned long my_size;
862 857
863 sectp->flags = S_REGULAR; 858 sectp->flags = S_REGULAR;
@@ -881,6 +876,27 @@ copy_data_segment (struct load_command *lc)
881 if (!unexec_write (header_offset, sectp, sizeof (struct section))) 876 if (!unexec_write (header_offset, sectp, sizeof (struct section)))
882 unexec_error ("cannot write section %.16s's header", sectp->sectname); 877 unexec_error ("cannot write section %.16s's header", sectp->sectname);
883 } 878 }
879 else if (strncmp (sectp->sectname, "__bss", 5) == 0
880 || strncmp (sectp->sectname, "__pu_bss", 8) == 0)
881 {
882 sectp->flags = S_REGULAR;
883
884 /* These sections are produced by GCC 4.6+.
885
886 FIXME: We possibly ought to clear uninitialized local
887 variables in statically linked libraries like for
888 SECT_BSS (__bss) above, but setting up the markers we
889 need in lastfile.c would be rather messy. See
890 darwin_output_aligned_bss () in gcc/config/darwin.c for
891 the root of the problem, keeping in mind that the
892 sections are numbered by their alignment in GCC 4.6, but
893 by log2(alignment) in GCC 4.7. */
894
895 if (!unexec_write (sectp->offset, (void *) sectp->addr, sectp->size))
896 unexec_error ("cannot copy section %.16s", sectp->sectname);
897 if (!unexec_write (header_offset, sectp, sizeof (struct section)))
898 unexec_error ("cannot write section %.16s's header", sectp->sectname);
899 }
884 else if (strncmp (sectp->sectname, "__la_symbol_ptr", 16) == 0 900 else if (strncmp (sectp->sectname, "__la_symbol_ptr", 16) == 0
885 || strncmp (sectp->sectname, "__nl_symbol_ptr", 16) == 0 901 || strncmp (sectp->sectname, "__nl_symbol_ptr", 16) == 0
886 || strncmp (sectp->sectname, "__got", 16) == 0 902 || strncmp (sectp->sectname, "__got", 16) == 0
@@ -892,6 +908,7 @@ copy_data_segment (struct load_command *lc)
892 || strncmp (sectp->sectname, "__program_vars", 16) == 0 908 || strncmp (sectp->sectname, "__program_vars", 16) == 0
893 || strncmp (sectp->sectname, "__mod_init_func", 16) == 0 909 || strncmp (sectp->sectname, "__mod_init_func", 16) == 0
894 || strncmp (sectp->sectname, "__mod_term_func", 16) == 0 910 || strncmp (sectp->sectname, "__mod_term_func", 16) == 0
911 || strncmp (sectp->sectname, "__static_data", 16) == 0
895 || strncmp (sectp->sectname, "__objc_", 7) == 0) 912 || strncmp (sectp->sectname, "__objc_", 7) == 0)
896 { 913 {
897 if (!unexec_copy (sectp->offset, old_file_offset, sectp->size)) 914 if (!unexec_copy (sectp->offset, old_file_offset, sectp->size))
@@ -1013,17 +1030,8 @@ unrelocate (const char *name, off_t reloff, int nrel, vm_address_t base)
1013 name, i, reloc_info.r_type); 1030 name, i, reloc_info.r_type);
1014 } 1031 }
1015 else 1032 else
1016 switch (sc_reloc_info->r_type) 1033 unexec_error ("unrelocate: %s:%d cannot handle scattered type = %d",
1017 { 1034 name, i, sc_reloc_info->r_type);
1018#if defined (__ppc__)
1019 case PPC_RELOC_PB_LA_PTR:
1020 /* nothing to do for prebound lazy pointer */
1021 break;
1022#endif
1023 default:
1024 unexec_error ("unrelocate: %s:%d cannot handle scattered type = %d",
1025 name, i, sc_reloc_info->r_type);
1026 }
1027 } 1035 }
1028 1036
1029 if (nrel > 0) 1037 if (nrel > 0)
@@ -1031,35 +1039,6 @@ unrelocate (const char *name, off_t reloff, int nrel, vm_address_t base)
1031 unreloc_count, nrel, name); 1039 unreloc_count, nrel, name);
1032} 1040}
1033 1041
1034#if __ppc64__
1035/* Rebase r_address in the relocation table. */
1036static void
1037rebase_reloc_address (off_t reloff, int nrel, long linkedit_delta, long diff)
1038{
1039 int i;
1040 struct relocation_info reloc_info;
1041 struct scattered_relocation_info *sc_reloc_info
1042 = (struct scattered_relocation_info *) &reloc_info;
1043
1044 for (i = 0; i < nrel; i++, reloff += sizeof (reloc_info))
1045 {
1046 if (lseek (infd, reloff - linkedit_delta, L_SET)
1047 != reloff - linkedit_delta)
1048 unexec_error ("rebase_reloc_table: cannot seek to reloc_info");
1049 if (!unexec_read (&reloc_info, sizeof (reloc_info)))
1050 unexec_error ("rebase_reloc_table: cannot read reloc_info");
1051
1052 if (sc_reloc_info->r_scattered == 0
1053 && reloc_info.r_type == GENERIC_RELOC_VANILLA)
1054 {
1055 reloc_info.r_address -= diff;
1056 if (!unexec_write (reloff, &reloc_info, sizeof (reloc_info)))
1057 unexec_error ("rebase_reloc_table: cannot write reloc_info");
1058 }
1059 }
1060}
1061#endif
1062
1063/* Copy a LC_DYSYMTAB load command from the input file to the output 1042/* Copy a LC_DYSYMTAB load command from the input file to the output
1064 file, adjusting the file offset fields. */ 1043 file, adjusting the file offset fields. */
1065static void 1044static void
@@ -1069,28 +1048,8 @@ copy_dysymtab (struct load_command *lc, long delta)
1069 vm_address_t base; 1048 vm_address_t base;
1070 1049
1071#ifdef _LP64 1050#ifdef _LP64
1072#if __ppc64__
1073 {
1074 int i;
1075
1076 base = 0;
1077 for (i = 0; i < nlc; i++)
1078 if (lca[i]->cmd == LC_SEGMENT)
1079 {
1080 struct segment_command *scp = (struct segment_command *) lca[i];
1081
1082 if (scp->vmaddr + scp->vmsize > 0x100000000
1083 && (scp->initprot & VM_PROT_WRITE) != 0)
1084 {
1085 base = data_segment_scp->vmaddr;
1086 break;
1087 }
1088 }
1089 }
1090#else
1091 /* First writable segment address. */ 1051 /* First writable segment address. */
1092 base = data_segment_scp->vmaddr; 1052 base = data_segment_scp->vmaddr;
1093#endif
1094#else 1053#else
1095 /* First segment address in the file (unless MH_SPLIT_SEGS set). */ 1054 /* First segment address in the file (unless MH_SPLIT_SEGS set). */
1096 base = 0; 1055 base = 0;
@@ -1116,29 +1075,6 @@ copy_dysymtab (struct load_command *lc, long delta)
1116 unexec_error ("cannot write symtab command to header"); 1075 unexec_error ("cannot write symtab command to header");
1117 1076
1118 curr_header_offset += lc->cmdsize; 1077 curr_header_offset += lc->cmdsize;
1119
1120#if __ppc64__
1121 /* Check if the relocation base needs to be changed. */
1122 if (base == 0)
1123 {
1124 vm_address_t newbase = 0;
1125 int i;
1126
1127 for (i = 0; i < num_unexec_regions; i++)
1128 if (unexec_regions[i].range.address + unexec_regions[i].range.size
1129 > 0x100000000)
1130 {
1131 newbase = data_segment_scp->vmaddr;
1132 break;
1133 }
1134
1135 if (newbase)
1136 {
1137 rebase_reloc_address (dstp->locreloff, dstp->nlocrel, delta, newbase);
1138 rebase_reloc_address (dstp->extreloff, dstp->nextrel, delta, newbase);
1139 }
1140 }
1141#endif
1142} 1078}
1143 1079
1144/* Copy a LC_TWOLEVEL_HINTS load command from the input file to the output 1080/* Copy a LC_TWOLEVEL_HINTS load command from the input file to the output
@@ -1302,7 +1238,9 @@ dump_it (void)
1302 } 1238 }
1303 1239
1304 if (curr_header_offset > text_seg_lowest_offset) 1240 if (curr_header_offset > text_seg_lowest_offset)
1305 unexec_error ("not enough room for load commands for new __DATA segments"); 1241 unexec_error ("not enough room for load commands for new __DATA segments"
1242 " (increase headerpad_extra in configure.in to at least %lX)",
1243 num_unexec_regions * sizeof (struct segment_command));
1306 1244
1307 printf ("%ld unused bytes follow Mach-O header\n", 1245 printf ("%ld unused bytes follow Mach-O header\n",
1308 text_seg_lowest_offset - curr_header_offset); 1246 text_seg_lowest_offset - curr_header_offset);
diff --git a/src/unexw32.c b/src/unexw32.c
index 7cbd95a46fe..5c1c1f3f391 100644
--- a/src/unexw32.c
+++ b/src/unexw32.c
@@ -43,19 +43,11 @@ PIMAGE_NT_HEADERS
43extern BOOL ctrl_c_handler (unsigned long type); 43extern BOOL ctrl_c_handler (unsigned long type);
44 44
45extern char my_begdata[]; 45extern char my_begdata[];
46extern char my_edata[];
47extern char my_begbss[]; 46extern char my_begbss[];
48extern char my_endbss[];
49extern char *my_begbss_static; 47extern char *my_begbss_static;
50extern char *my_endbss_static;
51 48
52#include "w32heap.h" 49#include "w32heap.h"
53 50
54#undef min
55#undef max
56#define min(x, y) (((x) < (y)) ? (x) : (y))
57#define max(x, y) (((x) > (y)) ? (x) : (y))
58
59/* Basically, our "initialized" flag. */ 51/* Basically, our "initialized" flag. */
60BOOL using_dynamic_heap = FALSE; 52BOOL using_dynamic_heap = FALSE;
61 53
diff --git a/src/vm-limit.c b/src/vm-limit.c
index 308613f7eb4..015f3ee2111 100644
--- a/src/vm-limit.c
+++ b/src/vm-limit.c
@@ -51,6 +51,15 @@ char data_start[1] = { 1 };
51# endif 51# endif
52#endif 52#endif
53 53
54/* From gmalloc.c. */
55extern void (* __after_morecore_hook) (void);
56extern void *(*__morecore) (ptrdiff_t);
57
58/* From ralloc.c. */
59#ifdef REL_ALLOC
60extern void *(*real_morecore) (ptrdiff_t);
61#endif
62
54/* 63/*
55 Level number of warnings already issued. 64 Level number of warnings already issued.
56 0 -- no warnings issued. 65 0 -- no warnings issued.
@@ -130,12 +139,9 @@ ret_lim_data (void)
130static void 139static void
131check_memory_limits (void) 140check_memory_limits (void)
132{ 141{
133#ifdef REL_ALLOC 142#ifndef REL_ALLOC
134 extern void *(*real_morecore) (ptrdiff_t);
135#else
136 void *(*real_morecore) (ptrdiff_t) = 0; 143 void *(*real_morecore) (ptrdiff_t) = 0;
137#endif 144#endif
138 extern void *(*__morecore) (ptrdiff_t);
139 145
140 char *cp; 146 char *cp;
141 size_t five_percent; 147 size_t five_percent;
@@ -203,8 +209,6 @@ check_memory_limits (void)
203void 209void
204memory_warnings (void *start, void (*warnfun) (const char *)) 210memory_warnings (void *start, void (*warnfun) (const char *))
205{ 211{
206 extern void (* __after_morecore_hook) (void); /* From gmalloc.c */
207
208 data_space_start = start ? start : data_start; 212 data_space_start = start ? start : data_start;
209 213
210 warn_function = warnfun; 214 warn_function = warnfun;
diff --git a/src/w32.c b/src/w32.c
index 7cb9d8960c5..f014cd73a76 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -309,6 +309,8 @@ static BOOL g_b_init_set_named_security_info_w;
309static BOOL g_b_init_set_named_security_info_a; 309static BOOL g_b_init_set_named_security_info_a;
310static BOOL g_b_init_get_adapters_info; 310static BOOL g_b_init_get_adapters_info;
311 311
312BOOL g_b_init_compare_string_w;
313
312/* 314/*
313 BEGIN: Wrapper functions around OpenProcessToken 315 BEGIN: Wrapper functions around OpenProcessToken
314 and other functions in advapi32.dll that are only 316 and other functions in advapi32.dll that are only
@@ -2292,7 +2294,7 @@ get_long_basename (char * name, char * buf, int size)
2292 2294
2293/* Get long name for file, if possible (assumed to be absolute). */ 2295/* Get long name for file, if possible (assumed to be absolute). */
2294BOOL 2296BOOL
2295w32_get_long_filename (char * name, char * buf, int size) 2297w32_get_long_filename (const char * name, char * buf, int size)
2296{ 2298{
2297 char * o = buf; 2299 char * o = buf;
2298 char * p; 2300 char * p;
@@ -2343,7 +2345,7 @@ w32_get_long_filename (char * name, char * buf, int size)
2343} 2345}
2344 2346
2345unsigned int 2347unsigned int
2346w32_get_short_filename (char * name, char * buf, int size) 2348w32_get_short_filename (const char * name, char * buf, int size)
2347{ 2349{
2348 if (w32_unicode_filenames) 2350 if (w32_unicode_filenames)
2349 { 2351 {
@@ -2389,6 +2391,8 @@ ansi_encode_filename (Lisp_Object filename)
2389 dostounix_filename (shortname); 2391 dostounix_filename (shortname);
2390 encoded_filename = build_string (shortname); 2392 encoded_filename = build_string (shortname);
2391 } 2393 }
2394 else
2395 encoded_filename = build_unibyte_string (fname);
2392 } 2396 }
2393 else 2397 else
2394 encoded_filename = build_unibyte_string (fname); 2398 encoded_filename = build_unibyte_string (fname);
@@ -7718,15 +7722,15 @@ fcntl (int s, int cmd, int options)
7718 if (cmd == F_DUPFD_CLOEXEC) 7722 if (cmd == F_DUPFD_CLOEXEC)
7719 return sys_dup (s); 7723 return sys_dup (s);
7720 7724
7721 if (winsock_lib == NULL)
7722 {
7723 errno = ENETDOWN;
7724 return -1;
7725 }
7726
7727 check_errno (); 7725 check_errno ();
7728 if (fd_info[s].flags & FILE_SOCKET) 7726 if (fd_info[s].flags & FILE_SOCKET)
7729 { 7727 {
7728 if (winsock_lib == NULL)
7729 {
7730 errno = ENETDOWN;
7731 return -1;
7732 }
7733
7730 if (cmd == F_SETFL && options == O_NONBLOCK) 7734 if (cmd == F_SETFL && options == O_NONBLOCK)
7731 { 7735 {
7732 unsigned long nblock = 1; 7736 unsigned long nblock = 1;
@@ -7743,13 +7747,36 @@ fcntl (int s, int cmd, int options)
7743 return SOCKET_ERROR; 7747 return SOCKET_ERROR;
7744 } 7748 }
7745 } 7749 }
7750 else if ((fd_info[s].flags & (FILE_PIPE | FILE_WRITE))
7751 == (FILE_PIPE | FILE_WRITE))
7752 {
7753 /* Force our writes to pipes be non-blocking. */
7754 if (cmd == F_SETFL && options == O_NONBLOCK)
7755 {
7756 HANDLE h = (HANDLE)_get_osfhandle (s);
7757 DWORD pipe_mode = PIPE_NOWAIT;
7758
7759 if (!SetNamedPipeHandleState (h, &pipe_mode, NULL, NULL))
7760 {
7761 DebPrint (("SetNamedPipeHandleState: %lu\n", GetLastError ()));
7762 return SOCKET_ERROR;
7763 }
7764 fd_info[s].flags |= FILE_NDELAY;
7765 return 0;
7766 }
7767 else
7768 {
7769 errno = EINVAL;
7770 return SOCKET_ERROR;
7771 }
7772 }
7746 errno = ENOTSOCK; 7773 errno = ENOTSOCK;
7747 return SOCKET_ERROR; 7774 return SOCKET_ERROR;
7748} 7775}
7749 7776
7750 7777
7751/* Shadow main io functions: we need to handle pipes and sockets more 7778/* Shadow main io functions: we need to handle pipes and sockets more
7752 intelligently, and implement non-blocking mode as well. */ 7779 intelligently. */
7753 7780
7754int 7781int
7755sys_close (int fd) 7782sys_close (int fd)
@@ -8234,11 +8261,11 @@ sys_read (int fd, char * buffer, unsigned int count)
8234/* From w32xfns.c */ 8261/* From w32xfns.c */
8235extern HANDLE interrupt_handle; 8262extern HANDLE interrupt_handle;
8236 8263
8237/* For now, don't bother with a non-blocking mode */
8238int 8264int
8239sys_write (int fd, const void * buffer, unsigned int count) 8265sys_write (int fd, const void * buffer, unsigned int count)
8240{ 8266{
8241 int nchars; 8267 int nchars;
8268 USE_SAFE_ALLOCA;
8242 8269
8243 if (fd < 0) 8270 if (fd < 0)
8244 { 8271 {
@@ -8257,30 +8284,33 @@ sys_write (int fd, const void * buffer, unsigned int count)
8257 /* Perform text mode translation if required. */ 8284 /* Perform text mode translation if required. */
8258 if ((fd_info[fd].flags & FILE_BINARY) == 0) 8285 if ((fd_info[fd].flags & FILE_BINARY) == 0)
8259 { 8286 {
8260 char * tmpbuf = alloca (count * 2); 8287 char * tmpbuf;
8261 unsigned char * src = (void *)buffer; 8288 const unsigned char * src = buffer;
8262 unsigned char * dst = tmpbuf; 8289 unsigned char * dst;
8263 int nbytes = count; 8290 int nbytes = count;
8264 8291
8292 SAFE_NALLOCA (tmpbuf, 2, count);
8293 dst = tmpbuf;
8294
8265 while (1) 8295 while (1)
8266 { 8296 {
8267 unsigned char *next; 8297 unsigned char *next;
8268 /* copy next line or remaining bytes */ 8298 /* Copy next line or remaining bytes. */
8269 next = _memccpy (dst, src, '\n', nbytes); 8299 next = _memccpy (dst, src, '\n', nbytes);
8270 if (next) 8300 if (next)
8271 { 8301 {
8272 /* copied one line ending with '\n' */ 8302 /* Copied one line ending with '\n'. */
8273 int copied = next - dst; 8303 int copied = next - dst;
8274 nbytes -= copied; 8304 nbytes -= copied;
8275 src += copied; 8305 src += copied;
8276 /* insert '\r' before '\n' */ 8306 /* Insert '\r' before '\n'. */
8277 next[-1] = '\r'; 8307 next[-1] = '\r';
8278 next[0] = '\n'; 8308 next[0] = '\n';
8279 dst = next + 1; 8309 dst = next + 1;
8280 count++; 8310 count++;
8281 } 8311 }
8282 else 8312 else
8283 /* copied remaining partial line -> now finished */ 8313 /* Copied remaining partial line -> now finished. */
8284 break; 8314 break;
8285 } 8315 }
8286 buffer = tmpbuf; 8316 buffer = tmpbuf;
@@ -8294,31 +8324,44 @@ sys_write (int fd, const void * buffer, unsigned int count)
8294 HANDLE wait_hnd[2] = { interrupt_handle, ovl->hEvent }; 8324 HANDLE wait_hnd[2] = { interrupt_handle, ovl->hEvent };
8295 DWORD active = 0; 8325 DWORD active = 0;
8296 8326
8327 /* This is async (a.k.a. "overlapped") I/O, so the return value
8328 of FALSE from WriteFile means either an error or the output
8329 will be completed asynchronously (ERROR_IO_PENDING). */
8297 if (!WriteFile (hnd, buffer, count, (DWORD*) &nchars, ovl)) 8330 if (!WriteFile (hnd, buffer, count, (DWORD*) &nchars, ovl))
8298 { 8331 {
8299 if (GetLastError () != ERROR_IO_PENDING) 8332 if (GetLastError () != ERROR_IO_PENDING)
8300 { 8333 {
8301 errno = EIO; 8334 errno = EIO;
8302 return -1; 8335 nchars = -1;
8303 } 8336 }
8304 if (detect_input_pending ())
8305 active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE,
8306 QS_ALLINPUT);
8307 else 8337 else
8308 active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE);
8309 if (active == WAIT_OBJECT_0)
8310 { /* User pressed C-g, cancel write, then leave. Don't bother
8311 cleaning up as we may only get stuck in buggy drivers. */
8312 PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR);
8313 CancelIo (hnd);
8314 errno = EIO;
8315 return -1;
8316 }
8317 if (active == WAIT_OBJECT_0 + 1
8318 && !GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE))
8319 { 8338 {
8320 errno = EIO; 8339 /* Wait for the write to complete, and watch C-g while
8321 return -1; 8340 at that. */
8341 if (detect_input_pending ())
8342 active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE,
8343 INFINITE, QS_ALLINPUT);
8344 else
8345 active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE);
8346 switch (active)
8347 {
8348 case WAIT_OBJECT_0:
8349 /* User pressed C-g, cancel write, then leave.
8350 Don't bother cleaning up as we may only get stuck
8351 in buggy drivers. */
8352 PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR);
8353 CancelIo (hnd);
8354 errno = EIO; /* Why not EINTR? */
8355 nchars = -1;
8356 break;
8357 case WAIT_OBJECT_0 + 1:
8358 if (!GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE))
8359 {
8360 errno = EIO;
8361 nchars = -1;
8362 }
8363 break;
8364 }
8322 } 8365 }
8323 } 8366 }
8324 } 8367 }
@@ -8369,6 +8412,22 @@ sys_write (int fd, const void * buffer, unsigned int count)
8369 nchars += n; 8412 nchars += n;
8370 if (n < 0) 8413 if (n < 0)
8371 { 8414 {
8415 /* When there's no buffer space in a pipe that is in the
8416 non-blocking mode, _write returns ENOSPC. We return
8417 EAGAIN instead, which should trigger the logic in
8418 send_process that enters waiting loop and calls
8419 wait_reading_process_output to allow process input to
8420 be accepted during the wait. Those calls to
8421 wait_reading_process_output allow sys_select to
8422 notice when process input becomes available, thus
8423 avoiding deadlock whereby each side of the pipe is
8424 blocked on write, waiting for the other party to read
8425 its end of the pipe. */
8426 if (errno == ENOSPC
8427 && fd < MAXDESC
8428 && ((fd_info[fd].flags & (FILE_PIPE | FILE_NDELAY))
8429 == (FILE_PIPE | FILE_NDELAY)))
8430 errno = EAGAIN;
8372 nchars = n; 8431 nchars = n;
8373 break; 8432 break;
8374 } 8433 }
@@ -8379,6 +8438,7 @@ sys_write (int fd, const void * buffer, unsigned int count)
8379 } 8438 }
8380 } 8439 }
8381 8440
8441 SAFE_FREE ();
8382 return nchars; 8442 return nchars;
8383} 8443}
8384 8444
@@ -9068,6 +9128,7 @@ globals_of_w32 (void)
9068 g_b_init_set_named_security_info_w = 0; 9128 g_b_init_set_named_security_info_w = 0;
9069 g_b_init_set_named_security_info_a = 0; 9129 g_b_init_set_named_security_info_a = 0;
9070 g_b_init_get_adapters_info = 0; 9130 g_b_init_get_adapters_info = 0;
9131 g_b_init_compare_string_w = 0;
9071 num_of_processors = 0; 9132 num_of_processors = 0;
9072 /* The following sets a handler for shutdown notifications for 9133 /* The following sets a handler for shutdown notifications for
9073 console apps. This actually applies to Emacs in both console and 9134 console apps. This actually applies to Emacs in both console and
diff --git a/src/w32.h b/src/w32.h
index 94f7a962833..e0aedcbffa2 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -144,10 +144,10 @@ extern char * w32_strerror (int error_no);
144extern int w32_valid_pointer_p (void *, int); 144extern int w32_valid_pointer_p (void *, int);
145 145
146/* Get long (aka "true") form of file name, if it exists. */ 146/* Get long (aka "true") form of file name, if it exists. */
147extern BOOL w32_get_long_filename (char * name, char * buf, int size); 147extern BOOL w32_get_long_filename (const char * name, char * buf, int size);
148 148
149/* Get the short (a.k.a. "8+3") form of a file name. */ 149/* Get the short (a.k.a. "8+3") form of a file name. */
150extern unsigned int w32_get_short_filename (char *, char *, int); 150extern unsigned int w32_get_short_filename (const char *, char *, int);
151 151
152/* Prepare our standard handles for proper inheritance by child processes. */ 152/* Prepare our standard handles for proper inheritance by child processes. */
153extern void prepare_standard_handles (int in, int out, 153extern void prepare_standard_handles (int in, int out,
@@ -210,6 +210,9 @@ extern int sys_link (const char *, const char *);
210extern int w32_memory_info (unsigned long long *, unsigned long long *, 210extern int w32_memory_info (unsigned long long *, unsigned long long *,
211 unsigned long long *, unsigned long long *); 211 unsigned long long *, unsigned long long *);
212 212
213/* Compare 2 UTF-8 strings in locale-dependent fashion. */
214extern int w32_compare_strings (const char *, const char *, char *, int);
215
213#ifdef HAVE_GNUTLS 216#ifdef HAVE_GNUTLS
214#include <gnutls/gnutls.h> 217#include <gnutls/gnutls.h>
215 218
diff --git a/src/w32fns.c b/src/w32fns.c
index ac0e693e1c0..05da2a5c1d1 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -263,9 +263,9 @@ static unsigned int sound_type = 0xFFFFFFFF;
263 the first display on the list. */ 263 the first display on the list. */
264 264
265struct w32_display_info * 265struct w32_display_info *
266check_x_display_info (Lisp_Object frame) 266check_x_display_info (Lisp_Object object)
267{ 267{
268 if (NILP (frame)) 268 if (NILP (object))
269 { 269 {
270 struct frame *sf = XFRAME (selected_frame); 270 struct frame *sf = XFRAME (selected_frame);
271 271
@@ -274,14 +274,23 @@ check_x_display_info (Lisp_Object frame)
274 else 274 else
275 return &one_w32_display_info; 275 return &one_w32_display_info;
276 } 276 }
277 else if (STRINGP (frame)) 277 else if (TERMINALP (object))
278 return x_display_info_for_name (frame); 278 {
279 struct terminal *t = decode_live_terminal (object);
280
281 if (t->type != output_w32)
282 error ("Terminal %d is not a W32 display", t->id);
283
284 return t->display_info.w32;
285 }
286 else if (STRINGP (object))
287 return x_display_info_for_name (object);
279 else 288 else
280 { 289 {
281 struct frame *f; 290 struct frame *f;
282 291
283 CHECK_LIVE_FRAME (frame); 292 CHECK_LIVE_FRAME (object);
284 f = XFRAME (frame); 293 f = XFRAME (object);
285 if (! FRAME_W32_P (f)) 294 if (! FRAME_W32_P (f))
286 error ("Non-W32 frame used"); 295 error ("Non-W32 frame used");
287 return FRAME_DISPLAY_INFO (f); 296 return FRAME_DISPLAY_INFO (f);
@@ -1956,13 +1965,12 @@ w32_createhscrollbar (struct frame *f, struct scroll_bar * bar)
1956} 1965}
1957 1966
1958static void 1967static void
1959w32_createwindow (struct frame *f) 1968w32_createwindow (struct frame *f, int *coords)
1960{ 1969{
1961 HWND hwnd; 1970 HWND hwnd;
1962 RECT rect; 1971 RECT rect;
1963 Lisp_Object top = Qunbound; 1972 int top;
1964 Lisp_Object left = Qunbound; 1973 int left;
1965 struct w32_display_info *dpyinfo = &one_w32_display_info;
1966 1974
1967 rect.left = rect.top = 0; 1975 rect.left = rect.top = 0;
1968 rect.right = FRAME_PIXEL_WIDTH (f); 1976 rect.right = FRAME_PIXEL_WIDTH (f);
@@ -1977,25 +1985,21 @@ w32_createwindow (struct frame *f)
1977 1985
1978 if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition) 1986 if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
1979 { 1987 {
1980 XSETINT (left, f->left_pos); 1988 left = f->left_pos;
1981 XSETINT (top, f->top_pos); 1989 top = f->top_pos;
1982 } 1990 }
1983 else if (EQ (left, Qunbound) && EQ (top, Qunbound)) 1991 else
1984 { 1992 {
1985 /* When called with RES_TYPE_NUMBER, w32_get_arg will return zero 1993 left = coords[0];
1986 for anything that is not a number and is not Qunbound. */ 1994 top = coords[1];
1987 left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
1988 top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
1989 } 1995 }
1990 1996
1991 FRAME_W32_WINDOW (f) = hwnd 1997 FRAME_W32_WINDOW (f) = hwnd
1992 = CreateWindow (EMACS_CLASS, 1998 = CreateWindow (EMACS_CLASS,
1993 f->namebuf, 1999 f->namebuf,
1994 f->output_data.w32->dwStyle | WS_CLIPCHILDREN, 2000 f->output_data.w32->dwStyle | WS_CLIPCHILDREN,
1995 EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), 2001 left, top,
1996 EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top), 2002 rect.right - rect.left, rect.bottom - rect.top,
1997 rect.right - rect.left,
1998 rect.bottom - rect.top,
1999 NULL, 2003 NULL,
2000 NULL, 2004 NULL,
2001 hinst, 2005 hinst,
@@ -2516,7 +2520,8 @@ w32_msg_pump (deferred_msg * msg_buf)
2516 the patch for XP is not publicly available until XP SP3, 2520 the patch for XP is not publicly available until XP SP3,
2517 and older versions will never be patched. */ 2521 and older versions will never be patched. */
2518 CoInitialize (NULL); 2522 CoInitialize (NULL);
2519 w32_createwindow ((struct frame *) msg.wParam); 2523 w32_createwindow ((struct frame *) msg.wParam,
2524 (int *) msg.lParam);
2520 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) 2525 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2521 emacs_abort (); 2526 emacs_abort ();
2522 break; 2527 break;
@@ -4136,8 +4141,25 @@ static void
4136my_create_window (struct frame * f) 4141my_create_window (struct frame * f)
4137{ 4142{
4138 MSG msg; 4143 MSG msg;
4144 static int coords[2];
4145 Lisp_Object left, top;
4146 struct w32_display_info *dpyinfo = &one_w32_display_info;
4147
4148 /* When called with RES_TYPE_NUMBER, x_get_arg will return zero for
4149 anything that is not a number and is not Qunbound. */
4150 left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
4151 top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
4152 if (EQ (left, Qunbound))
4153 coords[0] = CW_USEDEFAULT;
4154 else
4155 coords[0] = XINT (left);
4156 if (EQ (top, Qunbound))
4157 coords[1] = CW_USEDEFAULT;
4158 else
4159 coords[1] = XINT (top);
4139 4160
4140 if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0)) 4161 if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW,
4162 (WPARAM)f, (LPARAM)coords))
4141 emacs_abort (); 4163 emacs_abort ();
4142 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); 4164 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
4143} 4165}
@@ -4569,7 +4591,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4569 NULL, NULL, RES_TYPE_NUMBER); 4591 NULL, NULL, RES_TYPE_NUMBER);
4570 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright, 4592 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
4571 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL); 4593 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
4572 x_default_parameter (f, parameters, Qhorizontal_scroll_bars, Qbottom, 4594 x_default_parameter (f, parameters, Qhorizontal_scroll_bars, Qnil,
4573 "horizontalScrollBars", "ScrollBars", RES_TYPE_SYMBOL); 4595 "horizontalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
4574 4596
4575 /* Also do the stuff which must be set before the window exists. */ 4597 /* Also do the stuff which must be set before the window exists. */
@@ -5012,7 +5034,7 @@ If omitted or nil, that stands for the selected frame's display. */)
5012 return Qnil; 5034 return Qnil;
5013} 5035}
5014 5036
5015static BOOL CALLBACK 5037static BOOL CALLBACK ALIGN_STACK
5016w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData) 5038w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData)
5017{ 5039{
5018 Lisp_Object *monitor_list = (Lisp_Object *) dwData; 5040 Lisp_Object *monitor_list = (Lisp_Object *) dwData;
@@ -5339,7 +5361,7 @@ terminate Emacs if we can't open the connection.
5339 { 5361 {
5340 char basename[ MAX_PATH ], *str; 5362 char basename[ MAX_PATH ], *str;
5341 5363
5342 strcpy (basename, SDATA (Vinvocation_name)); 5364 lispstpcpy (basename, Vinvocation_name);
5343 str = strrchr (basename, '.'); 5365 str = strrchr (basename, '.');
5344 if (str) *str = 0; 5366 if (str) *str = 0;
5345 Vinvocation_name = build_string (basename); 5367 Vinvocation_name = build_string (basename);
@@ -5640,7 +5662,8 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5640 f->wants_modeline = 0; 5662 f->wants_modeline = 0;
5641 XSETFRAME (frame, f); 5663 XSETFRAME (frame, f);
5642 5664
5643 buffer = Fget_buffer_create (build_string (" *tip*")); 5665 AUTO_STRING (tip, " *tip*");
5666 buffer = Fget_buffer_create (tip);
5644 /* Use set_window_buffer instead of Fset_window_buffer (see 5667 /* Use set_window_buffer instead of Fset_window_buffer (see
5645 discussion of bug#11984, bug#12025, bug#12026). */ 5668 discussion of bug#11984, bug#12025, bug#12026). */
5646 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0); 5669 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
diff --git a/src/w32font.c b/src/w32font.c
index 81e25eb0856..895931843ba 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -115,15 +115,15 @@ static void compute_metrics (HDC, struct w32font_info *, unsigned int,
115static Lisp_Object w32_registry (LONG, DWORD); 115static Lisp_Object w32_registry (LONG, DWORD);
116 116
117/* EnumFontFamiliesEx callbacks. */ 117/* EnumFontFamiliesEx callbacks. */
118static int CALLBACK add_font_entity_to_list (ENUMLOGFONTEX *, 118static int CALLBACK ALIGN_STACK add_font_entity_to_list (ENUMLOGFONTEX *,
119 NEWTEXTMETRICEX *, 119 NEWTEXTMETRICEX *,
120 DWORD, LPARAM); 120 DWORD, LPARAM);
121static int CALLBACK add_one_font_entity_to_list (ENUMLOGFONTEX *, 121static int CALLBACK ALIGN_STACK add_one_font_entity_to_list (ENUMLOGFONTEX *,
122 NEWTEXTMETRICEX *, 122 NEWTEXTMETRICEX *,
123 DWORD, LPARAM); 123 DWORD, LPARAM);
124static int CALLBACK add_font_name_to_list (ENUMLOGFONTEX *, 124static int CALLBACK ALIGN_STACK add_font_name_to_list (ENUMLOGFONTEX *,
125 NEWTEXTMETRICEX *, 125 NEWTEXTMETRICEX *,
126 DWORD, LPARAM); 126 DWORD, LPARAM);
127 127
128/* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track 128/* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
129 of what we really want. */ 129 of what we really want. */
@@ -287,11 +287,11 @@ Lisp_Object
287intern_font_name (char * string) 287intern_font_name (char * string)
288{ 288{
289 Lisp_Object str = DECODE_SYSTEM (build_string (string)); 289 Lisp_Object str = DECODE_SYSTEM (build_string (string));
290 int len = SCHARS (str); 290 ptrdiff_t len = SCHARS (str);
291 Lisp_Object obarray = check_obarray (Vobarray); 291 Lisp_Object obarray = check_obarray (Vobarray);
292 Lisp_Object tem = oblookup (obarray, SDATA (str), len, len); 292 Lisp_Object tem = oblookup (obarray, SDATA (str), len, len);
293 /* This code is similar to intern function from lread.c. */ 293 /* This code is similar to intern function from lread.c. */
294 return SYMBOLP (tem) ? tem : Fintern (str, obarray); 294 return SYMBOLP (tem) ? tem : intern_driver (str, obarray, XINT (tem));
295} 295}
296 296
297/* w32 implementation of get_cache for font backend. 297/* w32 implementation of get_cache for font backend.
@@ -473,7 +473,7 @@ w32font_encode_char (struct font *font, int c)
473 of METRICS. The glyphs are specified by their glyph codes in 473 of METRICS. The glyphs are specified by their glyph codes in
474 CODE (length NGLYPHS). Apparently metrics can be NULL, in this 474 CODE (length NGLYPHS). Apparently metrics can be NULL, in this
475 case just return the overall width. */ 475 case just return the overall width. */
476int 476void
477w32font_text_extents (struct font *font, unsigned *code, 477w32font_text_extents (struct font *font, unsigned *code,
478 int nglyphs, struct font_metrics *metrics) 478 int nglyphs, struct font_metrics *metrics)
479{ 479{
@@ -487,84 +487,80 @@ w32font_text_extents (struct font *font, unsigned *code,
487 487
488 struct w32font_info *w32_font = (struct w32font_info *) font; 488 struct w32font_info *w32_font = (struct w32font_info *) font;
489 489
490 if (metrics) 490 memset (metrics, 0, sizeof (struct font_metrics));
491 { 491 metrics->ascent = font->ascent;
492 memset (metrics, 0, sizeof (struct font_metrics)); 492 metrics->descent = font->descent;
493 metrics->ascent = font->ascent;
494 metrics->descent = font->descent;
495
496 for (i = 0; i < nglyphs; i++)
497 {
498 struct w32_metric_cache *char_metric;
499 int block = *(code + i) / CACHE_BLOCKSIZE;
500 int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
501 493
502 if (block >= w32_font->n_cache_blocks) 494 for (i = 0; i < nglyphs; i++)
503 { 495 {
504 if (!w32_font->cached_metrics) 496 struct w32_metric_cache *char_metric;
505 w32_font->cached_metrics 497 int block = *(code + i) / CACHE_BLOCKSIZE;
506 = xmalloc ((block + 1) 498 int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
507 * sizeof (struct w32_metric_cache *));
508 else
509 w32_font->cached_metrics
510 = xrealloc (w32_font->cached_metrics,
511 (block + 1)
512 * sizeof (struct w32_metric_cache *));
513 memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
514 ((block + 1 - w32_font->n_cache_blocks)
515 * sizeof (struct w32_metric_cache *)));
516 w32_font->n_cache_blocks = block + 1;
517 }
518 499
519 if (!w32_font->cached_metrics[block]) 500 if (block >= w32_font->n_cache_blocks)
520 { 501 {
521 w32_font->cached_metrics[block] 502 if (!w32_font->cached_metrics)
522 = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache)); 503 w32_font->cached_metrics
523 } 504 = xmalloc ((block + 1)
505 * sizeof (struct w32_metric_cache *));
506 else
507 w32_font->cached_metrics
508 = xrealloc (w32_font->cached_metrics,
509 (block + 1)
510 * sizeof (struct w32_metric_cache *));
511 memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
512 ((block + 1 - w32_font->n_cache_blocks)
513 * sizeof (struct w32_metric_cache *)));
514 w32_font->n_cache_blocks = block + 1;
515 }
524 516
525 char_metric = w32_font->cached_metrics[block] + pos_in_block; 517 if (!w32_font->cached_metrics[block])
518 {
519 w32_font->cached_metrics[block]
520 = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
521 }
526 522
527 if (char_metric->status == W32METRIC_NO_ATTEMPT) 523 char_metric = w32_font->cached_metrics[block] + pos_in_block;
528 {
529 if (dc == NULL)
530 {
531 /* TODO: Frames can come and go, and their fonts
532 outlive them. So we can't cache the frame in the
533 font structure. Use selected_frame until the API
534 is updated to pass in a frame. */
535 f = XFRAME (selected_frame);
536
537 dc = get_frame_dc (f);
538 old_font = SelectObject (dc, w32_font->hfont);
539 }
540 compute_metrics (dc, w32_font, *(code + i), char_metric);
541 }
542 524
543 if (char_metric->status == W32METRIC_SUCCESS) 525 if (char_metric->status == W32METRIC_NO_ATTEMPT)
526 {
527 if (dc == NULL)
544 { 528 {
545 metrics->lbearing = min (metrics->lbearing, 529 /* TODO: Frames can come and go, and their fonts
546 metrics->width + char_metric->lbearing); 530 outlive them. So we can't cache the frame in the
547 metrics->rbearing = max (metrics->rbearing, 531 font structure. Use selected_frame until the API
548 metrics->width + char_metric->rbearing); 532 is updated to pass in a frame. */
549 metrics->width += char_metric->width; 533 f = XFRAME (selected_frame);
534
535 dc = get_frame_dc (f);
536 old_font = SelectObject (dc, w32_font->hfont);
550 } 537 }
551 else 538 compute_metrics (dc, w32_font, *(code + i), char_metric);
552 /* If we couldn't get metrics for a char,
553 use alternative method. */
554 break;
555 } 539 }
556 /* If we got through everything, return. */
557 if (i == nglyphs)
558 {
559 if (dc != NULL)
560 {
561 /* Restore state and release DC. */
562 SelectObject (dc, old_font);
563 release_frame_dc (f, dc);
564 }
565 540
566 return metrics->width; 541 if (char_metric->status == W32METRIC_SUCCESS)
567 } 542 {
543 metrics->lbearing = min (metrics->lbearing,
544 metrics->width + char_metric->lbearing);
545 metrics->rbearing = max (metrics->rbearing,
546 metrics->width + char_metric->rbearing);
547 metrics->width += char_metric->width;
548 }
549 else
550 /* If we couldn't get metrics for a char,
551 use alternative method. */
552 break;
553 }
554 /* If we got through everything, return. */
555 if (i == nglyphs)
556 {
557 if (dc != NULL)
558 {
559 /* Restore state and release DC. */
560 SelectObject (dc, old_font);
561 release_frame_dc (f, dc);
562 }
563 return;
568 } 564 }
569 565
570 /* For non-truetype fonts, GetGlyphOutlineW is not supported, so 566 /* For non-truetype fonts, GetGlyphOutlineW is not supported, so
@@ -620,18 +616,13 @@ w32font_text_extents (struct font *font, unsigned *code,
620 } 616 }
621 617
622 /* Give our best estimate of the metrics, based on what we know. */ 618 /* Give our best estimate of the metrics, based on what we know. */
623 if (metrics) 619 metrics->width = total_width - w32_font->metrics.tmOverhang;
624 { 620 metrics->lbearing = 0;
625 metrics->width = total_width - w32_font->metrics.tmOverhang; 621 metrics->rbearing = total_width;
626 metrics->lbearing = 0;
627 metrics->rbearing = total_width;
628 }
629 622
630 /* Restore state and release DC. */ 623 /* Restore state and release DC. */
631 SelectObject (dc, old_font); 624 SelectObject (dc, old_font);
632 release_frame_dc (f, dc); 625 release_frame_dc (f, dc);
633
634 return total_width;
635} 626}
636 627
637/* w32 implementation of draw for font backend. 628/* w32 implementation of draw for font backend.
@@ -1009,7 +1000,7 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity,
1009 1000
1010/* Callback function for EnumFontFamiliesEx. 1001/* Callback function for EnumFontFamiliesEx.
1011 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */ 1002 * Adds the name of a font to a Lisp list (passed in as the lParam arg). */
1012static int CALLBACK 1003static int CALLBACK ALIGN_STACK
1013add_font_name_to_list (ENUMLOGFONTEX *logical_font, 1004add_font_name_to_list (ENUMLOGFONTEX *logical_font,
1014 NEWTEXTMETRICEX *physical_font, 1005 NEWTEXTMETRICEX *physical_font,
1015 DWORD font_type, LPARAM list_object) 1006 DWORD font_type, LPARAM list_object)
@@ -1455,7 +1446,7 @@ check_face_name (LOGFONT *font, char *full_name)
1455 * and if so, adds it to a list. Both the data we are checking against 1446 * and if so, adds it to a list. Both the data we are checking against
1456 * and the list to which the fonts are added are passed in via the 1447 * and the list to which the fonts are added are passed in via the
1457 * lparam argument, in the form of a font_callback_data struct. */ 1448 * lparam argument, in the form of a font_callback_data struct. */
1458static int CALLBACK 1449static int CALLBACK ALIGN_STACK
1459add_font_entity_to_list (ENUMLOGFONTEX *logical_font, 1450add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
1460 NEWTEXTMETRICEX *physical_font, 1451 NEWTEXTMETRICEX *physical_font,
1461 DWORD font_type, LPARAM lParam) 1452 DWORD font_type, LPARAM lParam)
@@ -1574,7 +1565,7 @@ add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
1574 1565
1575/* Callback function for EnumFontFamiliesEx. 1566/* Callback function for EnumFontFamiliesEx.
1576 * Terminates the search once we have a match. */ 1567 * Terminates the search once we have a match. */
1577static int CALLBACK 1568static int CALLBACK ALIGN_STACK
1578add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font, 1569add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font,
1579 NEWTEXTMETRICEX *physical_font, 1570 NEWTEXTMETRICEX *physical_font,
1580 DWORD font_type, LPARAM lParam) 1571 DWORD font_type, LPARAM lParam)
diff --git a/src/w32font.h b/src/w32font.h
index 1be49bb91c2..5ce3ac7a5f9 100644
--- a/src/w32font.h
+++ b/src/w32font.h
@@ -74,8 +74,8 @@ int w32font_open_internal (struct frame *f, Lisp_Object font_entity,
74 int pixel_size, Lisp_Object font_object); 74 int pixel_size, Lisp_Object font_object);
75void w32font_close (struct font *font); 75void w32font_close (struct font *font);
76int w32font_has_char (Lisp_Object entity, int c); 76int w32font_has_char (Lisp_Object entity, int c);
77int w32font_text_extents (struct font *font, unsigned *code, int nglyphs, 77void w32font_text_extents (struct font *font, unsigned *code, int nglyphs,
78 struct font_metrics *metrics); 78 struct font_metrics *metrics);
79int w32font_draw (struct glyph_string *s, int from, int to, 79int w32font_draw (struct glyph_string *s, int from, int to,
80 int x, int y, bool with_background); 80 int x, int y, bool with_background);
81 81
diff --git a/src/w32inevt.c b/src/w32inevt.c
index ccb5a900a16..7d10d88155c 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -411,7 +411,7 @@ w32_console_mouse_position (struct frame **f,
411 411
412 *f = get_frame (); 412 *f = get_frame ();
413 *bar_window = Qnil; 413 *bar_window = Qnil;
414 *part = 0; 414 *part = scroll_bar_above_handle;
415 SELECTED_FRAME ()->mouse_moved = 0; 415 SELECTED_FRAME ()->mouse_moved = 0;
416 416
417 XSETINT (*x, movement_pos.X); 417 XSETINT (*x, movement_pos.X);
@@ -605,7 +605,7 @@ maybe_generate_resize_event (void)
605 change_frame_size (f, 605 change_frame_size (f,
606 1 + info.srWindow.Right - info.srWindow.Left, 606 1 + info.srWindow.Right - info.srWindow.Left,
607 1 + info.srWindow.Bottom - info.srWindow.Top 607 1 + info.srWindow.Bottom - info.srWindow.Top
608 - FRAME_MENU_BAR_LINES (f), 0, 0, 0, 0); 608 - FRAME_MENU_BAR_LINES (f), 0, 1, 0, 0);
609} 609}
610 610
611#if HAVE_W32NOTIFY 611#if HAVE_W32NOTIFY
diff --git a/src/w32inevt.h b/src/w32inevt.h
index 9117453e721..c4836211bc9 100644
--- a/src/w32inevt.h
+++ b/src/w32inevt.h
@@ -27,6 +27,6 @@ extern void w32_console_mouse_position (struct frame **f, int insist,
27 Lisp_Object *bar_window, 27 Lisp_Object *bar_window,
28 enum scroll_bar_part *part, 28 enum scroll_bar_part *part,
29 Lisp_Object *x, Lisp_Object *y, 29 Lisp_Object *x, Lisp_Object *y,
30 unsigned long *time); 30 Time *time);
31 31
32#endif /* EMACS_W32INEVT_H */ 32#endif /* EMACS_W32INEVT_H */
diff --git a/src/w32proc.c b/src/w32proc.c
index 426a656f566..38452917add 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include <signal.h> 32#include <signal.h>
33#include <sys/file.h> 33#include <sys/file.h>
34#include <mbstring.h> 34#include <mbstring.h>
35#include <locale.h>
35 36
36/* must include CRT headers *before* config.h */ 37/* must include CRT headers *before* config.h */
37#include <config.h> 38#include <config.h>
@@ -1604,6 +1605,15 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
1604 program = ENCODE_FILE (full); 1605 program = ENCODE_FILE (full);
1605 cmdname = SDATA (program); 1606 cmdname = SDATA (program);
1606 } 1607 }
1608 else
1609 {
1610 char *p = alloca (strlen (cmdname) + 1);
1611
1612 /* Don't change the command name we were passed by our caller
1613 (unixtodos_filename below will destructively mirror forward
1614 slashes). */
1615 cmdname = strcpy (p, cmdname);
1616 }
1607 1617
1608 /* make sure argv[0] and cmdname are both in DOS format */ 1618 /* make sure argv[0] and cmdname are both in DOS format */
1609 unixtodos_filename (cmdname); 1619 unixtodos_filename (cmdname);
@@ -1646,7 +1656,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
1646 strcpy (cmdname, egetenv ("CMDPROXY")); 1656 strcpy (cmdname, egetenv ("CMDPROXY"));
1647 else 1657 else
1648 { 1658 {
1649 strcpy (cmdname, SDATA (Vinvocation_directory)); 1659 lispstpcpy (cmdname, Vinvocation_directory);
1650 strcat (cmdname, "cmdproxy.exe"); 1660 strcat (cmdname, "cmdproxy.exe");
1651 } 1661 }
1652 1662
@@ -2908,7 +2918,7 @@ int_from_hex (char * s)
2908 function isn't given a context pointer. */ 2918 function isn't given a context pointer. */
2909Lisp_Object Vw32_valid_locale_ids; 2919Lisp_Object Vw32_valid_locale_ids;
2910 2920
2911static BOOL CALLBACK 2921static BOOL CALLBACK ALIGN_STACK
2912enum_locale_fn (LPTSTR localeNum) 2922enum_locale_fn (LPTSTR localeNum)
2913{ 2923{
2914 DWORD id = int_from_hex (localeNum); 2924 DWORD id = int_from_hex (localeNum);
@@ -2972,7 +2982,7 @@ If successful, the new locale id is returned, otherwise nil. */)
2972 function isn't given a context pointer. */ 2982 function isn't given a context pointer. */
2973Lisp_Object Vw32_valid_codepages; 2983Lisp_Object Vw32_valid_codepages;
2974 2984
2975static BOOL CALLBACK 2985static BOOL CALLBACK ALIGN_STACK
2976enum_codepage_fn (LPTSTR codepageNum) 2986enum_codepage_fn (LPTSTR codepageNum)
2977{ 2987{
2978 DWORD id = atoi (codepageNum); 2988 DWORD id = atoi (codepageNum);
@@ -3144,6 +3154,190 @@ If successful, the new layout id is returned, otherwise nil. */)
3144 return Fw32_get_keyboard_layout (); 3154 return Fw32_get_keyboard_layout ();
3145} 3155}
3146 3156
3157/* Two variables to interface between get_lcid and the EnumLocales
3158 callback function below. */
3159#ifndef LOCALE_NAME_MAX_LENGTH
3160# define LOCALE_NAME_MAX_LENGTH 85
3161#endif
3162static LCID found_lcid;
3163static char lname[3 * LOCALE_NAME_MAX_LENGTH + 1 + 1];
3164
3165/* Callback function for EnumLocales. */
3166static BOOL CALLBACK
3167get_lcid_callback (LPTSTR locale_num_str)
3168{
3169 char *endp;
3170 char locval[2 * LOCALE_NAME_MAX_LENGTH + 1 + 1];
3171 LCID try_lcid = strtoul (locale_num_str, &endp, 16);
3172
3173 if (GetLocaleInfo (try_lcid, LOCALE_SABBREVLANGNAME,
3174 locval, LOCALE_NAME_MAX_LENGTH))
3175 {
3176 /* This is for when they only specify the language, as in "ENU". */
3177 if (stricmp (locval, lname) == 0)
3178 {
3179 found_lcid = try_lcid;
3180 return FALSE;
3181 }
3182 strcat (locval, "_");
3183 if (GetLocaleInfo (try_lcid, LOCALE_SABBREVCTRYNAME,
3184 locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
3185 {
3186 size_t locval_len = strlen (locval);
3187
3188 if (strnicmp (locval, lname, locval_len) == 0
3189 && (lname[locval_len] == '.'
3190 || lname[locval_len] == '\0'))
3191 {
3192 found_lcid = try_lcid;
3193 return FALSE;
3194 }
3195 }
3196 }
3197 return TRUE;
3198}
3199
3200/* Return the Locale ID (LCID) number given the locale's name, a
3201 string, in LOCALE_NAME. This works by enumerating all the locales
3202 supported by the system, until we find one whose name matches
3203 LOCALE_NAME. */
3204static LCID
3205get_lcid (const char *locale_name)
3206{
3207 /* A simple cache. */
3208 static LCID last_lcid;
3209 static char last_locale[1000];
3210
3211 /* The code below is not thread-safe, as it uses static variables.
3212 But this function is called only from the Lisp thread. */
3213 if (last_lcid > 0 && strcmp (locale_name, last_locale) == 0)
3214 return last_lcid;
3215
3216 strncpy (lname, locale_name, sizeof (lname) - 1);
3217 lname[sizeof (lname) - 1] = '\0';
3218 found_lcid = 0;
3219 EnumSystemLocales (get_lcid_callback, LCID_SUPPORTED);
3220 if (found_lcid > 0)
3221 {
3222 last_lcid = found_lcid;
3223 strcpy (last_locale, locale_name);
3224 }
3225 return found_lcid;
3226}
3227
3228#ifndef _NSLCMPERROR
3229# define _NSLCMPERROR INT_MAX
3230#endif
3231#ifndef LINGUISTIC_IGNORECASE
3232# define LINGUISTIC_IGNORECASE 0x00000010
3233#endif
3234
3235int
3236w32_compare_strings (const char *s1, const char *s2, char *locname,
3237 int ignore_case)
3238{
3239 LCID lcid = GetThreadLocale ();
3240 wchar_t *string1_w, *string2_w;
3241 int val, needed;
3242 extern BOOL g_b_init_compare_string_w;
3243 static int (WINAPI *pCompareStringW)(LCID, DWORD, LPCWSTR, int, LPCWSTR, int);
3244 DWORD flags = 0;
3245
3246 USE_SAFE_ALLOCA;
3247
3248 /* The LCID machinery doesn't seem to support the "C" locale, so we
3249 need to do that by hand. */
3250 if (locname
3251 && ((locname[0] == 'C' && (locname[1] == '\0' || locname[1] == '.'))
3252 || strcmp (locname, "POSIX") == 0))
3253 return (ignore_case ? stricmp (s1, s2) : strcmp (s1, s2));
3254
3255 if (!g_b_init_compare_string_w)
3256 {
3257 if (os_subtype == OS_9X)
3258 {
3259 pCompareStringW = GetProcAddress (LoadLibrary ("Unicows.dll"),
3260 "CompareStringW");
3261 if (!pCompareStringW)
3262 {
3263 errno = EINVAL;
3264 /* This return value is compatible with wcscoll and
3265 other MS CRT functions. */
3266 return _NSLCMPERROR;
3267 }
3268 }
3269 else
3270 pCompareStringW = CompareStringW;
3271
3272 g_b_init_compare_string_w = 1;
3273 }
3274
3275 needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s1, -1, NULL, 0);
3276 if (needed > 0)
3277 {
3278 SAFE_NALLOCA (string1_w, 1, needed + 1);
3279 pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s1, -1,
3280 string1_w, needed);
3281 }
3282 else
3283 {
3284 errno = EINVAL;
3285 return _NSLCMPERROR;
3286 }
3287
3288 needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s2, -1, NULL, 0);
3289 if (needed > 0)
3290 {
3291 SAFE_NALLOCA (string2_w, 1, needed + 1);
3292 pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, s2, -1,
3293 string2_w, needed);
3294 }
3295 else
3296 {
3297 SAFE_FREE ();
3298 errno = EINVAL;
3299 return _NSLCMPERROR;
3300 }
3301
3302 if (locname)
3303 {
3304 /* Convert locale name string to LCID. We don't want to use
3305 LocaleNameToLCID because (a) it is only available since
3306 Vista, and (b) it doesn't accept locale names returned by
3307 'setlocale' and 'GetLocaleInfo'. */
3308 LCID new_lcid = get_lcid (locname);
3309
3310 if (new_lcid > 0)
3311 lcid = new_lcid;
3312 else
3313 error ("Invalid locale %s: Invalid argument", locname);
3314 }
3315
3316 if (ignore_case)
3317 {
3318 /* NORM_IGNORECASE ignores any tertiary distinction, not just
3319 case variants. LINGUISTIC_IGNORECASE is more selective, and
3320 is sensitive to the locale's language, but it is not
3321 available before Vista. */
3322 if (w32_major_version >= 6)
3323 flags |= LINGUISTIC_IGNORECASE;
3324 else
3325 flags |= NORM_IGNORECASE;
3326 }
3327 /* This approximates what glibc collation functions do when the
3328 locale's codeset is UTF-8. */
3329 if (!NILP (Vw32_collate_ignore_punctuation))
3330 flags |= NORM_IGNORESYMBOLS;
3331 val = pCompareStringW (lcid, flags, string1_w, -1, string2_w, -1);
3332 SAFE_FREE ();
3333 if (!val)
3334 {
3335 errno = EINVAL;
3336 return _NSLCMPERROR;
3337 }
3338 return val - 2;
3339}
3340
3147 3341
3148void 3342void
3149syms_of_ntproc (void) 3343syms_of_ntproc (void)
@@ -3254,6 +3448,20 @@ Any other non-nil value means do this even on remote and removable drives
3254where the performance impact may be noticeable even on modern hardware. */); 3448where the performance impact may be noticeable even on modern hardware. */);
3255 Vw32_get_true_file_attributes = Qlocal; 3449 Vw32_get_true_file_attributes = Qlocal;
3256 3450
3451 DEFVAR_LISP ("w32-collate-ignore-punctuation",
3452 Vw32_collate_ignore_punctuation,
3453 doc: /* Non-nil causes string collation functions ignore punctuation on MS-Windows.
3454On Posix platforms, `string-collate-lessp' and `string-collate-equalp'
3455ignore punctuation characters when they compare strings, if the
3456locale's codeset is UTF-8, as in \"en_US.UTF-8\". Binding this option
3457to a non-nil value will achieve a similar effect on MS-Windows, where
3458locales with UTF-8 codeset are not supported.
3459
3460Note that setting this to non-nil will also ignore blanks and symbols
3461in the strings. So do NOT use this option when comparing file names
3462for equality, only when you need to sort them. */);
3463 Vw32_collate_ignore_punctuation = Qnil;
3464
3257 staticpro (&Vw32_valid_locale_ids); 3465 staticpro (&Vw32_valid_locale_ids);
3258 staticpro (&Vw32_valid_codepages); 3466 staticpro (&Vw32_valid_codepages);
3259} 3467}
diff --git a/src/w32term.c b/src/w32term.c
index d9e051be870..e8bcf3ef639 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2228,7 +2228,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
2228 { 2228 {
2229 /* In R2L rows, draw the cursor on the right edge of the 2229 /* In R2L rows, draw the cursor on the right edge of the
2230 stretch glyph. */ 2230 stretch glyph. */
2231 int right_x = window_box_right_offset (s->w, TEXT_AREA); 2231 int right_x = window_box_right (s->w, TEXT_AREA);
2232 2232
2233 if (x + background_width > right_x) 2233 if (x + background_width > right_x)
2234 background_width -= x - right_x; 2234 background_width -= x - right_x;
@@ -3344,11 +3344,11 @@ static struct scroll_bar *x_window_to_scroll_bar (Window, int);
3344static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, 3344static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
3345 enum scroll_bar_part *, 3345 enum scroll_bar_part *,
3346 Lisp_Object *, Lisp_Object *, 3346 Lisp_Object *, Lisp_Object *,
3347 unsigned long *); 3347 Time *);
3348static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *, 3348static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
3349 enum scroll_bar_part *, 3349 enum scroll_bar_part *,
3350 Lisp_Object *, Lisp_Object *, 3350 Lisp_Object *, Lisp_Object *,
3351 unsigned long *); 3351 Time *);
3352static void x_check_fullscreen (struct frame *); 3352static void x_check_fullscreen (struct frame *);
3353 3353
3354static void 3354static void
@@ -3380,7 +3380,7 @@ w32_define_cursor (Window window, Cursor cursor)
3380static void 3380static void
3381w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, 3381w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3382 enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, 3382 enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
3383 unsigned long *time) 3383 Time *time)
3384{ 3384{
3385 struct frame *f1; 3385 struct frame *f1;
3386 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); 3386 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
@@ -3448,7 +3448,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3448 dpyinfo->last_mouse_glyph_frame = f1; 3448 dpyinfo->last_mouse_glyph_frame = f1;
3449 3449
3450 *bar_window = Qnil; 3450 *bar_window = Qnil;
3451 *part = 0; 3451 *part = scroll_bar_above_handle;
3452 *fp = f1; 3452 *fp = f1;
3453 XSETINT (*x, pt.x); 3453 XSETINT (*x, pt.x);
3454 XSETINT (*y, pt.y); 3454 XSETINT (*y, pt.y);
@@ -4293,7 +4293,7 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4293 x = si.nTrackPos; 4293 x = si.nTrackPos;
4294 else 4294 else
4295 x = si.nPos; 4295 x = si.nPos;
4296 y = si.nMax - x - si.nPage; 4296 y = si.nMax - si.nPage;
4297 4297
4298 bar->dragging = 0; 4298 bar->dragging = 0;
4299 FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam; 4299 FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
@@ -4350,12 +4350,9 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4350 int end = bar->end; 4350 int end = bar->end;
4351 4351
4352 si.cbSize = sizeof (si); 4352 si.cbSize = sizeof (si);
4353/** si.fMask = SIF_PAGE | SIF_POS; **/
4354 si.fMask = SIF_POS; 4353 si.fMask = SIF_POS;
4355/** si.nPage = end - start + HORIZONTAL_SCROLL_BAR_MIN_HANDLE; **/
4356 si.nPos = min (last_scroll_bar_drag_pos, 4354 si.nPos = min (last_scroll_bar_drag_pos,
4357 XWINDOW (bar->window)->hscroll_whole - 1); 4355 XWINDOW (bar->window)->hscroll_whole - 1);
4358/** si.nPos = last_scroll_bar_drag_pos; **/
4359 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE); 4356 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
4360 } 4357 }
4361 /* fall through */ 4358 /* fall through */
@@ -4377,7 +4374,7 @@ static void
4377x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, 4374x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4378 enum scroll_bar_part *part, 4375 enum scroll_bar_part *part,
4379 Lisp_Object *x, Lisp_Object *y, 4376 Lisp_Object *x, Lisp_Object *y,
4380 unsigned long *time) 4377 Time *time)
4381{ 4378{
4382 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); 4379 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
4383 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; 4380 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
@@ -4427,7 +4424,7 @@ static void
4427x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, 4424x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4428 enum scroll_bar_part *part, 4425 enum scroll_bar_part *part,
4429 Lisp_Object *x, Lisp_Object *y, 4426 Lisp_Object *x, Lisp_Object *y,
4430 unsigned long *time) 4427 Time *time)
4431{ 4428{
4432 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); 4429 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
4433 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; 4430 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
@@ -5147,30 +5144,38 @@ w32_read_socket (struct terminal *terminal,
5147 RECT rect; 5144 RECT rect;
5148 int rows, columns, width, height, text_width, text_height; 5145 int rows, columns, width, height, text_width, text_height;
5149 5146
5150 GetClientRect (msg.msg.hwnd, &rect); 5147 if (GetClientRect (msg.msg.hwnd, &rect)
5151 5148 /* GetClientRect evidently returns (0, 0, 0, 0) if
5152 height = rect.bottom - rect.top; 5149 called on a minimized frame. Such "dimensions"
5153 width = rect.right - rect.left; 5150 aren't useful anyway. */
5154 text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width); 5151 && !(rect.bottom == 0
5155 text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height); 5152 && rect.top == 0
5156 /* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */ 5153 && rect.left == 0
5157 /* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */ 5154 && rect.right == 0))
5158
5159 /* TODO: Clip size to the screen dimensions. */
5160
5161 /* Even if the number of character rows and columns has
5162 not changed, the font size may have changed, so we need
5163 to check the pixel dimensions as well. */
5164
5165 if (width != FRAME_PIXEL_WIDTH (f)
5166 || height != FRAME_PIXEL_HEIGHT (f)
5167 || text_width != FRAME_TEXT_WIDTH (f)
5168 || text_height != FRAME_TEXT_HEIGHT (f))
5169 { 5155 {
5170 change_frame_size (f, text_width, text_height, 0, 1, 0, 1); 5156 height = rect.bottom - rect.top;
5171 SET_FRAME_GARBAGED (f); 5157 width = rect.right - rect.left;
5172 cancel_mouse_face (f); 5158 text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
5173 f->win_gravity = NorthWestGravity; 5159 text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
5160 /* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */
5161 /* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */
5162
5163 /* TODO: Clip size to the screen dimensions. */
5164
5165 /* Even if the number of character rows and columns
5166 has not changed, the font size may have changed,
5167 so we need to check the pixel dimensions as well. */
5168
5169 if (width != FRAME_PIXEL_WIDTH (f)
5170 || height != FRAME_PIXEL_HEIGHT (f)
5171 || text_width != FRAME_TEXT_WIDTH (f)
5172 || text_height != FRAME_TEXT_HEIGHT (f))
5173 {
5174 change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
5175 SET_FRAME_GARBAGED (f);
5176 cancel_mouse_face (f);
5177 f->win_gravity = NorthWestGravity;
5178 }
5174 } 5179 }
5175 } 5180 }
5176 5181
@@ -5475,6 +5480,12 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
5475 /* Compute frame-relative coordinates for phys cursor. */ 5480 /* Compute frame-relative coordinates for phys cursor. */
5476 get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h); 5481 get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
5477 rect.left = left; 5482 rect.left = left;
5483 /* When on R2L character, show cursor at the right edge of the
5484 glyph, unless the cursor box is as wide as the glyph or wider
5485 (the latter happens when x-stretch-cursor is non-nil). */
5486 if ((cursor_glyph->resolved_level & 1) != 0
5487 && cursor_glyph->pixel_width > w->phys_cursor_width)
5488 rect.left += cursor_glyph->pixel_width - w->phys_cursor_width;
5478 rect.top = top; 5489 rect.top = top;
5479 rect.bottom = rect.top + h; 5490 rect.bottom = rect.top + h;
5480 rect.right = rect.left + w->phys_cursor_width; 5491 rect.right = rect.left + w->phys_cursor_width;
@@ -5556,7 +5567,7 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row,
5556 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), 5567 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
5557 width, row->height); 5568 width, row->height);
5558 } 5569 }
5559 else 5570 else /* HBAR_CURSOR */
5560 { 5571 {
5561 int dummy_x, dummy_y, dummy_h; 5572 int dummy_x, dummy_y, dummy_h;
5562 5573
@@ -5567,6 +5578,9 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row,
5567 5578
5568 get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x, 5579 get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
5569 &dummy_y, &dummy_h); 5580 &dummy_y, &dummy_h);
5581 if ((cursor_glyph->resolved_level & 1) != 0
5582 && cursor_glyph->pixel_width > w->phys_cursor_width)
5583 x += cursor_glyph->pixel_width - w->phys_cursor_width;
5570 w32_fill_area (f, hdc, cursor_color, x, 5584 w32_fill_area (f, hdc, cursor_color, x,
5571 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y + 5585 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
5572 row->height - width), 5586 row->height - width),
@@ -6333,7 +6347,7 @@ x_make_frame_visible (struct frame *f)
6333 RECT window_rect; 6347 RECT window_rect;
6334 6348
6335 /* Adjust vertical window position in order to avoid being 6349 /* Adjust vertical window position in order to avoid being
6336 covered by a task bar placed at the bottom of the desktop. */ 6350 covered by a taskbar placed at the bottom of the desktop. */
6337 SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); 6351 SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
6338 GetWindowRect (FRAME_W32_WINDOW (f), &window_rect); 6352 GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
6339 if (window_rect.bottom > workarea_rect.bottom 6353 if (window_rect.bottom > workarea_rect.bottom
diff --git a/src/w32term.h b/src/w32term.h
index 0fabe12819c..fb37550100e 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -22,6 +22,22 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include "frame.h" 22#include "frame.h"
23#include "atimer.h" 23#include "atimer.h"
24 24
25/* Stack alignment stuff. Every CALLBACK function should have the
26 ALIGN_STACK attribute if it manipulates Lisp objects, because
27 Windows x86 32-bit ABI only guarantees 4-byte stack alignment, and
28 that is what we will get when a Windows function calls us. The
29 ALIGN_STACK attribute forces GCC to emit a preamble code to
30 re-align the stack at function entry. Further details about this
31 can be found in http://www.peterstock.co.uk/games/mingw_sse/. */
32#ifdef __GNUC__
33# if USE_STACK_LISP_OBJECTS && !defined _WIN64 && !defined __x86_64__ \
34 && __GNUC__ + (__GNUC_MINOR__ > 1) >= 5
35# define ALIGN_STACK __attribute__((force_align_arg_pointer))
36# else
37# define ALIGN_STACK
38# endif /* USE_STACK_LISP_OBJECTS */
39#endif
40
25 41
26#define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0) 42#define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0)
27#define WHITE_PIX_DEFAULT(f) PALETTERGB(255,255,255) 43#define WHITE_PIX_DEFAULT(f) PALETTERGB(255,255,255)
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index d06586f973a..1c7b256988c 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -52,9 +52,9 @@ extern Lisp_Object Quniscribe;
52extern Lisp_Object Qopentype; 52extern Lisp_Object Qopentype;
53 53
54/* EnumFontFamiliesEx callback. */ 54/* EnumFontFamiliesEx callback. */
55static int CALLBACK add_opentype_font_name_to_list (ENUMLOGFONTEX *, 55static int CALLBACK ALIGN_STACK add_opentype_font_name_to_list (ENUMLOGFONTEX *,
56 NEWTEXTMETRICEX *, 56 NEWTEXTMETRICEX *,
57 DWORD, LPARAM); 57 DWORD, LPARAM);
58/* Used by uniscribe_otf_capability. */ 58/* Used by uniscribe_otf_capability. */
59static Lisp_Object otf_features (HDC context, char *table); 59static Lisp_Object otf_features (HDC context, char *table);
60 60
@@ -591,8 +591,8 @@ uniscribe_encode_char (struct font *font, int c)
591 Lisp_Object uniscribe_get_cache (Lisp_Object frame); 591 Lisp_Object uniscribe_get_cache (Lisp_Object frame);
592 void uniscribe_free_entity (Lisp_Object font_entity); 592 void uniscribe_free_entity (Lisp_Object font_entity);
593 int uniscribe_has_char (Lisp_Object entity, int c); 593 int uniscribe_has_char (Lisp_Object entity, int c);
594 int uniscribe_text_extents (struct font *font, unsigned *code, 594 void uniscribe_text_extents (struct font *font, unsigned *code,
595 int nglyphs, struct font_metrics *metrics); 595 int nglyphs, struct font_metrics *metrics);
596 int uniscribe_draw (struct glyph_string *s, int from, int to, 596 int uniscribe_draw (struct glyph_string *s, int from, int to,
597 int x, int y, int with_background); 597 int x, int y, int with_background);
598 598
@@ -613,7 +613,7 @@ uniscribe_encode_char (struct font *font, int c)
613/* Callback function for EnumFontFamiliesEx. 613/* Callback function for EnumFontFamiliesEx.
614 Adds the name of opentype fonts to a Lisp list (passed in as the 614 Adds the name of opentype fonts to a Lisp list (passed in as the
615 lParam arg). */ 615 lParam arg). */
616static int CALLBACK 616static int CALLBACK ALIGN_STACK
617add_opentype_font_name_to_list (ENUMLOGFONTEX *logical_font, 617add_opentype_font_name_to_list (ENUMLOGFONTEX *logical_font,
618 NEWTEXTMETRICEX *physical_font, 618 NEWTEXTMETRICEX *physical_font,
619 DWORD font_type, LPARAM list_object) 619 DWORD font_type, LPARAM list_object)
diff --git a/src/widget.c b/src/widget.c
index b5b76bb306b..baa6a2ab917 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -579,15 +579,6 @@ EmacsFrameResize (Widget widget)
579 if (true || frame_resize_pixelwise) 579 if (true || frame_resize_pixelwise)
580 { 580 {
581 int width, height; 581 int width, height;
582/** int width = (ew->core.width **/
583/** - FRAME_SCROLL_BAR_AREA_WIDTH (f) **/
584/** - FRAME_TOTAL_FRINGE_WIDTH (f) **/
585/** - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
586
587/** int height = (ew->core.height **/
588/** - FRAME_TOOLBAR_HEIGHT (f) **/
589/** - FRAME_SCROLL_BAR_AREA_HEIGHT (f) **/
590/** - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
591 582
592 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height); 583 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
593 change_frame_size (f, width, height, 0, 1, 0, 1); 584 change_frame_size (f, width, height, 0, 1, 0, 1);
diff --git a/src/window.c b/src/window.c
index ac685f6867f..0b0f2140a58 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4163,7 +4163,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4163 new_pixel_size = max (horflag 4163 new_pixel_size = max (horflag
4164 ? size 4164 ? size
4165 : (size 4165 : (size
4166/** - FRAME_TOP_MARGIN_HEIGHT (f) **/
4167 - ((FRAME_HAS_MINIBUF_P (f) 4166 - ((FRAME_HAS_MINIBUF_P (f)
4168 && !FRAME_MINIBUF_ONLY_P (f)) 4167 && !FRAME_MINIBUF_ONLY_P (f))
4169 ? FRAME_LINE_HEIGHT (f) : 0)), 4168 ? FRAME_LINE_HEIGHT (f) : 0)),
@@ -4175,7 +4174,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4175 new_size = max (horflag 4174 new_size = max (horflag
4176 ? size 4175 ? size
4177 : (size 4176 : (size
4178/** - FRAME_TOP_MARGIN (f) **/
4179 - ((FRAME_HAS_MINIBUF_P (f) 4177 - ((FRAME_HAS_MINIBUF_P (f)
4180 && !FRAME_MINIBUF_ONLY_P (f)) 4178 && !FRAME_MINIBUF_ONLY_P (f))
4181 ? 1 : 0)), 4179 ? 1 : 0)),
@@ -4796,10 +4794,10 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4796 block_input (); 4794 block_input ();
4797 window_resize_apply (r, 0); 4795 window_resize_apply (r, 0);
4798 4796
4799 w->total_lines = XFASTINT (w->new_total);
4800 w->top_line = r->top_line + r->total_lines;
4801 w->pixel_height = XFASTINT (w->new_pixel); 4797 w->pixel_height = XFASTINT (w->new_pixel);
4798 w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
4802 w->pixel_top = r->pixel_top + r->pixel_height; 4799 w->pixel_top = r->pixel_top + r->pixel_height;
4800 w->top_line = r->top_line + r->total_lines;
4803 4801
4804 fset_redisplay (f); 4802 fset_redisplay (f);
4805 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4803 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
@@ -5916,6 +5914,8 @@ and redisplay normally--don't erase and redraw the frame. */)
5916 w->start_at_line_beg = (bytepos == BEGV_BYTE 5914 w->start_at_line_beg = (bytepos == BEGV_BYTE
5917 || FETCH_BYTE (bytepos - 1) == '\n'); 5915 || FETCH_BYTE (bytepos - 1) == '\n');
5918 5916
5917 wset_redisplay (w);
5918
5919 return Qnil; 5919 return Qnil;
5920} 5920}
5921 5921
@@ -6124,6 +6124,7 @@ the return value is nil. Otherwise the value is t. */)
6124 Lisp_Object frame; 6124 Lisp_Object frame;
6125 struct frame *f; 6125 struct frame *f;
6126 ptrdiff_t old_point = -1; 6126 ptrdiff_t old_point = -1;
6127 USE_SAFE_ALLOCA;
6127 6128
6128 CHECK_WINDOW_CONFIGURATION (configuration); 6129 CHECK_WINDOW_CONFIGURATION (configuration);
6129 6130
@@ -6231,8 +6232,8 @@ the return value is nil. Otherwise the value is t. */)
6231 really like to do is to free only those matrices not reused 6232 really like to do is to free only those matrices not reused
6232 below. */ 6233 below. */
6233 root_window = XWINDOW (FRAME_ROOT_WINDOW (f)); 6234 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
6234 leaf_windows = alloca (count_windows (root_window) 6235 int nwindows = count_windows (root_window);
6235 * sizeof *leaf_windows); 6236 SAFE_NALLOCA (leaf_windows, 1, nwindows);
6236 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0); 6237 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
6237 6238
6238 /* Kludge Alert! 6239 /* Kludge Alert!
@@ -6456,424 +6457,11 @@ the return value is nil. Otherwise the value is t. */)
6456 Vminibuf_scroll_window = data->minibuf_scroll_window; 6457 Vminibuf_scroll_window = data->minibuf_scroll_window;
6457 minibuf_selected_window = data->minibuf_selected_window; 6458 minibuf_selected_window = data->minibuf_selected_window;
6458 6459
6460 SAFE_FREE ();
6459 return (FRAME_LIVE_P (f) ? Qt : Qnil); 6461 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6460} 6462}
6461 6463
6462 6464
6463#if 0
6464DEFUN ("set-window-configuration", Fset_window_configuration,
6465 Sset_window_configuration, 1, 1, 0,
6466 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
6467CONFIGURATION must be a value previously returned
6468by `current-window-configuration' (which see).
6469If CONFIGURATION was made from a frame that is now deleted,
6470only frame-independent values can be restored. In this case,
6471the return value is nil. Otherwise the value is t. */)
6472 (Lisp_Object configuration)
6473{
6474 register struct save_window_data *data;
6475 struct Lisp_Vector *saved_windows;
6476 Lisp_Object new_current_buffer;
6477 Lisp_Object frame;
6478 struct frame *f;
6479 ptrdiff_t old_point = -1;
6480
6481 CHECK_WINDOW_CONFIGURATION (configuration);
6482
6483 data = (struct save_window_data *) XVECTOR (configuration);
6484 saved_windows = XVECTOR (data->saved_windows);
6485
6486 new_current_buffer = data->current_buffer;
6487 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
6488 new_current_buffer = Qnil;
6489 else
6490 {
6491 if (XBUFFER (new_current_buffer) == current_buffer)
6492 /* The code further down "preserves point" by saving here PT in
6493 old_point and then setting it later back into PT. When the
6494 current-selected-window and the final-selected-window both show
6495 the current buffer, this suffers from the problem that the
6496 current PT is the window-point of the current-selected-window,
6497 while the final PT is the point of the final-selected-window, so
6498 this copy from one PT to the other would end up moving the
6499 window-point of the final-selected-window to the window-point of
6500 the current-selected-window. So we have to be careful which
6501 point of the current-buffer we copy into old_point. */
6502 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6503 && WINDOWP (selected_window)
6504 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
6505 && !EQ (selected_window, data->current_window))
6506 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6507 else
6508 old_point = PT;
6509 else
6510 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6511 point in new_current_buffer as of the last time this buffer was
6512 used. This can be non-deterministic since it can be changed by
6513 things like jit-lock by mere temporary selection of some random
6514 window that happens to show this buffer.
6515 So if possible we want this arbitrary choice of "which point" to
6516 be the one from the to-be-selected-window so as to prevent this
6517 window's cursor from being copied from another window. */
6518 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6519 /* If current_window = selected_window, its point is in BUF_PT. */
6520 && !EQ (selected_window, data->current_window))
6521 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6522 else
6523 old_point = BUF_PT (XBUFFER (new_current_buffer));
6524 }
6525
6526 frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
6527 f = XFRAME (frame);
6528
6529 /* If f is a dead frame, don't bother rebuilding its window tree.
6530 However, there is other stuff we should still try to do below. */
6531 if (FRAME_LIVE_P (f))
6532 {
6533 Lisp_Object window;
6534 Lisp_Object dead_windows = Qnil;
6535 register Lisp_Object tem, par, pers;
6536 register struct window *w;
6537 register struct saved_window *p;
6538 struct window *root_window;
6539 struct window **leaf_windows;
6540 int n_leaf_windows;
6541 ptrdiff_t k;
6542 int i, n;
6543 ptrdiff_t count = SPECPDL_INDEX ();
6544 /* If the frame has been resized since this window configuration was
6545 made, we change the frame to the size specified in the
6546 configuration, restore the configuration, and then resize it
6547 back. We keep track of the prevailing height in these variables. */
6548 int previous_frame_text_height = FRAME_TEXT_HEIGHT (f);
6549 int previous_frame_text_width = FRAME_TEXT_WIDTH (f);
6550 /* int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); */
6551 /* int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); */
6552 /* int previous_frame_lines = FRAME_LINES (f); */
6553 /* int previous_frame_cols = FRAME_COLS (f); */
6554 int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
6555 int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
6556
6557 /* Don't do this within the main loop below: This may call Lisp
6558 code and is thus potentially unsafe while input is blocked. */
6559 for (k = 0; k < saved_windows->header.size; k++)
6560 {
6561 p = SAVED_WINDOW_N (saved_windows, k);
6562 window = p->window;
6563 w = XWINDOW (window);
6564 if (BUFFERP (w->contents)
6565 && !EQ (w->contents, p->buffer)
6566 && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6567 /* If a window we restore gets another buffer, record the
6568 window's old buffer. */
6569 call1 (Qrecord_window_buffer, window);
6570 }
6571
6572 /* Consider frame unofficial, temporarily. */
6573 f->official = false;
6574 /* The mouse highlighting code could get screwed up
6575 if it runs during this. */
6576 block_input ();
6577
6578 if (data->frame_text_width != previous_frame_text_width
6579 || data->frame_text_height != previous_frame_text_height)
6580 /* Make frame size fit the one in data, so window sizes restored
6581 from data match those of the frame. */
6582 adjust_frame_size (f, data->frame_text_width,
6583 data->frame_text_height, 5, 0);
6584
6585 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
6586 {
6587#ifdef HAVE_WINDOW_SYSTEM
6588 if (FRAME_WINDOW_P (f))
6589 x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
6590 make_number (0));
6591 else /* TTY or MSDOS */
6592#endif
6593 set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
6594 make_number (0));
6595 }
6596#ifdef HAVE_WINDOW_SYSTEM
6597 if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines)
6598 x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
6599 make_number (0));
6600#endif
6601
6602 /* "Swap out" point from the selected window's buffer
6603 into the window itself. (Normally the pointm of the selected
6604 window holds garbage.) We do this now, before
6605 restoring the window contents, and prevent it from
6606 being done later on when we select a new window. */
6607 if (! NILP (XWINDOW (selected_window)->contents))
6608 {
6609 w = XWINDOW (selected_window);
6610 set_marker_both (w->pointm,
6611 w->contents,
6612 BUF_PT (XBUFFER (w->contents)),
6613 BUF_PT_BYTE (XBUFFER (w->contents)));
6614 }
6615
6616 fset_redisplay (f);
6617 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
6618
6619 /* Problem: Freeing all matrices and later allocating them again
6620 is a serious redisplay flickering problem. What we would
6621 really like to do is to free only those matrices not reused
6622 below. */
6623 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
6624 leaf_windows = alloca (count_windows (root_window)
6625 * sizeof *leaf_windows);
6626 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
6627
6628 /* Kludge Alert!
6629 Mark all windows now on frame as "deleted".
6630 Restoring the new configuration "undeletes" any that are in it.
6631
6632 Save their current buffers in their height fields, since we may
6633 need it later, if a buffer saved in the configuration is now
6634 dead. */
6635 delete_all_child_windows (FRAME_ROOT_WINDOW (f));
6636
6637 for (k = 0; k < saved_windows->header.size; k++)
6638 {
6639 p = SAVED_WINDOW_N (saved_windows, k);
6640 window = p->window;
6641 w = XWINDOW (window);
6642 wset_next (w, Qnil);
6643
6644 if (!NILP (p->parent))
6645 wset_parent
6646 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window);
6647 else
6648 wset_parent (w, Qnil);
6649
6650 if (!NILP (p->prev))
6651 {
6652 wset_prev
6653 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window);
6654 wset_next (XWINDOW (w->prev), p->window);
6655 }
6656 else
6657 {
6658 wset_prev (w, Qnil);
6659 if (!NILP (w->parent))
6660 wset_combination (XWINDOW (w->parent),
6661 (XINT (p->total_cols)
6662 != XWINDOW (w->parent)->total_cols),
6663 p->window);
6664 }
6665
6666 /* If we squirreled away the buffer, restore it now. */
6667 if (BUFFERP (w->combination_limit))
6668 wset_buffer (w, w->combination_limit);
6669 w->pixel_left = XFASTINT (p->pixel_left);
6670 w->pixel_top = XFASTINT (p->pixel_top);
6671 w->pixel_width = XFASTINT (p->pixel_width);
6672 w->pixel_height = XFASTINT (p->pixel_height);
6673 w->left_col = XFASTINT (p->left_col);
6674 w->top_line = XFASTINT (p->top_line);
6675 w->total_cols = XFASTINT (p->total_cols);
6676 w->total_lines = XFASTINT (p->total_lines);
6677 wset_normal_cols (w, p->normal_cols);
6678 wset_normal_lines (w, p->normal_lines);
6679 w->hscroll = XFASTINT (p->hscroll);
6680 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
6681 w->min_hscroll = XFASTINT (p->min_hscroll);
6682 w->hscroll_whole = XFASTINT (p->hscroll_whole);
6683 wset_display_table (w, p->display_table);
6684 w->left_margin_cols = XINT (p->left_margin_cols);
6685 w->right_margin_cols = XINT (p->right_margin_cols);
6686 w->left_fringe_width = XINT (p->left_fringe_width);
6687 w->right_fringe_width = XINT (p->right_fringe_width);
6688 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6689 w->scroll_bar_width = XINT (p->scroll_bar_width);
6690 w->scroll_bar_height = XINT (p->scroll_bar_height);
6691 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6692 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6693 wset_dedicated (w, p->dedicated);
6694 wset_combination_limit (w, p->combination_limit);
6695 /* Restore any window parameters that have been saved.
6696 Parameters that have not been saved are left alone. */
6697 for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
6698 {
6699 pers = XCAR (tem);
6700 if (CONSP (pers))
6701 {
6702 if (NILP (XCDR (pers)))
6703 {
6704 par = Fassq (XCAR (pers), w->window_parameters);
6705 if (CONSP (par) && !NILP (XCDR (par)))
6706 /* Reset a parameter to nil if and only if it
6707 has a non-nil association. Don't make new
6708 associations. */
6709 Fsetcdr (par, Qnil);
6710 }
6711 else
6712 /* Always restore a non-nil value. */
6713 Fset_window_parameter (window, XCAR (pers), XCDR (pers));
6714 }
6715 }
6716
6717 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6718 /* If saved buffer is alive, install it. */
6719 {
6720 wset_buffer (w, p->buffer);
6721 w->start_at_line_beg = !NILP (p->start_at_line_beg);
6722 set_marker_restricted (w->start, p->start, w->contents);
6723 set_marker_restricted (w->pointm, p->pointm, w->contents);
6724 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
6725 /* As documented in Fcurrent_window_configuration, don't
6726 restore the location of point in the buffer which was
6727 current when the window configuration was recorded. */
6728 if (!EQ (p->buffer, new_current_buffer)
6729 && XBUFFER (p->buffer) == current_buffer)
6730 Fgoto_char (w->pointm);
6731 }
6732 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
6733 /* Keep window's old buffer; make sure the markers are real. */
6734 {
6735 /* Set window markers at start of visible range. */
6736 if (XMARKER (w->start)->buffer == 0)
6737 set_marker_restricted_both (w->start, w->contents, 0, 0);
6738 if (XMARKER (w->pointm)->buffer == 0)
6739 set_marker_restricted_both
6740 (w->pointm, w->contents,
6741 BUF_PT (XBUFFER (w->contents)),
6742 BUF_PT_BYTE (XBUFFER (w->contents)));
6743 if (XMARKER (w->old_pointm)->buffer == 0)
6744 set_marker_restricted_both
6745 (w->old_pointm, w->contents,
6746 BUF_PT (XBUFFER (w->contents)),
6747 BUF_PT_BYTE (XBUFFER (w->contents)));
6748 w->start_at_line_beg = 1;
6749 }
6750 else if (!NILP (w->start))
6751 /* Leaf window has no live buffer, get one. */
6752 {
6753 /* Get the buffer via other_buffer_safely in order to
6754 avoid showing an unimportant buffer and, if necessary, to
6755 recreate *scratch* in the course (part of Juanma's bs-show
6756 scenario from March 2011). */
6757 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
6758 /* This will set the markers to beginning of visible
6759 range. */
6760 set_marker_restricted_both (w->start, w->contents, 0, 0);
6761 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
6762 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
6763 w->start_at_line_beg = 1;
6764 if (!NILP (w->dedicated))
6765 /* Record this window as dead. */
6766 dead_windows = Fcons (window, dead_windows);
6767 /* Make sure window is no more dedicated. */
6768 wset_dedicated (w, Qnil);
6769 }
6770 }
6771
6772 fset_root_window (f, data->root_window);
6773 /* Arrange *not* to restore point in the buffer that was
6774 current when the window configuration was saved. */
6775 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6776 set_marker_restricted (XWINDOW (data->current_window)->pointm,
6777 make_number (old_point),
6778 XWINDOW (data->current_window)->contents);
6779
6780 /* In the following call to `select-window', prevent "swapping out
6781 point" in the old selected window using the buffer that has
6782 been restored into it. We already swapped out that point from
6783 that window's old buffer.
6784
6785 Do not record the buffer here. We do that in a separate call
6786 to select_window below. See also Bug#16207. */
6787 select_window (data->current_window, Qt, 1);
6788 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6789 last_selected_window)
6790 = selected_window;
6791
6792 if (NILP (data->focus_frame)
6793 || (FRAMEP (data->focus_frame)
6794 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
6795 Fredirect_frame_focus (frame, data->focus_frame);
6796
6797 /* Set the frame size to the value it had before this function. */
6798 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
6799 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
6800 adjust_frame_size (f, previous_frame_text_width,
6801 previous_frame_text_height, 5, 0);
6802
6803 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
6804 {
6805#ifdef HAVE_WINDOW_SYSTEM
6806 if (FRAME_WINDOW_P (f))
6807 x_set_menu_bar_lines (f,
6808 make_number (previous_frame_menu_bar_lines),
6809 make_number (0));
6810 else /* TTY or MSDOS */
6811#endif
6812 set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines),
6813 make_number (0));
6814 }
6815#ifdef HAVE_WINDOW_SYSTEM
6816 if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f))
6817 x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines),
6818 make_number (0));
6819#endif
6820
6821 /* Now, free glyph matrices in windows that were not reused. */
6822 for (i = n = 0; i < n_leaf_windows; ++i)
6823 {
6824 if (NILP (leaf_windows[i]->contents))
6825 free_window_matrices (leaf_windows[i]);
6826 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
6827 ++n;
6828 }
6829
6830 /* Make frame official again and apply frame size changes if
6831 needed. */
6832 f->official = true;
6833 adjust_frame_size (f, -1, -1, 1, 0);
6834
6835 adjust_frame_glyphs (f);
6836 unblock_input ();
6837
6838 /* Scan dead buffer windows. */
6839 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
6840 {
6841 window = XCAR (dead_windows);
6842 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
6843 delete_deletable_window (window);
6844 }
6845
6846 /* Record the selected window's buffer here. The window should
6847 already be the selected one from the call above. */
6848 select_window (data->current_window, Qnil, 0);
6849
6850 /* Fselect_window will have made f the selected frame, so we
6851 reselect the proper frame here. Fhandle_switch_frame will change the
6852 selected window too, but that doesn't make the call to
6853 Fselect_window above totally superfluous; it still sets f's
6854 selected window. */
6855 if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
6856 do_switch_frame (data->selected_frame, 0, 0, Qnil);
6857
6858 run_window_configuration_change_hook (f);
6859 }
6860
6861 if (!NILP (new_current_buffer))
6862 {
6863 Fset_buffer (new_current_buffer);
6864 /* If the new current buffer doesn't appear in the selected
6865 window, go to its old point (see bug#12208). */
6866 if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6867 Fgoto_char (make_number (old_point));
6868 }
6869
6870 Vminibuf_scroll_window = data->minibuf_scroll_window;
6871 minibuf_selected_window = data->minibuf_selected_window;
6872
6873 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6874}
6875#endif
6876
6877void 6465void
6878restore_window_configuration (Lisp_Object configuration) 6466restore_window_configuration (Lisp_Object configuration)
6879{ 6467{
@@ -7374,9 +6962,7 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
7374 } 6962 }
7375 } 6963 }
7376 6964
7377#if (defined (HAVE_WINDOW_SYSTEM) \ 6965#if USE_HORIZONTAL_SCROLL_BARS
7378 && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \
7379 || defined (HAVE_NTGUI)))
7380 { 6966 {
7381 int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height))); 6967 int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height)));
7382 6968
@@ -7416,16 +7002,17 @@ DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
7416 doc: /* Set width and type of scroll bars of window WINDOW. 7002 doc: /* Set width and type of scroll bars of window WINDOW.
7417WINDOW must be a live window and defaults to the selected one. 7003WINDOW must be a live window and defaults to the selected one.
7418 7004
7419Second parameter WIDTH specifies the pixel width for the scroll bar. 7005Second parameter WIDTH specifies the pixel width for the vertical scroll
7006bar. If WIDTH is nil, use the scroll-bar width of WINDOW's frame.
7420Third parameter VERTICAL-TYPE specifies the type of the vertical scroll 7007Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
7421bar: left, right, or nil. If WIDTH is nil, use the frame's scroll-bar 7008bar: left, right, or nil. If VERTICAL-TYPE is t, this means use the
7422width. If VERTICAL-TYPE is t, use the frame's scroll-bar type. 7009frame's scroll-bar type.
7423 7010
7424Fourth parameter HEIGHT specifies the pixel height for the scroll bar. 7011Fourth parameter HEIGHT specifies the pixel height for the horizontal
7425Fifth parameter HORIZONTAL-TYPE specifies the type of the vertical 7012scroll bar. If HEIGHT is nil, use the scroll-bar height of WINDOW's
7426scroll bar: nil, bottom, or t. If HEIGHT is nil, use the frame's 7013frame. Fifth parameter HORIZONTAL-TYPE specifies the type of the
7427scroll-bar height. If HORIZONTAL-TYPE is t, use the frame's scroll-bar 7014horizontal scroll bar: nil, bottom, or t. If HORIZONTAL-TYPE is t, this
7428type. 7015means to use the frame's horizontal scroll-bar type.
7429 7016
7430Return t if scroll bars were actually changed and nil otherwise. */) 7017Return t if scroll bars were actually changed and nil otherwise. */)
7431 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, 7018 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
@@ -7443,17 +7030,22 @@ DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
7443 doc: /* Get width and type of scroll bars of window WINDOW. 7030 doc: /* Get width and type of scroll bars of window WINDOW.
7444WINDOW must be a live window and defaults to the selected one. 7031WINDOW must be a live window and defaults to the selected one.
7445 7032
7446Value is a list of the form (WIDTH COLS VERTICAL-TYPE HEIGHT LINES 7033Value is a list of the form (WIDTH COLUMNS VERTICAL-TYPE HEIGHT LINES
7447HORIZONTAL-TYPE). If WIDTH or HEIGHT is nil or TYPE is t, the window is 7034HORIZONTAL-TYPE). If WIDTH or HEIGHT is nil or VERTICAL-TYPE or
7448using the frame's corresponding value. */) 7035HORIZONTAL-TYPE is t, the window is using the frame's corresponding
7036value. */)
7449 (Lisp_Object window) 7037 (Lisp_Object window)
7450{ 7038{
7451 struct window *w = decode_live_window (window); 7039 struct window *w = decode_live_window (window);
7452 7040
7453 return Fcons (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)), 7041 return Fcons (((w->scroll_bar_width >= 0)
7042 ? make_number (w->scroll_bar_width)
7043 : Qnil),
7454 list5 (make_number (WINDOW_SCROLL_BAR_COLS (w)), 7044 list5 (make_number (WINDOW_SCROLL_BAR_COLS (w)),
7455 w->vertical_scroll_bar_type, 7045 w->vertical_scroll_bar_type,
7456 make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (w)), 7046 ((w->scroll_bar_height >= 0)
7047 ? make_number (w->scroll_bar_height)
7048 : Qnil),
7457 make_number (WINDOW_SCROLL_BAR_LINES (w)), 7049 make_number (WINDOW_SCROLL_BAR_LINES (w)),
7458 w->horizontal_scroll_bar_type)); 7050 w->horizontal_scroll_bar_type));
7459} 7051}
diff --git a/src/window.h b/src/window.h
index 7e1c7d619b9..ea5dddc9fc8 100644
--- a/src/window.h
+++ b/src/window.h
@@ -785,11 +785,17 @@ wset_next_buffers (struct window *w, Lisp_Object val)
785 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (W) \ 785 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (W) \
786 || WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W)) 786 || WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W))
787 787
788/* Say whether horizontal scroll bars are currently enabled for window
789 W. Horizontal scrollbars exist for toolkit versions only. */
790#if (defined (HAVE_WINDOW_SYSTEM) \ 788#if (defined (HAVE_WINDOW_SYSTEM) \
791 && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \ 789 && ((defined (USE_TOOLKIT_SCROLL_BARS) && !defined (HAVE_NS)) \
792 || defined (HAVE_NTGUI))) 790 || defined (HAVE_NTGUI)))
791# define USE_HORIZONTAL_SCROLL_BARS true
792#else
793# define USE_HORIZONTAL_SCROLL_BARS false
794#endif
795
796/* Say whether horizontal scroll bars are currently enabled for window
797 W. Horizontal scrollbars exist for toolkit versions only. */
798#if USE_HORIZONTAL_SCROLL_BARS
793#define WINDOW_HAS_HORIZONTAL_SCROLL_BAR(W) \ 799#define WINDOW_HAS_HORIZONTAL_SCROLL_BAR(W) \
794 ((WINDOW_PSEUDO_P (W) || MINI_NON_ONLY_WINDOW_P (W)) \ 800 ((WINDOW_PSEUDO_P (W) || MINI_NON_ONLY_WINDOW_P (W)) \
795 ? false \ 801 ? false \
diff --git a/src/xdisp.c b/src/xdisp.c
index a1e78f1129a..7c3aaa2042e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1144,7 +1144,7 @@ window_box_left_offset (struct window *w, enum glyph_row_area area)
1144 area AREA of window W. ANY_AREA means return the right edge of the 1144 area AREA of window W. ANY_AREA means return the right edge of the
1145 whole window, to the left of the right fringe of W. */ 1145 whole window, to the left of the right fringe of W. */
1146 1146
1147int 1147static int
1148window_box_right_offset (struct window *w, enum glyph_row_area area) 1148window_box_right_offset (struct window *w, enum glyph_row_area area)
1149{ 1149{
1150 /* Don't return more than the window's pixel width. */ 1150 /* Don't return more than the window's pixel width. */
@@ -1455,15 +1455,19 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1455 glyph. */ 1455 glyph. */
1456 int top_x = it.current_x; 1456 int top_x = it.current_x;
1457 int top_y = it.current_y; 1457 int top_y = it.current_y;
1458 /* Calling line_bottom_y may change it.method, it.position, etc. */
1459 enum it_method it_method = it.method;
1460 int bottom_y = (last_height = 0, line_bottom_y (&it));
1461 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w); 1458 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1459 int bottom_y;
1460 struct it save_it;
1461 void *save_it_data = NULL;
1462 1462
1463 /* Calling line_bottom_y may change it.method, it.position, etc. */
1464 SAVE_IT (save_it, it, save_it_data);
1465 last_height = 0;
1466 bottom_y = line_bottom_y (&it);
1463 if (top_y < window_top_y) 1467 if (top_y < window_top_y)
1464 visible_p = bottom_y > window_top_y; 1468 visible_p = bottom_y > window_top_y;
1465 else if (top_y < it.last_visible_y) 1469 else if (top_y < it.last_visible_y)
1466 visible_p = true; 1470 visible_p = 1;
1467 if (bottom_y >= it.last_visible_y 1471 if (bottom_y >= it.last_visible_y
1468 && it.bidi_p && it.bidi_it.scan_dir == -1 1472 && it.bidi_p && it.bidi_it.scan_dir == -1
1469 && IT_CHARPOS (it) < charpos) 1473 && IT_CHARPOS (it) < charpos)
@@ -1476,7 +1480,6 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1476 move_it_to again with a slightly larger vertical limit, 1480 move_it_to again with a slightly larger vertical limit,
1477 and see if it actually moved vertically; if it did, we 1481 and see if it actually moved vertically; if it did, we
1478 didn't really reach CHARPOS, which is beyond window end. */ 1482 didn't really reach CHARPOS, which is beyond window end. */
1479 struct it save_it = it;
1480 /* Why 10? because we don't know how many canonical lines 1483 /* Why 10? because we don't know how many canonical lines
1481 will the height of the next line(s) be. So we guess. */ 1484 will the height of the next line(s) be. So we guess. */
1482 int ten_more_lines = 10 * default_line_pixel_height (w); 1485 int ten_more_lines = 10 * default_line_pixel_height (w);
@@ -1486,11 +1489,11 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1486 if (it.current_y > top_y) 1489 if (it.current_y > top_y)
1487 visible_p = 0; 1490 visible_p = 0;
1488 1491
1489 it = save_it;
1490 } 1492 }
1493 RESTORE_IT (&it, &save_it, save_it_data);
1491 if (visible_p) 1494 if (visible_p)
1492 { 1495 {
1493 if (it_method == GET_FROM_DISPLAY_VECTOR) 1496 if (it.method == GET_FROM_DISPLAY_VECTOR)
1494 { 1497 {
1495 /* We stopped on the last glyph of a display vector. 1498 /* We stopped on the last glyph of a display vector.
1496 Try and recompute. Hack alert! */ 1499 Try and recompute. Hack alert! */
@@ -2174,7 +2177,10 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
2174 2177
2175 if (s->x > r.x) 2178 if (s->x > r.x)
2176 { 2179 {
2177 r.width -= s->x - r.x; 2180 if (r.width >= s->x - r.x)
2181 r.width -= s->x - r.x;
2182 else /* R2L hscrolled row with cursor outside text area */
2183 r.width = 0;
2178 r.x = s->x; 2184 r.x = s->x;
2179 } 2185 }
2180 r.width = min (r.width, glyph->pixel_width); 2186 r.width = min (r.width, glyph->pixel_width);
@@ -2535,7 +2541,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2535 gy = 0; 2541 gy = 0;
2536 /* The bottom divider prevails. */ 2542 /* The bottom divider prevails. */
2537 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w); 2543 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2538 goto add_edge;; 2544 goto add_edge;
2539 2545
2540 case ON_BOTTOM_DIVIDER: 2546 case ON_BOTTOM_DIVIDER:
2541 gx = 0; 2547 gx = 0;
@@ -2623,15 +2629,14 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2623 { 2629 {
2624 ptrdiff_t i; 2630 ptrdiff_t i;
2625 ptrdiff_t count = SPECPDL_INDEX (); 2631 ptrdiff_t count = SPECPDL_INDEX ();
2626 struct gcpro gcpro1; 2632 Lisp_Object *args;
2627 Lisp_Object *args = alloca (nargs * word_size); 2633 USE_SAFE_ALLOCA;
2634 SAFE_ALLOCA_LISP (args, nargs);
2628 2635
2629 args[0] = func; 2636 args[0] = func;
2630 for (i = 1; i < nargs; i++) 2637 for (i = 1; i < nargs; i++)
2631 args[i] = va_arg (ap, Lisp_Object); 2638 args[i] = va_arg (ap, Lisp_Object);
2632 2639
2633 GCPRO1 (args[0]);
2634 gcpro1.nvars = nargs;
2635 specbind (Qinhibit_redisplay, Qt); 2640 specbind (Qinhibit_redisplay, Qt);
2636 if (inhibit_quit) 2641 if (inhibit_quit)
2637 specbind (Qinhibit_quit, Qt); 2642 specbind (Qinhibit_quit, Qt);
@@ -2639,7 +2644,7 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2639 so there is no possibility of wanting to redisplay. */ 2644 so there is no possibility of wanting to redisplay. */
2640 val = internal_condition_case_n (Ffuncall, nargs, args, Qt, 2645 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2641 safe_eval_handler); 2646 safe_eval_handler);
2642 UNGCPRO; 2647 SAFE_FREE ();
2643 val = unbind_to (count, val); 2648 val = unbind_to (count, val);
2644 } 2649 }
2645 2650
@@ -2990,12 +2995,8 @@ init_iterator (struct it *it, struct window *w,
2990 2995
2991 /* If we truncate lines, leave room for the truncation glyph(s) at 2996 /* If we truncate lines, leave room for the truncation glyph(s) at
2992 the right margin. Otherwise, leave room for the continuation 2997 the right margin. Otherwise, leave room for the continuation
2993 glyph(s). Done only if the window has no fringes. Since we 2998 glyph(s). Done only if the window has no right fringe. */
2994 don't know at this point whether there will be any R2L lines in 2999 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
2995 the window, we reserve space for truncation/continuation glyphs
2996 even if only one of the fringes is absent. */
2997 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2998 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2999 { 3000 {
3000 if (it->line_wrap == TRUNCATE) 3001 if (it->line_wrap == TRUNCATE)
3001 it->last_visible_x -= it->truncation_pixel_width; 3002 it->last_visible_x -= it->truncation_pixel_width;
@@ -3060,6 +3061,19 @@ init_iterator (struct it *it, struct window *w,
3060 iterator. */ 3061 iterator. */
3061 if (it->bidi_p) 3062 if (it->bidi_p)
3062 { 3063 {
3064 /* Since we don't know at this point whether there will be
3065 any R2L lines in the window, we reserve space for
3066 truncation/continuation glyphs even if only the left
3067 fringe is absent. */
3068 if (base_face_id == DEFAULT_FACE_ID
3069 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
3070 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
3071 {
3072 if (it->line_wrap == TRUNCATE)
3073 it->last_visible_x -= it->truncation_pixel_width;
3074 else
3075 it->last_visible_x -= it->continuation_pixel_width;
3076 }
3063 /* Note the paragraph direction that this buffer wants to 3077 /* Note the paragraph direction that this buffer wants to
3064 use. */ 3078 use. */
3065 if (EQ (BVAR (current_buffer, bidi_paragraph_direction), 3079 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
@@ -3413,6 +3427,48 @@ handle_stop (struct it *it)
3413 if (it->selective_display_ellipsis_p) 3427 if (it->selective_display_ellipsis_p)
3414 it->saved_face_id = it->face_id; 3428 it->saved_face_id = it->face_id;
3415 3429
3430 /* Here's the description of the semantics of, and the logic behind,
3431 the various HANDLED_* statuses:
3432
3433 HANDLED_NORMALLY means the handler did its job, and the loop
3434 should proceed to calling the next handler in order.
3435
3436 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3437 change in the properties and overlays at current position, so the
3438 loop should be restarted, to re-invoke the handlers that were
3439 already called. This happens when fontification-functions were
3440 called by handle_fontified_prop, and actually fontified
3441 something. Another case where HANDLED_RECOMPUTE_PROPS is
3442 returned is when we discover overlay strings that need to be
3443 displayed right away. The loop below will continue for as long
3444 as the status is HANDLED_RECOMPUTE_PROPS.
3445
3446 HANDLED_RETURN means return immediately to the caller, to
3447 continue iteration without calling any further handlers. This is
3448 used when we need to act on some property right away, for example
3449 when we need to display the ellipsis or a replacing display
3450 property, such as display string or image.
3451
3452 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3453 consumed, and the handler switched to the next overlay string.
3454 This signals the loop below to refrain from looking for more
3455 overlays before all the overlay strings of the current overlay
3456 are processed.
3457
3458 Some of the handlers called by the loop push the iterator state
3459 onto the stack (see 'push_it'), and arrange for the iteration to
3460 continue with another object, such as an image, a display string,
3461 or an overlay string. In most such cases, it->stop_charpos is
3462 set to the first character of the string, so that when the
3463 iteration resumes, this function will immediately be called
3464 again, to examine the properties at the beginning of the string.
3465
3466 When a display or overlay string is exhausted, the iterator state
3467 is popped (see 'pop_it'), and iteration continues with the
3468 previous object. Again, in many such cases this function is
3469 called again to find the next position where properties might
3470 change. */
3471
3416 do 3472 do
3417 { 3473 {
3418 handled = HANDLED_NORMALLY; 3474 handled = HANDLED_NORMALLY;
@@ -3614,6 +3670,7 @@ next_overlay_change (ptrdiff_t pos)
3614 ptrdiff_t i, noverlays; 3670 ptrdiff_t i, noverlays;
3615 ptrdiff_t endpos; 3671 ptrdiff_t endpos;
3616 Lisp_Object *overlays; 3672 Lisp_Object *overlays;
3673 USE_SAFE_ALLOCA;
3617 3674
3618 /* Get all overlays at the given position. */ 3675 /* Get all overlays at the given position. */
3619 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1); 3676 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
@@ -3630,6 +3687,7 @@ next_overlay_change (ptrdiff_t pos)
3630 endpos = min (endpos, oendpos); 3687 endpos = min (endpos, oendpos);
3631 } 3688 }
3632 3689
3690 SAFE_FREE ();
3633 return endpos; 3691 return endpos;
3634} 3692}
3635 3693
@@ -5075,7 +5133,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
5075 5133
5076 if (it) 5134 if (it)
5077 { 5135 {
5078 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);; 5136 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5079 5137
5080 if (CONSP (XCDR (XCDR (spec)))) 5138 if (CONSP (XCDR (XCDR (spec))))
5081 { 5139 {
@@ -5690,10 +5748,11 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
5690 Lisp_Object overlay, window, str, invisible; 5748 Lisp_Object overlay, window, str, invisible;
5691 struct Lisp_Overlay *ov; 5749 struct Lisp_Overlay *ov;
5692 ptrdiff_t start, end; 5750 ptrdiff_t start, end;
5693 ptrdiff_t size = 20;
5694 ptrdiff_t n = 0, i, j; 5751 ptrdiff_t n = 0, i, j;
5695 int invis_p; 5752 int invis_p;
5696 struct overlay_entry *entries = alloca (size * sizeof *entries); 5753 struct overlay_entry entriesbuf[20];
5754 ptrdiff_t size = ARRAYELTS (entriesbuf);
5755 struct overlay_entry *entries = entriesbuf;
5697 USE_SAFE_ALLOCA; 5756 USE_SAFE_ALLOCA;
5698 5757
5699 if (charpos <= 0) 5758 if (charpos <= 0)
@@ -9694,6 +9753,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9694 back_to_previous_visible_line_start (it); 9753 back_to_previous_visible_line_start (it);
9695 it->vpos--; 9754 it->vpos--;
9696 } 9755 }
9756 reseat_1 (it, it->current.pos, 1);
9697 } 9757 }
9698 else 9758 else
9699 RESTORE_IT (it, it, it2data); 9759 RESTORE_IT (it, it, it2data);
@@ -10147,9 +10207,9 @@ message3 (Lisp_Object m)
10147 { 10207 {
10148 ptrdiff_t nbytes = SBYTES (m); 10208 ptrdiff_t nbytes = SBYTES (m);
10149 bool multibyte = STRING_MULTIBYTE (m); 10209 bool multibyte = STRING_MULTIBYTE (m);
10210 char *buffer;
10150 USE_SAFE_ALLOCA; 10211 USE_SAFE_ALLOCA;
10151 char *buffer = SAFE_ALLOCA (nbytes); 10212 SAFE_ALLOCA_STRING (buffer, m);
10152 memcpy (buffer, SDATA (m), nbytes);
10153 message_dolog (buffer, nbytes, 1, multibyte); 10213 message_dolog (buffer, nbytes, 1, multibyte);
10154 SAFE_FREE (); 10214 SAFE_FREE ();
10155 } 10215 }
@@ -10351,11 +10411,13 @@ vmessage (const char *m, va_list ap)
10351 { 10411 {
10352 ptrdiff_t len; 10412 ptrdiff_t len;
10353 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f); 10413 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10354 char *message_buf = alloca (maxsize + 1); 10414 USE_SAFE_ALLOCA;
10415 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10355 10416
10356 len = doprnt (message_buf, maxsize, m, 0, ap); 10417 len = doprnt (message_buf, maxsize, m, 0, ap);
10357 10418
10358 message3 (make_string (message_buf, len)); 10419 message3 (make_string (message_buf, len));
10420 SAFE_FREE ();
10359 } 10421 }
10360 else 10422 else
10361 message1 (0); 10423 message1 (0);
@@ -11987,11 +12049,11 @@ static void
11987build_desired_tool_bar_string (struct frame *f) 12049build_desired_tool_bar_string (struct frame *f)
11988{ 12050{
11989 int i, size, size_needed; 12051 int i, size, size_needed;
11990 struct gcpro gcpro1, gcpro2, gcpro3; 12052 struct gcpro gcpro1, gcpro2;
11991 Lisp_Object image, plist, props; 12053 Lisp_Object image, plist;
11992 12054
11993 image = plist = props = Qnil; 12055 image = plist = Qnil;
11994 GCPRO3 (image, plist, props); 12056 GCPRO2 (image, plist);
11995 12057
11996 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so. 12058 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11997 Otherwise, make a new string. */ 12059 Otherwise, make a new string. */
@@ -12010,9 +12072,12 @@ build_desired_tool_bar_string (struct frame *f)
12010 (f, Fmake_string (make_number (size_needed), make_number (' '))); 12072 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12011 else 12073 else
12012 { 12074 {
12013 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil); 12075 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12076 struct gcpro gcpro1;
12077 GCPRO1 (props);
12014 Fremove_text_properties (make_number (0), make_number (size), 12078 Fremove_text_properties (make_number (0), make_number (size),
12015 props, f->desired_tool_bar_string); 12079 props, f->desired_tool_bar_string);
12080 UNGCPRO;
12016 } 12081 }
12017 12082
12018 /* Put a `display' property on the string for the images to display, 12083 /* Put a `display' property on the string for the images to display,
@@ -12123,8 +12188,10 @@ build_desired_tool_bar_string (struct frame *f)
12123 the start of this item's properties in the tool-bar items 12188 the start of this item's properties in the tool-bar items
12124 vector. */ 12189 vector. */
12125 image = Fcons (Qimage, plist); 12190 image = Fcons (Qimage, plist);
12126 props = list4 (Qdisplay, image, 12191 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12127 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS)); 12192 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12193 struct gcpro gcpro1;
12194 GCPRO1 (props);
12128 12195
12129 /* Let the last image hide all remaining spaces in the tool bar 12196 /* Let the last image hide all remaining spaces in the tool bar
12130 string. The string can be longer than needed when we reuse a 12197 string. The string can be longer than needed when we reuse a
@@ -12135,6 +12202,7 @@ build_desired_tool_bar_string (struct frame *f)
12135 end = i + 1; 12202 end = i + 1;
12136 Fadd_text_properties (make_number (i), make_number (end), 12203 Fadd_text_properties (make_number (i), make_number (end),
12137 props, f->desired_tool_bar_string); 12204 props, f->desired_tool_bar_string);
12205 UNGCPRO;
12138#undef PROP 12206#undef PROP
12139 } 12207 }
12140 12208
@@ -13506,6 +13574,12 @@ redisplay_internal (void)
13506 13574
13507 if (mode_line_update_needed (w)) 13575 if (mode_line_update_needed (w))
13508 w->update_mode_line = 1; 13576 w->update_mode_line = 1;
13577
13578 /* If reconsider_clip_changes above decided that the narrowing
13579 in the current buffer changed, make sure all other windows
13580 showing that buffer will be redisplayed. */
13581 if (current_buffer->clip_changed)
13582 bset_update_mode_line (current_buffer);
13509 } 13583 }
13510 13584
13511 /* Normally the message* functions will have already displayed and 13585 /* Normally the message* functions will have already displayed and
@@ -14929,6 +15003,10 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14929 If FORCE_P is non-zero, return 0 even if partial visible cursor row 15003 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14930 is higher than window. 15004 is higher than window.
14931 15005
15006 If CURRENT_MATRIX_P is non-zero, use the information from the
15007 window's current glyph matrix; otherwise use the desired glyph
15008 matrix.
15009
14932 A value of 0 means the caller should do scrolling 15010 A value of 0 means the caller should do scrolling
14933 as if point had gone off the screen. */ 15011 as if point had gone off the screen. */
14934 15012
@@ -16102,26 +16180,48 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16102 16180
16103 /* If someone specified a new starting point but did not insist, 16181 /* If someone specified a new starting point but did not insist,
16104 check whether it can be used. */ 16182 check whether it can be used. */
16105 if (w->optional_new_start 16183 if ((w->optional_new_start || window_frozen_p (w))
16106 && CHARPOS (startp) >= BEGV 16184 && CHARPOS (startp) >= BEGV
16107 && CHARPOS (startp) <= ZV) 16185 && CHARPOS (startp) <= ZV)
16108 { 16186 {
16187 ptrdiff_t it_charpos;
16188
16109 w->optional_new_start = 0; 16189 w->optional_new_start = 0;
16110 start_display (&it, w, startp); 16190 start_display (&it, w, startp);
16111 move_it_to (&it, PT, 0, it.last_visible_y, -1, 16191 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16112 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 16192 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16113 if (IT_CHARPOS (it) == PT) 16193 /* Record IT's position now, since line_bottom_y might change
16114 w->force_start = 1; 16194 that. */
16115 /* IT may overshoot PT if text at PT is invisible. */ 16195 it_charpos = IT_CHARPOS (it);
16116 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT) 16196 /* Make sure we set the force_start flag only if the cursor row
16117 w->force_start = 1; 16197 will be fully visible. Otherwise, the code under force_start
16198 label below will try to move point back into view, which is
16199 not what the code which sets optional_new_start wants. */
16200 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16201 && !w->force_start)
16202 {
16203 if (it_charpos == PT)
16204 w->force_start = 1;
16205 /* IT may overshoot PT if text at PT is invisible. */
16206 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16207 w->force_start = 1;
16208#ifdef GLYPH_DEBUG
16209 if (w->force_start)
16210 {
16211 if (window_frozen_p (w))
16212 debug_method_add (w, "set force_start from frozen window start");
16213 else
16214 debug_method_add (w, "set force_start from optional_new_start");
16215 }
16216#endif
16217 }
16118 } 16218 }
16119 16219
16120 force_start: 16220 force_start:
16121 16221
16122 /* Handle case where place to start displaying has been specified, 16222 /* Handle case where place to start displaying has been specified,
16123 unless the specified location is outside the accessible range. */ 16223 unless the specified location is outside the accessible range. */
16124 if (w->force_start || window_frozen_p (w)) 16224 if (w->force_start)
16125 { 16225 {
16126 /* We set this later on if we have to adjust point. */ 16226 /* We set this later on if we have to adjust point. */
16127 int new_vpos = -1; 16227 int new_vpos = -1;
@@ -16166,7 +16266,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16166 goto need_larger_matrices; 16266 goto need_larger_matrices;
16167 } 16267 }
16168 16268
16169 if (w->cursor.vpos < 0 && !window_frozen_p (w)) 16269 if (w->cursor.vpos < 0)
16170 { 16270 {
16171 /* If point does not appear, try to move point so it does 16271 /* If point does not appear, try to move point so it does
16172 appear. The desired matrix has been built above, so we 16272 appear. The desired matrix has been built above, so we
@@ -16259,6 +16359,11 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16259 } 16359 }
16260 */ 16360 */
16261 } 16361 }
16362 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, 0, 0))
16363 {
16364 clear_glyph_matrix (w->desired_matrix);
16365 goto try_to_scroll;
16366 }
16262 16367
16263#ifdef GLYPH_DEBUG 16368#ifdef GLYPH_DEBUG
16264 debug_method_add (w, "forced window start"); 16369 debug_method_add (w, "forced window start");
@@ -16323,7 +16428,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16323 || CHARPOS (startp) == BEGV 16428 || CHARPOS (startp) == BEGV
16324 || !window_outdated (w))) 16429 || !window_outdated (w)))
16325 { 16430 {
16326 int d1, d2, d3, d4, d5, d6; 16431 int d1, d2, d5, d6;
16432 int rtop, rbot;
16327 16433
16328 /* If first window line is a continuation line, and window start 16434 /* If first window line is a continuation line, and window start
16329 is inside the modified region, but the first change is before 16435 is inside the modified region, but the first change is before
@@ -16348,14 +16454,20 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16348 && compute_window_start_on_continuation_line (w) 16454 && compute_window_start_on_continuation_line (w)
16349 /* It doesn't make sense to force the window start like we 16455 /* It doesn't make sense to force the window start like we
16350 do at label force_start if it is already known that point 16456 do at label force_start if it is already known that point
16351 will not be visible in the resulting window, because 16457 will not be fully visible in the resulting window, because
16352 doing so will move point from its correct position 16458 doing so will move point from its correct position
16353 instead of scrolling the window to bring point into view. 16459 instead of scrolling the window to bring point into view.
16354 See bug#9324. */ 16460 See bug#9324. */
16355 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6)) 16461 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
16462 /* A very tall row could need more than the window height,
16463 in which case we accept that it is partially visible. */
16464 && (rtop != 0) == (rbot != 0))
16356 { 16465 {
16357 w->force_start = 1; 16466 w->force_start = 1;
16358 SET_TEXT_POS_FROM_MARKER (startp, w->start); 16467 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16468#ifdef GLYPH_DEBUG
16469 debug_method_add (w, "recomputed window start in continuation line");
16470#endif
16359 goto force_start; 16471 goto force_start;
16360 } 16472 }
16361 16473
@@ -18651,10 +18763,10 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18651 else if (glyphs == 1) 18763 else if (glyphs == 1)
18652 { 18764 {
18653 int area; 18765 int area;
18766 char s[SHRT_MAX + 4];
18654 18767
18655 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) 18768 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18656 { 18769 {
18657 char *s = alloca (row->used[area] + 4);
18658 int i; 18770 int i;
18659 18771
18660 for (i = 0; i < row->used[area]; ++i) 18772 for (i = 0; i < row->used[area]; ++i)
@@ -18807,7 +18919,7 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18807 struct buffer *buffer = XBUFFER (w->contents); 18919 struct buffer *buffer = XBUFFER (w->contents);
18808 struct buffer *old = current_buffer; 18920 struct buffer *old = current_buffer;
18809 const unsigned char *arrow_string = SDATA (overlay_arrow_string); 18921 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18810 int arrow_len = SCHARS (overlay_arrow_string); 18922 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
18811 const unsigned char *arrow_end = arrow_string + arrow_len; 18923 const unsigned char *arrow_end = arrow_string + arrow_len;
18812 const unsigned char *p; 18924 const unsigned char *p;
18813 struct it it; 18925 struct it it;
@@ -19328,7 +19440,18 @@ extend_face_to_end_of_line (struct it *it)
19328 19440
19329 for (row_width = 0, g = row_start; g < row_end; g++) 19441 for (row_width = 0, g = row_start; g < row_end; g++)
19330 row_width += g->pixel_width; 19442 row_width += g->pixel_width;
19331 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width; 19443
19444 /* FIXME: There are various minor display glitches in R2L
19445 rows when only one of the fringes is missing. The
19446 strange condition below produces the least bad effect. */
19447 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19448 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
19449 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
19450 stretch_width = window_box_width (it->w, TEXT_AREA);
19451 else
19452 stretch_width = it->last_visible_x - it->first_visible_x;
19453 stretch_width -= row_width;
19454
19332 if (stretch_width > 0) 19455 if (stretch_width > 0)
19333 { 19456 {
19334 stretch_ascent = 19457 stretch_ascent =
@@ -20469,9 +20592,17 @@ display_line (struct it *it)
20469 /* When the last glyph of an R2L row only fits 20592 /* When the last glyph of an R2L row only fits
20470 partially on the line, we need to set row->x to a 20593 partially on the line, we need to set row->x to a
20471 negative offset, so that the leftmost glyph is 20594 negative offset, so that the leftmost glyph is
20472 the one that is partially visible. */ 20595 the one that is partially visible. But if we are
20473 if (row->reversed_p && new_x > it->last_visible_x) 20596 going to produce the truncation glyph, this will
20474 row->x = it->last_visible_x - new_x; 20597 be taken care of in produce_special_glyphs. */
20598 if (row->reversed_p
20599 && new_x > it->last_visible_x
20600 && !(it->line_wrap == TRUNCATE
20601 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
20602 {
20603 eassert (FRAME_WINDOW_P (it->f));
20604 row->x = it->last_visible_x - new_x;
20605 }
20475 } 20606 }
20476 else 20607 else
20477 { 20608 {
@@ -20545,7 +20676,10 @@ display_line (struct it *it)
20545 that they are cropped at the right edge of the 20676 that they are cropped at the right edge of the
20546 window, so an image glyph will always end exactly at 20677 window, so an image glyph will always end exactly at
20547 last_visible_x, even if there's no right fringe. */ 20678 last_visible_x, even if there's no right fringe. */
20548 && (WINDOW_RIGHT_FRINGE_WIDTH (it->w) || it->what == IT_IMAGE)) 20679 && ((row->reversed_p
20680 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
20681 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
20682 || it->what == IT_IMAGE))
20549 ? (it->current_x >= it->last_visible_x) 20683 ? (it->current_x >= it->last_visible_x)
20550 : (it->current_x > it->last_visible_x))) 20684 : (it->current_x > it->last_visible_x)))
20551 { 20685 {
@@ -20622,10 +20756,15 @@ display_line (struct it *it)
20622 row->truncated_on_right_p = 1; 20756 row->truncated_on_right_p = 1;
20623 it->continuation_lines_width = 0; 20757 it->continuation_lines_width = 0;
20624 reseat_at_next_visible_line_start (it, 0); 20758 reseat_at_next_visible_line_start (it, 0);
20625 if (IT_BYTEPOS (*it) <= BEG_BYTE) 20759 /* We insist below that IT's position be at ZV because in
20626 row->ends_at_zv_p = true; 20760 bidi-reordered lines the character at visible line start
20761 might not be the character that follows the newline in
20762 the logical order. */
20763 if (IT_BYTEPOS (*it) > BEG_BYTE)
20764 row->ends_at_zv_p =
20765 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
20627 else 20766 else
20628 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; 20767 row->ends_at_zv_p = false;
20629 break; 20768 break;
20630 } 20769 }
20631 } 20770 }
@@ -20828,7 +20967,8 @@ See also `bidi-paragraph-direction'. */)
20828 the previous non-empty line. */ 20967 the previous non-empty line. */
20829 if (pos >= ZV && pos > BEGV) 20968 if (pos >= ZV && pos > BEGV)
20830 DEC_BOTH (pos, bytepos); 20969 DEC_BOTH (pos, bytepos);
20831 if (fast_looking_at (build_string ("[\f\t ]*\n"), 20970 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
20971 if (fast_looking_at (trailing_white_space,
20832 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0) 20972 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20833 { 20973 {
20834 while ((c = FETCH_BYTE (bytepos)) == '\n' 20974 while ((c = FETCH_BYTE (bytepos)) == '\n'
@@ -20939,7 +21079,7 @@ Value is the new character position of point. */)
20939 if ((gpt->resolved_level - row->reversed_p) % 2 == 0) 21079 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
20940 new_pos += (row->reversed_p ? -dir : dir); 21080 new_pos += (row->reversed_p ? -dir : dir);
20941 else 21081 else
20942 new_pos -= (row->reversed_p ? -dir : dir);; 21082 new_pos -= (row->reversed_p ? -dir : dir);
20943 } 21083 }
20944 else if (BUFFERP (g->object)) 21084 else if (BUFFERP (g->object))
20945 new_pos = g->charpos; 21085 new_pos = g->charpos;
@@ -22749,10 +22889,8 @@ decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_
22749 } 22889 }
22750 else if (CHARACTERP (eoltype)) 22890 else if (CHARACTERP (eoltype))
22751 { 22891 {
22752 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
22753 int c = XFASTINT (eoltype); 22892 int c = XFASTINT (eoltype);
22754 eol_str_len = CHAR_STRING (c, tmp); 22893 return buf + CHAR_STRING (c, (unsigned char *) buf);
22755 eol_str = tmp;
22756 } 22894 }
22757 else 22895 else
22758 { 22896 {
@@ -22888,7 +23026,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
22888 } 23026 }
22889 23027
22890 case 'e': 23028 case 'e':
22891#ifndef SYSTEM_MALLOC 23029#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
22892 { 23030 {
22893 if (NILP (Vmemory_full)) 23031 if (NILP (Vmemory_full))
22894 return ""; 23032 return "";
@@ -24668,7 +24806,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24668 face_id = (row)->glyphs[area][START].face_id; \ 24806 face_id = (row)->glyphs[area][START].face_id; \
24669 \ 24807 \
24670 s = alloca (sizeof *s); \ 24808 s = alloca (sizeof *s); \
24671 char2b = alloca ((END - START) * sizeof *char2b); \ 24809 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
24672 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \ 24810 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24673 append_glyph_string (&HEAD, &TAIL, s); \ 24811 append_glyph_string (&HEAD, &TAIL, s); \
24674 s->x = (X); \ 24812 s->x = (X); \
@@ -24696,7 +24834,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24696 struct glyph_string *first_s = NULL; \ 24834 struct glyph_string *first_s = NULL; \
24697 int n; \ 24835 int n; \
24698 \ 24836 \
24699 char2b = alloca (cmp->glyph_len * sizeof *char2b); \ 24837 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
24700 \ 24838 \
24701 /* Make glyph_strings for each glyph sequence that is drawable by \ 24839 /* Make glyph_strings for each glyph sequence that is drawable by \
24702 the same face, and append them to HEAD/TAIL. */ \ 24840 the same face, and append them to HEAD/TAIL. */ \
@@ -24731,7 +24869,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
24731 gstring = (composition_gstring_from_id \ 24869 gstring = (composition_gstring_from_id \
24732 ((row)->glyphs[area][START].u.cmp.id)); \ 24870 ((row)->glyphs[area][START].u.cmp.id)); \
24733 s = alloca (sizeof *s); \ 24871 s = alloca (sizeof *s); \
24734 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \ 24872 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
24735 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \ 24873 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
24736 append_glyph_string (&(HEAD), &(TAIL), s); \ 24874 append_glyph_string (&(HEAD), &(TAIL), s); \
24737 s->x = (X); \ 24875 s->x = (X); \
@@ -24883,6 +25021,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
24883 BUILD_GLYPH_STRINGS will modify its start parameter. That's 25021 BUILD_GLYPH_STRINGS will modify its start parameter. That's
24884 the reason we use a separate variable `i'. */ 25022 the reason we use a separate variable `i'. */
24885 i = start; 25023 i = start;
25024 USE_SAFE_ALLOCA;
24886 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x); 25025 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
24887 if (tail) 25026 if (tail)
24888 x_reached = tail->x + tail->background_width; 25027 x_reached = tail->x + tail->background_width;
@@ -25082,6 +25221,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
25082 25221
25083 RELEASE_HDC (hdc, f); 25222 RELEASE_HDC (hdc, f);
25084 25223
25224 SAFE_FREE ();
25085 return x_reached; 25225 return x_reached;
25086} 25226}
25087 25227
@@ -25821,14 +25961,13 @@ produce_special_glyphs (struct it *it, enum display_element_type what)
25821 25961
25822 temp_it.dp = NULL; 25962 temp_it.dp = NULL;
25823 temp_it.what = IT_CHARACTER; 25963 temp_it.what = IT_CHARACTER;
25824 temp_it.len = 1;
25825 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph); 25964 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
25826 temp_it.face_id = GLYPH_FACE (glyph); 25965 temp_it.face_id = GLYPH_FACE (glyph);
25827 temp_it.len = CHAR_BYTES (temp_it.c); 25966 temp_it.len = CHAR_BYTES (temp_it.c);
25828 25967
25829 PRODUCE_GLYPHS (&temp_it); 25968 PRODUCE_GLYPHS (&temp_it);
25830 it->pixel_width = temp_it.pixel_width; 25969 it->pixel_width = temp_it.pixel_width;
25831 it->nglyphs = temp_it.pixel_width; 25970 it->nglyphs = temp_it.nglyphs;
25832} 25971}
25833 25972
25834#ifdef HAVE_WINDOW_SYSTEM 25973#ifdef HAVE_WINDOW_SYSTEM
@@ -27567,6 +27706,10 @@ display_and_set_cursor (struct window *w, bool on,
27567 && (!on 27706 && (!on
27568 || w->phys_cursor.x != x 27707 || w->phys_cursor.x != x
27569 || w->phys_cursor.y != y 27708 || w->phys_cursor.y != y
27709 /* HPOS can be negative in R2L rows whose
27710 exact_window_width_line_p flag is set (i.e. their newline
27711 would "overflow into the fringe"). */
27712 || hpos < 0
27570 || new_cursor_type != w->phys_cursor_type 27713 || new_cursor_type != w->phys_cursor_type
27571 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR) 27714 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
27572 && new_cursor_width != w->phys_cursor_width))) 27715 && new_cursor_width != w->phys_cursor_width)))
@@ -29341,6 +29484,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
29341 /* Is this char mouse-active or does it have help-echo? */ 29484 /* Is this char mouse-active or does it have help-echo? */
29342 position = make_number (pos); 29485 position = make_number (pos);
29343 29486
29487 USE_SAFE_ALLOCA;
29488
29344 if (BUFFERP (object)) 29489 if (BUFFERP (object))
29345 { 29490 {
29346 /* Put all the overlays we want in a vector in overlay_vec. */ 29491 /* Put all the overlays we want in a vector in overlay_vec. */
@@ -29622,6 +29767,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
29622 BEGV = obegv; 29767 BEGV = obegv;
29623 ZV = ozv; 29768 ZV = ozv;
29624 current_buffer = obuf; 29769 current_buffer = obuf;
29770 SAFE_FREE ();
29625 } 29771 }
29626 29772
29627 set_cursor: 29773 set_cursor:
@@ -30141,8 +30287,6 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
30141 r.x = r.y = 0; 30287 r.x = r.y = 0;
30142 r.width = FRAME_TEXT_WIDTH (f); 30288 r.width = FRAME_TEXT_WIDTH (f);
30143 r.height = FRAME_TEXT_HEIGHT (f); 30289 r.height = FRAME_TEXT_HEIGHT (f);
30144/** r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); **/
30145/** r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); **/
30146 } 30290 }
30147 else 30291 else
30148 { 30292 {
diff --git a/src/xfaces.c b/src/xfaces.c
index 047f75ffb19..6afa0a2953d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3112,17 +3112,26 @@ FRAME 0 means change the face on all frames, and change the default
3112 f = XFRAME (selected_frame); 3112 f = XFRAME (selected_frame);
3113 else 3113 else
3114 f = XFRAME (frame); 3114 f = XFRAME (frame);
3115 if (! FONT_OBJECT_P (value))
3116 {
3117 Lisp_Object *attrs = XVECTOR (lface)->contents;
3118 Lisp_Object font_object;
3119 3115
3120 font_object = font_load_for_lface (f, attrs, value); 3116 /* FIXME:
3121 if (NILP (font_object)) 3117 If frame is t, and selected frame is a tty frame, the font
3122 signal_error ("Font not available", value); 3118 can't be realized. An improvement would be to loop over frames
3123 value = font_object; 3119 for a non-tty frame and use that. See discussion in
3124 } 3120 bug#18573. */
3125 set_lface_from_font (f, lface, value, 1); 3121 if (f->terminal->type != output_termcap)
3122 {
3123 if (! FONT_OBJECT_P (value))
3124 {
3125 Lisp_Object *attrs = XVECTOR (lface)->contents;
3126 Lisp_Object font_object;
3127
3128 font_object = font_load_for_lface (f, attrs, value);
3129 if (NILP (font_object))
3130 signal_error ("Font not available", value);
3131 value = font_object;
3132 }
3133 set_lface_from_font (f, lface, value, 1);
3134 }
3126 } 3135 }
3127 else 3136 else
3128 ASET (lface, LFACE_FONT_INDEX, value); 3137 ASET (lface, LFACE_FONT_INDEX, value);
@@ -3398,7 +3407,8 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
3398 ASET (lface, LFACE_FONT_INDEX, font); 3407 ASET (lface, LFACE_FONT_INDEX, font);
3399 } 3408 }
3400 f->default_face_done_p = 0; 3409 f->default_face_done_p = 0;
3401 Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, font))); 3410 AUTO_FRAME_ARG (arg, Qfont, font);
3411 Fmodify_frame_parameters (frame, arg);
3402 } 3412 }
3403} 3413}
3404 3414
@@ -3787,18 +3797,23 @@ Default face attributes override any local face attributes. */)
3787 && newface->font) 3797 && newface->font)
3788 { 3798 {
3789 Lisp_Object name = newface->font->props[FONT_NAME_INDEX]; 3799 Lisp_Object name = newface->font->props[FONT_NAME_INDEX];
3790 Fmodify_frame_parameters (frame, list1 (Fcons (Qfont, name))); 3800 AUTO_FRAME_ARG (arg, Qfont, name);
3801 Fmodify_frame_parameters (frame, arg);
3791 } 3802 }
3792 3803
3793 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX])) 3804 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
3794 Fmodify_frame_parameters (frame, 3805 {
3795 list1 (Fcons (Qforeground_color, 3806 AUTO_FRAME_ARG (arg, Qforeground_color,
3796 gvec[LFACE_FOREGROUND_INDEX]))); 3807 gvec[LFACE_FOREGROUND_INDEX]);
3808 Fmodify_frame_parameters (frame, arg);
3809 }
3797 3810
3798 if (STRINGP (gvec[LFACE_BACKGROUND_INDEX])) 3811 if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
3799 Fmodify_frame_parameters (frame, 3812 {
3800 list1 (Fcons (Qbackground_color, 3813 AUTO_FRAME_ARG (arg, Qbackground_color,
3801 gvec[LFACE_BACKGROUND_INDEX]))); 3814 gvec[LFACE_BACKGROUND_INDEX]);
3815 Fmodify_frame_parameters (frame, arg);
3816 }
3802 } 3817 }
3803 } 3818 }
3804 3819
@@ -5980,6 +5995,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
5980 endpos = XINT (end); 5995 endpos = XINT (end);
5981 5996
5982 /* Look at properties from overlays. */ 5997 /* Look at properties from overlays. */
5998 USE_SAFE_ALLOCA;
5983 { 5999 {
5984 ptrdiff_t next_overlay; 6000 ptrdiff_t next_overlay;
5985 6001
@@ -6006,7 +6022,10 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
6006 /* Optimize common cases where we can use the default face. */ 6022 /* Optimize common cases where we can use the default face. */
6007 if (noverlays == 0 6023 if (noverlays == 0
6008 && NILP (prop)) 6024 && NILP (prop))
6009 return default_face->id; 6025 {
6026 SAFE_FREE ();
6027 return default_face->id;
6028 }
6010 6029
6011 /* Begin with attributes from the default face. */ 6030 /* Begin with attributes from the default face. */
6012 memcpy (attrs, default_face->lface, sizeof attrs); 6031 memcpy (attrs, default_face->lface, sizeof attrs);
@@ -6034,6 +6053,8 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
6034 6053
6035 *endptr = endpos; 6054 *endptr = endpos;
6036 6055
6056 SAFE_FREE ();
6057
6037 /* Look up a realized face with the given face attributes, 6058 /* Look up a realized face with the given face attributes,
6038 or realize a new one for ASCII characters. */ 6059 or realize a new one for ASCII characters. */
6039 return lookup_face (f, attrs); 6060 return lookup_face (f, attrs);
diff --git a/src/xfns.c b/src/xfns.c
index 0c07d6cb03d..5edb635b182 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -159,7 +159,7 @@ check_x_display_info (Lisp_Object object)
159 } 159 }
160 else if (TERMINALP (object)) 160 else if (TERMINALP (object))
161 { 161 {
162 struct terminal *t = get_terminal (object, 1); 162 struct terminal *t = decode_live_terminal (object);
163 163
164 if (t->type != output_x_window) 164 if (t->type != output_x_window)
165 error ("Terminal %d is not an X display", t->id); 165 error ("Terminal %d is not an X display", t->id);
@@ -1140,10 +1140,8 @@ x_change_tool_bar_height (struct frame *f, int height)
1140 1140
1141 adjust_frame_size (f, -1, -1, 4, 0); 1141 adjust_frame_size (f, -1, -1, 4, 0);
1142 1142
1143/** #if !defined USE_X_TOOLKIT **/
1144 if (FRAME_X_WINDOW (f)) 1143 if (FRAME_X_WINDOW (f))
1145 x_clear_under_internal_border (f); 1144 x_clear_under_internal_border (f);
1146/** #endif **/
1147 1145
1148#endif /* USE_GTK */ 1146#endif /* USE_GTK */
1149} 1147}
@@ -1571,13 +1569,14 @@ x_default_scroll_bar_color_parameter (struct frame *f,
1571 1569
1572 /* See if an X resource for the scroll bar color has been 1570 /* See if an X resource for the scroll bar color has been
1573 specified. */ 1571 specified. */
1574 tem = display_x_get_resource (dpyinfo, 1572 AUTO_STRING (foreground, "foreground");
1575 build_string (foreground_p 1573 AUTO_STRING (background, "foreground");
1576 ? "foreground" 1574 AUTO_STRING (verticalScrollBar, "verticalScrollBar");
1577 : "background"), 1575 tem = (display_x_get_resource
1578 empty_unibyte_string, 1576 (dpyinfo, foreground_p ? foreground : background,
1579 build_string ("verticalScrollBar"), 1577 empty_unibyte_string,
1580 empty_unibyte_string); 1578 verticalScrollBar,
1579 empty_unibyte_string));
1581 if (!STRINGP (tem)) 1580 if (!STRINGP (tem))
1582 { 1581 {
1583 /* If nothing has been specified, scroll bars will use a 1582 /* If nothing has been specified, scroll bars will use a
@@ -1595,7 +1594,8 @@ x_default_scroll_bar_color_parameter (struct frame *f,
1595#endif /* not USE_TOOLKIT_SCROLL_BARS */ 1594#endif /* not USE_TOOLKIT_SCROLL_BARS */
1596 } 1595 }
1597 1596
1598 x_set_frame_parameters (f, list1 (Fcons (prop, tem))); 1597 AUTO_FRAME_ARG (arg, prop, tem);
1598 x_set_frame_parameters (f, arg);
1599 return tem; 1599 return tem;
1600} 1600}
1601 1601
@@ -1786,7 +1786,7 @@ xic_create_fontsetname (const char *base_fontname, int motif)
1786 len = p - base_fontname + strlen (allcs) + 1; 1786 len = p - base_fontname + strlen (allcs) + 1;
1787 font_allcs = alloca (len); 1787 font_allcs = alloca (len);
1788 memcpy (font_allcs, base_fontname, p - base_fontname); 1788 memcpy (font_allcs, base_fontname, p - base_fontname);
1789 strcat (font_allcs, allcs); 1789 strcpy (font_allcs + (p - base_fontname), allcs);
1790 1790
1791 /* Build the font spec that matches all families and 1791 /* Build the font spec that matches all families and
1792 add-styles. */ 1792 add-styles. */
@@ -1794,7 +1794,7 @@ xic_create_fontsetname (const char *base_fontname, int motif)
1794 font_allfamilies = alloca (len); 1794 font_allfamilies = alloca (len);
1795 strcpy (font_allfamilies, allfamilies); 1795 strcpy (font_allfamilies, allfamilies);
1796 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1); 1796 memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
1797 strcat (font_allfamilies, allcs); 1797 strcpy (font_allfamilies + strlen (allfamilies) + (p - p1), allcs);
1798 1798
1799 /* Build the font spec that matches all. */ 1799 /* Build the font spec that matches all. */
1800 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1; 1800 len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
@@ -1802,7 +1802,8 @@ xic_create_fontsetname (const char *base_fontname, int motif)
1802 strcpy (font_all, allfamilies); 1802 strcpy (font_all, allfamilies);
1803 strcat (font_all, all); 1803 strcat (font_all, all);
1804 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2); 1804 memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2);
1805 strcat (font_all, allcs); 1805 strcpy (font_all + strlen (all) + strlen (allfamilies) + (p - p2),
1806 allcs);
1806 1807
1807 /* Build the actual font set name. */ 1808 /* Build the actual font set name. */
1808 len = strlen (base_fontname) + strlen (font_allcs) 1809 len = strlen (base_fontname) + strlen (font_allcs)
@@ -2846,7 +2847,8 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms)
2846 { 2847 {
2847 /* Remember the explicit font parameter, so we can re-apply it after 2848 /* Remember the explicit font parameter, so we can re-apply it after
2848 we've applied the `default' face settings. */ 2849 we've applied the `default' face settings. */
2849 x_set_frame_parameters (f, list1 (Fcons (Qfont_param, font_param))); 2850 AUTO_FRAME_ARG (arg, Qfont_param, font_param);
2851 x_set_frame_parameters (f, arg);
2850 } 2852 }
2851 2853
2852 /* This call will make X resources override any system font setting. */ 2854 /* This call will make X resources override any system font setting. */
@@ -3112,15 +3114,9 @@ This function is an internal primitive--use `make-frame' instead. */)
3112#endif 3114#endif
3113 "verticalScrollBars", "ScrollBars", 3115 "verticalScrollBars", "ScrollBars",
3114 RES_TYPE_SYMBOL); 3116 RES_TYPE_SYMBOL);
3115 x_default_parameter (f, parms, Qhorizontal_scroll_bars, 3117 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
3116#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3117 Qt,
3118#else
3119 Qnil,
3120#endif
3121 "horizontalScrollBars", "ScrollBars", 3118 "horizontalScrollBars", "ScrollBars",
3122 RES_TYPE_SYMBOL); 3119 RES_TYPE_SYMBOL);
3123
3124 /* Also do the stuff which must be set before the window exists. */ 3120 /* Also do the stuff which must be set before the window exists. */
3125 x_default_parameter (f, parms, Qforeground_color, build_string ("black"), 3121 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3126 "foreground", "Foreground", RES_TYPE_STRING); 3122 "foreground", "Foreground", RES_TYPE_STRING);
@@ -4279,13 +4275,13 @@ select_visual (struct x_display_info *dpyinfo)
4279{ 4275{
4280 Display *dpy = dpyinfo->display; 4276 Display *dpy = dpyinfo->display;
4281 Screen *screen = dpyinfo->screen; 4277 Screen *screen = dpyinfo->screen;
4282 Lisp_Object value;
4283 4278
4284 /* See if a visual is specified. */ 4279 /* See if a visual is specified. */
4285 value = display_x_get_resource (dpyinfo, 4280 AUTO_STRING (visualClass, "visualClass");
4286 build_string ("visualClass"), 4281 AUTO_STRING (VisualClass, "VisualClass");
4287 build_string ("VisualClass"), 4282 Lisp_Object value = display_x_get_resource (dpyinfo, visualClass,
4288 Qnil, Qnil); 4283 VisualClass, Qnil, Qnil);
4284
4289 if (STRINGP (value)) 4285 if (STRINGP (value))
4290 { 4286 {
4291 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one 4287 /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
@@ -4296,7 +4292,7 @@ select_visual (struct x_display_info *dpyinfo)
4296 int i, class = -1; 4292 int i, class = -1;
4297 XVisualInfo vinfo; 4293 XVisualInfo vinfo;
4298 4294
4299 strcpy (s, SSDATA (value)); 4295 lispstpcpy (s, value);
4300 dash = strchr (s, '-'); 4296 dash = strchr (s, '-');
4301 if (dash) 4297 if (dash)
4302 { 4298 {
@@ -4833,7 +4829,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
4833 f = make_frame (1); 4829 f = make_frame (1);
4834 XSETFRAME (frame, f); 4830 XSETFRAME (frame, f);
4835 4831
4836 buffer = Fget_buffer_create (build_string (" *tip*")); 4832 AUTO_STRING (tip, " *tip*");
4833 buffer = Fget_buffer_create (tip);
4837 /* Use set_window_buffer instead of Fset_window_buffer (see 4834 /* Use set_window_buffer instead of Fset_window_buffer (see
4838 discussion of bug#11984, bug#12025, bug#12026). */ 4835 discussion of bug#11984, bug#12025, bug#12026). */
4839 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0); 4836 set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
@@ -5043,7 +5040,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5043 5040
5044 /* Add `tooltip' frame parameter's default value. */ 5041 /* Add `tooltip' frame parameter's default value. */
5045 if (NILP (Fframe_parameter (frame, Qtooltip))) 5042 if (NILP (Fframe_parameter (frame, Qtooltip)))
5046 Fmodify_frame_parameters (frame, list1 (Fcons (Qtooltip, Qt))); 5043 {
5044 AUTO_FRAME_ARG (arg, Qtooltip, Qt);
5045 Fmodify_frame_parameters (frame, arg);
5046 }
5047 5047
5048 /* FIXME - can this be done in a similar way to normal frames? 5048 /* FIXME - can this be done in a similar way to normal frames?
5049 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */ 5049 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
@@ -5061,7 +5061,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5061 disptype = intern ("color"); 5061 disptype = intern ("color");
5062 5062
5063 if (NILP (Fframe_parameter (frame, Qdisplay_type))) 5063 if (NILP (Fframe_parameter (frame, Qdisplay_type)))
5064 Fmodify_frame_parameters (frame, list1 (Fcons (Qdisplay_type, disptype))); 5064 {
5065 AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
5066 Fmodify_frame_parameters (frame, arg);
5067 }
5065 } 5068 }
5066 5069
5067 /* Set up faces after all frame parameters are known. This call 5070 /* Set up faces after all frame parameters are known. This call
@@ -5080,7 +5083,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5080 call2 (Qface_set_after_frame_default, frame, Qnil); 5083 call2 (Qface_set_after_frame_default, frame, Qnil);
5081 5084
5082 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) 5085 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5083 Fmodify_frame_parameters (frame, list1 (Fcons (Qbackground_color, bg))); 5086 {
5087 AUTO_FRAME_ARG (arg, Qbackground_color, bg);
5088 Fmodify_frame_parameters (frame, arg);
5089 }
5084 } 5090 }
5085 5091
5086 f->no_split = 1; 5092 f->no_split = 1;
diff --git a/src/xfont.c b/src/xfont.c
index 8996783541b..5e8dd370120 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -124,8 +124,8 @@ static void xfont_close (struct font *);
124static void xfont_prepare_face (struct frame *, struct face *); 124static void xfont_prepare_face (struct frame *, struct face *);
125static int xfont_has_char (Lisp_Object, int); 125static int xfont_has_char (Lisp_Object, int);
126static unsigned xfont_encode_char (struct font *, int); 126static unsigned xfont_encode_char (struct font *, int);
127static int xfont_text_extents (struct font *, unsigned *, int, 127static void xfont_text_extents (struct font *, unsigned *, int,
128 struct font_metrics *); 128 struct font_metrics *);
129static int xfont_draw (struct glyph_string *, int, int, int, int, bool); 129static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
130static int xfont_check (struct frame *, struct font *); 130static int xfont_check (struct frame *, struct font *);
131 131
@@ -541,7 +541,7 @@ xfont_list (struct frame *f, Lisp_Object spec)
541 if (STRINGP (XCAR (alter)) 541 if (STRINGP (XCAR (alter))
542 && ((r - name) + SBYTES (XCAR (alter))) < 256) 542 && ((r - name) + SBYTES (XCAR (alter))) < 256)
543 { 543 {
544 strcpy (r, SSDATA (XCAR (alter))); 544 lispstpcpy (r, XCAR (alter));
545 list = xfont_list_pattern (display, name, registry, script); 545 list = xfont_list_pattern (display, name, registry, script);
546 if (! NILP (list)) 546 if (! NILP (list))
547 break; 547 break;
@@ -975,15 +975,14 @@ xfont_encode_char (struct font *font, int c)
975 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE); 975 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
976} 976}
977 977
978static int 978static void
979xfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics) 979xfont_text_extents (struct font *font, unsigned int *code,
980 int nglyphs, struct font_metrics *metrics)
980{ 981{
981 XFontStruct *xfont = ((struct xfont_info *) font)->xfont; 982 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
982 int width = 0; 983 int i, width = 0;
983 int i, first; 984 bool first;
984 985
985 if (metrics)
986 memset (metrics, 0, sizeof (struct font_metrics));
987 for (i = 0, first = 1; i < nglyphs; i++) 986 for (i = 0, first = 1; i < nglyphs; i++)
988 { 987 {
989 XChar2b char2b; 988 XChar2b char2b;
@@ -997,34 +996,27 @@ xfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct f
997 continue; 996 continue;
998 if (first) 997 if (first)
999 { 998 {
1000 if (metrics) 999 metrics->lbearing = pcm->lbearing;
1001 { 1000 metrics->rbearing = pcm->rbearing;
1002 metrics->lbearing = pcm->lbearing; 1001 metrics->ascent = pcm->ascent;
1003 metrics->rbearing = pcm->rbearing; 1002 metrics->descent = pcm->descent;
1004 metrics->ascent = pcm->ascent;
1005 metrics->descent = pcm->descent;
1006 }
1007 first = 0; 1003 first = 0;
1008 } 1004 }
1009 else 1005 else
1010 { 1006 {
1011 if (metrics) 1007 if (metrics->lbearing > width + pcm->lbearing)
1012 { 1008 metrics->lbearing = width + pcm->lbearing;
1013 if (metrics->lbearing > width + pcm->lbearing) 1009 if (metrics->rbearing < width + pcm->rbearing)
1014 metrics->lbearing = width + pcm->lbearing; 1010 metrics->rbearing = width + pcm->rbearing;
1015 if (metrics->rbearing < width + pcm->rbearing) 1011 if (metrics->ascent < pcm->ascent)
1016 metrics->rbearing = width + pcm->rbearing; 1012 metrics->ascent = pcm->ascent;
1017 if (metrics->ascent < pcm->ascent) 1013 if (metrics->descent < pcm->descent)
1018 metrics->ascent = pcm->ascent; 1014 metrics->descent = pcm->descent;
1019 if (metrics->descent < pcm->descent)
1020 metrics->descent = pcm->descent;
1021 }
1022 } 1015 }
1023 width += pcm->width; 1016 width += pcm->width;
1024 } 1017 }
1025 if (metrics) 1018
1026 metrics->width = width; 1019 metrics->width = width;
1027 return width;
1028} 1020}
1029 1021
1030static int 1022static int
diff --git a/src/xftfont.c b/src/xftfont.c
index 9726a3b9911..0a883a7b87b 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -557,8 +557,9 @@ xftfont_encode_char (struct font *font, int c)
557 return (code ? code : FONT_INVALID_CODE); 557 return (code ? code : FONT_INVALID_CODE);
558} 558}
559 559
560static int 560static void
561xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics) 561xftfont_text_extents (struct font *font, unsigned int *code,
562 int nglyphs, struct font_metrics *metrics)
562{ 563{
563 struct xftfont_info *xftfont_info = (struct xftfont_info *) font; 564 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
564 XGlyphInfo extents; 565 XGlyphInfo extents;
@@ -567,15 +568,12 @@ xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct
567 XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs, 568 XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
568 &extents); 569 &extents);
569 unblock_input (); 570 unblock_input ();
570 if (metrics) 571
571 { 572 metrics->lbearing = - extents.x;
572 metrics->lbearing = - extents.x; 573 metrics->rbearing = - extents.x + extents.width;
573 metrics->rbearing = - extents.x + extents.width; 574 metrics->width = extents.xOff;
574 metrics->width = extents.xOff; 575 metrics->ascent = extents.y;
575 metrics->ascent = extents.y; 576 metrics->descent = extents.height - extents.y;
576 metrics->descent = extents.height - extents.y;
577 }
578 return extents.xOff;
579} 577}
580 578
581static XftDraw * 579static XftDraw *
diff --git a/src/xmenu.c b/src/xmenu.c
index a7d47188ef5..e3f1a17fbce 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -627,7 +627,6 @@ update_frame_menubar (struct frame *f)
627 xg_update_frame_menubar (f); 627 xg_update_frame_menubar (f);
628#else 628#else
629 struct x_output *x; 629 struct x_output *x;
630/** int columns, rows; **/
631 630
632 eassert (FRAME_X_P (f)); 631 eassert (FRAME_X_P (f));
633 632
@@ -637,10 +636,6 @@ update_frame_menubar (struct frame *f)
637 return; 636 return;
638 637
639 block_input (); 638 block_input ();
640 /* Save the size of the frame because the pane widget doesn't accept
641 to resize itself. So force it. */
642/** columns = FRAME_COLS (f); **/
643/** rows = FRAME_LINES (f); **/
644 639
645 /* Do the voodoo which means "I'm changing lots of things, don't try 640 /* Do the voodoo which means "I'm changing lots of things, don't try
646 to refigure sizes until I'm done." */ 641 to refigure sizes until I'm done." */
@@ -661,8 +656,7 @@ update_frame_menubar (struct frame *f)
661 XtManageChild (x->edit_widget); 656 XtManageChild (x->edit_widget);
662 lw_refigure_widget (x->column_widget, True); 657 lw_refigure_widget (x->column_widget, True);
663 658
664 /* Force the pane widget to resize itself with the right values. */ 659 /* Force the pane widget to resize itself. */
665/** EmacsFrameSetCharSize (x->edit_widget, columns, rows); **/
666 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 2, 0); 660 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 2, 0);
667 unblock_input (); 661 unblock_input ();
668#endif 662#endif
@@ -2023,7 +2017,8 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2023 Window root; 2017 Window root;
2024 XMenu *menu; 2018 XMenu *menu;
2025 int pane, selidx, lpane, status; 2019 int pane, selidx, lpane, status;
2026 Lisp_Object entry, pane_prefix; 2020 Lisp_Object entry = Qnil;
2021 Lisp_Object pane_prefix;
2027 char *datap; 2022 char *datap;
2028 int ulx, uly, width, height; 2023 int ulx, uly, width, height;
2029 int dispwidth, dispheight; 2024 int dispwidth, dispheight;
@@ -2045,6 +2040,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2045 return Qnil; 2040 return Qnil;
2046 } 2041 }
2047 2042
2043 USE_SAFE_ALLOCA;
2048 block_input (); 2044 block_input ();
2049 2045
2050 /* Figure out which root window F is on. */ 2046 /* Figure out which root window F is on. */
@@ -2057,8 +2053,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2057 if (menu == NULL) 2053 if (menu == NULL)
2058 { 2054 {
2059 *error_name = "Can't create menu"; 2055 *error_name = "Can't create menu";
2060 unblock_input (); 2056 goto return_entry;
2061 return Qnil;
2062 } 2057 }
2063 2058
2064 /* Don't GC while we prepare and show the menu, 2059 /* Don't GC while we prepare and show the menu,
@@ -2101,8 +2096,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2101 { 2096 {
2102 XMenuDestroy (FRAME_X_DISPLAY (f), menu); 2097 XMenuDestroy (FRAME_X_DISPLAY (f), menu);
2103 *error_name = "Can't create pane"; 2098 *error_name = "Can't create pane";
2104 unblock_input (); 2099 goto return_entry;
2105 return Qnil;
2106 } 2100 }
2107 i += MENU_ITEMS_PANE_LENGTH; 2101 i += MENU_ITEMS_PANE_LENGTH;
2108 2102
@@ -2146,9 +2140,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2146 2140
2147 if (!NILP (descrip)) 2141 if (!NILP (descrip))
2148 { 2142 {
2149 /* if alloca is fast, use that to make the space, 2143 item_data = SAFE_ALLOCA (maxwidth + SBYTES (descrip) + 1);
2150 to reduce gc needs. */
2151 item_data = alloca (maxwidth + SBYTES (descrip) + 1);
2152 memcpy (item_data, SSDATA (item_name), SBYTES (item_name)); 2144 memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
2153 for (j = SCHARS (item_name); j < maxwidth; j++) 2145 for (j = SCHARS (item_name); j < maxwidth; j++)
2154 item_data[j] = ' '; 2146 item_data[j] = ' ';
@@ -2166,8 +2158,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2166 { 2158 {
2167 XMenuDestroy (FRAME_X_DISPLAY (f), menu); 2159 XMenuDestroy (FRAME_X_DISPLAY (f), menu);
2168 *error_name = "Can't add selection to menu"; 2160 *error_name = "Can't add selection to menu";
2169 unblock_input (); 2161 goto return_entry;
2170 return Qnil;
2171 } 2162 }
2172 i += MENU_ITEMS_ITEM_LENGTH; 2163 i += MENU_ITEMS_ITEM_LENGTH;
2173 lines++; 2164 lines++;
@@ -2241,7 +2232,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2241 status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx, 2232 status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx,
2242 x, y, ButtonReleaseMask, &datap, 2233 x, y, ButtonReleaseMask, &datap,
2243 menu_help_callback); 2234 menu_help_callback);
2244 entry = pane_prefix = Qnil; 2235 pane_prefix = Qnil;
2245 2236
2246 switch (status) 2237 switch (status)
2247 { 2238 {
@@ -2300,10 +2291,10 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
2300 break; 2291 break;
2301 } 2292 }
2302 2293
2294 return_entry:
2303 unblock_input (); 2295 unblock_input ();
2304 unbind_to (specpdl_count, Qnil); 2296 SAFE_FREE ();
2305 2297 return unbind_to (specpdl_count, entry);
2306 return entry;
2307} 2298}
2308 2299
2309#endif /* not USE_X_TOOLKIT */ 2300#endif /* not USE_X_TOOLKIT */
diff --git a/src/xselect.c b/src/xselect.c
index 23310b0f867..92e89822293 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -96,13 +96,6 @@ static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions;
96 is not necessarily sizeof (long). */ 96 is not necessarily sizeof (long). */
97#define X_LONG_SIZE 4 97#define X_LONG_SIZE 4
98 98
99/* Extreme 'short' and 'long' values suitable for libX11. */
100#define X_SHRT_MAX 0x7fff
101#define X_SHRT_MIN (-1 - X_SHRT_MAX)
102#define X_LONG_MAX 0x7fffffff
103#define X_LONG_MIN (-1 - X_LONG_MAX)
104#define X_ULONG_MAX 0xffffffffUL
105
106/* If this is a smaller number than the max-request-size of the display, 99/* If this is a smaller number than the max-request-size of the display,
107 emacs will use INCR selection transfer when the selection is larger 100 emacs will use INCR selection transfer when the selection is larger
108 than this. The max-request-size is usually around 64k, so if you want 101 than this. The max-request-size is usually around 64k, so if you want
@@ -1908,7 +1901,7 @@ frame_for_x_selection (Lisp_Object object)
1908 } 1901 }
1909 else if (TERMINALP (object)) 1902 else if (TERMINALP (object))
1910 { 1903 {
1911 struct terminal *t = get_terminal (object, 1); 1904 struct terminal *t = decode_live_terminal (object);
1912 1905
1913 if (t->type == output_x_window) 1906 if (t->type == output_x_window)
1914 FOR_EACH_FRAME (tail, frame) 1907 FOR_EACH_FRAME (tail, frame)
@@ -2159,11 +2152,9 @@ x_clipboard_manager_save (Lisp_Object frame)
2159static Lisp_Object 2152static Lisp_Object
2160x_clipboard_manager_error_1 (Lisp_Object err) 2153x_clipboard_manager_error_1 (Lisp_Object err)
2161{ 2154{
2162 Lisp_Object args[2]; 2155 AUTO_STRING (format, "X clipboard manager error: %s\n\
2163 args[0] = build_string ("X clipboard manager error: %s\n\
2164If the problem persists, set `x-select-enable-clipboard-manager' to nil."); 2156If the problem persists, set `x-select-enable-clipboard-manager' to nil.");
2165 args[1] = CAR (CDR (err)); 2157 Fmessage (2, (Lisp_Object []) {format, CAR (CDR (err))});
2166 Fmessage (2, args);
2167 return Qnil; 2158 return Qnil;
2168} 2159}
2169 2160
@@ -2230,10 +2221,8 @@ x_clipboard_manager_save_all (void)
2230 local_frame = XCAR (XCDR (XCDR (XCDR (local_selection)))); 2221 local_frame = XCAR (XCDR (XCDR (XCDR (local_selection))));
2231 if (FRAME_LIVE_P (XFRAME (local_frame))) 2222 if (FRAME_LIVE_P (XFRAME (local_frame)))
2232 { 2223 {
2233 Lisp_Object args[1]; 2224 AUTO_STRING (saving, "Saving clipboard to X clipboard manager...");
2234 args[0] = build_string ("Saving clipboard to X clipboard manager..."); 2225 Fmessage (1, &saving);
2235 Fmessage (1, args);
2236
2237 internal_condition_case_1 (x_clipboard_manager_save, local_frame, 2226 internal_condition_case_1 (x_clipboard_manager_save, local_frame,
2238 Qt, x_clipboard_manager_error_2); 2227 Qt, x_clipboard_manager_error_2);
2239 } 2228 }
@@ -2288,10 +2277,10 @@ x_check_property_data (Lisp_Object data)
2288void 2277void
2289x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) 2278x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
2290{ 2279{
2291 long val; 2280 unsigned long val;
2292 long *d32 = (long *) ret; 2281 unsigned long *d32 = (unsigned long *) ret;
2293 short *d16 = (short *) ret; 2282 unsigned short *d16 = (unsigned short *) ret;
2294 char *d08 = (char *) ret; 2283 unsigned char *d08 = (unsigned char *) ret;
2295 Lisp_Object iter; 2284 Lisp_Object iter;
2296 2285
2297 for (iter = data; CONSP (iter); iter = XCDR (iter)) 2286 for (iter = data; CONSP (iter); iter = XCDR (iter))
@@ -2299,7 +2288,22 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
2299 Lisp_Object o = XCAR (iter); 2288 Lisp_Object o = XCAR (iter);
2300 2289
2301 if (INTEGERP (o) || FLOATP (o) || CONSP (o)) 2290 if (INTEGERP (o) || FLOATP (o) || CONSP (o))
2302 val = cons_to_signed (o, LONG_MIN, LONG_MAX); 2291 {
2292 if (CONSP (o)
2293 && RANGED_INTEGERP (X_LONG_MIN >> 16, XCAR (o), X_LONG_MAX >> 16)
2294 && RANGED_INTEGERP (- (1 << 15), XCDR (o), -1))
2295 {
2296 /* cons_to_x_long does not handle negative values for v2.
2297 For XDnd, v2 might be y of a window, and can be negative.
2298 The XDnd spec. is not explicit about negative values,
2299 but let's assume negative v2 is sent modulo 2**16. */
2300 unsigned long v1 = XINT (XCAR (o)) & 0xffff;
2301 unsigned long v2 = XINT (XCDR (o)) & 0xffff;
2302 val = (v1 << 16) | v2;
2303 }
2304 else
2305 val = cons_to_x_long (o);
2306 }
2303 else if (STRINGP (o)) 2307 else if (STRINGP (o))
2304 { 2308 {
2305 block_input (); 2309 block_input ();
@@ -2311,17 +2315,15 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
2311 2315
2312 if (format == 8) 2316 if (format == 8)
2313 { 2317 {
2314 if (CHAR_MIN <= val && val <= CHAR_MAX) 2318 if ((1 << 8) < val && val <= X_ULONG_MAX - (1 << 7))
2315 *d08++ = val;
2316 else
2317 error ("Out of 'char' range"); 2319 error ("Out of 'char' range");
2320 *d08++ = val;
2318 } 2321 }
2319 else if (format == 16) 2322 else if (format == 16)
2320 { 2323 {
2321 if (SHRT_MIN <= val && val <= SHRT_MAX) 2324 if ((1 << 16) < val && val <= X_ULONG_MAX - (1 << 15))
2322 *d16++ = val;
2323 else
2324 error ("Out of 'short' range"); 2325 error ("Out of 'short' range");
2326 *d16++ = val;
2325 } 2327 }
2326 else 2328 else
2327 *d32++ = val; 2329 *d32++ = val;
@@ -2627,12 +2629,14 @@ syms_of_xselect (void)
2627 converted_selections = NULL; 2629 converted_selections = NULL;
2628 conversion_fail_tag = None; 2630 conversion_fail_tag = None;
2629 2631
2632 /* FIXME: Duplicate definition in nsselect.c. */
2630 DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist, 2633 DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
2631 doc: /* An alist associating X Windows selection-types with functions. 2634 doc: /* An alist associating X Windows selection-types with functions.
2632These functions are called to convert the selection, with three args: 2635These functions are called to convert the selection, with three args:
2633the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD'); 2636the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
2634a desired type to which the selection should be converted; 2637a desired type to which the selection should be converted;
2635and the local selection value (whatever was given to `x-own-selection'). 2638and the local selection value (whatever was given to
2639`x-own-selection-internal').
2636 2640
2637The function should return the value to send to the X server 2641The function should return the value to send to the X server
2638\(typically a string). A return value of nil 2642\(typically a string). A return value of nil
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 81b012690f9..cd4f9ce57fa 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -49,7 +49,7 @@ static struct input_event emacs_event;
49 49
50/* The descriptor that we use to check for data from the session manager. */ 50/* The descriptor that we use to check for data from the session manager. */
51 51
52static int ice_fd; 52static int ice_fd = -1;
53 53
54/* A flag that says if we are in shutdown interactions or not. */ 54/* A flag that says if we are in shutdown interactions or not. */
55 55
@@ -415,11 +415,11 @@ x_session_initialize (struct x_display_info *dpyinfo)
415 /* This malloc will not be freed, but it is only done once, and hopefully 415 /* This malloc will not be freed, but it is only done once, and hopefully
416 not very large */ 416 not very large */
417 emacs_program = xmalloc (name_len + 1); 417 emacs_program = xmalloc (name_len + 1);
418 emacs_program[0] = '\0'; 418 char *z = emacs_program;
419 419
420 if (! EQ (Vinvocation_directory, Qnil)) 420 if (! EQ (Vinvocation_directory, Qnil))
421 strcpy (emacs_program, SSDATA (Vinvocation_directory)); 421 z = lispstpcpy (z, Vinvocation_directory);
422 strcat (emacs_program, SSDATA (Vinvocation_name)); 422 lispstpcpy (z, Vinvocation_name);
423 423
424 /* The SM protocol says all callbacks are mandatory, so set up all 424 /* The SM protocol says all callbacks are mandatory, so set up all
425 here and in the mask passed to SmcOpenConnection. */ 425 here and in the mask passed to SmcOpenConnection. */
diff --git a/src/xterm.c b/src/xterm.c
index 7b8d32a4516..f32aea031f9 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2474,7 +2474,7 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
2474 { 2474 {
2475 /* In R2L rows, draw the cursor on the right edge of the 2475 /* In R2L rows, draw the cursor on the right edge of the
2476 stretch glyph. */ 2476 stretch glyph. */
2477 int right_x = window_box_right_offset (s->w, TEXT_AREA); 2477 int right_x = window_box_right (s->w, TEXT_AREA);
2478 2478
2479 if (x + background_width > right_x) 2479 if (x + background_width > right_x)
2480 background_width -= x - right_x; 2480 background_width -= x - right_x;
@@ -4157,7 +4157,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
4157 dpyinfo->last_mouse_glyph_frame = f1; 4157 dpyinfo->last_mouse_glyph_frame = f1;
4158 4158
4159 *bar_window = Qnil; 4159 *bar_window = Qnil;
4160 *part = 0; 4160 *part = scroll_bar_above_handle;
4161 *fp = f1; 4161 *fp = f1;
4162 XSETINT (*x, win_x); 4162 XSETINT (*x, win_x);
4163 XSETINT (*y, win_y); 4163 XSETINT (*y, win_y);
@@ -4250,7 +4250,8 @@ x_window_to_menu_bar (Window window)
4250 4250
4251#ifdef USE_TOOLKIT_SCROLL_BARS 4251#ifdef USE_TOOLKIT_SCROLL_BARS
4252 4252
4253static void x_send_scroll_bar_event (Lisp_Object, int, int, int, bool); 4253static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part,
4254 int, int, bool);
4254 4255
4255/* Lisp window being scrolled. Set when starting to interact with 4256/* Lisp window being scrolled. Set when starting to interact with
4256 a toolkit scroll bar, reset to nil when ending the interaction. */ 4257 a toolkit scroll bar, reset to nil when ending the interaction. */
@@ -4371,7 +4372,8 @@ xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_n
4371 amount to scroll of a whole of WHOLE. */ 4372 amount to scroll of a whole of WHOLE. */
4372 4373
4373static void 4374static void
4374x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole, bool horizontal) 4375x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
4376 int portion, int whole, bool horizontal)
4375{ 4377{
4376 XEvent event; 4378 XEvent event;
4377 XClientMessageEvent *ev = &event.xclient; 4379 XClientMessageEvent *ev = &event.xclient;
@@ -4504,8 +4506,8 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4504{ 4506{
4505 struct scroll_bar *bar = client_data; 4507 struct scroll_bar *bar = client_data;
4506 XmScrollBarCallbackStruct *cs = call_data; 4508 XmScrollBarCallbackStruct *cs = call_data;
4507 int part = -1, whole = 0, portion = 0; 4509 enum scroll_bar_part part = scroll_bar_nowhere;
4508 int horizontal = bar->horizontal; 4510 int horizontal = bar->horizontal, whole = 0, portion = 0;
4509 4511
4510 switch (cs->reason) 4512 switch (cs->reason)
4511 { 4513 {
@@ -4549,12 +4551,9 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4549 4551
4550 if (horizontal) 4552 if (horizontal)
4551 { 4553 {
4552 whole = bar->whole; 4554 portion = bar->whole * ((float)cs->value / XM_SB_MAX);
4553 portion = (((float) cs->value 4555 whole = bar->whole * ((float)(XM_SB_MAX - slider_size) / XM_SB_MAX);
4554 / (XM_SB_MAX - slider_size)) 4556 portion = min (portion, whole);
4555 * (whole
4556 - ((float) slider_size / XM_SB_MAX) * whole));
4557 portion = max (0, portion);
4558 part = scroll_bar_horizontal_handle; 4557 part = scroll_bar_horizontal_handle;
4559 } 4558 }
4560 else 4559 else
@@ -4572,7 +4571,7 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4572 break; 4571 break;
4573 }; 4572 };
4574 4573
4575 if (part >= 0) 4574 if (part != scroll_bar_nowhere)
4576 { 4575 {
4577 window_being_scrolled = bar->window; 4576 window_being_scrolled = bar->window;
4578 x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal); 4577 x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
@@ -4590,8 +4589,9 @@ xg_scroll_callback (GtkRange *range,
4590 gdouble value, 4589 gdouble value,
4591 gpointer user_data) 4590 gpointer user_data)
4592{ 4591{
4592 int whole = 0, portion = 0;
4593 struct scroll_bar *bar = user_data; 4593 struct scroll_bar *bar = user_data;
4594 int part = -1, whole = 0, portion = 0; 4594 enum scroll_bar_part part = scroll_bar_nowhere;
4595 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range)); 4595 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
4596 struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA); 4596 struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
4597 4597
@@ -4644,7 +4644,7 @@ xg_scroll_callback (GtkRange *range,
4644 break; 4644 break;
4645 } 4645 }
4646 4646
4647 if (part >= 0) 4647 if (part != scroll_bar_nowhere)
4648 { 4648 {
4649 window_being_scrolled = bar->window; 4649 window_being_scrolled = bar->window;
4650 x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal); 4650 x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
@@ -4687,24 +4687,51 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4687 float *top_addr = call_data; 4687 float *top_addr = call_data;
4688 float top = *top_addr; 4688 float top = *top_addr;
4689 float shown; 4689 float shown;
4690 int whole, portion, height; 4690 int whole, portion, height, width;
4691 enum scroll_bar_part part; 4691 enum scroll_bar_part part;
4692 int horizontal = bar->horizontal; 4692 int horizontal = bar->horizontal;
4693 4693
4694 /* Get the size of the thumb, a value between 0 and 1. */
4695 block_input ();
4696 XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
4697 unblock_input ();
4698 4694
4699 if (horizontal) 4695 if (horizontal)
4700 { 4696 {
4701 whole = bar->whole; 4697 /* Get the size of the thumb, a value between 0 and 1. */
4702 portion = (top * (whole - (shown * whole))) / (1 - shown); 4698 block_input ();
4703 portion = max (0, portion); 4699 XtVaGetValues (widget, XtNshown, &shown, XtNwidth, &width, NULL);
4700 unblock_input ();
4701
4702 if (shown < 1)
4703 {
4704 whole = bar->whole - (shown * bar->whole);
4705 portion = min (top * bar->whole, whole);
4706 }
4707 else
4708 {
4709 whole = bar->whole;
4710 portion = 0;
4711 }
4712
4704 part = scroll_bar_horizontal_handle; 4713 part = scroll_bar_horizontal_handle;
4705 } 4714 }
4706 else 4715 else
4707 part = scroll_bar_handle; 4716 {
4717 /* Get the size of the thumb, a value between 0 and 1. */
4718 block_input ();
4719 XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
4720 unblock_input ();
4721
4722 whole = 10000000;
4723 portion = shown < 1 ? top * whole : 0;
4724
4725 if (shown < 1 && (eabs (top + shown - 1) < 1.0f / height))
4726 /* Some derivatives of Xaw refuse to shrink the thumb when you reach
4727 the bottom, so we force the scrolling whenever we see that we're
4728 too close to the bottom (in x_set_toolkit_scroll_bar_thumb
4729 we try to ensure that we always stay two pixels away from the
4730 bottom). */
4731 part = scroll_bar_down_arrow;
4732 else
4733 part = scroll_bar_handle;
4734 }
4708 4735
4709 window_being_scrolled = bar->window; 4736 window_being_scrolled = bar->window;
4710 bar->dragging = portion; 4737 bar->dragging = portion;
@@ -4727,28 +4754,54 @@ xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4727 struct scroll_bar *bar = client_data; 4754 struct scroll_bar *bar = client_data;
4728 /* The position really is stored cast to a pointer. */ 4755 /* The position really is stored cast to a pointer. */
4729 int position = (intptr_t) call_data; 4756 int position = (intptr_t) call_data;
4730 Dimension height; 4757 Dimension height, width;
4731 enum scroll_bar_part part; 4758 enum scroll_bar_part part;
4732 4759
4733 /* Get the height of the scroll bar. */ 4760 if (bar->horizontal)
4734 block_input (); 4761 {
4735 XtVaGetValues (widget, XtNheight, &height, NULL); 4762 /* Get the width of the scroll bar. */
4736 unblock_input (); 4763 block_input ();
4764 XtVaGetValues (widget, XtNwidth, &width, NULL);
4765 unblock_input ();
4737 4766
4738 if (eabs (position) >= height) 4767 if (eabs (position) >= width)
4739 part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle; 4768 part = (position < 0) ? scroll_bar_before_handle : scroll_bar_after_handle;
4769
4770 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
4771 it maps line-movement to call_data = max(5, height/20). */
4772 else if (xaw3d_arrow_scroll && eabs (position) <= max (5, width / 20))
4773 part = (position < 0) ? scroll_bar_left_arrow : scroll_bar_right_arrow;
4774 else
4775 part = scroll_bar_move_ratio;
4740 4776
4741 /* If Xaw3d was compiled with ARROW_SCROLLBAR, 4777 window_being_scrolled = bar->window;
4742 it maps line-movement to call_data = max(5, height/20). */ 4778 bar->dragging = -1;
4743 else if (xaw3d_arrow_scroll && eabs (position) <= max (5, height / 20)) 4779 bar->last_seen_part = part;
4744 part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow; 4780 x_send_scroll_bar_event (bar->window, part, position, width, bar->horizontal);
4781 }
4745 else 4782 else
4746 part = scroll_bar_move_ratio; 4783 {
4747 4784
4748 window_being_scrolled = bar->window; 4785 /* Get the height of the scroll bar. */
4749 bar->dragging = -1; 4786 block_input ();
4750 bar->last_seen_part = part; 4787 XtVaGetValues (widget, XtNheight, &height, NULL);
4751 x_send_scroll_bar_event (bar->window, part, position, height, bar->horizontal); 4788 unblock_input ();
4789
4790 if (eabs (position) >= height)
4791 part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
4792
4793 /* If Xaw3d was compiled with ARROW_SCROLLBAR,
4794 it maps line-movement to call_data = max(5, height/20). */
4795 else if (xaw3d_arrow_scroll && eabs (position) <= max (5, height / 20))
4796 part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
4797 else
4798 part = scroll_bar_move_ratio;
4799
4800 window_being_scrolled = bar->window;
4801 bar->dragging = -1;
4802 bar->last_seen_part = part;
4803 x_send_scroll_bar_event (bar->window, part, position, height, bar->horizontal);
4804 }
4752} 4805}
4753 4806
4754#endif /* not USE_GTK and not USE_MOTIF */ 4807#endif /* not USE_GTK and not USE_MOTIF */
@@ -6134,7 +6187,7 @@ x_scroll_bar_handle_click (struct scroll_bar *bar,
6134 /* If the user has released the handle, set it to its final position. */ 6187 /* If the user has released the handle, set it to its final position. */
6135 if (event->type == ButtonRelease && bar->dragging != -1) 6188 if (event->type == ButtonRelease && bar->dragging != -1)
6136 { 6189 {
6137 int new_start = - bar->dragging; 6190 int new_start = - bar->dragging;
6138 int new_end = new_start + bar->end - bar->start; 6191 int new_end = new_start + bar->end - bar->start;
6139 6192
6140 x_scroll_bar_set_handle (bar, new_start, new_end, 0); 6193 x_scroll_bar_set_handle (bar, new_start, new_end, 0);
@@ -6749,7 +6802,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6749 break; 6802 break;
6750 6803
6751 case SelectionNotify: 6804 case SelectionNotify:
6752 dpyinfo->last_user_time = event->xselection.time; 6805 x_display_set_last_user_time (dpyinfo, event->xselection.time);
6753#ifdef USE_X_TOOLKIT 6806#ifdef USE_X_TOOLKIT
6754 if (! x_window_to_frame (dpyinfo, event->xselection.requestor)) 6807 if (! x_window_to_frame (dpyinfo, event->xselection.requestor))
6755 goto OTHER; 6808 goto OTHER;
@@ -6758,7 +6811,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6758 break; 6811 break;
6759 6812
6760 case SelectionClear: /* Someone has grabbed ownership. */ 6813 case SelectionClear: /* Someone has grabbed ownership. */
6761 dpyinfo->last_user_time = event->xselectionclear.time; 6814 x_display_set_last_user_time (dpyinfo, event->xselectionclear.time);
6762#ifdef USE_X_TOOLKIT 6815#ifdef USE_X_TOOLKIT
6763 if (! x_window_to_frame (dpyinfo, event->xselectionclear.window)) 6816 if (! x_window_to_frame (dpyinfo, event->xselectionclear.window))
6764 goto OTHER; 6817 goto OTHER;
@@ -6774,7 +6827,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6774 break; 6827 break;
6775 6828
6776 case SelectionRequest: /* Someone wants our selection. */ 6829 case SelectionRequest: /* Someone wants our selection. */
6777 dpyinfo->last_user_time = event->xselectionrequest.time; 6830 x_display_set_last_user_time (dpyinfo, event->xselectionrequest.time);
6778#ifdef USE_X_TOOLKIT 6831#ifdef USE_X_TOOLKIT
6779 if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner)) 6832 if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner))
6780 goto OTHER; 6833 goto OTHER;
@@ -6793,23 +6846,33 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6793 break; 6846 break;
6794 6847
6795 case PropertyNotify: 6848 case PropertyNotify:
6796 dpyinfo->last_user_time = event->xproperty.time; 6849 x_display_set_last_user_time (dpyinfo, event->xproperty.time);
6797 f = x_top_window_to_frame (dpyinfo, event->xproperty.window); 6850 f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
6798 if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state) 6851 if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state)
6799 if (x_handle_net_wm_state (f, &event->xproperty) 6852 {
6800 && FRAME_ICONIFIED_P (f) 6853 if (x_handle_net_wm_state (f, &event->xproperty)
6801 && f->output_data.x->net_wm_state_hidden_seen) 6854 && FRAME_ICONIFIED_P (f)
6802 { 6855 && f->output_data.x->net_wm_state_hidden_seen)
6803 /* Gnome shell does not iconify us when C-z is pressed. 6856 {
6804 It hides the frame. So if our state says we aren't 6857 /* Gnome shell does not iconify us when C-z is pressed.
6805 hidden anymore, treat it as deiconified. */ 6858 It hides the frame. So if our state says we aren't
6806 SET_FRAME_VISIBLE (f, 1); 6859 hidden anymore, treat it as deiconified. */
6807 SET_FRAME_ICONIFIED (f, 0); 6860 SET_FRAME_VISIBLE (f, 1);
6808 f->output_data.x->has_been_visible = 1; 6861 SET_FRAME_ICONIFIED (f, 0);
6809 f->output_data.x->net_wm_state_hidden_seen = 0; 6862 f->output_data.x->has_been_visible = 1;
6810 inev.ie.kind = DEICONIFY_EVENT; 6863 f->output_data.x->net_wm_state_hidden_seen = 0;
6811 XSETFRAME (inev.ie.frame_or_window, f); 6864 inev.ie.kind = DEICONIFY_EVENT;
6812 } 6865 XSETFRAME (inev.ie.frame_or_window, f);
6866 }
6867 else if (! FRAME_ICONIFIED_P (f)
6868 && f->output_data.x->net_wm_state_hidden_seen)
6869 {
6870 SET_FRAME_VISIBLE (f, 0);
6871 SET_FRAME_ICONIFIED (f, 1);
6872 inev.ie.kind = ICONIFY_EVENT;
6873 XSETFRAME (inev.ie.frame_or_window, f);
6874 }
6875 }
6813 6876
6814 x_handle_property_notify (&event->xproperty); 6877 x_handle_property_notify (&event->xproperty);
6815 xft_settings_event (dpyinfo, event); 6878 xft_settings_event (dpyinfo, event);
@@ -6981,7 +7044,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6981 7044
6982 case KeyPress: 7045 case KeyPress:
6983 7046
6984 dpyinfo->last_user_time = event->xkey.time; 7047 x_display_set_last_user_time (dpyinfo, event->xkey.time);
6985 ignore_next_mouse_click_timeout = 0; 7048 ignore_next_mouse_click_timeout = 0;
6986 7049
6987#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 7050#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
@@ -7315,7 +7378,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7315#endif 7378#endif
7316 7379
7317 case KeyRelease: 7380 case KeyRelease:
7318 dpyinfo->last_user_time = event->xkey.time; 7381 x_display_set_last_user_time (dpyinfo, event->xkey.time);
7319#ifdef HAVE_X_I18N 7382#ifdef HAVE_X_I18N
7320 /* Don't dispatch this event since XtDispatchEvent calls 7383 /* Don't dispatch this event since XtDispatchEvent calls
7321 XFilterEvent, and two calls in a row may freeze the 7384 XFilterEvent, and two calls in a row may freeze the
@@ -7326,7 +7389,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7326#endif 7389#endif
7327 7390
7328 case EnterNotify: 7391 case EnterNotify:
7329 dpyinfo->last_user_time = event->xcrossing.time; 7392 x_display_set_last_user_time (dpyinfo, event->xcrossing.time);
7330 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 7393 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
7331 7394
7332 f = any; 7395 f = any;
@@ -7351,7 +7414,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7351 goto OTHER; 7414 goto OTHER;
7352 7415
7353 case LeaveNotify: 7416 case LeaveNotify:
7354 dpyinfo->last_user_time = event->xcrossing.time; 7417 x_display_set_last_user_time (dpyinfo, event->xcrossing.time);
7355 x_detect_focus_change (dpyinfo, any, event, &inev.ie); 7418 x_detect_focus_change (dpyinfo, any, event, &inev.ie);
7356 7419
7357 f = x_top_window_to_frame (dpyinfo, event->xcrossing.window); 7420 f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
@@ -7385,7 +7448,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7385 7448
7386 case MotionNotify: 7449 case MotionNotify:
7387 { 7450 {
7388 dpyinfo->last_user_time = event->xmotion.time; 7451 x_display_set_last_user_time (dpyinfo, event->xmotion.time);
7389 previous_help_echo_string = help_echo_string; 7452 previous_help_echo_string = help_echo_string;
7390 help_echo_string = Qnil; 7453 help_echo_string = Qnil;
7391 7454
@@ -7497,9 +7560,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7497 SET_FRAME_GARBAGED (f); 7560 SET_FRAME_GARBAGED (f);
7498 cancel_mouse_face (f); 7561 cancel_mouse_face (f);
7499 } 7562 }
7500
7501/** FRAME_PIXEL_WIDTH (f) = event->xconfigure.width; **/
7502/** FRAME_PIXEL_HEIGHT (f) = event->xconfigure.height; **/
7503#endif /* not USE_GTK */ 7563#endif /* not USE_GTK */
7504#endif 7564#endif
7505 7565
@@ -7528,7 +7588,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7528 7588
7529 memset (&compose_status, 0, sizeof (compose_status)); 7589 memset (&compose_status, 0, sizeof (compose_status));
7530 dpyinfo->last_mouse_glyph_frame = NULL; 7590 dpyinfo->last_mouse_glyph_frame = NULL;
7531 dpyinfo->last_user_time = event->xbutton.time; 7591 x_display_set_last_user_time (dpyinfo, event->xbutton.time);
7532 7592
7533 f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame 7593 f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
7534 : x_window_to_frame (dpyinfo, event->xbutton.window)); 7594 : x_window_to_frame (dpyinfo, event->xbutton.window));
@@ -7917,6 +7977,15 @@ x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
7917 GCForeground, &xgcv); 7977 GCForeground, &xgcv);
7918 gc = dpyinfo->scratch_cursor_gc; 7978 gc = dpyinfo->scratch_cursor_gc;
7919 7979
7980 /* When on R2L character, show cursor at the right edge of the
7981 glyph, unless the cursor box is as wide as the glyph or wider
7982 (the latter happens when x-stretch-cursor is non-nil). */
7983 if ((cursor_glyph->resolved_level & 1) != 0
7984 && cursor_glyph->pixel_width > w->phys_cursor_width)
7985 {
7986 x += cursor_glyph->pixel_width - w->phys_cursor_width;
7987 wd -= 1;
7988 }
7920 /* Set clipping, draw the rectangle, and reset clipping again. */ 7989 /* Set clipping, draw the rectangle, and reset clipping again. */
7921 x_clip_to_row (w, row, TEXT_AREA, gc); 7990 x_clip_to_row (w, row, TEXT_AREA, gc);
7922 XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h - 1); 7991 XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h - 1);
@@ -8002,9 +8071,10 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
8002 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), 8071 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
8003 width, row->height); 8072 width, row->height);
8004 } 8073 }
8005 else 8074 else /* HBAR_CURSOR */
8006 { 8075 {
8007 int dummy_x, dummy_y, dummy_h; 8076 int dummy_x, dummy_y, dummy_h;
8077 int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8008 8078
8009 if (width < 0) 8079 if (width < 0)
8010 width = row->height; 8080 width = row->height;
@@ -8014,8 +8084,10 @@ x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text
8014 get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x, 8084 get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
8015 &dummy_y, &dummy_h); 8085 &dummy_y, &dummy_h);
8016 8086
8017 XFillRectangle (dpy, window, gc, 8087 if ((cursor_glyph->resolved_level & 1) != 0
8018 WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x), 8088 && cursor_glyph->pixel_width > w->phys_cursor_width)
8089 x += cursor_glyph->pixel_width - w->phys_cursor_width;
8090 XFillRectangle (dpy, window, gc, x,
8019 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y + 8091 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
8020 row->height - width), 8092 row->height - width),
8021 w->phys_cursor_width, width); 8093 w->phys_cursor_width, width);
@@ -8571,8 +8643,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
8571 FRAME_COLUMN_WIDTH (f) = font->average_width; 8643 FRAME_COLUMN_WIDTH (f) = font->average_width;
8572 FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); 8644 FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font);
8573 8645
8574#ifndef USE_X_TOOLKIT \ 8646#ifndef USE_X_TOOLKIT
8575/** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); **/
8576 FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); 8647 FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
8577#endif 8648#endif
8578 8649
@@ -9415,18 +9486,6 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height,
9415{ 9486{
9416 int pixelwidth, pixelheight; 9487 int pixelwidth, pixelheight;
9417 9488
9418/** if (pixelwise) **/
9419/** { **/
9420/** pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); **/
9421/** pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); **/
9422/** } **/
9423/** else **/
9424/** { **/
9425/** pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width); **/
9426/** pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height); **/
9427/** } **/
9428
9429/** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOLBAR_HEIGHT (f); **/
9430 pixelwidth = (pixelwise 9489 pixelwidth = (pixelwise
9431 ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) 9490 ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width)
9432 : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); 9491 : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width));
@@ -9434,16 +9493,6 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height,
9434 ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) 9493 ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height)
9435 : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))); 9494 : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height)));
9436 9495
9437/** pixelwidth = ((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f))) **/
9438/** + FRAME_SCROLL_BAR_AREA_WIDTH (f) **/
9439/** + FRAME_TOTAL_FRINGE_WIDTH (f) **/
9440/** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
9441
9442/** pixelheight = ((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f))) **/
9443/** + FRAME_TOOLBAR_HEIGHT (f) **/
9444/** + FRAME_SCROLL_BAR_AREA_HEIGHT (f) **/
9445/** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
9446
9447 if (change_gravity) f->win_gravity = NorthWestGravity; 9496 if (change_gravity) f->win_gravity = NorthWestGravity;
9448 x_wm_set_size_hint (f, 0, 0); 9497 x_wm_set_size_hint (f, 0, 0);
9449 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 9498 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
@@ -10617,7 +10666,6 @@ static unsigned x_display_id;
10617struct x_display_info * 10666struct x_display_info *
10618x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) 10667x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10619{ 10668{
10620 int connection;
10621 Display *dpy; 10669 Display *dpy;
10622 struct terminal *terminal; 10670 struct terminal *terminal;
10623 struct x_display_info *dpyinfo; 10671 struct x_display_info *dpyinfo;
@@ -10669,10 +10717,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10669 10717
10670 XSetLocaleModifiers (""); 10718 XSetLocaleModifiers ("");
10671 10719
10672 /* Emacs can only handle core input events, so make sure
10673 Gtk doesn't use Xinput or Xinput2 extensions. */
10674 xputenv ("GDK_CORE_DEVICE_EVENTS=1");
10675
10676 /* Work around GLib bug that outputs a faulty warning. See 10720 /* Work around GLib bug that outputs a faulty warning. See
10677 https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ 10721 https://bugzilla.gnome.org/show_bug.cgi?id=563627. */
10678 id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL 10722 id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
@@ -10831,8 +10875,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10831 dpyinfo->x_id = ++x_display_id; 10875 dpyinfo->x_id = ++x_display_id;
10832 dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name) 10876 dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name)
10833 + SBYTES (Vsystem_name) + 2); 10877 + SBYTES (Vsystem_name) + 2);
10834 strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"), 10878 char *nametail = lispstpcpy (dpyinfo->x_id_name, Vinvocation_name);
10835 SSDATA (Vsystem_name)); 10879 *nametail++ = '@';
10880 lispstpcpy (nametail, Vsystem_name);
10836 10881
10837 /* Figure out which modifier bits mean what. */ 10882 /* Figure out which modifier bits mean what. */
10838 x_find_modifier_meanings (dpyinfo); 10883 x_find_modifier_meanings (dpyinfo);
@@ -10886,11 +10931,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10886 { 10931 {
10887 if (dpyinfo->visual->class == PseudoColor) 10932 if (dpyinfo->visual->class == PseudoColor)
10888 { 10933 {
10889 Lisp_Object value; 10934 AUTO_STRING (privateColormap, "privateColormap");
10890 value = display_x_get_resource (dpyinfo, 10935 AUTO_STRING (PrivateColormap, "PrivateColormap");
10891 build_string ("privateColormap"), 10936 Lisp_Object value
10892 build_string ("PrivateColormap"), 10937 = display_x_get_resource (dpyinfo, privateColormap,
10893 Qnil, Qnil); 10938 PrivateColormap, Qnil, Qnil);
10894 if (STRINGP (value) 10939 if (STRINGP (value)
10895 && (!strcmp (SSDATA (value), "true") 10940 && (!strcmp (SSDATA (value), "true")
10896 || !strcmp (SSDATA (value), "on"))) 10941 || !strcmp (SSDATA (value), "on")))
@@ -11014,11 +11059,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11014 }; 11059 };
11015 11060
11016 int i; 11061 int i;
11017 const int atom_count = ARRAYELTS (atom_refs); 11062 enum { atom_count = ARRAYELTS (atom_refs) };
11018 /* 1 for _XSETTINGS_SN */ 11063 /* 1 for _XSETTINGS_SN. */
11019 const int total_atom_count = 1 + atom_count; 11064 enum { total_atom_count = 1 + atom_count };
11020 Atom *atoms_return = xmalloc (total_atom_count * sizeof *atoms_return); 11065 Atom atoms_return[total_atom_count];
11021 char **atom_names = xmalloc (total_atom_count * sizeof *atom_names); 11066 char *atom_names[total_atom_count];
11022 static char const xsettings_fmt[] = "_XSETTINGS_S%d"; 11067 static char const xsettings_fmt[] = "_XSETTINGS_S%d";
11023 char xsettings_atom_name[sizeof xsettings_fmt - 2 11068 char xsettings_atom_name[sizeof xsettings_fmt - 2
11024 + INT_STRLEN_BOUND (int)]; 11069 + INT_STRLEN_BOUND (int)];
@@ -11026,7 +11071,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11026 for (i = 0; i < atom_count; i++) 11071 for (i = 0; i < atom_count; i++)
11027 atom_names[i] = (char *) atom_refs[i].name; 11072 atom_names[i] = (char *) atom_refs[i].name;
11028 11073
11029 /* Build _XSETTINGS_SN atom name */ 11074 /* Build _XSETTINGS_SN atom name. */
11030 sprintf (xsettings_atom_name, xsettings_fmt, 11075 sprintf (xsettings_atom_name, xsettings_fmt,
11031 XScreenNumberOfScreen (dpyinfo->screen)); 11076 XScreenNumberOfScreen (dpyinfo->screen));
11032 atom_names[i] = xsettings_atom_name; 11077 atom_names[i] = xsettings_atom_name;
@@ -11037,11 +11082,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11037 for (i = 0; i < atom_count; i++) 11082 for (i = 0; i < atom_count; i++)
11038 *(Atom *) ((char *) dpyinfo + atom_refs[i].offset) = atoms_return[i]; 11083 *(Atom *) ((char *) dpyinfo + atom_refs[i].offset) = atoms_return[i];
11039 11084
11040 /* Manual copy of last atom */ 11085 /* Manually copy last atom. */
11041 dpyinfo->Xatom_xsettings_sel = atoms_return[i]; 11086 dpyinfo->Xatom_xsettings_sel = atoms_return[i];
11042
11043 xfree (atom_names);
11044 xfree (atoms_return);
11045 } 11087 }
11046 11088
11047 dpyinfo->x_dnd_atoms_size = 8; 11089 dpyinfo->x_dnd_atoms_size = 8;
@@ -11060,22 +11102,19 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11060 11102
11061 xsettings_initialize (dpyinfo); 11103 xsettings_initialize (dpyinfo);
11062 11104
11063 connection = ConnectionNumber (dpyinfo->display);
11064
11065 /* This is only needed for distinguishing keyboard and process input. */ 11105 /* This is only needed for distinguishing keyboard and process input. */
11066 if (connection != 0) 11106 if (dpyinfo->connection != 0)
11067 add_keyboard_wait_descriptor (connection); 11107 add_keyboard_wait_descriptor (dpyinfo->connection);
11068 11108
11069#ifdef F_SETOWN 11109#ifdef F_SETOWN
11070 fcntl (connection, F_SETOWN, getpid ()); 11110 fcntl (dpyinfo->connection, F_SETOWN, getpid ());
11071#endif /* ! defined (F_SETOWN) */ 11111#endif /* ! defined (F_SETOWN) */
11072 11112
11073 if (interrupt_input) 11113 if (interrupt_input)
11074 init_sigio (connection); 11114 init_sigio (dpyinfo->connection);
11075 11115
11076#ifdef USE_LUCID 11116#ifdef USE_LUCID
11077 { 11117 {
11078 XFontStruct *xfont = NULL;
11079 XrmValue d, fr, to; 11118 XrmValue d, fr, to;
11080 Font font; 11119 Font font;
11081 11120
@@ -11089,10 +11128,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11089 x_catch_errors (dpy); 11128 x_catch_errors (dpy);
11090 if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL)) 11129 if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
11091 emacs_abort (); 11130 emacs_abort ();
11092 if (x_had_errors_p (dpy) || !((xfont = XQueryFont (dpy, font)))) 11131 if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
11093 XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15"); 11132 XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
11094 if (xfont) 11133 /* Do not free XFontStruct returned by the above call to XQueryFont.
11095 XFreeFont (dpy, xfont); 11134 This leads to X protocol errors at XtCloseDisplay (Bug#18403). */
11096 x_uncatch_errors (); 11135 x_uncatch_errors ();
11097 } 11136 }
11098#endif 11137#endif
@@ -11100,11 +11139,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11100 /* See if we should run in synchronous mode. This is useful 11139 /* See if we should run in synchronous mode. This is useful
11101 for debugging X code. */ 11140 for debugging X code. */
11102 { 11141 {
11103 Lisp_Object value; 11142 AUTO_STRING (synchronous, "synchronous");
11104 value = display_x_get_resource (dpyinfo, 11143 AUTO_STRING (Synchronous, "Synchronous");
11105 build_string ("synchronous"), 11144 Lisp_Object value = display_x_get_resource (dpyinfo, synchronous,
11106 build_string ("Synchronous"), 11145 Synchronous, Qnil, Qnil);
11107 Qnil, Qnil);
11108 if (STRINGP (value) 11146 if (STRINGP (value)
11109 && (!strcmp (SSDATA (value), "true") 11147 && (!strcmp (SSDATA (value), "true")
11110 || !strcmp (SSDATA (value), "on"))) 11148 || !strcmp (SSDATA (value), "on")))
@@ -11112,11 +11150,10 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11112 } 11150 }
11113 11151
11114 { 11152 {
11115 Lisp_Object value; 11153 AUTO_STRING (useXIM, "useXIM");
11116 value = display_x_get_resource (dpyinfo, 11154 AUTO_STRING (UseXIM, "UseXIM");
11117 build_string ("useXIM"), 11155 Lisp_Object value = display_x_get_resource (dpyinfo, useXIM, UseXIM,
11118 build_string ("UseXIM"), 11156 Qnil, Qnil);
11119 Qnil, Qnil);
11120#ifdef USE_XIM 11157#ifdef USE_XIM
11121 if (STRINGP (value) 11158 if (STRINGP (value)
11122 && (!strcmp (SSDATA (value), "false") 11159 && (!strcmp (SSDATA (value), "false")
@@ -11133,8 +11170,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
11133#ifdef HAVE_X_SM 11170#ifdef HAVE_X_SM
11134 /* Only do this for the very first display in the Emacs session. 11171 /* Only do this for the very first display in the Emacs session.
11135 Ignore X session management when Emacs was first started on a 11172 Ignore X session management when Emacs was first started on a
11136 tty. */ 11173 tty or started as a daemon. */
11137 if (terminal->id == 1) 11174 if (terminal->id == 1 && ! IS_DAEMON)
11138 x_session_initialize (dpyinfo); 11175 x_session_initialize (dpyinfo);
11139#endif 11176#endif
11140 11177
@@ -11325,18 +11362,17 @@ x_delete_terminal (struct terminal *terminal)
11325 XCloseDisplay (dpyinfo->display); 11362 XCloseDisplay (dpyinfo->display);
11326#endif 11363#endif
11327#endif /* ! USE_GTK */ 11364#endif /* ! USE_GTK */
11328 }
11329 11365
11330 /* No more input on this descriptor. */ 11366 /* No more input on this descriptor. Do not close it because
11331 if (0 <= dpyinfo->connection) 11367 it's already closed by X(t)CloseDisplay (Bug#18403). */
11332 { 11368 eassert (0 <= dpyinfo->connection);
11333 delete_keyboard_wait_descriptor (dpyinfo->connection); 11369 delete_keyboard_wait_descriptor (dpyinfo->connection);
11334 emacs_close (dpyinfo->connection); 11370
11371 /* Mark as dead. */
11372 dpyinfo->display = NULL;
11373 dpyinfo->connection = -1;
11335 } 11374 }
11336 11375
11337 /* Mark as dead. */
11338 dpyinfo->display = NULL;
11339 dpyinfo->connection = -1;
11340 x_delete_display (dpyinfo); 11376 x_delete_display (dpyinfo);
11341 unblock_input (); 11377 unblock_input ();
11342} 11378}
@@ -11430,6 +11466,15 @@ x_initialize (void)
11430 XSetIOErrorHandler (x_io_error_quitter); 11466 XSetIOErrorHandler (x_io_error_quitter);
11431} 11467}
11432 11468
11469#ifdef USE_GTK
11470void
11471init_xterm (void)
11472{
11473 /* Emacs can handle only core input events, so make sure
11474 Gtk doesn't use Xinput or Xinput2 extensions. */
11475 xputenv ("GDK_CORE_DEVICE_EVENTS=1");
11476}
11477#endif
11433 11478
11434void 11479void
11435syms_of_xterm (void) 11480syms_of_xterm (void)
diff --git a/src/xterm.h b/src/xterm.h
index c8673123611..ed611f1d19f 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -434,7 +434,7 @@ extern void select_visual (struct x_display_info *);
434 434
435struct x_output 435struct x_output
436{ 436{
437#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 437#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
438 /* Height of menu bar widget, in pixels. This value 438 /* Height of menu bar widget, in pixels. This value
439 is not meaningful if the menubar is turned off. */ 439 is not meaningful if the menubar is turned off. */
440 int menubar_height; 440 int menubar_height;
@@ -654,6 +654,13 @@ struct x_output
654 int move_offset_left; 654 int move_offset_left;
655}; 655};
656 656
657/* Extreme 'short' and 'long' values suitable for libX11. */
658#define X_SHRT_MAX 0x7fff
659#define X_SHRT_MIN (-1 - X_SHRT_MAX)
660#define X_LONG_MAX 0x7fffffff
661#define X_LONG_MIN (-1 - X_LONG_MAX)
662#define X_ULONG_MAX 0xffffffffUL
663
657#define No_Cursor (None) 664#define No_Cursor (None)
658 665
659enum 666enum
@@ -1022,6 +1029,15 @@ x_display_pixel_width (struct x_display_info *dpyinfo)
1022 return WidthOfScreen (dpyinfo->screen); 1029 return WidthOfScreen (dpyinfo->screen);
1023} 1030}
1024 1031
1032INLINE void
1033x_display_set_last_user_time (struct x_display_info *dpyinfo, Time t)
1034{
1035#ifdef ENABLE_CHECKING
1036 eassert (t <= X_ULONG_MAX);
1037#endif
1038 dpyinfo->last_user_time = t;
1039}
1040
1025extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); 1041extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object);
1026extern void x_wait_for_event (struct frame *, int); 1042extern void x_wait_for_event (struct frame *, int);
1027extern void x_clear_under_internal_border (struct frame *f); 1043extern void x_clear_under_internal_border (struct frame *f);