aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog1403
-rw-r--r--src/Makefile.in8
-rw-r--r--src/alloc.c53
-rw-r--r--src/atimer.c33
-rw-r--r--src/atimer.h8
-rw-r--r--src/bidi.c39
-rw-r--r--src/buffer.c136
-rw-r--r--src/buffer.h30
-rw-r--r--src/callint.c11
-rw-r--r--src/callproc.c840
-rw-r--r--src/casefiddle.c2
-rw-r--r--src/casetab.c9
-rw-r--r--src/category.c8
-rw-r--r--src/character.c18
-rw-r--r--src/cmds.c20
-rw-r--r--src/coding.c5
-rw-r--r--src/coding.h2
-rw-r--r--src/composite.h6
-rw-r--r--src/data.c13
-rw-r--r--src/decompress.c232
-rw-r--r--src/dispextern.h175
-rw-r--r--src/dispnew.c218
-rw-r--r--src/doc.c2
-rw-r--r--src/editfns.c92
-rw-r--r--src/emacs.c10
-rw-r--r--src/emacsgtkfixed.c4
-rw-r--r--src/emacsgtkfixed.h2
-rw-r--r--src/eval.c31
-rw-r--r--src/fileio.c264
-rw-r--r--src/filelock.c33
-rw-r--r--src/font.c50
-rw-r--r--src/font.h8
-rw-r--r--src/fontset.c13
-rw-r--r--src/fontset.h3
-rw-r--r--src/frame.c132
-rw-r--r--src/frame.h49
-rw-r--r--src/fringe.c2
-rw-r--r--src/gtkutil.c124
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/image.c399
-rw-r--r--src/indent.c44
-rw-r--r--src/insdel.c36
-rw-r--r--src/intervals.c12
-rw-r--r--src/keyboard.c129
-rw-r--r--src/keyboard.h14
-rw-r--r--src/keymap.c3
-rw-r--r--src/lisp.h84
-rw-r--r--src/lisp.mk1
-rw-r--r--src/lread.c10
-rw-r--r--src/marker.c6
-rw-r--r--src/minibuf.c27
-rw-r--r--src/msdos.c65
-rw-r--r--src/nsfns.m16
-rw-r--r--src/nsfont.m12
-rw-r--r--src/nsmenu.m66
-rw-r--r--src/nsterm.h40
-rw-r--r--src/nsterm.m200
-rw-r--r--src/print.c9
-rw-r--r--src/process.c520
-rw-r--r--src/process.h16
-rw-r--r--src/profiler.c4
-rw-r--r--src/regex.c44
-rw-r--r--src/scroll.c8
-rw-r--r--src/search.c90
-rw-r--r--src/sheap.c17
-rw-r--r--src/syntax.c7
-rw-r--r--src/sysdep.c204
-rw-r--r--src/sysselect.h11
-rw-r--r--src/systime.h134
-rw-r--r--src/syswait.h3
-rw-r--r--src/term.c38
-rw-r--r--src/termcap.c4
-rw-r--r--src/termchar.h17
-rw-r--r--src/termhooks.h28
-rw-r--r--src/textprop.c41
-rw-r--r--src/w16select.c12
-rw-r--r--src/w32.c140
-rw-r--r--src/w32.h1
-rw-r--r--src/w32console.c16
-rw-r--r--src/w32fns.c16
-rw-r--r--src/w32proc.c14
-rw-r--r--src/w32term.c182
-rw-r--r--src/w32term.h6
-rw-r--r--src/window.c468
-rw-r--r--src/window.h169
-rw-r--r--src/xdisp.c685
-rw-r--r--src/xfaces.c11
-rw-r--r--src/xfns.c55
-rw-r--r--src/xfont.c6
-rw-r--r--src/xgselect.c16
-rw-r--r--src/xgselect.h10
-rw-r--r--src/xmenu.c40
-rw-r--r--src/xrdb.c18
-rw-r--r--src/xselect.c10
-rw-r--r--src/xsmfns.c3
-rw-r--r--src/xterm.c421
-rw-r--r--src/xterm.h38
97 files changed, 5021 insertions, 3765 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 69e00cadbe9..e0aa1ed577f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,1388 @@
12013-09-03 Dmitry Antipov <dmantipov@yandex.ru>
2
3 * buffer.c (drop_overlay):
4 * fileio.c (restore_point_unwind): Prefer unchain_marker to
5 Fset_marker (X, Qnil, ...) (which is the same but a bit slower).
6
72013-09-03 Dmitry Antipov <dmantipov@yandex.ru>
8
9 * buffer.c (Fmake_overlay, Fmove_overlay):
10 * intervals.c (set_point_from_marker):
11 * print.c (PRINTPREPARE): Prefer signal_error
12 to plain error and report unsuitable marker too.
13
142013-09-03 Dmitry Antipov <dmantipov@yandex.ru>
15
16 * xterm.h (struct scroll_bar): Prefer int to Lisp_Object
17 for 'dragging' member.
18 (struct x_output): Remove set-but-unused leftovers
19 'left_before_move' and 'top_before_move'.
20 * gtkutil.c (xg_set_toolkit_scroll_bar_thumb):
21 * xterm.c (xt_action_hook, xm_scroll_callback, xg_scroll_callback)
22 (xg_end_scroll_callback, xaw_jump_callback, xaw_scroll_callback)
23 (x_set_toolkit_scroll_bar_thumb, x_scroll_bar_create)
24 (x_scroll_bar_set_handle, XTset_vertical_scroll_bar)
25 (x_scroll_bar_handle_click, x_scroll_bar_note_movement)
26 (x_scroll_bar_report_motion, x_set_offset): Related users changed.
27 * xfns.c, image.c (XLIB_ILLEGAL_ACCESS): No longer needed.
28
292013-09-03 Jan Djärv <jan.h.d@swipnet.se>
30
31 * nsfont.m (INVALID_GLYPH): New define.
32 (nsfont_encode_char): Use INVALID_GLYPH.
33 (ns_uni_to_glyphs): Ditto, check for NSNullGlyph (Bug#15138).
34
352013-09-02 Dmitry Antipov <dmantipov@yandex.ru>
36
37 * xterm.c (x_last_mouse_movement_time): Revert last change.
38 This code should use XDisplayMotionBufferSize to check display's
39 motion history first, and there are few other issues as well.
40 (x_scroll_bar_note_movement): Pass XMotionEvent rather than XEvent.
41 (handle_one_xevent): Adjust user.
42
432013-09-02 Martin Rudalics <rudalics@gmx.at>
44
45 * dispnew.c (Flast_nonminibuf_frame): Move from here ...
46 * frame.c (Flast_nonminibuf_frame): ... to here.
47 (check_minibuf_window): Don't abort if no window was found
48 (Bug#15247).
49
502013-09-02 Dmitry Antipov <dmantipov@yandex.ru>
51
52 Use XGetMotionEvents to ask the last mouse motion time from X server.
53 * xterm.c (X_MOTION_HISTORY): Default to 1.
54 (x_last_mouse_movement_time) [X_MOTION_HISTORY]: New function.
55 (x_last_mouse_movement_time) [!X_MOTION_HISTORY]: Legacy version.
56 (note_mouse_movement, x_scroll_bar_note_movement) [!X_MOTION_HISTORY]:
57 Ifdef away legacy code.
58 (XTmouse_position, x_scroll_bar_report_motion):
59 Use x_last_mouse_movement_time.
60 (handle_one_xevent): Use event.xunmap and not event.xmap when handling
61 UnmapNotify event.
62
632013-09-02 Dmitry Antipov <dmantipov@yandex.ru>
64
65 * msdos.c (last_mouse_window): Move to...
66 (dos_rawgetc): ...this function and adjust comment.
67 * nsterm.m (last_window): Rename to last_mouse_window, move to...
68 (mouseMoved): ...this function and adjust comment.
69 * w32term.c (last_window): Likewise with...
70 (w32_read_socket): ...this function.
71 * xterm.c (last_window): Likewise with...
72 (handle_one_xevent): ...this function.
73
742013-09-02 Dmitry Antipov <dmantipov@yandex.ru>
75
76 * window.h (Vmouse_window, Vmouse_event): Remove the leftovers.
77 * xterm.c (toplevel): Drop obsolete comment and move compose_status...
78 (handle_one_xevent): ...to here.
79 (STORE_KEYSYM_FOR_DEBUG): Move under ENABLE_CHECKING and make no-op
80 otherwise.
81
822013-09-02 Dmitry Antipov <dmantipov@yandex.ru>
83
84 * msdos.c (IT_set_terminal_window): Remove no-op.
85 (initialize_msdos_display): Adjust terminal setup.
86 * w32console.c (w32con_set_terminal_window): Remove no-op.
87 (initialize_w32_display): Adjust terminal setup.
88 * w32term.c (w32_set_terminal_window): Remove no-op.
89 (w32_create_terminal): Adjust terminal setup.
90 * xterm.c (XTset_terminal_window): Remove no-op.
91 (x_create_terminal): Adjust terminal setup.
92
932013-09-01 Dmitry Antipov <dmantipov@yandex.ru>
94
95 * nsterm.m (ns_set_terminal_modes, ns_reset_terminal_modes):
96 Remove no-ops.
97 (ns_create_terminal): Adjust terminal setup.
98 * w32term.c (w32_set_terminal_modes, w32_reset_terminal_modes):
99 Remove no-ops.
100 (w32_create_terminal): Adjust terminal setup.
101 * xterm.c (XTset_terminal_modes, XTreset_terminal_modes):
102 Remove no-ops.
103 (x_create_terminal): Adjust terminal setup.
104
1052013-09-01 Dmitry Antipov <dmantipov@yandex.ru>
106
107 * dispextern.h (SET_TEXT_POS_FROM_MARKER): Indent.
108 (CLIP_TEXT_POS_FROM_MARKER): New macro.
109 * dispnew.c (buffer_posn_from_coords):
110 * window.c (Fwindow_end, displayed_window_lines):
111 * xdisp.c (redisplay_mode_lines): Use it.
112
1132013-09-01 Jan Djärv <jan.h.d@swipnet.se>
114
115 * fontset.c (face_for_char): Check char in the current face font first
116 if HAVE_NS (Bug#15138).
117
1182013-08-31 Martin Rudalics <rudalics@gmx.at>
119
120 * window.c (temp_output_buffer_show): Make sure window returned
121 by display_buffer is live (Bug#15213).
122
1232013-08-30 Dmitry Antipov <dmantipov@yandex.ru>
124
125 Minor cleanup to avoid forward declarations.
126 * coding.h (struct ccl_spec): Remove forward declaration.
127 * composite.h (toplevel): Include font.h.
128 (struct composition_it, struct face, struct font_metrics):
129 Remove forward declaration.
130 * dispextern.h (struct image, struct atimer): Likewise.
131 * emacsgtkfixed.h (struct frame): Likewise.
132 * emacsgtkfixed.c (toplevel): Reorder headers and drop stdio.h.
133 * font.h (struct font_driver, struct font, struct glyph_string)
134 (struct face): Remove forward declaration.
135 * fontset.h (struct face, struct font): Likewise.
136 * frame.h (toplevel): Style cleanup.
137 (enum output_method): Move to...
138 * termhooks.h (enum output_method): ...here.
139 (struct glyph, struct frame, struct ns_display_info)
140 (struct x_display_info, struct w32_display_info):
141 Remove forward declaration.
142 * xterm.h (toplevel): Include termhooks.h.
143 (struct font, struct window, struct glyph_matrix, struct frame)
144 (struct input_event, struct face, struct image): Remove forward
145 declaration.
146 * gtkutil.h (struct _widget_value): Likewise.
147 * keyboard.h (toplevel): Include termhooks.h.
148 (struct input_event): Remove forward declaration.
149
1502013-08-29 Dmitry Antipov <dmantipov@yandex.ru>
151
152 * intervals.c (set_point_from_marker): New function.
153 * editfns.c (Fgoto_char):
154 * process.c (Finternal_default_process_filter):
155 * window.c (select_window_1): Use it.
156 * buffer.h (set_point_from_marker): Add prototype.
157
1582013-08-29 Eli Zaretskii <eliz@gnu.org>
159
160 * w32.c (term_winsock): Call release_listen_threads before calling
161 WSACleanup.
162 (_sys_wait_accept): Wait for accept event in a loop with a finite
163 timeout, instead of waiting indefinitely. Will hopefully avoid
164 hanging during exit because WSACleanup deadlocks waiting for the
165 event object to be released. (Bug#14333)
166
167 * w32proc.c (release_listen_threads): New function, signals all
168 the reader threads that listen for connections to stop waiting.
169
170 * w32.h (release_listen_threads): Add prototype.
171
1722013-08-29 Dmitry Antipov <dmantipov@yandex.ru>
173
174 * alloc.c (Fmake_marker, build_marker): Zero need_adjustment
175 field of new marker (for sanity and safety).
176 * lisp.h (XSETMARKER): Remove unused macro (it doesn't work
177 anyway because XMISCTYPE is a function and can't be an lvalue).
178
1792013-08-29 Dmitry Antipov <dmantipov@yandex.ru>
180
181 * xterm.c (x_clear_area): Lost 7th arg because it is always False.
182 (x_after_update_window_line, x_scroll_bar_create):
183 (x_scroll_bar_set_handle, XTset_vertical_scroll_bar):
184 (handle_one_xevent, x_clear_frame_area):
185 * gtkutil.c (xg_clear_under_internal_border, xg_update_scrollbar_pos):
186 * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Adjust users.
187 * xterm.h (x_clear_area): Adjust prototype.
188
1892013-08-29 Dmitry Antipov <dmantipov@yandex.ru>
190
191 Hook scanning and indentation functions to find_newline. This helps
192 to avoid duplicated code and renders more respect to newline cache.
193 * lisp.h (scan_newline): Prefer ptrdiff_t to EMACS_INT.
194 * cmds.c (Fforward_line):
195 * indent.c (scan_for_column, Fcurrent_indentation, indented_beyond_p):
196 Use find_newline and avoid unnecessary point movements.
197 * search.c (scan_newline): Implement on top of find_newline.
198
1992013-08-28 Stefan Monnier <monnier@iro.umontreal.ca>
200
201 * eval.c (Ffuncall): Fix handling of ((lambda ..) ..) in lexically
202 scoped code (bug#11258).
203
2042013-08-28 Davor Cubranic <cubranic@stat.ubc.ca> (tiny change)
205
206 * nsterm.m (last_window): New variable.
207 (EV_TRAILER2): New macro.
208 (EV_TRAILER): Call EV_TRAILER2.
209 (mouseMoved:): Add support for mouse-autoselect-window
210 on nextstep (Bug#6888).
211
2122013-08-28 Andreas Schwab <schwab@suse.de>
213
214 * regex.c (CHAR_CHARSET, CHARSET_LEADING_CODE_BASE, CHAR_HEAD_P)
215 (SINGLE_BYTE_CHAR_P, SAME_CHARSET_P, MAKE_CHAR, BYTE8_TO_CHAR):
216 Remove unused macro definitions.
217 (CHARSET_RANGE_TABLE_BITS, EXTEND_RANGE_TABLE)
218 (SET_RANGE_TABLE_WORK_AREA_BIT, SET_RANGE_TABLE_WORK_AREA):
219 Only define if emacs.
220
2212013-08-28 Dmitry Antipov <dmantipov@yandex.ru>
222
223 Prefer enum glyph_row_area to int where appropriate.
224 * dispextern.h (enum glyph_row_area): Add ANY_AREA member.
225 Fix comment.
226 (window_box, window_box_width, window_box_left, window_box_left_offset)
227 (window_box_right, window_box_right_offset): Adjust prototypes.
228 * xdisp.c (window_box, window_box_width, window_box_left)
229 (window_box_left_offset, window_box_right, window_box_right_offset):
230 Use enum glyph_row_area. Adjust users and tweak comment where needed.
231 (window_box_edges): Likewise. Lost 2nd arg since it is always ANY_AREA.
232 * nsterm.m (ns_clip_to_row):
233 * w32term.c (w32_clip_to_row):
234 * xterm.c (x_clip_to_row): Likewise.
235
2362013-08-28 Dmitry Antipov <dmantipov@yandex.ru>
237
238 * buffer.c (Foverlays_at, Foverlays_in, Fnext_overlay_change)
239 (Fprevious_overlay_change): Fast path for buffer with no overlays.
240
2412013-08-28 Paul Eggert <eggert@cs.ucla.edu>
242
243 * Makefile.in (SHELL): Now @SHELL@, not /bin/sh,
244 for portability to hosts where /bin/sh has problems.
245
2462013-08-28 Dmitry Antipov <dmantipov@yandex.ru>
247
248 Redesign redisplay interface to drop global output_cursor.
249 * dispextern.h (struct redisplay_interface): Remove cursor_to member.
250 (toplevel): Remove declaration of output_cursor.
251 (set_output_cursor, x_cursor_to): Remove prototype.
252 * window.h (struct window): New member output_cursor.
253 (output_cursor_to): New function to replace RIF member.
254 * dispnew.c (redraw_overlapped_rows, update_marginal_area)
255 (update_text_area, set_window_cursor_after_update): Use it.
256 * xdisp.c (output_cursor, set_output_cursor, x_cursor_to): Remove.
257 (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
258 * nsterm.m (ns_update_window_begin, ns_update_window_end):
259 * w32term.c (x_update_window_begin, x_update_window_end):
260 * xterm.c (x_update_window_begin, x_update_window_end):
261 Adjust to use per-window output cursor.
262
2632013-08-27 Paul Eggert <eggert@cs.ucla.edu>
264
265 Simplify SELECT_TYPE-related code.
266 Like EMACS_TIME, this portability layer is no longer needed, since
267 Emacs has been using fd_set as a portability layer for some time.
268 * sysselect.h (FD_SETSIZE): Rename from MAXDESC. All uses changed.
269 (SELECT_TYPE): Remove. All uses changed to fd_set.
270 (fd_set) [!FD_SET]: New typedef.
271
272 Simplify EMACS_TIME-related code.
273 This portability layer is no longer needed, since Emacs has been
274 using struct timespec as a portability layer for some time.
275 * atimer.h, buffer.h, dispextern.h, xgselect.h:
276 Include <time.h> rather than "systime.h"; that's all that's needed now.
277 * dispnew.c: Include <timespec.h> rather than "systime.h";
278 that's all that's needed now.
279 * systime.h (EMACS_TIME): Remove. All uses changed to struct timespec.
280 (EMACS_TIME_RESOLUTION): Remove. All uses changed to
281 TIMESPEC_RESOLUTION.
282 (LOG10_EMACS_TIME_RESOLUTION): Remove. All uses changed to
283 LOG10_TIMESPEC_RESOLUTION.
284 (EMACS_SECS, emacs_secs_addr): Remove. All uses changed to tv_sec.
285 (EMACS_NSECS): Remove. All uses changed to tv_nsec.
286 (make_emacs_time): Remove. All used changed to make_timespec.
287 (invalid_timespec): Rename from invalid_emacs_time. All uses changed.
288 (current_timespec): Rename from current_emacs_time. All uses changed.
289 (add_emacs_time): Remove. All uses changed to timespec_add.
290 (sub_emacs_time): Remove. All uses change dot timespec_sub.
291 (EMACS_TIME_SIGN): Remove. All uses changed to timespec_sign.
292 (timespec_valid_p): Rename from EMACS_TIME_VALID_P. All uses changed.
293 (EMACS_TIME_FROM_DOUBLE): Remove. All uses changed to dtotimespec.
294 (EMACS_TIME_TO_DOUBLE): Remove. All uses changed to timespectod.
295 (current_timespec): Rename from current_emacs_time. All uses changed.
296 (EMACS_TIME_EQ, EMACS_TIME_LT, EMACS_TIME_LE): Remove. All uses
297 changed to timespec_cmp.
298 * xgselect.c: Include <timespec.h>, since our .h files don't.
299
3002013-08-27 Dmitry Antipov <dmantipov@yandex.ru>
301
302 * xterm.h (FONT_TYPE_FOR_UNIBYTE, FONT_TYPE_FOR_MULTIBYTE:)
303 * nsterm.h (FONT_TYPE_FOR_UNIBYTE, FONT_TYPE_FOR_MULTIBYTE):
304 Remove the leftovers.
305 * gtkutil.c (toplevel): Do not declare Qxft but include
306 font.h to do so.
307 * image.c (toplevel): Do not declare Vlibrary_cache because
308 it's already done in lisp.h.
309
3102013-08-27 Dmitry Antipov <dmantipov@yandex.ru>
311
312 * lisp.h (Mouse_HLInfo): Move from here...
313 * dispextern.h (Mouse_HLInfo): ...to here and offload lisp.h.
314 (reset_mouse_highlight): New function.
315 * msdos.c (dos_set_window_size, IT_update_begin)
316 (internal_terminal_init):
317 * nsterm.m (ns_update_window_end, x_free_frame_resources)
318 (ns_initialize_display_info):
319 * w32console.c (initialize_w32_display):
320 * w32term.c (x_update_window_end, x_free_frame_resources)
321 (w32_initialize_display_info):
322 * xterm.c (x_update_window_end, x_free_frame_resources, x_term_init):
323 * window.c (Fdelete_other_windows_internal):
324 * xdisp.c (clear_mouse_face, cancel_mouse_face): Use it.
325 * termchar.h (toplevel):
326 * xterm.h (toplevel): Include dispextern.h.
327
3282013-08-26 Paul Eggert <eggert@cs.ucla.edu>
329
330 Fix minor problems found by static checking.
331 * image.c (XGetPixel, XPutPixel) [HAVE_NS]: Now static.
332 (expect): Avoid nested-if warning.
333 (x_build_heuristic_mask) [HAVE_NS]: Avoid unused-var warning.
334 * nsmenu.m (fillWithWidgetValue:): Avoid type warning.
335 * nsterm.h, nsterm.m (ns_select):
336 * xgselect.c, xgselect.h (xg_select):
337 Adjust signature to better match pselect's.
338 * nsterm.m (ns_select):
339 Don't set *TIMEOUT, since pselect doesn't.
340 * regex.c (whitespace_regexp): Now const_re_char *, to avoid
341 diagnostic about assigning const char * to it.
342 * xfaces.c (x_display_info) [HAVE_NS]: Remove; unused.
343
3442013-08-26 Stefan Monnier <monnier@iro.umontreal.ca>
345
346 * lread.c (substitute_object_recurse): Handle hash-tables as well
347 (bug#15190).
348
3492013-08-26 Paul Eggert <eggert@cs.ucla.edu>
350
351 Fix unlikely core dump in init_tty, and simplify terminfo case.
352 * term.c (init_tty) [TERMINFO]: Fix check for buffer overrun.
353 The old version incorrectly dumped core if malloc returned a
354 buffer containing only non-NUL bytes.
355 (init_tty): Do not allocate or free termcap buffers; the
356 struct does that for us now.
357 * termchar.h (TERMCAP_BUFFER_SIZE) [!TERMINFO]: New constant.
358 (struct tty_display_info): Define members termcap_term_buffer and
359 termcap_strings_buffer only if !TERMINFO, since terminfo doesn't
360 use them. Allocate them directly in struct rather than indirectly
361 via a pointer, to simplify init_tty.
362
363 * frame.c (check_minibuf_window): Initialize 'window' properly,
364 so that Emacs reliably aborts later if 'window' is not initialized.
365
3662013-08-26 Jan Djärv <jan.h.d@swipnet.se>
367
368 * gtkutil.c (xg_initialize): Set gtk-menu-bar-accel to "" instead
369 of VoidSymbol (Bug#15154).
370
3712013-08-26 Dmitry Antipov <dmantipov@yandex.ru>
372
373 * lisp.h (Mouse_HLInfo): Drop set-but-unused members
374 mouse_face_beg_y and mouse_face_end_y.
375 * xdisp.c (note_tool_bar_highlight, mouse_face_from_buffer_pos)
376 (mouse_face_from_string_pos, note_mode_line_or_margin_highlight):
377 Adjust users and update comment where appropriate.
378
3792013-08-26 Martin Rudalics <rudalics@gmx.at>
380
381 * frame.c (check_minibuf_window): New function.
382 (delete_frame, Fmake_frame_invisible, Ficonify_frame):
383 Call check_minibuf_window (Bug#15183).
384
3852013-08-26 Dmitry Antipov <dmantipov@yandex.ru>
386
387 * window.h (struct window): Replace last_cursor with last_cursor_vpos
388 because this is the only last cursor data we need to keep and consult.
389 * window.c (replace_window, set_window_buffer, Fsplit_window_internal):
390 * xdisp.c (mark_window_display_accurate_1, try_cursor_movement):
391 Adjust users.
392
3932013-08-26 Dmitry Antipov <dmantipov@yandex.ru>
394
395 Fix recovering from possible decompression error.
396 Since insert_from_gap doesn't always move point, we can't use PT as
397 the position where the partially decompressed data ends, and
398 should count how many bytes was produced so far.
399 * decompress.c (struct decompress_unwind_data): Add nbytes member.
400 (unwind_decompress): Really delete partially uncompressed data.
401 (Fzlib_decompress_region): Take decompressed data size into account.
402
4032013-08-26 Dmitry Antipov <dmantipov@yandex.ru>
404
405 * syntax.c (init_syntax_once): Adjust comment and do an early
406 initialization of Qchar_table_extra_slots just once...
407 * casetab.c (init_casetab_once):
408 * category.c (init_category_once):
409 * character.c (syms_of_character):
410 * coding.c (syms_of_coding):
411 * xdisp.c (syms_of_xdisp): ...and omit it here.
412
4132013-08-24 Eli Zaretskii <eliz@gnu.org>
414
415 * xdisp.c (get_next_display_element): Don't apply to characters
416 from a display vector the logic of setting it->end_of_box_run_p
417 suitable for characters from a buffer. (Bug#15175)
418
419 * w32.c (fdutimens): Call 'utime', which is implemented on w32.c
420 to handle directories, rather than '_utime' which doesn't.
421 (Bug#15176)
422
4232013-08-24 Jan Djärv <jan.h.d@swipnet.se>
424
425 * gtkutil.c (x_wm_set_size_hint): Don't set hints when maximized
426 or fullscreen (Bug#14627).
427
4282013-08-24 Paul Eggert <eggert@cs.ucla.edu>
429
430 System-dependent integer overflow fixes.
431 * process.c (Fset_process_window_size): Signal an error if
432 the window size is outside the range supported by the lower level.
433 * sysdep.c (set_window_size): Return negative on error,
434 nonnegative on success, rather than -1, 0, 1 on not in system,
435 failure, success. This is simpler. Caller changed.
436 (serial_configure): Remove unnecessary initialization of local.
437 (procfs_get_total_memory) [GNU_LINUX]: Don't assume system memory
438 size fits in unsigned long; this isn't true on some 32-bit hosts.
439 Avoid buffer overrun if some future version of /proc/meminfo has a
440 variable name longer than 20 bytes.
441 (system_process_attributes) [__FreeBSD__]:
442 Don't assume hw.availpages fits in 'int'.
443
4442013-08-23 Paul Eggert <eggert@cs.ucla.edu>
445
446 Don't let very long directory names overrun the stack.
447 Fix some related minor problems involving "//", vfork.
448 * callproc.c (encode_current_directory): New function.
449 (call_process): Don't append "/"; not needed.
450 * fileio.c (file_name_as_directory_slop): New constant.
451 (file_name_as_directory): Allow SRC to be longer than SRCLEN;
452 this can save the caller having to alloca.
453 (Ffile_name_as_directory, Fdirectory_file_name, Fexpand_file_name):
454 Use SAFE_ALLOCA, not alloca.
455 (directory_file_name, Fexpand_file_name): Leave leading "//"
456 alone, since it can be special even on POSIX platforms.
457 * callproc.c (call_process):
458 * process.c (Fformat_network_address):
459 * sysdep.c (sys_subshell):
460 Use encode_current_directory rather than rolling our own.
461 (create_process): No need to encode directory; caller does that now.
462 * process.h (encode_current_directory): New decl.
463 * sysdep.c (sys_subshell): Work even if vfork trashes saved_handlers.
464 Rework to avoid 'goto xyzzy;'.
465
4662013-08-23 Eli Zaretskii <eliz@gnu.org>
467
468 * xdisp.c (handle_face_prop): If the default face was remapped use
469 the remapped face for strings from prefix properties. (Bug#15155)
470
4712013-08-23 Dmitry Antipov <dmantipov@yandex.ru>
472
473 Minor cleanup for redisplay interface and few related functions.
474 * frame.h (enum text_cursor_kinds): Move from here...
475 * dispextern.h (enum text_cursor_kinds): ...to here.
476 (toplevel): Drop unnecessary declarations.
477 (struct redisplay_interface): Use bool and enum text_cursor_kinds
478 in update_window_end_hook and draw_window_cursor functions.
479 (display_and_set_cursor, x_update_cursor): Adjust prototypes.
480 * nsterm.m (ns_update_window_end, ns_draw_window_cursor):
481 * w32term.c (x_update_window_end,w32_draw_window_cursor):
482 * xterm.c (x_update_window_end, x_draw_window_cursor):
483 * xdisp.c (display_and_set_cursor, update_window_cursor)
484 (update_cursor_in_window_tree, x_update_cursor): Use bool and
485 enum text_cursor_kinds where appropriate.
486
4872013-08-23 Dmitry Antipov <dmantipov@yandex.ru>
488
489 Redesign redisplay interface to drop updated_row and updated_area.
490 * dispextern.h (updated_row, updated_area): Remove declaration.
491 (struct redisplay_interface): Pass glyph row and row area parameters
492 to write_glyphs, insert_glyphs and clear_end_of_line functions.
493 (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
494 Adjust prototypes.
495 * dispnew.c (updated_row, updated_area): Remove.
496 (redraw_overlapped_rows, update_window_line): Adjust user.
497 (update_marginal_area, update_text_area): Likewise. Pass updated row
498 as a parameter. Prefer enum glyph_row_area to int where appropriate.
499 * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
500 Adjust users.
501
5022013-08-22 Paul Eggert <eggert@cs.ucla.edu>
503
504 * process.c (flush_pending_output): Remove stub.
505 All uses removed.
506
5072013-08-21 Paul Eggert <eggert@cs.ucla.edu>
508
509 * callproc.c: Fix race that killed background processes (Bug#15144).
510 (call_process): New arg TEMPFILE_INDEX. Callers changed.
511 Record deleted process-id in critical section, not afterwards.
512 Don't mistakenly kill process created by a call-process invocation
513 that discards output and does not wait.
514
5152013-08-21 Dmitry Antipov <dmantipov@yandex.ru>
516
517 Fix compilation with GC_MARK_STACK == GC_USE_GCPROS_AS_BEFORE
518 and GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES.
519 * alloc.c (toplevel): Remove unnecessary nested #if...#endif.
520 (mark_maybe_object) [!GC_MARK_STACK]: Define to emacs_abort
521 to shut up compiler in mark_object.
522 (dump_zombies): Convert to global and add EXTERNALLY_VISIBLE.
523
5242013-08-21 Paul Eggert <eggert@cs.ucla.edu>
525
526 * process.c (allocate_pty) [PTY_OPEN]: Set fd's FD_CLOEXEC flag.
527 We can't portably rely on PTY_OPEN doing that, even if
528 it calls posix_openpt with O_CLOEXEC.
529
5302013-08-20 Kenichi Handa <handa@gnu.org>
531
532 * character.c (string_char): Improve commentary.
533
5342013-08-20 Paul Eggert <eggert@cs.ucla.edu>
535
536 * image.c (SIGNATURE_DIGESTSIZE): Remove.
537 (struct animation_cache): Make signature a flexible array member.
538 All uses changed. This is a tad slower but may insulate us better
539 from future changes to ImageMagick.
540
5412013-08-19 Paul Eggert <eggert@cs.ucla.edu>
542
543 * image.c: Shrink memory needed for animation cache.
544 (SIGNATURE_DIGESTSIZE): New constant.
545 (struct animation_cache): Make 'signature' a fixed size array of bytes.
546 (imagemagick_create_cache): Copy the signature. This saves
547 several KB of memory that ImageMagick wastes per signature.
548 Don't bother updating the update_time, as the caller does that now.
549 (imagemagick_prune_animation_cache): Don't destroy the signature, as
550 it's a fixed size struct member now.
551 (imagemagick_get_animation_cache): Always destroy the signature,
552 as it's now imagemagick_create_cache's responsibility to copy it.
553 Avoid duplicate calls to strcmp and to imagemagick_create_cache,
554 and use memcmp rather than strcmp.
555 eassert that ImageMagick returns a signature of the specified length.
556
5572013-08-19 Lars Magne Ingebrigtsen <larsi@gnus.org>
558
559 * image.c (imagemagick_get_animation_cache): Don't segfault on
560 each invocation.
561 (imagemagick_get_animation_cache): Revert to previous definition
562 so that it actually works. But keep the memory leak fix.
563 (imagemagick_get_animation_cache): Fix memory leak.
564
5652013-08-19 Paul Eggert <eggert@cs.ucla.edu>
566
567 * image.c: Fix animation cache signature memory leak.
568 Fix some other minor performance problems while we're at it.
569 (imagemagick_create_cache): Clear just the members that
570 need clearing. Don't set update_time, as caller does that now.
571 (imagemagick_prune_animation_cache, imagemagick_get_animation_cache):
572 Simplify by using pointer-to-pointer instead of a prev pointer.
573 (imagemagick_prune_animation_cache): Use make_emacs_time rather
574 than EMACS_TIME_FROM_DOUBLE, and DestroyString rather than free.
575 (imagemagick_get_animation_cache): Don't xstrdup the image signature;
576 it's already a copy. Free the signature probe unless it's cached.
577
578 * process.c (handle_child_signal): Fix crash; deleted pid (Bug#15106).
579 This was introduced by my 2013-08-12 fix for Bug#15035.
580
5812013-08-19 Dmitry Antipov <dmantipov@yandex.ru>
582
583 * image.c (imagemagick_create_cache, imagemagick_get_animation_cache)
584 (imagemagick_prune_animation_cache): Now static.
585
5862013-08-18 Lars Magne Ingebrigtsen <larsi@gnus.org>
587
588 * image.c (imagemagick_get_animation_cache): Don't segfault when
589 pruning all entries.
590
5912013-08-18 Ken Brown <kbrown@cornell.edu>
592
593 * sheap.c (STATIC_HEAP_SIZE): Adjust to current needs; use bigger
594 static heap if ENABLE_CHECKING is defined.
595 (max_bss_sbrk_ptr): New variable.
596 (bss_sbrk): Use it.
597 (report_sheap_usage): Report maximum static heap usage instead of
598 ending static heap usage.
599
6002013-08-17 Eli Zaretskii <eliz@gnu.org>
601
602 * decompress.c (Fzlib_available_p) [WINDOWSNT]: Update the value
603 of zlib_initialized according to the results of calling
604 init_zlib_functions.
605
6062013-08-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
607
608 * image.c: Implement an ImageMagick per-image cache.
609 (imagemagick_get_animation_cache): Fix a double-free error.
610 (imagemagick_load_image): Remove the ping_wand code, which only
611 apparently saved time on invalid animated images, and slowed down
612 everything else. Optimise for the common case.
613
6142013-08-16 Xue Fuqiao <xfq.free@gmail.com>
615
616 * buffer.c (syms_of_buffer) <buffer-undo-list>: Doc fix.
617
618 * editfns.c (insert_before_markers): Mention overlay in the doc string.
619
620 * marker.c (set_marker): Remove documentation of undefined behavior.
621
6222013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org>
623
624 * image.c (imagemagick_compute_animated_image): Animate correctly
625 when sub-images are smaller than the main image.
626 (imagemagick_compute_animated_image): Setting the iterator row to
627 zero is apparently not allowed.
628 (imagemagick_compute_animated_image): Allow images that say they
629 have sub-images that are bigger than the main image, but just crop
630 them.
631
6322013-08-15 Jan Djärv <jan.h.d@swipnet.se>
633
634 * nsmenu.m (menuWillOpen:): Fix preprocessor test (Bug#15001).
635
6362013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org>
637
638 * image.c (imagemagick_compute_animated_image): Respect the GIF
639 disposal methods.
640
6412013-08-15 Ken Brown <kbrown@cornell.edu>
642
643 * emacs.c (main): Update comment about G_SLICE_ALWAYS_MALLOC.
644 * gmalloc.c (memalign) [CYGWIN]: Revert last change; it's not
645 needed.
646
6472013-08-15 Paul Eggert <eggert@cs.ucla.edu>
648
649 Fix minor problems found by static checking.
650 * frame.c (delete_frame):
651 * xdisp.c (next_element_from_display_vector):
652 Avoid uninitialized local.
653 * image.c (imagemagick_compute_animated_image): Port to C89.
654 Prefer usual GNU indentation style for loops.
655 Be more careful about bizarrely large sizes, by using ptrdiff_t
656 instead of int.
657
6582013-08-15 Dmitry Antipov <dmantipov@yandex.ru>
659
660 Fix infinite frame selection loop (Bug#15025).
661 * frame.c (delete_frame): Prefer fast ad-hoc loop to next_frame.
662
6632013-08-15 Eli Zaretskii <eliz@gnu.org>
664
665 * xdisp.c (compute_window_start_on_continuation_line):
666 When WORD_WRAP is in effect, use move_it_to instead of move_it_by_lines
667 to make sure we end up setting the window start at the leftmost
668 visible character of the display line. This avoids funky
669 horizontal shifting because the window start is not kept on the
670 same position. (Bug#15090)
671 (next_element_from_display_vector): Support 'box' face attribute
672 in the face definitions of a display vector. (Bug#15099)
673
6742013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org>
675
676 * image.c (imagemagick_compute_animated_image): Implement animated
677 images (bug#14700).
678 (imagemagick_compute_animated_image): Fix some compilation
679 warnings. Implement a very simple cache to make the animation
680 usable at all, but it should be replaced with a per-image cache.
681
6822013-08-15 Dmitry Antipov <dmantipov@yandex.ru>
683
684 * lisp.h (FOR_EACH_ALIST_VALUE): New macro
685 to do `for' loops over alist values.
686 * buffer.h (FOR_EACH_BUFFER):
687 * process.c (FOR_EACH_PROCESS): Use it.
688 (handle_child_signal, status_notify, Fget_buffer_process)
689 (kill_buffer_processes): Use FOR_EACH_PROCESS.
690
6912013-08-15 Dmitry Antipov <dmantipov@yandex.ru>
692
693 * term.c (get_named_tty, create_tty_output, tty_free_frame_resources)
694 (tty_free_frame_resources, delete_tty): Prefer eassert to emacs_abort.
695 * image.c (make_image_cache): For struct image_cache, prefer xmalloc
696 to xzalloc and so avoid redundant call to memset.
697 * xterm.c (x_term_init): Avoid unnecessary initializations of dpyinfo
698 members because it is allocated with xzalloc and so already zeroed.
699
7002013-08-14 Ken Brown <kbrown@cornell.edu>
701
702 * gmalloc.c (memalign) [CYGWIN]: Rename to emacs_memalign
703 (Bug#15094).
704
7052013-08-14 Dmitry Antipov <dmantipov@yandex.ru>
706
707 Utility function and macro to copy Lisp string to C string.
708 * lisp.h (xlispstrdupa): New macro.
709 (xlispstrdup): New prototype.
710 * alloc.c (xlispstrdup): New function.
711 * callint.c (Fcall_interactively):
712 * fileio.c (Ffile_name_directory, Fexpand_file_name)
713 (Fsubstitute_in_file_name):
714 * frame.c (Fmake_terminal_frame): Use xlispstrdupa.
715 * image.c (x_create_bitmap_from_file):
716 * w32term.c (w32_term_init):
717 * xterm.c (x_term_init): Use xlispstrdup.
718
7192013-08-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
720
721 * image.c (imagemagick_load_image): Make animated pictures work.
722 There's still some problems with background color settings, though
723 (bug#14700).
724
725 * decompress.c (unwind_decompress): Always restore point.
726
7272013-08-14 Xue Fuqiao <xfq.free@gmail.com>
728
729 * marker.c (set_marker): Reformat documentation.
730
7312013-08-14 Paul Eggert <eggert@cs.ucla.edu>
732
733 * xdisp.c (cursor_type_changed): Now static.
734
735 * image.c (imagemagick_filename_hint): New arg HINT_BUFFER.
736 Use changed. This avoids the need to call xmalloc and for the
737 caller to call xfree, and avoids memory leaks in some situations.
738
7392013-08-14 Dmitry Antipov <dmantipov@yandex.ru>
740
741 * xdisp.c (adjust_window_ends): Move duplicated code to new function.
742 (try_window, try_window_reusing_current_matrix, try_window_id): Use it.
743 (redisplay_window): If window_end_valid is cleared due to non-zero
744 windows_or_buffers_changed, clear current_matrix_up_to_date_p and
745 so do not call to try_cursor_movement for that window.
746
7472013-08-14 Dmitry Antipov <dmantipov@yandex.ru>
748
749 * window.h (struct window): Convert window_end_pos and
750 window_end_vpos from Lisp_Object to ptrdiff_t and int, respectively.
751 (wset_window_end_pos, wset_window_end_vpos): Remove.
752 * dispnew.c (adjust_glyph_matrix):
753 * window.c (Fwindow_end, replace_window, set_window_buffer)
754 (make_window):
755 * xdisp.c (check_window_end, move_it_to, redisplay_internal)
756 (set_vertical_scroll_bar, redisplay_window, try_window)
757 (try_window_reusing_current_matrix, find_first_unchanged_at_end_row)
758 (try_window_id, decode_mode_spec, mouse_face_from_buffer_pos)
759 (note_mouse_highlight): Adjust users.
760 (try_cursor_movement): Likewise. Convert old precondition to eassert.
761 Add comment.
762
7632013-08-14 Dmitry Antipov <dmantipov@yandex.ru>
764
765 Fix --enable-gcc-warnings errors introduced in 2013-08-13 commit.
766 * image.c (imagemagick_filename_hint): Use `const char *' and
767 prefer SSDATA to SDATA to avoid warnings.
768
7692013-08-14 Dmitry Antipov <dmantipov@yandex.ru>
770
771 Cleanup window fringes, margins and scroll bars adjustments.
772 * window.c (set_window_fringes, set_window_margins)
773 (set_window_scroll_bars, apply_window_adjustment): New functions.
774 (set_window_buffer, Fset_window_margins, Fset_window_fringes)
775 (Fset_window_scroll_bars): Use them.
776
7772013-08-14 Dmitry Antipov <dmantipov@yandex.ru>
778
779 * window.h (struct window): Convert scroll_bar_width
780 from Lisp_Object to integer. Adjust comment.
781 (WINDOW_CONFIG_SCROLL_BAR_WIDTH, WINDOW_CONFIG_SCROLL_BAR_COLS):
782 Adjust users.
783 * window.c (wset_scroll_bar_width): Remove.
784 (make_window): Initialize scroll_bar_width.
785 (Fsplit_window_internal): Use direct assignment.
786 (Fset_window_configuration, save_window_save):
787 Convert Lisp_Object to integer and back where appropriate.
788 (Fset_window_scroll_bars): Adjust user. Return t if any scroll
789 bar was actually changed, and mention this in docstring.
790
7912013-08-13 Paul Eggert <eggert@cs.ucla.edu>
792
793 * decompress.c: Minor simplifications.
794 (Fzlib_decompress_region): Don't bother verifying
795 that avail_out <= UINT_MAX, as that was confusing.
796 Mention the restriction in a comment instead.
797 Prefer 'int' to 'ptrdiff_t' when 'int' is wide enough.
798
7992013-08-13 Jan Djärv <jan.h.d@swipnet.se>
800
801 * nsmenu.m (x_activate_menubar): Check for OSX >= 10.5
802 (trackingNotification:): Call ns_check_menu_open only for OSX >= 10.5.
803
8042013-08-13 Lars Magne Ingebrigtsen <larsi@gnus.org>
805
806 * image.c (imagemagick_filename_hint): Check for errors in the
807 alist structure.
808
8092013-08-13 Eli Zaretskii <eliz@gnu.org>
810
811 * window.c (Fwindow_margins): Return nil when there's no marginal
812 area, as per the documented API.
813
814 * w32term.c (x_scroll_bar_create): Use ALLOCATE_PSEUDOVECTOR, not
815 Fmake_vector, as scroll bar's struct members are not all Lisp
816 objects now. This avoids crashes in GC.
817
818 * w32term.h (struct scroll_bar): Convert fringe_extended_p to a
819 bool, so its address could be taken.
820
8212013-08-13 Lars Magne Ingebrigtsen <larsi@gnus.org>
822
823 * image.c (imagemagick_filename_hint): New function to possibly
824 apply `image-content-type-suffixes'.
825 (imagemagick_load_image): Use it.
826
8272013-08-13 Eli Zaretskii <eliz@gnu.org>
828
829 * decompress.c (Fzlib_decompress_region) [WINDOWSNT]: Return Qnil
830 if loading zlib failed.
831
8322013-08-13 Jan Djärv <jan.h.d@swipnet.se>
833
834 * nsterm.m (ns_set_vertical_scroll_bar): Fix breakage intruduced by
835 2013-08-13 checkin below. Change bool to BOOL, rule is:
836 All Obj-C code uses BOOL, except for interfaces callable from C.
837
838 * nsterm.h: Fix CGFloat for OSX 10.4 (Bug#15086).
839
8402013-08-13 Dmitry Antipov <dmantipov@yandex.ru>
841
842 * window.h (WINDOW_FRINGE_EXTENDED_P): New macro.
843 * nsterm.m (ns_set_vertical_scroll_bar): Use it. Use convenient
844 bool instead of BOOL.
845 * w32term.h (struct scroll_bar): Convert fringe_extended_p
846 from Lisp_Object to bitfield. Adjust comment.
847 * w32term.c (x_scroll_bar_create): Adjust user.
848 Use WINDOW_FRINGE_EXTENDED_P and bool for boolean.
849 * xterm.c (XTset_vertical_scroll_bar): Likewise.
850 Use bool for boolean.
851 * xterm.h (struct scroll_bar): Prefer commonly used `unsigned'
852 to `unsigned int' when defining a bitfield.
853
8542013-08-13 Paul Eggert <eggert@cs.ucla.edu>
855
856 * decompress.c (Fzlib_decompress_region): Try to clarify 'avail_out'.
857
8582013-08-13 Dmitry Antipov <dmantipov@yandex.ru>
859
860 * window.h (struct window): Convert left_margin_cols and
861 right_margin_cols from Lisp_Objects to integers. Adjust comment.
862 (WINDOW_LEFT_MARGIN_COLS, WINDOW_RIGHT_MARGIN_COLS)
863 (WINDOW_LEFT_MARGIN_WIDTH, WINDOW_RIGHT_MARGIN_WIDTH):
864 Adjust users.
865 * dispnew.c (margin_glyphs_to_reserve): Convert 3rd arg to int.
866 Adjust comment.
867 (showing_window_margins_p, update_window_line, update_frame_1):
868 * fringe.c (draw_fringe_bitmap_1):
869 * xdisp.c (window_box_width): Adjust users.
870 * window.c (wset_left_margin_cols, wset_right_margin_cols): Remove.
871 (adjust_window_margins, set_window_buffer, Fsplit_window_internal):
872 Use direct assignment.
873 (Fset_window_configuration, save_window_save, Fwindow_margins):
874 Convert Lisp_Object to integer and back where appropriate.
875 (Fset_window_margins): Adjust user. Return t if any margin
876 was actually changed, and mention this in docstring.
877
8782013-08-13 Xue Fuqiao <xfq.free@gmail.com>
879
880 * syntax.c (forward_word):
881 * cmds.c (forward_char, backward_char): Mention the optional argument.
882
8832013-08-13 Dmitry Antipov <dmantipov@yandex.ru>
884
885 * window.h (struct window): Convert left_fringe_width
886 and right_fringe_width from Lisp_Objects to integers.
887 Adjust comment.
888 (WINDOW_FRINGE_COLS, WINDOW_LEFT_FRINGE_WIDTH)
889 (WINDOW_RIGHT_FRINGE_WIDTH): Adjust users.
890 * window.c (wset_left_fringe_width, wset_right_fringe_width):
891 Remove.
892 (make_window): Initialize new integer fields to -1.
893 (Fsplit_window_internal): Use direct assignment.
894 (Fset_window_configuration, save_window_save):
895 Convert Lisp_Object to integer and back where appropriate.
896 (Fset_window_fringes): Adjust user. Return t if any fringe
897 was actually changed, and mention this in docstring.
898
8992013-08-13 Dmitry Antipov <dmantipov@yandex.ru>
900
901 * keyboard.c (Fdiscard_input): Do not increment update_mode_lines.
902 * nsfns.m (x_set_cursor_type):
903 * w32fns.c (x_set_cursor_type):
904 * xfns.m (x_set_cursor_type): Do not set cursor_type_changed here...
905 * xdisp.c (set_frame_cursor_types): ...but in common code.
906
9072013-08-13 Dmitry Antipov <dmantipov@yandex.ru>
908
909 * font.c (clear_font_cache): New function, stripped from...
910 (Fclear_font_cache): ...here, which now uses the function
911 above. Adjust comment.
912 * font.h (clear_font_cache): Add prototype.
913 * xfaces.c (clear_face_cache): Use clear_font_cache.
914
9152013-08-13 Dmitry Antipov <dmantipov@yandex.ru>
916
917 * window.c (Fset_window_start): Compare `w', not `window' because
918 `w' might not be equal to `window' after call to decode_live_window.
919
9202013-08-12 Paul Eggert <eggert@cs.ucla.edu>
921
922 * process.c (deactivate_process): Reset fds to -1 (Bug#15035).
923 This fixes a problem introduced by the Bug#15035 patch
924 when using GPG. Reported by Herbert J. Skuhra.
925
9262013-08-12 Eli Zaretskii <eliz@gnu.org>
927
928 * decompress.c <zlib_initialized> [WINDOWSNT]: New static variable.
929 (Fzlib_decompress_region) [WINDOWSNT]: Call init_zlib_functions if
930 not yet initialized.
931
9322013-08-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
933
934 * decompress.c (Fzlib_decompress_region): Support zlib
935 decompression, too, and rename.
936
9372013-08-12 Paul Eggert <eggert@cs.ucla.edu>
938
939 Minor zlib configuration tweaks.
940 * decompress.c (fn_inflateInit2) [!WINDOWSNT]:
941 Don't assume presence of fn_inflateInit2_ zlib internal function.
942
9432013-08-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
944
945 * decompress.c (Fzlib_decompress_gzipped_region): Rename to
946 include the zlib prefix.
947
9482013-08-12 Eli Zaretskii <eliz@gnu.org>
949
950 * decompress.c [WINDOWSNT]: Include windows.h and w32.h.
951 (DEF_ZLIB_FN, LOAD_ZLIB_FN) [WINDOWSNT]: New macros. Use them to
952 define static variables that are pointers to zlib functions to be
953 dynamically loaded.
954 (init_zlib_functions) [WINDOWSNT]: New function.
955 (fn_inflateInit2_, fn_inflate, fn_inflateEnd, fn_inflateInit2):
956 New macros.
957 (Fdecompress_gzipped_region, unwind_decompress): Use the fn_*
958 macros instead of invoking the zlib functions directly.
959 (syms_of_decompress): DEFSYM Qzlib_dll.
960 Staticpro Szlib_available_p.
961
9622013-08-12 Dmitry Antipov <dmantipov@yandex.ru>
963
964 Avoid looping over all frame windows to freeze and unfreeze.
965 * window.h (struct window): Drop frozen_window_start_p.
966 (freeze_window_starts): Drop prototype.
967 * frame.h (struct frame): New frozen_window_starts flag.
968 (FRAME_WINDOWS_FROZEN): New macro.
969 * window.c (freeze_window_start, freeze_window_starts):
970 Remove.
971 (select_window, replace_window): Adjust users.
972 * xdisp.c (resize_mini_window): Use FRAME_WINDOWS_FROZEN.
973 (window_frozen_p): New function.
974 (redisplay_window): Use it.
975
9762013-08-12 Paul Eggert <eggert@cs.ucla.edu>
977
978 Fix some fd issues when running subprocesses (Bug#15035).
979 Fix bugs that can leak files or file descriptors on errors.
980 Don't unlink open temp files, as that's hard for users to diagnose
981 when things go awry (e.g., temp disk exhausted).
982 Don't bother to lock temp files. Check for invalid recursion.
983 * callproc.c (synch_process_fd): Remove. All uses removed.
984 (synch_process_tempfile): New var or macro.
985 (CALLPROC_STDOUT, CALLPROC_STDERR, CALLPROC_PIPEREAD, CALLPROC_FDS):
986 New constants.
987 (record_kill_process): New arg, the temp name. All callers changed.
988 (delete_temp_file): Now just a simple wrapper around unlink.
989 (call_process_kill): New arg, the call_process_fd array.
990 Close them all. Clear synch_process_pid. Remove the temp file,
991 or arrange for it to be removed.
992 (call_process_cleanup) [MSDOS]: Arg no longer contains file name;
993 that's been moved to synch_process_tempfile. Caller changed.
994 Do not remove the tempfile; that's now call_process_kill's
995 responsibility.
996 (call_process_cleanup) [!MSDOS]: Do not record unwind-protect for
997 call_process_kill; the caller now does that.
998 (call_process_cleanup): Do not close the process fd; that's now
999 call_process_kill's responsibility.
1000 (Fcall_process): Implement via new function call_process, which
1001 has most of the old body of Fcall_process, but with a different API.
1002 (call_process): New function that does not open or close filefd if
1003 it is nonnegative. Record which fds need to be closed, and let
1004 call_process_kill close (and remove the tempfile, on MSDOS) on error.
1005 Signal an error if invoked recursively (could be done via a hook).
1006 Simplify creation of the tempfile in the MSDOS case.
1007 Don't create the output file until after checking for the executable.
1008 Report any failure to open /dev/null.
1009 Don't open /dev/null for writing twice; once is enough.
1010 Don't create pipe if all output is being discarded or sent to file.
1011 Don't worry about setting up the coding system or reading from the
1012 pipe if all output is being discarded.
1013 Hoist fd_error local into top level, to lessen block nesting.
1014 Don't record deleted pid here; now done by Fcall_process_region.
1015 (Fcall_process) [MSDOS]: Report mktemp failure immediately,
1016 and note its success in synch_process_tempfile.
1017 Do not leak resources when child_setup fails.
1018 (Fcall_process) [!MSDOS && !WINDOWSNT]: Remove duplicate assignment
1019 to child_errno. Remove unnecessary close of fd0; it's close-on-exec.
1020 (create_temp_file): Now returns open fd, with an additional
1021 Lisp_Object * argument to return the name. All callers changed.
1022 Do not close the file; rewind it instead, and leave it open for
1023 the caller. Do not lock the temp file. Unwind-protect the file
1024 and the file-descriptor.
1025 (Fcall_process_region): If the input is /dev/null, unwind-protect it.
1026 If an asynchrounous process, record it here, not in call_process.
1027 (syms_of_callproc) [MSDOS]: Initialize synch_process_tempfile.
1028 * eval.c (set_unwind_protect): New function.
1029 * fileio.c (write_region): New function, generalized from the
1030 old Fwrite_region. Do not lock temp files.
1031 (Fwrite_region): Use it.
1032 * lisp.h (set_unwind_protect, write_region): New decls.
1033 * process.c: Include <verify.h>.
1034 (make_process): Mark fds as initially closed.
1035 (deleted_pid_list): Now a list of pid-filename pairs.
1036 All uses changed.
1037 (close_process_fd): New function.
1038 (SUBPROCESS_STDIN, WRITE_TO_SUBPROCESS, READ_FROM_SUBPROCESS)
1039 (SUBPROCESS_STDOUT, READ_FROM_EXEC_MONITOR, EXEC_MONITOR_OUTPUT):
1040 New constants. Verify that their number matches PROCESS_OPEN_FDS.
1041 (create_process, create_pty, Fmake_serial_process)
1042 (server_accept_connection): Record which fds need to be closed,
1043 and let deactivate_process close them.
1044 (Fmake_network_process): Do not discard the unwind-protect
1045 until it's safe to do so.
1046 (deactivate_process): Close the fds opened by create_process etc.
1047 (Fprocess_send_eof): Adjust to new way of recording open fds.
1048 Report an error if /dev/null can't be opened, instead of aborting.
1049 * process.h (PROCESS_OPEN_FDS): New constant.
1050 (struct Lisp_Process): New member open_fds.
1051 (record_kill_process, record_deleted_pid): Adjust signatures.
1052 (record_deleted_pid): Move decl here ...
1053 * syswait.h (record_deleted_pid): ... from here.
1054
10552013-08-11 Paul Eggert <eggert@cs.ucla.edu>
1056
1057 * decompress.c: Fix bugs with large buffers and weird inputs.
1058 Tune a bit. Reindent as per usual Emacs style.
1059 (BUFFER_SIZE): Remove.
1060 (Fdecompress_gzipped_region): Do not mishandle input buffers with
1061 more than UINT_MAX bytes. Decompress into the gap instead of into
1062 an auto buffer, as this should avoid copying. Return nil if
1063 'inflate' returns Z_NEED_DICT, as we have no dictionary. Do not
1064 set immediate_quit; we shouldn't trust zlib code that much.
1065
10662013-08-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
1067
1068 * decompress.c (Fdecompress_gzipped_region): Respect all zlib
1069 errors, and really move the gap to where we want it.
1070
1071 * lisp.h: Include decompress.c support.
1072
1073 * emacs.c (main): Include decompress.c support.
1074
1075 * Makefile.in: Include -lz if present.
1076
10772013-08-11 Jan Djärv <jan.h.d@swipnet.se>
1078
1079 * nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:frame:
1080 (initWithTitle:): Initialize frame to 0.
1081 (fillWithWidgetValue:): Call fillWithWidgetValue:frame.
1082 (fillWithWidgetValue:frame:): Rename from
1083 fillWithWidgetValue:setDelegate, call initWithTile:frame: if f.
1084
1085 * nsterm.h (EmacsMenu): fillWithWidgetValue:setDelegate renamed to
1086 fillWithWidgetValue:frame:
1087
1088 * nsfns.m (Fns_convert_utf8_nfd_to_nfc): Allocate and release pool to
1089 remove memory leak warnings.
1090
1091 * nsterm.m (menu_pending_title, ns_get_pending_menu_title): Remove.
1092 (ns_check_menu_open): Handle menu == nil. Remove assignment to
1093 menu_pending_title.
1094
1095 * nsmenu.m (ns_update_menubar): Call fillWithWidgetValue:setDelegate.
1096 (x_activate_menubar): Update the whole menu.
1097 (trackingNotification:): Call ns_check_menu_open if tracking ends.
1098 (menuWillOpen:): Increment trackingMenu. For OSX <= 10.6, exit if
1099 current event is not NSSystemDefined (Bug#15001).
1100 Call ns_check_menu_open only if trackingMenu is 2.
1101 (menuDidClose:): New method, decrease trackingMenu.
1102 (fillWithWidgetValue:setDelegate:): New method.
1103 (fillWithWidgetValue:): Call the above.
1104
1105 * nsterm.h (EmacsMenu): Add fillWithWidgetValue:setDelegate:
1106
11072013-08-11 Paul Eggert <eggert@cs.ucla.edu>
1108
1109 Omit some unnecessary casts.
1110 Many of these go back to the old pre-C89 days, when they may have
1111 been needed, but we've been assuming C89 or later for a while now.
1112 * alloc.c (live_string_p, live_cons_p, live_symbol_p)
1113 (live_float_p, live_misc_p, live_vector_p):
1114 * buffer.c (compare_overlays, cmp_for_strings, mmap_find)
1115 (mmap_alloc, alloc_buffer_text, enlarge_buffer_text)
1116 (defvar_per_buffer):
1117 * callint.c (Fcall_interactively):
1118 * doc.c (Fsubstitute_command_keys):
1119 * filelock.c (get_boot_time):
1120 * frame.c (xrdb_get_resource):
1121 * gtkutil.c (hierarchy_ch_cb, qttip_cb, style_changed_cb)
1122 (delete_cb, xg_dialog_response_cb, xg_maybe_add_timer)
1123 (xg_get_file_name_from_selector, menuitem_destroy_callback)
1124 (menuitem_highlight_callback, menu_destroy_callback)
1125 (xg_update_menu_item, xg_modify_menubar_widgets, menubar_map_cb)
1126 (xg_tool_bar_callback, xg_get_tool_bar_widgets)
1127 (xg_tool_bar_detach_callback, xg_tool_bar_attach_callback)
1128 (xg_tool_bar_help_callback, tb_size_cb):
1129 * image.c (xpm_alloc_color, png_read_from_memory)
1130 (png_read_from_file, png_load_body, our_memory_skip_input_data)
1131 (jpeg_memory_src, jpeg_file_src, imagemagick_load_image)
1132 (syms_of_image):
1133 * keymap.c (describe_map):
1134 * nsfns.m (Fns_display_monitor_attributes_list):
1135 * nsmenu.m (process_dialog:):
1136 * nsterm.m (hold_event):
1137 * process.c (wait_reading_process_output):
1138 * regex.c (REGEX_REALLOCATE, re_set_registers, re_exec, regexec):
1139 * scroll.c (do_direct_scrolling, scrolling_1):
1140 * termcap.c (tgetent):
1141 * window.c (check_window_containing, add_window_to_list)
1142 (freeze_window_starts):
1143 * xdisp.c (compare_overlay_entries, vmessage):
1144 * xfns.c (x_window, x_get_monitor_attributes_xinerama)
1145 (x_get_monitor_attributes_xrandr)
1146 (Fx_display_monitor_attributes_list, x_display_info_for_name)
1147 (Fx_open_connection, file_dialog_cb, file_dialog_unmap_cb):
1148 * xfont.c (xfont_match, xfont_open):
1149 * xmenu.c (x_menu_wait_for_event, menu_highlight_callback)
1150 (menubar_selection_callback, menu_position_func)
1151 (popup_selection_callback, create_and_show_popup_menu)
1152 (dialog_selection_callback, create_and_show_dialog):
1153 * xrdb.c (x_get_string_resource):
1154 (main) [TESTRM]:
1155 * xsmfns.c (x_session_check_input):
1156 * xterm.c (x_draw_glyphless_glyph_string_foreground)
1157 (xm_scroll_callback, xg_scroll_callback, xg_end_scroll_callback)
1158 (xaw_jump_callback, xaw_scroll_callback):
1159 Omit unnecessary casts.
1160
11612013-08-10 Paul Eggert <eggert@cs.ucla.edu>
1162
1163 Minor string-length refactoring.
1164 * alloc.c (xstrdup): Use memcpy, not strcpy, since the length's known.
1165 * frame.c (make_monitor_attribute_list):
1166 Prefer build_string to strlen + make_string.
1167
11682013-08-10 Jan Djärv <jan.h.d@swipnet.se>
1169
1170 * xterm.c (x_error_handler): Also ignore BadWindow for X_SetInputFocus,
1171 don't check minor_code (Bug#14417).
1172
11732013-08-09 Eli Zaretskii <eliz@gnu.org>
1174
1175 * xdisp.c (draw_glyphs): Don't compare row pointers, compare row
1176 vertical positions instead. This avoids calling MATRIX_ROW with
1177 row numbers that are possibly beyond valid limits. (Bug#15064)
1178
11792013-08-09 Dmitry Antipov <dmantipov@yandex.ru>
1180
1181 Use xstrdup and build_unibyte_string where applicable.
1182 * alloc.c (xstrdup): Tiny cleanup. Add eassert.
1183 * xfns.c (x_window):
1184 * xrdb.c (x_get_customization_string):
1185 * xterm.c (xim_initialize):
1186 * w32fns.c (w32_window): Use xstrdup.
1187 (w32_display_monitor_attributes_list):
1188 * emacs.c (init_cmdargs):
1189 * keyboard.c (PUSH_C_STR):
1190 * nsfont.m (nsfont_open):
1191 * sysdep.c (system_process_attributes):
1192 * w32.c (system_process_attributes):
1193 * xdisp.c (message1, message1_nolog): Use build_unibyte_string.
1194
11952013-08-09 Eli Zaretskii <eliz@gnu.org>
1196
1197 * w32.c (PEXCEPTION_POINTERS, PEXCEPTION_RECORD, PCONTEXT): Define
1198 variables of these types so that GDB would know about them, as aid
1199 for debugging fatal exceptions. (Bug#15024) See also
1200 http://sourceware.org/ml/gdb/2013-08/msg00010.html for related
1201 discussions.
1202
12032013-08-08 Jan Djärv <jan.h.d@swipnet.se>
1204
1205 * nsterm.m (ns_update_begin): Don't change clip path if it would be
1206 larger than the NSWindow (Bug#14934).
1207
12082013-08-08 Dmitry Antipov <dmantipov@yandex.ru>
1209
1210 Redesign redisplay interface to drop global variable updated_window.
1211 Always pass currently updated window as a parameter to update routines.
1212 * dispextern.h (updated_window): Remove declaration.
1213 (struct redisplay_interface): Pass window parameter to
1214 write_glyphs, insert_glyphs, clear_end_of_line, cursor_to
1215 and after_update_window_hook.
1216 (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line, x_cursor_to):
1217 Adjust prototypes.
1218 * dispnew.c (updated_window): Remove.
1219 (redraw_overlapped_rows, update_marginal_area, update_text_area)
1220 (update_window_line): Adjust to match redisplay interface changes.
1221 * nsterm.m (ns_update_window_begin, ns_update_window_end)
1222 (ns_scroll_run, ns_after_update_window_line):
1223 * w32term.c (x_update_window_begin, x_update_window_end)
1224 (x_after_update_window_line, x_scroll_run):
1225 * xterm.c (x_update_window_begin, x_update_window_end)
1226 (x_after_update_window_line, x_scroll_run):
1227 * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line):
1228 Likewise. Adjust comments where appropriate.
1229 (x_cursor_to): Simplify because this is always called during window
1230 update (but install debugging check anyway).
1231 (expose_window): Check must_be_updated_p flag to see whether this
1232 function is called during window update.
1233
12342013-08-08 Dmitry Antipov <dmantipov@yandex.ru>
1235
1236 Do not reset window modification event counters excessively.
1237 These leftovers and poor man's tricky methods to catch extra
1238 redisplay's attention are no longer needed.
1239 * frame.c (set_menu_bar_lines_1):
1240 * minibuf.c (read_minibuf_unwind):
1241 * window.c (Fset_window_start, set_window_buffer, window_resize_apply)
1242 (grow_mini_window, shrink_mini_window, window_scroll_pixel_based)
1243 (window_scroll_line_based, Fset_window_configuration):
1244 * xdisp.c (redisplay_window): Do not reset last_modified and
1245 last_overlay_modified counters.
1246
12472013-08-07 Jan Djärv <jan.h.d@swipnet.se>
1248
1249 * xselect.c (x_send_client_event): Set send_event and serial, memset
1250 data.l as it might be bigger than data.b. Use 24 bit mask to
1251 XSendEvent (Bug#15034).
1252
12532013-08-07 Eli Zaretskii <eliz@gnu.org>
1254
1255 * xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title
1256 for TTY frames that are not the top frame on their console.
1257 (Bug#14616)
1258
12592013-08-07 Martin Rudalics <rudalics@gmx.at>
1260
1261 * w32term.c (w32fullscreen_hook): Really maximize frame when
1262 asked for (Bug#14841).
1263
12642013-08-07 Dmitry Antipov <dmantipov@yandex.ru>
1265
1266 Prefer selected_window to Fselected_window, likewise for frames.
1267 * buffer.c (Fbuffer_swap_text):
1268 * data.c (Fvariable_binding_locus):
1269 * window.c (run_window_configuration_change_hook): Adjust users.
1270 * w16select.c (Fw16_set_clipboard_data, Fw16_get_clipboard_data):
1271 Use decode_live_frame.
1272
12732013-08-07 Dmitry Antipov <dmantipov@yandex.ru>
1274
1275 Be more careful if selected window shows the buffer other than current,
1276 use window_outdated only if this is not so. This change should also
1277 address some weird issues discussed in Bug#13012.
1278 * window.h (window_outdated): New prototype.
1279 * window.c (window_outdated): Now here. Convert from static and
1280 always assume window's buffer.
1281 (Fwindow_end, Fwindow_line_height): Use it.
1282 * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg
1283 and always assume window's buffer.
1284 (redisplay_window): Adjust user.
1285 (redisplay_internal): Call to reconsider_clip_changes once and
1286 check whether mode line should be updated only if selected window
1287 shows current buffer.
1288 (run_window_scroll_functions): Use eassert for debugging check.
1289 (Fmove_point_visually, note_mouse_highlight): Use window_outdated.
1290
12912013-08-06 Dmitry Antipov <dmantipov@yandex.ru>
1292
1293 * window.c (window_scroll, window_scroll_pixel_based)
1294 (window_scroll_line_based): Use bool for booleans.
1295
12962013-08-06 Paul Eggert <eggert@cs.ucla.edu>
1297
1298 * process.c: Fix minor off-by-one issues in descriptor counts.
1299 This shouldn't fix any real bugs, but it cleans up the code a bit.
1300 (max_process_desc, max_input_desc): -1, not 0, means none.
1301 All uses changed.
1302 (delete_input_desc): New function.
1303 (delete_write_fd, delete_keyboard_wait_descriptor): Use it.
1304 (deactivate_process): Scan backwards when recomuting max_process_desc;
1305 that should be faster.
1306 (init_process_emacs): Initialize max_input_desc.
1307
13082013-08-06 Dmitry Antipov <dmantipov@yandex.ru>
1309
1310 Use region cache to speedup bidi_find_paragraph_start.
1311 * buffer.h (struct buffer): New member bidi_paragraph_cache.
1312 Rename cache_long_line_scans to cache_long_scans.
1313 * buffer.c (bset_cache_long_line_scans): Rename to
1314 bset_cache_long_scans.
1315 (Fget_buffer_create, Fmake_indirect_buffer, Fkill_buffer)
1316 (Fbuffer_swap_text, init_buffer_once): Take bidi_paragraph_cache
1317 into account.
1318 (syms_of_buffer): Rename cache-long-line-scans to
1319 cache-long-scans. Adjust docstring.
1320 * search.c (newline_cache_on_off):
1321 * indent.c (width_run_cache_on_off): Adjust users.
1322 * bidi.c (bidi_paragraph_cache_on_off): New function.
1323 (bidi_find_paragraph_start): Use bidi_paragraph_cache if needed.
1324 * insdel.c (prepare_to_modify_buffer):
1325 Invalidate bidi_paragraph_cache if enabled.
1326
13272013-08-06 Dmitry Antipov <dmantipov@yandex.ru>
1328
1329 Invalidate region caches only if buffer text is going to be changed.
1330 * lisp.h (modify_region_1): Remove 3rd arg and rename to...
1331 (modify_text): ...new prototype.
1332 (prepare_to_modify_buffer_1): New prototype.
1333 * textprop.c (modify_region): Rename to...
1334 (modify_text_properties): ...new function.
1335 (add_text_properties_1, set_text_properties, Fremove_text_properties)
1336 (Fremove_list_of_text_properties): Adjust users.
1337 * insdel.c (modify_region_1): Remove 3rd arg and reimplement as...
1338 (modify_text): ...new function.
1339 (prepare_to_modify_buffer): Reimplement mostly as a wrapper for...
1340 (prepare_to_modify_buffer_1): ...new function.
1341 * casefiddle.c (casify_region):
1342 * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal)
1343 (Ftranspose_regions): Use modify_text.
1344
13452013-08-05 Stefan Monnier <monnier@iro.umontreal.ca>
1346
1347 * lisp.mk (lisp): Add nadvice.elc.
1348
13492013-08-05 Dmitry Antipov <dmantipov@yandex.ru>
1350
1351 New macro to iterate over live buffers similar to frames.
1352 * buffer.h (FOR_EACH_LIVE_BUFFER): New macro.
1353 (Vbuffer_alist, Qpriority, Qbefore_string, Qafter_string):
1354 Declare buffer-related variables here to offload lisp.h.
1355 * buffer.c (Vbuffer_alist): Adjust comment.
1356 (Fget_file_buffer, get_truename_buffer, Fother_buffer)
1357 (other_buffer_safely):
1358 * data.c (store_symval_forwarding):
1359 * dispnew.c (Fframe_or_buffer_changed_p):
1360 * fileio.c (Fdo_auto_save):
1361 * filelock.c (unlock_all_files):
1362 * minibuf.c (read_minibuf): Use FOR_EACH_LIVE_BUFFER.
1363
13642013-08-04 Paul Eggert <eggert@cs.ucla.edu>
1365
1366 Fix some minor races in hosts lacking mkostemp (Bug#15015).
1367 * callproc.c (create_temp_file):
1368 * filelock.c (create_lock_file):
1369 Assume mkostemp, since it's now provided by Gnulib.
1370
13712013-08-04 Eli Zaretskii <eliz@gnu.org>
1372
1373 * w32.c (mkostemp): New function.
1374 (mktemp): Remove, no longer used. Most of the code reused in
1375 mkostemp. (Bug#15015)
1376 (mktemp): Don't undef.
1377
13782013-08-04 Dmitry Antipov <dmantipov@yandex.ru>
1379
1380 * dispnew.c (glyph_matrix_count, glyph_pool_count):
1381 Move under GLYPH_DEBUG and ENABLE_CHECKING.
1382 (new_glyph_matrix, free_glyph_matrix, new_glyph_pool)
1383 (free_glyph_pool, check_glyph_memory): Likewise for
1384 all users. Adjust comments where appropriate.
1385
12013-08-03 Paul Eggert <eggert@cs.ucla.edu> 13862013-08-03 Paul Eggert <eggert@cs.ucla.edu>
2 1387
3 * composite.h: Minor fixups. 1388 * composite.h: Minor fixups.
@@ -108,8 +1493,8 @@
108 Avoid redundant Lisp_Object <-> struct frame conversions in font API. 1493 Avoid redundant Lisp_Object <-> struct frame conversions in font API.
109 * font.h (struct font_driver): Change list, match, and list_family 1494 * font.h (struct font_driver): Change list, match, and list_family
110 functions to accept struct frame * as first arg. 1495 functions to accept struct frame * as first arg.
111 * font.c (font_score, font_compare, font_sort_entities): Remove 1496 * font.c (font_score, font_compare, font_sort_entities):
112 prototypes. 1497 Remove prototypes.
113 (font_sort_entities, font_list_entities, font_select_entity): 1498 (font_sort_entities, font_list_entities, font_select_entity):
114 (font_find_for_lface, Flist_fonts, Ffont_family_list): Adjust to 1499 (font_find_for_lface, Flist_fonts, Ffont_family_list): Adjust to
115 match font API change. 1500 match font API change.
@@ -416,9 +1801,9 @@
416 or fscanf fails. 1801 or fscanf fails.
417 (system_process_attributes): Prefer plain char to unsigned char 1802 (system_process_attributes): Prefer plain char to unsigned char
418 when either will do. Clean up properly if interrupted or if 1803 when either will do. Clean up properly if interrupted or if
419 memory allocations fail. Don't assume sscanf succeeds. Remove 1804 memory allocations fail. Don't assume sscanf succeeds.
420 no-longer-needed workaround to stop GCC from whining. Read 1805 Remove no-longer-needed workaround to stop GCC from whining.
421 command-line once, instead of multiple times. Check read status a 1806 Read command-line once, instead of multiple times. Check read status a
422 bit more carefully. 1807 bit more carefully.
423 1808
424 Fix obscure porting bug with varargs functions. 1809 Fix obscure porting bug with varargs functions.
@@ -772,8 +2157,8 @@
772 of the old Fcall_process_region. Use Fcopy_sequence to create the 2157 of the old Fcall_process_region. Use Fcopy_sequence to create the
773 temp file name, rather than alloca + build_string, for simplicity. 2158 temp file name, rather than alloca + build_string, for simplicity.
774 Don't bother to block input around the temp file creation; 2159 Don't bother to block input around the temp file creation;
775 shouldn't be needed. Simplify use of mktemp. Use 2160 shouldn't be needed. Simplify use of mktemp.
776 record_unwind_protect immediately after creating the temp file; 2161 Use record_unwind_protect immediately after creating the temp file;
777 this closes an unlikely race where the temp file was not removed. 2162 this closes an unlikely race where the temp file was not removed.
778 Use memcpy rather than an open-coded loop. 2163 Use memcpy rather than an open-coded loop.
779 (Fcall_process_region): Use the new function. If the input is 2164 (Fcall_process_region): Use the new function. If the input is
@@ -1132,8 +2517,8 @@
1132 (try_cursor_movement, redisplay_window, try_window) 2517 (try_cursor_movement, redisplay_window, try_window)
1133 (try_window_id): Use it instead of FRAME_LINE_HEIGHT. (Bug#14771) 2518 (try_window_id): Use it instead of FRAME_LINE_HEIGHT. (Bug#14771)
1134 2519
1135 * window.c (window_scroll_pixel_based): use 2520 * window.c (window_scroll_pixel_based):
1136 default_line_pixel_height. 2521 use default_line_pixel_height.
1137 2522
1138 * dispextern.h (default_line_pixel_height): Add prototype. 2523 * dispextern.h (default_line_pixel_height): Add prototype.
1139 2524
diff --git a/src/Makefile.in b/src/Makefile.in
index 65927ba236c..0e7ff9cbd33 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -23,7 +23,7 @@
23# script may need modifying in sync with changes made here. Try to 23# script may need modifying in sync with changes made here. Try to
24# avoid shell-ism because the DOS build has to use the DOS shell. 24# avoid shell-ism because the DOS build has to use the DOS shell.
25 25
26SHELL = /bin/sh 26SHELL = @SHELL@
27 27
28# Here are the things that we expect ../configure to edit. 28# Here are the things that we expect ../configure to edit.
29# We use $(srcdir) explicitly in dependencies so as not to depend on VPATH. 29# We use $(srcdir) explicitly in dependencies so as not to depend on VPATH.
@@ -243,6 +243,8 @@ IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
243LIBXML2_LIBS = @LIBXML2_LIBS@ 243LIBXML2_LIBS = @LIBXML2_LIBS@
244LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ 244LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
245 245
246LIBZ = @LIBZ@
247
246XRANDR_LIBS = @XRANDR_LIBS@ 248XRANDR_LIBS = @XRANDR_LIBS@
247XRANDR_CFLAGS = @XRANDR_CFLAGS@ 249XRANDR_CFLAGS = @XRANDR_CFLAGS@
248 250
@@ -374,7 +376,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
374 process.o gnutls.o callproc.o \ 376 process.o gnutls.o callproc.o \
375 region-cache.o sound.o atimer.o \ 377 region-cache.o sound.o atimer.o \
376 doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \ 378 doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \
377 profiler.o \ 379 profiler.o decompress.o \
378 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ 380 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
379 $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) 381 $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ)
380obj = $(base_obj) $(NS_OBJC_OBJ) 382obj = $(base_obj) $(NS_OBJC_OBJ)
@@ -429,7 +431,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
429 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 431 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
430 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 432 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
431 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \ 433 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \
432 $(GFILENOTIFY_LIBS) $(LIB_MATH) 434 $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ)
433 435
434all: emacs$(EXEEXT) $(OTHER_FILES) 436all: emacs$(EXEEXT) $(OTHER_FILES)
435.PHONY: all 437.PHONY: all
diff --git a/src/alloc.c b/src/alloc.c
index c8141d22f95..8417ef4982b 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -318,7 +318,6 @@ static void *min_heap_address, *max_heap_address;
318static struct mem_node mem_z; 318static struct mem_node mem_z;
319#define MEM_NIL &mem_z 319#define MEM_NIL &mem_z
320 320
321#if GC_MARK_STACK || defined GC_MALLOC_CHECK
322static struct mem_node *mem_insert (void *, void *, enum mem_type); 321static struct mem_node *mem_insert (void *, void *, enum mem_type);
323static void mem_insert_fixup (struct mem_node *); 322static void mem_insert_fixup (struct mem_node *);
324static void mem_rotate_left (struct mem_node *); 323static void mem_rotate_left (struct mem_node *);
@@ -326,7 +325,6 @@ static void mem_rotate_right (struct mem_node *);
326static void mem_delete (struct mem_node *); 325static void mem_delete (struct mem_node *);
327static void mem_delete_fixup (struct mem_node *); 326static void mem_delete_fixup (struct mem_node *);
328static struct mem_node *mem_find (void *); 327static struct mem_node *mem_find (void *);
329#endif
330 328
331#endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ 329#endif /* GC_MARK_STACK || GC_MALLOC_CHECK */
332 330
@@ -796,10 +794,19 @@ xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
796char * 794char *
797xstrdup (const char *s) 795xstrdup (const char *s)
798{ 796{
799 size_t len = strlen (s) + 1; 797 ptrdiff_t size;
800 char *p = xmalloc (len); 798 eassert (s);
801 memcpy (p, s, len); 799 size = strlen (s) + 1;
802 return p; 800 return memcpy (xmalloc (size), s, size);
801}
802
803/* Like above, but duplicates Lisp string to C string. */
804
805char *
806xlispstrdup (Lisp_Object string)
807{
808 ptrdiff_t size = SBYTES (string) + 1;
809 return memcpy (xmalloc (size), SSDATA (string), size);
803} 810}
804 811
805/* Like putenv, but (1) use the equivalent of xmalloc and (2) the 812/* Like putenv, but (1) use the equivalent of xmalloc and (2) the
@@ -2798,7 +2805,7 @@ vector_nbytes (struct Lisp_Vector *v)
2798static void 2805static void
2799sweep_vectors (void) 2806sweep_vectors (void)
2800{ 2807{
2801 struct vector_block *block = vector_blocks, **bprev = &vector_blocks; 2808 struct vector_block *block, **bprev = &vector_blocks;
2802 struct large_vector *lv, **lvprev = &large_vectors; 2809 struct large_vector *lv, **lvprev = &large_vectors;
2803 struct Lisp_Vector *vector, *next; 2810 struct Lisp_Vector *vector, *next;
2804 2811
@@ -3472,6 +3479,7 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
3472 p->charpos = 0; 3479 p->charpos = 0;
3473 p->next = NULL; 3480 p->next = NULL;
3474 p->insertion_type = 0; 3481 p->insertion_type = 0;
3482 p->need_adjustment = 0;
3475 return val; 3483 return val;
3476} 3484}
3477 3485
@@ -3496,6 +3504,7 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos)
3496 m->charpos = charpos; 3504 m->charpos = charpos;
3497 m->bytepos = bytepos; 3505 m->bytepos = bytepos;
3498 m->insertion_type = 0; 3506 m->insertion_type = 0;
3507 m->need_adjustment = 0;
3499 m->next = BUF_MARKERS (buf); 3508 m->next = BUF_MARKERS (buf);
3500 BUF_MARKERS (buf) = m; 3509 BUF_MARKERS (buf) = m;
3501 return obj; 3510 return obj;
@@ -4058,7 +4067,7 @@ live_string_p (struct mem_node *m, void *p)
4058{ 4067{
4059 if (m->type == MEM_TYPE_STRING) 4068 if (m->type == MEM_TYPE_STRING)
4060 { 4069 {
4061 struct string_block *b = (struct string_block *) m->start; 4070 struct string_block *b = m->start;
4062 ptrdiff_t offset = (char *) p - (char *) &b->strings[0]; 4071 ptrdiff_t offset = (char *) p - (char *) &b->strings[0];
4063 4072
4064 /* P must point to the start of a Lisp_String structure, and it 4073 /* P must point to the start of a Lisp_String structure, and it
@@ -4081,7 +4090,7 @@ live_cons_p (struct mem_node *m, void *p)
4081{ 4090{
4082 if (m->type == MEM_TYPE_CONS) 4091 if (m->type == MEM_TYPE_CONS)
4083 { 4092 {
4084 struct cons_block *b = (struct cons_block *) m->start; 4093 struct cons_block *b = m->start;
4085 ptrdiff_t offset = (char *) p - (char *) &b->conses[0]; 4094 ptrdiff_t offset = (char *) p - (char *) &b->conses[0];
4086 4095
4087 /* P must point to the start of a Lisp_Cons, not be 4096 /* P must point to the start of a Lisp_Cons, not be
@@ -4107,7 +4116,7 @@ live_symbol_p (struct mem_node *m, void *p)
4107{ 4116{
4108 if (m->type == MEM_TYPE_SYMBOL) 4117 if (m->type == MEM_TYPE_SYMBOL)
4109 { 4118 {
4110 struct symbol_block *b = (struct symbol_block *) m->start; 4119 struct symbol_block *b = m->start;
4111 ptrdiff_t offset = (char *) p - (char *) &b->symbols[0]; 4120 ptrdiff_t offset = (char *) p - (char *) &b->symbols[0];
4112 4121
4113 /* P must point to the start of a Lisp_Symbol, not be 4122 /* P must point to the start of a Lisp_Symbol, not be
@@ -4133,7 +4142,7 @@ live_float_p (struct mem_node *m, void *p)
4133{ 4142{
4134 if (m->type == MEM_TYPE_FLOAT) 4143 if (m->type == MEM_TYPE_FLOAT)
4135 { 4144 {
4136 struct float_block *b = (struct float_block *) m->start; 4145 struct float_block *b = m->start;
4137 ptrdiff_t offset = (char *) p - (char *) &b->floats[0]; 4146 ptrdiff_t offset = (char *) p - (char *) &b->floats[0];
4138 4147
4139 /* P must point to the start of a Lisp_Float and not be 4148 /* P must point to the start of a Lisp_Float and not be
@@ -4157,7 +4166,7 @@ live_misc_p (struct mem_node *m, void *p)
4157{ 4166{
4158 if (m->type == MEM_TYPE_MISC) 4167 if (m->type == MEM_TYPE_MISC)
4159 { 4168 {
4160 struct marker_block *b = (struct marker_block *) m->start; 4169 struct marker_block *b = m->start;
4161 ptrdiff_t offset = (char *) p - (char *) &b->markers[0]; 4170 ptrdiff_t offset = (char *) p - (char *) &b->markers[0];
4162 4171
4163 /* P must point to the start of a Lisp_Misc, not be 4172 /* P must point to the start of a Lisp_Misc, not be
@@ -4184,7 +4193,7 @@ live_vector_p (struct mem_node *m, void *p)
4184 if (m->type == MEM_TYPE_VECTOR_BLOCK) 4193 if (m->type == MEM_TYPE_VECTOR_BLOCK)
4185 { 4194 {
4186 /* This memory node corresponds to a vector block. */ 4195 /* This memory node corresponds to a vector block. */
4187 struct vector_block *block = (struct vector_block *) m->start; 4196 struct vector_block *block = m->start;
4188 struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data; 4197 struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data;
4189 4198
4190 /* P is in the block's allocation range. Scan the block 4199 /* P is in the block's allocation range. Scan the block
@@ -4229,6 +4238,10 @@ live_buffer_p (struct mem_node *m, void *p)
4229 4238
4230#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 4239#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
4231 4240
4241/* Currently not used, but may be called from gdb. */
4242
4243void dump_zombies (void) EXTERNALLY_VISIBLE;
4244
4232/* Array of objects that are kept alive because the C stack contains 4245/* Array of objects that are kept alive because the C stack contains
4233 a pattern that looks like a reference to them . */ 4246 a pattern that looks like a reference to them . */
4234 4247
@@ -4611,7 +4624,7 @@ check_gcpros (void)
4611 4624
4612#elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 4625#elif GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
4613 4626
4614static void 4627void
4615dump_zombies (void) 4628dump_zombies (void)
4616{ 4629{
4617 int i; 4630 int i;
@@ -4748,6 +4761,10 @@ mark_stack (void)
4748#endif 4761#endif
4749} 4762}
4750 4763
4764#else /* GC_MARK_STACK == 0 */
4765
4766#define mark_maybe_object(obj) emacs_abort ()
4767
4751#endif /* GC_MARK_STACK != 0 */ 4768#endif /* GC_MARK_STACK != 0 */
4752 4769
4753 4770
@@ -5218,7 +5235,7 @@ See Info node `(elisp)Garbage Collection'. */)
5218 ptrdiff_t i; 5235 ptrdiff_t i;
5219 bool message_p; 5236 bool message_p;
5220 ptrdiff_t count = SPECPDL_INDEX (); 5237 ptrdiff_t count = SPECPDL_INDEX ();
5221 EMACS_TIME start; 5238 struct timespec start;
5222 Lisp_Object retval = Qnil; 5239 Lisp_Object retval = Qnil;
5223 size_t tot_before = 0; 5240 size_t tot_before = 0;
5224 5241
@@ -5243,7 +5260,7 @@ See Info node `(elisp)Garbage Collection'. */)
5243 if (profiler_memory_running) 5260 if (profiler_memory_running)
5244 tot_before = total_bytes_of_live_objects (); 5261 tot_before = total_bytes_of_live_objects ();
5245 5262
5246 start = current_emacs_time (); 5263 start = current_timespec ();
5247 5264
5248 /* In case user calls debug_print during GC, 5265 /* In case user calls debug_print during GC,
5249 don't let that cause a recursive GC. */ 5266 don't let that cause a recursive GC. */
@@ -5506,9 +5523,9 @@ See Info node `(elisp)Garbage Collection'. */)
5506 /* Accumulate statistics. */ 5523 /* Accumulate statistics. */
5507 if (FLOATP (Vgc_elapsed)) 5524 if (FLOATP (Vgc_elapsed))
5508 { 5525 {
5509 EMACS_TIME since_start = sub_emacs_time (current_emacs_time (), start); 5526 struct timespec since_start = timespec_sub (current_timespec (), start);
5510 Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed) 5527 Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed)
5511 + EMACS_TIME_TO_DOUBLE (since_start)); 5528 + timespectod (since_start));
5512 } 5529 }
5513 5530
5514 gcs_done++; 5531 gcs_done++;
diff --git a/src/atimer.c b/src/atimer.c
index 219b3502acc..6aef71db873 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -94,17 +94,16 @@ static struct atimer *append_atimer_lists (struct atimer *,
94 to cancel_atimer; don't free it yourself. */ 94 to cancel_atimer; don't free it yourself. */
95 95
96struct atimer * 96struct atimer *
97start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn, 97start_atimer (enum atimer_type type, struct timespec timestamp,
98 void *client_data) 98 atimer_callback fn, void *client_data)
99{ 99{
100 struct atimer *t; 100 struct atimer *t;
101 101
102 /* Round TIME up to the next full second if we don't have 102 /* Round TIME up to the next full second if we don't have
103 itimers. */ 103 itimers. */
104#ifndef HAVE_SETITIMER 104#ifndef HAVE_SETITIMER
105 if (EMACS_NSECS (timestamp) != 0 105 if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
106 && EMACS_SECS (timestamp) < TYPE_MAXIMUM (time_t)) 106 timestamp = make_timespec (timestamp.tv_sec + 1, 0);
107 timestamp = make_emacs_time (EMACS_SECS (timestamp) + 1, 0);
108#endif /* not HAVE_SETITIMER */ 107#endif /* not HAVE_SETITIMER */
109 108
110 /* Get an atimer structure from the free-list, or allocate 109 /* Get an atimer structure from the free-list, or allocate
@@ -133,11 +132,11 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
133 break; 132 break;
134 133
135 case ATIMER_RELATIVE: 134 case ATIMER_RELATIVE:
136 t->expiration = add_emacs_time (current_emacs_time (), timestamp); 135 t->expiration = timespec_add (current_timespec (), timestamp);
137 break; 136 break;
138 137
139 case ATIMER_CONTINUOUS: 138 case ATIMER_CONTINUOUS:
140 t->expiration = add_emacs_time (current_emacs_time (), timestamp); 139 t->expiration = timespec_add (current_timespec (), timestamp);
141 t->interval = timestamp; 140 t->interval = timestamp;
142 break; 141 break;
143 } 142 }
@@ -284,7 +283,7 @@ set_alarm (void)
284#ifdef HAVE_SETITIMER 283#ifdef HAVE_SETITIMER
285 struct itimerval it; 284 struct itimerval it;
286#endif 285#endif
287 EMACS_TIME now, interval; 286 struct timespec now, interval;
288 287
289#ifdef HAVE_ITIMERSPEC 288#ifdef HAVE_ITIMERSPEC
290 if (alarm_timer_ok) 289 if (alarm_timer_ok)
@@ -299,10 +298,10 @@ set_alarm (void)
299 298
300 /* Determine interval till the next timer is ripe. 299 /* Determine interval till the next timer is ripe.
301 Don't set the interval to 0; this disables the timer. */ 300 Don't set the interval to 0; this disables the timer. */
302 now = current_emacs_time (); 301 now = current_timespec ();
303 interval = (EMACS_TIME_LE (atimers->expiration, now) 302 interval = (timespec_cmp (atimers->expiration, now) <= 0
304 ? make_emacs_time (0, 1000 * 1000) 303 ? make_timespec (0, 1000 * 1000)
305 : sub_emacs_time (atimers->expiration, now)); 304 : timespec_sub (atimers->expiration, now));
306 305
307#ifdef HAVE_SETITIMER 306#ifdef HAVE_SETITIMER
308 307
@@ -310,7 +309,7 @@ set_alarm (void)
310 it.it_value = make_timeval (interval); 309 it.it_value = make_timeval (interval);
311 setitimer (ITIMER_REAL, &it, 0); 310 setitimer (ITIMER_REAL, &it, 0);
312#else /* not HAVE_SETITIMER */ 311#else /* not HAVE_SETITIMER */
313 alarm (max (EMACS_SECS (interval), 1)); 312 alarm (max (interval.tv_sec, 1));
314#endif /* not HAVE_SETITIMER */ 313#endif /* not HAVE_SETITIMER */
315 } 314 }
316} 315}
@@ -326,7 +325,7 @@ schedule_atimer (struct atimer *t)
326 struct atimer *a = atimers, *prev = NULL; 325 struct atimer *a = atimers, *prev = NULL;
327 326
328 /* Look for the first atimer that is ripe after T. */ 327 /* Look for the first atimer that is ripe after T. */
329 while (a && EMACS_TIME_LT (a->expiration, t->expiration)) 328 while (a && timespec_cmp (a->expiration, t->expiration) < 0)
330 prev = a, a = a->next; 329 prev = a, a = a->next;
331 330
332 /* Insert T in front of the atimer found, if any. */ 331 /* Insert T in front of the atimer found, if any. */
@@ -341,9 +340,9 @@ schedule_atimer (struct atimer *t)
341static void 340static void
342run_timers (void) 341run_timers (void)
343{ 342{
344 EMACS_TIME now = current_emacs_time (); 343 struct timespec now = current_timespec ();
345 344
346 while (atimers && EMACS_TIME_LE (atimers->expiration, now)) 345 while (atimers && timespec_cmp (atimers->expiration, now) <= 0)
347 { 346 {
348 struct atimer *t = atimers; 347 struct atimer *t = atimers;
349 atimers = atimers->next; 348 atimers = atimers->next;
@@ -351,7 +350,7 @@ run_timers (void)
351 350
352 if (t->type == ATIMER_CONTINUOUS) 351 if (t->type == ATIMER_CONTINUOUS)
353 { 352 {
354 t->expiration = add_emacs_time (now, t->interval); 353 t->expiration = timespec_add (now, t->interval);
355 schedule_atimer (t); 354 schedule_atimer (t);
356 } 355 }
357 else 356 else
diff --git a/src/atimer.h b/src/atimer.h
index a1825fc0933..8c4d732aa4e 100644
--- a/src/atimer.h
+++ b/src/atimer.h
@@ -19,8 +19,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19#ifndef EMACS_ATIMER_H 19#ifndef EMACS_ATIMER_H
20#define EMACS_ATIMER_H 20#define EMACS_ATIMER_H
21 21
22#include "systime.h" /* for EMACS_TIME */
23#include <stdbool.h> 22#include <stdbool.h>
23#include <time.h>
24 24
25/* Forward declaration. */ 25/* Forward declaration. */
26 26
@@ -52,10 +52,10 @@ struct atimer
52 enum atimer_type type; 52 enum atimer_type type;
53 53
54 /* Time when this timer is ripe. */ 54 /* Time when this timer is ripe. */
55 EMACS_TIME expiration; 55 struct timespec expiration;
56 56
57 /* Interval of this timer. */ 57 /* Interval of this timer. */
58 EMACS_TIME interval; 58 struct timespec interval;
59 59
60 /* Function to call when timer is ripe. Interrupt input is 60 /* Function to call when timer is ripe. Interrupt input is
61 guaranteed to not be blocked when this function is called. */ 61 guaranteed to not be blocked when this function is called. */
@@ -70,7 +70,7 @@ struct atimer
70 70
71/* Function prototypes. */ 71/* Function prototypes. */
72 72
73struct atimer *start_atimer (enum atimer_type, EMACS_TIME, 73struct atimer *start_atimer (enum atimer_type, struct timespec,
74 atimer_callback, void *); 74 atimer_callback, void *);
75void cancel_atimer (struct atimer *); 75void cancel_atimer (struct atimer *);
76void do_pending_atimers (void); 76void do_pending_atimers (void);
diff --git a/src/bidi.c b/src/bidi.c
index c31d208ecbc..7d082a94997 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -61,6 +61,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
61#include "character.h" 61#include "character.h"
62#include "buffer.h" 62#include "buffer.h"
63#include "dispextern.h" 63#include "dispextern.h"
64#include "region-cache.h"
64 65
65static bool bidi_initialized = 0; 66static bool bidi_initialized = 0;
66 67
@@ -1085,6 +1086,29 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos)
1085 return val; 1086 return val;
1086} 1087}
1087 1088
1089/* If the user has requested the long scans caching, make sure that
1090 BIDI cache is enabled. Otherwise, make sure it's disabled. */
1091
1092static struct region_cache *
1093bidi_paragraph_cache_on_off (void)
1094{
1095 if (NILP (BVAR (current_buffer, cache_long_scans)))
1096 {
1097 if (current_buffer->bidi_paragraph_cache)
1098 {
1099 free_region_cache (current_buffer->bidi_paragraph_cache);
1100 current_buffer->bidi_paragraph_cache = 0;
1101 }
1102 return NULL;
1103 }
1104 else
1105 {
1106 if (!current_buffer->bidi_paragraph_cache)
1107 current_buffer->bidi_paragraph_cache = new_region_cache ();
1108 return current_buffer->bidi_paragraph_cache;
1109 }
1110}
1111
1088/* On my 2005-vintage machine, searching back for paragraph start 1112/* On my 2005-vintage machine, searching back for paragraph start
1089 takes ~1 ms per line. And bidi_paragraph_init is called 4 times 1113 takes ~1 ms per line. And bidi_paragraph_init is called 4 times
1090 when user types C-p. The number below limits each call to 1114 when user types C-p. The number below limits each call to
@@ -1100,7 +1124,8 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1100{ 1124{
1101 Lisp_Object re = paragraph_start_re; 1125 Lisp_Object re = paragraph_start_re;
1102 ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; 1126 ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
1103 ptrdiff_t n = 0; 1127 struct region_cache *bpc = bidi_paragraph_cache_on_off ();
1128 ptrdiff_t n = 0, oldpos = pos, next;
1104 1129
1105 while (pos_byte > BEGV_BYTE 1130 while (pos_byte > BEGV_BYTE
1106 && n++ < MAX_PARAGRAPH_SEARCH 1131 && n++ < MAX_PARAGRAPH_SEARCH
@@ -1111,10 +1136,18 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1111 of the text over which we scan back includes 1136 of the text over which we scan back includes
1112 paragraph_start_re? */ 1137 paragraph_start_re? */
1113 DEC_BOTH (pos, pos_byte); 1138 DEC_BOTH (pos, pos_byte);
1114 pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); 1139 if (bpc && region_cache_backward (current_buffer, bpc, pos, &next))
1140 {
1141 pos = next, pos_byte = CHAR_TO_BYTE (pos);
1142 break;
1143 }
1144 else
1145 pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
1115 } 1146 }
1116 if (n >= MAX_PARAGRAPH_SEARCH) 1147 if (n >= MAX_PARAGRAPH_SEARCH)
1117 pos_byte = BEGV_BYTE; 1148 pos = BEGV, pos_byte = BEGV_BYTE;
1149 if (bpc)
1150 know_region_cache (current_buffer, bpc, pos, oldpos);
1118 return pos_byte; 1151 return pos_byte;
1119} 1152}
1120 1153
diff --git a/src/buffer.c b/src/buffer.c
index dfc6b8bcc02..0bcb608dbd3 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -108,9 +108,9 @@ static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
108static void swap_out_buffer_local_variables (struct buffer *b); 108static void swap_out_buffer_local_variables (struct buffer *b);
109static void reset_buffer_local_variables (struct buffer *, bool); 109static void reset_buffer_local_variables (struct buffer *, bool);
110 110
111/* Alist of all buffer names vs the buffers. */ 111/* Alist of all buffer names vs the buffers. This used to be
112/* This used to be a variable, but is no longer, 112 a Lisp-visible variable, but is no longer, to prevent lossage
113 to prevent lossage due to user rplac'ing this alist or its elements. */ 113 due to user rplac'ing this alist or its elements. */
114Lisp_Object Vbuffer_alist; 114Lisp_Object Vbuffer_alist;
115 115
116static Lisp_Object Qkill_buffer_query_functions; 116static Lisp_Object Qkill_buffer_query_functions;
@@ -203,9 +203,9 @@ bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val)
203 b->INTERNAL_FIELD (buffer_file_coding_system) = val; 203 b->INTERNAL_FIELD (buffer_file_coding_system) = val;
204} 204}
205static void 205static void
206bset_cache_long_line_scans (struct buffer *b, Lisp_Object val) 206bset_cache_long_scans (struct buffer *b, Lisp_Object val)
207{ 207{
208 b->INTERNAL_FIELD (cache_long_line_scans) = val; 208 b->INTERNAL_FIELD (cache_long_scans) = val;
209} 209}
210static void 210static void
211bset_case_fold_search (struct buffer *b, Lisp_Object val) 211bset_case_fold_search (struct buffer *b, Lisp_Object val)
@@ -478,8 +478,7 @@ If there is no such live buffer, return nil.
478See also `find-buffer-visiting'. */) 478See also `find-buffer-visiting'. */)
479 (register Lisp_Object filename) 479 (register Lisp_Object filename)
480{ 480{
481 register Lisp_Object tail, buf, tem; 481 register Lisp_Object tail, buf, handler;
482 Lisp_Object handler;
483 482
484 CHECK_STRING (filename); 483 CHECK_STRING (filename);
485 filename = Fexpand_file_name (filename, Qnil); 484 filename = Fexpand_file_name (filename, Qnil);
@@ -494,13 +493,10 @@ See also `find-buffer-visiting'. */)
494 return BUFFERP (handled_buf) ? handled_buf : Qnil; 493 return BUFFERP (handled_buf) ? handled_buf : Qnil;
495 } 494 }
496 495
497 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 496 FOR_EACH_LIVE_BUFFER (tail, buf)
498 { 497 {
499 buf = Fcdr (XCAR (tail));
500 if (!BUFFERP (buf)) continue;
501 if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue; 498 if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue;
502 tem = Fstring_equal (BVAR (XBUFFER (buf), filename), filename); 499 if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), filename), filename)))
503 if (!NILP (tem))
504 return buf; 500 return buf;
505 } 501 }
506 return Qnil; 502 return Qnil;
@@ -509,15 +505,12 @@ See also `find-buffer-visiting'. */)
509Lisp_Object 505Lisp_Object
510get_truename_buffer (register Lisp_Object filename) 506get_truename_buffer (register Lisp_Object filename)
511{ 507{
512 register Lisp_Object tail, buf, tem; 508 register Lisp_Object tail, buf;
513 509
514 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 510 FOR_EACH_LIVE_BUFFER (tail, buf)
515 { 511 {
516 buf = Fcdr (XCAR (tail));
517 if (!BUFFERP (buf)) continue;
518 if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue; 512 if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue;
519 tem = Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename); 513 if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename)))
520 if (!NILP (tem))
521 return buf; 514 return buf;
522 } 515 }
523 return Qnil; 516 return Qnil;
@@ -590,6 +583,7 @@ even if it is dead. The return value is never nil. */)
590 583
591 b->newline_cache = 0; 584 b->newline_cache = 0;
592 b->width_run_cache = 0; 585 b->width_run_cache = 0;
586 b->bidi_paragraph_cache = 0;
593 bset_width_table (b, Qnil); 587 bset_width_table (b, Qnil);
594 b->prevent_redisplay_optimizations_p = 1; 588 b->prevent_redisplay_optimizations_p = 1;
595 589
@@ -813,6 +807,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
813 807
814 b->newline_cache = 0; 808 b->newline_cache = 0;
815 b->width_run_cache = 0; 809 b->width_run_cache = 0;
810 b->bidi_paragraph_cache = 0;
816 bset_width_table (b, Qnil); 811 bset_width_table (b, Qnil);
817 812
818 name = Fcopy_sequence (name); 813 name = Fcopy_sequence (name);
@@ -893,8 +888,8 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
893 eassert (b == XBUFFER (Fmarker_buffer (ov->start))); 888 eassert (b == XBUFFER (Fmarker_buffer (ov->start)));
894 modify_overlay (b, marker_position (ov->start), 889 modify_overlay (b, marker_position (ov->start),
895 marker_position (ov->end)); 890 marker_position (ov->end));
896 Fset_marker (ov->start, Qnil, Qnil); 891 unchain_marker (XMARKER (ov->start));
897 Fset_marker (ov->end, Qnil, Qnil); 892 unchain_marker (XMARKER (ov->end));
898 893
899} 894}
900 895
@@ -938,7 +933,7 @@ reset_buffer (register struct buffer *b)
938 bset_filename (b, Qnil); 933 bset_filename (b, Qnil);
939 bset_file_truename (b, Qnil); 934 bset_file_truename (b, Qnil);
940 bset_directory (b, current_buffer ? BVAR (current_buffer, directory) : Qnil); 935 bset_directory (b, current_buffer ? BVAR (current_buffer, directory) : Qnil);
941 b->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS); 936 b->modtime = make_timespec (0, UNKNOWN_MODTIME_NSECS);
942 b->modtime_size = -1; 937 b->modtime_size = -1;
943 XSETFASTINT (BVAR (b, save_length), 0); 938 XSETFASTINT (BVAR (b, save_length), 0);
944 b->last_window_start = 1; 939 b->last_window_start = 1;
@@ -1581,10 +1576,8 @@ exists, return the buffer `*scratch*' (creating it if necessary). */)
1581 } 1576 }
1582 1577
1583 /* Consider alist of all buffers next. */ 1578 /* Consider alist of all buffers next. */
1584 tail = Vbuffer_alist; 1579 FOR_EACH_LIVE_BUFFER (tail, buf)
1585 for (; CONSP (tail); tail = XCDR (tail))
1586 { 1580 {
1587 buf = Fcdr (XCAR (tail));
1588 if (candidate_buffer (buf, buffer) 1581 if (candidate_buffer (buf, buffer)
1589 /* If the frame has a buffer_predicate, disregard buffers that 1582 /* If the frame has a buffer_predicate, disregard buffers that
1590 don't fit the predicate. */ 1583 don't fit the predicate. */
@@ -1621,12 +1614,9 @@ other_buffer_safely (Lisp_Object buffer)
1621{ 1614{
1622 Lisp_Object tail, buf; 1615 Lisp_Object tail, buf;
1623 1616
1624 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 1617 FOR_EACH_LIVE_BUFFER (tail, buf)
1625 { 1618 if (candidate_buffer (buf, buffer))
1626 buf = Fcdr (XCAR (tail)); 1619 return buf;
1627 if (candidate_buffer (buf, buffer))
1628 return buf;
1629 }
1630 1620
1631 buf = Fget_buffer (build_string ("*scratch*")); 1621 buf = Fget_buffer (build_string ("*scratch*"));
1632 if (NILP (buf)) 1622 if (NILP (buf))
@@ -1957,6 +1947,11 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1957 free_region_cache (b->width_run_cache); 1947 free_region_cache (b->width_run_cache);
1958 b->width_run_cache = 0; 1948 b->width_run_cache = 0;
1959 } 1949 }
1950 if (b->bidi_paragraph_cache)
1951 {
1952 free_region_cache (b->bidi_paragraph_cache);
1953 b->bidi_paragraph_cache = 0;
1954 }
1960 bset_width_table (b, Qnil); 1955 bset_width_table (b, Qnil);
1961 unblock_input (); 1956 unblock_input ();
1962 bset_undo_list (b, Qnil); 1957 bset_undo_list (b, Qnil);
@@ -2367,6 +2362,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2367 current_buffer->clip_changed = 1; other_buffer->clip_changed = 1; 2362 current_buffer->clip_changed = 1; other_buffer->clip_changed = 1;
2368 swapfield (newline_cache, struct region_cache *); 2363 swapfield (newline_cache, struct region_cache *);
2369 swapfield (width_run_cache, struct region_cache *); 2364 swapfield (width_run_cache, struct region_cache *);
2365 swapfield (bidi_paragraph_cache, struct region_cache *);
2370 current_buffer->prevent_redisplay_optimizations_p = 1; 2366 current_buffer->prevent_redisplay_optimizations_p = 1;
2371 other_buffer->prevent_redisplay_optimizations_p = 1; 2367 other_buffer->prevent_redisplay_optimizations_p = 1;
2372 swapfield (overlays_before, struct Lisp_Overlay *); 2368 swapfield (overlays_before, struct Lisp_Overlay *);
@@ -2413,7 +2409,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2413 live window points to that window's buffer. So since we 2409 live window points to that window's buffer. So since we
2414 just swapped the markers between the two buffers, we need 2410 just swapped the markers between the two buffers, we need
2415 to undo the effect of this swap for window markers. */ 2411 to undo the effect of this swap for window markers. */
2416 Lisp_Object w = Fselected_window (), ws = Qnil; 2412 Lisp_Object w = selected_window, ws = Qnil;
2417 Lisp_Object buf1, buf2; 2413 Lisp_Object buf1, buf2;
2418 XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer); 2414 XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer);
2419 2415
@@ -3150,8 +3146,8 @@ struct sortvec
3150static int 3146static int
3151compare_overlays (const void *v1, const void *v2) 3147compare_overlays (const void *v1, const void *v2)
3152{ 3148{
3153 const struct sortvec *s1 = (const struct sortvec *) v1; 3149 const struct sortvec *s1 = v1;
3154 const struct sortvec *s2 = (const struct sortvec *) v2; 3150 const struct sortvec *s2 = v2;
3155 if (s1->priority != s2->priority) 3151 if (s1->priority != s2->priority)
3156 return s1->priority < s2->priority ? -1 : 1; 3152 return s1->priority < s2->priority ? -1 : 1;
3157 if (s1->beg != s2->beg) 3153 if (s1->beg != s2->beg)
@@ -3257,8 +3253,8 @@ static ptrdiff_t overlay_str_len;
3257static int 3253static int
3258cmp_for_strings (const void *as1, const void *as2) 3254cmp_for_strings (const void *as1, const void *as2)
3259{ 3255{
3260 struct sortstr *s1 = (struct sortstr *)as1; 3256 struct sortstr const *s1 = as1;
3261 struct sortstr *s2 = (struct sortstr *)as2; 3257 struct sortstr const *s2 = as2;
3262 if (s1->size != s2->size) 3258 if (s1->size != s2->size)
3263 return s2->size < s1->size ? -1 : 1; 3259 return s2->size < s1->size ? -1 : 1;
3264 if (s1->priority != s2->priority) 3260 if (s1->priority != s2->priority)
@@ -3838,7 +3834,8 @@ for the front of the overlay advance when text is inserted there
3838The fifth arg REAR-ADVANCE, if non-nil, makes the marker 3834The fifth arg REAR-ADVANCE, if non-nil, makes the marker
3839for the rear of the overlay advance when text is inserted there 3835for the rear of the overlay advance when text is inserted there
3840\(which means the text *is* included in the overlay). */) 3836\(which means the text *is* included in the overlay). */)
3841 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, Lisp_Object front_advance, Lisp_Object rear_advance) 3837 (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
3838 Lisp_Object front_advance, Lisp_Object rear_advance)
3842{ 3839{
3843 Lisp_Object overlay; 3840 Lisp_Object overlay;
3844 struct buffer *b; 3841 struct buffer *b;
@@ -3847,12 +3844,11 @@ for the rear of the overlay advance when text is inserted there
3847 XSETBUFFER (buffer, current_buffer); 3844 XSETBUFFER (buffer, current_buffer);
3848 else 3845 else
3849 CHECK_BUFFER (buffer); 3846 CHECK_BUFFER (buffer);
3850 if (MARKERP (beg) 3847
3851 && ! EQ (Fmarker_buffer (beg), buffer)) 3848 if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer))
3852 error ("Marker points into wrong buffer"); 3849 signal_error ("Marker points into wrong buffer", beg);
3853 if (MARKERP (end) 3850 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
3854 && ! EQ (Fmarker_buffer (end), buffer)) 3851 signal_error ("Marker points into wrong buffer", end);
3855 error ("Marker points into wrong buffer");
3856 3852
3857 CHECK_NUMBER_COERCE_MARKER (beg); 3853 CHECK_NUMBER_COERCE_MARKER (beg);
3858 CHECK_NUMBER_COERCE_MARKER (end); 3854 CHECK_NUMBER_COERCE_MARKER (end);
@@ -3978,12 +3974,10 @@ buffer. */)
3978 if (NILP (Fbuffer_live_p (buffer))) 3974 if (NILP (Fbuffer_live_p (buffer)))
3979 error ("Attempt to move overlay to a dead buffer"); 3975 error ("Attempt to move overlay to a dead buffer");
3980 3976
3981 if (MARKERP (beg) 3977 if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer))
3982 && ! EQ (Fmarker_buffer (beg), buffer)) 3978 signal_error ("Marker points into wrong buffer", beg);
3983 error ("Marker points into wrong buffer"); 3979 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
3984 if (MARKERP (end) 3980 signal_error ("Marker points into wrong buffer", end);
3985 && ! EQ (Fmarker_buffer (end), buffer))
3986 error ("Marker points into wrong buffer");
3987 3981
3988 CHECK_NUMBER_COERCE_MARKER (beg); 3982 CHECK_NUMBER_COERCE_MARKER (beg);
3989 CHECK_NUMBER_COERCE_MARKER (end); 3983 CHECK_NUMBER_COERCE_MARKER (end);
@@ -4165,6 +4159,9 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
4165 4159
4166 CHECK_NUMBER_COERCE_MARKER (pos); 4160 CHECK_NUMBER_COERCE_MARKER (pos);
4167 4161
4162 if (!buffer_has_overlays ())
4163 return Qnil;
4164
4168 len = 10; 4165 len = 10;
4169 /* We can't use alloca here because overlays_at can call xrealloc. */ 4166 /* We can't use alloca here because overlays_at can call xrealloc. */
4170 overlay_vec = xmalloc (len * sizeof *overlay_vec); 4167 overlay_vec = xmalloc (len * sizeof *overlay_vec);
@@ -4197,6 +4194,9 @@ end of the buffer. */)
4197 CHECK_NUMBER_COERCE_MARKER (beg); 4194 CHECK_NUMBER_COERCE_MARKER (beg);
4198 CHECK_NUMBER_COERCE_MARKER (end); 4195 CHECK_NUMBER_COERCE_MARKER (end);
4199 4196
4197 if (!buffer_has_overlays ())
4198 return Qnil;
4199
4200 len = 10; 4200 len = 10;
4201 overlay_vec = xmalloc (len * sizeof *overlay_vec); 4201 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4202 4202
@@ -4225,6 +4225,9 @@ the value is (point-max). */)
4225 4225
4226 CHECK_NUMBER_COERCE_MARKER (pos); 4226 CHECK_NUMBER_COERCE_MARKER (pos);
4227 4227
4228 if (!buffer_has_overlays ())
4229 return make_number (ZV);
4230
4228 len = 10; 4231 len = 10;
4229 overlay_vec = xmalloc (len * sizeof *overlay_vec); 4232 overlay_vec = xmalloc (len * sizeof *overlay_vec);
4230 4233
@@ -4264,6 +4267,9 @@ the value is (point-min). */)
4264 4267
4265 CHECK_NUMBER_COERCE_MARKER (pos); 4268 CHECK_NUMBER_COERCE_MARKER (pos);
4266 4269
4270 if (!buffer_has_overlays ())
4271 return make_number (BEGV);
4272
4267 /* At beginning of buffer, we know the answer; 4273 /* At beginning of buffer, we know the answer;
4268 avoid bug subtracting 1 below. */ 4274 avoid bug subtracting 1 below. */
4269 if (XINT (pos) == BEGV) 4275 if (XINT (pos) == BEGV)
@@ -4756,7 +4762,7 @@ static struct mmap_region *
4756mmap_find (void *start, void *end) 4762mmap_find (void *start, void *end)
4757{ 4763{
4758 struct mmap_region *r; 4764 struct mmap_region *r;
4759 char *s = (char *) start, *e = (char *) end; 4765 char *s = start, *e = end;
4760 4766
4761 for (r = mmap_regions; r; r = r->next) 4767 for (r = mmap_regions; r; r = r->next)
4762 { 4768 {
@@ -4915,7 +4921,7 @@ mmap_alloc (void **var, size_t nbytes)
4915 } 4921 }
4916 else 4922 else
4917 { 4923 {
4918 struct mmap_region *r = (struct mmap_region *) p; 4924 struct mmap_region *r = p;
4919 4925
4920 r->nbytes_specified = nbytes; 4926 r->nbytes_specified = nbytes;
4921 r->nbytes_mapped = map; 4927 r->nbytes_mapped = map;
@@ -5055,7 +5061,7 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
5055 memory_full (nbytes); 5061 memory_full (nbytes);
5056 } 5062 }
5057 5063
5058 b->text->beg = (unsigned char *) p; 5064 b->text->beg = p;
5059 unblock_input (); 5065 unblock_input ();
5060} 5066}
5061 5067
@@ -5083,7 +5089,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
5083 memory_full (nbytes); 5089 memory_full (nbytes);
5084 } 5090 }
5085 5091
5086 BUF_BEG_ADDR (b) = (unsigned char *) p; 5092 BUF_BEG_ADDR (b) = p;
5087 unblock_input (); 5093 unblock_input ();
5088} 5094}
5089 5095
@@ -5181,7 +5187,7 @@ init_buffer_once (void)
5181 bset_buffer_file_coding_system (&buffer_defaults, Qnil); 5187 bset_buffer_file_coding_system (&buffer_defaults, Qnil);
5182 XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70); 5188 XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70);
5183 XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0); 5189 XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0);
5184 bset_cache_long_line_scans (&buffer_defaults, Qnil); 5190 bset_cache_long_scans (&buffer_defaults, Qnil);
5185 bset_file_truename (&buffer_defaults, Qnil); 5191 bset_file_truename (&buffer_defaults, Qnil);
5186 XSETFASTINT (BVAR (&buffer_defaults, display_count), 0); 5192 XSETFASTINT (BVAR (&buffer_defaults, display_count), 0);
5187 XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0); 5193 XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0);
@@ -5245,7 +5251,7 @@ init_buffer_once (void)
5245 XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx; 5251 XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx;
5246 XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx; 5252 XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx;
5247 XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx; 5253 XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx;
5248 XSETFASTINT (BVAR (&buffer_local_flags, cache_long_line_scans), idx); ++idx; 5254 XSETFASTINT (BVAR (&buffer_local_flags, cache_long_scans), idx); ++idx;
5249 XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx; 5255 XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx;
5250 XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx; 5256 XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx;
5251 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx; 5257 XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx;
@@ -5401,11 +5407,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5401 bo_fwd->predicate = predicate; 5407 bo_fwd->predicate = predicate;
5402 sym->declared_special = 1; 5408 sym->declared_special = 1;
5403 sym->redirect = SYMBOL_FORWARDED; 5409 sym->redirect = SYMBOL_FORWARDED;
5404 { 5410 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd);
5405 /* I tried to do the job without a cast, but it seems impossible.
5406 union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */
5407 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd);
5408 }
5409 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); 5411 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
5410 5412
5411 if (PER_BUFFER_IDX (offset) == 0) 5413 if (PER_BUFFER_IDX (offset) == 0)
@@ -6114,7 +6116,7 @@ An entry (apply FUN-NAME . ARGS) means undo the change with
6114 6116
6115An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo 6117An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo
6116in the active region. BEG and END is the range affected by this entry 6118in the active region. BEG and END is the range affected by this entry
6117and DELTA is the number of bytes added or deleted in that range by 6119and DELTA is the number of characters added or deleted in that range by
6118this change. 6120this change.
6119 6121
6120An entry (MARKER . DISTANCE) indicates that the marker MARKER 6122An entry (MARKER . DISTANCE) indicates that the marker MARKER
@@ -6132,8 +6134,8 @@ If the value of the variable is t, undo information is not recorded. */);
6132 DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil, 6134 DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil,
6133 doc: /* Non-nil means the mark and region are currently active in this buffer. */); 6135 doc: /* Non-nil means the mark and region are currently active in this buffer. */);
6134 6136
6135 DEFVAR_PER_BUFFER ("cache-long-line-scans", &BVAR (current_buffer, cache_long_line_scans), Qnil, 6137 DEFVAR_PER_BUFFER ("cache-long-scans", &BVAR (current_buffer, cache_long_scans), Qnil,
6136 doc: /* Non-nil means that Emacs should use caches to handle long lines more quickly. 6138 doc: /* Non-nil means that Emacs should use caches in attempt to speedup buffer scans.
6137 6139
6138Normally, the line-motion functions work by scanning the buffer for 6140Normally, the line-motion functions work by scanning the buffer for
6139newlines. Columnar operations (like `move-to-column' and 6141newlines. Columnar operations (like `move-to-column' and
@@ -6143,18 +6145,24 @@ buffer's lines are very long (say, more than 500 characters), these
6143motion functions will take longer to execute. Emacs may also take 6145motion functions will take longer to execute. Emacs may also take
6144longer to update the display. 6146longer to update the display.
6145 6147
6146If `cache-long-line-scans' is non-nil, these motion functions cache the 6148If `cache-long-scans' is non-nil, these motion functions cache the
6147results of their scans, and consult the cache to avoid rescanning 6149results of their scans, and consult the cache to avoid rescanning
6148regions of the buffer until the text is modified. The caches are most 6150regions of the buffer until the text is modified. The caches are most
6149beneficial when they prevent the most searching---that is, when the 6151beneficial when they prevent the most searching---that is, when the
6150buffer contains long lines and large regions of characters with the 6152buffer contains long lines and large regions of characters with the
6151same, fixed screen width. 6153same, fixed screen width.
6152 6154
6153When `cache-long-line-scans' is non-nil, processing short lines will 6155When `cache-long-scans' is non-nil, processing short lines will
6154become slightly slower (because of the overhead of consulting the 6156become slightly slower (because of the overhead of consulting the
6155cache), and the caches will use memory roughly proportional to the 6157cache), and the caches will use memory roughly proportional to the
6156number of newlines and characters whose screen width varies. 6158number of newlines and characters whose screen width varies.
6157 6159
6160Bidirectional editing also requires buffer scans to find paragraph
6161separators. If you have large paragraphs or no paragraph separators
6162at all, these scans may be slow. If `cache-long-scans' is non-nil,
6163results of these scans are cached. This doesn't help too much if
6164paragraphs are of the reasonable (few thousands of characters) size.
6165
6158The caches require no explicit maintenance; their accuracy is 6166The caches require no explicit maintenance; their accuracy is
6159maintained internally by the Emacs primitives. Enabling or disabling 6167maintained internally by the Emacs primitives. Enabling or disabling
6160the cache should not affect the behavior of any of the motion 6168the cache should not affect the behavior of any of the motion
diff --git a/src/buffer.h b/src/buffer.h
index 641a561cafc..169a15c7d0f 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -18,8 +18,8 @@ GNU General Public License for more details.
18You should have received a copy of the GNU General Public License 18You should have received a copy of the GNU General Public License
19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <sys/types.h> /* for off_t, time_t */ 21#include <sys/types.h>
22#include "systime.h" /* for EMACS_TIME */ 22#include <time.h>
23 23
24INLINE_HEADER_BEGIN 24INLINE_HEADER_BEGIN
25#ifndef BUFFER_INLINE 25#ifndef BUFFER_INLINE
@@ -249,6 +249,7 @@ extern void temp_set_point (struct buffer *, ptrdiff_t);
249extern void set_point_both (ptrdiff_t, ptrdiff_t); 249extern void set_point_both (ptrdiff_t, ptrdiff_t);
250extern void temp_set_point_both (struct buffer *, 250extern void temp_set_point_both (struct buffer *,
251 ptrdiff_t, ptrdiff_t); 251 ptrdiff_t, ptrdiff_t);
252extern void set_point_from_marker (Lisp_Object);
252extern void enlarge_buffer_text (struct buffer *, ptrdiff_t); 253extern void enlarge_buffer_text (struct buffer *, ptrdiff_t);
253 254
254 255
@@ -632,9 +633,9 @@ struct buffer
632 /* List of symbols naming the file format used for auto-save file. */ 633 /* List of symbols naming the file format used for auto-save file. */
633 Lisp_Object INTERNAL_FIELD (auto_save_file_format); 634 Lisp_Object INTERNAL_FIELD (auto_save_file_format);
634 635
635 /* True if the newline position cache and width run cache are 636 /* True if the newline position cache, width run cache and BIDI paragraph
636 enabled. See search.c and indent.c. */ 637 cache are enabled. See search.c, indent.c and bidi.c for details. */
637 Lisp_Object INTERNAL_FIELD (cache_long_line_scans); 638 Lisp_Object INTERNAL_FIELD (cache_long_scans);
638 639
639 /* If the width run cache is enabled, this table contains the 640 /* If the width run cache is enabled, this table contains the
640 character widths width_run_cache (see above) assumes. When we 641 character widths width_run_cache (see above) assumes. When we
@@ -794,13 +795,13 @@ struct buffer
794 char local_flags[MAX_PER_BUFFER_VARS]; 795 char local_flags[MAX_PER_BUFFER_VARS];
795 796
796 /* Set to the modtime of the visited file when read or written. 797 /* Set to the modtime of the visited file when read or written.
797 EMACS_NSECS (modtime) == NONEXISTENT_MODTIME_NSECS means 798 modtime.tv_nsec == NONEXISTENT_MODTIME_NSECS means
798 visited file was nonexistent. EMACS_NSECS (modtime) == 799 visited file was nonexistent. modtime.tv_nsec ==
799 UNKNOWN_MODTIME_NSECS means visited file modtime unknown; 800 UNKNOWN_MODTIME_NSECS means visited file modtime unknown;
800 in no case complain about any mismatch on next save attempt. */ 801 in no case complain about any mismatch on next save attempt. */
801#define NONEXISTENT_MODTIME_NSECS (-1) 802#define NONEXISTENT_MODTIME_NSECS (-1)
802#define UNKNOWN_MODTIME_NSECS (-2) 803#define UNKNOWN_MODTIME_NSECS (-2)
803 EMACS_TIME modtime; 804 struct timespec modtime;
804 805
805 /* Size of the file when modtime was set. This is used to detect the 806 /* Size of the file when modtime was set. This is used to detect the
806 case where the file grew while we were reading it, so the modtime 807 case where the file grew while we were reading it, so the modtime
@@ -839,9 +840,12 @@ struct buffer
839 the character's width; if it maps a character to zero, we don't 840 the character's width; if it maps a character to zero, we don't
840 know what its width is. This allows compute_motion to process 841 know what its width is. This allows compute_motion to process
841 such regions very quickly, using algebra instead of inspecting 842 such regions very quickly, using algebra instead of inspecting
842 each character. See also width_table, below. */ 843 each character. See also width_table, below.
844
845 The latter cache is used to speedup bidi_find_paragraph_start. */
843 struct region_cache *newline_cache; 846 struct region_cache *newline_cache;
844 struct region_cache *width_run_cache; 847 struct region_cache *width_run_cache;
848 struct region_cache *bidi_paragraph_cache;
845 849
846 /* Non-zero means don't use redisplay optimizations for 850 /* Non-zero means don't use redisplay optimizations for
847 displaying this buffer. */ 851 displaying this buffer. */
@@ -1120,9 +1124,17 @@ record_unwind_current_buffer (void)
1120 } \ 1124 } \
1121 } while (0) 1125 } while (0)
1122 1126
1127extern Lisp_Object Vbuffer_alist;
1123extern Lisp_Object Qbefore_change_functions; 1128extern Lisp_Object Qbefore_change_functions;
1124extern Lisp_Object Qafter_change_functions; 1129extern Lisp_Object Qafter_change_functions;
1125extern Lisp_Object Qfirst_change_hook; 1130extern Lisp_Object Qfirst_change_hook;
1131extern Lisp_Object Qpriority, Qbefore_string, Qafter_string;
1132
1133/* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is
1134 a `for' loop which iterates over the buffers from Vbuffer_alist. */
1135
1136#define FOR_EACH_LIVE_BUFFER(list_var, buf_var) \
1137 FOR_EACH_ALIST_VALUE (Vbuffer_alist, list_var, buf_var)
1126 1138
1127/* Get text properties of B. */ 1139/* Get text properties of B. */
1128 1140
diff --git a/src/callint.c b/src/callint.c
index 38431226508..25096af5068 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -331,12 +331,9 @@ invoke it. If KEYS is omitted or nil, the return value of
331 331
332 /* If SPECS is set to a string, use it as an interactive prompt. */ 332 /* If SPECS is set to a string, use it as an interactive prompt. */
333 if (STRINGP (specs)) 333 if (STRINGP (specs))
334 { 334 /* Make a copy of string so that if a GC relocates specs,
335 /* Make a copy of string so that if a GC relocates specs, 335 `string' will still be valid. */
336 `string' will still be valid. */ 336 string = xlispstrdupa (specs);
337 string = alloca (SBYTES (specs) + 1);
338 memcpy (string, SSDATA (specs), SBYTES (specs) + 1);
339 }
340 else 337 else
341 { 338 {
342 Lisp_Object input; 339 Lisp_Object input;
@@ -529,7 +526,7 @@ invoke it. If KEYS is omitted or nil, the return value of
529 make_number (SCHARS (callint_message)), 526 make_number (SCHARS (callint_message)),
530 Qface, Qminibuffer_prompt, callint_message); 527 Qface, Qminibuffer_prompt, callint_message);
531 args[i] = Fread_char (callint_message, Qnil, Qnil); 528 args[i] = Fread_char (callint_message, Qnil, Qnil);
532 message1_nolog ((char *) 0); 529 message1_nolog (0);
533 /* Passing args[i] directly stimulates compiler bug. */ 530 /* Passing args[i] directly stimulates compiler bug. */
534 teml = args[i]; 531 teml = args[i];
535 /* See bug#8479. */ 532 /* See bug#8479. */
diff --git a/src/callproc.c b/src/callproc.c
index 450fc57f929..d4b4a26ec3a 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -68,9 +68,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
68/* Pattern used by call-process-region to make temp files. */ 68/* Pattern used by call-process-region to make temp files. */
69static Lisp_Object Vtemp_file_name_pattern; 69static Lisp_Object Vtemp_file_name_pattern;
70 70
71/* The next two variables are valid only while record-unwind-protect 71/* The next two variables are used while record-unwind-protect is in place
72 is in place during call-process for a synchronous subprocess. At 72 during call-process for a subprocess for which record_deleted_pid has
73 other times, their contents are irrelevant. Doing this via static 73 not yet been called. At other times, synch_process_pid is zero and
74 synch_process_tempfile's contents are irrelevant. Doing this via static
74 C variables is more convenient than putting them into the arguments 75 C variables is more convenient than putting them into the arguments
75 of record-unwind-protect, as they need to be updated at randomish 76 of record-unwind-protect, as they need to be updated at randomish
76 times in the code, and Lisp cannot always store these values as 77 times in the code, and Lisp cannot always store these values as
@@ -80,8 +81,28 @@ static Lisp_Object Vtemp_file_name_pattern;
80/* If nonzero, a process-ID that has not been reaped. */ 81/* If nonzero, a process-ID that has not been reaped. */
81static pid_t synch_process_pid; 82static pid_t synch_process_pid;
82 83
83/* If nonnegative, a file descriptor that has not been closed. */ 84/* If a string, the name of a temp file that has not been removed. */
84static int synch_process_fd; 85#ifdef MSDOS
86static Lisp_Object synch_process_tempfile;
87#else
88# define synch_process_tempfile make_number (0)
89#endif
90
91/* Indexes of file descriptors that need closing on call_process_kill. */
92enum
93 {
94 /* The subsidiary process's stdout and stderr. stdin is handled
95 separately, in either Fcall_process_region or create_temp_file. */
96 CALLPROC_STDOUT, CALLPROC_STDERR,
97
98 /* How to read from a pipe (or substitute) from the subsidiary process. */
99 CALLPROC_PIPEREAD,
100
101 /* A bound on the number of file descriptors. */
102 CALLPROC_FDS
103 };
104
105static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t);
85 106
86/* Block SIGCHLD. */ 107/* Block SIGCHLD. */
87 108
@@ -102,85 +123,104 @@ unblock_child_signal (void)
102 pthread_sigmask (SIG_SETMASK, &empty_mask, 0); 123 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
103} 124}
104 125
126/* Return the current buffer's working directory, or the home
127 directory if it's unreachable, as a string suitable for a system call.
128 Signal an error if the result would not be an accessible directory. */
129
130Lisp_Object
131encode_current_directory (void)
132{
133 Lisp_Object dir;
134 struct gcpro gcpro1;
135
136 dir = BVAR (current_buffer, directory);
137 GCPRO1 (dir);
138
139 dir = Funhandled_file_name_directory (dir);
140
141 /* If the file name handler says that dir is unreachable, use
142 a sensible default. */
143 if (NILP (dir))
144 dir = build_string ("~");
145
146 dir = expand_and_dir_to_file (dir, Qnil);
147
148 if (STRING_MULTIBYTE (dir))
149 dir = ENCODE_FILE (dir);
150 if (! file_accessible_directory_p (SSDATA (dir)))
151 report_file_error ("Setting current directory",
152 BVAR (current_buffer, directory));
153
154 RETURN_UNGCPRO (dir);
155}
156
105/* If P is reapable, record it as a deleted process and kill it. 157/* If P is reapable, record it as a deleted process and kill it.
106 Do this in a critical section. Unless PID is wedged it will be 158 Do this in a critical section. Unless PID is wedged it will be
107 reaped on receipt of the first SIGCHLD after the critical section. */ 159 reaped on receipt of the first SIGCHLD after the critical section. */
108 160
109void 161void
110record_kill_process (struct Lisp_Process *p) 162record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile)
111{ 163{
112 block_child_signal (); 164 block_child_signal ();
113 165
114 if (p->alive) 166 if (p->alive)
115 { 167 {
168 record_deleted_pid (p->pid, tempfile);
116 p->alive = 0; 169 p->alive = 0;
117 record_deleted_pid (p->pid);
118 kill (- p->pid, SIGKILL); 170 kill (- p->pid, SIGKILL);
119 } 171 }
120 172
121 unblock_child_signal (); 173 unblock_child_signal ();
122} 174}
123 175
124/* Clean up when exiting call_process_cleanup. */ 176/* Clean up files, file descriptors and processes created by Fcall_process. */
177
178static void
179delete_temp_file (Lisp_Object name)
180{
181 unlink (SSDATA (name));
182}
125 183
126static void 184static void
127call_process_kill (void) 185call_process_kill (void *ptr)
128{ 186{
129 if (synch_process_fd >= 0) 187 int *callproc_fd = ptr;
130 emacs_close (synch_process_fd); 188 int i;
189 for (i = 0; i < CALLPROC_FDS; i++)
190 if (0 <= callproc_fd[i])
191 emacs_close (callproc_fd[i]);
131 192
132 if (synch_process_pid) 193 if (synch_process_pid)
133 { 194 {
134 struct Lisp_Process proc; 195 struct Lisp_Process proc;
135 proc.alive = 1; 196 proc.alive = 1;
136 proc.pid = synch_process_pid; 197 proc.pid = synch_process_pid;
137 record_kill_process (&proc); 198 record_kill_process (&proc, synch_process_tempfile);
199 synch_process_pid = 0;
138 } 200 }
201 else if (STRINGP (synch_process_tempfile))
202 delete_temp_file (synch_process_tempfile);
139} 203}
140 204
141/* Clean up when exiting Fcall_process. 205/* Clean up when exiting Fcall_process: restore the buffer, and
142 On MSDOS, delete the temporary file on any kind of termination. 206 kill the subsidiary process group if the process still exists. */
143 On Unix, kill the process and any children on termination by signal. */
144 207
145static void 208static void
146call_process_cleanup (Lisp_Object arg) 209call_process_cleanup (Lisp_Object buffer)
147{ 210{
148#ifdef MSDOS
149 Lisp_Object buffer = Fcar (arg);
150 Lisp_Object file = Fcdr (arg);
151#else
152 Lisp_Object buffer = arg;
153#endif
154
155 Fset_buffer (buffer); 211 Fset_buffer (buffer);
156 212
157#ifndef MSDOS
158 /* If the process still exists, kill its process group. */
159 if (synch_process_pid) 213 if (synch_process_pid)
160 { 214 {
161 ptrdiff_t count = SPECPDL_INDEX ();
162 kill (-synch_process_pid, SIGINT); 215 kill (-synch_process_pid, SIGINT);
163 record_unwind_protect_void (call_process_kill);
164 message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); 216 message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
165 immediate_quit = 1; 217 immediate_quit = 1;
166 QUIT; 218 QUIT;
167 wait_for_termination (synch_process_pid, 0, 1); 219 wait_for_termination (synch_process_pid, 0, 1);
168 synch_process_pid = 0; 220 synch_process_pid = 0;
169 immediate_quit = 0; 221 immediate_quit = 0;
170 specpdl_ptr = specpdl + count; /* Discard the unwind protect. */
171 message1 ("Waiting for process to die...done"); 222 message1 ("Waiting for process to die...done");
172 } 223 }
173#endif
174
175 if (synch_process_fd >= 0)
176 emacs_close (synch_process_fd);
177
178#ifdef MSDOS
179 /* FILE is "" when we didn't actually create a temporary file in
180 call-process. */
181 if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0'))
182 unlink (SDATA (file));
183#endif
184} 224}
185 225
186#ifdef DOS_NT 226#ifdef DOS_NT
@@ -218,10 +258,48 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
218usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */) 258usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */)
219 (ptrdiff_t nargs, Lisp_Object *args) 259 (ptrdiff_t nargs, Lisp_Object *args)
220{ 260{
221 Lisp_Object infile, buffer, current_dir, path; 261 Lisp_Object infile, encoded_infile;
262 int filefd;
263 struct gcpro gcpro1;
264 ptrdiff_t count = SPECPDL_INDEX ();
265
266 if (nargs >= 2 && ! NILP (args[1]))
267 {
268 infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory));
269 CHECK_STRING (infile);
270 }
271 else
272 infile = build_string (NULL_DEVICE);
273
274 GCPRO1 (infile);
275 encoded_infile = STRING_MULTIBYTE (infile) ? ENCODE_FILE (infile) : infile;
276
277 filefd = emacs_open (SSDATA (encoded_infile), O_RDONLY, 0);
278 if (filefd < 0)
279 report_file_error ("Opening process input file", infile);
280 record_unwind_protect_int (close_file_unwind, filefd);
281 UNGCPRO;
282 return unbind_to (count, call_process (nargs, args, filefd, -1));
283}
284
285/* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file.
286
287 If TEMPFILE_INDEX is nonnegative, it is the specpdl index of an
288 unwinder that is intended to remove the input temporary file; in
289 this case NARGS must be at least 2 and ARGS[1] is the file's name.
290
291 At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */
292
293static Lisp_Object
294call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
295 ptrdiff_t tempfile_index)
296{
297 Lisp_Object buffer, current_dir, path;
222 bool display_p; 298 bool display_p;
223 int fd0, fd1, filefd; 299 int fd0;
300 int callproc_fd[CALLPROC_FDS];
224 int status; 301 int status;
302 ptrdiff_t i;
225 ptrdiff_t count = SPECPDL_INDEX (); 303 ptrdiff_t count = SPECPDL_INDEX ();
226 USE_SAFE_ALLOCA; 304 USE_SAFE_ALLOCA;
227 305
@@ -231,19 +309,21 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
231 Lisp_Object error_file; 309 Lisp_Object error_file;
232 Lisp_Object output_file = Qnil; 310 Lisp_Object output_file = Qnil;
233#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ 311#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
234 char *outf, *tempfile = NULL; 312 char *tempfile = NULL;
235 int outfilefd;
236 int pid; 313 int pid;
237#else 314#else
238 pid_t pid; 315 pid_t pid;
239#endif 316#endif
240 int child_errno; 317 int child_errno;
241 int fd_output = -1; 318 int fd_output, fd_error;
242 struct coding_system process_coding; /* coding-system of process output */ 319 struct coding_system process_coding; /* coding-system of process output */
243 struct coding_system argument_coding; /* coding-system of arguments */ 320 struct coding_system argument_coding; /* coding-system of arguments */
244 /* Set to the return value of Ffind_operation_coding_system. */ 321 /* Set to the return value of Ffind_operation_coding_system. */
245 Lisp_Object coding_systems; 322 Lisp_Object coding_systems;
246 bool output_to_buffer = 1; 323 bool discard_output;
324
325 if (synch_process_pid)
326 error ("call-process invoked recursively");
247 327
248 /* Qt denotes that Ffind_operation_coding_system is not yet called. */ 328 /* Qt denotes that Ffind_operation_coding_system is not yet called. */
249 coding_systems = Qt; 329 coding_systems = Qt;
@@ -262,7 +342,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
262 /* Decide the coding-system for giving arguments. */ 342 /* Decide the coding-system for giving arguments. */
263 { 343 {
264 Lisp_Object val, *args2; 344 Lisp_Object val, *args2;
265 ptrdiff_t i;
266 345
267 /* If arguments are supplied, we may have to encode them. */ 346 /* If arguments are supplied, we may have to encode them. */
268 if (nargs >= 5) 347 if (nargs >= 5)
@@ -301,24 +380,16 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
301 } 380 }
302 } 381 }
303 382
304 if (nargs >= 2 && ! NILP (args[1])) 383 if (nargs < 3)
305 { 384 buffer = Qnil;
306 infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory));
307 CHECK_STRING (infile);
308 }
309 else 385 else
310 infile = build_string (NULL_DEVICE);
311
312 if (nargs >= 3)
313 { 386 {
314 buffer = args[2]; 387 buffer = args[2];
315 388
316 /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT 389 /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT
317 FILE-FOR-STDERR), unless the first element is :file, in which case see 390 FILE-FOR-STDERR), unless the first element is :file, in which case see
318 the next paragraph. */ 391 the next paragraph. */
319 if (CONSP (buffer) 392 if (CONSP (buffer) && !EQ (XCAR (buffer), QCfile))
320 && (! SYMBOLP (XCAR (buffer))
321 || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")))
322 { 393 {
323 if (CONSP (XCDR (buffer))) 394 if (CONSP (XCDR (buffer)))
324 { 395 {
@@ -335,9 +406,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
335 } 406 }
336 407
337 /* If the buffer is (still) a list, it might be a (:file "file") spec. */ 408 /* If the buffer is (still) a list, it might be a (:file "file") spec. */
338 if (CONSP (buffer) 409 if (CONSP (buffer) && EQ (XCAR (buffer), QCfile))
339 && SYMBOLP (XCAR (buffer))
340 && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))
341 { 410 {
342 output_file = Fexpand_file_name (XCAR (XCDR (buffer)), 411 output_file = Fexpand_file_name (XCAR (XCDR (buffer)),
343 BVAR (current_buffer, directory)); 412 BVAR (current_buffer, directory));
@@ -345,9 +414,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
345 buffer = Qnil; 414 buffer = Qnil;
346 } 415 }
347 416
348 if (!(EQ (buffer, Qnil) 417 if (! (NILP (buffer) || EQ (buffer, Qt) || INTEGERP (buffer)))
349 || EQ (buffer, Qt)
350 || INTEGERP (buffer)))
351 { 418 {
352 Lisp_Object spec_buffer; 419 Lisp_Object spec_buffer;
353 spec_buffer = buffer; 420 spec_buffer = buffer;
@@ -358,8 +425,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
358 CHECK_BUFFER (buffer); 425 CHECK_BUFFER (buffer);
359 } 426 }
360 } 427 }
361 else
362 buffer = Qnil;
363 428
364 /* Make sure that the child will be able to chdir to the current 429 /* Make sure that the child will be able to chdir to the current
365 buffer's current directory, or its unhandled equivalent. We 430 buffer's current directory, or its unhandled equivalent. We
@@ -372,28 +437,12 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
372 protected by the caller, so all we really have to worry about is 437 protected by the caller, so all we really have to worry about is
373 buffer. */ 438 buffer. */
374 { 439 {
375 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 440 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
376
377 current_dir = BVAR (current_buffer, directory);
378
379 GCPRO5 (infile, buffer, current_dir, error_file, output_file);
380 441
381 current_dir = Funhandled_file_name_directory (current_dir); 442 current_dir = encode_current_directory ();
382 if (NILP (current_dir))
383 /* If the file name handler says that current_dir is unreachable, use
384 a sensible default. */
385 current_dir = build_string ("~/");
386 current_dir = expand_and_dir_to_file (current_dir, Qnil);
387 current_dir = Ffile_name_as_directory (current_dir);
388 443
389 if (NILP (Ffile_accessible_directory_p (current_dir))) 444 GCPRO4 (buffer, current_dir, error_file, output_file);
390 report_file_error ("Setting current directory",
391 BVAR (current_buffer, directory));
392 445
393 if (STRING_MULTIBYTE (infile))
394 infile = ENCODE_FILE (infile);
395 if (STRING_MULTIBYTE (current_dir))
396 current_dir = ENCODE_FILE (current_dir);
397 if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) 446 if (STRINGP (error_file) && STRING_MULTIBYTE (error_file))
398 error_file = ENCODE_FILE (error_file); 447 error_file = ENCODE_FILE (error_file);
399 if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) 448 if (STRINGP (output_file) && STRING_MULTIBYTE (output_file))
@@ -403,44 +452,23 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
403 452
404 display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); 453 display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]);
405 454
406 filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); 455 for (i = 0; i < CALLPROC_FDS; i++)
407 if (filefd < 0) 456 callproc_fd[i] = -1;
408 { 457#ifdef MSDOS
409 int open_errno = errno; 458 synch_process_tempfile = make_number (0);
410 report_file_errno ("Opening process input file", DECODE_FILE (infile), 459#endif
411 open_errno); 460 record_unwind_protect_ptr (call_process_kill, callproc_fd);
412 }
413
414 if (STRINGP (output_file))
415 {
416 fd_output = emacs_open (SSDATA (output_file),
417 O_WRONLY | O_CREAT | O_TRUNC | O_TEXT,
418 default_output_mode);
419 if (fd_output < 0)
420 {
421 int open_errno = errno;
422 output_file = DECODE_FILE (output_file);
423 report_file_errno ("Opening process output file",
424 output_file, open_errno);
425 }
426 if (STRINGP (error_file) || NILP (error_file))
427 output_to_buffer = 0;
428 }
429 461
430 /* Search for program; barf if not found. */ 462 /* Search for program; barf if not found. */
431 { 463 {
432 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 464 struct gcpro gcpro1, gcpro2, gcpro3;
433 int ok; 465 int ok;
434 466
435 GCPRO4 (infile, buffer, current_dir, error_file); 467 GCPRO3 (buffer, current_dir, error_file);
436 ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); 468 ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK));
437 UNGCPRO; 469 UNGCPRO;
438 if (ok < 0) 470 if (ok < 0)
439 { 471 report_file_error ("Searching for program", args[0]);
440 int openp_errno = errno;
441 emacs_close (filefd);
442 report_file_errno ("Searching for program", args[0], openp_errno);
443 }
444 } 472 }
445 473
446 /* If program file name starts with /: for quoting a magic name, 474 /* If program file name starts with /: for quoting a magic name,
@@ -452,9 +480,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
452 new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); 480 new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv);
453 481
454 { 482 {
455 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 483 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
456 484
457 GCPRO5 (infile, buffer, current_dir, path, error_file); 485 GCPRO4 (buffer, current_dir, path, error_file);
458 if (nargs > 4) 486 if (nargs > 4)
459 { 487 {
460 ptrdiff_t i; 488 ptrdiff_t i;
@@ -479,254 +507,228 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
479 UNGCPRO; 507 UNGCPRO;
480 } 508 }
481 509
482#ifdef MSDOS /* MW, July 1993 */ 510 discard_output = INTEGERP (buffer) || (NILP (buffer) && NILP (output_file));
483 511
484 /* If we're redirecting STDOUT to a file, that file is already open 512#ifdef MSDOS
485 on fd_output. */ 513 if (! discard_output && ! STRINGP (output_file))
486 if (fd_output < 0)
487 { 514 {
488 if ((outf = egetenv ("TMPDIR"))) 515 char const *tmpdir = egetenv ("TMPDIR");
489 strcpy (tempfile = alloca (strlen (outf) + 20), outf); 516 char const *outf = tmpdir ? tmpdir : "";
490 else 517 tempfile = alloca (strlen (outf) + 20);
491 { 518 strcpy (tempfile, outf);
492 tempfile = alloca (20);
493 *tempfile = '\0';
494 }
495 dostounix_filename (tempfile, 0); 519 dostounix_filename (tempfile, 0);
496 if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') 520 if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/')
497 strcat (tempfile, "/"); 521 strcat (tempfile, "/");
498 strcat (tempfile, "detmp.XXX"); 522 strcat (tempfile, "detmp.XXX");
499 mktemp (tempfile); 523 mktemp (tempfile);
500 outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, 524 if (!*tempfile)
501 S_IREAD | S_IWRITE); 525 report_file_error ("Opening process output file", Qnil);
502 if (outfilefd < 0) 526 output_file = build_string (tempfile);
527 synch_process_tempfile = output_file;
528 }
529#endif
530
531 if (discard_output)
532 {
533 fd_output = emacs_open (NULL_DEVICE, O_WRONLY, 0);
534 if (fd_output < 0)
535 report_file_error ("Opening null device", Qnil);
536 }
537 else if (STRINGP (output_file))
538 {
539 fd_output = emacs_open (SSDATA (output_file),
540 O_WRONLY | O_CREAT | O_TRUNC | O_TEXT,
541 default_output_mode);
542 if (fd_output < 0)
503 { 543 {
504 int open_errno = errno; 544 int open_errno = errno;
505 emacs_close (filefd); 545 output_file = DECODE_FILE (output_file);
506 report_file_errno ("Opening process output file", 546 report_file_errno ("Opening process output file",
507 build_string (tempfile), open_errno); 547 output_file, open_errno);
508 } 548 }
509 } 549 }
510 else 550 else
511 outfilefd = fd_output;
512 fd0 = filefd;
513 fd1 = outfilefd;
514#endif /* MSDOS */
515
516 if (INTEGERP (buffer))
517 { 551 {
518 fd0 = -1;
519 fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0);
520 }
521 else
522 {
523#ifndef MSDOS
524 int fd[2]; 552 int fd[2];
525 if (emacs_pipe (fd) != 0) 553 if (emacs_pipe (fd) != 0)
526 { 554 report_file_error ("Creating process pipe", Qnil);
527 int pipe_errno = errno; 555 callproc_fd[CALLPROC_PIPEREAD] = fd[0];
528 emacs_close (filefd); 556 fd_output = fd[1];
529 report_file_errno ("Creating process pipe", Qnil, pipe_errno);
530 }
531 fd0 = fd[0];
532 fd1 = fd[1];
533#endif
534 } 557 }
558 callproc_fd[CALLPROC_STDOUT] = fd_output;
535 559
536 { 560 fd_error = fd_output;
537 int fd_error = fd1;
538 561
539 if (fd_output >= 0) 562 if (STRINGP (error_file) || (NILP (error_file) && !discard_output))
540 fd1 = fd_output; 563 {
541 564 fd_error = emacs_open ((STRINGP (error_file)
542 if (NILP (error_file)) 565 ? SSDATA (error_file)
543 fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); 566 : NULL_DEVICE),
544 else if (STRINGP (error_file))
545 fd_error = emacs_open (SSDATA (error_file),
546 O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, 567 O_WRONLY | O_CREAT | O_TRUNC | O_TEXT,
547 default_output_mode); 568 default_output_mode);
548 569 if (fd_error < 0)
549 if (fd_error < 0) 570 {
550 { 571 int open_errno = errno;
551 int open_errno = errno; 572 report_file_errno ("Cannot redirect stderr",
552 emacs_close (filefd); 573 (STRINGP (error_file)
553 if (fd0 != filefd) 574 ? DECODE_FILE (error_file)
554 emacs_close (fd0); 575 : build_string (NULL_DEVICE)),
555 if (fd1 >= 0) 576 open_errno);
556 emacs_close (fd1); 577 }
557#ifdef MSDOS 578 callproc_fd[CALLPROC_STDERR] = fd_error;
558 unlink (tempfile); 579 }
559#endif
560 if (NILP (error_file))
561 error_file = build_string (NULL_DEVICE);
562 else if (STRINGP (error_file))
563 error_file = DECODE_FILE (error_file);
564 report_file_errno ("Cannot redirect stderr", error_file, open_errno);
565 }
566 580
567#ifdef MSDOS /* MW, July 1993 */ 581#ifdef MSDOS /* MW, July 1993 */
568 /* Note that on MSDOS `child_setup' actually returns the child process 582 /* Note that on MSDOS `child_setup' actually returns the child process
569 exit status, not its PID, so assign it to status below. */ 583 exit status, not its PID, so assign it to status below. */
570 pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); 584 pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir);
571 child_errno = errno; 585
572 586 if (pid < 0)
573 emacs_close (outfilefd); 587 {
574 if (fd_error != outfilefd) 588 child_errno = errno;
575 emacs_close (fd_error); 589 unbind_to (count, Qnil);
576 if (pid < 0) 590 synchronize_system_messages_locale ();
577 { 591 return
578 synchronize_system_messages_locale (); 592 code_convert_string_norecord (build_string (strerror (child_errno)),
579 return 593 Vlocale_coding_system, 0);
580 code_convert_string_norecord (build_string (strerror (child_errno)), 594 }
581 Vlocale_coding_system, 0); 595 status = pid;
582 } 596
583 status = pid; 597 for (i = 0; i < CALLPROC_FDS; i++)
584 fd1 = -1; /* No harm in closing that one! */ 598 if (0 <= callproc_fd[i])
585 if (tempfile)
586 { 599 {
587 /* Since CRLF is converted to LF within `decode_coding', we 600 emacs_close (callproc_fd[i]);
588 can always open a file with binary mode. */ 601 callproc_fd[i] = -1;
589 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
590 if (fd0 < 0)
591 {
592 int open_errno = errno;
593 unlink (tempfile);
594 emacs_close (filefd);
595 report_file_errno ("Cannot re-open temporary file",
596 build_string (tempfile), open_errno);
597 }
598 } 602 }
599 else 603 emacs_close (filefd);
600 fd0 = -1; /* We are not going to read from tempfile. */ 604 clear_unwind_protect (count - 1);
605
606 if (tempfile)
607 {
608 /* Since CRLF is converted to LF within `decode_coding', we
609 can always open a file with binary mode. */
610 callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile,
611 O_RDONLY | O_BINARY, 0);
612 if (callproc_fd[CALLPROC_PIPEREAD] < 0)
613 {
614 int open_errno = errno;
615 report_file_errno ("Cannot re-open temporary file",
616 build_string (tempfile), open_errno);
617 }
618 }
619
601#endif /* MSDOS */ 620#endif /* MSDOS */
602 621
603 /* Do the unwind-protect now, even though the pid is not known, so 622 /* Do the unwind-protect now, even though the pid is not known, so
604 that no storage allocation is done in the critical section. 623 that no storage allocation is done in the critical section.
605 The actual PID will be filled in during the critical section. */ 624 The actual PID will be filled in during the critical section. */
606 synch_process_pid = 0; 625 record_unwind_protect (call_process_cleanup, Fcurrent_buffer ());
607 synch_process_fd = fd0;
608 626
609#ifdef MSDOS 627#ifndef MSDOS
610 /* MSDOS needs different cleanup information. */
611 record_unwind_protect (call_process_cleanup,
612 Fcons (Fcurrent_buffer (),
613 build_string (tempfile ? tempfile : "")));
614#else
615 record_unwind_protect (call_process_cleanup, Fcurrent_buffer ());
616 628
617 block_input (); 629 block_input ();
618 block_child_signal (); 630 block_child_signal ();
619 631
620#ifdef WINDOWSNT 632#ifdef WINDOWSNT
621 pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); 633 pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir);
622 /* We need to record the input file of this child, for when we are
623 called from call-process-region to create an async subprocess.
624 That's because call-process-region's unwind procedure will
625 attempt to delete the temporary input file, which will fail
626 because that file is still in use. Recording it with the child
627 will allow us to delete the file when the subprocess exits.
628 The second part of this is in delete_temp_file, q.v. */
629 if (pid > 0 && INTEGERP (buffer) && nargs >= 2 && !NILP (args[1]))
630 record_infile (pid, xstrdup (SSDATA (infile)));
631#else /* not WINDOWSNT */ 634#else /* not WINDOWSNT */
632 635
633 /* vfork, and prevent local vars from being clobbered by the vfork. */ 636 /* vfork, and prevent local vars from being clobbered by the vfork. */
634 { 637 {
635 Lisp_Object volatile buffer_volatile = buffer; 638 Lisp_Object volatile buffer_volatile = buffer;
636 Lisp_Object volatile coding_systems_volatile = coding_systems; 639 Lisp_Object volatile coding_systems_volatile = coding_systems;
637 Lisp_Object volatile current_dir_volatile = current_dir; 640 Lisp_Object volatile current_dir_volatile = current_dir;
638 bool volatile display_p_volatile = display_p; 641 bool volatile display_p_volatile = display_p;
639 bool volatile output_to_buffer_volatile = output_to_buffer; 642 bool volatile sa_must_free_volatile = sa_must_free;
640 bool volatile sa_must_free_volatile = sa_must_free; 643 int volatile fd_error_volatile = fd_error;
641 int volatile fd1_volatile = fd1; 644 int volatile filefd_volatile = filefd;
642 int volatile fd_error_volatile = fd_error; 645 ptrdiff_t volatile count_volatile = count;
643 int volatile fd_output_volatile = fd_output; 646 ptrdiff_t volatile sa_count_volatile = sa_count;
644 int volatile filefd_volatile = filefd; 647 char **volatile new_argv_volatile = new_argv;
645 ptrdiff_t volatile count_volatile = count; 648 int volatile callproc_fd_volatile[CALLPROC_FDS];
646 ptrdiff_t volatile sa_count_volatile = sa_count; 649 for (i = 0; i < CALLPROC_FDS; i++)
647 char **volatile new_argv_volatile = new_argv; 650 callproc_fd_volatile[i] = callproc_fd[i];
648 651
649 pid = vfork (); 652 pid = vfork ();
650 child_errno = errno; 653
651 654 buffer = buffer_volatile;
652 buffer = buffer_volatile; 655 coding_systems = coding_systems_volatile;
653 coding_systems = coding_systems_volatile; 656 current_dir = current_dir_volatile;
654 current_dir = current_dir_volatile; 657 display_p = display_p_volatile;
655 display_p = display_p_volatile; 658 sa_must_free = sa_must_free_volatile;
656 output_to_buffer = output_to_buffer_volatile; 659 fd_error = fd_error_volatile;
657 sa_must_free = sa_must_free_volatile; 660 filefd = filefd_volatile;
658 fd1 = fd1_volatile; 661 count = count_volatile;
659 fd_error = fd_error_volatile; 662 sa_count = sa_count_volatile;
660 fd_output = fd_output_volatile; 663 new_argv = new_argv_volatile;
661 filefd = filefd_volatile; 664
662 count = count_volatile; 665 for (i = 0; i < CALLPROC_FDS; i++)
663 sa_count = sa_count_volatile; 666 callproc_fd[i] = callproc_fd_volatile[i];
664 new_argv = new_argv_volatile; 667 fd_output = callproc_fd[CALLPROC_STDOUT];
665 668 }
666 fd0 = synch_process_fd;
667 }
668
669 if (pid == 0)
670 {
671 unblock_child_signal ();
672 669
673 if (fd0 >= 0) 670 if (pid == 0)
674 emacs_close (fd0); 671 {
672 unblock_child_signal ();
675 673
676 setsid (); 674 setsid ();
677 675
678 /* Emacs ignores SIGPIPE, but the child should not. */ 676 /* Emacs ignores SIGPIPE, but the child should not. */
679 signal (SIGPIPE, SIG_DFL); 677 signal (SIGPIPE, SIG_DFL);
680 678
681 child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); 679 child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir);
682 } 680 }
683 681
684#endif /* not WINDOWSNT */ 682#endif /* not WINDOWSNT */
685 683
686 child_errno = errno; 684 child_errno = errno;
687 685
688 if (pid > 0) 686 if (pid > 0)
689 { 687 {
690 if (INTEGERP (buffer)) 688 synch_process_pid = pid;
691 record_deleted_pid (pid);
692 else
693 synch_process_pid = pid;
694 }
695 689
696 unblock_child_signal (); 690 if (INTEGERP (buffer))
697 unblock_input (); 691 {
692 if (tempfile_index < 0)
693 record_deleted_pid (pid, Qnil);
694 else
695 {
696 eassert (1 < nargs);
697 record_deleted_pid (pid, args[1]);
698 clear_unwind_protect (tempfile_index);
699 }
700 synch_process_pid = 0;
701 }
702 }
698 703
699 /* The MSDOS case did this already. */ 704 unblock_child_signal ();
700 if (fd_error >= 0) 705 unblock_input ();
701 emacs_close (fd_error);
702#endif /* not MSDOS */
703 706
704 /* Close most of our file descriptors, but not fd0 707#endif /* not MSDOS */
705 since we will use that to read input from. */
706 emacs_close (filefd);
707 if (fd_output >= 0)
708 emacs_close (fd_output);
709 if (fd1 >= 0 && fd1 != fd_error)
710 emacs_close (fd1);
711 }
712 708
713 if (pid < 0) 709 if (pid < 0)
714 report_file_errno ("Doing vfork", Qnil, child_errno); 710 report_file_errno ("Doing vfork", Qnil, child_errno);
715 711
712 /* Close our file descriptors, except for callproc_fd[CALLPROC_PIPEREAD]
713 since we will use that to read input from. */
714 for (i = 0; i < CALLPROC_FDS; i++)
715 if (i != CALLPROC_PIPEREAD && 0 <= callproc_fd[i])
716 {
717 emacs_close (callproc_fd[i]);
718 callproc_fd[i] = -1;
719 }
720 emacs_close (filefd);
721 clear_unwind_protect (count - 1);
722
716 if (INTEGERP (buffer)) 723 if (INTEGERP (buffer))
717 return unbind_to (count, Qnil); 724 return unbind_to (count, Qnil);
718 725
719 if (BUFFERP (buffer)) 726 if (BUFFERP (buffer))
720 Fset_buffer (buffer); 727 Fset_buffer (buffer);
721 728
722 if (NILP (buffer)) 729 fd0 = callproc_fd[CALLPROC_PIPEREAD];
723 { 730
724 /* If BUFFER is nil, we must read process output once and then 731 if (0 <= fd0)
725 discard it, so setup coding system but with nil. */
726 setup_coding_system (Qnil, &process_coding);
727 process_coding.dst_multibyte = 0;
728 }
729 else
730 { 732 {
731 Lisp_Object val, *args2; 733 Lisp_Object val, *args2;
732 734
@@ -762,13 +764,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
762 setup_coding_system (val, &process_coding); 764 setup_coding_system (val, &process_coding);
763 process_coding.dst_multibyte 765 process_coding.dst_multibyte
764 = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 766 = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
767 process_coding.src_multibyte = 0;
765 } 768 }
766 process_coding.src_multibyte = 0;
767 769
768 immediate_quit = 1; 770 immediate_quit = 1;
769 QUIT; 771 QUIT;
770 772
771 if (output_to_buffer) 773 if (0 <= fd0)
772 { 774 {
773 enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; 775 enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 };
774 enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; 776 enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN };
@@ -779,9 +781,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
779 EMACS_INT total_read = 0; 781 EMACS_INT total_read = 0;
780 int carryover = 0; 782 int carryover = 0;
781 bool display_on_the_fly = display_p; 783 bool display_on_the_fly = display_p;
782 struct coding_system saved_coding; 784 struct coding_system saved_coding = process_coding;
783 785
784 saved_coding = process_coding;
785 while (1) 786 while (1)
786 { 787 {
787 /* Repeatedly read until we've filled as much as possible 788 /* Repeatedly read until we've filled as much as possible
@@ -812,58 +813,54 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
812 /* Now NREAD is the total amount of data in the buffer. */ 813 /* Now NREAD is the total amount of data in the buffer. */
813 immediate_quit = 0; 814 immediate_quit = 0;
814 815
815 if (!NILP (buffer)) 816 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
816 { 817 && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
817 if (NILP (BVAR (current_buffer, enable_multibyte_characters)) 818 insert_1_both (buf, nread, nread, 0, 1, 0);
818 && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) 819 else
819 insert_1_both (buf, nread, nread, 0, 1, 0); 820 { /* We have to decode the input. */
820 else 821 Lisp_Object curbuf;
821 { /* We have to decode the input. */ 822 ptrdiff_t count1 = SPECPDL_INDEX ();
822 Lisp_Object curbuf; 823
823 ptrdiff_t count1 = SPECPDL_INDEX (); 824 XSETBUFFER (curbuf, current_buffer);
824 825 /* We cannot allow after-change-functions be run
825 XSETBUFFER (curbuf, current_buffer); 826 during decoding, because that might modify the
826 /* We cannot allow after-change-functions be run 827 buffer, while we rely on process_coding.produced to
827 during decoding, because that might modify the 828 faithfully reflect inserted text until we
828 buffer, while we rely on process_coding.produced to 829 TEMP_SET_PT_BOTH below. */
829 faithfully reflect inserted text until we 830 specbind (Qinhibit_modification_hooks, Qt);
830 TEMP_SET_PT_BOTH below. */ 831 decode_coding_c_string (&process_coding,
831 specbind (Qinhibit_modification_hooks, Qt); 832 (unsigned char *) buf, nread, curbuf);
832 decode_coding_c_string (&process_coding, 833 unbind_to (count1, Qnil);
833 (unsigned char *) buf, nread, curbuf); 834 if (display_on_the_fly
834 unbind_to (count1, Qnil); 835 && CODING_REQUIRE_DETECTION (&saved_coding)
835 if (display_on_the_fly 836 && ! CODING_REQUIRE_DETECTION (&process_coding))
836 && CODING_REQUIRE_DETECTION (&saved_coding) 837 {
837 && ! CODING_REQUIRE_DETECTION (&process_coding)) 838 /* We have detected some coding system, but the
838 { 839 detection may have been via insufficient data.
839 /* We have detected some coding system. But, 840 So give up displaying on the fly. */
840 there's a possibility that the detection was 841 if (process_coding.produced > 0)
841 done by insufficient data. So, we give up 842 del_range_2 (process_coding.dst_pos,
842 displaying on the fly. */ 843 process_coding.dst_pos_byte,
843 if (process_coding.produced > 0) 844 (process_coding.dst_pos
844 del_range_2 (process_coding.dst_pos, 845 + process_coding.produced_char),
845 process_coding.dst_pos_byte, 846 (process_coding.dst_pos_byte
846 process_coding.dst_pos 847 + process_coding.produced),
847 + process_coding.produced_char, 848 0);
848 process_coding.dst_pos_byte 849 display_on_the_fly = 0;
849 + process_coding.produced, 0); 850 process_coding = saved_coding;
850 display_on_the_fly = 0; 851 carryover = nread;
851 process_coding = saved_coding; 852 /* Make the above condition always fail in the future. */
852 carryover = nread; 853 saved_coding.common_flags
853 /* This is to make the above condition always 854 &= ~CODING_REQUIRE_DETECTION_MASK;
854 fails in the future. */ 855 continue;
855 saved_coding.common_flags
856 &= ~CODING_REQUIRE_DETECTION_MASK;
857 continue;
858 }
859
860 TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
861 PT_BYTE + process_coding.produced);
862 carryover = process_coding.carryover_bytes;
863 if (carryover > 0)
864 memcpy (buf, process_coding.carryover,
865 process_coding.carryover_bytes);
866 } 856 }
857
858 TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
859 PT_BYTE + process_coding.produced);
860 carryover = process_coding.carryover_bytes;
861 if (carryover > 0)
862 memcpy (buf, process_coding.carryover,
863 process_coding.carryover_bytes);
867 } 864 }
868 865
869 if (process_coding.mode & CODING_MODE_LAST_BLOCK) 866 if (process_coding.mode & CODING_MODE_LAST_BLOCK)
@@ -882,7 +879,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
882 first = 0; 879 first = 0;
883 redisplay_preserve_echo_area (1); 880 redisplay_preserve_echo_area (1);
884 /* This variable might have been set to 0 for code 881 /* This variable might have been set to 0 for code
885 detection. In that case, we set it back to 1 because 882 detection. In that case, set it back to 1 because
886 we should have already detected a coding system. */ 883 we should have already detected a coding system. */
887 display_on_the_fly = 1; 884 display_on_the_fly = 1;
888 } 885 }
@@ -901,7 +898,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
901 898
902#ifndef MSDOS 899#ifndef MSDOS
903 /* Wait for it to terminate, unless it already has. */ 900 /* Wait for it to terminate, unless it already has. */
904 wait_for_termination (pid, &status, !output_to_buffer); 901 wait_for_termination (pid, &status, fd0 < 0);
905#endif 902#endif
906 903
907 immediate_quit = 0; 904 immediate_quit = 0;
@@ -931,37 +928,18 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
931 return make_number (WEXITSTATUS (status)); 928 return make_number (WEXITSTATUS (status));
932} 929}
933 930
934static void
935delete_temp_file (Lisp_Object name)
936{
937 /* Suppress jka-compr handling, etc. */
938 ptrdiff_t count = SPECPDL_INDEX ();
939 specbind (intern ("file-name-handler-alist"), Qnil);
940#ifdef WINDOWSNT
941 /* If this is called when the subprocess didn't exit yet, the
942 attempt to delete its input file will fail. In that case, we
943 schedule the file for deletion when the subprocess exits. This
944 is the 2nd part of handling this situation; see the call to
945 record_infile in call-process above, for the first part. */
946 if (!internal_delete_file (name))
947 {
948 Lisp_Object encoded_file = ENCODE_FILE (name);
949
950 record_pending_deletion (SSDATA (encoded_file));
951 }
952#else
953 internal_delete_file (name);
954#endif
955 unbind_to (count, Qnil);
956}
957
958/* Create a temporary file suitable for storing the input data of 931/* Create a temporary file suitable for storing the input data of
959 call-process-region. NARGS and ARGS are the same as for 932 call-process-region. NARGS and ARGS are the same as for
960 call-process-region. */ 933 call-process-region. Store into *FILENAME_STRING_PTR a Lisp string
934 naming the file, and return a file descriptor for reading.
935 Unwind-protect the file, so that the file descriptor will be closed
936 and the file removed when the caller unwinds the specpdl stack. */
961 937
962static Lisp_Object 938static int
963create_temp_file (ptrdiff_t nargs, Lisp_Object *args) 939create_temp_file (ptrdiff_t nargs, Lisp_Object *args,
940 Lisp_Object *filename_string_ptr)
964{ 941{
942 int fd;
965 struct gcpro gcpro1; 943 struct gcpro gcpro1;
966 Lisp_Object filename_string; 944 Lisp_Object filename_string;
967 Lisp_Object val, start, end; 945 Lisp_Object val, start, end;
@@ -988,6 +966,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args)
988 { 966 {
989 Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); 967 Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir);
990 char *tempfile; 968 char *tempfile;
969 ptrdiff_t count;
991 970
992#ifdef WINDOWSNT 971#ifdef WINDOWSNT
993 /* Cannot use the result of Fexpand_file_name, because it 972 /* Cannot use the result of Fexpand_file_name, because it
@@ -1008,27 +987,14 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args)
1008 GCPRO1 (filename_string); 987 GCPRO1 (filename_string);
1009 tempfile = SSDATA (filename_string); 988 tempfile = SSDATA (filename_string);
1010 989
1011 { 990 count = SPECPDL_INDEX ();
1012 int fd; 991 record_unwind_protect_nothing ();
1013 992 fd = mkostemp (tempfile, O_CLOEXEC);
1014#ifdef HAVE_MKOSTEMP 993 if (fd < 0)
1015 fd = mkostemp (tempfile, O_CLOEXEC); 994 report_file_error ("Failed to open temporary file using pattern",
1016#elif defined HAVE_MKSTEMP 995 pattern);
1017 fd = mkstemp (tempfile); 996 set_unwind_protect (count, delete_temp_file, filename_string);
1018#else 997 record_unwind_protect_int (close_file_unwind, fd);
1019 errno = EEXIST;
1020 mktemp (tempfile);
1021 fd = *tempfile ? 0 : -1;
1022#endif
1023 if (fd < 0)
1024 report_file_error ("Failed to open temporary file using pattern",
1025 pattern);
1026#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP
1027 emacs_close (fd);
1028#endif
1029 }
1030
1031 record_unwind_protect (delete_temp_file, filename_string);
1032 } 998 }
1033 999
1034 start = args[0]; 1000 start = args[0];
@@ -1059,15 +1025,20 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args)
1059 /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we 1025 /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we
1060 happen to get a ".Z" suffix. */ 1026 happen to get a ".Z" suffix. */
1061 specbind (intern ("file-name-handler-alist"), Qnil); 1027 specbind (intern ("file-name-handler-alist"), Qnil);
1062 Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil); 1028 write_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil, fd);
1063 1029
1064 unbind_to (count1, Qnil); 1030 unbind_to (count1, Qnil);
1065 } 1031 }
1066 1032
1033 if (lseek (fd, 0, SEEK_SET) < 0)
1034 report_file_error ("Setting file position", filename_string);
1035
1067 /* Note that Fcall_process takes care of binding 1036 /* Note that Fcall_process takes care of binding
1068 coding-system-for-read. */ 1037 coding-system-for-read. */
1069 1038
1070 RETURN_UNGCPRO (filename_string); 1039 *filename_string_ptr = filename_string;
1040 UNGCPRO;
1041 return fd;
1071} 1042}
1072 1043
1073DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, 1044DEFUN ("call-process-region", Fcall_process_region, Scall_process_region,
@@ -1098,11 +1069,12 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1098 (ptrdiff_t nargs, Lisp_Object *args) 1069 (ptrdiff_t nargs, Lisp_Object *args)
1099{ 1070{
1100 struct gcpro gcpro1; 1071 struct gcpro gcpro1;
1101 Lisp_Object infile; 1072 Lisp_Object infile, val;
1102 ptrdiff_t count = SPECPDL_INDEX (); 1073 ptrdiff_t count = SPECPDL_INDEX ();
1103 Lisp_Object start = args[0]; 1074 Lisp_Object start = args[0];
1104 Lisp_Object end = args[1]; 1075 Lisp_Object end = args[1];
1105 bool empty_input; 1076 bool empty_input;
1077 int fd;
1106 1078
1107 if (STRINGP (start)) 1079 if (STRINGP (start))
1108 empty_input = SCHARS (start) == 0; 1080 empty_input = SCHARS (start) == 0;
@@ -1116,7 +1088,17 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1116 empty_input = XINT (start) == XINT (end); 1088 empty_input = XINT (start) == XINT (end);
1117 } 1089 }
1118 1090
1119 infile = empty_input ? Qnil : create_temp_file (nargs, args); 1091 if (!empty_input)
1092 fd = create_temp_file (nargs, args, &infile);
1093 else
1094 {
1095 infile = Qnil;
1096 fd = emacs_open (NULL_DEVICE, O_RDONLY, 0);
1097 if (fd < 0)
1098 report_file_error ("Opening null device", Qnil);
1099 record_unwind_protect_int (close_file_unwind, fd);
1100 }
1101
1120 GCPRO1 (infile); 1102 GCPRO1 (infile);
1121 1103
1122 if (nargs > 3 && !NILP (args[3])) 1104 if (nargs > 3 && !NILP (args[3]))
@@ -1134,7 +1116,8 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1134 } 1116 }
1135 args[1] = infile; 1117 args[1] = infile;
1136 1118
1137 RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); 1119 val = call_process (nargs, args, fd, empty_input ? -1 : count);
1120 RETURN_UNGCPRO (unbind_to (count, val));
1138} 1121}
1139 1122
1140#ifndef WINDOWSNT 1123#ifndef WINDOWSNT
@@ -1210,23 +1193,21 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1210 static variables as if the superior had done alloca and will be 1193 static variables as if the superior had done alloca and will be
1211 cleaned up in the usual way. */ 1194 cleaned up in the usual way. */
1212 { 1195 {
1213 register char *temp; 1196 char *temp;
1214 size_t i; /* size_t, because ptrdiff_t might overflow here! */ 1197 ptrdiff_t i;
1215 1198
1216 i = SBYTES (current_dir); 1199 i = SBYTES (current_dir);
1217#ifdef MSDOS 1200#ifdef MSDOS
1218 /* MSDOS must have all environment variables malloc'ed, because 1201 /* MSDOS must have all environment variables malloc'ed, because
1219 low-level libc functions that launch subsidiary processes rely 1202 low-level libc functions that launch subsidiary processes rely
1220 on that. */ 1203 on that. */
1221 pwd_var = xmalloc (i + 6); 1204 pwd_var = xmalloc (i + 5);
1222#else 1205#else
1223 pwd_var = alloca (i + 6); 1206 pwd_var = alloca (i + 5);
1224#endif 1207#endif
1225 temp = pwd_var + 4; 1208 temp = pwd_var + 4;
1226 memcpy (pwd_var, "PWD=", 4); 1209 memcpy (pwd_var, "PWD=", 4);
1227 memcpy (temp, SDATA (current_dir), i); 1210 strcpy (temp, SSDATA (current_dir));
1228 if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP;
1229 temp[i] = 0;
1230 1211
1231#ifndef DOS_NT 1212#ifndef DOS_NT
1232 /* We can't signal an Elisp error here; we're in a vfork. Since 1213 /* We can't signal an Elisp error here; we're in a vfork. Since
@@ -1695,6 +1676,11 @@ syms_of_callproc (void)
1695#endif 1676#endif
1696 staticpro (&Vtemp_file_name_pattern); 1677 staticpro (&Vtemp_file_name_pattern);
1697 1678
1679#ifdef MSDOS
1680 synch_process_tempfile = make_number (0);
1681 staticpro (&synch_process_tempfile);
1682#endif
1683
1698 DEFVAR_LISP ("shell-file-name", Vshell_file_name, 1684 DEFVAR_LISP ("shell-file-name", Vshell_file_name,
1699 doc: /* File name to load inferior shells from. 1685 doc: /* File name to load inferior shells from.
1700Initialized from the SHELL environment variable, or to a system-dependent 1686Initialized from the SHELL environment variable, or to a system-dependent
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 7f5b99752fa..5a40790f87f 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -214,7 +214,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
214 validate_region (&b, &e); 214 validate_region (&b, &e);
215 start = XFASTINT (b); 215 start = XFASTINT (b);
216 end = XFASTINT (e); 216 end = XFASTINT (e);
217 modify_region_1 (start, end, false); 217 modify_text (start, end);
218 record_change (start, end - start); 218 record_change (start, end - start);
219 start_byte = CHAR_TO_BYTE (start); 219 start_byte = CHAR_TO_BYTE (start);
220 220
diff --git a/src/casetab.c b/src/casetab.c
index 5f3c8db2869..b6b1c99c39f 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -247,15 +247,8 @@ init_casetab_once (void)
247{ 247{
248 register int i; 248 register int i;
249 Lisp_Object down, up, eqv; 249 Lisp_Object down, up, eqv;
250 DEFSYM (Qcase_table, "case-table");
251
252 /* Intern this now in case it isn't already done.
253 Setting this variable twice is harmless.
254 But don't staticpro it here--that is done in alloc.c. */
255 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
256 250
257 /* Now we are ready to set up this property, so we can 251 DEFSYM (Qcase_table, "case-table");
258 create char tables. */
259 Fput (Qcase_table, Qchar_table_extra_slots, make_number (3)); 252 Fput (Qcase_table, Qchar_table_extra_slots, make_number (3));
260 253
261 down = Fmake_char_table (Qcase_table, Qnil); 254 down = Fmake_char_table (Qcase_table, Qnil);
diff --git a/src/category.c b/src/category.c
index 30ffbd0890f..b28978fb721 100644
--- a/src/category.c
+++ b/src/category.c
@@ -460,14 +460,6 @@ init_category_once (void)
460{ 460{
461 /* This has to be done here, before we call Fmake_char_table. */ 461 /* This has to be done here, before we call Fmake_char_table. */
462 DEFSYM (Qcategory_table, "category-table"); 462 DEFSYM (Qcategory_table, "category-table");
463
464 /* Intern this now in case it isn't already done.
465 Setting this variable twice is harmless.
466 But don't staticpro it here--that is done in alloc.c. */
467 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
468
469 /* Now we are ready to set up this property, so we can
470 create category tables. */
471 Fput (Qcategory_table, Qchar_table_extra_slots, make_number (2)); 463 Fput (Qcategory_table, Qchar_table_extra_slots, make_number (2));
472 464
473 Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil); 465 Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil);
diff --git a/src/character.c b/src/character.c
index b2caaa290af..6fefb6e8824 100644
--- a/src/character.c
+++ b/src/character.c
@@ -174,11 +174,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
174 174
175 if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10)) 175 if (*p < 0x80 || ! (*p & 0x20) || ! (*p & 0x10))
176 { 176 {
177 /* 1-, 2-, and 3-byte sequences can be handled by the macro. */
177 c = STRING_CHAR_ADVANCE (p); 178 c = STRING_CHAR_ADVANCE (p);
178 } 179 }
179 else if (! (*p & 0x08)) 180 else if (! (*p & 0x08))
180 { 181 {
181 c = ((((p)[0] & 0xF) << 18) 182 /* A 4-byte sequence of this form:
183 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
184 c = ((((p)[0] & 0x7) << 18)
182 | (((p)[1] & 0x3F) << 12) 185 | (((p)[1] & 0x3F) << 12)
183 | (((p)[2] & 0x3F) << 6) 186 | (((p)[2] & 0x3F) << 6)
184 | ((p)[3] & 0x3F)); 187 | ((p)[3] & 0x3F));
@@ -186,7 +189,14 @@ string_char (const unsigned char *p, const unsigned char **advanced, int *len)
186 } 189 }
187 else 190 else
188 { 191 {
189 c = ((((p)[1] & 0x3F) << 18) 192 /* A 5-byte sequence of this form:
193
194 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
195
196 Note that the top 4 `x's are always 0, so shifting p[1] can
197 never exceed the maximum valid character codepoint. */
198 c = (/* (((p)[0] & 0x3) << 24) ... always 0, so no need to shift. */
199 (((p)[1] & 0x3F) << 18)
190 | (((p)[2] & 0x3F) << 12) 200 | (((p)[2] & 0x3F) << 12)
191 | (((p)[3] & 0x3F) << 6) 201 | (((p)[3] & 0x3F) << 6)
192 | ((p)[4] & 0x3F)); 202 | ((p)[4] & 0x3F));
@@ -1062,10 +1072,6 @@ A char-table for width (columns) of each character. */);
1062 doc: /* Char table of script symbols. 1072 doc: /* Char table of script symbols.
1063It has one extra slot whose value is a list of script symbols. */); 1073It has one extra slot whose value is a list of script symbols. */);
1064 1074
1065 /* Intern this now in case it isn't already done.
1066 Setting this variable twice is harmless.
1067 But don't staticpro it here--that is done in alloc.c. */
1068 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
1069 DEFSYM (Qchar_script_table, "char-script-table"); 1075 DEFSYM (Qchar_script_table, "char-script-table");
1070 Fput (Qchar_script_table, Qchar_table_extra_slots, make_number (1)); 1076 Fput (Qchar_script_table, Qchar_table_extra_slots, make_number (1));
1071 Vchar_script_table = Fmake_char_table (Qchar_script_table, Qnil); 1077 Vchar_script_table = Fmake_char_table (Qchar_script_table, Qnil);
diff --git a/src/cmds.c b/src/cmds.c
index 3ebad50184a..ee3be79a0ab 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -86,6 +86,7 @@ DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p",
86 doc: /* Move point N characters forward (backward if N is negative). 86 doc: /* Move point N characters forward (backward if N is negative).
87On reaching end or beginning of buffer, stop and signal error. 87On reaching end or beginning of buffer, stop and signal error.
88Interactively, N is the numeric prefix argument. 88Interactively, N is the numeric prefix argument.
89If N is omitted or nil, move point 1 character forward.
89 90
90Depending on the bidirectional context, the movement may be to the 91Depending on the bidirectional context, the movement may be to the
91right or to the left on the screen. This is in contrast with 92right or to the left on the screen. This is in contrast with
@@ -99,6 +100,7 @@ DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p",
99 doc: /* Move point N characters backward (forward if N is negative). 100 doc: /* Move point N characters backward (forward if N is negative).
100On attempt to pass beginning or end of buffer, stop and signal error. 101On attempt to pass beginning or end of buffer, stop and signal error.
101Interactively, N is the numeric prefix argument. 102Interactively, N is the numeric prefix argument.
103If N is omitted or nil, move point 1 character backward.
102 104
103Depending on the bidirectional context, the movement may be to the 105Depending on the bidirectional context, the movement may be to the
104right or to the left on the screen. This is in contrast with 106right or to the left on the screen. This is in contrast with
@@ -119,9 +121,7 @@ With positive N, a non-empty line at the end counts as one line
119successfully moved (for the return value). */) 121successfully moved (for the return value). */)
120 (Lisp_Object n) 122 (Lisp_Object n)
121{ 123{
122 ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; 124 ptrdiff_t opoint = PT, pos, pos_byte, shortage, count;
123 ptrdiff_t pos, pos_byte;
124 EMACS_INT count, shortage;
125 125
126 if (NILP (n)) 126 if (NILP (n))
127 count = 1; 127 count = 1;
@@ -132,16 +132,12 @@ successfully moved (for the return value). */)
132 } 132 }
133 133
134 if (count <= 0) 134 if (count <= 0)
135 shortage = scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, 1); 135 pos = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1,
136 &shortage, &pos_byte, 1);
136 else 137 else
137 shortage = scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, 1); 138 pos = find_newline (PT, PT_BYTE, ZV, ZV_BYTE, count,
138 139 &shortage, &pos_byte, 1);
139 /* Since scan_newline does TEMP_SET_PT_BOTH, 140
140 and we want to set PT "for real",
141 go back to the old point and then come back here. */
142 pos = PT;
143 pos_byte = PT_BYTE;
144 TEMP_SET_PT_BOTH (opoint, opoint_byte);
145 SET_PT_BOTH (pos, pos_byte); 141 SET_PT_BOTH (pos, pos_byte);
146 142
147 if (shortage > 0 143 if (shortage > 0
diff --git a/src/coding.c b/src/coding.c
index 5b637627763..c10fb375672 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -10814,11 +10814,6 @@ syms_of_coding (void)
10814 Fput (Qcoding_system_error, Qerror_message, 10814 Fput (Qcoding_system_error, Qerror_message,
10815 build_pure_c_string ("Invalid coding system")); 10815 build_pure_c_string ("Invalid coding system"));
10816 10816
10817 /* Intern this now in case it isn't already done.
10818 Setting this variable twice is harmless.
10819 But don't staticpro it here--that is done in alloc.c. */
10820 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
10821
10822 DEFSYM (Qtranslation_table, "translation-table"); 10817 DEFSYM (Qtranslation_table, "translation-table");
10823 Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2)); 10818 Fput (Qtranslation_table, Qchar_table_extra_slots, make_number (2));
10824 DEFSYM (Qtranslation_table_id, "translation-table-id"); 10819 DEFSYM (Qtranslation_table_id, "translation-table-id");
diff --git a/src/coding.h b/src/coding.h
index 7b7078e06fa..2c01a05d197 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -378,8 +378,6 @@ struct emacs_mule_spec
378 struct composition_status cmp_status; 378 struct composition_status cmp_status;
379}; 379};
380 380
381struct ccl_spec;
382
383struct undecided_spec 381struct undecided_spec
384{ 382{
385 /* Inhibit null byte detection. 1 means always inhibit, 383 /* Inhibit null byte detection. 1 means always inhibit,
diff --git a/src/composite.h b/src/composite.h
index 53665b36bd1..df170093797 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -25,6 +25,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25#ifndef EMACS_COMPOSITE_H 25#ifndef EMACS_COMPOSITE_H
26#define EMACS_COMPOSITE_H 26#define EMACS_COMPOSITE_H
27 27
28#include "font.h"
29
28INLINE_HEADER_BEGIN 30INLINE_HEADER_BEGIN
29#ifndef COMPOSITE_INLINE 31#ifndef COMPOSITE_INLINE
30# define COMPOSITE_INLINE INLINE 32# define COMPOSITE_INLINE INLINE
@@ -312,10 +314,6 @@ enum lglyph_indices
312#define LGLYPH_WADJUST(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \ 314#define LGLYPH_WADJUST(g) (VECTORP (LGLYPH_ADJUSTMENT (g)) \
313 ? XINT (AREF (LGLYPH_ADJUSTMENT (g), 2)) : 0) 315 ? XINT (AREF (LGLYPH_ADJUSTMENT (g), 2)) : 0)
314 316
315struct composition_it;
316struct face;
317struct font_metrics;
318
319extern Lisp_Object composition_gstring_put_cache (Lisp_Object, ptrdiff_t); 317extern Lisp_Object composition_gstring_put_cache (Lisp_Object, ptrdiff_t);
320extern Lisp_Object composition_gstring_from_id (ptrdiff_t); 318extern Lisp_Object composition_gstring_from_id (ptrdiff_t);
321extern bool composition_gstring_p (Lisp_Object); 319extern bool composition_gstring_p (Lisp_Object);
diff --git a/src/data.c b/src/data.c
index d1e43ac1b5f..9f4bd1f1c02 100644
--- a/src/data.c
+++ b/src/data.c
@@ -981,19 +981,14 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
981 - (char *) &buffer_defaults); 981 - (char *) &buffer_defaults);
982 int idx = PER_BUFFER_IDX (offset); 982 int idx = PER_BUFFER_IDX (offset);
983 983
984 Lisp_Object tail; 984 Lisp_Object tail, buf;
985 985
986 if (idx <= 0) 986 if (idx <= 0)
987 break; 987 break;
988 988
989 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 989 FOR_EACH_LIVE_BUFFER (tail, buf)
990 { 990 {
991 Lisp_Object lbuf; 991 struct buffer *b = XBUFFER (buf);
992 struct buffer *b;
993
994 lbuf = Fcdr (XCAR (tail));
995 if (!BUFFERP (lbuf)) continue;
996 b = XBUFFER (lbuf);
997 992
998 if (! PER_BUFFER_VALUE_P (b, idx)) 993 if (! PER_BUFFER_VALUE_P (b, idx))
999 set_per_buffer_value (b, offset, newval); 994 set_per_buffer_value (b, offset, newval);
@@ -1980,7 +1975,7 @@ If the current binding is global (the default), the value is nil. */)
1980 { 1975 {
1981 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); 1976 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1982 if (KBOARD_OBJFWDP (valcontents)) 1977 if (KBOARD_OBJFWDP (valcontents))
1983 return Fframe_terminal (Fselected_frame ()); 1978 return Fframe_terminal (selected_frame);
1984 else if (!BUFFER_OBJFWDP (valcontents)) 1979 else if (!BUFFER_OBJFWDP (valcontents))
1985 return Qnil; 1980 return Qnil;
1986 } 1981 }
diff --git a/src/decompress.c b/src/decompress.c
new file mode 100644
index 00000000000..dc9f4b72d93
--- /dev/null
+++ b/src/decompress.c
@@ -0,0 +1,232 @@
1/* Interface to zlib.
2 Copyright (C) 2013 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18
19#include <config.h>
20
21#ifdef HAVE_ZLIB
22
23#include <zlib.h>
24
25#include "lisp.h"
26#include "character.h"
27#include "buffer.h"
28
29#include <verify.h>
30
31static Lisp_Object Qzlib_dll;
32
33#ifdef WINDOWSNT
34#include <windows.h>
35#include "w32.h"
36
37/* Macro for defining functions that will be loaded from the zlib DLL. */
38#define DEF_ZLIB_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
39
40/* Macro for loading zlib functions from the library. */
41#define LOAD_ZLIB_FN(lib,func) { \
42 fn_##func = (void *) GetProcAddress (lib, #func); \
43 if (!fn_##func) return false; \
44 }
45
46DEF_ZLIB_FN (int, inflateInit2_,
47 (z_streamp strm, int windowBits, const char *version, int stream_size));
48
49DEF_ZLIB_FN (int, inflate,
50 (z_streamp strm, int flush));
51
52DEF_ZLIB_FN (int, inflateEnd,
53 (z_streamp strm));
54
55static bool zlib_initialized;
56
57static bool
58init_zlib_functions (void)
59{
60 HMODULE library = w32_delayed_load (Qzlib_dll);
61
62 if (!library)
63 {
64 message1 ("zlib library not found");
65 return false;
66 }
67
68 LOAD_ZLIB_FN (library, inflateInit2_);
69 LOAD_ZLIB_FN (library, inflate);
70 LOAD_ZLIB_FN (library, inflateEnd);
71 return true;
72}
73
74#define fn_inflateInit2(strm, windowBits) \
75 fn_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
76
77#else /* !WINDOWSNT */
78
79#define fn_inflateInit2 inflateInit2
80#define fn_inflate inflate
81#define fn_inflateEnd inflateEnd
82
83#endif /* WINDOWSNT */
84
85
86struct decompress_unwind_data
87{
88 ptrdiff_t old_point, start, nbytes;
89 z_stream *stream;
90};
91
92static void
93unwind_decompress (void *ddata)
94{
95 struct decompress_unwind_data *data = ddata;
96 fn_inflateEnd (data->stream);
97
98 /* Delete any uncompressed data already inserted on error. */
99 if (data->start)
100 del_range (data->start, data->start + data->nbytes);
101
102 /* Put point where it was, or if the buffer has shrunk because the
103 compressed data is bigger than the uncompressed, at
104 point-max. */
105 SET_PT (min (data->old_point, ZV));
106}
107
108DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0,
109 doc: /* Return t if zlib decompression is available in this instance of Emacs. */)
110 (void)
111{
112#ifdef WINDOWSNT
113 Lisp_Object found = Fassq (Qzlib_dll, Vlibrary_cache);
114 if (CONSP (found))
115 return XCDR (found);
116 else
117 {
118 Lisp_Object status;
119 zlib_initialized = init_zlib_functions ();
120 status = zlib_initialized ? Qt : Qnil;
121 Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache);
122 return status;
123 }
124#else
125 return Qt;
126#endif
127}
128
129DEFUN ("zlib-decompress-region", Fzlib_decompress_region,
130 Szlib_decompress_region,
131 2, 2, 0,
132 doc: /* Decompress a gzip- or zlib-compressed region.
133Replace the text in the region by the decompressed data.
134On failure, return nil and leave the data in place.
135This function can be called only in unibyte buffers. */)
136 (Lisp_Object start, Lisp_Object end)
137{
138 ptrdiff_t istart, iend, pos_byte;
139 z_stream stream;
140 int inflate_status;
141 struct decompress_unwind_data unwind_data;
142 ptrdiff_t count = SPECPDL_INDEX ();
143
144 validate_region (&start, &end);
145
146 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
147 error ("This function can be called only in unibyte buffers");
148
149#ifdef WINDOWSNT
150 if (!zlib_initialized)
151 zlib_initialized = init_zlib_functions ();
152 if (!zlib_initialized)
153 return Qnil;
154#endif
155
156 /* This is a unibyte buffer, so character positions and bytes are
157 the same. */
158 istart = XINT (start);
159 iend = XINT (end);
160 move_gap_both (iend, iend);
161
162 stream.zalloc = Z_NULL;
163 stream.zfree = Z_NULL;
164 stream.opaque = Z_NULL;
165 stream.avail_in = 0;
166 stream.next_in = Z_NULL;
167
168 /* The magic number 32 apparently means "autodetect both the gzip and
169 zlib formats" according to zlib.h. */
170 if (fn_inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK)
171 return Qnil;
172
173 unwind_data.start = iend;
174 unwind_data.stream = &stream;
175 unwind_data.old_point = PT;
176 unwind_data.nbytes = 0;
177 record_unwind_protect_ptr (unwind_decompress, &unwind_data);
178
179 /* Insert the decompressed data at the end of the compressed data. */
180 SET_PT (iend);
181
182 pos_byte = istart;
183
184 /* Keep calling 'inflate' until it reports an error or end-of-input. */
185 do
186 {
187 /* Maximum number of bytes that one 'inflate' call should read and write.
188 Do not make avail_out too large, as that might unduly delay C-g.
189 zlib requires that avail_in and avail_out not exceed UINT_MAX. */
190 ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX);
191 int avail_out = 16 * 1024;
192 int decompressed;
193
194 if (GAP_SIZE < avail_out)
195 make_gap (avail_out - GAP_SIZE);
196 stream.next_in = BYTE_POS_ADDR (pos_byte);
197 stream.avail_in = avail_in;
198 stream.next_out = GPT_ADDR;
199 stream.avail_out = avail_out;
200 inflate_status = fn_inflate (&stream, Z_NO_FLUSH);
201 pos_byte += avail_in - stream.avail_in;
202 decompressed = avail_out - stream.avail_out;
203 insert_from_gap (decompressed, decompressed, 0);
204 unwind_data.nbytes += decompressed;
205 QUIT;
206 }
207 while (inflate_status == Z_OK);
208
209 if (inflate_status != Z_STREAM_END)
210 return unbind_to (count, Qnil);
211
212 unwind_data.start = 0;
213
214 /* Delete the compressed data. */
215 del_range (istart, iend);
216
217 return unbind_to (count, Qt);
218}
219
220
221/***********************************************************************
222 Initialization
223 ***********************************************************************/
224void
225syms_of_decompress (void)
226{
227 DEFSYM (Qzlib_dll, "zlib");
228 defsubr (&Szlib_decompress_region);
229 defsubr (&Szlib_available_p);
230}
231
232#endif /* HAVE_ZLIB */
diff --git a/src/dispextern.h b/src/dispextern.h
index d747700fd66..947e50fa4dd 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -83,7 +83,7 @@ typedef XImagePtr XImagePtr_or_DC;
83#endif 83#endif
84 84
85#ifdef HAVE_WINDOW_SYSTEM 85#ifdef HAVE_WINDOW_SYSTEM
86# include "systime.h" 86# include <time.h>
87#endif 87#endif
88 88
89#ifndef HAVE_WINDOW_SYSTEM 89#ifndef HAVE_WINDOW_SYSTEM
@@ -95,18 +95,17 @@ typedef int Cursor;
95#define NativeRectangle int 95#define NativeRectangle int
96#endif 96#endif
97 97
98/* Structure forward declarations. Some are here because function 98/* Text cursor types. */
99 prototypes below reference structure types before their definition
100 in this file. Some are here because not every file including
101 dispextern.h also includes frame.h and windows.h. */
102
103struct glyph;
104struct glyph_row;
105struct glyph_matrix;
106struct glyph_pool;
107struct frame;
108struct window;
109 99
100enum text_cursor_kinds
101{
102 DEFAULT_CURSOR = -2,
103 NO_CURSOR = -1,
104 FILLED_BOX_CURSOR,
105 HOLLOW_BOX_CURSOR,
106 BAR_CURSOR,
107 HBAR_CURSOR
108};
110 109
111/* Values returned from coordinates_in_window. */ 110/* Values returned from coordinates_in_window. */
112 111
@@ -224,8 +223,16 @@ struct text_pos
224/* Set text position POS from marker MARKER. */ 223/* Set text position POS from marker MARKER. */
225 224
226#define SET_TEXT_POS_FROM_MARKER(POS, MARKER) \ 225#define SET_TEXT_POS_FROM_MARKER(POS, MARKER) \
227 (CHARPOS (POS) = marker_position ((MARKER)), \ 226 (CHARPOS (POS) = marker_position (MARKER), \
228 BYTEPOS (POS) = marker_byte_position ((MARKER))) 227 BYTEPOS (POS) = marker_byte_position (MARKER))
228
229/* Like above, but clip POS within accessible range. */
230
231#define CLIP_TEXT_POS_FROM_MARKER(POS, MARKER) \
232 (CHARPOS (POS) = clip_to_bounds \
233 (BEGV, marker_position (MARKER), ZV), \
234 BYTEPOS (POS) = clip_to_bounds \
235 (BEGV_BYTE, marker_byte_position (MARKER), ZV_BYTE))
229 236
230/* Set marker MARKER from text position POS. */ 237/* Set marker MARKER from text position POS. */
231 238
@@ -752,11 +759,12 @@ void check_matrix_pointer_lossage (struct glyph_matrix *);
752 Glyph Rows 759 Glyph Rows
753 ***********************************************************************/ 760 ***********************************************************************/
754 761
755/* Area in window glyph matrix. If values are added or removed, the 762/* Area in window glyph matrix. If values are added or removed,
756 function mark_object in alloc.c has to be changed. */ 763 the function mark_glyph_matrix in alloc.c may need to be changed. */
757 764
758enum glyph_row_area 765enum glyph_row_area
759{ 766{
767 ANY_AREA = -1,
760 LEFT_MARGIN_AREA, 768 LEFT_MARGIN_AREA,
761 TEXT_AREA, 769 TEXT_AREA,
762 RIGHT_MARGIN_AREA, 770 RIGHT_MARGIN_AREA,
@@ -1197,16 +1205,6 @@ extern bool fonts_changed_p;
1197 1205
1198extern struct glyph space_glyph; 1206extern struct glyph space_glyph;
1199 1207
1200/* Window being updated by update_window. This is non-null as long as
1201 update_window has not finished, and null otherwise. */
1202
1203extern struct window *updated_window;
1204
1205/* Glyph row and area updated by update_window_line. */
1206
1207extern struct glyph_row *updated_row;
1208extern int updated_area;
1209
1210/* Non-zero means last display completed. Zero means it was 1208/* Non-zero means last display completed. Zero means it was
1211 preempted. */ 1209 preempted. */
1212 1210
@@ -2678,8 +2676,57 @@ enum move_operation_enum
2678 MOVE_TO_POS = 0x08 2676 MOVE_TO_POS = 0x08
2679}; 2677};
2680 2678
2679/***********************************************************************
2680 Mouse Highlight
2681 ***********************************************************************/
2682
2683/* Structure to hold mouse highlight data. */
2684
2685typedef struct {
2686 /* These variables describe the range of text currently shown in its
2687 mouse-face, together with the window they apply to. As long as
2688 the mouse stays within this range, we need not redraw anything on
2689 its account. Rows and columns are glyph matrix positions in
2690 MOUSE_FACE_WINDOW. */
2691 int mouse_face_beg_row, mouse_face_beg_col, mouse_face_beg_x;
2692 int mouse_face_end_row, mouse_face_end_col, mouse_face_end_x;
2693 Lisp_Object mouse_face_window;
2694 int mouse_face_face_id;
2695 Lisp_Object mouse_face_overlay;
2696
2697 /* FRAME and X, Y position of mouse when last checked for
2698 highlighting. X and Y can be negative or out of range for the frame. */
2699 struct frame *mouse_face_mouse_frame;
2700 int mouse_face_mouse_x, mouse_face_mouse_y;
2701
2702 /* Nonzero if part of the text currently shown in
2703 its mouse-face is beyond the window end. */
2704 unsigned mouse_face_past_end : 1;
2705
2706 /* Nonzero means defer mouse-motion highlighting. */
2707 unsigned mouse_face_defer : 1;
2708
2709 /* Nonzero means that the mouse highlight should not be shown. */
2710 unsigned mouse_face_hidden : 1;
2711} Mouse_HLInfo;
2712
2713DISPEXTERN_INLINE void
2714reset_mouse_highlight (Mouse_HLInfo *hlinfo)
2715{
2716
2717 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
2718 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
2719 hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
2720 hlinfo->mouse_face_beg_x = hlinfo->mouse_face_end_x = 0;
2721 hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
2722 hlinfo->mouse_face_mouse_frame = NULL;
2723 hlinfo->mouse_face_window = Qnil;
2724 hlinfo->mouse_face_overlay = Qnil;
2725 hlinfo->mouse_face_past_end = 0;
2726 hlinfo->mouse_face_hidden = 0;
2727 hlinfo->mouse_face_defer = 0;
2728}
2681 2729
2682
2683/*********************************************************************** 2730/***********************************************************************
2684 Window-based redisplay interface 2731 Window-based redisplay interface
2685 ***********************************************************************/ 2732 ***********************************************************************/
@@ -2718,12 +2765,17 @@ struct redisplay_interface
2718 2765
2719 /* Write or insert LEN glyphs from STRING at the nominal output 2766 /* Write or insert LEN glyphs from STRING at the nominal output
2720 position. */ 2767 position. */
2721 void (*write_glyphs) (struct glyph *string, int len); 2768 void (*write_glyphs) (struct window *w, struct glyph_row *row,
2722 void (*insert_glyphs) (struct glyph *start, int len); 2769 struct glyph *string, enum glyph_row_area area,
2770 int len);
2771 void (*insert_glyphs) (struct window *w, struct glyph_row *row,
2772 struct glyph *start, enum glyph_row_area area,
2773 int len);
2723 2774
2724 /* Clear from nominal output position to X. X < 0 means clear 2775 /* Clear from nominal output position to X. X < 0 means clear
2725 to right end of display. */ 2776 to right end of display. */
2726 void (*clear_end_of_line) (int x); 2777 void (*clear_end_of_line) (struct window *w, struct glyph_row *row,
2778 enum glyph_row_area area, int x);
2727 2779
2728 /* Function to call to scroll the display as described by RUN on 2780 /* Function to call to scroll the display as described by RUN on
2729 window W. */ 2781 window W. */
@@ -2732,7 +2784,8 @@ struct redisplay_interface
2732 /* Function to call after a line in a display has been completely 2784 /* Function to call after a line in a display has been completely
2733 updated. Used to draw truncation marks and alike. DESIRED_ROW 2785 updated. Used to draw truncation marks and alike. DESIRED_ROW
2734 is the desired row which has been updated. */ 2786 is the desired row which has been updated. */
2735 void (*after_update_window_line_hook) (struct glyph_row *desired_row); 2787 void (*after_update_window_line_hook) (struct window *w,
2788 struct glyph_row *desired_row);
2736 2789
2737 /* Function to call before beginning to update window W in 2790 /* Function to call before beginning to update window W in
2738 window-based redisplay. */ 2791 window-based redisplay. */
@@ -2743,13 +2796,8 @@ struct redisplay_interface
2743 MOUSE_FACE_OVERWRITTEN_P non-zero means that some lines in W 2796 MOUSE_FACE_OVERWRITTEN_P non-zero means that some lines in W
2744 that contained glyphs in mouse-face were overwritten, so we 2797 that contained glyphs in mouse-face were overwritten, so we
2745 have to update the mouse highlight. */ 2798 have to update the mouse highlight. */
2746 void (*update_window_end_hook) (struct window *w, int cursor_on_p, 2799 void (*update_window_end_hook) (struct window *w, bool cursor_on_p,
2747 int mouse_face_overwritten_p); 2800 bool mouse_face_overwritten_p);
2748
2749 /* Move cursor to row/column position VPOS/HPOS, pixel coordinates
2750 Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y
2751 are window-relative pixel positions. */
2752 void (*cursor_to) (int vpos, int hpos, int y, int x);
2753 2801
2754 /* Flush the display of frame F. For X, this is XFlush. */ 2802 /* Flush the display of frame F. For X, this is XFlush. */
2755 void (*flush_display) (struct frame *f); 2803 void (*flush_display) (struct frame *f);
@@ -2803,10 +2851,10 @@ struct redisplay_interface
2803 0, don't draw cursor. If ACTIVE_P is 1, system caret 2851 0, don't draw cursor. If ACTIVE_P is 1, system caret
2804 should track this cursor (when applicable). */ 2852 should track this cursor (when applicable). */
2805 void (*draw_window_cursor) (struct window *w, 2853 void (*draw_window_cursor) (struct window *w,
2806 struct glyph_row *glyph_row, 2854 struct glyph_row *glyph_row,
2807 int x, int y, 2855 int x, int y,
2808 int cursor_type, int cursor_width, 2856 enum text_cursor_kinds cursor_type,
2809 int on_p, int active_p); 2857 int cursor_width, bool on_p, bool active_p);
2810 2858
2811/* Draw vertical border for window W from (X,Y_0) to (X,Y_1). */ 2859/* Draw vertical border for window W from (X,Y_0) to (X,Y_1). */
2812 void (*draw_vertical_window_border) (struct window *w, 2860 void (*draw_vertical_window_border) (struct window *w,
@@ -2829,11 +2877,6 @@ struct redisplay_interface
2829 2877
2830#ifdef HAVE_WINDOW_SYSTEM 2878#ifdef HAVE_WINDOW_SYSTEM
2831 2879
2832/* Structure forward declarations. */
2833
2834struct image;
2835
2836
2837/* Each image format (JPEG, TIFF, ...) supported is described by 2880/* Each image format (JPEG, TIFF, ...) supported is described by
2838 a structure of the type below. */ 2881 a structure of the type below. */
2839 2882
@@ -2870,7 +2913,7 @@ struct image
2870{ 2913{
2871 /* The time in seconds at which the image was last displayed. Set 2914 /* The time in seconds at which the image was last displayed. Set
2872 in prepare_image_for_display. */ 2915 in prepare_image_for_display. */
2873 EMACS_TIME timestamp; 2916 struct timespec timestamp;
2874 2917
2875 /* Pixmaps of the image. */ 2918 /* Pixmaps of the image. */
2876 Pixmap pixmap, mask; 2919 Pixmap pixmap, mask;
@@ -3124,14 +3167,15 @@ int resize_mini_window (struct window *, int);
3124void set_vertical_scroll_bar (struct window *); 3167void set_vertical_scroll_bar (struct window *);
3125#endif 3168#endif
3126int try_window (Lisp_Object, struct text_pos, int); 3169int try_window (Lisp_Object, struct text_pos, int);
3127void window_box (struct window *, int, int *, int *, int *, int *); 3170void window_box (struct window *, enum glyph_row_area,
3171 int *, int *, int *, int *);
3128int window_box_height (struct window *); 3172int window_box_height (struct window *);
3129int window_text_bottom_y (struct window *); 3173int window_text_bottom_y (struct window *);
3130int window_box_width (struct window *, int); 3174int window_box_width (struct window *, enum glyph_row_area);
3131int window_box_left (struct window *, int); 3175int window_box_left (struct window *, enum glyph_row_area);
3132int window_box_left_offset (struct window *, int); 3176int window_box_left_offset (struct window *, enum glyph_row_area);
3133int window_box_right (struct window *, int); 3177int window_box_right (struct window *, enum glyph_row_area);
3134int window_box_right_offset (struct window *, int); 3178int window_box_right_offset (struct window *, enum glyph_row_area);
3135int estimate_mode_line_height (struct frame *, enum face_id); 3179int estimate_mode_line_height (struct frame *, enum face_id);
3136void pixel_to_glyph_coords (struct frame *, int, int, int *, int *, 3180void pixel_to_glyph_coords (struct frame *, int, int, int *, int *,
3137 NativeRectangle *, int); 3181 NativeRectangle *, int);
@@ -3182,12 +3226,12 @@ extern void x_get_glyph_overhangs (struct glyph *, struct frame *,
3182 int *, int *); 3226 int *, int *);
3183extern void x_produce_glyphs (struct it *); 3227extern void x_produce_glyphs (struct it *);
3184 3228
3185extern void x_write_glyphs (struct glyph *, int); 3229extern void x_write_glyphs (struct window *, struct glyph_row *,
3186extern void x_insert_glyphs (struct glyph *, int len); 3230 struct glyph *, enum glyph_row_area, int);
3187extern void x_clear_end_of_line (int); 3231extern void x_insert_glyphs (struct window *, struct glyph_row *,
3188 3232 struct glyph *, enum glyph_row_area, int);
3189extern struct cursor_pos output_cursor; 3233extern void x_clear_end_of_line (struct window *, struct glyph_row *,
3190 3234 enum glyph_row_area, int);
3191extern void x_fix_overlapping_area (struct window *, struct glyph_row *, 3235extern void x_fix_overlapping_area (struct window *, struct glyph_row *,
3192 enum glyph_row_area, int); 3236 enum glyph_row_area, int);
3193extern void draw_phys_cursor_glyph (struct window *, 3237extern void draw_phys_cursor_glyph (struct window *,
@@ -3196,13 +3240,8 @@ extern void draw_phys_cursor_glyph (struct window *,
3196extern void get_phys_cursor_geometry (struct window *, struct glyph_row *, 3240extern void get_phys_cursor_geometry (struct window *, struct glyph_row *,
3197 struct glyph *, int *, int *, int *); 3241 struct glyph *, int *, int *, int *);
3198extern void erase_phys_cursor (struct window *); 3242extern void erase_phys_cursor (struct window *);
3199extern void display_and_set_cursor (struct window *, 3243extern void display_and_set_cursor (struct window *, bool, int, int, int, int);
3200 int, int, int, int, int); 3244extern void x_update_cursor (struct frame *, bool);
3201
3202extern void set_output_cursor (struct cursor_pos *);
3203extern void x_cursor_to (int, int, int, int);
3204
3205extern void x_update_cursor (struct frame *, int);
3206extern void x_clear_cursor (struct window *); 3245extern void x_clear_cursor (struct window *);
3207extern void x_draw_vertical_border (struct window *w); 3246extern void x_draw_vertical_border (struct window *w);
3208 3247
@@ -3365,8 +3404,6 @@ extern frame_parm_handler x_frame_parm_handlers[];
3365extern void start_hourglass (void); 3404extern void start_hourglass (void);
3366extern void cancel_hourglass (void); 3405extern void cancel_hourglass (void);
3367extern int hourglass_shown_p; 3406extern int hourglass_shown_p;
3368
3369struct atimer; /* Defined in atimer.h. */
3370/* If non-null, an asynchronous timer that, when it expires, displays 3407/* If non-null, an asynchronous timer that, when it expires, displays
3371 an hourglass cursor on all frames. */ 3408 an hourglass cursor on all frames. */
3372extern struct atimer *hourglass_atimer; 3409extern struct atimer *hourglass_atimer;
diff --git a/src/dispnew.c b/src/dispnew.c
index 522a0e6a30d..1d7cad13e6d 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -49,12 +49,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
49#include TERM_HEADER 49#include TERM_HEADER
50#endif /* HAVE_WINDOW_SYSTEM */ 50#endif /* HAVE_WINDOW_SYSTEM */
51 51
52/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
53
54#include "systime.h"
55#include <errno.h> 52#include <errno.h>
56 53
57#include <fpending.h> 54#include <fpending.h>
55#include <timespec.h>
58 56
59#if defined (HAVE_TERM_H) && defined (GNU_LINUX) 57#if defined (HAVE_TERM_H) && defined (GNU_LINUX)
60#include <term.h> /* for tgetent */ 58#include <term.h> /* for tgetent */
@@ -135,25 +133,20 @@ struct frame *last_nonminibuf_frame;
135 133
136static bool delayed_size_change; 134static bool delayed_size_change;
137 135
138/* Updated window if != 0. Set by update_window. */
139
140struct window *updated_window;
141
142/* Glyph row updated in update_window_line, and area that is updated. */
143
144struct glyph_row *updated_row;
145int updated_area;
146
147/* A glyph for a space. */ 136/* A glyph for a space. */
148 137
149struct glyph space_glyph; 138struct glyph space_glyph;
150 139
140#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
141
151/* Counts of allocated structures. These counts serve to diagnose 142/* Counts of allocated structures. These counts serve to diagnose
152 memory leaks and double frees. */ 143 memory leaks and double frees. */
153 144
154static int glyph_matrix_count; 145static int glyph_matrix_count;
155static int glyph_pool_count; 146static int glyph_pool_count;
156 147
148#endif /* GLYPH_DEBUG and ENABLE_CHECKING */
149
157/* If non-null, the frame whose frame matrices are manipulated. If 150/* If non-null, the frame whose frame matrices are manipulated. If
158 null, window matrices are worked on. */ 151 null, window matrices are worked on. */
159 152
@@ -307,9 +300,11 @@ new_glyph_matrix (struct glyph_pool *pool)
307{ 300{
308 struct glyph_matrix *result = xzalloc (sizeof *result); 301 struct glyph_matrix *result = xzalloc (sizeof *result);
309 302
303#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
310 /* Increment number of allocated matrices. This count is used 304 /* Increment number of allocated matrices. This count is used
311 to detect memory leaks. */ 305 to detect memory leaks. */
312 ++glyph_matrix_count; 306 ++glyph_matrix_count;
307#endif
313 308
314 /* Set pool and return. */ 309 /* Set pool and return. */
315 result->pool = pool; 310 result->pool = pool;
@@ -319,10 +314,10 @@ new_glyph_matrix (struct glyph_pool *pool)
319 314
320/* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed. 315/* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed.
321 316
322 The global counter glyph_matrix_count is decremented when a matrix 317 If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global counter
323 is freed. If the count gets negative, more structures were freed 318 glyph_matrix_count is decremented when a matrix is freed. If the count
324 than allocated, i.e. one matrix was freed more than once or a bogus 319 gets negative, more structures were freed than allocated, i.e. one matrix
325 pointer was passed to this function. 320 was freed more than once or a bogus pointer was passed to this function.
326 321
327 If MATRIX->pool is null, this means that the matrix manages its own 322 If MATRIX->pool is null, this means that the matrix manages its own
328 glyph memory---this is done for matrices on X frames. Freeing the 323 glyph memory---this is done for matrices on X frames. Freeing the
@@ -335,10 +330,12 @@ free_glyph_matrix (struct glyph_matrix *matrix)
335 { 330 {
336 int i; 331 int i;
337 332
333#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
338 /* Detect the case that more matrices are freed than were 334 /* Detect the case that more matrices are freed than were
339 allocated. */ 335 allocated. */
340 if (--glyph_matrix_count < 0) 336 --glyph_matrix_count;
341 emacs_abort (); 337 eassert (glyph_matrix_count >= 0);
338#endif
342 339
343 /* Free glyph memory if MATRIX owns it. */ 340 /* Free glyph memory if MATRIX owns it. */
344 if (matrix->pool == NULL) 341 if (matrix->pool == NULL)
@@ -355,25 +352,19 @@ free_glyph_matrix (struct glyph_matrix *matrix)
355/* Return the number of glyphs to reserve for a marginal area of 352/* Return the number of glyphs to reserve for a marginal area of
356 window W. TOTAL_GLYPHS is the number of glyphs in a complete 353 window W. TOTAL_GLYPHS is the number of glyphs in a complete
357 display line of window W. MARGIN gives the width of the marginal 354 display line of window W. MARGIN gives the width of the marginal
358 area in canonical character units. MARGIN should be an integer 355 area in canonical character units. */
359 or a float. */
360 356
361static int 357static int
362margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin) 358margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin)
363{ 359{
364 int n; 360 if (margin > 0)
365
366 if (NUMBERP (margin))
367 { 361 {
368 int width = w->total_cols; 362 int width = w->total_cols;
369 double d = max (0, XFLOATINT (margin)); 363 double d = max (0, margin);
370 d = min (width / 2 - 1, d); 364 d = min (width / 2 - 1, d);
371 n = (int) ((double) total_glyphs / width * d); 365 return (int) ((double) total_glyphs / width * d);
372 } 366 }
373 else 367 return 0;
374 n = 0;
375
376 return n;
377} 368}
378 369
379/* Return true if ROW's hash value is correct. 370/* Return true if ROW's hash value is correct.
@@ -422,7 +413,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
422 Get W's size. */ 413 Get W's size. */
423 if (w) 414 if (w)
424 { 415 {
425 window_box (w, -1, 0, 0, &window_width, &window_height); 416 window_box (w, ANY_AREA, 0, 0, &window_width, &window_height);
426 417
427 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w); 418 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
428 header_line_changed_p = header_line_p != matrix->header_line_p; 419 header_line_changed_p = header_line_p != matrix->header_line_p;
@@ -600,8 +591,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
600 591
601 /* Window end is invalid, if inside of the rows that 592 /* Window end is invalid, if inside of the rows that
602 are invalidated below. */ 593 are invalidated below. */
603 if (INTEGERP (w->window_end_vpos) 594 if (w->window_end_vpos >= i)
604 && XFASTINT (w->window_end_vpos) >= i)
605 w->window_end_valid = 0; 595 w->window_end_valid = 0;
606 596
607 while (i < matrix->nrows) 597 while (i < matrix->nrows)
@@ -1310,38 +1300,41 @@ row_equal_p (struct glyph_row *a, struct glyph_row *b, bool mouse_face_p)
1310 See dispextern.h for an overall explanation of glyph pools. 1300 See dispextern.h for an overall explanation of glyph pools.
1311 ***********************************************************************/ 1301 ***********************************************************************/
1312 1302
1313/* Allocate a glyph_pool structure. The structure returned is 1303/* Allocate a glyph_pool structure. The structure returned is initialized
1314 initialized with zeros. The global variable glyph_pool_count is 1304 with zeros. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global
1315 incremented for each pool allocated. */ 1305 variable glyph_pool_count is incremented for each pool allocated. */
1316 1306
1317static struct glyph_pool * 1307static struct glyph_pool *
1318new_glyph_pool (void) 1308new_glyph_pool (void)
1319{ 1309{
1320 struct glyph_pool *result = xzalloc (sizeof *result); 1310 struct glyph_pool *result = xzalloc (sizeof *result);
1321 1311
1312#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
1322 /* For memory leak and double deletion checking. */ 1313 /* For memory leak and double deletion checking. */
1323 ++glyph_pool_count; 1314 ++glyph_pool_count;
1315#endif
1324 1316
1325 return result; 1317 return result;
1326} 1318}
1327 1319
1328 1320
1329/* Free a glyph_pool structure POOL. The function may be called with 1321/* Free a glyph_pool structure POOL. The function may be called with
1330 a null POOL pointer. The global variable glyph_pool_count is 1322 a null POOL pointer. If GLYPH_DEBUG and ENABLE_CHECKING are in effect,
1331 decremented with every pool structure freed. If this count gets 1323 global variable glyph_pool_count is decremented with every pool structure
1332 negative, more structures were freed than allocated, i.e. one 1324 freed. If this count gets negative, more structures were freed than
1333 structure must have been freed more than once or a bogus pointer 1325 allocated, i.e. one structure must have been freed more than once or
1334 was passed to free_glyph_pool. */ 1326 a bogus pointer was passed to free_glyph_pool. */
1335 1327
1336static void 1328static void
1337free_glyph_pool (struct glyph_pool *pool) 1329free_glyph_pool (struct glyph_pool *pool)
1338{ 1330{
1339 if (pool) 1331 if (pool)
1340 { 1332 {
1333#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
1341 /* More freed than allocated? */ 1334 /* More freed than allocated? */
1342 --glyph_pool_count; 1335 --glyph_pool_count;
1343 eassert (glyph_pool_count >= 0); 1336 eassert (glyph_pool_count >= 0);
1344 1337#endif
1345 xfree (pool->glyphs); 1338 xfree (pool->glyphs);
1346 xfree (pool); 1339 xfree (pool);
1347 } 1340 }
@@ -1860,7 +1853,7 @@ showing_window_margins_p (struct window *w)
1860 if (showing_window_margins_p (XWINDOW (w->contents))) 1853 if (showing_window_margins_p (XWINDOW (w->contents)))
1861 return 1; 1854 return 1;
1862 } 1855 }
1863 else if (!NILP (w->left_margin_cols) || !NILP (w->right_margin_cols)) 1856 else if (w->left_margin_cols > 0 || w->right_margin_cols > 0)
1864 return 1; 1857 return 1;
1865 1858
1866 w = NILP (w->next) ? 0 : XWINDOW (w->next); 1859 w = NILP (w->next) ? 0 : XWINDOW (w->next);
@@ -2254,11 +2247,11 @@ check_glyph_memory (void)
2254 FOR_EACH_FRAME (tail, frame) 2247 FOR_EACH_FRAME (tail, frame)
2255 free_glyphs (XFRAME (frame)); 2248 free_glyphs (XFRAME (frame));
2256 2249
2250#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2257 /* Check that nothing is left allocated. */ 2251 /* Check that nothing is left allocated. */
2258 if (glyph_matrix_count) 2252 eassert (glyph_matrix_count == 0);
2259 emacs_abort (); 2253 eassert (glyph_pool_count == 0);
2260 if (glyph_pool_count) 2254#endif
2261 emacs_abort ();
2262} 2255}
2263 2256
2264 2257
@@ -2275,7 +2268,7 @@ check_glyph_memory (void)
2275 screen. We build such a view by constructing a frame matrix from 2268 screen. We build such a view by constructing a frame matrix from
2276 window matrices in this section. 2269 window matrices in this section.
2277 2270
2278 Windows that must be updated have their must_be_update_p flag set. 2271 Windows that must be updated have their must_be_updated_p flag set.
2279 For all such windows, their desired matrix is made part of the 2272 For all such windows, their desired matrix is made part of the
2280 desired frame matrix. For other windows, their current matrix is 2273 desired frame matrix. For other windows, their current matrix is
2281 made part of the desired frame matrix. 2274 made part of the desired frame matrix.
@@ -3230,14 +3223,12 @@ redraw_overlapped_rows (struct window *w, int yb)
3230 3223
3231 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) 3224 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3232 { 3225 {
3233 updated_row = row; 3226 output_cursor_to (w, i, 0, row->y,
3234 updated_area = area; 3227 area == TEXT_AREA ? row->x : 0);
3235 FRAME_RIF (f)->cursor_to (i, 0, row->y,
3236 area == TEXT_AREA ? row->x : 0);
3237 if (row->used[area]) 3228 if (row->used[area])
3238 FRAME_RIF (f)->write_glyphs (row->glyphs[area], 3229 FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area],
3239 row->used[area]); 3230 area, row->used[area]);
3240 FRAME_RIF (f)->clear_end_of_line (-1); 3231 FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
3241 } 3232 }
3242 3233
3243 row->overlapped_p = 0; 3234 row->overlapped_p = 0;
@@ -3490,7 +3481,7 @@ update_window (struct window *w, bool force_p)
3490 /* End the update of window W. Don't set the cursor if we 3481 /* End the update of window W. Don't set the cursor if we
3491 paused updating the display because in this case, 3482 paused updating the display because in this case,
3492 set_window_cursor_after_update hasn't been called, and 3483 set_window_cursor_after_update hasn't been called, and
3493 output_cursor doesn't contain the cursor location. */ 3484 W->output_cursor doesn't contain the cursor location. */
3494 rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p); 3485 rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
3495 } 3486 }
3496 else 3487 else
@@ -3511,22 +3502,20 @@ update_window (struct window *w, bool force_p)
3511 AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */ 3502 AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
3512 3503
3513static void 3504static void
3514update_marginal_area (struct window *w, int area, int vpos) 3505update_marginal_area (struct window *w, struct glyph_row *updated_row,
3506 enum glyph_row_area area, int vpos)
3515{ 3507{
3516 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); 3508 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3517 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); 3509 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3518 3510
3519 /* Let functions in xterm.c know what area subsequent X positions
3520 will be relative to. */
3521 updated_area = area;
3522
3523 /* Set cursor to start of glyphs, write them, and clear to the end 3511 /* Set cursor to start of glyphs, write them, and clear to the end
3524 of the area. I don't think that something more sophisticated is 3512 of the area. I don't think that something more sophisticated is
3525 necessary here, since marginal areas will not be the default. */ 3513 necessary here, since marginal areas will not be the default. */
3526 rif->cursor_to (vpos, 0, desired_row->y, 0); 3514 output_cursor_to (w, vpos, 0, desired_row->y, 0);
3527 if (desired_row->used[area]) 3515 if (desired_row->used[area])
3528 rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]); 3516 rif->write_glyphs (w, updated_row, desired_row->glyphs[area],
3529 rif->clear_end_of_line (-1); 3517 area, desired_row->used[area]);
3518 rif->clear_end_of_line (w, updated_row, area, -1);
3530} 3519}
3531 3520
3532 3521
@@ -3534,17 +3523,13 @@ update_marginal_area (struct window *w, int area, int vpos)
3534 Value is true if display has changed. */ 3523 Value is true if display has changed. */
3535 3524
3536static bool 3525static bool
3537update_text_area (struct window *w, int vpos) 3526update_text_area (struct window *w, struct glyph_row *updated_row, int vpos)
3538{ 3527{
3539 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos); 3528 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
3540 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos); 3529 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3541 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); 3530 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3542 bool changed_p = 0; 3531 bool changed_p = 0;
3543 3532
3544 /* Let functions in xterm.c know what area subsequent X positions
3545 will be relative to. */
3546 updated_area = TEXT_AREA;
3547
3548 /* If rows are at different X or Y, or rows have different height, 3533 /* If rows are at different X or Y, or rows have different height,
3549 or the current row is marked invalid, write the entire line. */ 3534 or the current row is marked invalid, write the entire line. */
3550 if (!current_row->enabled_p 3535 if (!current_row->enabled_p
@@ -3564,14 +3549,14 @@ update_text_area (struct window *w, int vpos)
3564 && !(current_row->mode_line_p && vpos > 0)) 3549 && !(current_row->mode_line_p && vpos > 0))
3565 || current_row->x != desired_row->x) 3550 || current_row->x != desired_row->x)
3566 { 3551 {
3567 rif->cursor_to (vpos, 0, desired_row->y, desired_row->x); 3552 output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
3568 3553
3569 if (desired_row->used[TEXT_AREA]) 3554 if (desired_row->used[TEXT_AREA])
3570 rif->write_glyphs (desired_row->glyphs[TEXT_AREA], 3555 rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA],
3571 desired_row->used[TEXT_AREA]); 3556 TEXT_AREA, desired_row->used[TEXT_AREA]);
3572 3557
3573 /* Clear to end of window. */ 3558 /* Clear to end of window. */
3574 rif->clear_end_of_line (-1); 3559 rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
3575 changed_p = 1; 3560 changed_p = 1;
3576 3561
3577 /* This erases the cursor. We do this here because 3562 /* This erases the cursor. We do this here because
@@ -3707,8 +3692,9 @@ update_text_area (struct window *w, int vpos)
3707 break; 3692 break;
3708 } 3693 }
3709 3694
3710 rif->cursor_to (vpos, start_hpos, desired_row->y, start_x); 3695 output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
3711 rif->write_glyphs (start, i - start_hpos); 3696 rif->write_glyphs (w, updated_row, start,
3697 TEXT_AREA, i - start_hpos);
3712 changed_p = 1; 3698 changed_p = 1;
3713 } 3699 }
3714 } 3700 }
@@ -3716,8 +3702,9 @@ update_text_area (struct window *w, int vpos)
3716 /* Write the rest. */ 3702 /* Write the rest. */
3717 if (i < desired_row->used[TEXT_AREA]) 3703 if (i < desired_row->used[TEXT_AREA])
3718 { 3704 {
3719 rif->cursor_to (vpos, i, desired_row->y, x); 3705 output_cursor_to (w, vpos, i, desired_row->y, x);
3720 rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i); 3706 rif->write_glyphs (w, updated_row, desired_glyph,
3707 TEXT_AREA, desired_row->used[TEXT_AREA] - i);
3721 changed_p = 1; 3708 changed_p = 1;
3722 } 3709 }
3723 3710
@@ -3737,9 +3724,9 @@ update_text_area (struct window *w, int vpos)
3737 { 3724 {
3738 /* If old row extends to the end of the text area, clear. */ 3725 /* If old row extends to the end of the text area, clear. */
3739 if (i >= desired_row->used[TEXT_AREA]) 3726 if (i >= desired_row->used[TEXT_AREA])
3740 rif->cursor_to (vpos, i, desired_row->y, 3727 output_cursor_to (w, vpos, i, desired_row->y,
3741 desired_row->pixel_width); 3728 desired_row->pixel_width);
3742 rif->clear_end_of_line (-1); 3729 rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
3743 changed_p = 1; 3730 changed_p = 1;
3744 } 3731 }
3745 else if (desired_row->pixel_width < current_row->pixel_width) 3732 else if (desired_row->pixel_width < current_row->pixel_width)
@@ -3749,8 +3736,8 @@ update_text_area (struct window *w, int vpos)
3749 int xlim; 3736 int xlim;
3750 3737
3751 if (i >= desired_row->used[TEXT_AREA]) 3738 if (i >= desired_row->used[TEXT_AREA])
3752 rif->cursor_to (vpos, i, desired_row->y, 3739 output_cursor_to (w, vpos, i, desired_row->y,
3753 desired_row->pixel_width); 3740 desired_row->pixel_width);
3754 3741
3755 /* If cursor is displayed at the end of the line, make sure 3742 /* If cursor is displayed at the end of the line, make sure
3756 it's cleared. Nowadays we don't have a phys_cursor_glyph 3743 it's cleared. Nowadays we don't have a phys_cursor_glyph
@@ -3767,7 +3754,7 @@ update_text_area (struct window *w, int vpos)
3767 } 3754 }
3768 else 3755 else
3769 xlim = current_row->pixel_width; 3756 xlim = current_row->pixel_width;
3770 rif->clear_end_of_line (xlim); 3757 rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
3771 changed_p = 1; 3758 changed_p = 1;
3772 } 3759 }
3773 } 3760 }
@@ -3786,10 +3773,6 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
3786 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); 3773 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3787 bool changed_p = 0; 3774 bool changed_p = 0;
3788 3775
3789 /* Set the row being updated. This is important to let xterm.c
3790 know what line height values are in effect. */
3791 updated_row = desired_row;
3792
3793 /* A row can be completely invisible in case a desired matrix was 3776 /* A row can be completely invisible in case a desired matrix was
3794 built with a vscroll and then make_cursor_line_fully_visible shifts 3777 built with a vscroll and then make_cursor_line_fully_visible shifts
3795 the matrix. Make sure to make such rows current anyway, since 3778 the matrix. Make sure to make such rows current anyway, since
@@ -3800,11 +3783,10 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
3800 eassert (desired_row->enabled_p); 3783 eassert (desired_row->enabled_p);
3801 3784
3802 /* Update display of the left margin area, if there is one. */ 3785 /* Update display of the left margin area, if there is one. */
3803 if (!desired_row->full_width_p 3786 if (!desired_row->full_width_p && w->left_margin_cols > 0)
3804 && !NILP (w->left_margin_cols))
3805 { 3787 {
3806 changed_p = 1; 3788 changed_p = 1;
3807 update_marginal_area (w, LEFT_MARGIN_AREA, vpos); 3789 update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
3808 /* Setting this flag will ensure the vertical border, if 3790 /* Setting this flag will ensure the vertical border, if
3809 any, between this window and the one on its left will be 3791 any, between this window and the one on its left will be
3810 redrawn. This is necessary because updating the left 3792 redrawn. This is necessary because updating the left
@@ -3813,7 +3795,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
3813 } 3795 }
3814 3796
3815 /* Update the display of the text area. */ 3797 /* Update the display of the text area. */
3816 if (update_text_area (w, vpos)) 3798 if (update_text_area (w, desired_row, vpos))
3817 { 3799 {
3818 changed_p = 1; 3800 changed_p = 1;
3819 if (current_row->mouse_face_p) 3801 if (current_row->mouse_face_p)
@@ -3821,11 +3803,10 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
3821 } 3803 }
3822 3804
3823 /* Update display of the right margin area, if there is one. */ 3805 /* Update display of the right margin area, if there is one. */
3824 if (!desired_row->full_width_p 3806 if (!desired_row->full_width_p && w->right_margin_cols > 0)
3825 && !NILP (w->right_margin_cols))
3826 { 3807 {
3827 changed_p = 1; 3808 changed_p = 1;
3828 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos); 3809 update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
3829 } 3810 }
3830 3811
3831 /* Draw truncation marks etc. */ 3812 /* Draw truncation marks etc. */
@@ -3839,12 +3820,11 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
3839 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p 3820 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
3840 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row) 3821 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
3841 != MATRIX_ROW_CONTINUATION_LINE_P (current_row))) 3822 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
3842 rif->after_update_window_line_hook (desired_row); 3823 rif->after_update_window_line_hook (w, desired_row);
3843 } 3824 }
3844 3825
3845 /* Update current_row from desired_row. */ 3826 /* Update current_row from desired_row. */
3846 make_current (w->desired_matrix, w->current_matrix, vpos); 3827 make_current (w->desired_matrix, w->current_matrix, vpos);
3847 updated_row = NULL;
3848 return changed_p; 3828 return changed_p;
3849} 3829}
3850 3830
@@ -3856,7 +3836,6 @@ static void
3856set_window_cursor_after_update (struct window *w) 3836set_window_cursor_after_update (struct window *w)
3857{ 3837{
3858 struct frame *f = XFRAME (w->frame); 3838 struct frame *f = XFRAME (w->frame);
3859 struct redisplay_interface *rif = FRAME_RIF (f);
3860 int cx, cy, vpos, hpos; 3839 int cx, cy, vpos, hpos;
3861 3840
3862 /* Not intended for frame matrix updates. */ 3841 /* Not intended for frame matrix updates. */
@@ -3928,7 +3907,7 @@ set_window_cursor_after_update (struct window *w)
3928 Horizontal position is -1 when cursor is on the left fringe. */ 3907 Horizontal position is -1 when cursor is on the left fringe. */
3929 hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1); 3908 hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
3930 vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1); 3909 vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
3931 rif->cursor_to (vpos, hpos, cy, cx); 3910 output_cursor_to (w, vpos, hpos, cy, cx);
3932} 3911}
3933 3912
3934 3913
@@ -4599,10 +4578,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p)
4599 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos); 4578 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
4600 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); 4579 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
4601 4580
4602 if (INTEGERP (w->left_margin_cols)) 4581 x += max (0, w->left_margin_cols);
4603 x += XFASTINT (w->left_margin_cols);
4604
4605 /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
4606 cursor_to (f, y, x); 4582 cursor_to (f, y, x);
4607 } 4583 }
4608 } 4584 }
@@ -5090,9 +5066,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5090 wrong thing with `face-remapping-alist' (bug#2044). */ 5066 wrong thing with `face-remapping-alist' (bug#2044). */
5091 Fset_buffer (w->contents); 5067 Fset_buffer (w->contents);
5092 itdata = bidi_shelve_cache (); 5068 itdata = bidi_shelve_cache ();
5093 SET_TEXT_POS_FROM_MARKER (startp, w->start); 5069 CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
5094 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
5095 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
5096 start_display (&it, w, startp); 5070 start_display (&it, w, startp);
5097 /* start_display takes into account the header-line row, but IT's 5071 /* start_display takes into account the header-line row, but IT's
5098 vpos still counts from the glyph row that includes the window's 5072 vpos still counts from the glyph row that includes the window's
@@ -5729,9 +5703,9 @@ additional wait period, in milliseconds; this is for backwards compatibility.
5729 5703
5730 if (duration > 0) 5704 if (duration > 0)
5731 { 5705 {
5732 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration); 5706 struct timespec t = dtotimespec (duration);
5733 wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX), 5707 wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX),
5734 EMACS_NSECS (t), 0, 0, Qnil, NULL, 0); 5708 t.tv_nsec, 0, 0, Qnil, NULL, 0);
5735 } 5709 }
5736 5710
5737 return Qnil; 5711 return Qnil;
@@ -5778,9 +5752,9 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
5778 return Qt; 5752 return Qt;
5779 else 5753 else
5780 { 5754 {
5781 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds); 5755 struct timespec t = dtotimespec (seconds);
5782 sec = min (EMACS_SECS (t), WAIT_READING_MAX); 5756 sec = min (t.tv_sec, WAIT_READING_MAX);
5783 nsec = EMACS_NSECS (t); 5757 nsec = t.tv_nsec;
5784 } 5758 }
5785 } 5759 }
5786 else if (EQ (timeout, Qt)) 5760 else if (EQ (timeout, Qt))
@@ -5884,9 +5858,8 @@ pass nil for VARIABLE. */)
5884 goto changed; 5858 goto changed;
5885 } 5859 }
5886 /* Check that the buffer info matches. */ 5860 /* Check that the buffer info matches. */
5887 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 5861 FOR_EACH_LIVE_BUFFER (tail, buf)
5888 { 5862 {
5889 buf = XCDR (XCAR (tail));
5890 /* Ignore buffers that aren't included in buffer lists. */ 5863 /* Ignore buffers that aren't included in buffer lists. */
5891 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') 5864 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
5892 continue; 5865 continue;
@@ -5916,7 +5889,7 @@ pass nil for VARIABLE. */)
5916 n = 1; 5889 n = 1;
5917 FOR_EACH_FRAME (tail, frame) 5890 FOR_EACH_FRAME (tail, frame)
5918 n += 2; 5891 n += 2;
5919 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 5892 FOR_EACH_LIVE_BUFFER (tail, buf)
5920 n += 3; 5893 n += 3;
5921 /* Reallocate the vector if data has grown to need it, 5894 /* Reallocate the vector if data has grown to need it,
5922 or if it has shrunk a lot. */ 5895 or if it has shrunk a lot. */
@@ -5941,9 +5914,8 @@ pass nil for VARIABLE. */)
5941 ASET (state, idx, XFRAME (frame)->name); 5914 ASET (state, idx, XFRAME (frame)->name);
5942 idx++; 5915 idx++;
5943 } 5916 }
5944 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 5917 FOR_EACH_LIVE_BUFFER (tail, buf)
5945 { 5918 {
5946 buf = XCDR (XCAR (tail));
5947 /* Ignore buffers that aren't included in buffer lists. */ 5919 /* Ignore buffers that aren't included in buffer lists. */
5948 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') 5920 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
5949 continue; 5921 continue;
@@ -6200,19 +6172,6 @@ WINDOW nil or omitted means report on the selected window. */)
6200{ 6172{
6201 return decode_any_window (window)->cursor_off_p ? Qnil : Qt; 6173 return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
6202} 6174}
6203
6204DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
6205 Slast_nonminibuf_frame, 0, 0, 0,
6206 doc: /* Value is last nonminibuffer frame. */)
6207 (void)
6208{
6209 Lisp_Object frame = Qnil;
6210
6211 if (last_nonminibuf_frame)
6212 XSETFRAME (frame, last_nonminibuf_frame);
6213
6214 return frame;
6215}
6216 6175
6217/*********************************************************************** 6176/***********************************************************************
6218 Initialization 6177 Initialization
@@ -6231,7 +6190,6 @@ syms_of_display (void)
6231 defsubr (&Ssend_string_to_terminal); 6190 defsubr (&Ssend_string_to_terminal);
6232 defsubr (&Sinternal_show_cursor); 6191 defsubr (&Sinternal_show_cursor);
6233 defsubr (&Sinternal_show_cursor_p); 6192 defsubr (&Sinternal_show_cursor_p);
6234 defsubr (&Slast_nonminibuf_frame);
6235 6193
6236#ifdef GLYPH_DEBUG 6194#ifdef GLYPH_DEBUG
6237 defsubr (&Sdump_redisplay_history); 6195 defsubr (&Sdump_redisplay_history);
diff --git a/src/doc.c b/src/doc.c
index 009616f4f87..d3f8fde08f6 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -905,7 +905,7 @@ Otherwise, return a new string, without any text properties. */)
905 If this one's not active, get nil. */ 905 If this one's not active, get nil. */
906 earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps))); 906 earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps)));
907 describe_map_tree (tem, 1, Fnreverse (earlier_maps), 907 describe_map_tree (tem, 1, Fnreverse (earlier_maps),
908 Qnil, (char *)0, 1, 0, 0, 1); 908 Qnil, 0, 1, 0, 0, 1);
909 } 909 }
910 tem = Fbuffer_string (); 910 tem = Fbuffer_string ();
911 Ferase_buffer (); 911 Ferase_buffer ();
diff --git a/src/editfns.c b/src/editfns.c
index 50bde90788d..84a5c8395fc 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -64,7 +64,7 @@ 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 Lisp_Object format_time_string (char const *, ptrdiff_t, EMACS_TIME, 67static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec,
68 bool, struct tm *); 68 bool, struct tm *);
69static int tm_diff (struct tm *, struct tm *); 69static int tm_diff (struct tm *, struct tm *);
70static void update_buffer_properties (ptrdiff_t, ptrdiff_t); 70static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
@@ -233,26 +233,12 @@ Beginning of buffer is position (point-min), end is (point-max).
233The return value is POSITION. */) 233The return value is POSITION. */)
234 (register Lisp_Object position) 234 (register Lisp_Object position)
235{ 235{
236 ptrdiff_t pos; 236 if (MARKERP (position))
237 237 set_point_from_marker (position);
238 if (MARKERP (position) 238 else if (INTEGERP (position))
239 && current_buffer == XMARKER (position)->buffer) 239 SET_PT (clip_to_bounds (BEGV, XINT (position), ZV));
240 { 240 else
241 pos = marker_position (position); 241 wrong_type_argument (Qinteger_or_marker_p, position);
242 if (pos < BEGV)
243 SET_PT_BOTH (BEGV, BEGV_BYTE);
244 else if (pos > ZV)
245 SET_PT_BOTH (ZV, ZV_BYTE);
246 else
247 SET_PT_BOTH (pos, marker_byte_position (position));
248
249 return position;
250 }
251
252 CHECK_NUMBER_COERCE_MARKER (position);
253
254 pos = clip_to_bounds (BEGV, XINT (position), ZV);
255 SET_PT (pos);
256 return position; 242 return position;
257} 243}
258 244
@@ -1420,7 +1406,7 @@ least significant 16 bits. USEC and PSEC are the microsecond and
1420picosecond counts. */) 1406picosecond counts. */)
1421 (void) 1407 (void)
1422{ 1408{
1423 return make_lisp_time (current_emacs_time ()); 1409 return make_lisp_time (current_timespec ());
1424} 1410}
1425 1411
1426DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time, 1412DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
@@ -1450,7 +1436,7 @@ does the same thing as `current-time'. */)
1450 usecs -= 1000000; 1436 usecs -= 1000000;
1451 secs++; 1437 secs++;
1452 } 1438 }
1453 return make_lisp_time (make_emacs_time (secs, usecs * 1000)); 1439 return make_lisp_time (make_timespec (secs, usecs * 1000));
1454#else /* ! HAVE_GETRUSAGE */ 1440#else /* ! HAVE_GETRUSAGE */
1455#ifdef WINDOWSNT 1441#ifdef WINDOWSNT
1456 return w32_get_internal_run_time (); 1442 return w32_get_internal_run_time ();
@@ -1481,10 +1467,10 @@ make_time (time_t t)
1481 UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a 1467 UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a
1482 correspondingly negative picosecond count. */ 1468 correspondingly negative picosecond count. */
1483Lisp_Object 1469Lisp_Object
1484make_lisp_time (EMACS_TIME t) 1470make_lisp_time (struct timespec t)
1485{ 1471{
1486 int ns = EMACS_NSECS (t); 1472 int ns = t.tv_nsec;
1487 return make_time_tail (EMACS_SECS (t), list2i (ns / 1000, ns % 1000 * 1000)); 1473 return make_time_tail (t.tv_sec, list2i (ns / 1000, ns % 1000 * 1000));
1488} 1474}
1489 1475
1490/* Decode a Lisp list SPECIFIED_TIME that represents a time. 1476/* Decode a Lisp list SPECIFIED_TIME that represents a time.
@@ -1529,7 +1515,7 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
1529 list, generate the corresponding time value. 1515 list, generate the corresponding time value.
1530 1516
1531 If RESULT is not null, store into *RESULT the converted time; 1517 If RESULT is not null, store into *RESULT the converted time;
1532 this can fail if the converted time does not fit into EMACS_TIME. 1518 this can fail if the converted time does not fit into struct timespec.
1533 If *DRESULT is not null, store into *DRESULT the number of 1519 If *DRESULT is not null, store into *DRESULT the number of
1534 seconds since the start of the POSIX Epoch. 1520 seconds since the start of the POSIX Epoch.
1535 1521
@@ -1537,7 +1523,7 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
1537bool 1523bool
1538decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, 1524decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1539 Lisp_Object psec, 1525 Lisp_Object psec,
1540 EMACS_TIME *result, double *dresult) 1526 struct timespec *result, double *dresult)
1541{ 1527{
1542 EMACS_INT hi, lo, us, ps; 1528 EMACS_INT hi, lo, us, ps;
1543 if (! (INTEGERP (high) && INTEGERP (low) 1529 if (! (INTEGERP (high) && INTEGERP (low)
@@ -1565,7 +1551,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1565 /* Return the greatest representable time that is not greater 1551 /* Return the greatest representable time that is not greater
1566 than the requested time. */ 1552 than the requested time. */
1567 time_t sec = hi; 1553 time_t sec = hi;
1568 *result = make_emacs_time ((sec << 16) + lo, us * 1000 + ps / 1000); 1554 *result = make_timespec ((sec << 16) + lo, us * 1000 + ps / 1000);
1569 } 1555 }
1570 else 1556 else
1571 { 1557 {
@@ -1583,15 +1569,15 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1583/* Decode a Lisp list SPECIFIED_TIME that represents a time. 1569/* Decode a Lisp list SPECIFIED_TIME that represents a time.
1584 If SPECIFIED_TIME is nil, use the current time. 1570 If SPECIFIED_TIME is nil, use the current time.
1585 1571
1586 Round the time down to the nearest EMACS_TIME value. 1572 Round the time down to the nearest struct timespec value.
1587 Return seconds since the Epoch. 1573 Return seconds since the Epoch.
1588 Signal an error if unsuccessful. */ 1574 Signal an error if unsuccessful. */
1589EMACS_TIME 1575struct timespec
1590lisp_time_argument (Lisp_Object specified_time) 1576lisp_time_argument (Lisp_Object specified_time)
1591{ 1577{
1592 EMACS_TIME t; 1578 struct timespec t;
1593 if (NILP (specified_time)) 1579 if (NILP (specified_time))
1594 t = current_emacs_time (); 1580 t = current_timespec ();
1595 else 1581 else
1596 { 1582 {
1597 Lisp_Object high, low, usec, psec; 1583 Lisp_Object high, low, usec, psec;
@@ -1613,12 +1599,12 @@ lisp_seconds_argument (Lisp_Object specified_time)
1613 else 1599 else
1614 { 1600 {
1615 Lisp_Object high, low, usec, psec; 1601 Lisp_Object high, low, usec, psec;
1616 EMACS_TIME t; 1602 struct timespec t;
1617 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) 1603 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
1618 && decode_time_components (high, low, make_number (0), 1604 && decode_time_components (high, low, make_number (0),
1619 make_number (0), &t, 0))) 1605 make_number (0), &t, 0)))
1620 error ("Invalid time specification"); 1606 error ("Invalid time specification");
1621 return EMACS_SECS (t); 1607 return t.tv_sec;
1622 } 1608 }
1623} 1609}
1624 1610
@@ -1639,8 +1625,8 @@ or (if you need time as a string) `format-time-string'. */)
1639 double t; 1625 double t;
1640 if (NILP (specified_time)) 1626 if (NILP (specified_time))
1641 { 1627 {
1642 EMACS_TIME now = current_emacs_time (); 1628 struct timespec now = current_timespec ();
1643 t = EMACS_SECS (now) + EMACS_NSECS (now) / 1e9; 1629 t = now.tv_sec + now.tv_nsec / 1e9;
1644 } 1630 }
1645 else 1631 else
1646 { 1632 {
@@ -1758,7 +1744,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".
1758usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) 1744usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1759 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) 1745 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1760{ 1746{
1761 EMACS_TIME t = lisp_time_argument (timeval); 1747 struct timespec t = lisp_time_argument (timeval);
1762 struct tm tm; 1748 struct tm tm;
1763 1749
1764 CHECK_STRING (format_string); 1750 CHECK_STRING (format_string);
@@ -1770,20 +1756,20 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1770 1756
1771static Lisp_Object 1757static Lisp_Object
1772format_time_string (char const *format, ptrdiff_t formatlen, 1758format_time_string (char const *format, ptrdiff_t formatlen,
1773 EMACS_TIME t, bool ut, struct tm *tmp) 1759 struct timespec t, bool ut, struct tm *tmp)
1774{ 1760{
1775 char buffer[4000]; 1761 char buffer[4000];
1776 char *buf = buffer; 1762 char *buf = buffer;
1777 ptrdiff_t size = sizeof buffer; 1763 ptrdiff_t size = sizeof buffer;
1778 size_t len; 1764 size_t len;
1779 Lisp_Object bufstring; 1765 Lisp_Object bufstring;
1780 int ns = EMACS_NSECS (t); 1766 int ns = t.tv_nsec;
1781 struct tm *tm; 1767 struct tm *tm;
1782 USE_SAFE_ALLOCA; 1768 USE_SAFE_ALLOCA;
1783 1769
1784 while (1) 1770 while (1)
1785 { 1771 {
1786 time_t *taddr = emacs_secs_addr (&t); 1772 time_t *taddr = &t.tv_sec;
1787 block_input (); 1773 block_input ();
1788 1774
1789 synchronize_system_time_locale (); 1775 synchronize_system_time_locale ();
@@ -2068,17 +2054,17 @@ in this case, `current-time-zone' returns a list containing nil for
2068the data it can't find. */) 2054the data it can't find. */)
2069 (Lisp_Object specified_time) 2055 (Lisp_Object specified_time)
2070{ 2056{
2071 EMACS_TIME value; 2057 struct timespec value;
2072 int offset; 2058 int offset;
2073 struct tm *t; 2059 struct tm *t;
2074 struct tm localtm; 2060 struct tm localtm;
2075 Lisp_Object zone_offset, zone_name; 2061 Lisp_Object zone_offset, zone_name;
2076 2062
2077 zone_offset = Qnil; 2063 zone_offset = Qnil;
2078 value = make_emacs_time (lisp_seconds_argument (specified_time), 0); 2064 value = make_timespec (lisp_seconds_argument (specified_time), 0);
2079 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm); 2065 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &localtm);
2080 block_input (); 2066 block_input ();
2081 t = gmtime (emacs_secs_addr (&value)); 2067 t = gmtime (&value.tv_sec);
2082 if (t) 2068 if (t)
2083 offset = tm_diff (&localtm, t); 2069 offset = tm_diff (&localtm, t);
2084 unblock_input (); 2070 unblock_input ();
@@ -2330,6 +2316,10 @@ to multibyte for insertion (see `unibyte-char-to-multibyte').
2330If the current buffer is unibyte, multibyte strings are converted 2316If the current buffer is unibyte, multibyte strings are converted
2331to unibyte for insertion. 2317to unibyte for insertion.
2332 2318
2319If an overlay begins at the insertion point, the inserted text falls
2320outside the overlay; if a nonempty overlay ends at the insertion
2321point, the inserted text falls inside that overlay.
2322
2333usage: (insert-before-markers &rest ARGS) */) 2323usage: (insert-before-markers &rest ARGS) */)
2334 (ptrdiff_t nargs, Lisp_Object *args) 2324 (ptrdiff_t nargs, Lisp_Object *args)
2335{ 2325{
@@ -2928,7 +2918,7 @@ Both characters must have the same length of multi-byte form. */)
2928 else if (!changed) 2918 else if (!changed)
2929 { 2919 {
2930 changed = -1; 2920 changed = -1;
2931 modify_region_1 (pos, XINT (end), false); 2921 modify_text (pos, XINT (end));
2932 2922
2933 if (! NILP (noundo)) 2923 if (! NILP (noundo))
2934 { 2924 {
@@ -3104,7 +3094,7 @@ It returns the number of characters changed. */)
3104 pos = XINT (start); 3094 pos = XINT (start);
3105 pos_byte = CHAR_TO_BYTE (pos); 3095 pos_byte = CHAR_TO_BYTE (pos);
3106 end_pos = XINT (end); 3096 end_pos = XINT (end);
3107 modify_region_1 (pos, end_pos, false); 3097 modify_text (pos, end_pos);
3108 3098
3109 cnt = 0; 3099 cnt = 0;
3110 for (; pos < end_pos; ) 3100 for (; pos < end_pos; )
@@ -4615,7 +4605,7 @@ Transposing beyond buffer boundaries is an error. */)
4615 4605
4616 if (end1 == start2) /* adjacent regions */ 4606 if (end1 == start2) /* adjacent regions */
4617 { 4607 {
4618 modify_region_1 (start1, end2, false); 4608 modify_text (start1, end2);
4619 record_change (start1, len1 + len2); 4609 record_change (start1, len1 + len2);
4620 4610
4621 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4611 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4674,8 +4664,8 @@ Transposing beyond buffer boundaries is an error. */)
4674 { 4664 {
4675 USE_SAFE_ALLOCA; 4665 USE_SAFE_ALLOCA;
4676 4666
4677 modify_region_1 (start1, end1, false); 4667 modify_text (start1, end1);
4678 modify_region_1 (start2, end2, false); 4668 modify_text (start2, end2);
4679 record_change (start1, len1); 4669 record_change (start1, len1);
4680 record_change (start2, len2); 4670 record_change (start2, len2);
4681 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4671 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4708,7 +4698,7 @@ Transposing beyond buffer boundaries is an error. */)
4708 { 4698 {
4709 USE_SAFE_ALLOCA; 4699 USE_SAFE_ALLOCA;
4710 4700
4711 modify_region_1 (start1, end2, false); 4701 modify_text (start1, end2);
4712 record_change (start1, (end2 - start1)); 4702 record_change (start1, (end2 - start1));
4713 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4703 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
4714 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); 4704 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
@@ -4741,7 +4731,7 @@ Transposing beyond buffer boundaries is an error. */)
4741 USE_SAFE_ALLOCA; 4731 USE_SAFE_ALLOCA;
4742 4732
4743 record_change (start1, (end2 - start1)); 4733 record_change (start1, (end2 - start1));
4744 modify_region_1 (start1, end2, false); 4734 modify_text (start1, end2);
4745 4735
4746 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4736 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
4747 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); 4737 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
diff --git a/src/emacs.c b/src/emacs.c
index cf3a3c68932..05384145330 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -517,8 +517,7 @@ init_cmdargs (int argc, char **argv, int skip_args)
517 They are decoded in the function command-line after we know 517 They are decoded in the function command-line after we know
518 locale-coding-system. */ 518 locale-coding-system. */
519 Vcommand_line_args 519 Vcommand_line_args
520 = Fcons (make_unibyte_string (argv[i], strlen (argv[i])), 520 = Fcons (build_unibyte_string (argv[i]), Vcommand_line_args);
521 Vcommand_line_args);
522 } 521 }
523 522
524 unbind_to (count, Qnil); 523 unbind_to (count, Qnil);
@@ -697,7 +696,8 @@ main (int argc, char **argv)
697#endif 696#endif
698 697
699#ifdef G_SLICE_ALWAYS_MALLOC 698#ifdef G_SLICE_ALWAYS_MALLOC
700 /* This is used by the Cygwin build. */ 699 /* This is used by the Cygwin build. It's not needed starting with
700 cygwin-1.7.24, but it doesn't do any harm. */
701 xputenv ("G_SLICE=always-malloc"); 701 xputenv ("G_SLICE=always-malloc");
702#endif 702#endif
703 703
@@ -1407,6 +1407,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1407 syms_of_xml (); 1407 syms_of_xml ();
1408#endif 1408#endif
1409 1409
1410#ifdef HAVE_ZLIB
1411 syms_of_decompress ();
1412#endif
1413
1410 syms_of_menu (); 1414 syms_of_menu ();
1411 1415
1412#ifdef HAVE_NTGUI 1416#ifdef HAVE_NTGUI
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index 8b19d89f3a0..44f5cde1b0b 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -20,12 +20,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22 22
23#include "emacsgtkfixed.h"
24#include <stdio.h>
25
26#include "lisp.h" 23#include "lisp.h"
27#include "frame.h" 24#include "frame.h"
28#include "xterm.h" 25#include "xterm.h"
26#include "emacsgtkfixed.h"
29 27
30/* Silence a bogus diagnostic; see GNOME bug 683906. */ 28/* Silence a bogus diagnostic; see GNOME bug 683906. */
31#if 4 < __GNUC__ + (7 <= __GNUC_MINOR__) 29#if 4 < __GNUC__ + (7 <= __GNUC_MINOR__)
diff --git a/src/emacsgtkfixed.h b/src/emacsgtkfixed.h
index d987797a934..773ca26b143 100644
--- a/src/emacsgtkfixed.h
+++ b/src/emacsgtkfixed.h
@@ -25,8 +25,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 25
26G_BEGIN_DECLS 26G_BEGIN_DECLS
27 27
28struct frame;
29
30extern GtkWidget *emacs_fixed_new (struct frame *f); 28extern GtkWidget *emacs_fixed_new (struct frame *f);
31 29
32G_END_DECLS 30G_END_DECLS
diff --git a/src/eval.c b/src/eval.c
index 8ee259110f4..1ce14ae94a6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2149,6 +2149,8 @@ eval_sub (Lisp_Object form)
2149 if (SYMBOLP (fun) && !NILP (fun) 2149 if (SYMBOLP (fun) && !NILP (fun)
2150 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2150 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun)))
2151 fun = indirect_function (fun); 2151 fun = indirect_function (fun);
2152 else
2153 fun = Ffunction (Fcons (fun, Qnil));
2152 2154
2153 if (SUBRP (fun)) 2155 if (SUBRP (fun))
2154 { 2156 {
@@ -3151,20 +3153,17 @@ let_shadows_global_binding_p (Lisp_Object symbol)
3151 return 0; 3153 return 0;
3152} 3154}
3153 3155
3154/* `specpdl_ptr->symbol' is a field which describes which variable is 3156/* `specpdl_ptr' describes which variable is
3155 let-bound, so it can be properly undone when we unbind_to. 3157 let-bound, so it can be properly undone when we unbind_to.
3156 It can have the following two shapes: 3158 It can be either a plain SPECPDL_LET or a SPECPDL_LET_LOCAL/DEFAULT.
3157 - SYMBOL : if it's a plain symbol, it means that we have let-bound 3159 - SYMBOL is the variable being bound. Note that it should not be
3158 a symbol that is not buffer-local (at least at the time
3159 the let binding started). Note also that it should not be
3160 aliased (i.e. when let-binding V1 that's aliased to V2, we want 3160 aliased (i.e. when let-binding V1 that's aliased to V2, we want
3161 to record V2 here). 3161 to record V2 here).
3162 - (SYMBOL WHERE . BUFFER) : this means that it is a let-binding for 3162 - WHERE tells us in which buffer the binding took place.
3163 variable SYMBOL which can be buffer-local. WHERE tells us 3163 This is used for SPECPDL_LET_LOCAL bindings (i.e. bindings to a
3164 which buffer is affected (or nil if the let-binding affects the 3164 buffer-local variable) as well as for SPECPDL_LET_DEFAULT bindings,
3165 global value of the variable) and BUFFER tells us which buffer was 3165 i.e. bindings to the default value of a variable which can be
3166 current (i.e. if WHERE is non-nil, then BUFFER==WHERE, otherwise 3166 buffer-local. */
3167 BUFFER did not yet have a buffer-local value). */
3168 3167
3169void 3168void
3170specbind (Lisp_Object symbol, Lisp_Object value) 3169specbind (Lisp_Object symbol, Lisp_Object value)
@@ -3302,6 +3301,16 @@ clear_unwind_protect (ptrdiff_t count)
3302 previous value without invoking it. */ 3301 previous value without invoking it. */
3303 3302
3304void 3303void
3304set_unwind_protect (ptrdiff_t count, void (*func) (Lisp_Object),
3305 Lisp_Object arg)
3306{
3307 union specbinding *p = specpdl + count;
3308 p->unwind.kind = SPECPDL_UNWIND;
3309 p->unwind.func = func;
3310 p->unwind.arg = arg;
3311}
3312
3313void
3305set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg) 3314set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg)
3306{ 3315{
3307 union specbinding *p = specpdl + count; 3316 union specbinding *p = specpdl + count;
diff --git a/src/fileio.c b/src/fileio.c
index 59e84053773..0e6113f349d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -233,7 +233,7 @@ void
233restore_point_unwind (Lisp_Object location) 233restore_point_unwind (Lisp_Object location)
234{ 234{
235 Fgoto_char (location); 235 Fgoto_char (location);
236 Fset_marker (location, Qnil, Qnil); 236 unchain_marker (XMARKER (location));
237} 237}
238 238
239 239
@@ -366,8 +366,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
366 } 366 }
367 367
368#ifdef DOS_NT 368#ifdef DOS_NT
369 beg = alloca (SBYTES (filename) + 1); 369 beg = xlispstrdupa (filename);
370 memcpy (beg, SSDATA (filename), SBYTES (filename) + 1);
371#else 370#else
372 beg = SSDATA (filename); 371 beg = SSDATA (filename);
373#endif 372#endif
@@ -505,6 +504,10 @@ get a current directory to run processes in. */)
505 return Ffile_name_directory (filename); 504 return Ffile_name_directory (filename);
506} 505}
507 506
507/* Maximum number of bytes that DST will be longer than SRC
508 in file_name_as_directory. This occurs when SRCLEN == 0. */
509enum { file_name_as_directory_slop = 2 };
510
508/* Convert from file name SRC of length SRCLEN to directory name in 511/* Convert from file name SRC of length SRCLEN to directory name in
509 DST. MULTIBYTE non-zero means the file name in SRC is a multibyte 512 DST. MULTIBYTE non-zero means the file name in SRC is a multibyte
510 string. On UNIX, just make sure there is a terminating /. Return 513 string. On UNIX, just make sure there is a terminating /. Return
@@ -522,14 +525,10 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen,
522 return 2; 525 return 2;
523 } 526 }
524 527
525 strcpy (dst, src); 528 memcpy (dst, src, srclen);
526
527 if (!IS_DIRECTORY_SEP (dst[srclen - 1])) 529 if (!IS_DIRECTORY_SEP (dst[srclen - 1]))
528 { 530 dst[srclen++] = DIRECTORY_SEP;
529 dst[srclen] = DIRECTORY_SEP; 531 dst[srclen] = 0;
530 dst[srclen + 1] = '\0';
531 srclen++;
532 }
533#ifdef DOS_NT 532#ifdef DOS_NT
534 dostounix_filename (dst, multibyte); 533 dostounix_filename (dst, multibyte);
535#endif 534#endif
@@ -548,7 +547,8 @@ For a Unix-syntax file name, just appends a slash. */)
548{ 547{
549 char *buf; 548 char *buf;
550 ptrdiff_t length; 549 ptrdiff_t length;
551 Lisp_Object handler; 550 Lisp_Object handler, val;
551 USE_SAFE_ALLOCA;
552 552
553 CHECK_STRING (file); 553 CHECK_STRING (file);
554 if (NILP (file)) 554 if (NILP (file))
@@ -570,10 +570,12 @@ For a Unix-syntax file name, just appends a slash. */)
570 if (!NILP (Vw32_downcase_file_names)) 570 if (!NILP (Vw32_downcase_file_names))
571 file = Fdowncase (file); 571 file = Fdowncase (file);
572#endif 572#endif
573 buf = alloca (SBYTES (file) + 10); 573 buf = SAFE_ALLOCA (SBYTES (file) + file_name_as_directory_slop + 1);
574 length = file_name_as_directory (buf, SSDATA (file), SBYTES (file), 574 length = file_name_as_directory (buf, SSDATA (file), SBYTES (file),
575 STRING_MULTIBYTE (file)); 575 STRING_MULTIBYTE (file));
576 return make_specified_string (buf, -1, length, STRING_MULTIBYTE (file)); 576 val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (file));
577 SAFE_FREE ();
578 return val;
577} 579}
578 580
579/* Convert from directory name SRC of length SRCLEN to file name in 581/* Convert from directory name SRC of length SRCLEN to file name in
@@ -585,18 +587,17 @@ static ptrdiff_t
585directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) 587directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte)
586{ 588{
587 /* Process as Unix format: just remove any final slash. 589 /* Process as Unix format: just remove any final slash.
588 But leave "/" unchanged; do not change it to "". */ 590 But leave "/" and "//" unchanged. */
589 strcpy (dst, src); 591 while (srclen > 1
590 if (srclen > 1
591 && IS_DIRECTORY_SEP (dst[srclen - 1])
592#ifdef DOS_NT 592#ifdef DOS_NT
593 && !IS_ANY_SEP (dst[srclen - 2]) 593 && !IS_ANY_SEP (src[srclen - 2])
594#endif 594#endif
595 ) 595 && IS_DIRECTORY_SEP (src[srclen - 1])
596 { 596 && ! (srclen == 2 && IS_DIRECTORY_SEP (src[0])))
597 dst[srclen - 1] = 0; 597 srclen--;
598 srclen--; 598
599 } 599 memcpy (dst, src, srclen);
600 dst[srclen] = 0;
600#ifdef DOS_NT 601#ifdef DOS_NT
601 dostounix_filename (dst, multibyte); 602 dostounix_filename (dst, multibyte);
602#endif 603#endif
@@ -614,7 +615,8 @@ In Unix-syntax, this function just removes the final slash. */)
614{ 615{
615 char *buf; 616 char *buf;
616 ptrdiff_t length; 617 ptrdiff_t length;
617 Lisp_Object handler; 618 Lisp_Object handler, val;
619 USE_SAFE_ALLOCA;
618 620
619 CHECK_STRING (directory); 621 CHECK_STRING (directory);
620 622
@@ -637,10 +639,12 @@ In Unix-syntax, this function just removes the final slash. */)
637 if (!NILP (Vw32_downcase_file_names)) 639 if (!NILP (Vw32_downcase_file_names))
638 directory = Fdowncase (directory); 640 directory = Fdowncase (directory);
639#endif 641#endif
640 buf = alloca (SBYTES (directory) + 20); 642 buf = SAFE_ALLOCA (SBYTES (directory) + 1);
641 length = directory_file_name (buf, SSDATA (directory), SBYTES (directory), 643 length = directory_file_name (buf, SSDATA (directory), SBYTES (directory),
642 STRING_MULTIBYTE (directory)); 644 STRING_MULTIBYTE (directory));
643 return make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory)); 645 val = make_specified_string (buf, -1, length, STRING_MULTIBYTE (directory));
646 SAFE_FREE ();
647 return val;
644} 648}
645 649
646static const char make_temp_name_tbl[64] = 650static const char make_temp_name_tbl[64] =
@@ -838,6 +842,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
838 Lisp_Object handler, result, handled_name; 842 Lisp_Object handler, result, handled_name;
839 bool multibyte; 843 bool multibyte;
840 Lisp_Object hdir; 844 Lisp_Object hdir;
845 USE_SAFE_ALLOCA;
841 846
842 CHECK_STRING (name); 847 CHECK_STRING (name);
843 848
@@ -944,8 +949,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
944#endif 949#endif
945 950
946 /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ 951 /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */
947 nm = alloca (SBYTES (name) + 1); 952 nm = xlispstrdupa (name);
948 memcpy (nm, SSDATA (name), SBYTES (name) + 1);
949 953
950#ifdef DOS_NT 954#ifdef DOS_NT
951 /* Note if special escape prefix is present, but remove for now. */ 955 /* Note if special escape prefix is present, but remove for now. */
@@ -1013,11 +1017,11 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1013 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3]) 1017 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
1014 || p[3] == 0)))) 1018 || p[3] == 0))))
1015 lose = 1; 1019 lose = 1;
1016 /* We want to replace multiple `/' in a row with a single 1020 /* Replace multiple slashes with a single one, except
1017 slash. */ 1021 leave leading "//" alone. */
1018 else if (p > nm 1022 else if (IS_DIRECTORY_SEP (p[0])
1019 && IS_DIRECTORY_SEP (p[0]) 1023 && IS_DIRECTORY_SEP (p[1])
1020 && IS_DIRECTORY_SEP (p[1])) 1024 && (p != nm || IS_DIRECTORY_SEP (p[2])))
1021 lose = 1; 1025 lose = 1;
1022 p++; 1026 p++;
1023 } 1027 }
@@ -1100,10 +1104,11 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1100 else /* ~user/filename */ 1104 else /* ~user/filename */
1101 { 1105 {
1102 char *o, *p; 1106 char *o, *p;
1103 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++); 1107 for (p = nm; *p && !IS_DIRECTORY_SEP (*p); p++)
1104 o = alloca (p - nm + 1); 1108 continue;
1109 o = SAFE_ALLOCA (p - nm + 1);
1105 memcpy (o, nm, p - nm); 1110 memcpy (o, nm, p - nm);
1106 o [p - nm] = 0; 1111 o[p - nm] = 0;
1107 1112
1108 block_input (); 1113 block_input ();
1109 pw = getpwnam (o + 1); 1114 pw = getpwnam (o + 1);
@@ -1219,7 +1224,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1219 if (!IS_DIRECTORY_SEP (nm[0])) 1224 if (!IS_DIRECTORY_SEP (nm[0]))
1220 { 1225 {
1221 ptrdiff_t newlen = strlen (newdir); 1226 ptrdiff_t newlen = strlen (newdir);
1222 char *tmp = alloca (newlen + strlen (nm) + 2); 1227 char *tmp = alloca (newlen + file_name_as_directory_slop
1228 + strlen (nm) + 1);
1223 file_name_as_directory (tmp, newdir, newlen, multibyte); 1229 file_name_as_directory (tmp, newdir, newlen, multibyte);
1224 strcat (tmp, nm); 1230 strcat (tmp, nm);
1225 nm = tmp; 1231 nm = tmp;
@@ -1273,31 +1279,18 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1273 1279
1274 if (newdir) 1280 if (newdir)
1275 { 1281 {
1276 /* Get rid of any slash at the end of newdir, unless newdir is 1282 /* Ignore any slash at the end of newdir, unless newdir is
1277 just / or // (an incomplete UNC name). */ 1283 just "/" or "//". */
1278 length = strlen (newdir); 1284 length = strlen (newdir);
1279 tlen = length + 1; 1285 while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
1280 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) 1286 && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0])))
1281#ifdef WINDOWSNT 1287 length--;
1282 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1283#endif
1284 )
1285 {
1286 char *temp = alloca (length);
1287 memcpy (temp, newdir, length - 1);
1288 temp[length - 1] = 0;
1289 length--;
1290 newdir = temp;
1291 }
1292 } 1288 }
1293 else 1289 else
1294 { 1290 length = 0;
1295 length = 0;
1296 tlen = 0;
1297 }
1298 1291
1299 /* Now concatenate the directory and name to new space in the stack frame. */ 1292 /* Now concatenate the directory and name to new space in the stack frame. */
1300 tlen += strlen (nm) + 1; 1293 tlen = length + file_name_as_directory_slop + strlen (nm) + 1;
1301#ifdef DOS_NT 1294#ifdef DOS_NT
1302 /* Reserve space for drive specifier and escape prefix, since either 1295 /* Reserve space for drive specifier and escape prefix, since either
1303 or both may need to be inserted. (The Microsoft x86 compiler 1296 or both may need to be inserted. (The Microsoft x86 compiler
@@ -1305,7 +1298,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1305 target = alloca (tlen + 4); 1298 target = alloca (tlen + 4);
1306 target += 4; 1299 target += 4;
1307#else /* not DOS_NT */ 1300#else /* not DOS_NT */
1308 target = alloca (tlen); 1301 target = SAFE_ALLOCA (tlen);
1309#endif /* not DOS_NT */ 1302#endif /* not DOS_NT */
1310 *target = 0; 1303 *target = 0;
1311 1304
@@ -1322,7 +1315,10 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1322 if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0]) 1315 if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0])
1323 && newdir[1] == '\0')) 1316 && newdir[1] == '\0'))
1324#endif 1317#endif
1325 strcpy (target, newdir); 1318 {
1319 memcpy (target, newdir, length);
1320 target[length] = 0;
1321 }
1326 } 1322 }
1327 else 1323 else
1328 file_name_as_directory (target, newdir, length, multibyte); 1324 file_name_as_directory (target, newdir, length, multibyte);
@@ -1382,8 +1378,9 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1382 ++o; 1378 ++o;
1383 p += 3; 1379 p += 3;
1384 } 1380 }
1385 else if (p > target && IS_DIRECTORY_SEP (p[1])) 1381 else if (IS_DIRECTORY_SEP (p[1])
1386 /* Collapse multiple `/' in a row. */ 1382 && (p != target || IS_DIRECTORY_SEP (p[2])))
1383 /* Collapse multiple "/", except leave leading "//" alone. */
1387 p++; 1384 p++;
1388 else 1385 else
1389 { 1386 {
@@ -1431,11 +1428,12 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1431 { 1428 {
1432 handled_name = call3 (handler, Qexpand_file_name, 1429 handled_name = call3 (handler, Qexpand_file_name,
1433 result, default_directory); 1430 result, default_directory);
1434 if (STRINGP (handled_name)) 1431 if (! STRINGP (handled_name))
1435 return handled_name; 1432 error ("Invalid handler in `file-name-handler-alist'");
1436 error ("Invalid handler in `file-name-handler-alist'"); 1433 result = handled_name;
1437 } 1434 }
1438 1435
1436 SAFE_FREE ();
1439 return result; 1437 return result;
1440} 1438}
1441 1439
@@ -1693,8 +1691,7 @@ those `/' is discarded. */)
1693 /* Always work on a copy of the string, in case GC happens during 1691 /* Always work on a copy of the string, in case GC happens during
1694 decode of environment variables, causing the original Lisp_String 1692 decode of environment variables, causing the original Lisp_String
1695 data to be relocated. */ 1693 data to be relocated. */
1696 nm = alloca (SBYTES (filename) + 1); 1694 nm = xlispstrdupa (filename);
1697 memcpy (nm, SDATA (filename), SBYTES (filename) + 1);
1698 1695
1699#ifdef DOS_NT 1696#ifdef DOS_NT
1700 dostounix_filename (nm, multibyte); 1697 dostounix_filename (nm, multibyte);
@@ -2048,7 +2045,7 @@ entries (depending on how Emacs was built). */)
2048 /* CopyFile retains the timestamp by default. */ 2045 /* CopyFile retains the timestamp by default. */
2049 else if (NILP (keep_time)) 2046 else if (NILP (keep_time))
2050 { 2047 {
2051 EMACS_TIME now; 2048 struct timespec now;
2052 DWORD attributes; 2049 DWORD attributes;
2053 char * filename; 2050 char * filename;
2054 2051
@@ -2057,7 +2054,7 @@ entries (depending on how Emacs was built). */)
2057 /* Ensure file is writable while its modified time is set. */ 2054 /* Ensure file is writable while its modified time is set. */
2058 attributes = GetFileAttributes (filename); 2055 attributes = GetFileAttributes (filename);
2059 SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY); 2056 SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY);
2060 now = current_emacs_time (); 2057 now = current_timespec ();
2061 if (set_file_times (-1, filename, now, now)) 2058 if (set_file_times (-1, filename, now, now))
2062 { 2059 {
2063 /* Restore original attributes. */ 2060 /* Restore original attributes. */
@@ -2181,8 +2178,8 @@ entries (depending on how Emacs was built). */)
2181 2178
2182 if (!NILP (keep_time)) 2179 if (!NILP (keep_time))
2183 { 2180 {
2184 EMACS_TIME atime = get_stat_atime (&st); 2181 struct timespec atime = get_stat_atime (&st);
2185 EMACS_TIME mtime = get_stat_mtime (&st); 2182 struct timespec mtime = get_stat_mtime (&st);
2186 if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime)) 2183 if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime))
2187 xsignal2 (Qfile_date_error, 2184 xsignal2 (Qfile_date_error,
2188 build_string ("Cannot set file date"), newname); 2185 build_string ("Cannot set file date"), newname);
@@ -3289,7 +3286,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
3289{ 3286{
3290 Lisp_Object absname, encoded_absname; 3287 Lisp_Object absname, encoded_absname;
3291 Lisp_Object handler; 3288 Lisp_Object handler;
3292 EMACS_TIME t = lisp_time_argument (timestamp); 3289 struct timespec t = lisp_time_argument (timestamp);
3293 3290
3294 absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)); 3291 absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
3295 3292
@@ -3366,7 +3363,7 @@ otherwise, if FILE2 does not exist, the answer is t. */)
3366 if (stat (SSDATA (absname2), &st2) < 0) 3363 if (stat (SSDATA (absname2), &st2) < 0)
3367 return Qt; 3364 return Qt;
3368 3365
3369 return (EMACS_TIME_LT (get_stat_mtime (&st2), get_stat_mtime (&st1)) 3366 return (timespec_cmp (get_stat_mtime (&st2), get_stat_mtime (&st1)) < 0
3370 ? Qt : Qnil); 3367 ? Qt : Qnil);
3371} 3368}
3372 3369
@@ -3466,13 +3463,13 @@ file_offset (Lisp_Object val)
3466} 3463}
3467 3464
3468/* Return a special time value indicating the error number ERRNUM. */ 3465/* Return a special time value indicating the error number ERRNUM. */
3469static EMACS_TIME 3466static struct timespec
3470time_error_value (int errnum) 3467time_error_value (int errnum)
3471{ 3468{
3472 int ns = (errnum == ENOENT || errnum == EACCES || errnum == ENOTDIR 3469 int ns = (errnum == ENOENT || errnum == EACCES || errnum == ENOTDIR
3473 ? NONEXISTENT_MODTIME_NSECS 3470 ? NONEXISTENT_MODTIME_NSECS
3474 : UNKNOWN_MODTIME_NSECS); 3471 : UNKNOWN_MODTIME_NSECS);
3475 return make_emacs_time (0, ns); 3472 return make_timespec (0, ns);
3476} 3473}
3477 3474
3478DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, 3475DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
@@ -3504,7 +3501,7 @@ by calling `format-decode', which see. */)
3504 (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace) 3501 (Lisp_Object filename, Lisp_Object visit, Lisp_Object beg, Lisp_Object end, Lisp_Object replace)
3505{ 3502{
3506 struct stat st; 3503 struct stat st;
3507 EMACS_TIME mtime; 3504 struct timespec mtime;
3508 int fd; 3505 int fd;
3509 ptrdiff_t inserted = 0; 3506 ptrdiff_t inserted = 0;
3510 ptrdiff_t how_much; 3507 ptrdiff_t how_much;
@@ -4570,7 +4567,7 @@ by calling `format-decode', which see. */)
4570 } 4567 }
4571 4568
4572 if (!NILP (visit) 4569 if (!NILP (visit)
4573 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) 4570 && current_buffer->modtime.tv_nsec == NONEXISTENT_MODTIME_NSECS)
4574 { 4571 {
4575 /* If visiting nonexistent file, return nil. */ 4572 /* If visiting nonexistent file, return nil. */
4576 report_file_errno ("Opening input file", orig_filename, save_errno); 4573 report_file_errno ("Opening input file", orig_filename, save_errno);
@@ -4746,25 +4743,39 @@ This does code conversion according to the value of
4746 4743
4747This calls `write-region-annotate-functions' at the start, and 4744This calls `write-region-annotate-functions' at the start, and
4748`write-region-post-annotation-function' at the end. */) 4745`write-region-post-annotation-function' at the end. */)
4749 (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) 4746 (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append,
4747 Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew)
4748{
4749 return write_region (start, end, filename, append, visit, lockname, mustbenew,
4750 -1);
4751}
4752
4753/* Like Fwrite_region, except that if DESC is nonnegative, it is a file
4754 descriptor for FILENAME, so do not open or close FILENAME. */
4755
4756Lisp_Object
4757write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
4758 Lisp_Object append, Lisp_Object visit, Lisp_Object lockname,
4759 Lisp_Object mustbenew, int desc)
4750{ 4760{
4751 int desc;
4752 int open_flags; 4761 int open_flags;
4753 int mode; 4762 int mode;
4754 off_t offset IF_LINT (= 0); 4763 off_t offset IF_LINT (= 0);
4764 bool open_and_close_file = desc < 0;
4755 bool ok; 4765 bool ok;
4756 int save_errno = 0; 4766 int save_errno = 0;
4757 const char *fn; 4767 const char *fn;
4758 struct stat st; 4768 struct stat st;
4759 EMACS_TIME modtime; 4769 struct timespec modtime;
4760 ptrdiff_t count = SPECPDL_INDEX (); 4770 ptrdiff_t count = SPECPDL_INDEX ();
4761 ptrdiff_t count1; 4771 ptrdiff_t count1 IF_LINT (= 0);
4762 Lisp_Object handler; 4772 Lisp_Object handler;
4763 Lisp_Object visit_file; 4773 Lisp_Object visit_file;
4764 Lisp_Object annotations; 4774 Lisp_Object annotations;
4765 Lisp_Object encoded_filename; 4775 Lisp_Object encoded_filename;
4766 bool visiting = (EQ (visit, Qt) || STRINGP (visit)); 4776 bool visiting = (EQ (visit, Qt) || STRINGP (visit));
4767 bool quietly = !NILP (visit); 4777 bool quietly = !NILP (visit);
4778 bool file_locked = 0;
4768 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 4779 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4769 struct buffer *given_buffer; 4780 struct buffer *given_buffer;
4770 struct coding_system coding; 4781 struct coding_system coding;
@@ -4832,7 +4843,6 @@ This calls `write-region-annotate-functions' at the start, and
4832 record_unwind_protect (build_annotations_unwind, 4843 record_unwind_protect (build_annotations_unwind,
4833 Vwrite_region_annotation_buffers); 4844 Vwrite_region_annotation_buffers);
4834 Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ()); 4845 Vwrite_region_annotation_buffers = list1 (Fcurrent_buffer ());
4835 count1 = SPECPDL_INDEX ();
4836 4846
4837 given_buffer = current_buffer; 4847 given_buffer = current_buffer;
4838 4848
@@ -4871,8 +4881,11 @@ This calls `write-region-annotate-functions' at the start, and
4871 coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; 4881 coding.mode |= CODING_MODE_SELECTIVE_DISPLAY;
4872 4882
4873#ifdef CLASH_DETECTION 4883#ifdef CLASH_DETECTION
4874 if (!auto_saving) 4884 if (open_and_close_file && !auto_saving)
4875 lock_file (lockname); 4885 {
4886 lock_file (lockname);
4887 file_locked = 1;
4888 }
4876#endif /* CLASH_DETECTION */ 4889#endif /* CLASH_DETECTION */
4877 4890
4878 encoded_filename = ENCODE_FILE (filename); 4891 encoded_filename = ENCODE_FILE (filename);
@@ -4889,19 +4902,23 @@ This calls `write-region-annotate-functions' at the start, and
4889 mode = auto_saving ? auto_save_mode_bits : 0666; 4902 mode = auto_saving ? auto_save_mode_bits : 0666;
4890#endif 4903#endif
4891 4904
4892 desc = emacs_open (fn, open_flags, mode); 4905 if (open_and_close_file)
4893
4894 if (desc < 0)
4895 { 4906 {
4896 int open_errno = errno; 4907 desc = emacs_open (fn, open_flags, mode);
4908 if (desc < 0)
4909 {
4910 int open_errno = errno;
4897#ifdef CLASH_DETECTION 4911#ifdef CLASH_DETECTION
4898 if (!auto_saving) unlock_file (lockname); 4912 if (file_locked)
4913 unlock_file (lockname);
4899#endif /* CLASH_DETECTION */ 4914#endif /* CLASH_DETECTION */
4900 UNGCPRO; 4915 UNGCPRO;
4901 report_file_errno ("Opening output file", filename, open_errno); 4916 report_file_errno ("Opening output file", filename, open_errno);
4902 } 4917 }
4903 4918
4904 record_unwind_protect_int (close_file_unwind, desc); 4919 count1 = SPECPDL_INDEX ();
4920 record_unwind_protect_int (close_file_unwind, desc);
4921 }
4905 4922
4906 if (NUMBERP (append)) 4923 if (NUMBERP (append))
4907 { 4924 {
@@ -4910,7 +4927,8 @@ This calls `write-region-annotate-functions' at the start, and
4910 { 4927 {
4911 int lseek_errno = errno; 4928 int lseek_errno = errno;
4912#ifdef CLASH_DETECTION 4929#ifdef CLASH_DETECTION
4913 if (!auto_saving) unlock_file (lockname); 4930 if (file_locked)
4931 unlock_file (lockname);
4914#endif /* CLASH_DETECTION */ 4932#endif /* CLASH_DETECTION */
4915 UNGCPRO; 4933 UNGCPRO;
4916 report_file_errno ("Lseek error", filename, lseek_errno); 4934 report_file_errno ("Lseek error", filename, lseek_errno);
@@ -4945,9 +4963,9 @@ This calls `write-region-annotate-functions' at the start, and
4945 4963
4946 immediate_quit = 0; 4964 immediate_quit = 0;
4947 4965
4948 /* fsync is not crucial for auto-save files, since they might lose 4966 /* fsync is not crucial for temporary files. Nor for auto-save
4949 some work anyway. */ 4967 files, since they might lose some work anyway. */
4950 if (!auto_saving && !write_region_inhibit_fsync) 4968 if (open_and_close_file && !auto_saving && !write_region_inhibit_fsync)
4951 { 4969 {
4952 /* Transfer data and metadata to disk, retrying if interrupted. 4970 /* Transfer data and metadata to disk, retrying if interrupted.
4953 fsync can report a write failure here, e.g., due to disk full 4971 fsync can report a write failure here, e.g., due to disk full
@@ -4962,7 +4980,7 @@ This calls `write-region-annotate-functions' at the start, and
4962 } 4980 }
4963 } 4981 }
4964 4982
4965 modtime = invalid_emacs_time (); 4983 modtime = invalid_timespec ();
4966 if (visiting) 4984 if (visiting)
4967 { 4985 {
4968 if (fstat (desc, &st) == 0) 4986 if (fstat (desc, &st) == 0)
@@ -4971,12 +4989,15 @@ This calls `write-region-annotate-functions' at the start, and
4971 ok = 0, save_errno = errno; 4989 ok = 0, save_errno = errno;
4972 } 4990 }
4973 4991
4974 /* NFS can report a write failure now. */ 4992 if (open_and_close_file)
4975 if (emacs_close (desc) < 0) 4993 {
4976 ok = 0, save_errno = errno; 4994 /* NFS can report a write failure now. */
4995 if (emacs_close (desc) < 0)
4996 ok = 0, save_errno = errno;
4977 4997
4978 /* Discard the unwind protect for close_file_unwind. */ 4998 /* Discard the unwind protect for close_file_unwind. */
4979 specpdl_ptr = specpdl + count1; 4999 specpdl_ptr = specpdl + count1;
5000 }
4980 5001
4981 /* Some file systems have a bug where st_mtime is not updated 5002 /* Some file systems have a bug where st_mtime is not updated
4982 properly after a write. For example, CIFS might not see the 5003 properly after a write. For example, CIFS might not see the
@@ -4993,7 +5014,7 @@ This calls `write-region-annotate-functions' at the start, and
4993 unlikely and a similar race between the last write and the fstat 5014 unlikely and a similar race between the last write and the fstat
4994 above cannot possibly be closed anyway. */ 5015 above cannot possibly be closed anyway. */
4995 5016
4996 if (EMACS_TIME_VALID_P (modtime) 5017 if (timespec_valid_p (modtime)
4997 && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system)) 5018 && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system))
4998 { 5019 {
4999 int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0); 5020 int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0);
@@ -5015,11 +5036,11 @@ This calls `write-region-annotate-functions' at the start, and
5015 bool use_heuristic 5036 bool use_heuristic
5016 = ((open_flags & (O_EXCL | O_TRUNC)) != 0 5037 = ((open_flags & (O_EXCL | O_TRUNC)) != 0
5017 && st.st_size != 0 5038 && st.st_size != 0
5018 && EMACS_NSECS (modtime) % 100 != 0); 5039 && modtime.tv_nsec % 100 != 0);
5019 5040
5020 EMACS_TIME modtime1 = get_stat_mtime (&st1); 5041 struct timespec modtime1 = get_stat_mtime (&st1);
5021 if (use_heuristic 5042 if (use_heuristic
5022 && EMACS_TIME_EQ (modtime, modtime1) 5043 && timespec_cmp (modtime, modtime1) == 0
5023 && st.st_size == st1.st_size) 5044 && st.st_size == st1.st_size)
5024 { 5045 {
5025 timestamp_file_system = st.st_dev; 5046 timestamp_file_system = st.st_dev;
@@ -5052,14 +5073,14 @@ This calls `write-region-annotate-functions' at the start, and
5052 unbind_to (count, Qnil); 5073 unbind_to (count, Qnil);
5053 5074
5054#ifdef CLASH_DETECTION 5075#ifdef CLASH_DETECTION
5055 if (!auto_saving) 5076 if (file_locked)
5056 unlock_file (lockname); 5077 unlock_file (lockname);
5057#endif /* CLASH_DETECTION */ 5078#endif /* CLASH_DETECTION */
5058 5079
5059 /* Do this before reporting IO error 5080 /* Do this before reporting IO error
5060 to avoid a "file has changed on disk" warning on 5081 to avoid a "file has changed on disk" warning on
5061 next attempt to save. */ 5082 next attempt to save. */
5062 if (EMACS_TIME_VALID_P (modtime)) 5083 if (timespec_valid_p (modtime))
5063 { 5084 {
5064 current_buffer->modtime = modtime; 5085 current_buffer->modtime = modtime;
5065 current_buffer->modtime_size = st.st_size; 5086 current_buffer->modtime_size = st.st_size;
@@ -5334,7 +5355,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5334 struct stat st; 5355 struct stat st;
5335 Lisp_Object handler; 5356 Lisp_Object handler;
5336 Lisp_Object filename; 5357 Lisp_Object filename;
5337 EMACS_TIME mtime; 5358 struct timespec mtime;
5338 5359
5339 if (NILP (buf)) 5360 if (NILP (buf))
5340 b = current_buffer; 5361 b = current_buffer;
@@ -5345,7 +5366,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5345 } 5366 }
5346 5367
5347 if (!STRINGP (BVAR (b, filename))) return Qt; 5368 if (!STRINGP (BVAR (b, filename))) return Qt;
5348 if (EMACS_NSECS (b->modtime) == UNKNOWN_MODTIME_NSECS) return Qt; 5369 if (b->modtime.tv_nsec == UNKNOWN_MODTIME_NSECS) return Qt;
5349 5370
5350 /* If the file name has special constructs in it, 5371 /* If the file name has special constructs in it,
5351 call the corresponding file handler. */ 5372 call the corresponding file handler. */
@@ -5359,7 +5380,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5359 mtime = (stat (SSDATA (filename), &st) == 0 5380 mtime = (stat (SSDATA (filename), &st) == 0
5360 ? get_stat_mtime (&st) 5381 ? get_stat_mtime (&st)
5361 : time_error_value (errno)); 5382 : time_error_value (errno));
5362 if (EMACS_TIME_EQ (mtime, b->modtime) 5383 if (timespec_cmp (mtime, b->modtime) == 0
5363 && (b->modtime_size < 0 5384 && (b->modtime_size < 0
5364 || st.st_size == b->modtime_size)) 5385 || st.st_size == b->modtime_size))
5365 return Qt; 5386 return Qt;
@@ -5376,7 +5397,7 @@ doesn't exist, return -1.
5376See Info node `(elisp)Modification Time' for more details. */) 5397See Info node `(elisp)Modification Time' for more details. */)
5377 (void) 5398 (void)
5378{ 5399{
5379 int ns = EMACS_NSECS (current_buffer->modtime); 5400 int ns = current_buffer->modtime.tv_nsec;
5380 if (ns < 0) 5401 if (ns < 0)
5381 return make_number (UNKNOWN_MODTIME_NSECS - ns); 5402 return make_number (UNKNOWN_MODTIME_NSECS - ns);
5382 return make_lisp_time (current_buffer->modtime); 5403 return make_lisp_time (current_buffer->modtime);
@@ -5395,11 +5416,11 @@ An argument specifies the modification time value to use
5395{ 5416{
5396 if (!NILP (time_flag)) 5417 if (!NILP (time_flag))
5397 { 5418 {
5398 EMACS_TIME mtime; 5419 struct timespec mtime;
5399 if (INTEGERP (time_flag)) 5420 if (INTEGERP (time_flag))
5400 { 5421 {
5401 CHECK_RANGED_INTEGER (time_flag, -1, 0); 5422 CHECK_RANGED_INTEGER (time_flag, -1, 0);
5402 mtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS - XINT (time_flag)); 5423 mtime = make_timespec (0, UNKNOWN_MODTIME_NSECS - XINT (time_flag));
5403 } 5424 }
5404 else 5425 else
5405 mtime = lisp_time_argument (time_flag); 5426 mtime = lisp_time_argument (time_flag);
@@ -5618,9 +5639,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5618 couldn't handle some ange-ftp'd file. */ 5639 couldn't handle some ange-ftp'd file. */
5619 5640
5620 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++) 5641 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
5621 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 5642 FOR_EACH_LIVE_BUFFER (tail, buf)
5622 { 5643 {
5623 buf = XCDR (XCAR (tail));
5624 b = XBUFFER (buf); 5644 b = XBUFFER (buf);
5625 5645
5626 /* Record all the buffers that have auto save mode 5646 /* Record all the buffers that have auto save mode
@@ -5663,12 +5683,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5663 || NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name), 5683 || NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name),
5664 Qwrite_region)))) 5684 Qwrite_region))))
5665 { 5685 {
5666 EMACS_TIME before_time = current_emacs_time (); 5686 struct timespec before_time = current_timespec ();
5667 EMACS_TIME after_time; 5687 struct timespec after_time;
5668 5688
5669 /* If we had a failure, don't try again for 20 minutes. */ 5689 /* If we had a failure, don't try again for 20 minutes. */
5670 if (b->auto_save_failure_time > 0 5690 if (b->auto_save_failure_time > 0
5671 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200) 5691 && before_time.tv_sec - b->auto_save_failure_time < 1200)
5672 continue; 5692 continue;
5673 5693
5674 set_buffer_internal (b); 5694 set_buffer_internal (b);
@@ -5701,12 +5721,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5701 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG); 5721 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
5702 set_buffer_internal (old); 5722 set_buffer_internal (old);
5703 5723
5704 after_time = current_emacs_time (); 5724 after_time = current_timespec ();
5705 5725
5706 /* If auto-save took more than 60 seconds, 5726 /* If auto-save took more than 60 seconds,
5707 assume it was an NFS failure that got a timeout. */ 5727 assume it was an NFS failure that got a timeout. */
5708 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60) 5728 if (after_time.tv_sec - before_time.tv_sec > 60)
5709 b->auto_save_failure_time = EMACS_SECS (after_time); 5729 b->auto_save_failure_time = after_time.tv_sec;
5710 } 5730 }
5711 } 5731 }
5712 5732
diff --git a/src/filelock.c b/src/filelock.c
index b9c991e4baf..df72eff5950 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -181,7 +181,7 @@ get_boot_time (void)
181 since utmp is typically much smaller than wtmp. 181 since utmp is typically much smaller than wtmp.
182 Passing a null pointer causes get_boot_time_1 182 Passing a null pointer causes get_boot_time_1
183 to inspect the default file, namely utmp. */ 183 to inspect the default file, namely utmp. */
184 get_boot_time_1 ((char *) 0, 0); 184 get_boot_time_1 (0, 0);
185 if (boot_time) 185 if (boot_time)
186 return boot_time; 186 return boot_time;
187 187
@@ -411,28 +411,14 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
411 memcpy (nonce, lfname, lfdirlen); 411 memcpy (nonce, lfname, lfdirlen);
412 strcpy (nonce + lfdirlen, nonce_base); 412 strcpy (nonce + lfdirlen, nonce_base);
413 413
414#if HAVE_MKOSTEMP
415 /* Prefer mkostemp to mkstemp, as it avoids a window where FD is
416 temporarily open without close-on-exec. */
417 fd = mkostemp (nonce, O_BINARY | O_CLOEXEC); 414 fd = mkostemp (nonce, O_BINARY | O_CLOEXEC);
418#elif HAVE_MKSTEMP
419 /* Prefer mkstemp to mktemp, as it avoids a race between
420 mktemp and emacs_open. */
421 fd = mkstemp (nonce);
422#else
423 mktemp (nonce);
424 fd = emacs_open (nonce, O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
425 S_IRUSR | S_IWUSR);
426#endif
427
428 if (fd < 0) 415 if (fd < 0)
429 err = errno; 416 err = errno;
430 else 417 else
431 { 418 {
432 ptrdiff_t lock_info_len; 419 ptrdiff_t lock_info_len;
433#if ! (HAVE_MKOSTEMP && O_CLOEXEC) 420 if (! O_CLOEXEC)
434 fcntl (fd, F_SETFD, FD_CLOEXEC); 421 fcntl (fd, F_SETFD, FD_CLOEXEC);
435#endif
436 lock_info_len = strlen (lock_info_str); 422 lock_info_len = strlen (lock_info_str);
437 err = 0; 423 err = 0;
438 /* Use 'write', not 'emacs_write', as garbage collection 424 /* Use 'write', not 'emacs_write', as garbage collection
@@ -759,16 +745,15 @@ unlock_file (Lisp_Object fn)
759void 745void
760unlock_all_files (void) 746unlock_all_files (void)
761{ 747{
762 register Lisp_Object tail; 748 register Lisp_Object tail, buf;
763 register struct buffer *b; 749 register struct buffer *b;
764 750
765 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 751 FOR_EACH_LIVE_BUFFER (tail, buf)
766 { 752 {
767 b = XBUFFER (XCDR (XCAR (tail))); 753 b = XBUFFER (buf);
768 if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) 754 if (STRINGP (BVAR (b, file_truename))
769 { 755 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
770 unlock_file (BVAR (b, file_truename)); 756 unlock_file (BVAR (b, file_truename));
771 }
772 } 757 }
773} 758}
774 759
diff --git a/src/font.c b/src/font.c
index 073487b540d..6a8262623dc 100644
--- a/src/font.c
+++ b/src/font.c
@@ -4226,36 +4226,38 @@ the consecutive wildcards are folded into one. */)
4226 return make_string (name, namelen); 4226 return make_string (name, namelen);
4227} 4227}
4228 4228
4229void
4230clear_font_cache (struct frame *f)
4231{
4232 struct font_driver_list *driver_list = f->font_driver_list;
4233
4234 for (; driver_list; driver_list = driver_list->next)
4235 if (driver_list->on)
4236 {
4237 Lisp_Object val, tmp, cache = driver_list->driver->get_cache (f);
4238
4239 val = XCDR (cache);
4240 while (! NILP (val)
4241 && ! EQ (XCAR (XCAR (val)), driver_list->driver->type))
4242 val = XCDR (val);
4243 eassert (! NILP (val));
4244 tmp = XCDR (XCAR (val));
4245 if (XINT (XCAR (tmp)) == 0)
4246 {
4247 font_clear_cache (f, XCAR (val), driver_list->driver);
4248 XSETCDR (cache, XCDR (val));
4249 }
4250 }
4251}
4252
4229DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0, 4253DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
4230 doc: /* Clear font cache. */) 4254 doc: /* Clear font cache of each frame. */)
4231 (void) 4255 (void)
4232{ 4256{
4233 Lisp_Object list, frame; 4257 Lisp_Object list, frame;
4234 4258
4235 FOR_EACH_FRAME (list, frame) 4259 FOR_EACH_FRAME (list, frame)
4236 { 4260 clear_font_cache (XFRAME (frame));
4237 struct frame *f = XFRAME (frame);
4238 struct font_driver_list *driver_list = f->font_driver_list;
4239
4240 for (; driver_list; driver_list = driver_list->next)
4241 if (driver_list->on)
4242 {
4243 Lisp_Object cache = driver_list->driver->get_cache (f);
4244 Lisp_Object val, tmp;
4245
4246 val = XCDR (cache);
4247 while (! NILP (val)
4248 && ! EQ (XCAR (XCAR (val)), driver_list->driver->type))
4249 val = XCDR (val);
4250 eassert (! NILP (val));
4251 tmp = XCDR (XCAR (val));
4252 if (XINT (XCAR (tmp)) == 0)
4253 {
4254 font_clear_cache (f, XCAR (val), driver_list->driver);
4255 XSETCDR (cache, XCDR (val));
4256 }
4257 }
4258 }
4259 4261
4260 return Qnil; 4262 return Qnil;
4261} 4263}
diff --git a/src/font.h b/src/font.h
index daeb320c1ab..3ee579aba2b 100644
--- a/src/font.h
+++ b/src/font.h
@@ -56,11 +56,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
56 56
57extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; 57extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
58 58
59
60struct font_driver;
61struct font;
62struct glyph_string;
63
64/* An enumerator for each font property. This is used as an index to 59/* An enumerator for each font property. This is used as an index to
65 the vector of FONT-SPEC and FONT-ENTITY. 60 the vector of FONT-SPEC and FONT-ENTITY.
66 61
@@ -487,8 +482,6 @@ struct font_bitmap
487 this value. */ 482 this value. */
488#define FONT_PIXEL_SIZE_QUANTUM 1 483#define FONT_PIXEL_SIZE_QUANTUM 1
489 484
490struct face;
491
492#define FONT_INVALID_CODE 0xFFFFFFFF 485#define FONT_INVALID_CODE 0xFFFFFFFF
493 486
494/* Font driver. Members specified as "optional" can be NULL. */ 487/* Font driver. Members specified as "optional" can be NULL. */
@@ -760,6 +753,7 @@ extern Lisp_Object font_load_for_lface (struct frame *f, Lisp_Object *lface,
760 Lisp_Object spec); 753 Lisp_Object spec);
761extern void font_prepare_for_face (struct frame *f, struct face *face); 754extern void font_prepare_for_face (struct frame *f, struct face *face);
762extern void font_done_for_face (struct frame *f, struct face *face); 755extern void font_done_for_face (struct frame *f, struct face *face);
756extern void clear_font_cache (struct frame *);
763 757
764extern Lisp_Object font_open_by_spec (struct frame *f, Lisp_Object spec); 758extern Lisp_Object font_open_by_spec (struct frame *f, Lisp_Object spec);
765extern Lisp_Object font_open_by_name (struct frame *f, Lisp_Object name); 759extern Lisp_Object font_open_by_name (struct frame *f, Lisp_Object name);
diff --git a/src/fontset.c b/src/fontset.c
index 0bf716bf1b2..a6277b050d5 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -944,6 +944,19 @@ face_for_char (struct frame *f, struct face *face, int c, int pos, Lisp_Object o
944 if (ASCII_CHAR_P (c) || face->fontset < 0) 944 if (ASCII_CHAR_P (c) || face->fontset < 0)
945 return face->ascii_face->id; 945 return face->ascii_face->id;
946 946
947#ifdef HAVE_NS
948 if (face->font)
949 {
950 /* Fonts often have characters in other scripts, like symbol, even if they
951 don't match script: symbol. So check if the character is present
952 in the current face first. Only enable for NS for now, but should
953 perhaps be general? */
954 Lisp_Object font_object;
955 XSETFONT (font_object, face->font);
956 if (font_has_char (f, font_object, c)) return face->id;
957 }
958#endif
959
947 eassert (fontset_id_valid_p (face->fontset)); 960 eassert (fontset_id_valid_p (face->fontset));
948 fontset = FONTSET_FROM_ID (face->fontset); 961 fontset = FONTSET_FROM_ID (face->fontset);
949 eassert (!BASE_FONTSET_P (fontset)); 962 eassert (!BASE_FONTSET_P (fontset));
diff --git a/src/fontset.h b/src/fontset.h
index fd16c7178f5..b8ef4789e71 100644
--- a/src/fontset.h
+++ b/src/fontset.h
@@ -26,8 +26,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#ifndef EMACS_FONTSET_H 26#ifndef EMACS_FONTSET_H
27#define EMACS_FONTSET_H 27#define EMACS_FONTSET_H
28 28
29struct face;
30
31extern void free_face_fontset (struct frame *, struct face *); 29extern void free_face_fontset (struct frame *, struct face *);
32extern int face_for_char (struct frame *, struct face *, int, 30extern int face_for_char (struct frame *, struct face *, int,
33 int, Lisp_Object); 31 int, Lisp_Object);
@@ -42,7 +40,6 @@ extern Lisp_Object Qlatin;
42extern Lisp_Object fontset_name (int); 40extern Lisp_Object fontset_name (int);
43extern Lisp_Object fontset_ascii (int); 41extern Lisp_Object fontset_ascii (int);
44 42
45struct font;
46extern int face_for_font (struct frame *, Lisp_Object, struct face *); 43extern int face_for_font (struct frame *, Lisp_Object, struct face *);
47 44
48#endif /* EMACS_FONTSET_H */ 45#endif /* EMACS_FONTSET_H */
diff --git a/src/frame.c b/src/frame.c
index 14fc15c4717..d11a6b8fee9 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -185,7 +185,6 @@ set_menu_bar_lines_1 (Lisp_Object window, int n)
185{ 185{
186 struct window *w = XWINDOW (window); 186 struct window *w = XWINDOW (window);
187 187
188 w->last_modified = 0;
189 w->top_line += n; 188 w->top_line += n;
190 w->total_lines -= n; 189 w->total_lines -= n;
191 190
@@ -693,24 +692,16 @@ affects all frames on the same terminal device. */)
693 ? FRAME_TTY (XFRAME (selected_frame))->name 692 ? FRAME_TTY (XFRAME (selected_frame))->name
694 : NULL)); 693 : NULL));
695 if (!NILP (tty)) 694 if (!NILP (tty))
696 { 695 name = xlispstrdupa (tty);
697 name = alloca (SBYTES (tty) + 1);
698 memcpy (name, SSDATA (tty), SBYTES (tty));
699 name[SBYTES (tty)] = 0;
700 }
701 696
702 tty_type = get_future_frame_param 697 tty_type = get_future_frame_param
703 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) 698 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
704 ? FRAME_TTY (XFRAME (selected_frame))->type 699 ? FRAME_TTY (XFRAME (selected_frame))->type
705 : NULL)); 700 : NULL));
706 if (!NILP (tty_type)) 701 if (!NILP (tty_type))
707 { 702 type = xlispstrdupa (tty_type);
708 type = alloca (SBYTES (tty_type) + 1);
709 memcpy (type, SSDATA (tty_type), SBYTES (tty_type));
710 type[SBYTES (tty_type)] = 0;
711 }
712 703
713 t = init_tty (name, type, 0); /* Errors are not fatal. */ 704 t = init_tty (name, type, 0); /* Errors are not fatal. */
714 } 705 }
715 706
716 f = make_terminal_frame (t); 707 f = make_terminal_frame (t);
@@ -726,7 +717,7 @@ affects all frames on the same terminal device. */)
726 XSETFRAME (frame, f); 717 XSETFRAME (frame, f);
727 718
728 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); 719 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
729 store_in_alist (&parms, Qtty, 720 store_in_alist (&parms, Qtty,
730 (t->display_info.tty->name 721 (t->display_info.tty->name
731 ? build_string (t->display_info.tty->name) 722 ? build_string (t->display_info.tty->name)
732 : Qnil)); 723 : Qnil));
@@ -1087,6 +1078,19 @@ Otherwise, include all frames. */)
1087 CHECK_LIVE_FRAME (frame); 1078 CHECK_LIVE_FRAME (frame);
1088 return prev_frame (frame, miniframe); 1079 return prev_frame (frame, miniframe);
1089} 1080}
1081
1082DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
1083 Slast_nonminibuf_frame, 0, 0, 0,
1084 doc: /* Return last non-minibuffer frame selected. */)
1085 (void)
1086{
1087 Lisp_Object frame = Qnil;
1088
1089 if (last_nonminibuf_frame)
1090 XSETFRAME (frame, last_nonminibuf_frame);
1091
1092 return frame;
1093}
1090 1094
1091/* Return 1 if it is ok to delete frame F; 1095/* Return 1 if it is ok to delete frame F;
1092 0 if all frames aside from F are invisible. 1096 0 if all frames aside from F are invisible.
@@ -1119,6 +1123,50 @@ other_visible_frames (struct frame *f)
1119 return 0; 1123 return 0;
1120} 1124}
1121 1125
1126/* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
1127 window. Preferably use the selected frame's minibuffer window
1128 instead. If the selected frame doesn't have one, get some other
1129 frame's minibuffer window. SELECT non-zero means select the new
1130 minibuffer window. */
1131static void
1132check_minibuf_window (Lisp_Object frame, int select)
1133{
1134 struct frame *f = decode_live_frame (frame);
1135
1136 if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window))
1137 {
1138 Lisp_Object frames, this, window = make_number (0);
1139
1140 if (!EQ (frame, selected_frame)
1141 && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame)))
1142 window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame));
1143 else
1144 FOR_EACH_FRAME (frames, this)
1145 {
1146 if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
1147 {
1148 window = FRAME_MINIBUF_WINDOW (XFRAME (this));
1149 break;
1150 }
1151 }
1152
1153 /* Don't abort if no window was found (Bug#15247). */
1154 if (WINDOWP (window))
1155 {
1156 /* Use set_window_buffer instead of Fset_window_buffer (see
1157 discussion of bug#11984, bug#12025, bug#12026). */
1158 set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0);
1159 minibuf_window = window;
1160
1161 /* SELECT non-zero usually means that FRAME's minibuffer
1162 window was selected; select the new one. */
1163 if (select)
1164 Fselect_window (minibuf_window, Qnil);
1165 }
1166 }
1167}
1168
1169
1122/* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME 1170/* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1123 unconditionally. x_connection_closed and delete_terminal use 1171 unconditionally. x_connection_closed and delete_terminal use
1124 this. Any other value of FORCE implements the semantics 1172 this. Any other value of FORCE implements the semantics
@@ -1206,10 +1254,18 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1206 /* Don't let the frame remain selected. */ 1254 /* Don't let the frame remain selected. */
1207 if (f == sf) 1255 if (f == sf)
1208 { 1256 {
1209 Lisp_Object tail, frame1; 1257 Lisp_Object tail;
1210 1258 Lisp_Object frame1 = Qnil;
1211 /* Look for another visible frame on the same terminal. */ 1259
1212 frame1 = next_frame (frame, Qvisible); 1260 /* Look for another visible frame on the same terminal.
1261 Do not call next_frame here because it may loop forever.
1262 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
1263 FOR_EACH_FRAME (tail, frame1)
1264 if (!EQ (frame, frame1)
1265 && (FRAME_TERMINAL (XFRAME (frame))
1266 == FRAME_TERMINAL (XFRAME (frame1)))
1267 && FRAME_VISIBLE_P (XFRAME (frame1)))
1268 break;
1213 1269
1214 /* If there is none, find *some* other frame. */ 1270 /* If there is none, find *some* other frame. */
1215 if (NILP (frame1) || EQ (frame1, frame)) 1271 if (NILP (frame1) || EQ (frame1, frame))
@@ -1245,19 +1301,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1245 } 1301 }
1246 1302
1247 /* Don't allow minibuf_window to remain on a deleted frame. */ 1303 /* Don't allow minibuf_window to remain on a deleted frame. */
1248 if (EQ (f->minibuffer_window, minibuf_window)) 1304 check_minibuf_window (frame, minibuffer_selected);
1249 {
1250 /* Use set_window_buffer instead of Fset_window_buffer (see
1251 discussion of bug#11984, bug#12025, bug#12026). */
1252 set_window_buffer (sf->minibuffer_window,
1253 XWINDOW (minibuf_window)->contents, 0, 0);
1254 minibuf_window = sf->minibuffer_window;
1255
1256 /* If the dying minibuffer window was selected,
1257 select the new one. */
1258 if (minibuffer_selected)
1259 Fselect_window (minibuf_window, Qnil);
1260 }
1261 1305
1262 /* Don't let echo_area_window to remain on a deleted frame. */ 1306 /* Don't let echo_area_window to remain on a deleted frame. */
1263 if (EQ (f->minibuffer_window, echo_area_window)) 1307 if (EQ (f->minibuffer_window, echo_area_window))
@@ -1684,16 +1728,8 @@ displayed in the terminal. */)
1684 if (NILP (force) && !other_visible_frames (f)) 1728 if (NILP (force) && !other_visible_frames (f))
1685 error ("Attempt to make invisible the sole visible or iconified frame"); 1729 error ("Attempt to make invisible the sole visible or iconified frame");
1686 1730
1687 /* Don't allow minibuf_window to remain on a deleted frame. */ 1731 /* Don't allow minibuf_window to remain on an invisible frame. */
1688 if (EQ (f->minibuffer_window, minibuf_window)) 1732 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
1689 {
1690 struct frame *sf = XFRAME (selected_frame);
1691 /* Use set_window_buffer instead of Fset_window_buffer (see
1692 discussion of bug#11984, bug#12025, bug#12026). */
1693 set_window_buffer (sf->minibuffer_window,
1694 XWINDOW (minibuf_window)->contents, 0, 0);
1695 minibuf_window = sf->minibuffer_window;
1696 }
1697 1733
1698 /* I think this should be done with a hook. */ 1734 /* I think this should be done with a hook. */
1699#ifdef HAVE_WINDOW_SYSTEM 1735#ifdef HAVE_WINDOW_SYSTEM
@@ -1716,15 +1752,7 @@ If omitted, FRAME defaults to the currently selected frame. */)
1716 struct frame *f = decode_live_frame (frame); 1752 struct frame *f = decode_live_frame (frame);
1717 1753
1718 /* Don't allow minibuf_window to remain on an iconified frame. */ 1754 /* Don't allow minibuf_window to remain on an iconified frame. */
1719 if (EQ (f->minibuffer_window, minibuf_window)) 1755 check_minibuf_window (frame, EQ (minibuf_window, selected_window));
1720 {
1721 struct frame *sf = XFRAME (selected_frame);
1722 /* Use set_window_buffer instead of Fset_window_buffer (see
1723 discussion of bug#11984, bug#12025, bug#12026). */
1724 set_window_buffer (sf->minibuffer_window,
1725 XWINDOW (minibuf_window)->contents, 0, 0);
1726 minibuf_window = sf->minibuffer_window;
1727 }
1728 1756
1729 /* I think this should be done with a hook. */ 1757 /* I think this should be done with a hook. */
1730#ifdef HAVE_WINDOW_SYSTEM 1758#ifdef HAVE_WINDOW_SYSTEM
@@ -3545,7 +3573,7 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
3545 3573
3546 value = x_get_string_resource (rdb, name_key, class_key); 3574 value = x_get_string_resource (rdb, name_key, class_key);
3547 3575
3548 if (value != (char *) 0 && *value) 3576 if (value && *value)
3549 return build_string (value); 3577 return build_string (value);
3550 else 3578 else
3551 return Qnil; 3579 return Qnil;
@@ -4204,8 +4232,7 @@ make_monitor_attribute_list (struct MonitorInfo *monitors,
4204 mi->work.width, mi->work.height); 4232 mi->work.width, mi->work.height);
4205 geometry = list4i (mi->geom.x, mi->geom.y, 4233 geometry = list4i (mi->geom.x, mi->geom.y,
4206 mi->geom.width, mi->geom.height); 4234 mi->geom.width, mi->geom.height);
4207 attributes = Fcons (Fcons (Qsource, 4235 attributes = Fcons (Fcons (Qsource, build_string (source)),
4208 make_string (source, strlen (source))),
4209 attributes); 4236 attributes);
4210 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), 4237 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
4211 attributes); 4238 attributes);
@@ -4478,6 +4505,7 @@ automatically. See also `mouse-autoselect-window'. */);
4478 defsubr (&Sframe_list); 4505 defsubr (&Sframe_list);
4479 defsubr (&Snext_frame); 4506 defsubr (&Snext_frame);
4480 defsubr (&Sprevious_frame); 4507 defsubr (&Sprevious_frame);
4508 defsubr (&Slast_nonminibuf_frame);
4481 defsubr (&Sdelete_frame); 4509 defsubr (&Sdelete_frame);
4482 defsubr (&Smouse_position); 4510 defsubr (&Smouse_position);
4483 defsubr (&Smouse_pixel_position); 4511 defsubr (&Smouse_pixel_position);
diff --git a/src/frame.h b/src/frame.h
index 33e4bb71d7a..17b6089120a 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -24,31 +24,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#define EMACS_FRAME_H 24#define EMACS_FRAME_H
25 25
26#include "dispextern.h" 26#include "dispextern.h"
27#include "termhooks.h"
27 28
28INLINE_HEADER_BEGIN 29INLINE_HEADER_BEGIN
29#ifndef FRAME_INLINE 30#ifndef FRAME_INLINE
30# define FRAME_INLINE INLINE 31# define FRAME_INLINE INLINE
31#endif 32#endif
32 33
33
34/* Miscellanea. */
35
36/* Nonzero means there is at least one garbaged frame. */
37extern bool frame_garbaged;
38
39
40/* The structure representing a frame. */
41
42enum output_method
43{
44 output_initial,
45 output_termcap,
46 output_x_window,
47 output_msdos_raw,
48 output_w32,
49 output_ns
50};
51
52enum vertical_scroll_bar_type 34enum vertical_scroll_bar_type
53{ 35{
54 vertical_scroll_bar_none, 36 vertical_scroll_bar_none,
@@ -56,16 +38,6 @@ enum vertical_scroll_bar_type
56 vertical_scroll_bar_right 38 vertical_scroll_bar_right
57}; 39};
58 40
59enum text_cursor_kinds
60{
61 DEFAULT_CURSOR = -2,
62 NO_CURSOR = -1,
63 FILLED_BOX_CURSOR,
64 HOLLOW_BOX_CURSOR,
65 BAR_CURSOR,
66 HBAR_CURSOR
67};
68
69enum fullscreen_type 41enum fullscreen_type
70{ 42{
71 FULLSCREEN_NONE, 43 FULLSCREEN_NONE,
@@ -76,10 +48,7 @@ enum fullscreen_type
76 FULLSCREEN_WAIT = 0x100 48 FULLSCREEN_WAIT = 0x100
77}; 49};
78 50
79 51/* The structure representing a frame. */
80#define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel)
81#define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel)
82
83 52
84struct frame 53struct frame
85{ 54{
@@ -410,6 +379,10 @@ struct frame
410 /* Nonzero means that the pointer is invisible. */ 379 /* Nonzero means that the pointer is invisible. */
411 unsigned pointer_invisible :1; 380 unsigned pointer_invisible :1;
412 381
382 /* Nonzero means that all windows except mini-window and
383 selected window on this frame have frozen window starts. */
384 unsigned frozen_window_starts : 1;
385
413 /* Nonzero if we should actually display the scroll bars on this frame. */ 386 /* Nonzero if we should actually display the scroll bars on this frame. */
414 enum vertical_scroll_bar_type vertical_scroll_bar_type; 387 enum vertical_scroll_bar_type vertical_scroll_bar_type;
415 388
@@ -761,6 +734,10 @@ default_pixels_per_inch_y (void)
761/* Not really implemented. */ 734/* Not really implemented. */
762#define FRAME_WANTS_MODELINE_P(f) (f)->wants_modeline 735#define FRAME_WANTS_MODELINE_P(f) (f)->wants_modeline
763 736
737/* Nonzero if all windows except selected window and mini window
738 are frozen on frame F. */
739#define FRAME_WINDOWS_FROZEN(f) (f)->frozen_window_starts
740
764/* Nonzero if a size change has been requested for frame F 741/* Nonzero if a size change has been requested for frame F
765 but not yet really put into effect. This can be true temporarily 742 but not yet really put into effect. This can be true temporarily
766 when an X event comes in at a bad time. */ 743 when an X event comes in at a bad time. */
@@ -886,6 +863,9 @@ default_pixels_per_inch_y (void)
886#define FRAME_CURSOR_WIDTH(f) ((f)->cursor_width) 863#define FRAME_CURSOR_WIDTH(f) ((f)->cursor_width)
887#define FRAME_BLINK_OFF_CURSOR_WIDTH(f) ((f)->blink_off_cursor_width) 864#define FRAME_BLINK_OFF_CURSOR_WIDTH(f) ((f)->blink_off_cursor_width)
888 865
866#define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel)
867#define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel)
868
889/* Return a pointer to the face cache of frame F. */ 869/* Return a pointer to the face cache of frame F. */
890 870
891#define FRAME_FACE_CACHE(F) (F)->face_cache 871#define FRAME_FACE_CACHE(F) (F)->face_cache
@@ -952,6 +932,9 @@ extern Lisp_Object Qtty_color_mode;
952extern Lisp_Object Qterminal; 932extern Lisp_Object Qterminal;
953extern Lisp_Object Qnoelisp; 933extern Lisp_Object Qnoelisp;
954 934
935/* Nonzero means there is at least one garbaged frame. */
936extern bool frame_garbaged;
937
955extern struct frame *last_nonminibuf_frame; 938extern struct frame *last_nonminibuf_frame;
956 939
957extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); 940extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
diff --git a/src/fringe.c b/src/fringe.c
index 1d05244e64e..492eddae8d4 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -666,7 +666,7 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o
666 and OTOH leaving out that one pixel leaves behind 666 and OTOH leaving out that one pixel leaves behind
667 traces of the cursor, if it was in column zero 667 traces of the cursor, if it was in column zero
668 before drawing non-empty margin area. */ 668 before drawing non-empty margin area. */
669 && NILP (w->left_margin_cols)) 669 && w->left_margin_cols == 0)
670 ? 1 : 0); 670 ? 1 : 0);
671 p.bx = x - wd; 671 p.bx = x - wd;
672 p.nx = wd; 672 p.nx = wd;
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 237d031295c..6228f2150f5 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -35,6 +35,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35#include "keyboard.h" 35#include "keyboard.h"
36#include "charset.h" 36#include "charset.h"
37#include "coding.h" 37#include "coding.h"
38#include "font.h"
39
38#include <gdk/gdkkeysyms.h> 40#include <gdk/gdkkeysyms.h>
39#include "xsettings.h" 41#include "xsettings.h"
40 42
@@ -641,7 +643,7 @@ hierarchy_ch_cb (GtkWidget *widget,
641 GtkWidget *previous_toplevel, 643 GtkWidget *previous_toplevel,
642 gpointer user_data) 644 gpointer user_data)
643{ 645{
644 struct frame *f = (struct frame *) user_data; 646 struct frame *f = user_data;
645 struct x_output *x = f->output_data.x; 647 struct x_output *x = f->output_data.x;
646 GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl); 648 GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl);
647 649
@@ -663,7 +665,7 @@ qttip_cb (GtkWidget *widget,
663 GtkTooltip *tooltip, 665 GtkTooltip *tooltip,
664 gpointer user_data) 666 gpointer user_data)
665{ 667{
666 struct frame *f = (struct frame *) user_data; 668 struct frame *f = user_data;
667 struct x_output *x = f->output_data.x; 669 struct x_output *x = f->output_data.x;
668 if (x->ttip_widget == NULL) 670 if (x->ttip_widget == NULL)
669 { 671 {
@@ -870,29 +872,23 @@ xg_clear_under_internal_border (struct frame *f)
870 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0) 872 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
871 { 873 {
872 GtkWidget *wfixed = f->output_data.x->edit_widget; 874 GtkWidget *wfixed = f->output_data.x->edit_widget;
875
873 gtk_widget_queue_draw (wfixed); 876 gtk_widget_queue_draw (wfixed);
874 gdk_window_process_all_updates (); 877 gdk_window_process_all_updates ();
875 x_clear_area (FRAME_X_DISPLAY (f), 878
876 FRAME_X_WINDOW (f), 879 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, 0,
877 0, 0, 880 FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f));
878 FRAME_PIXEL_WIDTH (f), 881
879 FRAME_INTERNAL_BORDER_WIDTH (f), 0); 882 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, 0,
880 x_clear_area (FRAME_X_DISPLAY (f), 883 FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
881 FRAME_X_WINDOW (f), 884
882 0, 0, 885 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0,
883 FRAME_INTERNAL_BORDER_WIDTH (f), 886 FRAME_PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
884 FRAME_PIXEL_HEIGHT (f), 0); 887 FRAME_PIXEL_WIDTH (f), FRAME_INTERNAL_BORDER_WIDTH (f));
885 x_clear_area (FRAME_X_DISPLAY (f), 888
886 FRAME_X_WINDOW (f), 889 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
887 0, FRAME_PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f), 890 FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
888 FRAME_PIXEL_WIDTH (f), 891 0, FRAME_INTERNAL_BORDER_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
889 FRAME_INTERNAL_BORDER_WIDTH (f), 0);
890 x_clear_area (FRAME_X_DISPLAY (f),
891 FRAME_X_WINDOW (f),
892 FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
893 0,
894 FRAME_INTERNAL_BORDER_WIDTH (f),
895 FRAME_PIXEL_HEIGHT (f), 0);
896 } 892 }
897} 893}
898 894
@@ -1073,7 +1069,7 @@ style_changed_cb (GObject *go,
1073 gpointer user_data) 1069 gpointer user_data)
1074{ 1070{
1075 struct input_event event; 1071 struct input_event event;
1076 GdkDisplay *gdpy = (GdkDisplay *) user_data; 1072 GdkDisplay *gdpy = user_data;
1077 const char *display_name = gdk_display_get_name (gdpy); 1073 const char *display_name = gdk_display_get_name (gdpy);
1078 Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy); 1074 Display *dpy = GDK_DISPLAY_XDISPLAY (gdpy);
1079 1075
@@ -1115,7 +1111,7 @@ delete_cb (GtkWidget *widget,
1115#ifdef HAVE_GTK3 1111#ifdef HAVE_GTK3
1116 /* The event doesn't arrive in the normal event loop. Send event 1112 /* The event doesn't arrive in the normal event loop. Send event
1117 here. */ 1113 here. */
1118 struct frame *f = (struct frame *) user_data; 1114 struct frame *f = user_data;
1119 struct input_event ie; 1115 struct input_event ie;
1120 1116
1121 EVENT_INIT (ie); 1117 EVENT_INIT (ie);
@@ -1341,6 +1337,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
1341 int base_width, base_height; 1337 int base_width, base_height;
1342 int min_rows = 0, min_cols = 0; 1338 int min_rows = 0, min_cols = 0;
1343 int win_gravity = f->win_gravity; 1339 int win_gravity = f->win_gravity;
1340 Lisp_Object fs_state, frame;
1344 1341
1345 /* Don't set size hints during initialization; that apparently leads 1342 /* Don't set size hints during initialization; that apparently leads
1346 to a race condition. See the thread at 1343 to a race condition. See the thread at
@@ -1348,6 +1345,16 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
1348 if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f)) 1345 if (NILP (Vafter_init_time) || !FRAME_GTK_OUTER_WIDGET (f))
1349 return; 1346 return;
1350 1347
1348 XSETFRAME (frame, f);
1349 fs_state = Fframe_parameter (frame, Qfullscreen);
1350 if (EQ (fs_state, Qmaximized) || EQ (fs_state, Qfullboth))
1351 {
1352 /* Don't set hints when maximized or fullscreen. Apparently KWin and
1353 Gtk3 don't get along and the frame shrinks (!).
1354 */
1355 return;
1356 }
1357
1351 if (flags) 1358 if (flags)
1352 { 1359 {
1353 memset (&size_hints, 0, sizeof (size_hints)); 1360 memset (&size_hints, 0, sizeof (size_hints));
@@ -1642,7 +1649,7 @@ xg_dialog_response_cb (GtkDialog *w,
1642 gint response, 1649 gint response,
1643 gpointer user_data) 1650 gpointer user_data)
1644{ 1651{
1645 struct xg_dialog_data *dd = (struct xg_dialog_data *)user_data; 1652 struct xg_dialog_data *dd = user_data;
1646 dd->response = response; 1653 dd->response = response;
1647 g_main_loop_quit (dd->loop); 1654 g_main_loop_quit (dd->loop);
1648} 1655}
@@ -1671,16 +1678,16 @@ pop_down_dialog (void *arg)
1671static gboolean 1678static gboolean
1672xg_maybe_add_timer (gpointer data) 1679xg_maybe_add_timer (gpointer data)
1673{ 1680{
1674 struct xg_dialog_data *dd = (struct xg_dialog_data *) data; 1681 struct xg_dialog_data *dd = data;
1675 EMACS_TIME next_time = timer_check (); 1682 struct timespec next_time = timer_check ();
1676 1683
1677 dd->timerid = 0; 1684 dd->timerid = 0;
1678 1685
1679 if (EMACS_TIME_VALID_P (next_time)) 1686 if (timespec_valid_p (next_time))
1680 { 1687 {
1681 time_t s = EMACS_SECS (next_time); 1688 time_t s = next_time.tv_sec;
1682 int per_ms = EMACS_TIME_RESOLUTION / 1000; 1689 int per_ms = TIMESPEC_RESOLUTION / 1000;
1683 int ms = (EMACS_NSECS (next_time) + per_ms - 1) / per_ms; 1690 int ms = (next_time.tv_nsec + per_ms - 1) / per_ms;
1684 if (s <= ((guint) -1 - ms) / 1000) 1691 if (s <= ((guint) -1 - ms) / 1000)
1685 dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd); 1692 dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd);
1686 } 1693 }
@@ -1921,7 +1928,7 @@ static char *
1921xg_get_file_name_from_selector (GtkWidget *w) 1928xg_get_file_name_from_selector (GtkWidget *w)
1922{ 1929{
1923 GtkFileSelection *filesel = GTK_FILE_SELECTION (w); 1930 GtkFileSelection *filesel = GTK_FILE_SELECTION (w);
1924 return xstrdup ((char*) gtk_file_selection_get_filename (filesel)); 1931 return xstrdup (gtk_file_selection_get_filename (filesel));
1925} 1932}
1926 1933
1927/* Create a file selection dialog. 1934/* Create a file selection dialog.
@@ -2039,7 +2046,6 @@ xg_get_file_name (struct frame *f,
2039 2046
2040 2047
2041static char *x_last_font_name; 2048static char *x_last_font_name;
2042extern Lisp_Object Qxft;
2043 2049
2044/* Pop up a GTK font selector and return the name of the font the user 2050/* Pop up a GTK font selector and return the name of the font the user
2045 selects, as a C string. The returned font name follows GTK's own 2051 selects, as a C string. The returned font name follows GTK's own
@@ -2277,7 +2283,7 @@ menuitem_destroy_callback (GtkWidget *w, gpointer client_data)
2277{ 2283{
2278 if (client_data) 2284 if (client_data)
2279 { 2285 {
2280 xg_menu_item_cb_data *data = (xg_menu_item_cb_data*) client_data; 2286 xg_menu_item_cb_data *data = client_data;
2281 xg_list_remove (&xg_menu_item_cb_list, &data->ptrs); 2287 xg_list_remove (&xg_menu_item_cb_list, &data->ptrs);
2282 xfree (data); 2288 xfree (data);
2283 } 2289 }
@@ -2301,8 +2307,7 @@ menuitem_highlight_callback (GtkWidget *w,
2301 2307
2302 ev.crossing = *event; 2308 ev.crossing = *event;
2303 subwidget = gtk_get_event_widget (&ev); 2309 subwidget = gtk_get_event_widget (&ev);
2304 data = (xg_menu_item_cb_data *) g_object_get_data (G_OBJECT (subwidget), 2310 data = g_object_get_data (G_OBJECT (subwidget), XG_ITEM_DATA);
2305 XG_ITEM_DATA);
2306 if (data) 2311 if (data)
2307 { 2312 {
2308 if (! NILP (data->help) && data->cl_data->highlight_cb) 2313 if (! NILP (data->help) && data->cl_data->highlight_cb)
@@ -2323,7 +2328,7 @@ menuitem_highlight_callback (GtkWidget *w,
2323static void 2328static void
2324menu_destroy_callback (GtkWidget *w, gpointer client_data) 2329menu_destroy_callback (GtkWidget *w, gpointer client_data)
2325{ 2330{
2326 unref_cl_data ((xg_menu_cb_data*) client_data); 2331 unref_cl_data (client_data);
2327} 2332}
2328 2333
2329/* Make a GTK widget that contains both UTF8_LABEL and UTF8_KEY (both 2334/* Make a GTK widget that contains both UTF8_LABEL and UTF8_KEY (both
@@ -3064,8 +3069,7 @@ xg_update_menu_item (widget_value *val,
3064 else if (val->enabled && ! gtk_widget_get_sensitive (w)) 3069 else if (val->enabled && ! gtk_widget_get_sensitive (w))
3065 gtk_widget_set_sensitive (w, TRUE); 3070 gtk_widget_set_sensitive (w, TRUE);
3066 3071
3067 cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (w), 3072 cb_data = g_object_get_data (G_OBJECT (w), XG_ITEM_DATA);
3068 XG_ITEM_DATA);
3069 if (cb_data) 3073 if (cb_data)
3070 { 3074 {
3071 cb_data->call_data = val->call_data; 3075 cb_data->call_data = val->call_data;
@@ -3271,8 +3275,7 @@ xg_modify_menubar_widgets (GtkWidget *menubar, struct frame *f,
3271 3275
3272 if (! list) return; 3276 if (! list) return;
3273 3277
3274 cl_data = (xg_menu_cb_data*) g_object_get_data (G_OBJECT (menubar), 3278 cl_data = g_object_get_data (G_OBJECT (menubar), XG_FRAME_DATA);
3275 XG_FRAME_DATA);
3276 3279
3277 xg_update_menubar (menubar, f, &list, list, 0, val->contents, 3280 xg_update_menubar (menubar, f, &list, list, 0, val->contents,
3278 select_cb, deactivate_cb, highlight_cb, cl_data); 3281 select_cb, deactivate_cb, highlight_cb, cl_data);
@@ -3336,7 +3339,7 @@ static void
3336menubar_map_cb (GtkWidget *w, gpointer user_data) 3339menubar_map_cb (GtkWidget *w, gpointer user_data)
3337{ 3340{
3338 GtkRequisition req; 3341 GtkRequisition req;
3339 struct frame *f = (struct frame *) user_data; 3342 struct frame *f = user_data;
3340 gtk_widget_get_preferred_size (w, NULL, &req); 3343 gtk_widget_get_preferred_size (w, NULL, &req);
3341 if (FRAME_MENUBAR_HEIGHT (f) != req.height) 3344 if (FRAME_MENUBAR_HEIGHT (f) != req.height)
3342 { 3345 {
@@ -3742,14 +3745,11 @@ xg_update_scrollbar_pos (struct frame *f,
3742 gtk_widget_queue_draw (wfixed); 3745 gtk_widget_queue_draw (wfixed);
3743 gdk_window_process_all_updates (); 3746 gdk_window_process_all_updates ();
3744 if (oldx != -1 && oldw > 0 && oldh > 0) 3747 if (oldx != -1 && oldw > 0 && oldh > 0)
3745 { 3748 /* Clear under old scroll bar position. This must be done after
3746 /* Clear under old scroll bar position. This must be done after 3749 the gtk_widget_queue_draw and gdk_window_process_all_updates
3747 the gtk_widget_queue_draw and gdk_window_process_all_updates 3750 above. */
3748 above. */ 3751 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3749 x_clear_area (FRAME_X_DISPLAY (f), 3752 oldx, oldy, oldw, oldh);
3750 FRAME_X_WINDOW (f),
3751 oldx, oldy, oldw, oldh, 0);
3752 }
3753 3753
3754 /* GTK does not redraw until the main loop is entered again, but 3754 /* GTK does not redraw until the main loop is entered again, but
3755 if there are no X events pending we will not enter it. So we sync 3755 if there are no X events pending we will not enter it. So we sync
@@ -3783,7 +3783,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
3783 3783
3784 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 3784 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3785 3785
3786 if (wscroll && NILP (bar->dragging)) 3786 if (wscroll && bar->dragging == -1)
3787 { 3787 {
3788 GtkAdjustment *adj; 3788 GtkAdjustment *adj;
3789 gdouble shown; 3789 gdouble shown;
@@ -3946,8 +3946,7 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data)
3946 gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER); 3946 gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER);
3947 intptr_t mod = (intptr_t) gmod; 3947 intptr_t mod = (intptr_t) gmod;
3948 3948
3949 struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (w), 3949 struct frame *f = g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
3950 XG_FRAME_DATA);
3951 Lisp_Object key, frame; 3950 Lisp_Object key, frame;
3952 struct input_event event; 3951 struct input_event event;
3953 EVENT_INIT (event); 3952 EVENT_INIT (event);
@@ -4020,8 +4019,8 @@ static GtkWidget *
4020xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage) 4019xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage)
4021{ 4020{
4022 GList *clist = gtk_container_get_children (GTK_CONTAINER (vb)); 4021 GList *clist = gtk_container_get_children (GTK_CONTAINER (vb));
4023 GtkWidget *c1 = (GtkWidget *) clist->data; 4022 GtkWidget *c1 = clist->data;
4024 GtkWidget *c2 = clist->next ? (GtkWidget *) clist->next->data : NULL; 4023 GtkWidget *c2 = clist->next ? clist->next->data : NULL;
4025 4024
4026 *wimage = GTK_IS_IMAGE (c1) ? c1 : c2; 4025 *wimage = GTK_IS_IMAGE (c1) ? c1 : c2;
4027 g_list_free (clist); 4026 g_list_free (clist);
@@ -4150,7 +4149,7 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox,
4150 GtkWidget *w, 4149 GtkWidget *w,
4151 gpointer client_data) 4150 gpointer client_data)
4152{ 4151{
4153 struct frame *f = (struct frame *) client_data; 4152 struct frame *f = client_data;
4154 4153
4155 g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar, 4154 g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar,
4156 NULL); 4155 NULL);
@@ -4187,7 +4186,7 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox,
4187 GtkWidget *w, 4186 GtkWidget *w,
4188 gpointer client_data) 4187 gpointer client_data)
4189{ 4188{
4190 struct frame *f = (struct frame *) client_data; 4189 struct frame *f = client_data;
4191 g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL); 4190 g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL);
4192 4191
4193 if (f) 4192 if (f)
@@ -4225,8 +4224,7 @@ xg_tool_bar_help_callback (GtkWidget *w,
4225 gpointer client_data) 4224 gpointer client_data)
4226{ 4225{
4227 intptr_t idx = (intptr_t) client_data; 4226 intptr_t idx = (intptr_t) client_data;
4228 struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (w), 4227 struct frame *f = g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
4229 XG_FRAME_DATA);
4230 Lisp_Object help, frame; 4228 Lisp_Object help, frame;
4231 4229
4232 if (! f || ! f->n_tool_bar_items || NILP (f->tool_bar_items)) 4230 if (! f || ! f->n_tool_bar_items || NILP (f->tool_bar_items))
@@ -4366,7 +4364,7 @@ tb_size_cb (GtkWidget *widget,
4366 /* When tool bar is created it has one preferred size. But when size is 4364 /* When tool bar is created it has one preferred size. But when size is
4367 allocated between widgets, it may get another. So we must update 4365 allocated between widgets, it may get another. So we must update
4368 size hints if tool bar size changes. Seen on Fedora 18 at least. */ 4366 size hints if tool bar size changes. Seen on Fedora 18 at least. */
4369 struct frame *f = (struct frame *) user_data; 4367 struct frame *f = user_data;
4370 if (xg_update_tool_bar_sizes (f)) 4368 if (xg_update_tool_bar_sizes (f))
4371 x_wm_set_size_hint (f, 0, 0); 4369 x_wm_set_size_hint (f, 0, 0);
4372} 4370}
@@ -5038,10 +5036,10 @@ xg_initialize (void)
5038 (gdk_display_get_default ())); 5036 (gdk_display_get_default ()));
5039 /* Remove F10 as a menu accelerator, it does not mix well with Emacs key 5037 /* Remove F10 as a menu accelerator, it does not mix well with Emacs key
5040 bindings. It doesn't seem to be any way to remove properties, 5038 bindings. It doesn't seem to be any way to remove properties,
5041 so we set it to VoidSymbol which in X means "no key". */ 5039 so we set it to "" which in means "no key". */
5042 gtk_settings_set_string_property (settings, 5040 gtk_settings_set_string_property (settings,
5043 "gtk-menu-bar-accel", 5041 "gtk-menu-bar-accel",
5044 "VoidSymbol", 5042 "",
5045 EMACS_CLASS); 5043 EMACS_CLASS);
5046 5044
5047 /* Make GTK text input widgets use Emacs style keybindings. This is 5045 /* Make GTK text input widgets use Emacs style keybindings. This is
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 482331a8934..fc959862fd3 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -74,8 +74,6 @@ typedef struct xg_menu_item_cb_data_
74 74
75} xg_menu_item_cb_data; 75} xg_menu_item_cb_data;
76 76
77struct _widget_value;
78
79extern struct _widget_value *malloc_widget_value (void); 77extern struct _widget_value *malloc_widget_value (void);
80extern void free_widget_value (struct _widget_value *); 78extern void free_widget_value (struct _widget_value *);
81 79
diff --git a/src/image.c b/src/image.c
index 911ca8e6681..1271376bcab 100644
--- a/src/image.c
+++ b/src/image.c
@@ -30,13 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30#endif 30#endif
31 31
32#include <setjmp.h> 32#include <setjmp.h>
33
34#include <c-ctype.h> 33#include <c-ctype.h>
35 34
36/* This makes the fields of a Display accessible, in Xlib header files. */
37
38#define XLIB_ILLEGAL_ACCESS
39
40#include "lisp.h" 35#include "lisp.h"
41#include "frame.h" 36#include "frame.h"
42#include "window.h" 37#include "window.h"
@@ -145,7 +140,7 @@ static Lisp_Object QCmax_width, QCmax_height;
145 140
146#ifdef HAVE_NS 141#ifdef HAVE_NS
147/* Use with images created by ns_image_for_XPM. */ 142/* Use with images created by ns_image_for_XPM. */
148unsigned long 143static unsigned long
149XGetPixel (XImagePtr ximage, int x, int y) 144XGetPixel (XImagePtr ximage, int x, int y)
150{ 145{
151 return ns_get_pixel (ximage, x, y); 146 return ns_get_pixel (ximage, x, y);
@@ -153,7 +148,7 @@ XGetPixel (XImagePtr ximage, int x, int y)
153 148
154/* Use with images created by ns_image_for_XPM; alpha set to 1; 149/* Use with images created by ns_image_for_XPM; alpha set to 1;
155 pixel is assumed to be in RGB form. */ 150 pixel is assumed to be in RGB form. */
156void 151static void
157XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) 152XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
158{ 153{
159 ns_put_pixel (ximage, x, y, pixel); 154 ns_put_pixel (ximage, x, y, pixel);
@@ -302,11 +297,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
302 id = x_allocate_bitmap_record (f); 297 id = x_allocate_bitmap_record (f);
303 dpyinfo->bitmaps[id - 1].img = bitmap; 298 dpyinfo->bitmaps[id - 1].img = bitmap;
304 dpyinfo->bitmaps[id - 1].refcount = 1; 299 dpyinfo->bitmaps[id - 1].refcount = 1;
305 dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); 300 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
306 dpyinfo->bitmaps[id - 1].depth = 1; 301 dpyinfo->bitmaps[id - 1].depth = 1;
307 dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap); 302 dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap);
308 dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap); 303 dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap);
309 strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file));
310 return id; 304 return id;
311#endif 305#endif
312 306
@@ -345,11 +339,10 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
345 dpyinfo->bitmaps[id - 1].pixmap = bitmap; 339 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
346 dpyinfo->bitmaps[id - 1].have_mask = 0; 340 dpyinfo->bitmaps[id - 1].have_mask = 0;
347 dpyinfo->bitmaps[id - 1].refcount = 1; 341 dpyinfo->bitmaps[id - 1].refcount = 1;
348 dpyinfo->bitmaps[id - 1].file = xmalloc (SBYTES (file) + 1); 342 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
349 dpyinfo->bitmaps[id - 1].depth = 1; 343 dpyinfo->bitmaps[id - 1].depth = 1;
350 dpyinfo->bitmaps[id - 1].height = height; 344 dpyinfo->bitmaps[id - 1].height = height;
351 dpyinfo->bitmaps[id - 1].width = width; 345 dpyinfo->bitmaps[id - 1].width = width;
352 strcpy (dpyinfo->bitmaps[id - 1].file, SSDATA (file));
353 346
354 return id; 347 return id;
355#endif /* HAVE_X_WINDOWS */ 348#endif /* HAVE_X_WINDOWS */
@@ -565,7 +558,6 @@ static void x_emboss (struct frame *, struct image *);
565static void x_build_heuristic_mask (struct frame *, struct image *, 558static void x_build_heuristic_mask (struct frame *, struct image *,
566 Lisp_Object); 559 Lisp_Object);
567#ifdef WINDOWSNT 560#ifdef WINDOWSNT
568extern Lisp_Object Vlibrary_cache;
569#define CACHE_IMAGE_TYPE(type, status) \ 561#define CACHE_IMAGE_TYPE(type, status) \
570 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) 562 do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
571#else 563#else
@@ -1044,7 +1036,7 @@ void
1044prepare_image_for_display (struct frame *f, struct image *img) 1036prepare_image_for_display (struct frame *f, struct image *img)
1045{ 1037{
1046 /* We're about to display IMG, so set its timestamp to `now'. */ 1038 /* We're about to display IMG, so set its timestamp to `now'. */
1047 img->timestamp = current_emacs_time (); 1039 img->timestamp = current_timespec ();
1048 1040
1049 /* If IMG doesn't have a pixmap yet, load it now, using the image 1041 /* If IMG doesn't have a pixmap yet, load it now, using the image
1050 type dependent loader function. */ 1042 type dependent loader function. */
@@ -1362,14 +1354,12 @@ static void cache_image (struct frame *f, struct image *img);
1362struct image_cache * 1354struct image_cache *
1363make_image_cache (void) 1355make_image_cache (void)
1364{ 1356{
1365 struct image_cache *c = xzalloc (sizeof *c); 1357 struct image_cache *c = xmalloc (sizeof *c);
1366 int size;
1367 1358
1368 size = 50; 1359 c->size = 50;
1369 c->images = xmalloc (size * sizeof *c->images); 1360 c->used = c->refcount = 0;
1370 c->size = size; 1361 c->images = xmalloc (c->size * sizeof *c->images);
1371 size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; 1362 c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
1372 c->buckets = xzalloc (size);
1373 return c; 1363 return c;
1374} 1364}
1375 1365
@@ -1485,7 +1475,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1485 else if (INTEGERP (Vimage_cache_eviction_delay)) 1475 else if (INTEGERP (Vimage_cache_eviction_delay))
1486 { 1476 {
1487 /* Free cache based on timestamp. */ 1477 /* Free cache based on timestamp. */
1488 EMACS_TIME old, t; 1478 struct timespec old, t;
1489 double delay; 1479 double delay;
1490 ptrdiff_t nimages = 0; 1480 ptrdiff_t nimages = 0;
1491 1481
@@ -1500,13 +1490,13 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1500 delay = 1600 * delay / nimages / nimages; 1490 delay = 1600 * delay / nimages / nimages;
1501 delay = max (delay, 1); 1491 delay = max (delay, 1);
1502 1492
1503 t = current_emacs_time (); 1493 t = current_timespec ();
1504 old = sub_emacs_time (t, EMACS_TIME_FROM_DOUBLE (delay)); 1494 old = timespec_sub (t, dtotimespec (delay));
1505 1495
1506 for (i = 0; i < c->used; ++i) 1496 for (i = 0; i < c->used; ++i)
1507 { 1497 {
1508 struct image *img = c->images[i]; 1498 struct image *img = c->images[i];
1509 if (img && EMACS_TIME_LT (img->timestamp, old)) 1499 if (img && timespec_cmp (img->timestamp, old) < 0)
1510 { 1500 {
1511 free_image (f, img); 1501 free_image (f, img);
1512 ++nfreed; 1502 ++nfreed;
@@ -1769,7 +1759,7 @@ lookup_image (struct frame *f, Lisp_Object spec)
1769 } 1759 }
1770 1760
1771 /* We're using IMG, so set its timestamp to `now'. */ 1761 /* We're using IMG, so set its timestamp to `now'. */
1772 img->timestamp = current_emacs_time (); 1762 img->timestamp = current_timespec ();
1773 1763
1774 /* Value is the image id. */ 1764 /* Value is the image id. */
1775 return img->id; 1765 return img->id;
@@ -2717,10 +2707,13 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
2717 LA1 = xbm_scan (&s, end, buffer, &value) 2707 LA1 = xbm_scan (&s, end, buffer, &value)
2718 2708
2719#define expect(TOKEN) \ 2709#define expect(TOKEN) \
2720 if (LA1 != (TOKEN)) \ 2710 do \
2721 goto failure; \ 2711 { \
2722 else \ 2712 if (LA1 != (TOKEN)) \
2723 match () 2713 goto failure; \
2714 match (); \
2715 } \
2716 while (0)
2724 2717
2725#define expect_ident(IDENT) \ 2718#define expect_ident(IDENT) \
2726 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ 2719 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
@@ -3332,7 +3325,7 @@ static int
3332xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color, 3325xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color,
3333 void *closure) 3326 void *closure)
3334{ 3327{
3335 return xpm_lookup_color ((struct frame *) closure, color_name, color); 3328 return xpm_lookup_color (closure, color_name, color);
3336} 3329}
3337 3330
3338 3331
@@ -3980,10 +3973,13 @@ xpm_load_image (struct frame *f,
3980 LA1 = xpm_scan (&s, end, &beg, &len) 3973 LA1 = xpm_scan (&s, end, &beg, &len)
3981 3974
3982#define expect(TOKEN) \ 3975#define expect(TOKEN) \
3983 if (LA1 != (TOKEN)) \ 3976 do \
3984 goto failure; \ 3977 { \
3985 else \ 3978 if (LA1 != (TOKEN)) \
3986 match () 3979 goto failure; \
3980 match (); \
3981 } \
3982 while (0)
3987 3983
3988#define expect_ident(IDENT) \ 3984#define expect_ident(IDENT) \
3989 if (LA1 == XPM_TK_IDENT \ 3985 if (LA1 == XPM_TK_IDENT \
@@ -4936,7 +4932,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
4936 int row_width; 4932 int row_width;
4937#endif /* HAVE_NTGUI */ 4933#endif /* HAVE_NTGUI */
4938 int x, y; 4934 int x, y;
4939 bool rc, use_img_background; 4935 bool use_img_background;
4940 unsigned long bg = 0; 4936 unsigned long bg = 0;
4941 4937
4942 if (img->mask) 4938 if (img->mask)
@@ -4945,9 +4941,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how)
4945#ifndef HAVE_NTGUI 4941#ifndef HAVE_NTGUI
4946#ifndef HAVE_NS 4942#ifndef HAVE_NS
4947 /* Create an image and pixmap serving as mask. */ 4943 /* Create an image and pixmap serving as mask. */
4948 rc = image_create_x_image_and_pixmap (f, img, img->width, img->height, 1, 4944 if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1,
4949 &mask_img, 1); 4945 &mask_img, 1))
4950 if (!rc)
4951 return; 4946 return;
4952#endif /* !HAVE_NS */ 4947#endif /* !HAVE_NS */
4953#else 4948#else
@@ -5652,8 +5647,7 @@ struct png_memory_storage
5652static void 5647static void
5653png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length) 5648png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
5654{ 5649{
5655 struct png_memory_storage *tbr 5650 struct png_memory_storage *tbr = fn_png_get_io_ptr (png_ptr);
5656 = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
5657 5651
5658 if (length > tbr->len - tbr->index) 5652 if (length > tbr->len - tbr->index)
5659 fn_png_error (png_ptr, "Read error"); 5653 fn_png_error (png_ptr, "Read error");
@@ -5670,7 +5664,7 @@ png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
5670static void 5664static void
5671png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) 5665png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
5672{ 5666{
5673 FILE *fp = (FILE *) fn_png_get_io_ptr (png_ptr); 5667 FILE *fp = fn_png_get_io_ptr (png_ptr);
5674 5668
5675 if (fread (data, 1, length, fp) < length) 5669 if (fread (data, 1, length, fp) < length)
5676 fn_png_error (png_ptr, "Read error"); 5670 fn_png_error (png_ptr, "Read error");
@@ -5814,9 +5808,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5814 5808
5815 /* Read image info. */ 5809 /* Read image info. */
5816 if (!NILP (specified_data)) 5810 if (!NILP (specified_data))
5817 fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); 5811 fn_png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
5818 else 5812 else
5819 fn_png_set_read_fn (png_ptr, (void *) fp, png_read_from_file); 5813 fn_png_set_read_fn (png_ptr, fp, png_read_from_file);
5820 5814
5821 fn_png_set_sig_bytes (png_ptr, sizeof sig); 5815 fn_png_set_sig_bytes (png_ptr, sizeof sig);
5822 fn_png_read_info (png_ptr, info_ptr); 5816 fn_png_read_info (png_ptr, info_ptr);
@@ -6306,7 +6300,7 @@ our_memory_fill_input_buffer (j_decompress_ptr cinfo)
6306static void 6300static void
6307our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) 6301our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6308{ 6302{
6309 struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src; 6303 struct jpeg_source_mgr *src = cinfo->src;
6310 6304
6311 if (src) 6305 if (src)
6312 { 6306 {
@@ -6326,19 +6320,17 @@ our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6326static void 6320static void
6327jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len) 6321jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
6328{ 6322{
6329 struct jpeg_source_mgr *src; 6323 struct jpeg_source_mgr *src = cinfo->src;
6330 6324
6331 if (cinfo->src == NULL) 6325 if (! src)
6332 { 6326 {
6333 /* First time for this JPEG object? */ 6327 /* First time for this JPEG object? */
6334 cinfo->src = (struct jpeg_source_mgr *) 6328 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6335 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 6329 JPOOL_PERMANENT, sizeof *src);
6336 sizeof (struct jpeg_source_mgr)); 6330 cinfo->src = src;
6337 src = (struct jpeg_source_mgr *) cinfo->src;
6338 src->next_input_byte = data; 6331 src->next_input_byte = data;
6339 } 6332 }
6340 6333
6341 src = (struct jpeg_source_mgr *) cinfo->src;
6342 src->init_source = our_common_init_source; 6334 src->init_source = our_common_init_source;
6343 src->fill_input_buffer = our_memory_fill_input_buffer; 6335 src->fill_input_buffer = our_memory_fill_input_buffer;
6344 src->skip_input_data = our_memory_skip_input_data; 6336 src->skip_input_data = our_memory_skip_input_data;
@@ -6430,20 +6422,17 @@ our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
6430static void 6422static void
6431jpeg_file_src (j_decompress_ptr cinfo, FILE *fp) 6423jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
6432{ 6424{
6433 struct jpeg_stdio_mgr *src; 6425 struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src;
6434 6426
6435 if (cinfo->src != NULL) 6427 if (! src)
6436 src = (struct jpeg_stdio_mgr *) cinfo->src;
6437 else
6438 { 6428 {
6439 /* First time for this JPEG object? */ 6429 /* First time for this JPEG object? */
6440 cinfo->src = (struct jpeg_source_mgr *) 6430 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6441 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 6431 JPOOL_PERMANENT, sizeof *src);
6442 sizeof (struct jpeg_stdio_mgr)); 6432 cinfo->src = (struct jpeg_source_mgr *) src;
6443 src = (struct jpeg_stdio_mgr *) cinfo->src; 6433 src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
6444 src->buffer = (JOCTET *) 6434 JPOOL_PERMANENT,
6445 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 6435 JPEG_STDIO_BUFFER_SIZE);
6446 JPEG_STDIO_BUFFER_SIZE);
6447 } 6436 }
6448 6437
6449 src->file = fp; 6438 src->file = fp;
@@ -7746,6 +7735,7 @@ enum imagemagick_keyword_index
7746 IMAGEMAGICK_WIDTH, 7735 IMAGEMAGICK_WIDTH,
7747 IMAGEMAGICK_MAX_HEIGHT, 7736 IMAGEMAGICK_MAX_HEIGHT,
7748 IMAGEMAGICK_MAX_WIDTH, 7737 IMAGEMAGICK_MAX_WIDTH,
7738 IMAGEMAGICK_FORMAT,
7749 IMAGEMAGICK_ROTATION, 7739 IMAGEMAGICK_ROTATION,
7750 IMAGEMAGICK_CROP, 7740 IMAGEMAGICK_CROP,
7751 IMAGEMAGICK_LAST 7741 IMAGEMAGICK_LAST
@@ -7770,6 +7760,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7770 {":width", IMAGE_INTEGER_VALUE, 0}, 7760 {":width", IMAGE_INTEGER_VALUE, 0},
7771 {":max-height", IMAGE_INTEGER_VALUE, 0}, 7761 {":max-height", IMAGE_INTEGER_VALUE, 0},
7772 {":max-width", IMAGE_INTEGER_VALUE, 0}, 7762 {":max-width", IMAGE_INTEGER_VALUE, 0},
7763 {":format", IMAGE_SYMBOL_VALUE, 0},
7773 {":rotation", IMAGE_NUMBER_VALUE, 0}, 7764 {":rotation", IMAGE_NUMBER_VALUE, 0},
7774 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} 7765 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7775 }; 7766 };
@@ -7848,6 +7839,233 @@ imagemagick_error (MagickWand *wand)
7848 description = (char *) MagickRelinquishMemory (description); 7839 description = (char *) MagickRelinquishMemory (description);
7849} 7840}
7850 7841
7842/* Possibly give ImageMagick some extra help to determine the image
7843 type by supplying a "dummy" filename based on the Content-Type. */
7844
7845static char *
7846imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
7847{
7848 Lisp_Object symbol = intern ("image-format-suffixes");
7849 Lisp_Object val = find_symbol_value (symbol);
7850 Lisp_Object format;
7851
7852 if (! CONSP (val))
7853 return NULL;
7854
7855 format = image_spec_value (spec, intern (":format"), NULL);
7856 val = Fcar_safe (Fcdr_safe (Fassq (format, val)));
7857 if (! STRINGP (val))
7858 return NULL;
7859
7860 /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
7861 as ImageMagick would ignore the extra bytes anyway. */
7862 snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val));
7863 return hint_buffer;
7864}
7865
7866/* Animated images (e.g., GIF89a) are composed from one "master image"
7867 (which is the first one, and then there's a number of images that
7868 follow. If following images have non-transparent colors, these are
7869 composed "on top" of the master image. So, in general, one has to
7870 compute ann the preceding images to be able to display a particular
7871 sub-image.
7872
7873 Computing all the preceding images is too slow, so we maintain a
7874 cache of previously computed images. We have to maintain a cache
7875 separate from the image cache, because the images may be scaled
7876 before display. */
7877
7878struct animation_cache
7879{
7880 MagickWand *wand;
7881 int index;
7882 struct timespec update_time;
7883 struct animation_cache *next;
7884 char signature[FLEXIBLE_ARRAY_MEMBER];
7885};
7886
7887static struct animation_cache *animation_cache = NULL;
7888
7889static struct animation_cache *
7890imagemagick_create_cache (char *signature)
7891{
7892 struct animation_cache *cache
7893 = xmalloc (offsetof (struct animation_cache, signature)
7894 + strlen (signature) + 1);
7895 cache->wand = 0;
7896 cache->index = 0;
7897 cache->next = 0;
7898 strcpy (cache->signature, signature);
7899 return cache;
7900}
7901
7902/* Discard cached images that haven't been used for a minute. */
7903static void
7904imagemagick_prune_animation_cache (void)
7905{
7906 struct animation_cache **pcache = &animation_cache;
7907 struct timespec old = timespec_sub (current_timespec (),
7908 make_timespec (60, 0));
7909
7910 while (*pcache)
7911 {
7912 struct animation_cache *cache = *pcache;
7913 if (timespec_cmp (old, cache->update_time) <= 0)
7914 pcache = &cache->next;
7915 else
7916 {
7917 if (cache->wand)
7918 DestroyMagickWand (cache->wand);
7919 *pcache = cache->next;
7920 xfree (cache);
7921 }
7922 }
7923}
7924
7925static struct animation_cache *
7926imagemagick_get_animation_cache (MagickWand *wand)
7927{
7928 char *signature = MagickGetImageSignature (wand);
7929 struct animation_cache *cache;
7930 struct animation_cache **pcache = &animation_cache;
7931
7932 imagemagick_prune_animation_cache ();
7933
7934 while (1)
7935 {
7936 cache = *pcache;
7937 if (! cache)
7938 {
7939 *pcache = cache = imagemagick_create_cache (signature);
7940 break;
7941 }
7942 if (strcmp (signature, cache->signature) == 0)
7943 break;
7944 pcache = &cache->next;
7945 }
7946
7947 DestroyString (signature);
7948 cache->update_time = current_timespec ();
7949 return cache;
7950}
7951
7952static MagickWand *
7953imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
7954{
7955 int i;
7956 MagickWand *composite_wand;
7957 size_t dest_width, dest_height;
7958 struct animation_cache *cache = imagemagick_get_animation_cache (super_wand);
7959
7960 MagickSetIteratorIndex (super_wand, 0);
7961
7962 if (ino == 0 || cache->wand == NULL || cache->index > ino)
7963 {
7964 composite_wand = MagickGetImage (super_wand);
7965 if (cache->wand)
7966 DestroyMagickWand (cache->wand);
7967 }
7968 else
7969 composite_wand = cache->wand;
7970
7971 dest_width = MagickGetImageWidth (composite_wand);
7972 dest_height = MagickGetImageHeight (composite_wand);
7973
7974 for (i = max (1, cache->index + 1); i <= ino; i++)
7975 {
7976 MagickWand *sub_wand;
7977 PixelIterator *source_iterator, *dest_iterator;
7978 PixelWand **source, **dest;
7979 size_t source_width, source_height;
7980 ssize_t source_left, source_top;
7981 MagickPixelPacket pixel;
7982 DisposeType dispose;
7983 ptrdiff_t lines = 0;
7984
7985 MagickSetIteratorIndex (super_wand, i);
7986 sub_wand = MagickGetImage (super_wand);
7987
7988 MagickGetImagePage (sub_wand, &source_width, &source_height,
7989 &source_left, &source_top);
7990
7991 /* This flag says how to handle transparent pixels. */
7992 dispose = MagickGetImageDispose (sub_wand);
7993
7994 source_iterator = NewPixelIterator (sub_wand);
7995 if (! source_iterator)
7996 {
7997 DestroyMagickWand (composite_wand);
7998 DestroyMagickWand (sub_wand);
7999 cache->wand = NULL;
8000 image_error ("Imagemagick pixel iterator creation failed",
8001 Qnil, Qnil);
8002 return NULL;
8003 }
8004
8005 dest_iterator = NewPixelIterator (composite_wand);
8006 if (! dest_iterator)
8007 {
8008 DestroyMagickWand (composite_wand);
8009 DestroyMagickWand (sub_wand);
8010 DestroyPixelIterator (source_iterator);
8011 cache->wand = NULL;
8012 image_error ("Imagemagick pixel iterator creation failed",
8013 Qnil, Qnil);
8014 return NULL;
8015 }
8016
8017 /* The sub-image may not start at origin, so move the destination
8018 iterator to where the sub-image should start. */
8019 if (source_top > 0)
8020 {
8021 PixelSetIteratorRow (dest_iterator, source_top);
8022 lines = source_top;
8023 }
8024
8025 while ((source = PixelGetNextIteratorRow (source_iterator, &source_width))
8026 != NULL)
8027 {
8028 ptrdiff_t x;
8029
8030 /* Sanity check. This shouldn't happen, but apparently
8031 does in some pictures. */
8032 if (++lines >= dest_height)
8033 break;
8034
8035 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width);
8036 for (x = 0; x < source_width; x++)
8037 {
8038 /* Sanity check. This shouldn't happen, but apparently
8039 also does in some pictures. */
8040 if (x + source_left > dest_width)
8041 break;
8042 /* Normally we only copy over non-transparent pixels,
8043 but if the disposal method is "Background", then we
8044 copy over all pixels. */
8045 if (dispose == BackgroundDispose ||
8046 PixelGetAlpha (source[x]))
8047 {
8048 PixelGetMagickColor (source[x], &pixel);
8049 PixelSetMagickColor (dest[x + source_left], &pixel);
8050 }
8051 }
8052 PixelSyncIterator (dest_iterator);
8053 }
8054
8055 DestroyPixelIterator (source_iterator);
8056 DestroyPixelIterator (dest_iterator);
8057 DestroyMagickWand (sub_wand);
8058 }
8059
8060 /* Cache a copy for the next iteration. The current wand will be
8061 destroyed by the caller. */
8062 cache->wand = CloneMagickWand (composite_wand);
8063 cache->index = ino;
8064
8065 return composite_wand;
8066}
8067
8068
7851/* Helper function for imagemagick_load, which does the actual loading 8069/* Helper function for imagemagick_load, which does the actual loading
7852 given contents and size, apart from frame and image structures, 8070 given contents and size, apart from frame and image structures,
7853 passed from imagemagick_load. Uses librimagemagick to do most of 8071 passed from imagemagick_load. Uses librimagemagick to do most of
@@ -7870,7 +8088,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
7870 XImagePtr ximg; 8088 XImagePtr ximg;
7871 int x, y; 8089 int x, y;
7872 MagickWand *image_wand; 8090 MagickWand *image_wand;
7873 MagickWand *ping_wand;
7874 PixelIterator *iterator; 8091 PixelIterator *iterator;
7875 PixelWand **pixels, *bg_wand = NULL; 8092 PixelWand **pixels, *bg_wand = NULL;
7876 MagickPixelPacket pixel; 8093 MagickPixelPacket pixel;
@@ -7881,6 +8098,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7881 int desired_width, desired_height; 8098 int desired_width, desired_height;
7882 double rotation; 8099 double rotation;
7883 int pixelwidth; 8100 int pixelwidth;
8101 char hint_buffer[MaxTextExtent];
8102 char *filename_hint = NULL;
7884 8103
7885 /* Handle image index for image types who can contain more than one image. 8104 /* Handle image index for image types who can contain more than one image.
7886 Interface :index is same as for GIF. First we "ping" the image to see how 8105 Interface :index is same as for GIF. First we "ping" the image to see how
@@ -7891,48 +8110,48 @@ imagemagick_load_image (struct frame *f, struct image *img,
7891 MagickWandGenesis (); 8110 MagickWandGenesis ();
7892 image = image_spec_value (img->spec, QCindex, NULL); 8111 image = image_spec_value (img->spec, QCindex, NULL);
7893 ino = INTEGERP (image) ? XFASTINT (image) : 0; 8112 ino = INTEGERP (image) ? XFASTINT (image) : 0;
7894 ping_wand = NewMagickWand (); 8113 image_wand = NewMagickWand ();
7895 /* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
7896 8114
7897 status = filename 8115 if (filename)
7898 ? MagickPingImage (ping_wand, filename) 8116 status = MagickReadImage (image_wand, filename);
7899 : MagickPingImageBlob (ping_wand, contents, size); 8117 else
8118 {
8119 filename_hint = imagemagick_filename_hint (img->spec, hint_buffer);
8120 MagickSetFilename (image_wand, filename_hint);
8121 status = MagickReadImageBlob (image_wand, contents, size);
8122 }
7900 8123
7901 if (status == MagickFalse) 8124 if (status == MagickFalse)
7902 { 8125 {
7903 imagemagick_error (ping_wand); 8126 imagemagick_error (image_wand);
7904 DestroyMagickWand (ping_wand); 8127 DestroyMagickWand (image_wand);
7905 return 0; 8128 return 0;
7906 } 8129 }
7907 8130
7908 if (ino < 0 || ino >= MagickGetNumberImages (ping_wand)) 8131 if (ino < 0 || ino >= MagickGetNumberImages (image_wand))
7909 { 8132 {
7910 image_error ("Invalid image number `%s' in image `%s'", 8133 image_error ("Invalid image number `%s' in image `%s'",
7911 image, img->spec); 8134 image, img->spec);
7912 DestroyMagickWand (ping_wand); 8135 DestroyMagickWand (image_wand);
7913 return 0; 8136 return 0;
7914 } 8137 }
7915 8138
7916 if (MagickGetNumberImages (ping_wand) > 1) 8139 if (MagickGetNumberImages (image_wand) > 1)
7917 img->lisp_data = 8140 img->lisp_data =
7918 Fcons (Qcount, 8141 Fcons (Qcount,
7919 Fcons (make_number (MagickGetNumberImages (ping_wand)), 8142 Fcons (make_number (MagickGetNumberImages (image_wand)),
7920 img->lisp_data)); 8143 img->lisp_data));
7921 8144
7922 DestroyMagickWand (ping_wand); 8145 /* If we have an animated image, get the new wand based on the
7923 8146 "super-wand". */
7924 /* Now we know how many images are inside the file. If it's not a 8147 if (MagickGetNumberImages (image_wand) > 1)
7925 bundle, the number is one. Load the image data. */
7926
7927 image_wand = NewMagickWand ();
7928
7929 if ((filename
7930 ? MagickReadImage (image_wand, filename)
7931 : MagickReadImageBlob (image_wand, contents, size))
7932 == MagickFalse)
7933 { 8148 {
7934 imagemagick_error (image_wand); 8149 MagickWand *super_wand = image_wand;
7935 goto imagemagick_error; 8150 image_wand = imagemagick_compute_animated_image (super_wand, ino);
8151 if (! image_wand)
8152 image_wand = super_wand;
8153 else
8154 DestroyMagickWand (super_wand);
7936 } 8155 }
7937 8156
7938 /* Retrieve the frame's background color, for use later. */ 8157 /* Retrieve the frame's background color, for use later. */
@@ -8120,7 +8339,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8120 8339
8121 /* Copy pixels from the imagemagick image structure to the x image map. */ 8340 /* Copy pixels from the imagemagick image structure to the x image map. */
8122 iterator = NewPixelIterator (image_wand); 8341 iterator = NewPixelIterator (image_wand);
8123 if (iterator == (PixelIterator *) NULL) 8342 if (! iterator)
8124 { 8343 {
8125#ifdef COLOR_TABLE_SUPPORT 8344#ifdef COLOR_TABLE_SUPPORT
8126 free_color_table (); 8345 free_color_table ();
@@ -8135,7 +8354,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8135 for (y = 0; y < image_height; y++) 8354 for (y = 0; y < image_height; y++)
8136 { 8355 {
8137 pixels = PixelGetNextIteratorRow (iterator, &width); 8356 pixels = PixelGetNextIteratorRow (iterator, &width);
8138 if (pixels == (PixelWand **) NULL) 8357 if (! pixels)
8139 break; 8358 break;
8140 for (x = 0; x < (long) width; x++) 8359 for (x = 0; x < (long) width; x++)
8141 { 8360 {
@@ -9200,7 +9419,7 @@ A cross is always drawn on black & white displays. */);
9200 9419
9201 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path, 9420 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
9202 doc: /* List of directories to search for window system bitmap files. */); 9421 doc: /* List of directories to search for window system bitmap files. */);
9203 Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); 9422 Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS);
9204 9423
9205 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay, 9424 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
9206 doc: /* Maximum time after which images are removed from the cache. 9425 doc: /* Maximum time after which images are removed from the cache.
diff --git a/src/indent.c b/src/indent.c
index 47358e17db8..891b42788ed 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -141,13 +141,13 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab)
141 XSETFASTINT (widthtab->contents[i], character_width (i, disptab)); 141 XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
142} 142}
143 143
144/* Allocate or free the width run cache, as requested by the current 144/* Allocate or free the width run cache, as requested by the
145 state of current_buffer's cache_long_line_scans variable. */ 145 current state of current_buffer's cache_long_scans variable. */
146 146
147static void 147static void
148width_run_cache_on_off (void) 148width_run_cache_on_off (void)
149{ 149{
150 if (NILP (BVAR (current_buffer, cache_long_line_scans)) 150 if (NILP (BVAR (current_buffer, cache_long_scans))
151 /* And, for the moment, this feature doesn't work on multibyte 151 /* And, for the moment, this feature doesn't work on multibyte
152 characters. */ 152 characters. */
153 || !NILP (BVAR (current_buffer, enable_multibyte_characters))) 153 || !NILP (BVAR (current_buffer, enable_multibyte_characters)))
@@ -510,15 +510,10 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol)
510 register ptrdiff_t col = 0, prev_col = 0; 510 register ptrdiff_t col = 0, prev_col = 0;
511 EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM; 511 EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM;
512 ptrdiff_t end = endpos ? *endpos : PT; 512 ptrdiff_t end = endpos ? *endpos : PT;
513 ptrdiff_t scan, scan_byte; 513 ptrdiff_t scan, scan_byte, next_boundary;
514 ptrdiff_t next_boundary; 514
515 { 515 scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1);
516 ptrdiff_t opoint = PT, opoint_byte = PT_BYTE;
517 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
518 scan = PT, scan_byte = PT_BYTE;
519 SET_PT_BOTH (opoint, opoint_byte);
520 next_boundary = scan; 516 next_boundary = scan;
521 }
522 517
523 window = Fget_buffer_window (Fcurrent_buffer (), Qnil); 518 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
524 w = ! NILP (window) ? XWINDOW (window) : NULL; 519 w = ! NILP (window) ? XWINDOW (window) : NULL;
@@ -835,14 +830,10 @@ This is the horizontal position of the character
835following any initial whitespace. */) 830following any initial whitespace. */)
836 (void) 831 (void)
837{ 832{
838 Lisp_Object val; 833 ptrdiff_t posbyte;
839 ptrdiff_t opoint = PT, opoint_byte = PT_BYTE;
840
841 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
842 834
843 XSETFASTINT (val, position_indentation (PT_BYTE)); 835 find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &posbyte, 1);
844 SET_PT_BOTH (opoint, opoint_byte); 836 return make_number (position_indentation (posbyte));
845 return val;
846} 837}
847 838
848static ptrdiff_t 839static ptrdiff_t
@@ -935,16 +926,13 @@ position_indentation (ptrdiff_t pos_byte)
935bool 926bool
936indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column) 927indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column)
937{ 928{
938 ptrdiff_t val; 929 while (pos > BEGV && FETCH_BYTE (pos_byte) == '\n')
939 ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; 930 {
940 931 DEC_BOTH (pos, pos_byte);
941 SET_PT_BOTH (pos, pos_byte); 932 pos = find_newline (pos, pos_byte, BEGV, BEGV_BYTE,
942 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n') 933 -1, NULL, &pos_byte, 0);
943 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0); 934 }
944 935 return position_indentation (pos_byte) >= column;
945 val = position_indentation (PT_BYTE);
946 SET_PT_BOTH (opoint, opoint_byte);
947 return val >= column;
948} 936}
949 937
950DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, 938DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2,
diff --git a/src/insdel.c b/src/insdel.c
index 58c3e15c233..f746fd34330 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1756,27 +1756,22 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
1756 return deletion; 1756 return deletion;
1757} 1757}
1758 1758
1759/* Call this if you're about to change the region of current buffer 1759/* Call this if you're about to change the text of current buffer
1760 from character positions START to END. This checks the read-only 1760 from character positions START to END. This checks the read-only
1761 properties of the region, calls the necessary modification hooks, 1761 properties of the region, calls the necessary modification hooks,
1762 and warns the next redisplay that it should pay attention to that 1762 and warns the next redisplay that it should pay attention to that
1763 area. 1763 area. */
1764
1765 If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF.
1766 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1767 1764
1768void 1765void
1769modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) 1766modify_text (ptrdiff_t start, ptrdiff_t end)
1770{ 1767{
1771 prepare_to_modify_buffer (start, end, NULL); 1768 prepare_to_modify_buffer (start, end, NULL);
1772 1769
1773 BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); 1770 BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end);
1774
1775 if (MODIFF <= SAVE_MODIFF) 1771 if (MODIFF <= SAVE_MODIFF)
1776 record_first_change (); 1772 record_first_change ();
1777 MODIFF++; 1773 MODIFF++;
1778 if (! preserve_chars_modiff) 1774 CHARS_MODIFF = MODIFF;
1779 CHARS_MODIFF = MODIFF;
1780 1775
1781 bset_point_before_scroll (current_buffer, Qnil); 1776 bset_point_before_scroll (current_buffer, Qnil);
1782} 1777}
@@ -1792,8 +1787,8 @@ modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff)
1792 by holding its value temporarily in a marker. */ 1787 by holding its value temporarily in a marker. */
1793 1788
1794void 1789void
1795prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, 1790prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
1796 ptrdiff_t *preserve_ptr) 1791 ptrdiff_t *preserve_ptr)
1797{ 1792{
1798 struct buffer *base_buffer; 1793 struct buffer *base_buffer;
1799 1794
@@ -1864,6 +1859,17 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1864 } 1859 }
1865 1860
1866 signal_before_change (start, end, preserve_ptr); 1861 signal_before_change (start, end, preserve_ptr);
1862 Vdeactivate_mark = Qt;
1863}
1864
1865/* Like above, but called when we know that the buffer text
1866 will be modified and region caches should be invalidated. */
1867
1868void
1869prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1870 ptrdiff_t *preserve_ptr)
1871{
1872 prepare_to_modify_buffer_1 (start, end, preserve_ptr);
1867 1873
1868 if (current_buffer->newline_cache) 1874 if (current_buffer->newline_cache)
1869 invalidate_region_cache (current_buffer, 1875 invalidate_region_cache (current_buffer,
@@ -1873,10 +1879,12 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1873 invalidate_region_cache (current_buffer, 1879 invalidate_region_cache (current_buffer,
1874 current_buffer->width_run_cache, 1880 current_buffer->width_run_cache,
1875 start - BEG, Z - end); 1881 start - BEG, Z - end);
1876 1882 if (current_buffer->bidi_paragraph_cache)
1877 Vdeactivate_mark = Qt; 1883 invalidate_region_cache (current_buffer,
1884 current_buffer->bidi_paragraph_cache,
1885 start - BEG, Z - end);
1878} 1886}
1879 1887
1880/* These macros work with an argument named `preserve_ptr' 1888/* These macros work with an argument named `preserve_ptr'
1881 and a local variable named `preserve_marker'. */ 1889 and a local variable named `preserve_marker'. */
1882 1890
diff --git a/src/intervals.c b/src/intervals.c
index f2ddcd01507..ded536ca3c8 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -1821,6 +1821,18 @@ set_point (ptrdiff_t charpos)
1821 set_point_both (charpos, buf_charpos_to_bytepos (current_buffer, charpos)); 1821 set_point_both (charpos, buf_charpos_to_bytepos (current_buffer, charpos));
1822} 1822}
1823 1823
1824/* Set PT from MARKER's clipped position. */
1825
1826void
1827set_point_from_marker (Lisp_Object marker)
1828{
1829 if (XMARKER (marker)->buffer != current_buffer)
1830 signal_error ("Marker points into wrong buffer", marker);
1831 set_point_both
1832 (clip_to_bounds (BEGV, marker_position (marker), ZV),
1833 clip_to_bounds (BEGV_BYTE, marker_byte_position (marker), ZV_BYTE));
1834}
1835
1824/* If there's an invisible character at position POS + TEST_OFFS in the 1836/* If there's an invisible character at position POS + TEST_OFFS in the
1825 current buffer, and the invisible property has a `stickiness' such that 1837 current buffer, and the invisible property has a `stickiness' such that
1826 inserting a character at position POS would inherit the property it, 1838 inserting a character at position POS would inherit the property it,
diff --git a/src/keyboard.c b/src/keyboard.c
index c026b16e689..b8e05cf7925 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -360,7 +360,7 @@ Lisp_Object Qmenu_bar;
360static void recursive_edit_unwind (Lisp_Object buffer); 360static void recursive_edit_unwind (Lisp_Object buffer);
361static Lisp_Object command_loop (void); 361static Lisp_Object command_loop (void);
362static Lisp_Object Qcommand_execute; 362static Lisp_Object Qcommand_execute;
363EMACS_TIME timer_check (void); 363struct timespec timer_check (void);
364 364
365static void echo_now (void); 365static void echo_now (void);
366static ptrdiff_t echo_length (void); 366static ptrdiff_t echo_length (void);
@@ -370,9 +370,9 @@ static Lisp_Object Qpolling_period;
370/* Incremented whenever a timer is run. */ 370/* Incremented whenever a timer is run. */
371unsigned timers_run; 371unsigned timers_run;
372 372
373/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt 373/* Address (if not 0) of struct timespec to zero out if a SIGIO interrupt
374 happens. */ 374 happens. */
375EMACS_TIME *input_available_clear_time; 375struct timespec *input_available_clear_time;
376 376
377/* True means use SIGIO interrupts; false means use CBREAK mode. 377/* True means use SIGIO interrupts; false means use CBREAK mode.
378 Default is true if INTERRUPT_INPUT is defined. */ 378 Default is true if INTERRUPT_INPUT is defined. */
@@ -389,12 +389,12 @@ bool interrupts_deferred;
389 389
390/* The time when Emacs started being idle. */ 390/* The time when Emacs started being idle. */
391 391
392static EMACS_TIME timer_idleness_start_time; 392static struct timespec timer_idleness_start_time;
393 393
394/* After Emacs stops being idle, this saves the last value 394/* After Emacs stops being idle, this saves the last value
395 of timer_idleness_start_time from when it was idle. */ 395 of timer_idleness_start_time from when it was idle. */
396 396
397static EMACS_TIME timer_last_idleness_start_time; 397static struct timespec timer_last_idleness_start_time;
398 398
399 399
400/* Global variable declarations. */ 400/* Global variable declarations. */
@@ -1986,10 +1986,10 @@ start_polling (void)
1986 /* If poll timer doesn't exist, are we need one with 1986 /* If poll timer doesn't exist, are we need one with
1987 a different interval, start a new one. */ 1987 a different interval, start a new one. */
1988 if (poll_timer == NULL 1988 if (poll_timer == NULL
1989 || EMACS_SECS (poll_timer->interval) != polling_period) 1989 || poll_timer->interval.tv_sec != polling_period)
1990 { 1990 {
1991 time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t))); 1991 time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
1992 EMACS_TIME interval = make_emacs_time (period, 0); 1992 struct timespec interval = make_timespec (period, 0);
1993 1993
1994 if (poll_timer) 1994 if (poll_timer)
1995 cancel_atimer (poll_timer); 1995 cancel_atimer (poll_timer);
@@ -2182,7 +2182,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
2182/* Input of single characters from keyboard */ 2182/* Input of single characters from keyboard */
2183 2183
2184static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu, 2184static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
2185 EMACS_TIME *end_time); 2185 struct timespec *end_time);
2186static void record_char (Lisp_Object c); 2186static void record_char (Lisp_Object c);
2187 2187
2188static Lisp_Object help_form_saved_window_configs; 2188static Lisp_Object help_form_saved_window_configs;
@@ -2204,7 +2204,7 @@ do { if (polling_stopped_here) start_polling (); \
2204 polling_stopped_here = 0; } while (0) 2204 polling_stopped_here = 0; } while (0)
2205 2205
2206static Lisp_Object 2206static Lisp_Object
2207read_event_from_main_queue (EMACS_TIME *end_time, 2207read_event_from_main_queue (struct timespec *end_time,
2208 sys_jmp_buf local_getcjmp, 2208 sys_jmp_buf local_getcjmp,
2209 bool *used_mouse_menu) 2209 bool *used_mouse_menu)
2210{ 2210{
@@ -2217,7 +2217,7 @@ read_event_from_main_queue (EMACS_TIME *end_time,
2217 /* Read from the main queue, and if that gives us something we can't use yet, 2217 /* Read from the main queue, and if that gives us something we can't use yet,
2218 we put it on the appropriate side queue and try again. */ 2218 we put it on the appropriate side queue and try again. */
2219 2219
2220 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) 2220 if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0)
2221 return c; 2221 return c;
2222 2222
2223 /* Actually read a character, waiting if necessary. */ 2223 /* Actually read a character, waiting if necessary. */
@@ -2278,7 +2278,7 @@ read_event_from_main_queue (EMACS_TIME *end_time,
2278/* Like `read_event_from_main_queue' but applies keyboard-coding-system 2278/* Like `read_event_from_main_queue' but applies keyboard-coding-system
2279 to tty input. */ 2279 to tty input. */
2280static Lisp_Object 2280static Lisp_Object
2281read_decoded_event_from_main_queue (EMACS_TIME *end_time, 2281read_decoded_event_from_main_queue (struct timespec *end_time,
2282 sys_jmp_buf local_getcjmp, 2282 sys_jmp_buf local_getcjmp,
2283 Lisp_Object prev_event, 2283 Lisp_Object prev_event,
2284 bool *used_mouse_menu) 2284 bool *used_mouse_menu)
@@ -2376,7 +2376,7 @@ read_decoded_event_from_main_queue (EMACS_TIME *end_time,
2376 Value is -2 when we find input on another keyboard. A second call 2376 Value is -2 when we find input on another keyboard. A second call
2377 to read_char will read it. 2377 to read_char will read it.
2378 2378
2379 If END_TIME is non-null, it is a pointer to an EMACS_TIME 2379 If END_TIME is non-null, it is a pointer to a struct timespec
2380 specifying the maximum time to wait until. If no input arrives by 2380 specifying the maximum time to wait until. If no input arrives by
2381 that time, stop waiting and return nil. 2381 that time, stop waiting and return nil.
2382 2382
@@ -2385,7 +2385,7 @@ read_decoded_event_from_main_queue (EMACS_TIME *end_time,
2385Lisp_Object 2385Lisp_Object
2386read_char (int commandflag, Lisp_Object map, 2386read_char (int commandflag, Lisp_Object map,
2387 Lisp_Object prev_event, 2387 Lisp_Object prev_event,
2388 bool *used_mouse_menu, EMACS_TIME *end_time) 2388 bool *used_mouse_menu, struct timespec *end_time)
2389{ 2389{
2390 Lisp_Object c; 2390 Lisp_Object c;
2391 ptrdiff_t jmpcount; 2391 ptrdiff_t jmpcount;
@@ -2877,7 +2877,7 @@ read_char (int commandflag, Lisp_Object map,
2877 { 2877 {
2878 c = read_decoded_event_from_main_queue (end_time, local_getcjmp, 2878 c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
2879 prev_event, used_mouse_menu); 2879 prev_event, used_mouse_menu);
2880 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) 2880 if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0)
2881 goto exit; 2881 goto exit;
2882 if (EQ (c, make_number (-2))) 2882 if (EQ (c, make_number (-2)))
2883 { 2883 {
@@ -3798,7 +3798,7 @@ clear_event (struct input_event *event)
3798static Lisp_Object 3798static Lisp_Object
3799kbd_buffer_get_event (KBOARD **kbp, 3799kbd_buffer_get_event (KBOARD **kbp,
3800 bool *used_mouse_menu, 3800 bool *used_mouse_menu,
3801 EMACS_TIME *end_time) 3801 struct timespec *end_time)
3802{ 3802{
3803 Lisp_Object obj; 3803 Lisp_Object obj;
3804 3804
@@ -3856,15 +3856,15 @@ kbd_buffer_get_event (KBOARD **kbp,
3856 break; 3856 break;
3857 if (end_time) 3857 if (end_time)
3858 { 3858 {
3859 EMACS_TIME now = current_emacs_time (); 3859 struct timespec now = current_timespec ();
3860 if (EMACS_TIME_LE (*end_time, now)) 3860 if (timespec_cmp (*end_time, now) <= 0)
3861 return Qnil; /* Finished waiting. */ 3861 return Qnil; /* Finished waiting. */
3862 else 3862 else
3863 { 3863 {
3864 EMACS_TIME duration = sub_emacs_time (*end_time, now); 3864 struct timespec duration = timespec_sub (*end_time, now);
3865 wait_reading_process_output (min (EMACS_SECS (duration), 3865 wait_reading_process_output (min (duration.tv_sec,
3866 WAIT_READING_MAX), 3866 WAIT_READING_MAX),
3867 EMACS_NSECS (duration), 3867 duration.tv_nsec,
3868 -1, 1, Qnil, NULL, 0); 3868 -1, 1, Qnil, NULL, 0);
3869 } 3869 }
3870 } 3870 }
@@ -4295,10 +4295,10 @@ static void
4295timer_start_idle (void) 4295timer_start_idle (void)
4296{ 4296{
4297 /* If we are already in the idle state, do nothing. */ 4297 /* If we are already in the idle state, do nothing. */
4298 if (EMACS_TIME_VALID_P (timer_idleness_start_time)) 4298 if (timespec_valid_p (timer_idleness_start_time))
4299 return; 4299 return;
4300 4300
4301 timer_idleness_start_time = current_emacs_time (); 4301 timer_idleness_start_time = current_timespec ();
4302 timer_last_idleness_start_time = timer_idleness_start_time; 4302 timer_last_idleness_start_time = timer_idleness_start_time;
4303 4303
4304 /* Mark all idle-time timers as once again candidates for running. */ 4304 /* Mark all idle-time timers as once again candidates for running. */
@@ -4310,7 +4310,7 @@ timer_start_idle (void)
4310static void 4310static void
4311timer_stop_idle (void) 4311timer_stop_idle (void)
4312{ 4312{
4313 timer_idleness_start_time = invalid_emacs_time (); 4313 timer_idleness_start_time = invalid_timespec ();
4314} 4314}
4315 4315
4316/* Resume idle timer from last idle start time. */ 4316/* Resume idle timer from last idle start time. */
@@ -4318,7 +4318,7 @@ timer_stop_idle (void)
4318static void 4318static void
4319timer_resume_idle (void) 4319timer_resume_idle (void)
4320{ 4320{
4321 if (EMACS_TIME_VALID_P (timer_idleness_start_time)) 4321 if (timespec_valid_p (timer_idleness_start_time))
4322 return; 4322 return;
4323 4323
4324 timer_idleness_start_time = timer_last_idleness_start_time; 4324 timer_idleness_start_time = timer_last_idleness_start_time;
@@ -4334,7 +4334,7 @@ Lisp_Object pending_funcalls;
4334 4334
4335/* Return true if TIMER is a valid timer, placing its value into *RESULT. */ 4335/* Return true if TIMER is a valid timer, placing its value into *RESULT. */
4336static bool 4336static bool
4337decode_timer (Lisp_Object timer, EMACS_TIME *result) 4337decode_timer (Lisp_Object timer, struct timespec *result)
4338{ 4338{
4339 Lisp_Object *vector; 4339 Lisp_Object *vector;
4340 4340
@@ -4361,16 +4361,16 @@ decode_timer (Lisp_Object timer, EMACS_TIME *result)
4361 In that case we return 0 to indicate that a new timer_check_2 call 4361 In that case we return 0 to indicate that a new timer_check_2 call
4362 should be done. */ 4362 should be done. */
4363 4363
4364static EMACS_TIME 4364static struct timespec
4365timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers) 4365timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4366{ 4366{
4367 EMACS_TIME nexttime; 4367 struct timespec nexttime;
4368 EMACS_TIME now; 4368 struct timespec now;
4369 EMACS_TIME idleness_now; 4369 struct timespec idleness_now;
4370 Lisp_Object chosen_timer; 4370 Lisp_Object chosen_timer;
4371 struct gcpro gcpro1; 4371 struct gcpro gcpro1;
4372 4372
4373 nexttime = invalid_emacs_time (); 4373 nexttime = invalid_timespec ();
4374 4374
4375 chosen_timer = Qnil; 4375 chosen_timer = Qnil;
4376 GCPRO1 (chosen_timer); 4376 GCPRO1 (chosen_timer);
@@ -4385,19 +4385,19 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4385 4385
4386 if (CONSP (timers) || CONSP (idle_timers)) 4386 if (CONSP (timers) || CONSP (idle_timers))
4387 { 4387 {
4388 now = current_emacs_time (); 4388 now = current_timespec ();
4389 idleness_now = (EMACS_TIME_VALID_P (timer_idleness_start_time) 4389 idleness_now = (timespec_valid_p (timer_idleness_start_time)
4390 ? sub_emacs_time (now, timer_idleness_start_time) 4390 ? timespec_sub (now, timer_idleness_start_time)
4391 : make_emacs_time (0, 0)); 4391 : make_timespec (0, 0));
4392 } 4392 }
4393 4393
4394 while (CONSP (timers) || CONSP (idle_timers)) 4394 while (CONSP (timers) || CONSP (idle_timers))
4395 { 4395 {
4396 Lisp_Object timer = Qnil, idle_timer = Qnil; 4396 Lisp_Object timer = Qnil, idle_timer = Qnil;
4397 EMACS_TIME timer_time, idle_timer_time; 4397 struct timespec timer_time, idle_timer_time;
4398 EMACS_TIME difference; 4398 struct timespec difference;
4399 EMACS_TIME timer_difference = invalid_emacs_time (); 4399 struct timespec timer_difference = invalid_timespec ();
4400 EMACS_TIME idle_timer_difference = invalid_emacs_time (); 4400 struct timespec idle_timer_difference = invalid_timespec ();
4401 bool ripe, timer_ripe = 0, idle_timer_ripe = 0; 4401 bool ripe, timer_ripe = 0, idle_timer_ripe = 0;
4402 4402
4403 /* Set TIMER and TIMER_DIFFERENCE 4403 /* Set TIMER and TIMER_DIFFERENCE
@@ -4414,10 +4414,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4414 continue; 4414 continue;
4415 } 4415 }
4416 4416
4417 timer_ripe = EMACS_TIME_LE (timer_time, now); 4417 timer_ripe = timespec_cmp (timer_time, now) <= 0;
4418 timer_difference = (timer_ripe 4418 timer_difference = (timer_ripe
4419 ? sub_emacs_time (now, timer_time) 4419 ? timespec_sub (now, timer_time)
4420 : sub_emacs_time (timer_time, now)); 4420 : timespec_sub (timer_time, now));
4421 } 4421 }
4422 4422
4423 /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE 4423 /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
@@ -4431,26 +4431,27 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4431 continue; 4431 continue;
4432 } 4432 }
4433 4433
4434 idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now); 4434 idle_timer_ripe = timespec_cmp (idle_timer_time, idleness_now) <= 0;
4435 idle_timer_difference 4435 idle_timer_difference
4436 = (idle_timer_ripe 4436 = (idle_timer_ripe
4437 ? sub_emacs_time (idleness_now, idle_timer_time) 4437 ? timespec_sub (idleness_now, idle_timer_time)
4438 : sub_emacs_time (idle_timer_time, idleness_now)); 4438 : timespec_sub (idle_timer_time, idleness_now));
4439 } 4439 }
4440 4440
4441 /* Decide which timer is the next timer, 4441 /* Decide which timer is the next timer,
4442 and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly. 4442 and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly.
4443 Also step down the list where we found that timer. */ 4443 Also step down the list where we found that timer. */
4444 4444
4445 if (EMACS_TIME_VALID_P (timer_difference) 4445 if (timespec_valid_p (timer_difference)
4446 && (! EMACS_TIME_VALID_P (idle_timer_difference) 4446 && (! timespec_valid_p (idle_timer_difference)
4447 || idle_timer_ripe < timer_ripe 4447 || idle_timer_ripe < timer_ripe
4448 || (idle_timer_ripe == timer_ripe 4448 || (idle_timer_ripe == timer_ripe
4449 && (timer_ripe 4449 && ((timer_ripe
4450 ? EMACS_TIME_LT (idle_timer_difference, 4450 ? timespec_cmp (idle_timer_difference,
4451 timer_difference) 4451 timer_difference)
4452 : EMACS_TIME_LT (timer_difference, 4452 : timespec_cmp (timer_difference,
4453 idle_timer_difference))))) 4453 idle_timer_difference))
4454 < 0))))
4454 { 4455 {
4455 chosen_timer = timer; 4456 chosen_timer = timer;
4456 timers = XCDR (timers); 4457 timers = XCDR (timers);
@@ -4490,7 +4491,7 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4490 return 0 to indicate that. */ 4491 return 0 to indicate that. */
4491 } 4492 }
4492 4493
4493 nexttime = make_emacs_time (0, 0); 4494 nexttime = make_timespec (0, 0);
4494 break; 4495 break;
4495 } 4496 }
4496 else 4497 else
@@ -4518,10 +4519,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4518 4519
4519 As long as any timer is ripe, we run it. */ 4520 As long as any timer is ripe, we run it. */
4520 4521
4521EMACS_TIME 4522struct timespec
4522timer_check (void) 4523timer_check (void)
4523{ 4524{
4524 EMACS_TIME nexttime; 4525 struct timespec nexttime;
4525 Lisp_Object timers, idle_timers; 4526 Lisp_Object timers, idle_timers;
4526 struct gcpro gcpro1, gcpro2; 4527 struct gcpro gcpro1, gcpro2;
4527 4528
@@ -4535,7 +4536,7 @@ timer_check (void)
4535 /* Always consider the ordinary timers. */ 4536 /* Always consider the ordinary timers. */
4536 timers = Fcopy_sequence (Vtimer_list); 4537 timers = Fcopy_sequence (Vtimer_list);
4537 /* Consider the idle timers only if Emacs is idle. */ 4538 /* Consider the idle timers only if Emacs is idle. */
4538 if (EMACS_TIME_VALID_P (timer_idleness_start_time)) 4539 if (timespec_valid_p (timer_idleness_start_time))
4539 idle_timers = Fcopy_sequence (Vtimer_idle_list); 4540 idle_timers = Fcopy_sequence (Vtimer_idle_list);
4540 else 4541 else
4541 idle_timers = Qnil; 4542 idle_timers = Qnil;
@@ -4548,7 +4549,7 @@ timer_check (void)
4548 { 4549 {
4549 nexttime = timer_check_2 (timers, idle_timers); 4550 nexttime = timer_check_2 (timers, idle_timers);
4550 } 4551 }
4551 while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0); 4552 while (nexttime.tv_sec == 0 && nexttime.tv_nsec == 0);
4552 4553
4553 UNGCPRO; 4554 UNGCPRO;
4554 return nexttime; 4555 return nexttime;
@@ -4564,9 +4565,9 @@ The value when Emacs is not idle is nil.
4564PSEC is a multiple of the system clock resolution. */) 4565PSEC is a multiple of the system clock resolution. */)
4565 (void) 4566 (void)
4566{ 4567{
4567 if (EMACS_TIME_VALID_P (timer_idleness_start_time)) 4568 if (timespec_valid_p (timer_idleness_start_time))
4568 return make_lisp_time (sub_emacs_time (current_emacs_time (), 4569 return make_lisp_time (timespec_sub (current_timespec (),
4569 timer_idleness_start_time)); 4570 timer_idleness_start_time));
4570 4571
4571 return Qnil; 4572 return Qnil;
4572} 4573}
@@ -7126,7 +7127,7 @@ handle_input_available_signal (int sig)
7126 pending_signals = 1; 7127 pending_signals = 1;
7127 7128
7128 if (input_available_clear_time) 7129 if (input_available_clear_time)
7129 *input_available_clear_time = make_emacs_time (0, 0); 7130 *input_available_clear_time = make_timespec (0, 0);
7130} 7131}
7131 7132
7132static void 7133static void
@@ -7213,7 +7214,7 @@ handle_user_signal (int sig)
7213 /* Tell wait_reading_process_output that it needs to wake 7214 /* Tell wait_reading_process_output that it needs to wake
7214 up and look around. */ 7215 up and look around. */
7215 if (input_available_clear_time) 7216 if (input_available_clear_time)
7216 *input_available_clear_time = make_emacs_time (0, 0); 7217 *input_available_clear_time = make_timespec (0, 0);
7217 } 7218 }
7218 break; 7219 break;
7219 } 7220 }
@@ -8431,7 +8432,7 @@ read_char_minibuf_menu_prompt (int commandflag,
8431 return Qnil; 8432 return Qnil;
8432 8433
8433#define PUSH_C_STR(str, listvar) \ 8434#define PUSH_C_STR(str, listvar) \
8434 listvar = Fcons (make_unibyte_string (str, strlen (str)), listvar) 8435 listvar = Fcons (build_unibyte_string (str), listvar)
8435 8436
8436 /* Prompt string always starts with map's prompt, and a space. */ 8437 /* Prompt string always starts with map's prompt, and a space. */
8437 prompt_strings = Fcons (name, prompt_strings); 8438 prompt_strings = Fcons (name, prompt_strings);
@@ -10124,8 +10125,6 @@ Also end any kbd macro being defined. */)
10124 end_kbd_macro (); 10125 end_kbd_macro ();
10125 } 10126 }
10126 10127
10127 update_mode_lines++;
10128
10129 Vunread_command_events = Qnil; 10128 Vunread_command_events = Qnil;
10130 10129
10131 discard_tty_input (); 10130 discard_tty_input ();
@@ -10237,7 +10236,7 @@ stuff_buffered_input (Lisp_Object stuffstring)
10237} 10236}
10238 10237
10239void 10238void
10240set_waiting_for_input (EMACS_TIME *time_to_clear) 10239set_waiting_for_input (struct timespec *time_to_clear)
10241{ 10240{
10242 input_available_clear_time = time_to_clear; 10241 input_available_clear_time = time_to_clear;
10243 10242
@@ -10848,7 +10847,7 @@ init_keyboard (void)
10848 immediate_quit = 0; 10847 immediate_quit = 0;
10849 quit_char = Ctl ('g'); 10848 quit_char = Ctl ('g');
10850 Vunread_command_events = Qnil; 10849 Vunread_command_events = Qnil;
10851 timer_idleness_start_time = invalid_emacs_time (); 10850 timer_idleness_start_time = invalid_timespec ();
10852 total_keys = 0; 10851 total_keys = 0;
10853 recent_keys_index = 0; 10852 recent_keys_index = 0;
10854 kbd_fetch_ptr = kbd_buffer; 10853 kbd_fetch_ptr = kbd_buffer;
diff --git a/src/keyboard.h b/src/keyboard.h
index daba94898d8..1ee4a97c5c5 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -17,8 +17,9 @@ GNU General Public License for more details.
17You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20#include "systime.h" /* for EMACS_TIME, Time */ 20#include "systime.h" /* for struct timespec, Time */
21#include "coding.h" /* for ENCODE_UTF_8 and ENCODE_SYSTEM */ 21#include "coding.h" /* for ENCODE_UTF_8 and ENCODE_SYSTEM */
22#include "termhooks.h"
22 23
23INLINE_HEADER_BEGIN 24INLINE_HEADER_BEGIN
24#ifndef KEYBOARD_INLINE 25#ifndef KEYBOARD_INLINE
@@ -466,9 +467,9 @@ extern Lisp_Object Qmode_line, Qvertical_line, Qheader_line;
466/* True while doing kbd input. */ 467/* True while doing kbd input. */
467extern bool waiting_for_input; 468extern bool waiting_for_input;
468 469
469/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt 470/* Address (if not 0) of struct timespec to zero out if a SIGIO interrupt
470 happens. */ 471 happens. */
471extern EMACS_TIME *input_available_clear_time; 472extern struct timespec *input_available_clear_time;
472 473
473#if defined HAVE_WINDOW_SYSTEM && !defined USE_GTK && !defined HAVE_NS 474#if defined HAVE_WINDOW_SYSTEM && !defined USE_GTK && !defined HAVE_NS
474extern bool ignore_mouse_drag_p; 475extern bool ignore_mouse_drag_p;
@@ -477,13 +478,10 @@ extern bool ignore_mouse_drag_p;
477/* The primary selection. */ 478/* The primary selection. */
478extern Lisp_Object QPRIMARY; 479extern Lisp_Object QPRIMARY;
479 480
480/* Forward declaration for prototypes. */
481struct input_event;
482
483extern Lisp_Object parse_modifiers (Lisp_Object); 481extern Lisp_Object parse_modifiers (Lisp_Object);
484extern Lisp_Object reorder_modifiers (Lisp_Object); 482extern Lisp_Object reorder_modifiers (Lisp_Object);
485extern Lisp_Object read_char (int, Lisp_Object, Lisp_Object, 483extern Lisp_Object read_char (int, Lisp_Object, Lisp_Object,
486 bool *, EMACS_TIME *); 484 bool *, struct timespec *);
487extern int parse_solitary_modifier (Lisp_Object symbol); 485extern int parse_solitary_modifier (Lisp_Object symbol);
488 486
489 487
@@ -549,7 +547,7 @@ extern bool kbd_buffer_events_waiting (void);
549extern void add_user_signal (int, const char *); 547extern void add_user_signal (int, const char *);
550 548
551extern int tty_read_avail_input (struct terminal *, struct input_event *); 549extern int tty_read_avail_input (struct terminal *, struct input_event *);
552extern EMACS_TIME timer_check (void); 550extern struct timespec timer_check (void);
553extern void mark_kboards (void); 551extern void mark_kboards (void);
554 552
555#ifdef HAVE_NTGUI 553#ifdef HAVE_NTGUI
diff --git a/src/keymap.c b/src/keymap.c
index d13a6274347..7a18cd5d983 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -3249,8 +3249,7 @@ describe_map (Lisp_Object map, Lisp_Object prefix,
3249 for (tail = map; CONSP (tail); tail = XCDR (tail)) 3249 for (tail = map; CONSP (tail); tail = XCDR (tail))
3250 length_needed++; 3250 length_needed++;
3251 3251
3252 vect = ((struct describe_map_elt *) 3252 vect = alloca (length_needed * sizeof *vect);
3253 alloca (sizeof (struct describe_map_elt) * length_needed));
3254 3253
3255 for (tail = map; CONSP (tail); tail = XCDR (tail)) 3254 for (tail = map; CONSP (tail); tail = XCDR (tail))
3256 { 3255 {
diff --git a/src/lisp.h b/src/lisp.h
index 5daddb7d335..b19745baf91 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -734,6 +734,7 @@ extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p;
734extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; 734extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil;
735extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp; 735extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp;
736extern Lisp_Object Qvector_or_char_table_p, Qwholenump; 736extern Lisp_Object Qvector_or_char_table_p, Qwholenump;
737extern Lisp_Object Qwindow;
737extern Lisp_Object Ffboundp (Lisp_Object); 738extern Lisp_Object Ffboundp (Lisp_Object);
738extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); 739extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object);
739 740
@@ -865,11 +866,7 @@ make_lisp_proc (struct Lisp_Process *p)
865#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) 866#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
866#define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol)) 867#define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol))
867#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) 868#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
868
869/* Misc types. */
870
871#define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc)) 869#define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc))
872#define XSETMARKER(a, b) (XSETMISC (a, b), XMISCTYPE (a) = Lisp_Misc_Marker)
873 870
874/* Pseudovector types. */ 871/* Pseudovector types. */
875 872
@@ -2163,38 +2160,6 @@ enum char_bits
2163 CHARACTERBITS = 22 2160 CHARACTERBITS = 22
2164 }; 2161 };
2165 2162
2166/* Structure to hold mouse highlight data. This is here because other
2167 header files need it for defining struct x_output etc. */
2168typedef struct {
2169 /* These variables describe the range of text currently shown in its
2170 mouse-face, together with the window they apply to. As long as
2171 the mouse stays within this range, we need not redraw anything on
2172 its account. Rows and columns are glyph matrix positions in
2173 MOUSE_FACE_WINDOW. */
2174 int mouse_face_beg_row, mouse_face_beg_col;
2175 int mouse_face_beg_x, mouse_face_beg_y;
2176 int mouse_face_end_row, mouse_face_end_col;
2177 int mouse_face_end_x, mouse_face_end_y;
2178 Lisp_Object mouse_face_window;
2179 int mouse_face_face_id;
2180 Lisp_Object mouse_face_overlay;
2181
2182 /* FRAME and X, Y position of mouse when last checked for
2183 highlighting. X and Y can be negative or out of range for the frame. */
2184 struct frame *mouse_face_mouse_frame;
2185 int mouse_face_mouse_x, mouse_face_mouse_y;
2186
2187 /* Nonzero if part of the text currently shown in
2188 its mouse-face is beyond the window end. */
2189 unsigned mouse_face_past_end : 1;
2190
2191 /* Nonzero means defer mouse-motion highlighting. */
2192 unsigned mouse_face_defer : 1;
2193
2194 /* Nonzero means that the mouse highlight should not be shown. */
2195 unsigned mouse_face_hidden : 1;
2196} Mouse_HLInfo;
2197
2198/* Data type checking. */ 2163/* Data type checking. */
2199 2164
2200LISP_MACRO_DEFUN (NILP, bool, (Lisp_Object x), (x)) 2165LISP_MACRO_DEFUN (NILP, bool, (Lisp_Object x), (x))
@@ -2665,19 +2630,6 @@ typedef jmp_buf sys_jmp_buf;
2665 they are bound by a function application or a let form, stores the 2630 they are bound by a function application or a let form, stores the
2666 code to be executed for unwind-protect forms. 2631 code to be executed for unwind-protect forms.
2667 2632
2668 If func is non-zero, undoing this binding applies func to old_value;
2669 This implements record_unwind_protect.
2670
2671 Otherwise, the element is a variable binding.
2672
2673 If the symbol field is a symbol, it is an ordinary variable binding.
2674
2675 Otherwise, it should be a structure (SYMBOL WHERE . CURRENT-BUFFER),
2676 which means having bound a local value while CURRENT-BUFFER was active.
2677 If WHERE is nil this means we saw the default value when binding SYMBOL.
2678 WHERE being a buffer or frame means we saw a buffer-local or frame-local
2679 value. Other values of WHERE mean an internal error.
2680
2681 NOTE: The specbinding union is defined here, because SPECPDL_INDEX is 2633 NOTE: The specbinding union is defined here, because SPECPDL_INDEX is
2682 used all over the place, needs to be fast, and needs to know the size of 2634 used all over the place, needs to be fast, and needs to know the size of
2683 union specbinding. But only eval.c should access it. */ 2635 union specbinding. But only eval.c should access it. */
@@ -3369,8 +3321,9 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool);
3369extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); 3321extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);
3370extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, 3322extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t,
3371 ptrdiff_t, ptrdiff_t, bool); 3323 ptrdiff_t, ptrdiff_t, bool);
3372extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); 3324extern void modify_text (ptrdiff_t, ptrdiff_t);
3373extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); 3325extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
3326extern void prepare_to_modify_buffer_1 (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
3374extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); 3327extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t);
3375extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, 3328extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t,
3376 ptrdiff_t, ptrdiff_t); 3329 ptrdiff_t, ptrdiff_t);
@@ -3744,11 +3697,12 @@ extern Lisp_Object internal_condition_case_n
3744 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); 3697 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
3745extern void specbind (Lisp_Object, Lisp_Object); 3698extern void specbind (Lisp_Object, Lisp_Object);
3746extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); 3699extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
3747extern void record_unwind_protect_int (void (*) (int), int);
3748extern void record_unwind_protect_ptr (void (*) (void *), void *); 3700extern void record_unwind_protect_ptr (void (*) (void *), void *);
3701extern void record_unwind_protect_int (void (*) (int), int);
3749extern void record_unwind_protect_void (void (*) (void)); 3702extern void record_unwind_protect_void (void (*) (void));
3750extern void record_unwind_protect_nothing (void); 3703extern void record_unwind_protect_nothing (void);
3751extern void clear_unwind_protect (ptrdiff_t); 3704extern void clear_unwind_protect (ptrdiff_t);
3705extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object);
3752extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *); 3706extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
3753extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); 3707extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
3754extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); 3708extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
@@ -3797,9 +3751,7 @@ extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t);
3797extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, 3751extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool,
3798 Lisp_Object, Lisp_Object, Lisp_Object); 3752 Lisp_Object, Lisp_Object, Lisp_Object);
3799extern bool overlay_touches_p (ptrdiff_t); 3753extern bool overlay_touches_p (ptrdiff_t);
3800extern Lisp_Object Vbuffer_alist;
3801extern Lisp_Object other_buffer_safely (Lisp_Object); 3754extern Lisp_Object other_buffer_safely (Lisp_Object);
3802extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string;
3803extern Lisp_Object get_truename_buffer (Lisp_Object); 3755extern Lisp_Object get_truename_buffer (Lisp_Object);
3804extern void init_buffer_once (void); 3756extern void init_buffer_once (void);
3805extern void init_buffer (void); 3757extern void init_buffer (void);
@@ -3830,6 +3782,9 @@ extern Lisp_Object Qfile_directory_p;
3830extern Lisp_Object Qinsert_file_contents; 3782extern Lisp_Object Qinsert_file_contents;
3831extern Lisp_Object Qfile_name_history; 3783extern Lisp_Object Qfile_name_history;
3832extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); 3784extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
3785extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object,
3786 Lisp_Object, Lisp_Object, Lisp_Object,
3787 Lisp_Object, int);
3833EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ 3788EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */
3834extern void close_file_unwind (int); 3789extern void close_file_unwind (int);
3835extern void fclose_unwind (void *); 3790extern void fclose_unwind (void *);
@@ -3862,8 +3817,8 @@ extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t,
3862 ptrdiff_t, ptrdiff_t, Lisp_Object); 3817 ptrdiff_t, ptrdiff_t, Lisp_Object);
3863extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, 3818extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
3864 ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool); 3819 ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool);
3865extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, 3820extern ptrdiff_t scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
3866 EMACS_INT, bool); 3821 ptrdiff_t, bool);
3867extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t, 3822extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t,
3868 ptrdiff_t, ptrdiff_t *); 3823 ptrdiff_t, ptrdiff_t *);
3869extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, 3824extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t,
@@ -4096,7 +4051,6 @@ extern void init_sys_modes (struct tty_display_info *);
4096extern void reset_sys_modes (struct tty_display_info *); 4051extern void reset_sys_modes (struct tty_display_info *);
4097extern void init_all_sys_modes (void); 4052extern void init_all_sys_modes (void);
4098extern void reset_all_sys_modes (void); 4053extern void reset_all_sys_modes (void);
4099extern void flush_pending_output (int) ATTRIBUTE_CONST;
4100extern void child_setup_tty (int); 4054extern void child_setup_tty (int);
4101extern void setup_pty (int); 4055extern void setup_pty (int);
4102extern int set_window_size (int, int, int); 4056extern int set_window_size (int, int, int);
@@ -4213,6 +4167,11 @@ extern void syms_of_xml (void);
4213extern void xml_cleanup_parser (void); 4167extern void xml_cleanup_parser (void);
4214#endif 4168#endif
4215 4169
4170#ifdef HAVE_ZLIB
4171/* Defined in decompress.c. */
4172extern void syms_of_decompress (void);
4173#endif
4174
4216#ifdef HAVE_DBUS 4175#ifdef HAVE_DBUS
4217/* Defined in dbusbind.c. */ 4176/* Defined in dbusbind.c. */
4218void syms_of_dbusbind (void); 4177void syms_of_dbusbind (void);
@@ -4246,10 +4205,17 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t);
4246extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); 4205extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
4247 4206
4248extern char *xstrdup (const char *); 4207extern char *xstrdup (const char *);
4208extern char *xlispstrdup (Lisp_Object);
4249extern void xputenv (const char *); 4209extern void xputenv (const char *);
4250 4210
4251extern char *egetenv (const char *); 4211extern char *egetenv (const char *);
4252 4212
4213/* Copy Lisp string to temporary (allocated on stack) C string. */
4214
4215#define xlispstrdupa(string) \
4216 memcpy (alloca (SBYTES (string) + 1), \
4217 SSDATA (string), SBYTES (string) + 1)
4218
4253/* Set up the name of the machine we're running on. */ 4219/* Set up the name of the machine we're running on. */
4254extern void init_system_name (void); 4220extern void init_system_name (void);
4255 4221
@@ -4326,6 +4292,12 @@ extern void *record_xmalloc (size_t);
4326 memory_full (SIZE_MAX); \ 4292 memory_full (SIZE_MAX); \
4327 } while (0) 4293 } while (0)
4328 4294
4295/* Do a `for' loop over alist values. */
4296
4297#define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \
4298 for (list_var = head_var; \
4299 (CONSP (list_var) && (value_var = XCDR (XCAR (list_var)), 1)); \
4300 list_var = XCDR (list_var))
4329 4301
4330/* Check whether it's time for GC, and run it if so. */ 4302/* Check whether it's time for GC, and run it if so. */
4331 4303
diff --git a/src/lisp.mk b/src/lisp.mk
index edd81bcf493..a9a661ea3a8 100644
--- a/src/lisp.mk
+++ b/src/lisp.mk
@@ -71,6 +71,7 @@ lisp = \
71 $(lispsource)/faces.elc \ 71 $(lispsource)/faces.elc \
72 $(lispsource)/button.elc \ 72 $(lispsource)/button.elc \
73 $(lispsource)/startup.elc \ 73 $(lispsource)/startup.elc \
74 $(lispsource)/emacs-lisp/nadvice.elc \
74 $(lispsource)/minibuffer.elc \ 75 $(lispsource)/minibuffer.elc \
75 $(lispsource)/abbrev.elc \ 76 $(lispsource)/abbrev.elc \
76 $(lispsource)/simple.elc \ 77 $(lispsource)/simple.elc \
diff --git a/src/lread.c b/src/lread.c
index 57c7df74127..9518631ba6d 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -609,7 +609,7 @@ read_filtered_event (bool no_switch_frame, bool ascii_required,
609 bool error_nonascii, bool input_method, Lisp_Object seconds) 609 bool error_nonascii, bool input_method, Lisp_Object seconds)
610{ 610{
611 Lisp_Object val, delayed_switch_frame; 611 Lisp_Object val, delayed_switch_frame;
612 EMACS_TIME end_time; 612 struct timespec end_time;
613 613
614#ifdef HAVE_WINDOW_SYSTEM 614#ifdef HAVE_WINDOW_SYSTEM
615 if (display_hourglass_p) 615 if (display_hourglass_p)
@@ -622,8 +622,8 @@ read_filtered_event (bool no_switch_frame, bool ascii_required,
622 if (NUMBERP (seconds)) 622 if (NUMBERP (seconds))
623 { 623 {
624 double duration = extract_float (seconds); 624 double duration = extract_float (seconds);
625 EMACS_TIME wait_time = EMACS_TIME_FROM_DOUBLE (duration); 625 struct timespec wait_time = dtotimespec (duration);
626 end_time = add_emacs_time (current_emacs_time (), wait_time); 626 end_time = timespec_add (current_timespec (), wait_time);
627 } 627 }
628 628
629 /* Read until we get an acceptable event. */ 629 /* Read until we get an acceptable event. */
@@ -1262,7 +1262,7 @@ Return t if the file exists and loads successfully. */)
1262 } 1262 }
1263 1263
1264 if (result == 0 1264 if (result == 0
1265 && EMACS_TIME_LT (get_stat_mtime (&s1), get_stat_mtime (&s2))) 1265 && timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0)
1266 { 1266 {
1267 /* Make the progress messages mention that source is newer. */ 1267 /* Make the progress messages mention that source is newer. */
1268 newer = 1; 1268 newer = 1;
@@ -3229,7 +3229,7 @@ substitute_object_recurse (Lisp_Object object, Lisp_Object placeholder, Lisp_Obj
3229 if (BOOL_VECTOR_P (subtree)) 3229 if (BOOL_VECTOR_P (subtree))
3230 return subtree; /* No sub-objects anyway. */ 3230 return subtree; /* No sub-objects anyway. */
3231 else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree) 3231 else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree)
3232 || COMPILEDP (subtree)) 3232 || COMPILEDP (subtree) || HASH_TABLE_P (subtree))
3233 length = ASIZE (subtree) & PSEUDOVECTOR_SIZE_MASK; 3233 length = ASIZE (subtree) & PSEUDOVECTOR_SIZE_MASK;
3234 else if (VECTORP (subtree)) 3234 else if (VECTORP (subtree))
3235 length = ASIZE (subtree); 3235 length = ASIZE (subtree);
diff --git a/src/marker.c b/src/marker.c
index 6c50def51a3..2f91bdf9727 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -534,9 +534,9 @@ set_marker_internal (Lisp_Object marker, Lisp_Object position,
534} 534}
535 535
536DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0, 536DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0,
537 doc: /* Position MARKER before character number POSITION in BUFFER, 537 doc: /* Position MARKER before character number POSITION in BUFFER.
538which defaults to the current buffer. If POSITION is nil, 538If BUFFER is omitted or nil, it defaults to the current buffer. If
539makes marker point nowhere so it no longer slows down 539POSITION is nil, makes marker point nowhere so it no longer slows down
540editing in any buffer. Returns MARKER. */) 540editing in any buffer. Returns MARKER. */)
541 (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer) 541 (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer)
542{ 542{
diff --git a/src/minibuf.c b/src/minibuf.c
index 2c33b83c11b..7403fc6c32d 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -568,22 +568,15 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
568 bset_directory (current_buffer, ambient_dir); 568 bset_directory (current_buffer, ambient_dir);
569 else 569 else
570 { 570 {
571 Lisp_Object buf_list; 571 Lisp_Object tail, buf;
572 572
573 for (buf_list = Vbuffer_alist; 573 FOR_EACH_LIVE_BUFFER (tail, buf)
574 CONSP (buf_list); 574 if (STRINGP (BVAR (XBUFFER (buf), directory)))
575 buf_list = XCDR (buf_list)) 575 {
576 { 576 bset_directory (current_buffer,
577 Lisp_Object other_buf; 577 BVAR (XBUFFER (buf), directory));
578 578 break;
579 other_buf = XCDR (XCAR (buf_list)); 579 }
580 if (STRINGP (BVAR (XBUFFER (other_buf), directory)))
581 {
582 bset_directory (current_buffer,
583 BVAR (XBUFFER (other_buf), directory));
584 break;
585 }
586 }
587 } 580 }
588 581
589 if (!EQ (mini_frame, selected_frame)) 582 if (!EQ (mini_frame, selected_frame))
@@ -877,10 +870,8 @@ read_minibuf_unwind (void)
877 if (minibuf_level == 0) 870 if (minibuf_level == 0)
878 resize_mini_window (XWINDOW (window), 0); 871 resize_mini_window (XWINDOW (window), 0);
879 872
880 /* Make sure minibuffer window is erased, not ignored. */ 873 /* Enforce full redisplay. FIXME: make it more selective. */
881 windows_or_buffers_changed++; 874 windows_or_buffers_changed++;
882 XWINDOW (window)->last_modified = 0;
883 XWINDOW (window)->last_overlay_modified = 0;
884 875
885 /* In case the previous minibuffer displayed in this miniwindow is 876 /* In case the previous minibuffer displayed in this miniwindow is
886 dead, we may keep displaying this buffer (tho it's inactive), so reset it, 877 dead, we may keep displaying this buffer (tho it's inactive), so reset it,
diff --git a/src/msdos.c b/src/msdos.c
index 88a2eb60726..7142c3ada77 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -602,11 +602,7 @@ dos_set_window_size (int *rows, int *cols)
602 Lisp_Object window = hlinfo->mouse_face_window; 602 Lisp_Object window = hlinfo->mouse_face_window;
603 603
604 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) 604 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
605 { 605 reset_mouse_highlight (hlinfo);
606 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
607 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
608 hlinfo->mouse_face_window = Qnil;
609 }
610 } 606 }
611 607
612 /* Enable bright background colors. */ 608 /* Enable bright background colors. */
@@ -950,9 +946,6 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
950 Mouse Highlight (and friends..) 946 Mouse Highlight (and friends..)
951 ************************************************************************/ 947 ************************************************************************/
952 948
953/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
954static Lisp_Object last_mouse_window;
955
956static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */ 949static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */
957 950
958int 951int
@@ -1276,14 +1269,9 @@ IT_update_begin (struct frame *f)
1276 } 1269 }
1277 } 1270 }
1278 else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame)) 1271 else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame))
1279 { 1272 /* If the frame with mouse highlight was deleted, invalidate the
1280 /* If the frame with mouse highlight was deleted, invalidate the 1273 highlight info. */
1281 highlight info. */ 1274 reset_mouse_highlight (hlinfo);
1282 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1283 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1284 hlinfo->mouse_face_window = Qnil;
1285 hlinfo->mouse_face_mouse_frame = NULL;
1286 }
1287 1275
1288 unblock_input (); 1276 unblock_input ();
1289} 1277}
@@ -1555,11 +1543,6 @@ IT_reset_terminal_modes (struct terminal *term)
1555 term_setup_done = 0; 1543 term_setup_done = 0;
1556} 1544}
1557 1545
1558static void
1559IT_set_terminal_window (struct frame *f, int foo)
1560{
1561}
1562
1563/* Remember the screen colors of the current frame, to serve as the 1546/* Remember the screen colors of the current frame, to serve as the
1564 default colors for newly-created frames. */ 1547 default colors for newly-created frames. */
1565DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors, 1548DEFUN ("msdos-remember-default-colors", Fmsdos_remember_default_colors,
@@ -1843,17 +1826,8 @@ internal_terminal_init (void)
1843 if (colors[1] >= 0 && colors[1] < 16) 1826 if (colors[1] >= 0 && colors[1] < 16)
1844 FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1]; 1827 FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1];
1845 } 1828 }
1846 the_only_display_info.mouse_highlight.mouse_face_mouse_frame = NULL; 1829
1847 the_only_display_info.mouse_highlight.mouse_face_beg_row = 1830 reset_mouse_highlight (&the_only_display_info.mouse_highlight);
1848 the_only_display_info.mouse_highlight.mouse_face_beg_col = -1;
1849 the_only_display_info.mouse_highlight.mouse_face_end_row =
1850 the_only_display_info.mouse_highlight.mouse_face_end_col = -1;
1851 the_only_display_info.mouse_highlight.mouse_face_face_id = DEFAULT_FACE_ID;
1852 the_only_display_info.mouse_highlight.mouse_face_window = Qnil;
1853 the_only_display_info.mouse_highlight.mouse_face_mouse_x =
1854 the_only_display_info.mouse_highlight.mouse_face_mouse_y = 0;
1855 the_only_display_info.mouse_highlight.mouse_face_defer = 0;
1856 the_only_display_info.mouse_highlight.mouse_face_hidden = 0;
1857 1831
1858 if (have_mouse) /* detected in dos_ttraw, which see */ 1832 if (have_mouse) /* detected in dos_ttraw, which see */
1859 { 1833 {
@@ -1889,7 +1863,7 @@ initialize_msdos_display (struct terminal *term)
1889 term->ring_bell_hook = IT_ring_bell; 1863 term->ring_bell_hook = IT_ring_bell;
1890 term->reset_terminal_modes_hook = IT_reset_terminal_modes; 1864 term->reset_terminal_modes_hook = IT_reset_terminal_modes;
1891 term->set_terminal_modes_hook = IT_set_terminal_modes; 1865 term->set_terminal_modes_hook = IT_set_terminal_modes;
1892 term->set_terminal_window_hook = IT_set_terminal_window; 1866 term->set_terminal_window_hook = NULL;
1893 term->update_begin_hook = IT_update_begin; 1867 term->update_begin_hook = IT_update_begin;
1894 term->update_end_hook = IT_update_end; 1868 term->update_end_hook = IT_update_end;
1895 term->frame_up_to_date_hook = IT_frame_up_to_date; 1869 term->frame_up_to_date_hook = IT_frame_up_to_date;
@@ -2691,10 +2665,10 @@ dos_rawgetc (void)
2691 /* Generate SELECT_WINDOW_EVENTs when needed. */ 2665 /* Generate SELECT_WINDOW_EVENTs when needed. */
2692 if (!NILP (Vmouse_autoselect_window)) 2666 if (!NILP (Vmouse_autoselect_window))
2693 { 2667 {
2694 mouse_window = window_from_coordinates (SELECTED_FRAME (), 2668 static Lisp_Object last_mouse_window;
2695 mouse_last_x, 2669
2696 mouse_last_y, 2670 mouse_window = window_from_coordinates
2697 0, 0); 2671 (SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0);
2698 /* A window will be selected only when it is not 2672 /* A window will be selected only when it is not
2699 selected now, and the last mouse movement event was 2673 selected now, and the last mouse movement event was
2700 not in it. A minibuffer window will be selected iff 2674 not in it. A minibuffer window will be selected iff
@@ -2709,10 +2683,9 @@ dos_rawgetc (void)
2709 event.timestamp = event_timestamp (); 2683 event.timestamp = event_timestamp ();
2710 kbd_buffer_store_event (&event); 2684 kbd_buffer_store_event (&event);
2711 } 2685 }
2686 /* Remember the last window where we saw the mouse. */
2712 last_mouse_window = mouse_window; 2687 last_mouse_window = mouse_window;
2713 } 2688 }
2714 else
2715 last_mouse_window = Qnil;
2716 2689
2717 previous_help_echo_string = help_echo_string; 2690 previous_help_echo_string = help_echo_string;
2718 help_echo_string = help_echo_object = help_echo_window = Qnil; 2691 help_echo_string = help_echo_object = help_echo_window = Qnil;
@@ -4073,7 +4046,7 @@ dos_yield_time_slice (void)
4073 because wait_reading_process_output takes care of that. */ 4046 because wait_reading_process_output takes care of that. */
4074int 4047int
4075sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, 4048sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
4076 EMACS_TIME *timeout, void *ignored) 4049 struct timespec *timeout, void *ignored)
4077{ 4050{
4078 int check_input; 4051 int check_input;
4079 struct timespec t; 4052 struct timespec t;
@@ -4103,20 +4076,20 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
4103 } 4076 }
4104 else 4077 else
4105 { 4078 {
4106 EMACS_TIME clnow, cllast, cldiff; 4079 struct timespec clnow, cllast, cldiff;
4107 4080
4108 gettime (&t); 4081 gettime (&t);
4109 cllast = make_emacs_time (t.tv_sec, t.tv_nsec); 4082 cllast = make_timespec (t.tv_sec, t.tv_nsec);
4110 4083
4111 while (!check_input || !detect_input_pending ()) 4084 while (!check_input || !detect_input_pending ())
4112 { 4085 {
4113 gettime (&t); 4086 gettime (&t);
4114 clnow = make_emacs_time (t.tv_sec, t.tv_nsec); 4087 clnow = make_timespec (t.tv_sec, t.tv_nsec);
4115 cldiff = sub_emacs_time (clnow, cllast); 4088 cldiff = timespec_sub (clnow, cllast);
4116 *timeout = sub_emacs_time (*timeout, cldiff); 4089 *timeout = timespec_sub (*timeout, cldiff);
4117 4090
4118 /* Stop when timeout value crosses zero. */ 4091 /* Stop when timeout value crosses zero. */
4119 if (EMACS_TIME_SIGN (*timeout) <= 0) 4092 if (timespec_sign (*timeout) <= 0)
4120 return 0; 4093 return 0;
4121 cllast = clnow; 4094 cllast = clnow;
4122 dos_yield_time_slice (); 4095 dos_yield_time_slice ();
diff --git a/src/nsfns.m b/src/nsfns.m
index 3f43afde787..fc276c2b12d 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -860,11 +860,7 @@ static void
860x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 860x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
861{ 861{
862 set_frame_cursor_types (f, arg); 862 set_frame_cursor_types (f, arg);
863
864 /* Make sure the cursor gets redrawn. */
865 cursor_type_changed = 1;
866} 863}
867
868 864
869/* called to set mouse pointer color, but all other terms use it to 865/* called to set mouse pointer color, but all other terms use it to
870 initialize pointer types (and don't set the color ;) */ 866 initialize pointer types (and don't set the color ;) */
@@ -2035,13 +2031,17 @@ DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc,
2035/* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping, 2031/* TODO: If GNUstep ever implements precomposedStringWithCanonicalMapping,
2036 remove this. */ 2032 remove this. */
2037 NSString *utfStr; 2033 NSString *utfStr;
2034 Lisp_Object ret;
2038 2035
2039 CHECK_STRING (str); 2036 CHECK_STRING (str);
2040 utfStr = [NSString stringWithUTF8String: SSDATA (str)]; 2037 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
2038 utfStr = [NSString stringWithUTF8String: SSDATA (str)];
2041#ifdef NS_IMPL_COCOA 2039#ifdef NS_IMPL_COCOA
2042 utfStr = [utfStr precomposedStringWithCanonicalMapping]; 2040 utfStr = [utfStr precomposedStringWithCanonicalMapping];
2043#endif 2041#endif
2044 return build_string ([utfStr UTF8String]); 2042 ret = build_string ([utfStr UTF8String]);
2043 [pool release];
2044 return ret;
2045} 2045}
2046 2046
2047 2047
@@ -2447,7 +2447,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
2447 if (n_monitors == 0) 2447 if (n_monitors == 0)
2448 return Qnil; 2448 return Qnil;
2449 2449
2450 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); 2450 monitors = xzalloc (n_monitors * sizeof *monitors);
2451 2451
2452 for (i = 0; i < [screens count]; ++i) 2452 for (i = 0; i < [screens count]; ++i)
2453 { 2453 {
diff --git a/src/nsfont.m b/src/nsfont.m
index ad169d7ddae..e1c7d32dde0 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -61,6 +61,7 @@ static void ns_uni_to_glyphs (struct nsfont_info *font_info,
61static void ns_glyph_metrics (struct nsfont_info *font_info, 61static void ns_glyph_metrics (struct nsfont_info *font_info,
62 unsigned char block); 62 unsigned char block);
63 63
64#define INVALID_GLYPH 0xFFFF
64 65
65/* ========================================================================== 66/* ==========================================================================
66 67
@@ -920,8 +921,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
920 font->underline_thickness = lrint (font_info->underwidth); 921 font->underline_thickness = lrint (font_info->underwidth);
921 922
922 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil); 923 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
923 font->props[FONT_FULLNAME_INDEX] = 924 font->props[FONT_FULLNAME_INDEX] = build_unibyte_string (font_info->name);
924 make_unibyte_string (font_info->name, strlen (font_info->name));
925 } 925 }
926 unblock_input (); 926 unblock_input ();
927 927
@@ -982,7 +982,7 @@ nsfont_encode_char (struct font *font, int c)
982 ns_uni_to_glyphs (font_info, high); 982 ns_uni_to_glyphs (font_info, high);
983 983
984 g = font_info->glyphs[high][low]; 984 g = font_info->glyphs[high][low];
985 return g == 0xFFFF ? FONT_INVALID_CODE : g; 985 return g == INVALID_GLYPH ? FONT_INVALID_CODE : g;
986} 986}
987 987
988 988
@@ -1355,8 +1355,8 @@ ns_uni_to_glyphs (struct nsfont_info *font_info, unsigned char block)
1355#else 1355#else
1356 g = glyphStorage->cglyphs[i]; 1356 g = glyphStorage->cglyphs[i];
1357 /* TODO: is this a good check? maybe need to use coveredChars.. */ 1357 /* TODO: is this a good check? maybe need to use coveredChars.. */
1358 if (g > numGlyphs) 1358 if (g > numGlyphs || g == NSNullGlyph)
1359 g = 0xFFFF; /* hopefully unused... */ 1359 g = INVALID_GLYPH; /* hopefully unused... */
1360#endif 1360#endif
1361 *glyphs = g; 1361 *glyphs = g;
1362 } 1362 }
@@ -1484,7 +1484,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
1484 characterIndex: (NSUInteger)charIndex 1484 characterIndex: (NSUInteger)charIndex
1485{ 1485{
1486 len = glyphIndex+length; 1486 len = glyphIndex+length;
1487 for (i =glyphIndex; i<len; i++) 1487 for (i =glyphIndex; i<len; i++)
1488 cglyphs[i] = glyphs[i-glyphIndex]; 1488 cglyphs[i] = glyphs[i-glyphIndex];
1489 if (len > maxGlyph) 1489 if (len > maxGlyph)
1490 maxGlyph = len; 1490 maxGlyph = len;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 464be89c524..f9cd511efe9 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -366,7 +366,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
366 } 366 }
367 else 367 else
368 { 368 {
369 [menu fillWithWidgetValue: first_wv->contents]; 369 [menu fillWithWidgetValue: first_wv->contents frame: f];
370 } 370 }
371 371
372 } 372 }
@@ -504,23 +504,11 @@ void
504x_activate_menubar (struct frame *f) 504x_activate_menubar (struct frame *f)
505{ 505{
506#ifdef NS_IMPL_COCOA 506#ifdef NS_IMPL_COCOA
507 NSArray *a = [[NSApp mainMenu] itemArray]; 507#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
508 /* Update each submenu separately so ns_update_menubar doesn't reset 508 ns_update_menubar (f, true, nil);
509 the delegate. */
510 int i = 0;
511 while (i < [a count])
512 {
513 EmacsMenu *menu = (EmacsMenu *)[[a objectAtIndex:i] submenu];
514 const char *title = [[menu title] UTF8String];
515 if (strcmp (title, ns_get_pending_menu_title ()) == 0)
516 {
517 ns_update_menubar (f, true, menu);
518 break;
519 }
520 ++i;
521 }
522 ns_check_pending_open_menu (); 509 ns_check_pending_open_menu ();
523#endif 510#endif
511#endif
524} 512}
525 513
526 514
@@ -541,6 +529,7 @@ x_activate_menubar (struct frame *f)
541/* override designated initializer */ 529/* override designated initializer */
542- initWithTitle: (NSString *)title 530- initWithTitle: (NSString *)title
543{ 531{
532 frame = 0;
544 if ((self = [super initWithTitle: title])) 533 if ((self = [super initWithTitle: title]))
545 [self setAutoenablesItems: NO]; 534 [self setAutoenablesItems: NO];
546 return self; 535 return self;
@@ -576,17 +565,36 @@ extern NSString *NSMenuDidBeginTrackingNotification;
576 /* Update menu in menuNeedsUpdate only while tracking menus. */ 565 /* Update menu in menuNeedsUpdate only while tracking menus. */
577 trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification 566 trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
578 ? 1 : 0); 567 ? 1 : 0);
568#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
569 if (! trackingMenu) ns_check_menu_open (nil);
570#endif
579} 571}
580 572
581#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 573#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
582- (void)menuWillOpen:(NSMenu *)menu 574- (void)menuWillOpen:(NSMenu *)menu
583{ 575{
584 ns_check_menu_open (menu); 576 ++trackingMenu;
585}
586#endif
587 577
578#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
579 // On 10.6 we get repeated calls, only the one for NSSystemDefined is "real".
580 if ([[NSApp currentEvent] type] != NSSystemDefined) return;
588#endif 581#endif
589 582
583 /* When dragging from one menu to another, we get willOpen followed by didClose,
584 i.e. trackingMenu == 3 in willOpen and then 2 after didClose.
585 We have updated all menus, so avoid doing it when trackingMenu == 3. */
586 if (trackingMenu == 2)
587 ns_check_menu_open (menu);
588}
589
590- (void)menuDidClose:(NSMenu *)menu
591{
592 --trackingMenu;
593}
594#endif /* OSX >= 10.5 */
595
596#endif /* NS_IMPL_COCOA */
597
590/* delegate method called when a submenu is being opened: run a 'deep' call 598/* delegate method called when a submenu is being opened: run a 'deep' call
591 to set_frame_menubar */ 599 to set_frame_menubar */
592- (void)menuNeedsUpdate: (NSMenu *)menu 600- (void)menuNeedsUpdate: (NSMenu *)menu
@@ -722,6 +730,11 @@ extern NSString *NSMenuDidBeginTrackingNotification;
722 730
723- (void)fillWithWidgetValue: (void *)wvptr 731- (void)fillWithWidgetValue: (void *)wvptr
724{ 732{
733 [self fillWithWidgetValue: wvptr frame: (struct frame *)nil];
734}
735
736- (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f
737{
725 widget_value *wv = (widget_value *)wvptr; 738 widget_value *wv = (widget_value *)wvptr;
726 739
727 /* clear existing contents */ 740 /* clear existing contents */
@@ -735,7 +748,12 @@ extern NSString *NSMenuDidBeginTrackingNotification;
735 748
736 if (wv->contents) 749 if (wv->contents)
737 { 750 {
738 EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: [item title]]; 751 EmacsMenu *submenu;
752
753 if (f)
754 submenu = [[EmacsMenu alloc] initWithTitle: [item title] frame:f];
755 else
756 submenu = [[EmacsMenu alloc] initWithTitle: [item title]];
739 757
740 [self setSubmenu: submenu forItem: item]; 758 [self setSubmenu: submenu forItem: item];
741 [submenu fillWithWidgetValue: wv->contents]; 759 [submenu fillWithWidgetValue: wv->contents];
@@ -1665,7 +1683,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1665 } 1683 }
1666 1684
1667 if (buttons > 0) 1685 if (buttons > 0)
1668 button_values = (Lisp_Object *) xmalloc (buttons * sizeof (*button_values)); 1686 button_values = xmalloc (buttons * sizeof *button_values);
1669 1687
1670 for (; XTYPE (list) == Lisp_Cons; list = XCDR (list)) 1688 for (; XTYPE (list) == Lisp_Cons; list = XCDR (list))
1671 { 1689 {
@@ -1849,11 +1867,11 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1849 while (popup_activated_flag) 1867 while (popup_activated_flag)
1850 { 1868 {
1851 NSTimer *tmo = nil; 1869 NSTimer *tmo = nil;
1852 EMACS_TIME next_time = timer_check (); 1870 struct timespec next_time = timer_check ();
1853 1871
1854 if (EMACS_TIME_VALID_P (next_time)) 1872 if (timespec_valid_p (next_time))
1855 { 1873 {
1856 double time = EMACS_TIME_TO_DOUBLE (next_time); 1874 double time = timespectod (next_time);
1857 tmo = [NSTimer timerWithTimeInterval: time 1875 tmo = [NSTimer timerWithTimeInterval: time
1858 target: self 1876 target: self
1859 selector: @selector (timeout_handler:) 1877 selector: @selector (timeout_handler:)
diff --git a/src/nsterm.h b/src/nsterm.h
index 1303a475547..4e07d796250 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -53,9 +53,24 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
53 53
54/* CGFloat on GNUStep may be 4 or 8 byte, but functions expect float* for some 54/* CGFloat on GNUStep may be 4 or 8 byte, but functions expect float* for some
55 versions. 55 versions.
56 On Cocoa, functions expect CGFloat*. Make compatible type. */ 56 On Cocoa >= 10.5, functions expect CGFloat*. Make compatible type. */
57#if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \ 57#ifdef NS_IMPL_COCOA
58 GNUSTEP_GUI_MINOR_VERSION >= 22 58
59#ifndef NS_HAVE_NSINTEGER
60#if defined (__LP64__) && __LP64__
61typedef double CGFloat;
62typedef long NSInteger;
63typedef unsigned long NSUInteger;
64#else
65typedef float CGFloat;
66typedef int NSInteger;
67typedef unsigned int NSUInteger;
68#endif /* not LP64 */
69#endif /* not NS_HAVE_NSINTEGER */
70
71typedef CGFloat EmacsCGFloat;
72
73#elif GNUSTEP_GUI_MAJOR_VERSION > 0 || GNUSTEP_GUI_MINOR_VERSION >= 22
59typedef CGFloat EmacsCGFloat; 74typedef CGFloat EmacsCGFloat;
60#else 75#else
61typedef float EmacsCGFloat; 76typedef float EmacsCGFloat;
@@ -196,6 +211,7 @@ typedef float EmacsCGFloat;
196- (NSString *)parseKeyEquiv: (const char *)key; 211- (NSString *)parseKeyEquiv: (const char *)key;
197- (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr; 212- (NSMenuItem *)addItemWithWidgetValue: (void *)wvptr;
198- (void)fillWithWidgetValue: (void *)wvptr; 213- (void)fillWithWidgetValue: (void *)wvptr;
214- (void)fillWithWidgetValue: (void *)wvptr frame: (struct frame *)f;
199- (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f; 215- (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f;
200- (void) clear; 216- (void) clear;
201- (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f 217- (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f
@@ -423,18 +439,6 @@ extern EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
423@end 439@end
424#endif 440#endif
425 441
426#ifndef NS_HAVE_NSINTEGER
427#if defined (__LP64__) && __LP64__
428typedef double CGFloat;
429typedef long NSInteger;
430typedef unsigned long NSUInteger;
431#else
432typedef float CGFloat;
433typedef int NSInteger;
434typedef unsigned int NSUInteger;
435#endif /* not LP64 */
436#endif /* not NS_HAVE_NSINTEGER */
437
438#endif /* __OBJC__ */ 442#endif /* __OBJC__ */
439 443
440 444
@@ -748,8 +752,6 @@ struct x_output
748 (FRAME_NS_DISPLAY_INFO (f)->smallest_char_width) 752 (FRAME_NS_DISPLAY_INFO (f)->smallest_char_width)
749#define FRAME_SMALLEST_FONT_HEIGHT(f) \ 753#define FRAME_SMALLEST_FONT_HEIGHT(f) \
750 (FRAME_NS_DISPLAY_INFO (f)->smallest_font_height) 754 (FRAME_NS_DISPLAY_INFO (f)->smallest_font_height)
751#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
752#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
753#define FRAME_BASELINE_OFFSET(f) ((f)->output_data.ns->baseline_offset) 755#define FRAME_BASELINE_OFFSET(f) ((f)->output_data.ns->baseline_offset)
754#define BLACK_PIX_DEFAULT(f) 0x000000 756#define BLACK_PIX_DEFAULT(f) 0x000000
755#define WHITE_PIX_DEFAULT(f) 0xFFFFFF 757#define WHITE_PIX_DEFAULT(f) 0xFFFFFF
@@ -870,8 +872,8 @@ extern int x_display_pixel_width (struct ns_display_info *);
870/* This in nsterm.m */ 872/* This in nsterm.m */
871extern void x_destroy_window (struct frame *f); 873extern void x_destroy_window (struct frame *f);
872extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, 874extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
873 fd_set *exceptfds, EMACS_TIME *timeout, 875 fd_set *exceptfds, struct timespec const *timeout,
874 sigset_t *sigmask); 876 sigset_t const *sigmask);
875extern unsigned long ns_get_rgb_color (struct frame *f, 877extern unsigned long ns_get_rgb_color (struct frame *f,
876 float r, float g, float b, float a); 878 float r, float g, float b, float a);
877extern NSPoint last_mouse_motion_position; 879extern NSPoint last_mouse_motion_position;
diff --git a/src/nsterm.m b/src/nsterm.m
index 3672c7656da..31053ca7a0d 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -214,7 +214,7 @@ static NSTimer *scroll_repeat_entry = nil;
214static fd_set select_readfds, select_writefds; 214static fd_set select_readfds, select_writefds;
215enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 }; 215enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 };
216static int select_nfds = 0, select_valid = 0; 216static int select_nfds = 0, select_valid = 0;
217static EMACS_TIME select_timeout = { 0, 0 }; 217static struct timespec select_timeout = { 0, 0 };
218static int selfds[2] = { -1, -1 }; 218static int selfds[2] = { -1, -1 };
219static pthread_mutex_t select_mutex; 219static pthread_mutex_t select_mutex;
220static int apploopnr = 0; 220static int apploopnr = 0;
@@ -250,9 +250,6 @@ static int menu_will_open_state = MENU_NONE;
250 250
251/* Saved position for menu click. */ 251/* Saved position for menu click. */
252static CGPoint menu_mouse_point; 252static CGPoint menu_mouse_point;
253
254/* Title for the menu to open. */
255static char *menu_pending_title = 0;
256#endif 253#endif
257 254
258/* Convert modifiers in a NeXTstep event to emacs style modifiers. */ 255/* Convert modifiers in a NeXTstep event to emacs style modifiers. */
@@ -311,8 +308,13 @@ static char *menu_pending_title = 0;
311/* This is a piece of code which is common to all the event handling 308/* This is a piece of code which is common to all the event handling
312 methods. Maybe it should even be a function. */ 309 methods. Maybe it should even be a function. */
313#define EV_TRAILER(e) \ 310#define EV_TRAILER(e) \
314 { \ 311 { \
315 XSETFRAME (emacs_event->frame_or_window, emacsframe); \ 312 XSETFRAME (emacs_event->frame_or_window, emacsframe); \
313 EV_TRAILER2 (e); \
314 }
315
316#define EV_TRAILER2(e) \
317 { \
316 if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ 318 if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \
317 if (q_event_ptr) \ 319 if (q_event_ptr) \
318 { \ 320 { \
@@ -344,8 +346,8 @@ hold_event (struct input_event *event)
344 { 346 {
345 if (hold_event_q.cap == 0) hold_event_q.cap = 10; 347 if (hold_event_q.cap == 0) hold_event_q.cap = 10;
346 else hold_event_q.cap *= 2; 348 else hold_event_q.cap *= 2;
347 hold_event_q.q = (struct input_event *) 349 hold_event_q.q =
348 xrealloc (hold_event_q.q, hold_event_q.cap * sizeof (*hold_event_q.q)); 350 xrealloc (hold_event_q.q, hold_event_q.cap * sizeof *hold_event_q.q);
349 } 351 }
350 352
351 hold_event_q.q[hold_event_q.nr++] = *event; 353 hold_event_q.q[hold_event_q.nr++] = *event;
@@ -488,16 +490,16 @@ ns_timeout (int usecs)
488 Blocking timer utility used by ns_ring_bell 490 Blocking timer utility used by ns_ring_bell
489 -------------------------------------------------------------------------- */ 491 -------------------------------------------------------------------------- */
490{ 492{
491 EMACS_TIME wakeup = add_emacs_time (current_emacs_time (), 493 struct timespec wakeup = timespec_add (current_timespec (),
492 make_emacs_time (0, usecs * 1000)); 494 make_timespec (0, usecs * 1000));
493 495
494 /* Keep waiting until past the time wakeup. */ 496 /* Keep waiting until past the time wakeup. */
495 while (1) 497 while (1)
496 { 498 {
497 EMACS_TIME timeout, now = current_emacs_time (); 499 struct timespec timeout, now = current_timespec ();
498 if (EMACS_TIME_LE (wakeup, now)) 500 if (timespec_cmp (wakeup, now) <= 0)
499 break; 501 break;
500 timeout = sub_emacs_time (wakeup, now); 502 timeout = timespec_sub (wakeup, now);
501 503
502 /* Try to wait that long--but we might wake up sooner. */ 504 /* Try to wait that long--but we might wake up sooner. */
503 pselect (0, NULL, NULL, NULL, &timeout, NULL); 505 pselect (0, NULL, NULL, NULL, &timeout, NULL);
@@ -691,9 +693,18 @@ ns_update_begin (struct frame *f)
691 { 693 {
692 NSBezierPath *bp; 694 NSBezierPath *bp;
693 NSRect r = [view frame]; 695 NSRect r = [view frame];
694 bp = [[NSBezierPath bezierPathWithRect: r] retain]; 696 NSRect cr = [[view window] frame];
695 [bp setClip]; 697 /* If a large frame size is set, r may be larger than the window frame
696 [bp release]; 698 before constrained. In that case don't change the clip path, as we
699 will clear in to the tool bar and title bar. */
700 if (r.size.height
701 + FRAME_NS_TITLEBAR_HEIGHT (f)
702 + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height)
703 {
704 bp = [[NSBezierPath bezierPathWithRect: r] retain];
705 [bp setClip];
706 [bp release];
707 }
697 } 708 }
698#endif 709#endif
699 710
@@ -711,10 +722,10 @@ ns_update_window_begin (struct window *w)
711 -------------------------------------------------------------------------- */ 722 -------------------------------------------------------------------------- */
712{ 723{
713 struct frame *f = XFRAME (WINDOW_FRAME (w)); 724 struct frame *f = XFRAME (WINDOW_FRAME (w));
714 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); 725 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
726
715 NSTRACE (ns_update_window_begin); 727 NSTRACE (ns_update_window_begin);
716 updated_window = w; 728 w->output_cursor = w->cursor;
717 set_output_cursor (&w->cursor);
718 729
719 block_input (); 730 block_input ();
720 731
@@ -736,15 +747,13 @@ ns_update_window_begin (struct window *w)
736 747
737 748
738static void 749static void
739ns_update_window_end (struct window *w, int cursor_on_p, 750ns_update_window_end (struct window *w, bool cursor_on_p,
740 int mouse_face_overwritten_p) 751 bool mouse_face_overwritten_p)
741/* -------------------------------------------------------------------------- 752/* --------------------------------------------------------------------------
742 Finished a grouped sequence of drawing calls 753 Finished a grouped sequence of drawing calls
743 external (RIF) call; for one window called before update_end 754 external (RIF) call; for one window called before update_end
744 -------------------------------------------------------------------------- */ 755 -------------------------------------------------------------------------- */
745{ 756{
746 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
747
748 /* note: this fn is nearly identical in all terms */ 757 /* note: this fn is nearly identical in all terms */
749 if (!w->pseudo_window_p) 758 if (!w->pseudo_window_p)
750 { 759 {
@@ -752,8 +761,8 @@ ns_update_window_end (struct window *w, int cursor_on_p,
752 761
753 if (cursor_on_p) 762 if (cursor_on_p)
754 display_and_set_cursor (w, 1, 763 display_and_set_cursor (w, 1,
755 output_cursor.hpos, output_cursor.vpos, 764 w->output_cursor.hpos, w->output_cursor.vpos,
756 output_cursor.x, output_cursor.y); 765 w->output_cursor.x, w->output_cursor.y);
757 766
758 if (draw_window_fringes (w, 1)) 767 if (draw_window_fringes (w, 1))
759 x_draw_vertical_border (w); 768 x_draw_vertical_border (w);
@@ -764,13 +773,8 @@ ns_update_window_end (struct window *w, int cursor_on_p,
764 /* If a row with mouse-face was overwritten, arrange for 773 /* If a row with mouse-face was overwritten, arrange for
765 frame_up_to_date to redisplay the mouse highlight. */ 774 frame_up_to_date to redisplay the mouse highlight. */
766 if (mouse_face_overwritten_p) 775 if (mouse_face_overwritten_p)
767 { 776 reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame)));
768 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
769 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
770 hlinfo->mouse_face_window = Qnil;
771 }
772 777
773 updated_window = NULL;
774 NSTRACE (update_window_end); 778 NSTRACE (update_window_end);
775} 779}
776 780
@@ -785,9 +789,9 @@ ns_update_end (struct frame *f)
785 EmacsView *view = FRAME_NS_VIEW (f); 789 EmacsView *view = FRAME_NS_VIEW (f);
786 790
787/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ 791/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
788 MOUSE_HL_INFO (f)->mouse_face_defer = 0; 792 MOUSE_HL_INFO (f)->mouse_face_defer = 0;
789 793
790 block_input (); 794 block_input ();
791 795
792 [view unlockFocus]; 796 [view unlockFocus];
793 [[view window] flushWindow]; 797 [[view window] flushWindow];
@@ -886,7 +890,8 @@ ns_unfocus (struct frame *f)
886 890
887 891
888static void 892static void
889ns_clip_to_row (struct window *w, struct glyph_row *row, int area, BOOL gc) 893ns_clip_to_row (struct window *w, struct glyph_row *row,
894 enum glyph_row_area area, BOOL gc)
890/* -------------------------------------------------------------------------- 895/* --------------------------------------------------------------------------
891 Internal (but parallels other terms): Focus drawing on given row 896 Internal (but parallels other terms): Focus drawing on given row
892 -------------------------------------------------------------------------- */ 897 -------------------------------------------------------------------------- */
@@ -955,24 +960,6 @@ ns_ring_bell (struct frame *f)
955 } 960 }
956} 961}
957 962
958
959static void
960ns_reset_terminal_modes (struct terminal *terminal)
961/* Externally called as hook */
962{
963 NSTRACE (ns_reset_terminal_modes);
964}
965
966
967static void
968ns_set_terminal_modes (struct terminal *terminal)
969/* Externally called as hook */
970{
971 NSTRACE (ns_set_terminal_modes);
972}
973
974
975
976/* ========================================================================== 963/* ==========================================================================
977 964
978 Frame / window manager related functions 965 Frame / window manager related functions
@@ -1178,12 +1165,7 @@ x_free_frame_resources (struct frame *f)
1178 if (f == dpyinfo->x_highlight_frame) 1165 if (f == dpyinfo->x_highlight_frame)
1179 dpyinfo->x_highlight_frame = 0; 1166 dpyinfo->x_highlight_frame = 0;
1180 if (f == hlinfo->mouse_face_mouse_frame) 1167 if (f == hlinfo->mouse_face_mouse_frame)
1181 { 1168 reset_mouse_highlight (hlinfo);
1182 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1183 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1184 hlinfo->mouse_face_window = Qnil;
1185 hlinfo->mouse_face_mouse_frame = 0;
1186 }
1187 1169
1188 if (f->output_data.ns->miniimage != nil) 1170 if (f->output_data.ns->miniimage != nil)
1189 [f->output_data.ns->miniimage release]; 1171 [f->output_data.ns->miniimage release];
@@ -1995,9 +1977,6 @@ ns_clear_frame (struct frame *f)
1995 1977
1996 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); 1978 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
1997 1979
1998 output_cursor.hpos = output_cursor.vpos = 0;
1999 output_cursor.x = -1;
2000
2001 r = [view bounds]; 1980 r = [view bounds];
2002 1981
2003 block_input (); 1982 block_input ();
@@ -2053,7 +2032,7 @@ ns_scroll_run (struct window *w, struct run *run)
2053 /* Get frame-relative bounding box of the text display area of W, 2032 /* Get frame-relative bounding box of the text display area of W,
2054 without mode lines. Include in this box the left and right 2033 without mode lines. Include in this box the left and right
2055 fringe of W. */ 2034 fringe of W. */
2056 window_box (w, -1, &x, &y, &width, &height); 2035 window_box (w, ANY_AREA, &x, &y, &width, &height);
2057 2036
2058 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); 2037 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
2059 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); 2038 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
@@ -2084,7 +2063,6 @@ ns_scroll_run (struct window *w, struct run *run)
2084 2063
2085 block_input (); 2064 block_input ();
2086 2065
2087 updated_window = w;
2088 x_clear_cursor (w); 2066 x_clear_cursor (w);
2089 2067
2090 { 2068 {
@@ -2102,12 +2080,11 @@ ns_scroll_run (struct window *w, struct run *run)
2102 2080
2103 2081
2104static void 2082static void
2105ns_after_update_window_line (struct glyph_row *desired_row) 2083ns_after_update_window_line (struct window *w, struct glyph_row *desired_row)
2106/* -------------------------------------------------------------------------- 2084/* --------------------------------------------------------------------------
2107 External (RIF): preparatory to fringe update after text was updated 2085 External (RIF): preparatory to fringe update after text was updated
2108 -------------------------------------------------------------------------- */ 2086 -------------------------------------------------------------------------- */
2109{ 2087{
2110 struct window *w = updated_window;
2111 struct frame *f; 2088 struct frame *f;
2112 int width, height; 2089 int width, height;
2113 2090
@@ -2230,7 +2207,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2230 } 2207 }
2231 2208
2232 /* Must clip because of partially visible lines. */ 2209 /* Must clip because of partially visible lines. */
2233 ns_clip_to_row (w, row, -1, YES); 2210 ns_clip_to_row (w, row, ANY_AREA, YES);
2234 2211
2235 if (!p->overlay_p) 2212 if (!p->overlay_p)
2236 { 2213 {
@@ -2338,8 +2315,8 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2338 2315
2339static void 2316static void
2340ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, 2317ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2341 int x, int y, int cursor_type, int cursor_width, 2318 int x, int y, enum text_cursor_kinds cursor_type,
2342 int on_p, int active_p) 2319 int cursor_width, bool on_p, bool active_p)
2343/* -------------------------------------------------------------------------- 2320/* --------------------------------------------------------------------------
2344 External call (RIF): draw cursor. 2321 External call (RIF): draw cursor.
2345 Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. 2322 Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
@@ -2410,7 +2387,7 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2410 2387
2411 /* TODO: only needed in rare cases with last-resort font in HELLO.. 2388 /* TODO: only needed in rare cases with last-resort font in HELLO..
2412 should we do this more efficiently? */ 2389 should we do this more efficiently? */
2413 ns_clip_to_row (w, glyph_row, -1, NO); /* do ns_focus(f, &r, 1); if remove */ 2390 ns_clip_to_row (w, glyph_row, ANY_AREA, NO); /* do ns_focus(f, &r, 1); if remove */
2414 2391
2415 2392
2416 face = FACE_FROM_ID (f, phys_cursor_glyph->face_id); 2393 face = FACE_FROM_ID (f, phys_cursor_glyph->face_id);
@@ -3391,12 +3368,6 @@ check_native_fs ()
3391/* GNUStep and OSX <= 10.4 does not have cancelTracking. */ 3368/* GNUStep and OSX <= 10.4 does not have cancelTracking. */
3392#if defined (NS_IMPL_COCOA) && \ 3369#if defined (NS_IMPL_COCOA) && \
3393 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 3370 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
3394const char *
3395ns_get_pending_menu_title ()
3396{
3397 return menu_pending_title;
3398}
3399
3400/* Check if menu open should be cancelled or continued as normal. */ 3371/* Check if menu open should be cancelled or continued as normal. */
3401void 3372void
3402ns_check_menu_open (NSMenu *menu) 3373ns_check_menu_open (NSMenu *menu)
@@ -3405,6 +3376,14 @@ ns_check_menu_open (NSMenu *menu)
3405 NSArray *a = [[NSApp mainMenu] itemArray]; 3376 NSArray *a = [[NSApp mainMenu] itemArray];
3406 int i; 3377 int i;
3407 BOOL found = NO; 3378 BOOL found = NO;
3379
3380 if (menu == nil) // Menu tracking ended.
3381 {
3382 if (menu_will_open_state == MENU_OPENING)
3383 menu_will_open_state = MENU_NONE;
3384 return;
3385 }
3386
3408 for (i = 0; ! found && i < [a count]; i++) 3387 for (i = 0; ! found && i < [a count]; i++)
3409 found = menu == [[a objectAtIndex:i] submenu]; 3388 found = menu == [[a objectAtIndex:i] submenu];
3410 if (found) 3389 if (found)
@@ -3422,8 +3401,6 @@ ns_check_menu_open (NSMenu *menu)
3422 CGEventRef ourEvent = CGEventCreate (NULL); 3401 CGEventRef ourEvent = CGEventCreate (NULL);
3423 menu_mouse_point = CGEventGetLocation (ourEvent); 3402 menu_mouse_point = CGEventGetLocation (ourEvent);
3424 CFRelease (ourEvent); 3403 CFRelease (ourEvent);
3425 xfree (menu_pending_title);
3426 menu_pending_title = xstrdup ([[menu title] UTF8String]);
3427 } 3404 }
3428 else if (menu_will_open_state == MENU_OPENING) 3405 else if (menu_will_open_state == MENU_OPENING)
3429 { 3406 {
@@ -3537,7 +3514,8 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3537 3514
3538int 3515int
3539ns_select (int nfds, fd_set *readfds, fd_set *writefds, 3516ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3540 fd_set *exceptfds, EMACS_TIME *timeout, sigset_t *sigmask) 3517 fd_set *exceptfds, struct timespec const *timeout,
3518 sigset_t const *sigmask)
3541/* -------------------------------------------------------------------------- 3519/* --------------------------------------------------------------------------
3542 Replacement for select, checking for events 3520 Replacement for select, checking for events
3543 -------------------------------------------------------------------------- */ 3521 -------------------------------------------------------------------------- */
@@ -3607,7 +3585,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3607 else if (nr == 0 && timeout) 3585 else if (nr == 0 && timeout)
3608 { 3586 {
3609 /* No file descriptor, just a timeout, no need to wake fd_handler */ 3587 /* No file descriptor, just a timeout, no need to wake fd_handler */
3610 double time = EMACS_TIME_TO_DOUBLE (*timeout); 3588 double time = timespectod (*timeout);
3611 timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time 3589 timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time
3612 target: NSApp 3590 target: NSApp
3613 selector: 3591 selector:
@@ -3663,7 +3641,6 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3663 pthread_mutex_lock (&select_mutex); 3641 pthread_mutex_lock (&select_mutex);
3664 if (readfds) *readfds = select_readfds; 3642 if (readfds) *readfds = select_readfds;
3665 if (writefds) *writefds = select_writefds; 3643 if (writefds) *writefds = select_writefds;
3666 if (timeout) *timeout = select_timeout;
3667 pthread_mutex_unlock (&select_mutex); 3644 pthread_mutex_unlock (&select_mutex);
3668 result = t; 3645 result = t;
3669 } 3646 }
@@ -3721,7 +3698,7 @@ ns_set_vertical_scroll_bar (struct window *window,
3721 NSTRACE (ns_set_vertical_scroll_bar); 3698 NSTRACE (ns_set_vertical_scroll_bar);
3722 3699
3723 /* Get dimensions. */ 3700 /* Get dimensions. */
3724 window_box (window, -1, 0, &window_y, 0, &window_height); 3701 window_box (window, ANY_AREA, 0, &window_y, 0, &window_height);
3725 top = window_y; 3702 top = window_y;
3726 height = window_height; 3703 height = window_height;
3727 width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f); 3704 width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f);
@@ -3737,16 +3714,7 @@ ns_set_vertical_scroll_bar (struct window *window,
3737 v = [view frame]; 3714 v = [view frame];
3738 r.origin.y = (v.size.height - r.size.height - r.origin.y); 3715 r.origin.y = (v.size.height - r.size.height - r.origin.y);
3739 3716
3740 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (window)) 3717 fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (window);
3741 fringe_extended_p = (WINDOW_LEFTMOST_P (window)
3742 && WINDOW_LEFT_FRINGE_WIDTH (window)
3743 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window)
3744 || WINDOW_LEFT_MARGIN_COLS (window) == 0));
3745 else
3746 fringe_extended_p = (WINDOW_RIGHTMOST_P (window)
3747 && WINDOW_RIGHT_FRINGE_WIDTH (window)
3748 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window)
3749 || WINDOW_RIGHT_MARGIN_COLS (window) == 0));
3750 3718
3751 XSETWINDOW (win, window); 3719 XSETWINDOW (win, window);
3752 block_input (); 3720 block_input ();
@@ -3957,7 +3925,6 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo)
3957{ 3925{
3958 NSScreen *screen = [NSScreen mainScreen]; 3926 NSScreen *screen = [NSScreen mainScreen];
3959 NSWindowDepth depth = [screen depth]; 3927 NSWindowDepth depth = [screen depth];
3960 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
3961 3928
3962 dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */ 3929 dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */
3963 dpyinfo->resy = 72.27; 3930 dpyinfo->resy = 72.27;
@@ -3970,22 +3937,12 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo)
3970 dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table); 3937 dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table);
3971 dpyinfo->color_table->colors = NULL; 3938 dpyinfo->color_table->colors = NULL;
3972 dpyinfo->root_window = 42; /* a placeholder.. */ 3939 dpyinfo->root_window = 42; /* a placeholder.. */
3973
3974 hlinfo->mouse_face_mouse_frame = NULL;
3975 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
3976 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
3977 hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
3978 hlinfo->mouse_face_window = hlinfo->mouse_face_overlay = Qnil;
3979 hlinfo->mouse_face_hidden = 0;
3980
3981 hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
3982 hlinfo->mouse_face_defer = 0;
3983
3984 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL; 3940 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL;
3985
3986 dpyinfo->n_fonts = 0; 3941 dpyinfo->n_fonts = 0;
3987 dpyinfo->smallest_font_height = 1; 3942 dpyinfo->smallest_font_height = 1;
3988 dpyinfo->smallest_char_width = 1; 3943 dpyinfo->smallest_char_width = 1;
3944
3945 reset_mouse_highlight (&dpyinfo->mouse_highlight);
3989} 3946}
3990 3947
3991 3948
@@ -4006,7 +3963,6 @@ static struct redisplay_interface ns_redisplay_interface =
4006 ns_after_update_window_line, 3963 ns_after_update_window_line,
4007 ns_update_window_begin, 3964 ns_update_window_begin,
4008 ns_update_window_end, 3965 ns_update_window_end,
4009 x_cursor_to,
4010 ns_flush, 3966 ns_flush,
4011 0, /* flush_display_optional */ 3967 0, /* flush_display_optional */
4012 x_clear_window_mouse_face, 3968 x_clear_window_mouse_face,
@@ -4073,8 +4029,8 @@ ns_create_terminal (struct ns_display_info *dpyinfo)
4073 terminal->ins_del_lines_hook = 0; /* XXX vestigial? */ 4029 terminal->ins_del_lines_hook = 0; /* XXX vestigial? */
4074 terminal->delete_glyphs_hook = 0; /* XXX vestigial? */ 4030 terminal->delete_glyphs_hook = 0; /* XXX vestigial? */
4075 terminal->ring_bell_hook = ns_ring_bell; 4031 terminal->ring_bell_hook = ns_ring_bell;
4076 terminal->reset_terminal_modes_hook = ns_reset_terminal_modes; 4032 terminal->reset_terminal_modes_hook = NULL;
4077 terminal->set_terminal_modes_hook = ns_set_terminal_modes; 4033 terminal->set_terminal_modes_hook = NULL;
4078 terminal->update_begin_hook = ns_update_begin; 4034 terminal->update_begin_hook = ns_update_begin;
4079 terminal->update_end_hook = ns_update_end; 4035 terminal->update_end_hook = ns_update_end;
4080 terminal->set_terminal_window_hook = NULL; /* XXX vestigial? */ 4036 terminal->set_terminal_window_hook = NULL; /* XXX vestigial? */
@@ -4714,8 +4670,8 @@ not_in_argv (NSString *arg)
4714 int waiting = 1, nfds; 4670 int waiting = 1, nfds;
4715 char c; 4671 char c;
4716 4672
4717 SELECT_TYPE readfds, writefds, *wfds; 4673 fd_set readfds, writefds, *wfds;
4718 EMACS_TIME timeout, *tmo; 4674 struct timespec timeout, *tmo;
4719 NSAutoreleasePool *pool = nil; 4675 NSAutoreleasePool *pool = nil;
4720 4676
4721 /* NSTRACE (fd_handler); */ 4677 /* NSTRACE (fd_handler); */
@@ -4727,7 +4683,7 @@ not_in_argv (NSString *arg)
4727 4683
4728 if (waiting) 4684 if (waiting)
4729 { 4685 {
4730 SELECT_TYPE fds; 4686 fd_set fds;
4731 FD_ZERO (&fds); 4687 FD_ZERO (&fds);
4732 FD_SET (selfds[0], &fds); 4688 FD_SET (selfds[0], &fds);
4733 result = select (selfds[0]+1, &fds, NULL, NULL, NULL); 4689 result = select (selfds[0]+1, &fds, NULL, NULL, NULL);
@@ -5496,6 +5452,30 @@ not_in_argv (NSString *arg)
5496 previous_help_echo_string = help_echo_string; 5452 previous_help_echo_string = help_echo_string;
5497 help_echo_string = Qnil; 5453 help_echo_string = Qnil;
5498 5454
5455 if (!NILP (Vmouse_autoselect_window))
5456 {
5457 NSTRACE (mouse_autoselect_window);
5458 static Lisp_Object last_mouse_window;
5459 Lisp_Object window = window_from_coordinates
5460 (emacsframe, last_mouse_motion_position.x,
5461 last_mouse_motion_position.y, 0, 0);
5462
5463 if (WINDOWP (window)
5464 && !EQ (window, last_mouse_window)
5465 && !EQ (window, selected_window)
5466 && (focus_follows_mouse
5467 || (EQ (XWINDOW (window)->frame,
5468 XWINDOW (selected_window)->frame))))
5469 {
5470 NSTRACE (in_window);
5471 emacs_event->kind = SELECT_WINDOW_EVENT;
5472 emacs_event->frame_or_window = window;
5473 EV_TRAILER2 (e);
5474 }
5475 /* Remember the last window where we saw the mouse. */
5476 last_mouse_window = window;
5477 }
5478
5499 if (!note_mouse_movement (emacsframe, last_mouse_motion_position.x, 5479 if (!note_mouse_movement (emacsframe, last_mouse_motion_position.x,
5500 last_mouse_motion_position.y)) 5480 last_mouse_motion_position.y))
5501 help_echo_string = previous_help_echo_string; 5481 help_echo_string = previous_help_echo_string;
diff --git a/src/print.c b/src/print.c
index 80f1bb6beb4..4ad34534da3 100644
--- a/src/print.c
+++ b/src/print.c
@@ -124,7 +124,8 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
124 set_buffer_internal (XMARKER (printcharfun)->buffer); \ 124 set_buffer_internal (XMARKER (printcharfun)->buffer); \
125 marker_pos = marker_position (printcharfun); \ 125 marker_pos = marker_position (printcharfun); \
126 if (marker_pos < BEGV || marker_pos > ZV) \ 126 if (marker_pos < BEGV || marker_pos > ZV) \
127 error ("Marker is outside the accessible part of the buffer"); \ 127 signal_error ("Marker is outside the accessible " \
128 "part of the buffer", printcharfun); \
128 old_point = PT; \ 129 old_point = PT; \
129 old_point_byte = PT_BYTE; \ 130 old_point_byte = PT_BYTE; \
130 SET_PT_BOTH (marker_pos, \ 131 SET_PT_BOTH (marker_pos, \
@@ -136,10 +137,10 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
136 if (NILP (printcharfun)) \ 137 if (NILP (printcharfun)) \
137 { \ 138 { \
138 Lisp_Object string; \ 139 Lisp_Object string; \
139 if (NILP (BVAR (current_buffer, enable_multibyte_characters)) \ 140 if (NILP (BVAR (current_buffer, enable_multibyte_characters)) \
140 && ! print_escape_multibyte) \ 141 && ! print_escape_multibyte) \
141 specbind (Qprint_escape_multibyte, Qt); \ 142 specbind (Qprint_escape_multibyte, Qt); \
142 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)) \ 143 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)) \
143 && ! print_escape_nonascii) \ 144 && ! print_escape_nonascii) \
144 specbind (Qprint_escape_nonascii, Qt); \ 145 specbind (Qprint_escape_nonascii, Qt); \
145 if (print_buffer != 0) \ 146 if (print_buffer != 0) \
@@ -166,7 +167,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
166 if (NILP (printcharfun)) \ 167 if (NILP (printcharfun)) \
167 { \ 168 { \
168 if (print_buffer_pos != print_buffer_pos_byte \ 169 if (print_buffer_pos != print_buffer_pos_byte \
169 && NILP (BVAR (current_buffer, enable_multibyte_characters))) \ 170 && NILP (BVAR (current_buffer, enable_multibyte_characters)))\
170 { \ 171 { \
171 unsigned char *temp = alloca (print_buffer_pos + 1); \ 172 unsigned char *temp = alloca (print_buffer_pos + 1); \
172 copy_text ((unsigned char *) print_buffer, temp, \ 173 copy_text ((unsigned char *) print_buffer, temp, \
diff --git a/src/process.c b/src/process.c
index d87a1803fe2..20f84990d6f 100644
--- a/src/process.c
+++ b/src/process.c
@@ -92,6 +92,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
92 92
93#include <c-ctype.h> 93#include <c-ctype.h>
94#include <sig2str.h> 94#include <sig2str.h>
95#include <verify.h>
95 96
96#endif /* subprocesses */ 97#endif /* subprocesses */
97 98
@@ -131,8 +132,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
131#endif 132#endif
132 133
133#ifdef WINDOWSNT 134#ifdef WINDOWSNT
134extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, 135extern int sys_select (int, fd_set *, fd_set *, fd_set *,
135 EMACS_TIME *, void *); 136 struct timespec *, void *);
136#endif 137#endif
137 138
138#ifndef SOCK_CLOEXEC 139#ifndef SOCK_CLOEXEC
@@ -260,7 +261,7 @@ static EMACS_INT update_tick;
260#endif 261#endif
261 262
262#ifdef ADAPTIVE_READ_BUFFERING 263#ifdef ADAPTIVE_READ_BUFFERING
263#define READ_OUTPUT_DELAY_INCREMENT (EMACS_TIME_RESOLUTION / 100) 264#define READ_OUTPUT_DELAY_INCREMENT (TIMESPEC_RESOLUTION / 100)
264#define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5) 265#define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5)
265#define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7) 266#define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7)
266 267
@@ -279,7 +280,7 @@ static bool process_output_skip;
279 280
280static void create_process (Lisp_Object, char **, Lisp_Object); 281static void create_process (Lisp_Object, char **, Lisp_Object);
281#ifdef USABLE_SIGIO 282#ifdef USABLE_SIGIO
282static bool keyboard_bit_set (SELECT_TYPE *); 283static bool keyboard_bit_set (fd_set *);
283#endif 284#endif
284static void deactivate_process (Lisp_Object); 285static void deactivate_process (Lisp_Object);
285static void status_notify (struct Lisp_Process *); 286static void status_notify (struct Lisp_Process *);
@@ -298,39 +299,39 @@ static void exec_sentinel (Lisp_Object proc, Lisp_Object reason);
298 299
299/* Mask of bits indicating the descriptors that we wait for input on. */ 300/* Mask of bits indicating the descriptors that we wait for input on. */
300 301
301static SELECT_TYPE input_wait_mask; 302static fd_set input_wait_mask;
302 303
303/* Mask that excludes keyboard input descriptor(s). */ 304/* Mask that excludes keyboard input descriptor(s). */
304 305
305static SELECT_TYPE non_keyboard_wait_mask; 306static fd_set non_keyboard_wait_mask;
306 307
307/* Mask that excludes process input descriptor(s). */ 308/* Mask that excludes process input descriptor(s). */
308 309
309static SELECT_TYPE non_process_wait_mask; 310static fd_set non_process_wait_mask;
310 311
311/* Mask for selecting for write. */ 312/* Mask for selecting for write. */
312 313
313static SELECT_TYPE write_mask; 314static fd_set write_mask;
314 315
315#ifdef NON_BLOCKING_CONNECT 316#ifdef NON_BLOCKING_CONNECT
316/* Mask of bits indicating the descriptors that we wait for connect to 317/* Mask of bits indicating the descriptors that we wait for connect to
317 complete on. Once they complete, they are removed from this mask 318 complete on. Once they complete, they are removed from this mask
318 and added to the input_wait_mask and non_keyboard_wait_mask. */ 319 and added to the input_wait_mask and non_keyboard_wait_mask. */
319 320
320static SELECT_TYPE connect_wait_mask; 321static fd_set connect_wait_mask;
321 322
322/* Number of bits set in connect_wait_mask. */ 323/* Number of bits set in connect_wait_mask. */
323static int num_pending_connects; 324static int num_pending_connects;
324#endif /* NON_BLOCKING_CONNECT */ 325#endif /* NON_BLOCKING_CONNECT */
325 326
326/* The largest descriptor currently in use for a process object. */ 327/* The largest descriptor currently in use for a process object; -1 if none. */
327static int max_process_desc; 328static int max_process_desc;
328 329
329/* The largest descriptor currently in use for input. */ 330/* The largest descriptor currently in use for input; -1 if none. */
330static int max_input_desc; 331static int max_input_desc;
331 332
332/* Indexed by descriptor, gives the process (if any) for that descriptor */ 333/* Indexed by descriptor, gives the process (if any) for that descriptor */
333static Lisp_Object chan_process[MAXDESC]; 334static Lisp_Object chan_process[FD_SETSIZE];
334 335
335/* Alist of elements (NAME . PROCESS) */ 336/* Alist of elements (NAME . PROCESS) */
336static Lisp_Object Vprocess_alist; 337static Lisp_Object Vprocess_alist;
@@ -341,18 +342,18 @@ static Lisp_Object Vprocess_alist;
341 output from the process is to read at least one char. 342 output from the process is to read at least one char.
342 Always -1 on systems that support FIONREAD. */ 343 Always -1 on systems that support FIONREAD. */
343 344
344static int proc_buffered_char[MAXDESC]; 345static int proc_buffered_char[FD_SETSIZE];
345 346
346/* Table of `struct coding-system' for each process. */ 347/* Table of `struct coding-system' for each process. */
347static struct coding_system *proc_decode_coding_system[MAXDESC]; 348static struct coding_system *proc_decode_coding_system[FD_SETSIZE];
348static struct coding_system *proc_encode_coding_system[MAXDESC]; 349static struct coding_system *proc_encode_coding_system[FD_SETSIZE];
349 350
350#ifdef DATAGRAM_SOCKETS 351#ifdef DATAGRAM_SOCKETS
351/* Table of `partner address' for datagram sockets. */ 352/* Table of `partner address' for datagram sockets. */
352static struct sockaddr_and_len { 353static struct sockaddr_and_len {
353 struct sockaddr *sa; 354 struct sockaddr *sa;
354 int len; 355 int len;
355} datagram_address[MAXDESC]; 356} datagram_address[FD_SETSIZE];
356#define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0) 357#define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0)
357#define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XPROCESS (proc)->infd].sa != 0) 358#define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XPROCESS (proc)->infd].sa != 0)
358#else 359#else
@@ -360,6 +361,12 @@ static struct sockaddr_and_len {
360#define DATAGRAM_CONN_P(proc) (0) 361#define DATAGRAM_CONN_P(proc) (0)
361#endif 362#endif
362 363
364/* FOR_EACH_PROCESS (LIST_VAR, PROC_VAR) followed by a statement is
365 a `for' loop which iterates over processes from Vprocess_alist. */
366
367#define FOR_EACH_PROCESS(list_var, proc_var) \
368 FOR_EACH_ALIST_VALUE (Vprocess_alist, list_var, proc_var)
369
363/* These setters are used only in this file, so they can be private. */ 370/* These setters are used only in this file, so they can be private. */
364static void 371static void
365pset_buffer (struct Lisp_Process *p, Lisp_Object val) 372pset_buffer (struct Lisp_Process *p, Lisp_Object val)
@@ -451,7 +458,7 @@ static struct fd_callback_data
451#define FOR_READ 1 458#define FOR_READ 1
452#define FOR_WRITE 2 459#define FOR_WRITE 2
453 int condition; /* mask of the defines above. */ 460 int condition; /* mask of the defines above. */
454} fd_callback_info[MAXDESC]; 461} fd_callback_info[FD_SETSIZE];
455 462
456 463
457/* Add a file descriptor FD to be monitored for when read is possible. 464/* Add a file descriptor FD to be monitored for when read is possible.
@@ -460,7 +467,7 @@ static struct fd_callback_data
460void 467void
461add_read_fd (int fd, fd_callback func, void *data) 468add_read_fd (int fd, fd_callback func, void *data)
462{ 469{
463 eassert (fd < MAXDESC); 470 eassert (fd < FD_SETSIZE);
464 add_keyboard_wait_descriptor (fd); 471 add_keyboard_wait_descriptor (fd);
465 472
466 fd_callback_info[fd].func = func; 473 fd_callback_info[fd].func = func;
@@ -473,7 +480,7 @@ add_read_fd (int fd, fd_callback func, void *data)
473void 480void
474delete_read_fd (int fd) 481delete_read_fd (int fd)
475{ 482{
476 eassert (fd < MAXDESC); 483 eassert (fd < FD_SETSIZE);
477 delete_keyboard_wait_descriptor (fd); 484 delete_keyboard_wait_descriptor (fd);
478 485
479 fd_callback_info[fd].condition &= ~FOR_READ; 486 fd_callback_info[fd].condition &= ~FOR_READ;
@@ -490,7 +497,7 @@ delete_read_fd (int fd)
490void 497void
491add_write_fd (int fd, fd_callback func, void *data) 498add_write_fd (int fd, fd_callback func, void *data)
492{ 499{
493 eassert (fd < MAXDESC); 500 eassert (fd < FD_SETSIZE);
494 FD_SET (fd, &write_mask); 501 FD_SET (fd, &write_mask);
495 if (fd > max_input_desc) 502 if (fd > max_input_desc)
496 max_input_desc = fd; 503 max_input_desc = fd;
@@ -500,29 +507,35 @@ add_write_fd (int fd, fd_callback func, void *data)
500 fd_callback_info[fd].condition |= FOR_WRITE; 507 fd_callback_info[fd].condition |= FOR_WRITE;
501} 508}
502 509
510/* FD is no longer an input descriptor; update max_input_desc accordingly. */
511
512static void
513delete_input_desc (int fd)
514{
515 if (fd == max_input_desc)
516 {
517 do
518 fd--;
519 while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask)
520 || FD_ISSET (fd, &write_mask)));
521
522 max_input_desc = fd;
523 }
524}
525
503/* Stop monitoring file descriptor FD for when write is possible. */ 526/* Stop monitoring file descriptor FD for when write is possible. */
504 527
505void 528void
506delete_write_fd (int fd) 529delete_write_fd (int fd)
507{ 530{
508 int lim = max_input_desc; 531 eassert (fd < FD_SETSIZE);
509
510 eassert (fd < MAXDESC);
511 FD_CLR (fd, &write_mask); 532 FD_CLR (fd, &write_mask);
512 fd_callback_info[fd].condition &= ~FOR_WRITE; 533 fd_callback_info[fd].condition &= ~FOR_WRITE;
513 if (fd_callback_info[fd].condition == 0) 534 if (fd_callback_info[fd].condition == 0)
514 { 535 {
515 fd_callback_info[fd].func = 0; 536 fd_callback_info[fd].func = 0;
516 fd_callback_info[fd].data = 0; 537 fd_callback_info[fd].data = 0;
517 538 delete_input_desc (fd);
518 if (fd == max_input_desc)
519 for (fd = lim; fd >= 0; fd--)
520 if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
521 {
522 max_input_desc = fd;
523 break;
524 }
525
526 } 539 }
527} 540}
528 541
@@ -674,6 +687,15 @@ allocate_pty (char pty_name[PTY_NAME_SIZE])
674 687
675 if (fd >= 0) 688 if (fd >= 0)
676 { 689 {
690#ifdef PTY_OPEN
691 /* Set FD's close-on-exec flag. This is needed even if
692 PT_OPEN calls posix_openpt with O_CLOEXEC, since POSIX
693 doesn't require support for that combination.
694 Multithreaded platforms where posix_openpt ignores
695 O_CLOEXEC (or where PTY_OPEN doesn't call posix_openpt)
696 have a race condition between the PTY_OPEN and here. */
697 fcntl (fd, F_SETFD, FD_CLOEXEC);
698#endif
677 /* check to make certain that both sides are available 699 /* check to make certain that both sides are available
678 this avoids a nasty yet stupid bug in rlogins */ 700 this avoids a nasty yet stupid bug in rlogins */
679#ifdef PTY_TTY_NAME_SPRINTF 701#ifdef PTY_TTY_NAME_SPRINTF
@@ -716,6 +738,8 @@ make_process (Lisp_Object name)
716 non-Lisp data, so do it only for slots which should not be zero. */ 738 non-Lisp data, so do it only for slots which should not be zero. */
717 p->infd = -1; 739 p->infd = -1;
718 p->outfd = -1; 740 p->outfd = -1;
741 for (i = 0; i < PROCESS_OPEN_FDS; i++)
742 p->open_fd[i] = -1;
719 743
720#ifdef HAVE_GNUTLS 744#ifdef HAVE_GNUTLS
721 p->gnutls_initstage = GNUTLS_STAGE_EMPTY; 745 p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
@@ -812,13 +836,17 @@ get_process (register Lisp_Object name)
812 treated by the SIGCHLD handler and waitpid has been invoked on them; 836 treated by the SIGCHLD handler and waitpid has been invoked on them;
813 otherwise they might fill up the kernel's process table. 837 otherwise they might fill up the kernel's process table.
814 838
815 Some processes created by call-process are also put onto this list. */ 839 Some processes created by call-process are also put onto this list.
840
841 Members of this list are (process-ID . filename) pairs. The
842 process-ID is a number; the filename, if a string, is a file that
843 needs to be removed after the process exits. */
816static Lisp_Object deleted_pid_list; 844static Lisp_Object deleted_pid_list;
817 845
818void 846void
819record_deleted_pid (pid_t pid) 847record_deleted_pid (pid_t pid, Lisp_Object filename)
820{ 848{
821 deleted_pid_list = Fcons (make_fixnum_or_float (pid), 849 deleted_pid_list = Fcons (Fcons (make_fixnum_or_float (pid), filename),
822 /* GC treated elements set to nil. */ 850 /* GC treated elements set to nil. */
823 Fdelq (Qnil, deleted_pid_list)); 851 Fdelq (Qnil, deleted_pid_list));
824 852
@@ -846,7 +874,7 @@ nil, indicating the current buffer's process. */)
846 else 874 else
847 { 875 {
848 if (p->alive) 876 if (p->alive)
849 record_kill_process (p); 877 record_kill_process (p, Qnil);
850 878
851 if (p->infd >= 0) 879 if (p->infd >= 0)
852 { 880 {
@@ -1112,15 +1140,18 @@ See `set-process-sentinel' for more info on sentinels. */)
1112DEFUN ("set-process-window-size", Fset_process_window_size, 1140DEFUN ("set-process-window-size", Fset_process_window_size,
1113 Sset_process_window_size, 3, 3, 0, 1141 Sset_process_window_size, 3, 3, 0,
1114 doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */) 1142 doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */)
1115 (register Lisp_Object process, Lisp_Object height, Lisp_Object width) 1143 (Lisp_Object process, Lisp_Object height, Lisp_Object width)
1116{ 1144{
1117 CHECK_PROCESS (process); 1145 CHECK_PROCESS (process);
1118 CHECK_RANGED_INTEGER (height, 0, INT_MAX); 1146
1119 CHECK_RANGED_INTEGER (width, 0, INT_MAX); 1147 /* All known platforms store window sizes as 'unsigned short'. */
1148 CHECK_RANGED_INTEGER (height, 0, USHRT_MAX);
1149 CHECK_RANGED_INTEGER (width, 0, USHRT_MAX);
1120 1150
1121 if (XPROCESS (process)->infd < 0 1151 if (XPROCESS (process)->infd < 0
1122 || set_window_size (XPROCESS (process)->infd, 1152 || (set_window_size (XPROCESS (process)->infd,
1123 XINT (height), XINT (width)) <= 0) 1153 XINT (height), XINT (width))
1154 < 0))
1124 return Qnil; 1155 return Qnil;
1125 else 1156 else
1126 return Qt; 1157 return Qt;
@@ -1380,22 +1411,9 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1380 function. The argument list is protected by the caller, so all 1411 function. The argument list is protected by the caller, so all
1381 we really have to worry about is buffer. */ 1412 we really have to worry about is buffer. */
1382 { 1413 {
1383 struct gcpro gcpro1, gcpro2; 1414 struct gcpro gcpro1;
1384 1415 GCPRO1 (buffer);
1385 current_dir = BVAR (current_buffer, directory); 1416 current_dir = encode_current_directory ();
1386
1387 GCPRO2 (buffer, current_dir);
1388
1389 current_dir = Funhandled_file_name_directory (current_dir);
1390 if (NILP (current_dir))
1391 /* If the file name handler says that current_dir is unreachable, use
1392 a sensible default. */
1393 current_dir = build_string ("~/");
1394 current_dir = expand_and_dir_to_file (current_dir, Qnil);
1395 if (NILP (Ffile_accessible_directory_p (current_dir)))
1396 report_file_error ("Setting current directory",
1397 BVAR (current_buffer, directory));
1398
1399 UNGCPRO; 1417 UNGCPRO;
1400 } 1418 }
1401 1419
@@ -1599,22 +1617,49 @@ start_process_unwind (Lisp_Object proc)
1599 remove_process (proc); 1617 remove_process (proc);
1600} 1618}
1601 1619
1620/* If *FD_ADDR is nonnegative, close it, and mark it as closed. */
1621
1622static void
1623close_process_fd (int *fd_addr)
1624{
1625 int fd = *fd_addr;
1626 if (0 <= fd)
1627 {
1628 *fd_addr = -1;
1629 emacs_close (fd);
1630 }
1631}
1632
1633/* Indexes of file descriptors in open_fds. */
1634enum
1635 {
1636 /* The pipe from Emacs to its subprocess. */
1637 SUBPROCESS_STDIN,
1638 WRITE_TO_SUBPROCESS,
1639
1640 /* The main pipe from the subprocess to Emacs. */
1641 READ_FROM_SUBPROCESS,
1642 SUBPROCESS_STDOUT,
1643
1644 /* The pipe from the subprocess to Emacs that is closed when the
1645 subprocess execs. */
1646 READ_FROM_EXEC_MONITOR,
1647 EXEC_MONITOR_OUTPUT
1648 };
1649
1650verify (PROCESS_OPEN_FDS == EXEC_MONITOR_OUTPUT + 1);
1602 1651
1603static void 1652static void
1604create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) 1653create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1605{ 1654{
1655 struct Lisp_Process *p = XPROCESS (process);
1606 int inchannel, outchannel; 1656 int inchannel, outchannel;
1607 pid_t pid; 1657 pid_t pid;
1608 int vfork_errno; 1658 int vfork_errno;
1609 int sv[2];
1610#ifndef WINDOWSNT
1611 int wait_child_setup[2];
1612#endif
1613 int forkin, forkout; 1659 int forkin, forkout;
1614 bool pty_flag = 0; 1660 bool pty_flag = 0;
1615 char pty_name[PTY_NAME_SIZE]; 1661 char pty_name[PTY_NAME_SIZE];
1616 Lisp_Object lisp_pty_name = Qnil; 1662 Lisp_Object lisp_pty_name = Qnil;
1617 Lisp_Object encoded_current_dir;
1618 1663
1619 inchannel = outchannel = -1; 1664 inchannel = outchannel = -1;
1620 1665
@@ -1623,6 +1668,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1623 1668
1624 if (inchannel >= 0) 1669 if (inchannel >= 0)
1625 { 1670 {
1671 p->open_fd[READ_FROM_SUBPROCESS] = inchannel;
1626#if ! defined (USG) || defined (USG_SUBTTY_WORKS) 1672#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
1627 /* On most USG systems it does not work to open the pty's tty here, 1673 /* On most USG systems it does not work to open the pty's tty here,
1628 then close it and reopen it in the child. */ 1674 then close it and reopen it in the child. */
@@ -1631,6 +1677,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1631 forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); 1677 forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
1632 if (forkin < 0) 1678 if (forkin < 0)
1633 report_file_error ("Opening pty", Qnil); 1679 report_file_error ("Opening pty", Qnil);
1680 p->open_fd[SUBPROCESS_STDIN] = forkin;
1634#else 1681#else
1635 forkin = forkout = -1; 1682 forkin = forkout = -1;
1636#endif /* not USG, or USG_SUBTTY_WORKS */ 1683#endif /* not USG, or USG_SUBTTY_WORKS */
@@ -1639,23 +1686,17 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1639 } 1686 }
1640 else 1687 else
1641 { 1688 {
1642 if (emacs_pipe (sv) != 0) 1689 if (emacs_pipe (p->open_fd + SUBPROCESS_STDIN) != 0
1690 || emacs_pipe (p->open_fd + READ_FROM_SUBPROCESS) != 0)
1643 report_file_error ("Creating pipe", Qnil); 1691 report_file_error ("Creating pipe", Qnil);
1644 inchannel = sv[0]; 1692 forkin = p->open_fd[SUBPROCESS_STDIN];
1645 forkout = sv[1]; 1693 outchannel = p->open_fd[WRITE_TO_SUBPROCESS];
1646 if (emacs_pipe (sv) != 0) 1694 inchannel = p->open_fd[READ_FROM_SUBPROCESS];
1647 { 1695 forkout = p->open_fd[SUBPROCESS_STDOUT];
1648 int pipe_errno = errno;
1649 emacs_close (inchannel);
1650 emacs_close (forkout);
1651 report_file_errno ("Creating pipe", Qnil, pipe_errno);
1652 }
1653 outchannel = sv[1];
1654 forkin = sv[0];
1655 } 1696 }
1656 1697
1657#ifndef WINDOWSNT 1698#ifndef WINDOWSNT
1658 if (emacs_pipe (wait_child_setup) != 0) 1699 if (emacs_pipe (p->open_fd + READ_FROM_EXEC_MONITOR) != 0)
1659 report_file_error ("Creating pipe", Qnil); 1700 report_file_error ("Creating pipe", Qnil);
1660#endif 1701#endif
1661 1702
@@ -1664,16 +1705,16 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1664 1705
1665 /* Record this as an active process, with its channels. */ 1706 /* Record this as an active process, with its channels. */
1666 chan_process[inchannel] = process; 1707 chan_process[inchannel] = process;
1667 XPROCESS (process)->infd = inchannel; 1708 p->infd = inchannel;
1668 XPROCESS (process)->outfd = outchannel; 1709 p->outfd = outchannel;
1669 1710
1670 /* Previously we recorded the tty descriptor used in the subprocess. 1711 /* Previously we recorded the tty descriptor used in the subprocess.
1671 It was only used for getting the foreground tty process, so now 1712 It was only used for getting the foreground tty process, so now
1672 we just reopen the device (see emacs_get_tty_pgrp) as this is 1713 we just reopen the device (see emacs_get_tty_pgrp) as this is
1673 more portable (see USG_SUBTTY_WORKS above). */ 1714 more portable (see USG_SUBTTY_WORKS above). */
1674 1715
1675 XPROCESS (process)->pty_flag = pty_flag; 1716 p->pty_flag = pty_flag;
1676 pset_status (XPROCESS (process), Qrun); 1717 pset_status (p, Qrun);
1677 1718
1678 FD_SET (inchannel, &input_wait_mask); 1719 FD_SET (inchannel, &input_wait_mask);
1679 FD_SET (inchannel, &non_keyboard_wait_mask); 1720 FD_SET (inchannel, &non_keyboard_wait_mask);
@@ -1683,35 +1724,29 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1683 /* This may signal an error. */ 1724 /* This may signal an error. */
1684 setup_process_coding_systems (process); 1725 setup_process_coding_systems (process);
1685 1726
1686 encoded_current_dir = ENCODE_FILE (current_dir);
1687
1688 block_input (); 1727 block_input ();
1689 block_child_signal (); 1728 block_child_signal ();
1690 1729
1691#ifndef WINDOWSNT 1730#ifndef WINDOWSNT
1692 /* vfork, and prevent local vars from being clobbered by the vfork. */ 1731 /* vfork, and prevent local vars from being clobbered by the vfork. */
1693 { 1732 {
1694 Lisp_Object volatile encoded_current_dir_volatile = encoded_current_dir; 1733 Lisp_Object volatile current_dir_volatile = current_dir;
1695 Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name; 1734 Lisp_Object volatile lisp_pty_name_volatile = lisp_pty_name;
1696 Lisp_Object volatile process_volatile = process;
1697 char **volatile new_argv_volatile = new_argv; 1735 char **volatile new_argv_volatile = new_argv;
1698 int volatile forkin_volatile = forkin; 1736 int volatile forkin_volatile = forkin;
1699 int volatile forkout_volatile = forkout; 1737 int volatile forkout_volatile = forkout;
1700 int volatile wait_child_setup_0_volatile = wait_child_setup[0]; 1738 struct Lisp_Process *p_volatile = p;
1701 int volatile wait_child_setup_1_volatile = wait_child_setup[1];
1702 1739
1703 pid = vfork (); 1740 pid = vfork ();
1704 1741
1705 encoded_current_dir = encoded_current_dir_volatile; 1742 current_dir = current_dir_volatile;
1706 lisp_pty_name = lisp_pty_name_volatile; 1743 lisp_pty_name = lisp_pty_name_volatile;
1707 process = process_volatile;
1708 new_argv = new_argv_volatile; 1744 new_argv = new_argv_volatile;
1709 forkin = forkin_volatile; 1745 forkin = forkin_volatile;
1710 forkout = forkout_volatile; 1746 forkout = forkout_volatile;
1711 wait_child_setup[0] = wait_child_setup_0_volatile; 1747 p = p_volatile;
1712 wait_child_setup[1] = wait_child_setup_1_volatile;
1713 1748
1714 pty_flag = XPROCESS (process)->pty_flag; 1749 pty_flag = p->pty_flag;
1715 } 1750 }
1716 1751
1717 if (pid == 0) 1752 if (pid == 0)
@@ -1816,53 +1851,51 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1816 if (pty_flag) 1851 if (pty_flag)
1817 child_setup_tty (xforkout); 1852 child_setup_tty (xforkout);
1818#ifdef WINDOWSNT 1853#ifdef WINDOWSNT
1819 pid = child_setup (xforkin, xforkout, xforkout, 1854 pid = child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir);
1820 new_argv, 1, encoded_current_dir);
1821#else /* not WINDOWSNT */ 1855#else /* not WINDOWSNT */
1822 child_setup (xforkin, xforkout, xforkout, 1856 child_setup (xforkin, xforkout, xforkout, new_argv, 1, current_dir);
1823 new_argv, 1, encoded_current_dir);
1824#endif /* not WINDOWSNT */ 1857#endif /* not WINDOWSNT */
1825 } 1858 }
1826 1859
1827 /* Back in the parent process. */ 1860 /* Back in the parent process. */
1828 1861
1829 vfork_errno = errno; 1862 vfork_errno = errno;
1830 XPROCESS (process)->pid = pid; 1863 p->pid = pid;
1831 if (pid >= 0) 1864 if (pid >= 0)
1832 XPROCESS (process)->alive = 1; 1865 p->alive = 1;
1833 1866
1834 /* Stop blocking in the parent. */ 1867 /* Stop blocking in the parent. */
1835 unblock_child_signal (); 1868 unblock_child_signal ();
1836 unblock_input (); 1869 unblock_input ();
1837 1870
1838 if (forkin >= 0)
1839 emacs_close (forkin);
1840 if (forkin != forkout && forkout >= 0)
1841 emacs_close (forkout);
1842
1843 if (pid < 0) 1871 if (pid < 0)
1844 report_file_errno ("Doing vfork", Qnil, vfork_errno); 1872 report_file_errno ("Doing vfork", Qnil, vfork_errno);
1845 else 1873 else
1846 { 1874 {
1847 /* vfork succeeded. */ 1875 /* vfork succeeded. */
1848 1876
1877 /* Close the pipe ends that the child uses, or the child's pty. */
1878 close_process_fd (&p->open_fd[SUBPROCESS_STDIN]);
1879 close_process_fd (&p->open_fd[SUBPROCESS_STDOUT]);
1880
1849#ifdef WINDOWSNT 1881#ifdef WINDOWSNT
1850 register_child (pid, inchannel); 1882 register_child (pid, inchannel);
1851#endif /* WINDOWSNT */ 1883#endif /* WINDOWSNT */
1852 1884
1853 pset_tty_name (XPROCESS (process), lisp_pty_name); 1885 pset_tty_name (p, lisp_pty_name);
1854 1886
1855#ifndef WINDOWSNT 1887#ifndef WINDOWSNT
1856 /* Wait for child_setup to complete in case that vfork is 1888 /* Wait for child_setup to complete in case that vfork is
1857 actually defined as fork. The descriptor wait_child_setup[1] 1889 actually defined as fork. The descriptor
1890 XPROCESS (proc)->open_fd[EXEC_MONITOR_OUTPUT]
1858 of a pipe is closed at the child side either by close-on-exec 1891 of a pipe is closed at the child side either by close-on-exec
1859 on successful execve or the _exit call in child_setup. */ 1892 on successful execve or the _exit call in child_setup. */
1860 { 1893 {
1861 char dummy; 1894 char dummy;
1862 1895
1863 emacs_close (wait_child_setup[1]); 1896 close_process_fd (&p->open_fd[EXEC_MONITOR_OUTPUT]);
1864 emacs_read (wait_child_setup[0], &dummy, 1); 1897 emacs_read (p->open_fd[READ_FROM_EXEC_MONITOR], &dummy, 1);
1865 emacs_close (wait_child_setup[0]); 1898 close_process_fd (&p->open_fd[READ_FROM_EXEC_MONITOR]);
1866 } 1899 }
1867#endif 1900#endif
1868 } 1901 }
@@ -1871,16 +1904,13 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1871static void 1904static void
1872create_pty (Lisp_Object process) 1905create_pty (Lisp_Object process)
1873{ 1906{
1907 struct Lisp_Process *p = XPROCESS (process);
1874 char pty_name[PTY_NAME_SIZE]; 1908 char pty_name[PTY_NAME_SIZE];
1875 int inchannel, outchannel; 1909 int pty_fd = NILP (Vprocess_connection_type) ? -1 : allocate_pty (pty_name);
1876 1910
1877 inchannel = outchannel = -1; 1911 if (pty_fd >= 0)
1878
1879 if (!NILP (Vprocess_connection_type))
1880 outchannel = inchannel = allocate_pty (pty_name);
1881
1882 if (inchannel >= 0)
1883 { 1912 {
1913 p->open_fd[SUBPROCESS_STDIN] = pty_fd;
1884#if ! defined (USG) || defined (USG_SUBTTY_WORKS) 1914#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
1885 /* On most USG systems it does not work to open the pty's tty here, 1915 /* On most USG systems it does not work to open the pty's tty here,
1886 then close it and reopen it in the child. */ 1916 then close it and reopen it in the child. */
@@ -1889,6 +1919,7 @@ create_pty (Lisp_Object process)
1889 int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); 1919 int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
1890 if (forkout < 0) 1920 if (forkout < 0)
1891 report_file_error ("Opening pty", Qnil); 1921 report_file_error ("Opening pty", Qnil);
1922 p->open_fd[WRITE_TO_SUBPROCESS] = forkout;
1892#if defined (DONT_REOPEN_PTY) 1923#if defined (DONT_REOPEN_PTY)
1893 /* In the case that vfork is defined as fork, the parent process 1924 /* In the case that vfork is defined as fork, the parent process
1894 (Emacs) may send some data before the child process completes 1925 (Emacs) may send some data before the child process completes
@@ -1897,33 +1928,32 @@ create_pty (Lisp_Object process)
1897#endif /* DONT_REOPEN_PTY */ 1928#endif /* DONT_REOPEN_PTY */
1898#endif /* not USG, or USG_SUBTTY_WORKS */ 1929#endif /* not USG, or USG_SUBTTY_WORKS */
1899 1930
1900 fcntl (inchannel, F_SETFL, O_NONBLOCK); 1931 fcntl (pty_fd, F_SETFL, O_NONBLOCK);
1901 fcntl (outchannel, F_SETFL, O_NONBLOCK);
1902 1932
1903 /* Record this as an active process, with its channels. 1933 /* Record this as an active process, with its channels.
1904 As a result, child_setup will close Emacs's side of the pipes. */ 1934 As a result, child_setup will close Emacs's side of the pipes. */
1905 chan_process[inchannel] = process; 1935 chan_process[pty_fd] = process;
1906 XPROCESS (process)->infd = inchannel; 1936 p->infd = pty_fd;
1907 XPROCESS (process)->outfd = outchannel; 1937 p->outfd = pty_fd;
1908 1938
1909 /* Previously we recorded the tty descriptor used in the subprocess. 1939 /* Previously we recorded the tty descriptor used in the subprocess.
1910 It was only used for getting the foreground tty process, so now 1940 It was only used for getting the foreground tty process, so now
1911 we just reopen the device (see emacs_get_tty_pgrp) as this is 1941 we just reopen the device (see emacs_get_tty_pgrp) as this is
1912 more portable (see USG_SUBTTY_WORKS above). */ 1942 more portable (see USG_SUBTTY_WORKS above). */
1913 1943
1914 XPROCESS (process)->pty_flag = 1; 1944 p->pty_flag = 1;
1915 pset_status (XPROCESS (process), Qrun); 1945 pset_status (p, Qrun);
1916 setup_process_coding_systems (process); 1946 setup_process_coding_systems (process);
1917 1947
1918 FD_SET (inchannel, &input_wait_mask); 1948 FD_SET (pty_fd, &input_wait_mask);
1919 FD_SET (inchannel, &non_keyboard_wait_mask); 1949 FD_SET (pty_fd, &non_keyboard_wait_mask);
1920 if (inchannel > max_process_desc) 1950 if (pty_fd > max_process_desc)
1921 max_process_desc = inchannel; 1951 max_process_desc = pty_fd;
1922 1952
1923 pset_tty_name (XPROCESS (process), build_string (pty_name)); 1953 pset_tty_name (p, build_string (pty_name));
1924 } 1954 }
1925 1955
1926 XPROCESS (process)->pid = -2; 1956 p->pid = -2;
1927} 1957}
1928 1958
1929 1959
@@ -2529,6 +2559,7 @@ usage: (make-serial-process &rest ARGS) */)
2529 p = XPROCESS (proc); 2559 p = XPROCESS (proc);
2530 2560
2531 fd = serial_open (port); 2561 fd = serial_open (port);
2562 p->open_fd[SUBPROCESS_STDIN] = fd;
2532 p->infd = fd; 2563 p->infd = fd;
2533 p->outfd = fd; 2564 p->outfd = fd;
2534 if (fd > max_process_desc) 2565 if (fd > max_process_desc)
@@ -3201,7 +3232,7 @@ usage: (make-network-process &rest ARGS) */)
3201 wait for completion is pselect(). */ 3232 wait for completion is pselect(). */
3202 int sc; 3233 int sc;
3203 socklen_t len; 3234 socklen_t len;
3204 SELECT_TYPE fdset; 3235 fd_set fdset;
3205 retry_select: 3236 retry_select:
3206 FD_ZERO (&fdset); 3237 FD_ZERO (&fdset);
3207 FD_SET (s, &fdset); 3238 FD_SET (s, &fdset);
@@ -3291,12 +3322,6 @@ usage: (make-network-process &rest ARGS) */)
3291 } 3322 }
3292#endif 3323#endif
3293 3324
3294 /* Discard the unwind protect for closing S, if any. */
3295 specpdl_ptr = specpdl + count1;
3296
3297 /* Unwind bind_polling_period and request_sigio. */
3298 unbind_to (count, Qnil);
3299
3300 if (s < 0) 3325 if (s < 0)
3301 { 3326 {
3302 /* If non-blocking got this far - and failed - assume non-blocking is 3327 /* If non-blocking got this far - and failed - assume non-blocking is
@@ -3338,8 +3363,17 @@ usage: (make-network-process &rest ARGS) */)
3338 if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) 3363 if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
3339 pset_command (p, Qt); 3364 pset_command (p, Qt);
3340 p->pid = 0; 3365 p->pid = 0;
3366
3367 p->open_fd[SUBPROCESS_STDIN] = inch;
3341 p->infd = inch; 3368 p->infd = inch;
3342 p->outfd = outch; 3369 p->outfd = outch;
3370
3371 /* Discard the unwind protect for closing S, if any. */
3372 specpdl_ptr = specpdl + count1;
3373
3374 /* Unwind bind_polling_period and request_sigio. */
3375 unbind_to (count, Qnil);
3376
3343 if (is_server && socktype != SOCK_DGRAM) 3377 if (is_server && socktype != SOCK_DGRAM)
3344 pset_status (p, Qlisten); 3378 pset_status (p, Qlisten);
3345 3379
@@ -3778,17 +3812,15 @@ FLAGS is the current flags of the interface. */)
3778static void 3812static void
3779deactivate_process (Lisp_Object proc) 3813deactivate_process (Lisp_Object proc)
3780{ 3814{
3781 register int inchannel, outchannel; 3815 int inchannel;
3782 register struct Lisp_Process *p = XPROCESS (proc); 3816 struct Lisp_Process *p = XPROCESS (proc);
3817 int i;
3783 3818
3784#ifdef HAVE_GNUTLS 3819#ifdef HAVE_GNUTLS
3785 /* Delete GnuTLS structures in PROC, if any. */ 3820 /* Delete GnuTLS structures in PROC, if any. */
3786 emacs_gnutls_deinit (proc); 3821 emacs_gnutls_deinit (proc);
3787#endif /* HAVE_GNUTLS */ 3822#endif /* HAVE_GNUTLS */
3788 3823
3789 inchannel = p->infd;
3790 outchannel = p->outfd;
3791
3792#ifdef ADAPTIVE_READ_BUFFERING 3824#ifdef ADAPTIVE_READ_BUFFERING
3793 if (p->read_output_delay > 0) 3825 if (p->read_output_delay > 0)
3794 { 3826 {
@@ -3799,14 +3831,14 @@ deactivate_process (Lisp_Object proc)
3799 } 3831 }
3800#endif 3832#endif
3801 3833
3834 /* Beware SIGCHLD hereabouts. */
3835
3836 for (i = 0; i < PROCESS_OPEN_FDS; i++)
3837 close_process_fd (&p->open_fd[i]);
3838
3839 inchannel = p->infd;
3802 if (inchannel >= 0) 3840 if (inchannel >= 0)
3803 { 3841 {
3804 /* Beware SIGCHLD hereabouts. */
3805 flush_pending_output (inchannel);
3806 emacs_close (inchannel);
3807 if (outchannel >= 0 && outchannel != inchannel)
3808 emacs_close (outchannel);
3809
3810 p->infd = -1; 3842 p->infd = -1;
3811 p->outfd = -1; 3843 p->outfd = -1;
3812#ifdef DATAGRAM_SOCKETS 3844#ifdef DATAGRAM_SOCKETS
@@ -3831,13 +3863,14 @@ deactivate_process (Lisp_Object proc)
3831#endif 3863#endif
3832 if (inchannel == max_process_desc) 3864 if (inchannel == max_process_desc)
3833 { 3865 {
3834 int i;
3835 /* We just closed the highest-numbered process input descriptor, 3866 /* We just closed the highest-numbered process input descriptor,
3836 so recompute the highest-numbered one now. */ 3867 so recompute the highest-numbered one now. */
3837 max_process_desc = 0; 3868 int i = inchannel;
3838 for (i = 0; i < MAXDESC; i++) 3869 do
3839 if (!NILP (chan_process[i])) 3870 i--;
3840 max_process_desc = i; 3871 while (0 <= i && NILP (chan_process[i]));
3872
3873 max_process_desc = i;
3841 } 3874 }
3842 } 3875 }
3843} 3876}
@@ -3899,9 +3932,9 @@ Return non-nil if we received any output before the timeout expired. */)
3899 { 3932 {
3900 if (XFLOAT_DATA (seconds) > 0) 3933 if (XFLOAT_DATA (seconds) > 0)
3901 { 3934 {
3902 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds)); 3935 struct timespec t = dtotimespec (XFLOAT_DATA (seconds));
3903 secs = min (EMACS_SECS (t), WAIT_READING_MAX); 3936 secs = min (t.tv_sec, WAIT_READING_MAX);
3904 nsecs = EMACS_NSECS (t); 3937 nsecs = t.tv_nsec;
3905 } 3938 }
3906 } 3939 }
3907 else 3940 else
@@ -4088,6 +4121,7 @@ server_accept_connection (Lisp_Object server, int channel)
4088 /* Discard the unwind protect for closing S. */ 4121 /* Discard the unwind protect for closing S. */
4089 specpdl_ptr = specpdl + count; 4122 specpdl_ptr = specpdl + count;
4090 4123
4124 p->open_fd[SUBPROCESS_STDIN] = s;
4091 p->infd = s; 4125 p->infd = s;
4092 p->outfd = s; 4126 p->outfd = s;
4093 pset_status (p, Qrun); 4127 pset_status (p, Qrun);
@@ -4198,14 +4232,14 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4198 struct Lisp_Process *wait_proc, int just_wait_proc) 4232 struct Lisp_Process *wait_proc, int just_wait_proc)
4199{ 4233{
4200 int channel, nfds; 4234 int channel, nfds;
4201 SELECT_TYPE Available; 4235 fd_set Available;
4202 SELECT_TYPE Writeok; 4236 fd_set Writeok;
4203 bool check_write; 4237 bool check_write;
4204 int check_delay; 4238 int check_delay;
4205 bool no_avail; 4239 bool no_avail;
4206 int xerrno; 4240 int xerrno;
4207 Lisp_Object proc; 4241 Lisp_Object proc;
4208 EMACS_TIME timeout, end_time; 4242 struct timespec timeout, end_time;
4209 int wait_channel = -1; 4243 int wait_channel = -1;
4210 bool got_some_input = 0; 4244 bool got_some_input = 0;
4211 ptrdiff_t count = SPECPDL_INDEX (); 4245 ptrdiff_t count = SPECPDL_INDEX ();
@@ -4238,8 +4272,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4238 compute the absolute time to return at. */ 4272 compute the absolute time to return at. */
4239 if (time_limit || nsecs > 0) 4273 if (time_limit || nsecs > 0)
4240 { 4274 {
4241 timeout = make_emacs_time (time_limit, nsecs); 4275 timeout = make_timespec (time_limit, nsecs);
4242 end_time = add_emacs_time (current_emacs_time (), timeout); 4276 end_time = timespec_add (current_timespec (), timeout);
4243 } 4277 }
4244 4278
4245 while (1) 4279 while (1)
@@ -4266,18 +4300,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4266 gobble output available now 4300 gobble output available now
4267 but don't wait at all. */ 4301 but don't wait at all. */
4268 4302
4269 timeout = make_emacs_time (0, 0); 4303 timeout = make_timespec (0, 0);
4270 } 4304 }
4271 else if (time_limit || nsecs > 0) 4305 else if (time_limit || nsecs > 0)
4272 { 4306 {
4273 EMACS_TIME now = current_emacs_time (); 4307 struct timespec now = current_timespec ();
4274 if (EMACS_TIME_LE (end_time, now)) 4308 if (timespec_cmp (end_time, now) <= 0)
4275 break; 4309 break;
4276 timeout = sub_emacs_time (end_time, now); 4310 timeout = timespec_sub (end_time, now);
4277 } 4311 }
4278 else 4312 else
4279 { 4313 {
4280 timeout = make_emacs_time (100000, 0); 4314 timeout = make_timespec (100000, 0);
4281 } 4315 }
4282 4316
4283 /* Normally we run timers here. 4317 /* Normally we run timers here.
@@ -4287,7 +4321,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4287 if (NILP (wait_for_cell) 4321 if (NILP (wait_for_cell)
4288 && just_wait_proc >= 0) 4322 && just_wait_proc >= 0)
4289 { 4323 {
4290 EMACS_TIME timer_delay; 4324 struct timespec timer_delay;
4291 4325
4292 do 4326 do
4293 { 4327 {
@@ -4322,9 +4356,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4322 /* A negative timeout means do not wait at all. */ 4356 /* A negative timeout means do not wait at all. */
4323 if (nsecs >= 0) 4357 if (nsecs >= 0)
4324 { 4358 {
4325 if (EMACS_TIME_VALID_P (timer_delay)) 4359 if (timespec_valid_p (timer_delay))
4326 { 4360 {
4327 if (EMACS_TIME_LT (timer_delay, timeout)) 4361 if (timespec_cmp (timer_delay, timeout) < 0)
4328 { 4362 {
4329 timeout = timer_delay; 4363 timeout = timer_delay;
4330 timeout_reduced_for_timers = 1; 4364 timeout_reduced_for_timers = 1;
@@ -4353,8 +4387,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4353 timeout to get our attention. */ 4387 timeout to get our attention. */
4354 if (update_tick != process_tick) 4388 if (update_tick != process_tick)
4355 { 4389 {
4356 SELECT_TYPE Atemp; 4390 fd_set Atemp;
4357 SELECT_TYPE Ctemp; 4391 fd_set Ctemp;
4358 4392
4359 if (kbd_on_hold_p ()) 4393 if (kbd_on_hold_p ())
4360 FD_ZERO (&Atemp); 4394 FD_ZERO (&Atemp);
@@ -4362,7 +4396,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4362 Atemp = input_wait_mask; 4396 Atemp = input_wait_mask;
4363 Ctemp = write_mask; 4397 Ctemp = write_mask;
4364 4398
4365 timeout = make_emacs_time (0, 0); 4399 timeout = make_timespec (0, 0);
4366 if ((pselect (max (max_process_desc, max_input_desc) + 1, 4400 if ((pselect (max (max_process_desc, max_input_desc) + 1,
4367 &Atemp, 4401 &Atemp,
4368#ifdef NON_BLOCKING_CONNECT 4402#ifdef NON_BLOCKING_CONNECT
@@ -4484,8 +4518,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4484 Vprocess_adaptive_read_buffering is nil. */ 4518 Vprocess_adaptive_read_buffering is nil. */
4485 if (process_output_skip && check_delay > 0) 4519 if (process_output_skip && check_delay > 0)
4486 { 4520 {
4487 int nsecs = EMACS_NSECS (timeout); 4521 int nsecs = timeout.tv_nsec;
4488 if (EMACS_SECS (timeout) > 0 || nsecs > READ_OUTPUT_DELAY_MAX) 4522 if (timeout.tv_sec > 0 || nsecs > READ_OUTPUT_DELAY_MAX)
4489 nsecs = READ_OUTPUT_DELAY_MAX; 4523 nsecs = READ_OUTPUT_DELAY_MAX;
4490 for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) 4524 for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++)
4491 { 4525 {
@@ -4505,7 +4539,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4505 nsecs = XPROCESS (proc)->read_output_delay; 4539 nsecs = XPROCESS (proc)->read_output_delay;
4506 } 4540 }
4507 } 4541 }
4508 timeout = make_emacs_time (0, nsecs); 4542 timeout = make_timespec (0, nsecs);
4509 process_output_skip = 0; 4543 process_output_skip = 0;
4510 } 4544 }
4511#endif 4545#endif
@@ -4519,7 +4553,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4519#endif 4553#endif
4520 (max (max_process_desc, max_input_desc) + 1, 4554 (max (max_process_desc, max_input_desc) + 1,
4521 &Available, 4555 &Available,
4522 (check_write ? &Writeok : (SELECT_TYPE *)0), 4556 (check_write ? &Writeok : 0),
4523 NULL, &timeout, NULL); 4557 NULL, &timeout, NULL);
4524 4558
4525#ifdef HAVE_GNUTLS 4559#ifdef HAVE_GNUTLS
@@ -4537,7 +4571,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4537 the gnutls library -- 2.12.14 has been confirmed 4571 the gnutls library -- 2.12.14 has been confirmed
4538 to need it. See 4572 to need it. See
4539 http://comments.gmane.org/gmane.emacs.devel/145074 */ 4573 http://comments.gmane.org/gmane.emacs.devel/145074 */
4540 for (channel = 0; channel < MAXDESC; ++channel) 4574 for (channel = 0; channel < FD_SETSIZE; ++channel)
4541 if (! NILP (chan_process[channel])) 4575 if (! NILP (chan_process[channel]))
4542 { 4576 {
4543 struct Lisp_Process *p = 4577 struct Lisp_Process *p =
@@ -5144,15 +5178,10 @@ DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
5144 5178
5145 bset_read_only (current_buffer, Qnil); 5179 bset_read_only (current_buffer, Qnil);
5146 5180
5147 /* Insert new output into buffer 5181 /* Insert new output into buffer at the current end-of-output
5148 at the current end-of-output marker, 5182 marker, thus preserving logical ordering of input and output. */
5149 thus preserving logical ordering of input and output. */
5150 if (XMARKER (p->mark)->buffer) 5183 if (XMARKER (p->mark)->buffer)
5151 SET_PT_BOTH (clip_to_bounds (BEGV, 5184 set_point_from_marker (p->mark);
5152 marker_position (p->mark), ZV),
5153 clip_to_bounds (BEGV_BYTE,
5154 marker_byte_position (p->mark),
5155 ZV_BYTE));
5156 else 5185 else
5157 SET_PT_BOTH (ZV, ZV_BYTE); 5186 SET_PT_BOTH (ZV, ZV_BYTE);
5158 before = PT; 5187 before = PT;
@@ -5733,10 +5762,9 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
5733 return; 5762 return;
5734 } 5763 }
5735 5764
5736 switch (signo)
5737 {
5738#ifdef SIGCONT 5765#ifdef SIGCONT
5739 case SIGCONT: 5766 if (signo == SIGCONT)
5767 {
5740 p->raw_status_new = 0; 5768 p->raw_status_new = 0;
5741 pset_status (p, Qrun); 5769 pset_status (p, Qrun);
5742 p->tick = ++process_tick; 5770 p->tick = ++process_tick;
@@ -5745,14 +5773,8 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
5745 status_notify (NULL); 5773 status_notify (NULL);
5746 redisplay_preserve_echo_area (13); 5774 redisplay_preserve_echo_area (13);
5747 } 5775 }
5748 break;
5749#endif /* ! defined (SIGCONT) */
5750 case SIGINT:
5751 case SIGQUIT:
5752 case SIGKILL:
5753 flush_pending_output (p->infd);
5754 break;
5755 } 5776 }
5777#endif
5756 5778
5757 /* If we don't have process groups, send the signal to the immediate 5779 /* If we don't have process groups, send the signal to the immediate
5758 subprocess. That isn't really right, but it's better than any 5780 subprocess. That isn't really right, but it's better than any
@@ -6007,7 +6029,8 @@ process has been transmitted to the serial port. */)
6007 } 6029 }
6008 else 6030 else
6009 { 6031 {
6010 int old_outfd, new_outfd; 6032 int old_outfd = XPROCESS (proc)->outfd;
6033 int new_outfd;
6011 6034
6012#ifdef HAVE_SHUTDOWN 6035#ifdef HAVE_SHUTDOWN
6013 /* If this is a network connection, or socketpair is used 6036 /* If this is a network connection, or socketpair is used
@@ -6015,18 +6038,15 @@ process has been transmitted to the serial port. */)
6015 (In some old system, shutdown to socketpair doesn't work. 6038 (In some old system, shutdown to socketpair doesn't work.
6016 Then we just can't win.) */ 6039 Then we just can't win.) */
6017 if (EQ (XPROCESS (proc)->type, Qnetwork) 6040 if (EQ (XPROCESS (proc)->type, Qnetwork)
6018 || XPROCESS (proc)->outfd == XPROCESS (proc)->infd) 6041 || XPROCESS (proc)->infd == old_outfd)
6019 shutdown (XPROCESS (proc)->outfd, 1); 6042 shutdown (old_outfd, 1);
6020 /* In case of socketpair, outfd == infd, so don't close it. */ 6043#endif
6021 if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd) 6044 close_process_fd (&XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS]);
6022 emacs_close (XPROCESS (proc)->outfd);
6023#else /* not HAVE_SHUTDOWN */
6024 emacs_close (XPROCESS (proc)->outfd);
6025#endif /* not HAVE_SHUTDOWN */
6026 new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0); 6045 new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0);
6027 if (new_outfd < 0) 6046 if (new_outfd < 0)
6028 emacs_abort (); 6047 report_file_error ("Opening null device", Qnil);
6029 old_outfd = XPROCESS (proc)->outfd; 6048 XPROCESS (proc)->open_fd[WRITE_TO_SUBPROCESS] = new_outfd;
6049 XPROCESS (proc)->outfd = new_outfd;
6030 6050
6031 if (!proc_encode_coding_system[new_outfd]) 6051 if (!proc_encode_coding_system[new_outfd])
6032 proc_encode_coding_system[new_outfd] 6052 proc_encode_coding_system[new_outfd]
@@ -6035,8 +6055,6 @@ process has been transmitted to the serial port. */)
6035 = *proc_encode_coding_system[old_outfd]; 6055 = *proc_encode_coding_system[old_outfd];
6036 memset (proc_encode_coding_system[old_outfd], 0, 6056 memset (proc_encode_coding_system[old_outfd], 0,
6037 sizeof (struct coding_system)); 6057 sizeof (struct coding_system));
6038
6039 XPROCESS (proc)->outfd = new_outfd;
6040 } 6058 }
6041 return process; 6059 return process;
6042} 6060}
@@ -6102,7 +6120,7 @@ static signal_handler_t volatile lib_child_handler;
6102static void 6120static void
6103handle_child_signal (int sig) 6121handle_child_signal (int sig)
6104{ 6122{
6105 Lisp_Object tail; 6123 Lisp_Object tail, proc;
6106 6124
6107 /* Find the process that signaled us, and record its status. */ 6125 /* Find the process that signaled us, and record its status. */
6108 6126
@@ -6113,7 +6131,11 @@ handle_child_signal (int sig)
6113 bool all_pids_are_fixnums 6131 bool all_pids_are_fixnums
6114 = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t) 6132 = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t)
6115 && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM); 6133 && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM);
6116 Lisp_Object xpid = XCAR (tail); 6134 Lisp_Object head = XCAR (tail);
6135 Lisp_Object xpid;
6136 if (! CONSP (head))
6137 continue;
6138 xpid = XCAR (head);
6117 if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid)) 6139 if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid))
6118 { 6140 {
6119 pid_t deleted_pid; 6141 pid_t deleted_pid;
@@ -6122,14 +6144,17 @@ handle_child_signal (int sig)
6122 else 6144 else
6123 deleted_pid = XFLOAT_DATA (xpid); 6145 deleted_pid = XFLOAT_DATA (xpid);
6124 if (child_status_changed (deleted_pid, 0, 0)) 6146 if (child_status_changed (deleted_pid, 0, 0))
6125 XSETCAR (tail, Qnil); 6147 {
6148 if (STRINGP (XCDR (head)))
6149 unlink (SSDATA (XCDR (head)));
6150 XSETCAR (tail, Qnil);
6151 }
6126 } 6152 }
6127 } 6153 }
6128 6154
6129 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ 6155 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
6130 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6156 FOR_EACH_PROCESS (tail, proc)
6131 { 6157 {
6132 Lisp_Object proc = XCDR (XCAR (tail));
6133 struct Lisp_Process *p = XPROCESS (proc); 6158 struct Lisp_Process *p = XPROCESS (proc);
6134 int status; 6159 int status;
6135 6160
@@ -6284,13 +6309,10 @@ status_notify (struct Lisp_Process *deleting_process)
6284 that we run, we get called again to handle their status changes. */ 6309 that we run, we get called again to handle their status changes. */
6285 update_tick = process_tick; 6310 update_tick = process_tick;
6286 6311
6287 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6312 FOR_EACH_PROCESS (tail, proc)
6288 { 6313 {
6289 Lisp_Object symbol; 6314 Lisp_Object symbol;
6290 register struct Lisp_Process *p; 6315 register struct Lisp_Process *p = XPROCESS (proc);
6291
6292 proc = Fcdr (XCAR (tail));
6293 p = XPROCESS (proc);
6294 6316
6295 if (p->tick != p->update_tick) 6317 if (p->tick != p->update_tick)
6296 { 6318 {
@@ -6515,8 +6537,8 @@ keyboard_bit_set (fd_set *mask)
6515#else /* not subprocesses */ 6537#else /* not subprocesses */
6516 6538
6517/* Defined on msdos.c. */ 6539/* Defined on msdos.c. */
6518extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, 6540extern int sys_select (int, fd_set *, fd_set *, fd_set *,
6519 EMACS_TIME *, void *); 6541 struct timespec *, void *);
6520 6542
6521/* Implementation of wait_reading_process_output, assuming that there 6543/* Implementation of wait_reading_process_output, assuming that there
6522 are no subprocesses. Used only by the MS-DOS build. 6544 are no subprocesses. Used only by the MS-DOS build.
@@ -6555,7 +6577,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6555 struct Lisp_Process *wait_proc, int just_wait_proc) 6577 struct Lisp_Process *wait_proc, int just_wait_proc)
6556{ 6578{
6557 register int nfds; 6579 register int nfds;
6558 EMACS_TIME end_time, timeout; 6580 struct timespec end_time, timeout;
6559 6581
6560 if (time_limit < 0) 6582 if (time_limit < 0)
6561 { 6583 {
@@ -6568,8 +6590,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6568 /* What does time_limit really mean? */ 6590 /* What does time_limit really mean? */
6569 if (time_limit || nsecs > 0) 6591 if (time_limit || nsecs > 0)
6570 { 6592 {
6571 timeout = make_emacs_time (time_limit, nsecs); 6593 timeout = make_timespec (time_limit, nsecs);
6572 end_time = add_emacs_time (current_emacs_time (), timeout); 6594 end_time = timespec_add (current_timespec (), timeout);
6573 } 6595 }
6574 6596
6575 /* Turn off periodic alarms (in case they are in use) 6597 /* Turn off periodic alarms (in case they are in use)
@@ -6581,7 +6603,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6581 while (1) 6603 while (1)
6582 { 6604 {
6583 bool timeout_reduced_for_timers = 0; 6605 bool timeout_reduced_for_timers = 0;
6584 SELECT_TYPE waitchannels; 6606 fd_set waitchannels;
6585 int xerrno; 6607 int xerrno;
6586 6608
6587 /* If calling from keyboard input, do not quit 6609 /* If calling from keyboard input, do not quit
@@ -6602,18 +6624,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6602 gobble output available now 6624 gobble output available now
6603 but don't wait at all. */ 6625 but don't wait at all. */
6604 6626
6605 timeout = make_emacs_time (0, 0); 6627 timeout = make_timespec (0, 0);
6606 } 6628 }
6607 else if (time_limit || nsecs > 0) 6629 else if (time_limit || nsecs > 0)
6608 { 6630 {
6609 EMACS_TIME now = current_emacs_time (); 6631 struct timespec now = current_timespec ();
6610 if (EMACS_TIME_LE (end_time, now)) 6632 if (timespec_cmp (end_time, now) <= 0)
6611 break; 6633 break;
6612 timeout = sub_emacs_time (end_time, now); 6634 timeout = timespec_sub (end_time, now);
6613 } 6635 }
6614 else 6636 else
6615 { 6637 {
6616 timeout = make_emacs_time (100000, 0); 6638 timeout = make_timespec (100000, 0);
6617 } 6639 }
6618 6640
6619 /* If our caller will not immediately handle keyboard events, 6641 /* If our caller will not immediately handle keyboard events,
@@ -6622,7 +6644,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6622 call timer_delay on their own.) */ 6644 call timer_delay on their own.) */
6623 if (NILP (wait_for_cell)) 6645 if (NILP (wait_for_cell))
6624 { 6646 {
6625 EMACS_TIME timer_delay; 6647 struct timespec timer_delay;
6626 6648
6627 do 6649 do
6628 { 6650 {
@@ -6642,9 +6664,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6642 && requeued_events_pending_p ()) 6664 && requeued_events_pending_p ())
6643 break; 6665 break;
6644 6666
6645 if (EMACS_TIME_VALID_P (timer_delay) && nsecs >= 0) 6667 if (timespec_valid_p (timer_delay) && nsecs >= 0)
6646 { 6668 {
6647 if (EMACS_TIME_LT (timer_delay, timeout)) 6669 if (timespec_cmp (timer_delay, timeout) < 0)
6648 { 6670 {
6649 timeout = timer_delay; 6671 timeout = timer_delay;
6650 timeout_reduced_for_timers = 1; 6672 timeout_reduced_for_timers = 1;
@@ -6763,16 +6785,9 @@ void
6763delete_keyboard_wait_descriptor (int desc) 6785delete_keyboard_wait_descriptor (int desc)
6764{ 6786{
6765#ifdef subprocesses 6787#ifdef subprocesses
6766 int fd;
6767 int lim = max_input_desc;
6768
6769 FD_CLR (desc, &input_wait_mask); 6788 FD_CLR (desc, &input_wait_mask);
6770 FD_CLR (desc, &non_process_wait_mask); 6789 FD_CLR (desc, &non_process_wait_mask);
6771 6790 delete_input_desc (desc);
6772 if (desc == max_input_desc)
6773 for (fd = 0; fd < lim; fd++)
6774 if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
6775 max_input_desc = fd;
6776#endif 6791#endif
6777} 6792}
6778 6793
@@ -6820,12 +6835,9 @@ BUFFER may be a buffer or the name of one. */)
6820 buf = Fget_buffer (buffer); 6835 buf = Fget_buffer (buffer);
6821 if (NILP (buf)) return Qnil; 6836 if (NILP (buf)) return Qnil;
6822 6837
6823 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6838 FOR_EACH_PROCESS (tail, proc)
6824 { 6839 if (EQ (XPROCESS (proc)->buffer, buf))
6825 proc = Fcdr (XCAR (tail)); 6840 return proc;
6826 if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
6827 return proc;
6828 }
6829#endif /* subprocesses */ 6841#endif /* subprocesses */
6830 return Qnil; 6842 return Qnil;
6831} 6843}
@@ -6858,18 +6870,14 @@ kill_buffer_processes (Lisp_Object buffer)
6858#ifdef subprocesses 6870#ifdef subprocesses
6859 Lisp_Object tail, proc; 6871 Lisp_Object tail, proc;
6860 6872
6861 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6873 FOR_EACH_PROCESS (tail, proc)
6862 { 6874 if (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))
6863 proc = XCDR (XCAR (tail)); 6875 {
6864 if (PROCESSP (proc) 6876 if (NETCONN_P (proc) || SERIALCONN_P (proc))
6865 && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))) 6877 Fdelete_process (proc);
6866 { 6878 else if (XPROCESS (proc)->infd >= 0)
6867 if (NETCONN_P (proc) || SERIALCONN_P (proc)) 6879 process_send_signal (proc, SIGHUP, Qnil, 1);
6868 Fdelete_process (proc); 6880 }
6869 else if (XPROCESS (proc)->infd >= 0)
6870 process_send_signal (proc, SIGHUP, Qnil, 1);
6871 }
6872 }
6873#else /* subprocesses */ 6881#else /* subprocesses */
6874 /* Since we have no subprocesses, this does nothing. */ 6882 /* Since we have no subprocesses, this does nothing. */
6875#endif /* subprocesses */ 6883#endif /* subprocesses */
@@ -7037,7 +7045,7 @@ init_process_emacs (void)
7037 FD_ZERO (&non_keyboard_wait_mask); 7045 FD_ZERO (&non_keyboard_wait_mask);
7038 FD_ZERO (&non_process_wait_mask); 7046 FD_ZERO (&non_process_wait_mask);
7039 FD_ZERO (&write_mask); 7047 FD_ZERO (&write_mask);
7040 max_process_desc = 0; 7048 max_process_desc = max_input_desc = -1;
7041 memset (fd_callback_info, 0, sizeof (fd_callback_info)); 7049 memset (fd_callback_info, 0, sizeof (fd_callback_info));
7042 7050
7043#ifdef NON_BLOCKING_CONNECT 7051#ifdef NON_BLOCKING_CONNECT
@@ -7059,7 +7067,7 @@ init_process_emacs (void)
7059 7067
7060 Vprocess_alist = Qnil; 7068 Vprocess_alist = Qnil;
7061 deleted_pid_list = Qnil; 7069 deleted_pid_list = Qnil;
7062 for (i = 0; i < MAXDESC; i++) 7070 for (i = 0; i < FD_SETSIZE; i++)
7063 { 7071 {
7064 chan_process[i] = Qnil; 7072 chan_process[i] = Qnil;
7065 proc_buffered_char[i] = -1; 7073 proc_buffered_char[i] = -1;
diff --git a/src/process.h b/src/process.h
index 8ae33aebf39..6aff95686a2 100644
--- a/src/process.h
+++ b/src/process.h
@@ -31,6 +31,11 @@ INLINE_HEADER_BEGIN
31# define PROCESS_INLINE INLINE 31# define PROCESS_INLINE INLINE
32#endif 32#endif
33 33
34/* Bound on number of file descriptors opened on behalf of a process,
35 that need to be closed. */
36
37enum { PROCESS_OPEN_FDS = 6 };
38
34/* This structure records information about a subprocess 39/* This structure records information about a subprocess
35 or network connection. */ 40 or network connection. */
36 41
@@ -115,6 +120,9 @@ struct Lisp_Process
115 int infd; 120 int infd;
116 /* Descriptor by which we write to this process */ 121 /* Descriptor by which we write to this process */
117 int outfd; 122 int outfd;
123 /* Descriptors that were created for this process and that need
124 closing. Unused entries are negative. */
125 int open_fd[PROCESS_OPEN_FDS];
118 /* Event-count of last event in which this process changed status. */ 126 /* Event-count of last event in which this process changed status. */
119 EMACS_INT tick; 127 EMACS_INT tick;
120 /* Event-count of last such event reported. */ 128 /* Event-count of last such event reported. */
@@ -210,13 +218,17 @@ enum
210 218
211extern void block_child_signal (void); 219extern void block_child_signal (void);
212extern void unblock_child_signal (void); 220extern void unblock_child_signal (void);
213extern void record_kill_process (struct Lisp_Process *); 221extern Lisp_Object encode_current_directory (void);
222extern void record_kill_process (struct Lisp_Process *, Lisp_Object);
214 223
215/* Defined in process.c. */ 224/* Defined in sysdep.c. */
216 225
217extern Lisp_Object list_system_processes (void); 226extern Lisp_Object list_system_processes (void);
218extern Lisp_Object system_process_attributes (Lisp_Object); 227extern Lisp_Object system_process_attributes (Lisp_Object);
219 228
229/* Defined in process.c. */
230
231extern void record_deleted_pid (pid_t, Lisp_Object);
220extern void hold_keyboard_input (void); 232extern void hold_keyboard_input (void);
221extern void unhold_keyboard_input (void); 233extern void unhold_keyboard_input (void);
222extern bool kbd_on_hold_p (void); 234extern bool kbd_on_hold_p (void);
diff --git a/src/profiler.c b/src/profiler.c
index c86fb47d21d..64eb5cafc25 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -267,8 +267,8 @@ setup_cpu_timer (Lisp_Object sampling_interval)
267 return NOT_RUNNING; 267 return NOT_RUNNING;
268 268
269 current_sampling_interval = XINT (sampling_interval); 269 current_sampling_interval = XINT (sampling_interval);
270 interval = make_emacs_time (current_sampling_interval / billion, 270 interval = make_timespec (current_sampling_interval / billion,
271 current_sampling_interval % billion); 271 current_sampling_interval % billion);
272 emacs_sigaction_init (&action, deliver_profiler_signal); 272 emacs_sigaction_init (&action, deliver_profiler_signal);
273 sigaction (SIGPROF, &action, 0); 273 sigaction (SIGPROF, &action, 0);
274 274
diff --git a/src/regex.c b/src/regex.c
index 39adb080efd..1befececd22 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -257,15 +257,10 @@ xrealloc (void *block, size_t size)
257enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 }; 257enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 };
258 258
259/* Dummy macros for non-Emacs environments. */ 259/* Dummy macros for non-Emacs environments. */
260# define CHAR_CHARSET(c) 0
261# define CHARSET_LEADING_CODE_BASE(c) 0
262# define MAX_MULTIBYTE_LENGTH 1 260# define MAX_MULTIBYTE_LENGTH 1
263# define RE_MULTIBYTE_P(x) 0 261# define RE_MULTIBYTE_P(x) 0
264# define RE_TARGET_MULTIBYTE_P(x) 0 262# define RE_TARGET_MULTIBYTE_P(x) 0
265# define WORD_BOUNDARY_P(c1, c2) (0) 263# define WORD_BOUNDARY_P(c1, c2) (0)
266# define CHAR_HEAD_P(p) (1)
267# define SINGLE_BYTE_CHAR_P(c) (1)
268# define SAME_CHARSET_P(c1, c2) (1)
269# define BYTES_BY_CHAR_HEAD(p) (1) 264# define BYTES_BY_CHAR_HEAD(p) (1)
270# define PREV_CHAR_BOUNDARY(p, limit) ((p)--) 265# define PREV_CHAR_BOUNDARY(p, limit) ((p)--)
271# define STRING_CHAR(p) (*(p)) 266# define STRING_CHAR(p) (*(p))
@@ -279,8 +274,6 @@ enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 };
279 (c = ((p) == (str2) ? *((end1) - 1) : *((p) - 1))) 274 (c = ((p) == (str2) ? *((end1) - 1) : *((p) - 1)))
280# define GET_CHAR_AFTER(c, p, len) \ 275# define GET_CHAR_AFTER(c, p, len) \
281 (c = *p, len = 1) 276 (c = *p, len = 1)
282# define MAKE_CHAR(charset, c1, c2) (c1)
283# define BYTE8_TO_CHAR(c) (c)
284# define CHAR_BYTE8_P(c) (0) 277# define CHAR_BYTE8_P(c) (0)
285# define CHAR_LEADING_CODE(c) (c) 278# define CHAR_LEADING_CODE(c) (c)
286 279
@@ -468,7 +461,7 @@ init_syntax_once (void)
468 461
469/* Assumes a `char *destination' variable. */ 462/* Assumes a `char *destination' variable. */
470# define REGEX_REALLOCATE(source, osize, nsize) \ 463# define REGEX_REALLOCATE(source, osize, nsize) \
471 (destination = (char *) alloca (nsize), \ 464 (destination = alloca (nsize), \
472 memcpy (destination, source, osize)) 465 memcpy (destination, source, osize))
473 466
474/* No need to do anything to free, after alloca. */ 467/* No need to do anything to free, after alloca. */
@@ -775,10 +768,12 @@ extract_number_and_incr (re_char **source)
775 and the 2 bytes of flags at the start of the range table. */ 768 and the 2 bytes of flags at the start of the range table. */
776#define CHARSET_RANGE_TABLE(p) (&(p)[4 + CHARSET_BITMAP_SIZE (p)]) 769#define CHARSET_RANGE_TABLE(p) (&(p)[4 + CHARSET_BITMAP_SIZE (p)])
777 770
771#ifdef emacs
778/* Extract the bit flags that start a range table. */ 772/* Extract the bit flags that start a range table. */
779#define CHARSET_RANGE_TABLE_BITS(p) \ 773#define CHARSET_RANGE_TABLE_BITS(p) \
780 ((p)[2 + CHARSET_BITMAP_SIZE (p)] \ 774 ((p)[2 + CHARSET_BITMAP_SIZE (p)] \
781 + (p)[3 + CHARSET_BITMAP_SIZE (p)] * 0x100) 775 + (p)[3 + CHARSET_BITMAP_SIZE (p)] * 0x100)
776#endif
782 777
783/* Return the address of end of RANGE_TABLE. COUNT is number of 778/* Return the address of end of RANGE_TABLE. COUNT is number of
784 ranges (which is a pair of (start, end)) in the RANGE_TABLE. `* 2' 779 ranges (which is a pair of (start, end)) in the RANGE_TABLE. `* 2'
@@ -1238,12 +1233,12 @@ re_set_syntax (reg_syntax_t syntax)
1238WEAK_ALIAS (__re_set_syntax, re_set_syntax) 1233WEAK_ALIAS (__re_set_syntax, re_set_syntax)
1239 1234
1240/* Regexp to use to replace spaces, or NULL meaning don't. */ 1235/* Regexp to use to replace spaces, or NULL meaning don't. */
1241static re_char *whitespace_regexp; 1236static const_re_char *whitespace_regexp;
1242 1237
1243void 1238void
1244re_set_whitespace_regexp (const char *regexp) 1239re_set_whitespace_regexp (const char *regexp)
1245{ 1240{
1246 whitespace_regexp = (re_char *) regexp; 1241 whitespace_regexp = (const_re_char *) regexp;
1247} 1242}
1248WEAK_ALIAS (__re_set_syntax, re_set_syntax) 1243WEAK_ALIAS (__re_set_syntax, re_set_syntax)
1249 1244
@@ -1830,6 +1825,8 @@ struct range_table_work_area
1830 int bits; /* flag to record character classes */ 1825 int bits; /* flag to record character classes */
1831}; 1826};
1832 1827
1828#ifdef emacs
1829
1833/* Make sure that WORK_AREA can hold more N multibyte characters. 1830/* Make sure that WORK_AREA can hold more N multibyte characters.
1834 This is used only in set_image_of_range and set_image_of_range_1. 1831 This is used only in set_image_of_range and set_image_of_range_1.
1835 It expects WORK_AREA to be a pointer. 1832 It expects WORK_AREA to be a pointer.
@@ -1848,15 +1845,6 @@ struct range_table_work_area
1848#define SET_RANGE_TABLE_WORK_AREA_BIT(work_area, bit) \ 1845#define SET_RANGE_TABLE_WORK_AREA_BIT(work_area, bit) \
1849 (work_area).bits |= (bit) 1846 (work_area).bits |= (bit)
1850 1847
1851/* Bits used to implement the multibyte-part of the various character classes
1852 such as [:alnum:] in a charset's range table. */
1853#define BIT_WORD 0x1
1854#define BIT_LOWER 0x2
1855#define BIT_PUNCT 0x4
1856#define BIT_SPACE 0x8
1857#define BIT_UPPER 0x10
1858#define BIT_MULTIBYTE 0x20
1859
1860/* Set a range (RANGE_START, RANGE_END) to WORK_AREA. */ 1848/* Set a range (RANGE_START, RANGE_END) to WORK_AREA. */
1861#define SET_RANGE_TABLE_WORK_AREA(work_area, range_start, range_end) \ 1849#define SET_RANGE_TABLE_WORK_AREA(work_area, range_start, range_end) \
1862 do { \ 1850 do { \
@@ -1865,6 +1853,8 @@ struct range_table_work_area
1865 (work_area).table[(work_area).used++] = (range_end); \ 1853 (work_area).table[(work_area).used++] = (range_end); \
1866 } while (0) 1854 } while (0)
1867 1855
1856#endif /* emacs */
1857
1868/* Free allocated memory for WORK_AREA. */ 1858/* Free allocated memory for WORK_AREA. */
1869#define FREE_RANGE_TABLE_WORK_AREA(work_area) \ 1859#define FREE_RANGE_TABLE_WORK_AREA(work_area) \
1870 do { \ 1860 do { \
@@ -1876,6 +1866,15 @@ struct range_table_work_area
1876#define RANGE_TABLE_WORK_USED(work_area) ((work_area).used) 1866#define RANGE_TABLE_WORK_USED(work_area) ((work_area).used)
1877#define RANGE_TABLE_WORK_BITS(work_area) ((work_area).bits) 1867#define RANGE_TABLE_WORK_BITS(work_area) ((work_area).bits)
1878#define RANGE_TABLE_WORK_ELT(work_area, i) ((work_area).table[i]) 1868#define RANGE_TABLE_WORK_ELT(work_area, i) ((work_area).table[i])
1869
1870/* Bits used to implement the multibyte-part of the various character classes
1871 such as [:alnum:] in a charset's range table. */
1872#define BIT_WORD 0x1
1873#define BIT_LOWER 0x2
1874#define BIT_PUNCT 0x4
1875#define BIT_SPACE 0x8
1876#define BIT_UPPER 0x10
1877#define BIT_MULTIBYTE 0x20
1879 1878
1880 1879
1881/* Set the bit for character C in a list. */ 1880/* Set the bit for character C in a list. */
@@ -4208,7 +4207,7 @@ re_set_registers (struct re_pattern_buffer *bufp, struct re_registers *regs, uns
4208 { 4207 {
4209 bufp->regs_allocated = REGS_UNALLOCATED; 4208 bufp->regs_allocated = REGS_UNALLOCATED;
4210 regs->num_regs = 0; 4209 regs->num_regs = 0;
4211 regs->start = regs->end = (regoff_t *) 0; 4210 regs->start = regs->end = 0;
4212 } 4211 }
4213} 4212}
4214WEAK_ALIAS (__re_set_registers, re_set_registers) 4213WEAK_ALIAS (__re_set_registers, re_set_registers)
@@ -6395,8 +6394,7 @@ weak_function
6395re_exec (const char *s) 6394re_exec (const char *s)
6396{ 6395{
6397 const size_t len = strlen (s); 6396 const size_t len = strlen (s);
6398 return (re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0) 6397 return re_search (&re_comp_buf, s, len, 0, len, 0) >= 0;
6399 >= 0);
6400} 6398}
6401#endif /* _REGEX_RE_COMP */ 6399#endif /* _REGEX_RE_COMP */
6402 6400
@@ -6560,7 +6558,7 @@ regexec (const regex_t *_Restrict_ preg, const char *_Restrict_ string,
6560 /* Perform the searching operation. */ 6558 /* Perform the searching operation. */
6561 ret = re_search (&private_preg, string, len, 6559 ret = re_search (&private_preg, string, len,
6562 /* start: */ 0, /* range: */ len, 6560 /* start: */ 0, /* range: */ len,
6563 want_reg_info ? &regs : (struct re_registers *) 0); 6561 want_reg_info ? &regs : 0);
6564 6562
6565 /* Copy the register information to the POSIX structure. */ 6563 /* Copy the register information to the POSIX structure. */
6566 if (want_reg_info) 6564 if (want_reg_info)
diff --git a/src/scroll.c b/src/scroll.c
index 3e296068e8f..b9ed8c04ba8 100644
--- a/src/scroll.c
+++ b/src/scroll.c
@@ -652,8 +652,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
652 652
653 /* A queue of deletions and insertions to be performed. */ 653 /* A queue of deletions and insertions to be performed. */
654 struct alt_queue { int count, pos, window; }; 654 struct alt_queue { int count, pos, window; };
655 struct alt_queue *queue_start = (struct alt_queue *) 655 struct alt_queue *queue_start = alloca (window_size * sizeof *queue_start);
656 alloca (window_size * sizeof *queue_start);
657 struct alt_queue *queue = queue_start; 656 struct alt_queue *queue = queue_start;
658 657
659 /* True if a terminal window has been set with set_terminal_window. */ 658 /* True if a terminal window has been set with set_terminal_window. */
@@ -797,9 +796,8 @@ scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top,
797 int unchanged_at_bottom, int *draw_cost, int *old_draw_cost, 796 int unchanged_at_bottom, int *draw_cost, int *old_draw_cost,
798 int *old_hash, int *new_hash, int free_at_end) 797 int *old_hash, int *new_hash, int free_at_end)
799{ 798{
800 struct matrix_elt *matrix; 799 struct matrix_elt *matrix
801 matrix = ((struct matrix_elt *) 800 = alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix);
802 alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix));
803 801
804 if (FRAME_SCROLL_REGION_OK (frame)) 802 if (FRAME_SCROLL_REGION_OK (frame))
805 { 803 {
diff --git a/src/search.c b/src/search.c
index 0f4d41586a3..99e8d2501fe 100644
--- a/src/search.c
+++ b/src/search.c
@@ -598,14 +598,14 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte,
598 598
599/* The newline cache: remembering which sections of text have no newlines. */ 599/* The newline cache: remembering which sections of text have no newlines. */
600 600
601/* If the user has requested newline caching, make sure it's on. 601/* If the user has requested the long scans caching, make sure it's on.
602 Otherwise, make sure it's off. 602 Otherwise, make sure it's off.
603 This is our cheezy way of associating an action with the change of 603 This is our cheezy way of associating an action with the change of
604 state of a buffer-local variable. */ 604 state of a buffer-local variable. */
605static void 605static void
606newline_cache_on_off (struct buffer *buf) 606newline_cache_on_off (struct buffer *buf)
607{ 607{
608 if (NILP (BVAR (buf, cache_long_line_scans))) 608 if (NILP (BVAR (buf, cache_long_scans)))
609 { 609 {
610 /* It should be off. */ 610 /* It should be off. */
611 if (buf->newline_cache) 611 if (buf->newline_cache)
@@ -859,88 +859,20 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
859 If ALLOW_QUIT, set immediate_quit. That's good to do 859 If ALLOW_QUIT, set immediate_quit. That's good to do
860 except in special cases. */ 860 except in special cases. */
861 861
862EMACS_INT 862ptrdiff_t
863scan_newline (ptrdiff_t start, ptrdiff_t start_byte, 863scan_newline (ptrdiff_t start, ptrdiff_t start_byte,
864 ptrdiff_t limit, ptrdiff_t limit_byte, 864 ptrdiff_t limit, ptrdiff_t limit_byte,
865 EMACS_INT count, bool allow_quit) 865 ptrdiff_t count, bool allow_quit)
866{ 866{
867 int direction = ((count > 0) ? 1 : -1); 867 ptrdiff_t charpos, bytepos, shortage;
868
869 unsigned char *cursor;
870 unsigned char *base;
871
872 ptrdiff_t ceiling;
873 unsigned char *ceiling_addr;
874
875 bool old_immediate_quit = immediate_quit;
876
877 if (allow_quit)
878 immediate_quit++;
879 868
880 if (count > 0) 869 charpos = find_newline (start, start_byte, limit, limit_byte,
881 { 870 count, &shortage, &bytepos, allow_quit);
882 while (start_byte < limit_byte) 871 if (shortage)
883 { 872 TEMP_SET_PT_BOTH (limit, limit_byte);
884 ceiling = BUFFER_CEILING_OF (start_byte);
885 ceiling = min (limit_byte - 1, ceiling);
886 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
887 base = (cursor = BYTE_POS_ADDR (start_byte));
888
889 do
890 {
891 unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor);
892 if (! nl)
893 break;
894 if (--count == 0)
895 {
896 immediate_quit = old_immediate_quit;
897 start_byte += nl - base + 1;
898 start = BYTE_TO_CHAR (start_byte);
899 TEMP_SET_PT_BOTH (start, start_byte);
900 return 0;
901 }
902 cursor = nl + 1;
903 }
904 while (cursor < ceiling_addr);
905
906 start_byte += ceiling_addr - base;
907 }
908 }
909 else 873 else
910 { 874 TEMP_SET_PT_BOTH (charpos, bytepos);
911 while (start_byte > limit_byte) 875 return shortage;
912 {
913 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
914 ceiling = max (limit_byte, ceiling);
915 ceiling_addr = BYTE_POS_ADDR (ceiling);
916 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
917 while (1)
918 {
919 unsigned char *nl = memrchr (ceiling_addr, '\n',
920 cursor - ceiling_addr);
921 if (! nl)
922 break;
923
924 if (++count == 0)
925 {
926 immediate_quit = old_immediate_quit;
927 /* Return the position AFTER the match we found. */
928 start_byte += nl - base + 1;
929 start = BYTE_TO_CHAR (start_byte);
930 TEMP_SET_PT_BOTH (start, start_byte);
931 return 0;
932 }
933
934 cursor = nl;
935 }
936 start_byte += ceiling_addr - base;
937 }
938 }
939
940 TEMP_SET_PT_BOTH (limit, limit_byte);
941 immediate_quit = old_immediate_quit;
942
943 return count * direction;
944} 876}
945 877
946/* Like find_newline, but doesn't allow QUITting and doesn't return 878/* Like find_newline, but doesn't allow QUITting and doesn't return
diff --git a/src/sheap.c b/src/sheap.c
index 54eef60c27d..daff0c1d700 100644
--- a/src/sheap.c
+++ b/src/sheap.c
@@ -26,10 +26,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#include <unistd.h> 26#include <unistd.h>
27 27
28#ifdef __x86_64__ 28#ifdef __x86_64__
29#ifdef ENABLE_CHECKING
30#define STATIC_HEAP_SIZE (28 * 1024 * 1024)
31#else
32#define STATIC_HEAP_SIZE (19 * 1024 * 1024)
33#endif
34#else /* x86 */
35#ifdef ENABLE_CHECKING
29#define STATIC_HEAP_SIZE (18 * 1024 * 1024) 36#define STATIC_HEAP_SIZE (18 * 1024 * 1024)
30#else 37#else
31#define STATIC_HEAP_SIZE (13 * 1024 * 1024) 38#define STATIC_HEAP_SIZE (13 * 1024 * 1024)
32#endif 39#endif
40#endif /* x86 */
33 41
34int debug_sheap = 0; 42int debug_sheap = 0;
35 43
@@ -37,6 +45,7 @@ int debug_sheap = 0;
37 45
38char bss_sbrk_buffer[STATIC_HEAP_SIZE]; 46char bss_sbrk_buffer[STATIC_HEAP_SIZE];
39char *bss_sbrk_ptr; 47char *bss_sbrk_ptr;
48char *max_bss_sbrk_ptr;
40int bss_sbrk_did_unexec; 49int bss_sbrk_did_unexec;
41 50
42void * 51void *
@@ -44,7 +53,7 @@ bss_sbrk (ptrdiff_t request_size)
44{ 53{
45 if (!bss_sbrk_ptr) 54 if (!bss_sbrk_ptr)
46 { 55 {
47 bss_sbrk_ptr = bss_sbrk_buffer; 56 max_bss_sbrk_ptr = bss_sbrk_ptr = bss_sbrk_buffer;
48#ifdef CYGWIN 57#ifdef CYGWIN
49 sbrk (BLOCKSIZE); /* force space for fork to work */ 58 sbrk (BLOCKSIZE); /* force space for fork to work */
50#endif 59#endif
@@ -85,6 +94,8 @@ bss_sbrk (ptrdiff_t request_size)
85 if (debug_sheap) 94 if (debug_sheap)
86 printf ("allocated 0x%08x size %d\n", ret, request_size); 95 printf ("allocated 0x%08x size %d\n", ret, request_size);
87 bss_sbrk_ptr += (int) request_size; 96 bss_sbrk_ptr += (int) request_size;
97 if (bss_sbrk_ptr > max_bss_sbrk_ptr)
98 max_bss_sbrk_ptr = bss_sbrk_ptr;
88 return ret; 99 return ret;
89 } 100 }
90} 101}
@@ -93,8 +104,8 @@ void
93report_sheap_usage (int die_if_pure_storage_exceeded) 104report_sheap_usage (int die_if_pure_storage_exceeded)
94{ 105{
95 char buf[200]; 106 char buf[200];
96 sprintf (buf, "Static heap usage: %d of %d bytes", 107 sprintf (buf, "Maximum static heap usage: %d of %d bytes",
97 bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE); 108 max_bss_sbrk_ptr - bss_sbrk_buffer, STATIC_HEAP_SIZE);
98 /* Don't log messages, cause at this point, we're not allowed to create 109 /* Don't log messages, cause at this point, we're not allowed to create
99 buffers. */ 110 buffers. */
100 message1_nolog (buf); 111 message1_nolog (buf);
diff --git a/src/syntax.c b/src/syntax.c
index 6d52d115889..31eb86faed8 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1464,6 +1464,7 @@ scan_words (register ptrdiff_t from, register EMACS_INT count)
1464 1464
1465DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p", 1465DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p",
1466 doc: /* Move point forward ARG words (backward if ARG is negative). 1466 doc: /* Move point forward ARG words (backward if ARG is negative).
1467If ARG is omitted or nil, move point forward one word.
1467Normally returns t. 1468Normally returns t.
1468If an edge of the buffer or a field boundary is reached, point is left there 1469If an edge of the buffer or a field boundary is reached, point is left there
1469and the function returns nil. Field boundaries are not noticed if 1470and the function returns nil. Field boundaries are not noticed if
@@ -3485,9 +3486,9 @@ init_syntax_once (void)
3485 /* This has to be done here, before we call Fmake_char_table. */ 3486 /* This has to be done here, before we call Fmake_char_table. */
3486 DEFSYM (Qsyntax_table, "syntax-table"); 3487 DEFSYM (Qsyntax_table, "syntax-table");
3487 3488
3488 /* Intern_C_String this now in case it isn't already done. 3489 /* This variable is DEFSYMed in alloc.c and not initialized yet, so
3489 Setting this variable twice is harmless. 3490 intern it here. NOTE: you must guarantee that init_syntax_once
3490 But don't staticpro it here--that is done in alloc.c. */ 3491 is called before all other users of this variable. */
3491 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); 3492 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
3492 3493
3493 /* Create objects which can be shared among syntax tables. */ 3494 /* Create objects which can be shared among syntax tables. */
diff --git a/src/sysdep.c b/src/sysdep.c
index 11a6f4a76ce..6439697501e 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -306,7 +306,7 @@ get_child_status (pid_t child, int *status, int options, bool interruptible)
306 /* If successful and status is requested, tell wait_reading_process_output 306 /* If successful and status is requested, tell wait_reading_process_output
307 that it needs to wake up and look around. */ 307 that it needs to wake up and look around. */
308 if (pid && status && input_available_clear_time) 308 if (pid && status && input_available_clear_time)
309 *input_available_clear_time = make_emacs_time (0, 0); 309 *input_available_clear_time = make_timespec (0, 0);
310 310
311 return pid; 311 return pid;
312} 312}
@@ -337,16 +337,6 @@ child_status_changed (pid_t child, int *status, int options)
337 return get_child_status (child, status, WNOHANG | options, 0); 337 return get_child_status (child, status, WNOHANG | options, 0);
338} 338}
339 339
340/*
341 * flush any pending output
342 * (may flush input as well; it does not matter the way we use it)
343 */
344
345void
346flush_pending_output (int channel)
347{
348 /* FIXME: maybe this function should be removed */
349}
350 340
351/* Set up the terminal at the other end of a pseudo-terminal that 341/* Set up the terminal at the other end of a pseudo-terminal that
352 we will be controlling an inferior through. 342 we will be controlling an inferior through.
@@ -481,10 +471,20 @@ sys_subshell (void)
481 pid_t pid; 471 pid_t pid;
482 int status; 472 int status;
483 struct save_signal saved_handlers[5]; 473 struct save_signal saved_handlers[5];
484 Lisp_Object dir; 474 char *str = SSDATA (encode_current_directory ());
485 unsigned char *volatile str_volatile = 0; 475
486 unsigned char *str; 476#ifdef DOS_NT
487 int len; 477 pid = 0;
478#else
479 {
480 char *volatile str_volatile = str;
481 pid = vfork ();
482 str = str_volatile;
483 }
484#endif
485
486 if (pid < 0)
487 error ("Can't spawn subshell");
488 488
489 saved_handlers[0].code = SIGINT; 489 saved_handlers[0].code = SIGINT;
490 saved_handlers[1].code = SIGQUIT; 490 saved_handlers[1].code = SIGQUIT;
@@ -496,31 +496,8 @@ sys_subshell (void)
496 saved_handlers[3].code = 0; 496 saved_handlers[3].code = 0;
497#endif 497#endif
498 498
499 /* Mentioning current_buffer->buffer would mean including buffer.h,
500 which somehow wedges the hp compiler. So instead... */
501
502 dir = intern ("default-directory");
503 if (NILP (Fboundp (dir)))
504 goto xyzzy;
505 dir = Fsymbol_value (dir);
506 if (!STRINGP (dir))
507 goto xyzzy;
508
509 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
510 str_volatile = str = alloca (SCHARS (dir) + 2);
511 len = SCHARS (dir);
512 memcpy (str, SDATA (dir), len);
513 if (str[len - 1] != '/') str[len++] = '/';
514 str[len] = 0;
515 xyzzy:
516
517#ifdef DOS_NT 499#ifdef DOS_NT
518 pid = 0;
519 save_signal_handlers (saved_handlers); 500 save_signal_handlers (saved_handlers);
520#else
521 pid = vfork ();
522 if (pid == -1)
523 error ("Can't spawn subshell");
524#endif 501#endif
525 502
526 if (pid == 0) 503 if (pid == 0)
@@ -538,11 +515,10 @@ sys_subshell (void)
538 sh = "sh"; 515 sh = "sh";
539 516
540 /* Use our buffer's default directory for the subshell. */ 517 /* Use our buffer's default directory for the subshell. */
541 str = str_volatile; 518 if (chdir (str) != 0)
542 if (str && chdir ((char *) str) != 0)
543 { 519 {
544#ifndef DOS_NT 520#ifndef DOS_NT
545 emacs_perror ((char *) str); 521 emacs_perror (str);
546 _exit (EXIT_CANCELED); 522 _exit (EXIT_CANCELED);
547#endif 523#endif
548 } 524 }
@@ -556,8 +532,6 @@ sys_subshell (void)
556 if (epwd) 532 if (epwd)
557 { 533 {
558 strcpy (old_pwd, epwd); 534 strcpy (old_pwd, epwd);
559 if (str[len - 1] == '/')
560 str[len - 1] = '\0';
561 setenv ("PWD", str, 1); 535 setenv ("PWD", str, 1);
562 } 536 }
563 st = system (sh); 537 st = system (sh);
@@ -614,7 +588,7 @@ restore_signal_handlers (struct save_signal *saved_handlers)
614} 588}
615 589
616#ifdef USABLE_SIGIO 590#ifdef USABLE_SIGIO
617static int old_fcntl_flags[MAXDESC]; 591static int old_fcntl_flags[FD_SETSIZE];
618#endif 592#endif
619 593
620void 594void
@@ -843,7 +817,7 @@ emacs_set_tty (int fd, struct emacs_tty *settings, bool flushp)
843 817
844 818
845#ifdef F_SETOWN 819#ifdef F_SETOWN
846static int old_fcntl_owner[MAXDESC]; 820static int old_fcntl_owner[FD_SETSIZE];
847#endif /* F_SETOWN */ 821#endif /* F_SETOWN */
848 822
849/* This may also be defined in stdio, 823/* This may also be defined in stdio,
@@ -1196,7 +1170,8 @@ get_tty_size (int fd, int *widthp, int *heightp)
1196} 1170}
1197 1171
1198/* Set the logical window size associated with descriptor FD 1172/* Set the logical window size associated with descriptor FD
1199 to HEIGHT and WIDTH. This is used mainly with ptys. */ 1173 to HEIGHT and WIDTH. This is used mainly with ptys.
1174 Return a negative value on failure. */
1200 1175
1201int 1176int
1202set_window_size (int fd, int height, int width) 1177set_window_size (int fd, int height, int width)
@@ -1208,10 +1183,7 @@ set_window_size (int fd, int height, int width)
1208 size.ws_row = height; 1183 size.ws_row = height;
1209 size.ws_col = width; 1184 size.ws_col = width;
1210 1185
1211 if (ioctl (fd, TIOCSWINSZ, &size) == -1) 1186 return ioctl (fd, TIOCSWINSZ, &size);
1212 return 0; /* error */
1213 else
1214 return 1;
1215 1187
1216#else 1188#else
1217#ifdef TIOCSSIZE 1189#ifdef TIOCSSIZE
@@ -1221,10 +1193,7 @@ set_window_size (int fd, int height, int width)
1221 size.ts_lines = height; 1193 size.ts_lines = height;
1222 size.ts_cols = width; 1194 size.ts_cols = width;
1223 1195
1224 if (ioctl (fd, TIOCGSIZE, &size) == -1) 1196 return ioctl (fd, TIOCGSIZE, &size);
1225 return 0;
1226 else
1227 return 1;
1228#else 1197#else
1229 return -1; 1198 return -1;
1230#endif /* not SunOS-style */ 1199#endif /* not SunOS-style */
@@ -2052,8 +2021,8 @@ seed_random (void *seed, ptrdiff_t seed_size)
2052void 2021void
2053init_random (void) 2022init_random (void)
2054{ 2023{
2055 EMACS_TIME t = current_emacs_time (); 2024 struct timespec t = current_timespec ();
2056 uintmax_t v = getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t); 2025 uintmax_t v = getpid () ^ t.tv_sec ^ t.tv_nsec;
2057 seed_random (&v, sizeof v); 2026 seed_random (&v, sizeof v);
2058} 2027}
2059 2028
@@ -2388,7 +2357,7 @@ emacs_perror (char const *message)
2388 Use the least timeval not less than T. 2357 Use the least timeval not less than T.
2389 Return an extremal value if the result would overflow. */ 2358 Return an extremal value if the result would overflow. */
2390struct timeval 2359struct timeval
2391make_timeval (EMACS_TIME t) 2360make_timeval (struct timespec t)
2392{ 2361{
2393 struct timeval tv; 2362 struct timeval tv;
2394 tv.tv_sec = t.tv_sec; 2363 tv.tv_sec = t.tv_sec;
@@ -2415,7 +2384,7 @@ make_timeval (EMACS_TIME t)
2415 If FD is nonnegative, then FILE can be NULL. */ 2384 If FD is nonnegative, then FILE can be NULL. */
2416int 2385int
2417set_file_times (int fd, const char *filename, 2386set_file_times (int fd, const char *filename,
2418 EMACS_TIME atime, EMACS_TIME mtime) 2387 struct timespec atime, struct timespec mtime)
2419{ 2388{
2420 struct timespec timespec[2]; 2389 struct timespec timespec[2];
2421 timespec[0] = atime; 2390 timespec[0] = atime;
@@ -2485,7 +2454,7 @@ serial_configure (struct Lisp_Process *p,
2485 Lisp_Object childp2 = Qnil; 2454 Lisp_Object childp2 = Qnil;
2486 Lisp_Object tem = Qnil; 2455 Lisp_Object tem = Qnil;
2487 struct termios attr; 2456 struct termios attr;
2488 int err = -1; 2457 int err;
2489 char summary[4] = "???"; /* This usually becomes "8N1". */ 2458 char summary[4] = "???"; /* This usually becomes "8N1". */
2490 2459
2491 childp2 = Fcopy_sequence (p->childp); 2460 childp2 = Fcopy_sequence (p->childp);
@@ -2732,7 +2701,7 @@ list_system_processes (void)
2732#endif /* !defined (WINDOWSNT) */ 2701#endif /* !defined (WINDOWSNT) */
2733 2702
2734#if defined GNU_LINUX && defined HAVE_LONG_LONG_INT 2703#if defined GNU_LINUX && defined HAVE_LONG_LONG_INT
2735static EMACS_TIME 2704static struct timespec
2736time_from_jiffies (unsigned long long tval, long hz) 2705time_from_jiffies (unsigned long long tval, long hz)
2737{ 2706{
2738 unsigned long long s = tval / hz; 2707 unsigned long long s = tval / hz;
@@ -2741,34 +2710,34 @@ time_from_jiffies (unsigned long long tval, long hz)
2741 2710
2742 if (TYPE_MAXIMUM (time_t) < s) 2711 if (TYPE_MAXIMUM (time_t) < s)
2743 time_overflow (); 2712 time_overflow ();
2744 if (LONG_MAX - 1 <= ULLONG_MAX / EMACS_TIME_RESOLUTION 2713 if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_RESOLUTION
2745 || frac <= ULLONG_MAX / EMACS_TIME_RESOLUTION) 2714 || frac <= ULLONG_MAX / TIMESPEC_RESOLUTION)
2746 ns = frac * EMACS_TIME_RESOLUTION / hz; 2715 ns = frac * TIMESPEC_RESOLUTION / hz;
2747 else 2716 else
2748 { 2717 {
2749 /* This is reachable only in the unlikely case that HZ * HZ 2718 /* This is reachable only in the unlikely case that HZ * HZ
2750 exceeds ULLONG_MAX. It calculates an approximation that is 2719 exceeds ULLONG_MAX. It calculates an approximation that is
2751 guaranteed to be in range. */ 2720 guaranteed to be in range. */
2752 long hz_per_ns = (hz / EMACS_TIME_RESOLUTION 2721 long hz_per_ns = (hz / TIMESPEC_RESOLUTION
2753 + (hz % EMACS_TIME_RESOLUTION != 0)); 2722 + (hz % TIMESPEC_RESOLUTION != 0));
2754 ns = frac / hz_per_ns; 2723 ns = frac / hz_per_ns;
2755 } 2724 }
2756 2725
2757 return make_emacs_time (s, ns); 2726 return make_timespec (s, ns);
2758} 2727}
2759 2728
2760static Lisp_Object 2729static Lisp_Object
2761ltime_from_jiffies (unsigned long long tval, long hz) 2730ltime_from_jiffies (unsigned long long tval, long hz)
2762{ 2731{
2763 EMACS_TIME t = time_from_jiffies (tval, hz); 2732 struct timespec t = time_from_jiffies (tval, hz);
2764 return make_lisp_time (t); 2733 return make_lisp_time (t);
2765} 2734}
2766 2735
2767static EMACS_TIME 2736static struct timespec
2768get_up_time (void) 2737get_up_time (void)
2769{ 2738{
2770 FILE *fup; 2739 FILE *fup;
2771 EMACS_TIME up = make_emacs_time (0, 0); 2740 struct timespec up = make_timespec (0, 0);
2772 2741
2773 block_input (); 2742 block_input ();
2774 fup = emacs_fopen ("/proc/uptime", "r"); 2743 fup = emacs_fopen ("/proc/uptime", "r");
@@ -2786,18 +2755,18 @@ get_up_time (void)
2786 if (TYPE_MAXIMUM (time_t) < upsec) 2755 if (TYPE_MAXIMUM (time_t) < upsec)
2787 { 2756 {
2788 upsec = TYPE_MAXIMUM (time_t); 2757 upsec = TYPE_MAXIMUM (time_t);
2789 upfrac = EMACS_TIME_RESOLUTION - 1; 2758 upfrac = TIMESPEC_RESOLUTION - 1;
2790 } 2759 }
2791 else 2760 else
2792 { 2761 {
2793 int upfraclen = upfrac_end - upfrac_start; 2762 int upfraclen = upfrac_end - upfrac_start;
2794 for (; upfraclen < LOG10_EMACS_TIME_RESOLUTION; upfraclen++) 2763 for (; upfraclen < LOG10_TIMESPEC_RESOLUTION; upfraclen++)
2795 upfrac *= 10; 2764 upfrac *= 10;
2796 for (; LOG10_EMACS_TIME_RESOLUTION < upfraclen; upfraclen--) 2765 for (; LOG10_TIMESPEC_RESOLUTION < upfraclen; upfraclen--)
2797 upfrac /= 10; 2766 upfrac /= 10;
2798 upfrac = min (upfrac, EMACS_TIME_RESOLUTION - 1); 2767 upfrac = min (upfrac, TIMESPEC_RESOLUTION - 1);
2799 } 2768 }
2800 up = make_emacs_time (upsec, upfrac); 2769 up = make_timespec (upsec, upfrac);
2801 } 2770 }
2802 fclose (fup); 2771 fclose (fup);
2803 } 2772 }
@@ -2852,29 +2821,41 @@ procfs_ttyname (int rdev)
2852 return build_string (name); 2821 return build_string (name);
2853} 2822}
2854 2823
2855static unsigned long 2824static uintmax_t
2856procfs_get_total_memory (void) 2825procfs_get_total_memory (void)
2857{ 2826{
2858 FILE *fmem; 2827 FILE *fmem;
2859 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ 2828 uintmax_t retval = 2 * 1024 * 1024; /* default: 2 GiB */
2829 int c;
2860 2830
2861 block_input (); 2831 block_input ();
2862 fmem = emacs_fopen ("/proc/meminfo", "r"); 2832 fmem = emacs_fopen ("/proc/meminfo", "r");
2863 2833
2864 if (fmem) 2834 if (fmem)
2865 { 2835 {
2866 unsigned long entry_value; 2836 uintmax_t entry_value;
2867 char entry_name[20]; /* the longest I saw is 13+1 */ 2837 bool done;
2838
2839 do
2840 switch (fscanf (fmem, "MemTotal: %"SCNuMAX, &entry_value))
2841 {
2842 case 1:
2843 retval = entry_value;
2844 done = 1;
2845 break;
2846
2847 case 0:
2848 while ((c = getc (fmem)) != EOF && c != '\n')
2849 continue;
2850 done = c == EOF;
2851 break;
2852
2853 default:
2854 done = 1;
2855 break;
2856 }
2857 while (!done);
2868 2858
2869 while (!feof (fmem) && !ferror (fmem))
2870 {
2871 if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2
2872 && strcmp (entry_name, "MemTotal:") == 0)
2873 {
2874 retval = entry_value;
2875 break;
2876 }
2877 }
2878 fclose (fmem); 2859 fclose (fmem);
2879 } 2860 }
2880 unblock_input (); 2861 unblock_input ();
@@ -2906,7 +2887,7 @@ system_process_attributes (Lisp_Object pid)
2906 unsigned long long u_time, s_time, cutime, cstime, start; 2887 unsigned long long u_time, s_time, cutime, cstime, start;
2907 long priority, niceness, rss; 2888 long priority, niceness, rss;
2908 unsigned long minflt, majflt, cminflt, cmajflt, vsize; 2889 unsigned long minflt, majflt, cminflt, cmajflt, vsize;
2909 EMACS_TIME tnow, tstart, tboot, telapsed, us_time; 2890 struct timespec tnow, tstart, tboot, telapsed, us_time;
2910 double pcpu, pmem; 2891 double pcpu, pmem;
2911 Lisp_Object attrs = Qnil; 2892 Lisp_Object attrs = Qnil;
2912 Lisp_Object cmd_str, decoded_cmd; 2893 Lisp_Object cmd_str, decoded_cmd;
@@ -3027,20 +3008,19 @@ system_process_attributes (Lisp_Object pid)
3027 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); 3008 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs);
3028 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)), 3009 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)),
3029 attrs); 3010 attrs);
3030 tnow = current_emacs_time (); 3011 tnow = current_timespec ();
3031 telapsed = get_up_time (); 3012 telapsed = get_up_time ();
3032 tboot = sub_emacs_time (tnow, telapsed); 3013 tboot = timespec_sub (tnow, telapsed);
3033 tstart = time_from_jiffies (start, clocks_per_sec); 3014 tstart = time_from_jiffies (start, clocks_per_sec);
3034 tstart = add_emacs_time (tboot, tstart); 3015 tstart = timespec_add (tboot, tstart);
3035 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); 3016 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
3036 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)), 3017 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)),
3037 attrs); 3018 attrs);
3038 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs); 3019 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs);
3039 telapsed = sub_emacs_time (tnow, tstart); 3020 telapsed = timespec_sub (tnow, tstart);
3040 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); 3021 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
3041 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); 3022 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
3042 pcpu = (EMACS_TIME_TO_DOUBLE (us_time) 3023 pcpu = timespectod (us_time) / timespectod (telapsed);
3043 / EMACS_TIME_TO_DOUBLE (telapsed));
3044 if (pcpu > 1.0) 3024 if (pcpu > 1.0)
3045 pcpu = 1.0; 3025 pcpu = 1.0;
3046 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs); 3026 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
@@ -3243,13 +3223,11 @@ system_process_attributes (Lisp_Object pid)
3243 attrs); 3223 attrs);
3244 3224
3245 decoded_cmd = (code_convert_string_norecord 3225 decoded_cmd = (code_convert_string_norecord
3246 (make_unibyte_string (pinfo.pr_fname, 3226 (build_unibyte_string (pinfo.pr_fname),
3247 strlen (pinfo.pr_fname)),
3248 Vlocale_coding_system, 0)); 3227 Vlocale_coding_system, 0));
3249 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); 3228 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3250 decoded_cmd = (code_convert_string_norecord 3229 decoded_cmd = (code_convert_string_norecord
3251 (make_unibyte_string (pinfo.pr_psargs, 3230 (build_unibyte_string (pinfo.pr_psargs),
3252 strlen (pinfo.pr_psargs)),
3253 Vlocale_coding_system, 0)); 3231 Vlocale_coding_system, 0));
3254 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); 3232 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3255 } 3233 }
@@ -3260,16 +3238,16 @@ system_process_attributes (Lisp_Object pid)
3260 3238
3261#elif defined __FreeBSD__ 3239#elif defined __FreeBSD__
3262 3240
3263static EMACS_TIME 3241static struct timespec
3264timeval_to_EMACS_TIME (struct timeval t) 3242timeval_to_timespec (struct timeval t)
3265{ 3243{
3266 return make_emacs_time (t.tv_sec, t.tv_usec * 1000); 3244 return make_timespec (t.tv_sec, t.tv_usec * 1000);
3267} 3245}
3268 3246
3269static Lisp_Object 3247static Lisp_Object
3270make_lisp_timeval (struct timeval t) 3248make_lisp_timeval (struct timeval t)
3271{ 3249{
3272 return make_lisp_time (timeval_to_EMACS_TIME (t)); 3250 return make_lisp_time (timeval_to_timespec (t));
3273} 3251}
3274 3252
3275Lisp_Object 3253Lisp_Object
@@ -3277,14 +3255,14 @@ system_process_attributes (Lisp_Object pid)
3277{ 3255{
3278 int proc_id; 3256 int proc_id;
3279 int pagesize = getpagesize (); 3257 int pagesize = getpagesize ();
3280 int npages; 3258 unsigned long npages;
3281 int fscale; 3259 int fscale;
3282 struct passwd *pw; 3260 struct passwd *pw;
3283 struct group *gr; 3261 struct group *gr;
3284 char *ttyname; 3262 char *ttyname;
3285 size_t len; 3263 size_t len;
3286 char args[MAXPATHLEN]; 3264 char args[MAXPATHLEN];
3287 EMACS_TIME t, now; 3265 struct timespec t, now;
3288 3266
3289 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID}; 3267 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
3290 struct kinfo_proc proc; 3268 struct kinfo_proc proc;
@@ -3319,9 +3297,9 @@ system_process_attributes (Lisp_Object pid)
3319 if (gr) 3297 if (gr)
3320 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); 3298 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3321 3299
3322 decoded_comm = code_convert_string_norecord 3300 decoded_comm = (code_convert_string_norecord
3323 (make_unibyte_string (proc.ki_comm, strlen (proc.ki_comm)), 3301 (build_unibyte_string (proc.ki_comm),
3324 Vlocale_coding_system, 0); 3302 Vlocale_coding_system, 0));
3325 3303
3326 attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); 3304 attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
3327 { 3305 {
@@ -3371,8 +3349,8 @@ system_process_attributes (Lisp_Object pid)
3371 attrs); 3349 attrs);
3372 attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.ki_rusage.ru_stime)), 3350 attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.ki_rusage.ru_stime)),
3373 attrs); 3351 attrs);
3374 t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage.ru_utime), 3352 t = timespec_add (timeval_to_timespec (proc.ki_rusage.ru_utime),
3375 timeval_to_EMACS_TIME (proc.ki_rusage.ru_stime)); 3353 timeval_to_timespec (proc.ki_rusage.ru_stime));
3376 attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs); 3354 attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs);
3377 3355
3378 attrs = Fcons (Fcons (Qcutime, 3356 attrs = Fcons (Fcons (Qcutime,
@@ -3381,8 +3359,8 @@ system_process_attributes (Lisp_Object pid)
3381 attrs = Fcons (Fcons (Qcstime, 3359 attrs = Fcons (Fcons (Qcstime,
3382 make_lisp_timeval (proc.ki_rusage_ch.ru_utime)), 3360 make_lisp_timeval (proc.ki_rusage_ch.ru_utime)),
3383 attrs); 3361 attrs);
3384 t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_utime), 3362 t = timespec_add (timeval_to_timespec (proc.ki_rusage_ch.ru_utime),
3385 timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_stime)); 3363 timeval_to_timespec (proc.ki_rusage_ch.ru_stime));
3386 attrs = Fcons (Fcons (Qctime, make_lisp_time (t)), attrs); 3364 attrs = Fcons (Fcons (Qctime, make_lisp_time (t)), attrs);
3387 3365
3388 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)), 3366 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)),
@@ -3394,8 +3372,8 @@ system_process_attributes (Lisp_Object pid)
3394 attrs = Fcons (Fcons (Qrss, make_number (proc.ki_rssize * pagesize >> 10)), 3372 attrs = Fcons (Fcons (Qrss, make_number (proc.ki_rssize * pagesize >> 10)),
3395 attrs); 3373 attrs);
3396 3374
3397 now = current_emacs_time (); 3375 now = current_timespec ();
3398 t = sub_emacs_time (now, timeval_to_EMACS_TIME (proc.ki_start)); 3376 t = timespec_sub (now, timeval_to_timespec (proc.ki_start));
3399 attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); 3377 attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs);
3400 3378
3401 len = sizeof fscale; 3379 len = sizeof fscale;
diff --git a/src/sysselect.h b/src/sysselect.h
index 0a4f7e3ad96..5df0af9ed37 100644
--- a/src/sysselect.h
+++ b/src/sysselect.h
@@ -25,15 +25,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 definitions in w32.h are incompatible with the below. */ 25 definitions in w32.h are incompatible with the below. */
26#ifndef WINDOWSNT 26#ifndef WINDOWSNT
27#ifdef FD_SET 27#ifdef FD_SET
28#ifdef FD_SETSIZE 28#ifndef FD_SETSIZE
29#define MAXDESC FD_SETSIZE 29#define FD_SETSIZE 64
30#else
31#define MAXDESC 64
32#endif 30#endif
33#define SELECT_TYPE fd_set
34#else /* no FD_SET */ 31#else /* no FD_SET */
35#define MAXDESC 32 32#define FD_SETSIZE 32
36#define SELECT_TYPE int 33typedef int fd_set;
37 34
38/* Define the macros to access a single-int bitmap of descriptors. */ 35/* Define the macros to access a single-int bitmap of descriptors. */
39#define FD_SET(n, p) (*(p) |= (1 << (n))) 36#define FD_SET(n, p) (*(p) |= (1 << (n)))
diff --git a/src/systime.h b/src/systime.h
index df733b290c3..b1c3d940b0e 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -46,140 +46,56 @@ typedef unsigned long Time;
46 46
47#include <sys/time.h> /* for 'struct timeval' */ 47#include <sys/time.h> /* for 'struct timeval' */
48 48
49/* The type to use to represent non-negative temporal intervals. Its 49/* Emacs uses struct timespec to represent nonnegative temporal intervals.
50 address can be passed as the timeout argument to the pselect system
51 call. */
52typedef struct timespec EMACS_TIME;
53
54/* Resolution of EMACS_TIME time stamps (in units per second), and log
55 base 10 of the resolution. The log must be a positive integer. */
56enum { EMACS_TIME_RESOLUTION = 1000000000 };
57enum { LOG10_EMACS_TIME_RESOLUTION = 9 };
58
59/* EMACS_SECS (TIME) is the seconds component of TIME.
60 EMACS_NSECS (TIME) is the nanoseconds component of TIME.
61 emacs_secs_addr (PTIME) is the address of *PTIME's seconds component. */
62SYSTIME_INLINE time_t EMACS_SECS (EMACS_TIME t) { return t.tv_sec; }
63SYSTIME_INLINE int EMACS_NSECS (EMACS_TIME t) { return t.tv_nsec; }
64SYSTIME_INLINE time_t *emacs_secs_addr (EMACS_TIME *t) { return &t->tv_sec; }
65
66/* Return an Emacs time with seconds S and nanoseconds NS. */
67SYSTIME_INLINE EMACS_TIME
68make_emacs_time (time_t s, int ns)
69{
70 EMACS_TIME r;
71 r.tv_sec = s;
72 r.tv_nsec = ns;
73 return r;
74}
75 50
76/* Return an invalid Emacs time. */ 51 WARNING: Since tv_sec might be an unsigned value, do not use struct
77SYSTIME_INLINE EMACS_TIME 52 timespec as a general-purpose data type for adding or subtracting
78invalid_emacs_time (void) 53 arbitrary time values! When computing A + B or A - B, typically A
79{ 54 should be an absolute time since the epoch and B a nonnegative offset. */
80 EMACS_TIME r;
81 r.tv_sec = 0;
82 r.tv_nsec = -1;
83 return r;
84}
85
86/* Return current system time. */
87SYSTIME_INLINE EMACS_TIME
88current_emacs_time (void)
89{
90 EMACS_TIME r;
91 gettime (&r);
92 return r;
93}
94
95/* Return the result of adding A to B, or of subtracting B from A.
96 On overflow, store an extremal value: ergo, if time_t is unsigned,
97 return 0 if the true answer would be negative.
98
99 WARNING: These are NOT general-purpose macros for adding or
100 subtracting arbitrary time values! They are generally intended to
101 be used with their first argument an absolute time since the epoch
102 and the second argument a non-negative offset. Do NOT use them for
103 anything else. */
104SYSTIME_INLINE EMACS_TIME
105add_emacs_time (EMACS_TIME a, EMACS_TIME b)
106{
107 return timespec_add (a, b);
108}
109SYSTIME_INLINE EMACS_TIME
110sub_emacs_time (EMACS_TIME a, EMACS_TIME b)
111{
112 return timespec_sub (a, b);
113}
114 55
115/* Return the sign of the valid time stamp TIME, either -1, 0, or 1. 56/* Return an invalid timespec. */
116 Note: this can only return a negative value if time_t is a signed 57SYSTIME_INLINE struct timespec
117 data type. */ 58invalid_timespec (void)
118SYSTIME_INLINE int
119EMACS_TIME_SIGN (EMACS_TIME t)
120{ 59{
121 return timespec_sign (t); 60 return make_timespec (0, -1);
122} 61}
123 62
124/* Return 1 if TIME is a valid time stamp. */ 63/* Return 1 if TIME is a valid timespec. This currently doesn't worry
64 about whether tv_nsec is less than TIMESPEC_RESOLUTION; leap seconds
65 might cause a problem if it did. */
125SYSTIME_INLINE int 66SYSTIME_INLINE int
126EMACS_TIME_VALID_P (EMACS_TIME t) 67timespec_valid_p (struct timespec t)
127{ 68{
128 return t.tv_nsec >= 0; 69 return t.tv_nsec >= 0;
129} 70}
130 71
131/* Convert the double D to the greatest EMACS_TIME not greater than D. 72/* Return current system time. */
132 On overflow, return an extremal value; in particular, if time_t is 73SYSTIME_INLINE struct timespec
133 an unsigned data type and D is negative, return zero. Return the 74current_timespec (void)
134 minimum EMACS_TIME if D is not a number. */
135SYSTIME_INLINE EMACS_TIME
136EMACS_TIME_FROM_DOUBLE (double d)
137{
138 return dtotimespec (d);
139}
140
141/* Convert the Emacs time T to an approximate double value D. */
142SYSTIME_INLINE double
143EMACS_TIME_TO_DOUBLE (EMACS_TIME t)
144{ 75{
145 return timespectod (t); 76 struct timespec r;
77 gettime (&r);
78 return r;
146} 79}
147 80
148/* defined in sysdep.c */ 81/* defined in sysdep.c */
149extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME); 82extern int set_file_times (int, const char *, struct timespec, struct timespec);
150extern struct timeval make_timeval (EMACS_TIME) ATTRIBUTE_CONST; 83extern struct timeval make_timeval (struct timespec) ATTRIBUTE_CONST;
151 84
152/* defined in keyboard.c */ 85/* defined in keyboard.c */
153extern void set_waiting_for_input (EMACS_TIME *); 86extern void set_waiting_for_input (struct timespec *);
154 87
155/* When lisp.h is not included Lisp_Object is not defined (this can 88/* When lisp.h is not included Lisp_Object is not defined (this can
156 happen when this files is used outside the src directory). 89 happen when this files is used outside the src directory).
157 Use GCPRO1 to determine if lisp.h was included. */ 90 Use GCPRO1 to determine if lisp.h was included. */
158#ifdef GCPRO1 91#ifdef GCPRO1
159/* defined in editfns.c */ 92/* defined in editfns.c */
160extern Lisp_Object make_lisp_time (EMACS_TIME); 93extern Lisp_Object make_lisp_time (struct timespec);
161extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, 94extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
162 Lisp_Object, EMACS_TIME *, double *); 95 Lisp_Object, struct timespec *, double *);
163extern EMACS_TIME lisp_time_argument (Lisp_Object); 96extern struct timespec lisp_time_argument (Lisp_Object);
164#endif 97#endif
165 98
166/* Compare times T1 and T2 for equality, inequality etc. */
167SYSTIME_INLINE int
168EMACS_TIME_EQ (EMACS_TIME t1, EMACS_TIME t2)
169{
170 return timespec_cmp (t1, t2) == 0;
171}
172SYSTIME_INLINE int
173EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2)
174{
175 return timespec_cmp (t1, t2) < 0;
176}
177SYSTIME_INLINE int
178EMACS_TIME_LE (EMACS_TIME t1, EMACS_TIME t2)
179{
180 return timespec_cmp (t1, t2) <= 0;
181}
182
183INLINE_HEADER_END 99INLINE_HEADER_END
184 100
185#endif /* EMACS_SYSTIME_H */ 101#endif /* EMACS_SYSTIME_H */
diff --git a/src/syswait.h b/src/syswait.h
index 03e5cb5fe2e..4ae9129d7ed 100644
--- a/src/syswait.h
+++ b/src/syswait.h
@@ -52,9 +52,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
52#define WTERMSIG(status) ((status) & 0x7f) 52#define WTERMSIG(status) ((status) & 0x7f)
53#endif 53#endif
54 54
55/* Defined in process.c. */
56extern void record_deleted_pid (pid_t);
57
58/* Defined in sysdep.c. */ 55/* Defined in sysdep.c. */
59extern void wait_for_termination (pid_t, int *, bool); 56extern void wait_for_termination (pid_t, int *, bool);
60extern pid_t child_status_changed (pid_t, int *, int); 57extern pid_t child_status_changed (pid_t, int *, int);
diff --git a/src/term.c b/src/term.c
index fb69aefbe7a..aa61fde06ee 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2233,8 +2233,7 @@ get_named_tty (const char *name)
2233{ 2233{
2234 struct terminal *t; 2234 struct terminal *t;
2235 2235
2236 if (!name) 2236 eassert (name);
2237 emacs_abort ();
2238 2237
2239 for (t = terminal_list; t; t = t->next_terminal) 2238 for (t = terminal_list; t; t = t->next_terminal)
2240 { 2239 {
@@ -2786,8 +2785,7 @@ create_tty_output (struct frame *f)
2786{ 2785{
2787 struct tty_output *t = xzalloc (sizeof *t); 2786 struct tty_output *t = xzalloc (sizeof *t);
2788 2787
2789 if (! FRAME_TERMCAP_P (f)) 2788 eassert (FRAME_TERMCAP_P (f));
2790 emacs_abort ();
2791 2789
2792 t->display_info = FRAME_TERMINAL (f)->display_info.tty; 2790 t->display_info = FRAME_TERMINAL (f)->display_info.tty;
2793 2791
@@ -2799,8 +2797,7 @@ create_tty_output (struct frame *f)
2799static void 2797static void
2800tty_free_frame_resources (struct frame *f) 2798tty_free_frame_resources (struct frame *f)
2801{ 2799{
2802 if (! FRAME_TERMCAP_P (f)) 2800 eassert (FRAME_TERMCAP_P (f));
2803 emacs_abort ();
2804 2801
2805 if (FRAME_FACE_CACHE (f)) 2802 if (FRAME_FACE_CACHE (f))
2806 free_frame_faces (f); 2803 free_frame_faces (f);
@@ -2815,8 +2812,7 @@ tty_free_frame_resources (struct frame *f)
2815static void 2812static void
2816tty_free_frame_resources (struct frame *f) 2813tty_free_frame_resources (struct frame *f)
2817{ 2814{
2818 if (! FRAME_TERMCAP_P (f) && ! FRAME_MSDOS_P (f)) 2815 eassert (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
2819 emacs_abort ();
2820 2816
2821 if (FRAME_FACE_CACHE (f)) 2817 if (FRAME_FACE_CACHE (f))
2822 free_frame_faces (f); 2818 free_frame_faces (f);
@@ -2938,9 +2934,12 @@ dissociate_if_controlling_tty (int fd)
2938struct terminal * 2934struct terminal *
2939init_tty (const char *name, const char *terminal_type, bool must_succeed) 2935init_tty (const char *name, const char *terminal_type, bool must_succeed)
2940{ 2936{
2941 char *area = NULL; 2937#ifdef TERMINFO
2938 char **address = 0;
2939#else
2940 char *area;
2942 char **address = &area; 2941 char **address = &area;
2943 int buffer_size = 4096; 2942#endif
2944 int status; 2943 int status;
2945 struct tty_display_info *tty = NULL; 2944 struct tty_display_info *tty = NULL;
2946 struct terminal *terminal = NULL; 2945 struct terminal *terminal = NULL;
@@ -3028,12 +3027,16 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
3028 3027
3029 Wcm_clear (tty); 3028 Wcm_clear (tty);
3030 3029
3031 tty->termcap_term_buffer = xmalloc (buffer_size);
3032
3033 /* On some systems, tgetent tries to access the controlling 3030 /* On some systems, tgetent tries to access the controlling
3034 terminal. */ 3031 terminal. */
3035 block_tty_out_signal (); 3032 block_tty_out_signal ();
3033#ifdef TERMINFO
3034 status = tgetent (0, terminal_type);
3035#else
3036 status = tgetent (tty->termcap_term_buffer, terminal_type); 3036 status = tgetent (tty->termcap_term_buffer, terminal_type);
3037 if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1])
3038 emacs_abort ();
3039#endif
3037 unblock_tty_out_signal (); 3040 unblock_tty_out_signal ();
3038 3041
3039 if (status < 0) 3042 if (status < 0)
@@ -3065,11 +3068,8 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3065 } 3068 }
3066 3069
3067#ifndef TERMINFO 3070#ifndef TERMINFO
3068 if (strlen (tty->termcap_term_buffer) >= buffer_size) 3071 area = tty->termcap_strings_buffer;
3069 emacs_abort ();
3070 buffer_size = strlen (tty->termcap_term_buffer);
3071#endif 3072#endif
3072 tty->termcap_strings_buffer = area = xmalloc (buffer_size);
3073 tty->TS_ins_line = tgetstr ("al", address); 3073 tty->TS_ins_line = tgetstr ("al", address);
3074 tty->TS_ins_multi_lines = tgetstr ("AL", address); 3074 tty->TS_ins_multi_lines = tgetstr ("AL", address);
3075 tty->TS_bell = tgetstr ("bl", address); 3075 tty->TS_bell = tgetstr ("bl", address);
@@ -3443,8 +3443,7 @@ delete_tty (struct terminal *terminal)
3443 if (!terminal->name) 3443 if (!terminal->name)
3444 return; 3444 return;
3445 3445
3446 if (terminal->type != output_termcap) 3446 eassert (terminal->type == output_termcap);
3447 emacs_abort ();
3448 3447
3449 tty = terminal->display_info.tty; 3448 tty = terminal->display_info.tty;
3450 3449
@@ -3486,9 +3485,6 @@ delete_tty (struct terminal *terminal)
3486 3485
3487 xfree (tty->old_tty); 3486 xfree (tty->old_tty);
3488 xfree (tty->Wcm); 3487 xfree (tty->Wcm);
3489 xfree (tty->termcap_strings_buffer);
3490 xfree (tty->termcap_term_buffer);
3491
3492 xfree (tty); 3488 xfree (tty);
3493} 3489}
3494 3490
diff --git a/src/termcap.c b/src/termcap.c
index be05828eea6..aa225d9b3b1 100644
--- a/src/termcap.c
+++ b/src/termcap.c
@@ -406,7 +406,7 @@ tgetent (char *bp, const char *name)
406 406
407 if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) 407 if (termcap_name && !filep && !strcmp (name, getenv ("TERM")))
408 { 408 {
409 indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0); 409 indirect = tgetst1 (find_capability (termcap_name, "tc"), 0);
410 if (!indirect) 410 if (!indirect)
411 { 411 {
412 if (!bp) 412 if (!bp)
@@ -490,7 +490,7 @@ tgetent (char *bp, const char *name)
490 /* Does this entry refer to another terminal type's entry? 490 /* Does this entry refer to another terminal type's entry?
491 If something is found, copy it into heap and null-terminate it. */ 491 If something is found, copy it into heap and null-terminate it. */
492 tc_search_point = find_capability (tc_search_point, "tc"); 492 tc_search_point = find_capability (tc_search_point, "tc");
493 term = tgetst1 (tc_search_point, (char **) 0); 493 term = tgetst1 (tc_search_point, 0);
494 } 494 }
495 495
496 emacs_close (fd); 496 emacs_close (fd);
diff --git a/src/termchar.h b/src/termchar.h
index 1c8e8646d4e..687f7fbd119 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -16,6 +16,8 @@ GNU General Public License for more details.
16You should have received a copy of the GNU General Public License 16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 18
19#include "dispextern.h"
20
19/* Each termcap frame points to its own struct tty_output object in 21/* Each termcap frame points to its own struct tty_output object in
20 the output_data.tty field. The tty_output structure contains the 22 the output_data.tty field. The tty_output structure contains the
21 information that is specific to termcap frames. */ 23 information that is specific to termcap frames. */
@@ -28,6 +30,10 @@ struct tty_output
28 /* There is nothing else here at the moment... */ 30 /* There is nothing else here at the moment... */
29}; 31};
30 32
33#ifndef TERMINFO
34enum { TERMCAP_BUFFER_SIZE = 4096 };
35#endif
36
31/* Parameters that are shared between frames on the same tty device. */ 37/* Parameters that are shared between frames on the same tty device. */
32 38
33struct tty_display_info 39struct tty_display_info
@@ -72,14 +78,15 @@ struct tty_display_info
72 mouse-face. */ 78 mouse-face. */
73 Mouse_HLInfo mouse_highlight; 79 Mouse_HLInfo mouse_highlight;
74 80
81#ifndef TERMINFO
75 /* Buffer used internally by termcap (see tgetent in the Termcap 82 /* Buffer used internally by termcap (see tgetent in the Termcap
76 manual). Only init_tty and delete_tty should change this. */ 83 manual). Only init_tty should use this. */
77 char *termcap_term_buffer; 84 char termcap_term_buffer[TERMCAP_BUFFER_SIZE];
78 85
79 /* Buffer storing terminal description strings (see tgetstr in the 86 /* Buffer storing terminal description strings (see tgetstr in the
80 Termcap manual). Only init_tty and delete_tty should change 87 Termcap manual). Only init_tty should use this. */
81 this. */ 88 char termcap_strings_buffer[TERMCAP_BUFFER_SIZE];
82 char *termcap_strings_buffer; 89#endif
83 90
84 /* Strings, numbers and flags taken from the termcap entry. */ 91 /* Strings, numbers and flags taken from the termcap entry. */
85 92
diff --git a/src/termhooks.h b/src/termhooks.h
index b49a7bc706b..77f98938edb 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -18,7 +18,9 @@ GNU General Public License for more details.
18You should have received a copy of the GNU General Public License 18You should have received a copy of the GNU General Public License
19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21 21#ifndef EMACS_TERMHOOKS_H
22#define EMACS_TERMHOOKS_H
23
22/* Miscellanea. */ 24/* Miscellanea. */
23 25
24#include "systime.h" /* for Time */ 26#include "systime.h" /* for Time */
@@ -28,10 +30,6 @@ INLINE_HEADER_BEGIN
28# define TERMHOOKS_INLINE INLINE 30# define TERMHOOKS_INLINE INLINE
29#endif 31#endif
30 32
31struct glyph;
32struct frame;
33
34
35enum scroll_bar_part { 33enum scroll_bar_part {
36 scroll_bar_above_handle, 34 scroll_bar_above_handle,
37 scroll_bar_handle, 35 scroll_bar_handle,
@@ -49,7 +47,18 @@ enum scroll_bar_part {
49 may do something OS dependent, like extended window manager hints on X11. */ 47 may do something OS dependent, like extended window manager hints on X11. */
50extern void (*fullscreen_hook) (struct frame *f); 48extern void (*fullscreen_hook) (struct frame *f);
51 49
52 50/* Output method of a terminal (and frames on this terminal, respectively). */
51
52enum output_method
53{
54 output_initial,
55 output_termcap,
56 output_x_window,
57 output_msdos_raw,
58 output_w32,
59 output_ns
60};
61
53/* Input queue declarations and hooks. */ 62/* Input queue declarations and hooks. */
54 63
55enum event_kind 64enum event_kind
@@ -321,11 +330,6 @@ extern void term_mouse_moveto (int, int);
321extern struct tty_display_info *gpm_tty; 330extern struct tty_display_info *gpm_tty;
322#endif 331#endif
323 332
324
325struct ns_display_info;
326struct x_display_info;
327struct w32_display_info;
328
329/* Terminal-local parameters. */ 333/* Terminal-local parameters. */
330struct terminal 334struct terminal
331{ 335{
@@ -660,3 +664,5 @@ extern void close_gpm (int gpm_fd);
660#endif 664#endif
661 665
662INLINE_HEADER_END 666INLINE_HEADER_END
667
668#endif /* EMACS_TERMHOOKS_H */
diff --git a/src/textprop.c b/src/textprop.c
index 282ae11d4ac..b804f345047 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -93,15 +93,25 @@ text_read_only (Lisp_Object propval)
93 xsignal0 (Qtext_read_only); 93 xsignal0 (Qtext_read_only);
94} 94}
95 95
96/* Prepare to modify the region of BUFFER from START to END. */ 96/* Prepare to modify the text properties of BUFFER from START to END. */
97 97
98static void 98static void
99modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) 99modify_text_properties (Lisp_Object buffer, Lisp_Object start, Lisp_Object end)
100{ 100{
101 ptrdiff_t b = XINT (start), e = XINT (end);
101 struct buffer *buf = XBUFFER (buffer), *old = current_buffer; 102 struct buffer *buf = XBUFFER (buffer), *old = current_buffer;
102 103
103 set_buffer_internal (buf); 104 set_buffer_internal (buf);
104 modify_region_1 (XINT (start), XINT (end), true); 105
106 prepare_to_modify_buffer_1 (b, e, NULL);
107
108 BUF_COMPUTE_UNCHANGED (buf, b - 1, e);
109 if (MODIFF <= SAVE_MODIFF)
110 record_first_change ();
111 MODIFF++;
112
113 bset_point_before_scroll (current_buffer, Qnil);
114
105 set_buffer_internal (old); 115 set_buffer_internal (old);
106} 116}
107 117
@@ -1213,9 +1223,9 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
1213 ptrdiff_t prev_total_length = TOTAL_LENGTH (i); 1223 ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
1214 ptrdiff_t prev_pos = i->position; 1224 ptrdiff_t prev_pos = i->position;
1215 1225
1216 modify_region (object, start, end); 1226 modify_text_properties (object, start, end);
1217 /* If someone called us recursively as a side effect of 1227 /* If someone called us recursively as a side effect of
1218 modify_region, and changed the intervals behind our back 1228 modify_text_properties, and changed the intervals behind our back
1219 (could happen if lock_file, called by prepare_to_modify_buffer, 1229 (could happen if lock_file, called by prepare_to_modify_buffer,
1220 triggers redisplay, and that calls add-text-properties again 1230 triggers redisplay, and that calls add-text-properties again
1221 in the same buffer), we cannot continue with I, because its 1231 in the same buffer), we cannot continue with I, because its
@@ -1357,7 +1367,8 @@ into it. */)
1357 otherwise. */ 1367 otherwise. */
1358 1368
1359Lisp_Object 1369Lisp_Object
1360set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, Lisp_Object coherent_change_p) 1370set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
1371 Lisp_Object object, Lisp_Object coherent_change_p)
1361{ 1372{
1362 register INTERVAL i; 1373 register INTERVAL i;
1363 Lisp_Object ostart, oend; 1374 Lisp_Object ostart, oend;
@@ -1403,7 +1414,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
1403 } 1414 }
1404 1415
1405 if (BUFFERP (object) && !NILP (coherent_change_p)) 1416 if (BUFFERP (object) && !NILP (coherent_change_p))
1406 modify_region (object, start, end); 1417 modify_text_properties (object, start, end);
1407 1418
1408 set_text_properties_1 (start, end, properties, object, i); 1419 set_text_properties_1 (start, end, properties, object, i);
1409 1420
@@ -1558,9 +1569,9 @@ Use `set-text-properties' if you want to remove all text properties. */)
1558 ptrdiff_t prev_total_length = TOTAL_LENGTH (i); 1569 ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
1559 ptrdiff_t prev_pos = i->position; 1570 ptrdiff_t prev_pos = i->position;
1560 1571
1561 modify_region (object, start, end); 1572 modify_text_properties (object, start, end);
1562 /* If someone called us recursively as a side effect of 1573 /* If someone called us recursively as a side effect of
1563 modify_region, and changed the intervals behind our back 1574 modify_text_properties, and changed the intervals behind our back
1564 (could happen if lock_file, called by prepare_to_modify_buffer, 1575 (could happen if lock_file, called by prepare_to_modify_buffer,
1565 triggers redisplay, and that calls add-text-properties again 1576 triggers redisplay, and that calls add-text-properties again
1566 in the same buffer), we cannot continue with I, because its 1577 in the same buffer), we cannot continue with I, because its
@@ -1667,9 +1678,9 @@ Return t if any property was actually removed, nil otherwise. */)
1667 1678
1668 /* We are at the beginning of an interval, with len to scan. 1679 /* We are at the beginning of an interval, with len to scan.
1669 The flag `modified' records if changes have been made. 1680 The flag `modified' records if changes have been made.
1670 When object is a buffer, we must call modify_region before changes are 1681 When object is a buffer, we must call modify_text_properties
1671 made and signal_after_change when we are done. 1682 before changes are made and signal_after_change when we are done.
1672 We call modify_region before calling remove_properties if modified == 0, 1683 We call modify_text_properties before calling remove_properties if modified == 0,
1673 and we call signal_after_change before returning if modified != 0. */ 1684 and we call signal_after_change before returning if modified != 0. */
1674 for (;;) 1685 for (;;)
1675 { 1686 {
@@ -1693,7 +1704,7 @@ Return t if any property was actually removed, nil otherwise. */)
1693 else if (LENGTH (i) == len) 1704 else if (LENGTH (i) == len)
1694 { 1705 {
1695 if (!modified && BUFFERP (object)) 1706 if (!modified && BUFFERP (object))
1696 modify_region (object, start, end); 1707 modify_text_properties (object, start, end);
1697 remove_properties (Qnil, properties, i, object); 1708 remove_properties (Qnil, properties, i, object);
1698 if (BUFFERP (object)) 1709 if (BUFFERP (object))
1699 signal_after_change (XINT (start), XINT (end) - XINT (start), 1710 signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1706,7 +1717,7 @@ Return t if any property was actually removed, nil otherwise. */)
1706 i = split_interval_left (i, len); 1717 i = split_interval_left (i, len);
1707 copy_properties (unchanged, i); 1718 copy_properties (unchanged, i);
1708 if (!modified && BUFFERP (object)) 1719 if (!modified && BUFFERP (object))
1709 modify_region (object, start, end); 1720 modify_text_properties (object, start, end);
1710 remove_properties (Qnil, properties, i, object); 1721 remove_properties (Qnil, properties, i, object);
1711 if (BUFFERP (object)) 1722 if (BUFFERP (object))
1712 signal_after_change (XINT (start), XINT (end) - XINT (start), 1723 signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1717,7 +1728,7 @@ Return t if any property was actually removed, nil otherwise. */)
1717 if (interval_has_some_properties_list (properties, i)) 1728 if (interval_has_some_properties_list (properties, i))
1718 { 1729 {
1719 if (!modified && BUFFERP (object)) 1730 if (!modified && BUFFERP (object))
1720 modify_region (object, start, end); 1731 modify_text_properties (object, start, end);
1721 remove_properties (Qnil, properties, i, object); 1732 remove_properties (Qnil, properties, i, object);
1722 modified = 1; 1733 modified = 1;
1723 } 1734 }
diff --git a/src/w16select.c b/src/w16select.c
index 3bcc663e565..864757b3e61 100644
--- a/src/w16select.c
+++ b/src/w16select.c
@@ -452,11 +452,7 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat
452 452
453 CHECK_STRING (string); 453 CHECK_STRING (string);
454 454
455 if (NILP (frame)) 455 if (!FRAME_MSDOS_P (decode_live_frame (frame)))
456 frame = Fselected_frame ();
457
458 CHECK_LIVE_FRAME (frame);
459 if ( !FRAME_MSDOS_P (XFRAME (frame)))
460 goto done; 456 goto done;
461 457
462 block_input (); 458 block_input ();
@@ -558,11 +554,7 @@ DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_dat
558 Lisp_Object ret = Qnil; 554 Lisp_Object ret = Qnil;
559 int require_decoding = 0; 555 int require_decoding = 0;
560 556
561 if (NILP (frame)) 557 if (!FRAME_MSDOS_P (decode_live_frame (frame)))
562 frame = Fselected_frame ();
563
564 CHECK_LIVE_FRAME (frame);
565 if ( !FRAME_MSDOS_P (XFRAME (frame)))
566 goto done; 558 goto done;
567 559
568 block_input (); 560 block_input ();
diff --git a/src/w32.c b/src/w32.c
index fb2d7c75972..1dcf46b5f4b 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -47,7 +47,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
47#undef fopen 47#undef fopen
48#undef link 48#undef link
49#undef mkdir 49#undef mkdir
50#undef mktemp
51#undef open 50#undef open
52#undef rename 51#undef rename
53#undef rmdir 52#undef rmdir
@@ -90,6 +89,21 @@ typedef struct _MEMORY_STATUS_EX {
90 DWORDLONG ullAvailExtendedVirtual; 89 DWORDLONG ullAvailExtendedVirtual;
91} MEMORY_STATUS_EX,*LPMEMORY_STATUS_EX; 90} MEMORY_STATUS_EX,*LPMEMORY_STATUS_EX;
92 91
92/* These are here so that GDB would know about these data types. This
93 allows to attach GDB to Emacs when a fatal exception is triggered
94 and Windows pops up the "application needs to be closed" dialog.
95 At that point, _gnu_exception_handler, the top-level exception
96 handler installed by the MinGW startup code, is somewhere on the
97 call-stack of the main thread, so going to that call frame and
98 looking at the argument to _gnu_exception_handler, which is a
99 PEXCEPTION_POINTERS pointer, can reveal the exception code
100 (excptr->ExceptionRecord->ExceptionCode) and the address where the
101 exception happened (excptr->ExceptionRecord->ExceptionAddress), as
102 well as some additional information specific to the exception. */
103PEXCEPTION_POINTERS excptr;
104PEXCEPTION_RECORD excprec;
105PCONTEXT ctxrec;
106
93#include <lmcons.h> 107#include <lmcons.h>
94#include <shlobj.h> 108#include <shlobj.h>
95 109
@@ -233,7 +247,7 @@ static BOOL WINAPI revert_to_self (void);
233extern int sys_access (const char *, int); 247extern int sys_access (const char *, int);
234extern void *e_malloc (size_t); 248extern void *e_malloc (size_t);
235extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, 249extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
236 EMACS_TIME *, void *); 250 struct timespec *, void *);
237extern int sys_dup (int); 251extern int sys_dup (int);
238 252
239 253
@@ -2489,8 +2503,6 @@ gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz)
2489int 2503int
2490fdutimens (int fd, char const *file, struct timespec const timespec[2]) 2504fdutimens (int fd, char const *file, struct timespec const timespec[2])
2491{ 2505{
2492 struct _utimbuf ut;
2493
2494 if (!timespec) 2506 if (!timespec)
2495 { 2507 {
2496 errno = ENOSYS; 2508 errno = ENOSYS;
@@ -2501,12 +2513,28 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
2501 errno = EBADF; 2513 errno = EBADF;
2502 return -1; 2514 return -1;
2503 } 2515 }
2504 ut.actime = timespec[0].tv_sec; 2516 /* _futime's prototype defines 2nd arg as having the type 'struct
2505 ut.modtime = timespec[1].tv_sec; 2517 _utimbuf', while utime needs to accept 'struct utimbuf' for
2518 compatibility with Posix. So we need to use 2 different (but
2519 equivalent) types to avoid compiler warnings, sigh. */
2506 if (fd >= 0) 2520 if (fd >= 0)
2507 return _futime (fd, &ut); 2521 {
2522 struct _utimbuf _ut;
2523
2524 _ut.actime = timespec[0].tv_sec;
2525 _ut.modtime = timespec[1].tv_sec;
2526 return _futime (fd, &_ut);
2527 }
2508 else 2528 else
2509 return _utime (file, &ut); 2529 {
2530 struct utimbuf ut;
2531
2532 ut.actime = timespec[0].tv_sec;
2533 ut.modtime = timespec[1].tv_sec;
2534 /* Call 'utime', which is implemented below, not the MS library
2535 function, which fails on directories. */
2536 return utime (file, &ut);
2537 }
2510} 2538}
2511 2539
2512 2540
@@ -3414,25 +3442,46 @@ sys_mkdir (const char * path)
3414 return _mkdir (map_w32_filename (path, NULL)); 3442 return _mkdir (map_w32_filename (path, NULL));
3415} 3443}
3416 3444
3417/* Because of long name mapping issues, we need to implement this 3445int
3418 ourselves. Also, MSVC's _mktemp returns NULL when it can't generate 3446sys_open (const char * path, int oflag, int mode)
3419 a unique name, instead of setting the input template to an empty 3447{
3420 string. 3448 const char* mpath = map_w32_filename (path, NULL);
3449 int res = -1;
3450
3451 /* If possible, try to open file without _O_CREAT, to be able to
3452 write to existing hidden and system files. Force all file
3453 handles to be non-inheritable. */
3454 if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL))
3455 res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
3456 if (res < 0)
3457 res = _open (mpath, oflag | _O_NOINHERIT, mode);
3458
3459 return res;
3460}
3461
3462/* Implementation of mkostemp for MS-Windows, to avoid race conditions
3463 when using mktemp.
3421 3464
3422 Standard algorithm seems to be use pid or tid with a letter on the 3465 Standard algorithm for generating a temporary file name seems to be
3423 front (in place of the 6 X's) and cycle through the letters to find a 3466 use pid or tid with a letter on the front (in place of the 6 X's)
3424 unique name. We extend that to allow any reasonable character as the 3467 and cycle through the letters to find a unique name. We extend
3425 first of the 6 X's. */ 3468 that to allow any reasonable character as the first of the 6 X's,
3426char * 3469 so that the number of simultaneously used temporary files will be
3427sys_mktemp (char * template) 3470 greater. */
3471
3472int
3473mkostemp (char * template, int flags)
3428{ 3474{
3429 char * p; 3475 char * p;
3430 int i; 3476 int i, fd = -1;
3431 unsigned uid = GetCurrentThreadId (); 3477 unsigned uid = GetCurrentThreadId ();
3478 int save_errno = errno;
3432 static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; 3479 static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
3433 3480
3481 errno = EINVAL;
3434 if (template == NULL) 3482 if (template == NULL)
3435 return NULL; 3483 return -1;
3484
3436 p = template + strlen (template); 3485 p = template + strlen (template);
3437 i = 5; 3486 i = 5;
3438 /* replace up to the last 5 X's with uid in decimal */ 3487 /* replace up to the last 5 X's with uid in decimal */
@@ -3447,38 +3496,22 @@ sys_mktemp (char * template)
3447 i = 0; 3496 i = 0;
3448 do 3497 do
3449 { 3498 {
3450 int save_errno = errno;
3451 p[0] = first_char[i]; 3499 p[0] = first_char[i];
3452 if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0) 3500 if ((fd = sys_open (template,
3501 flags | _O_CREAT | _O_EXCL | _O_RDWR,
3502 S_IRUSR | S_IWUSR)) >= 0
3503 || errno != EEXIST)
3453 { 3504 {
3454 errno = save_errno; 3505 if (fd >= 0)
3455 return template; 3506 errno = save_errno;
3507 return fd;
3456 } 3508 }
3457 } 3509 }
3458 while (++i < sizeof (first_char)); 3510 while (++i < sizeof (first_char));
3459 } 3511 }
3460 3512
3461 /* Template is badly formed or else we can't generate a unique name, 3513 /* Template is badly formed or else we can't generate a unique name. */
3462 so return empty string */ 3514 return -1;
3463 template[0] = 0;
3464 return template;
3465}
3466
3467int
3468sys_open (const char * path, int oflag, int mode)
3469{
3470 const char* mpath = map_w32_filename (path, NULL);
3471 int res = -1;
3472
3473 /* If possible, try to open file without _O_CREAT, to be able to
3474 write to existing hidden and system files. Force all file
3475 handles to be non-inheritable. */
3476 if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL))
3477 res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
3478 if (res < 0)
3479 res = _open (mpath, oflag | _O_NOINHERIT, mode);
3480
3481 return res;
3482} 3515}
3483 3516
3484int 3517int
@@ -4482,6 +4515,9 @@ fstat (int desc, struct stat * buf)
4482 return 0; 4515 return 0;
4483} 4516}
4484 4517
4518/* A version of 'utime' which handles directories as well as
4519 files. */
4520
4485int 4521int
4486utime (const char *name, struct utimbuf *times) 4522utime (const char *name, struct utimbuf *times)
4487{ 4523{
@@ -5750,8 +5786,8 @@ system_process_attributes (Lisp_Object pid)
5750 { 5786 {
5751 /* Decode the command name from locale-specific 5787 /* Decode the command name from locale-specific
5752 encoding. */ 5788 encoding. */
5753 cmd_str = make_unibyte_string (pe.szExeFile, 5789 cmd_str = build_unibyte_string (pe.szExeFile);
5754 strlen (pe.szExeFile)); 5790
5755 decoded_cmd = 5791 decoded_cmd =
5756 code_convert_string_norecord (cmd_str, 5792 code_convert_string_norecord (cmd_str,
5757 Vlocale_coding_system, 0); 5793 Vlocale_coding_system, 0);
@@ -6056,6 +6092,7 @@ term_winsock (void)
6056{ 6092{
6057 if (winsock_lib != NULL && winsock_inuse == 0) 6093 if (winsock_lib != NULL && winsock_inuse == 0)
6058 { 6094 {
6095 release_listen_threads ();
6059 /* Not sure what would cause WSAENETDOWN, or even if it can happen 6096 /* Not sure what would cause WSAENETDOWN, or even if it can happen
6060 after WSAStartup returns successfully, but it seems reasonable 6097 after WSAStartup returns successfully, but it seems reasonable
6061 to allow unloading winsock anyway in that case. */ 6098 to allow unloading winsock anyway in that case. */
@@ -7040,7 +7077,12 @@ _sys_wait_accept (int fd)
7040 rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT); 7077 rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT);
7041 if (rc != SOCKET_ERROR) 7078 if (rc != SOCKET_ERROR)
7042 { 7079 {
7043 rc = WaitForSingleObject (hEv, INFINITE); 7080 do {
7081 rc = WaitForSingleObject (hEv, 500);
7082 Sleep (5);
7083 } while (rc == WAIT_TIMEOUT
7084 && cp->status != STATUS_READ_ERROR
7085 && cp->char_avail);
7044 pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0); 7086 pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
7045 if (rc == WAIT_OBJECT_0) 7087 if (rc == WAIT_OBJECT_0)
7046 cp->status = STATUS_READ_SUCCEEDED; 7088 cp->status = STATUS_READ_SUCCEEDED;
@@ -7903,7 +7945,7 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
7903{ 7945{
7904 int n, err; 7946 int n, err;
7905 SELECT_TYPE fdset; 7947 SELECT_TYPE fdset;
7906 EMACS_TIME timeout; 7948 struct timespec timeout;
7907 struct Lisp_Process *process = (struct Lisp_Process *)p; 7949 struct Lisp_Process *process = (struct Lisp_Process *)p;
7908 int fd = process->infd; 7950 int fd = process->infd;
7909 7951
diff --git a/src/w32.h b/src/w32.h
index 9c1f1efa699..32d0fdbe3cf 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -163,6 +163,7 @@ extern void reset_standard_handles (int in, int out,
163/* Return the string resource associated with KEY of type TYPE. */ 163/* Return the string resource associated with KEY of type TYPE. */
164extern LPBYTE w32_get_resource (char * key, LPDWORD type); 164extern LPBYTE w32_get_resource (char * key, LPDWORD type);
165 165
166extern void release_listen_threads (void);
166extern void init_ntproc (int); 167extern void init_ntproc (int);
167extern void term_ntproc (int); 168extern void term_ntproc (int);
168extern void globals_of_w32 (void); 169extern void globals_of_w32 (void);
diff --git a/src/w32console.c b/src/w32console.c
index ee92a593301..8da1ccf1892 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -53,7 +53,6 @@ static void w32con_write_glyphs (struct frame *f, struct glyph *string, int len)
53static void w32con_delete_glyphs (struct frame *f, int n); 53static void w32con_delete_glyphs (struct frame *f, int n);
54static void w32con_reset_terminal_modes (struct terminal *t); 54static void w32con_reset_terminal_modes (struct terminal *t);
55static void w32con_set_terminal_modes (struct terminal *t); 55static void w32con_set_terminal_modes (struct terminal *t);
56static void w32con_set_terminal_window (struct frame *f, int size);
57static void w32con_update_begin (struct frame * f); 56static void w32con_update_begin (struct frame * f);
58static void w32con_update_end (struct frame * f); 57static void w32con_update_end (struct frame * f);
59static WORD w32_face_attributes (struct frame *f, int face_id); 58static WORD w32_face_attributes (struct frame *f, int face_id);
@@ -497,11 +496,6 @@ w32con_update_end (struct frame * f)
497 SetConsoleCursorPosition (cur_screen, cursor_coords); 496 SetConsoleCursorPosition (cur_screen, cursor_coords);
498} 497}
499 498
500static void
501w32con_set_terminal_window (struct frame *f, int size)
502{
503}
504
505/*********************************************************************** 499/***********************************************************************
506 stubs from termcap.c 500 stubs from termcap.c
507 ***********************************************************************/ 501 ***********************************************************************/
@@ -619,7 +613,7 @@ initialize_w32_display (struct terminal *term, int *width, int *height)
619 term->ring_bell_hook = w32_sys_ring_bell; 613 term->ring_bell_hook = w32_sys_ring_bell;
620 term->reset_terminal_modes_hook = w32con_reset_terminal_modes; 614 term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
621 term->set_terminal_modes_hook = w32con_set_terminal_modes; 615 term->set_terminal_modes_hook = w32con_set_terminal_modes;
622 term->set_terminal_window_hook = w32con_set_terminal_window; 616 term->set_terminal_window_hook = NULL;
623 term->update_begin_hook = w32con_update_begin; 617 term->update_begin_hook = w32con_update_begin;
624 term->update_end_hook = w32con_update_end; 618 term->update_end_hook = w32con_update_end;
625 619
@@ -636,13 +630,7 @@ initialize_w32_display (struct terminal *term, int *width, int *height)
636 term->frame_up_to_date_hook = 0; 630 term->frame_up_to_date_hook = 0;
637 631
638 /* Initialize the mouse-highlight data. */ 632 /* Initialize the mouse-highlight data. */
639 hlinfo = &term->display_info.tty->mouse_highlight; 633 reset_mouse_highlight (&term->display_info.tty->mouse_highlight);
640 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
641 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
642 hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
643 hlinfo->mouse_face_mouse_frame = NULL;
644 hlinfo->mouse_face_window = Qnil;
645 hlinfo->mouse_face_hidden = 0;
646 634
647 /* Initialize interrupt_handle. */ 635 /* Initialize interrupt_handle. */
648 init_crit (); 636 init_crit ();
diff --git a/src/w32fns.c b/src/w32fns.c
index dff35de0973..b8c445a3a36 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1528,11 +1528,8 @@ void
1528x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 1528x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1529{ 1529{
1530 set_frame_cursor_types (f, arg); 1530 set_frame_cursor_types (f, arg);
1531
1532 /* Make sure the cursor gets redrawn. */
1533 cursor_type_changed = 1;
1534} 1531}
1535 1532
1536void 1533void
1537x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 1534x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1538{ 1535{
@@ -4124,12 +4121,7 @@ w32_window (struct frame *f, long window_prompting, int minibuffer_only)
4124 for the window manager, so GC relocation won't bother it. 4121 for the window manager, so GC relocation won't bother it.
4125 4122
4126 Elsewhere we specify the window name for the window manager. */ 4123 Elsewhere we specify the window name for the window manager. */
4127 4124 f->namebuf = xstrdup (SSDATA (Vx_resource_name));
4128 {
4129 char *str = SSDATA (Vx_resource_name);
4130 f->namebuf = xmalloc (strlen (str) + 1);
4131 strcpy (f->namebuf, str);
4132 }
4133 4125
4134 my_create_window (f); 4126 my_create_window (f);
4135 4127
@@ -4992,8 +4984,8 @@ w32_display_monitor_attributes_list (void)
4992 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), 4984 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
4993 attributes); 4985 attributes);
4994 4986
4995 name = DECODE_SYSTEM (make_unibyte_string (mi.szDevice, 4987 name = DECODE_SYSTEM (build_unibyte_string (mi.szDevice));
4996 strlen (mi.szDevice))); 4988
4997 attributes = Fcons (Fcons (Qname, name), attributes); 4989 attributes = Fcons (Fcons (Qname, name), attributes);
4998 4990
4999 attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), 4991 attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)),
diff --git a/src/w32proc.c b/src/w32proc.c
index 84589388cd7..dabaa62f71c 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -990,6 +990,18 @@ find_child_pid (DWORD pid)
990 return NULL; 990 return NULL;
991} 991}
992 992
993void
994release_listen_threads (void)
995{
996 int i;
997
998 for (i = child_proc_count - 1; i >= 0; i--)
999 {
1000 if (CHILD_ACTIVE (&child_procs[i])
1001 && (fd_info[child_procs[i].fd].flags & FILE_LISTEN))
1002 child_procs[i].status = STATUS_READ_ERROR;
1003 }
1004}
993 1005
994/* Thread proc for child process and socket reader threads. Each thread 1006/* Thread proc for child process and socket reader threads. Each thread
995 is normally blocked until woken by select() to check for input by 1007 is normally blocked until woken by select() to check for input by
@@ -1916,7 +1928,7 @@ extern int proc_buffered_char[];
1916 1928
1917int 1929int
1918sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, 1930sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1919 EMACS_TIME *timeout, void *ignored) 1931 struct timespec *timeout, void *ignored)
1920{ 1932{
1921 SELECT_TYPE orfds; 1933 SELECT_TYPE orfds;
1922 DWORD timeout_ms, start_time; 1934 DWORD timeout_ms, start_time;
diff --git a/src/w32term.c b/src/w32term.c
index 59cfdee86b0..532ded7cdad 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -84,9 +84,6 @@ static int last_mousemove_y = 0;
84 84
85static int any_help_event_p; 85static int any_help_event_p;
86 86
87/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
88static Lisp_Object last_window;
89
90extern unsigned int msh_mousewheel; 87extern unsigned int msh_mousewheel;
91 88
92extern void free_frame_menubar (struct frame *); 89extern void free_frame_menubar (struct frame *);
@@ -210,7 +207,6 @@ static int volatile input_signal_count;
210int w32_message_fd = -1; 207int w32_message_fd = -1;
211#endif /* CYGWIN */ 208#endif /* CYGWIN */
212 209
213static void x_update_window_end (struct window *, int, int);
214static void w32_handle_tool_bar_click (struct frame *, 210static void w32_handle_tool_bar_click (struct frame *,
215 struct input_event *); 211 struct input_event *);
216static void w32_define_cursor (Window, Cursor); 212static void w32_define_cursor (Window, Cursor);
@@ -225,8 +221,6 @@ void x_wm_set_icon_pixmap (struct frame *, int);
225static void w32_initialize (void); 221static void w32_initialize (void);
226static void x_update_end (struct frame *); 222static void x_update_end (struct frame *);
227static void w32_frame_up_to_date (struct frame *); 223static void w32_frame_up_to_date (struct frame *);
228static void w32_set_terminal_modes (struct terminal *);
229static void w32_reset_terminal_modes (struct terminal *);
230static void x_clear_frame (struct frame *); 224static void x_clear_frame (struct frame *);
231static void frame_highlight (struct frame *); 225static void frame_highlight (struct frame *);
232static void frame_unhighlight (struct frame *); 226static void frame_unhighlight (struct frame *);
@@ -241,7 +235,8 @@ static void x_frame_rehighlight (struct w32_display_info *);
241static void x_draw_hollow_cursor (struct window *, struct glyph_row *); 235static void x_draw_hollow_cursor (struct window *, struct glyph_row *);
242static void x_draw_bar_cursor (struct window *, struct glyph_row *, int, 236static void x_draw_bar_cursor (struct window *, struct glyph_row *, int,
243 enum text_cursor_kinds); 237 enum text_cursor_kinds);
244static void w32_clip_to_row (struct window *, struct glyph_row *, int, HDC); 238static void w32_clip_to_row (struct window *, struct glyph_row *,
239 enum glyph_row_area, HDC);
245static BOOL my_show_window (struct frame *, HWND, int); 240static BOOL my_show_window (struct frame *, HWND, int);
246static void my_set_window_pos (HWND, HWND, int, int, int, int, UINT); 241static void my_set_window_pos (HWND, HWND, int, int, int, int, UINT);
247#if 0 242#if 0
@@ -577,9 +572,7 @@ x_update_begin (struct frame *f)
577} 572}
578 573
579 574
580/* Start update of window W. Set the global variable updated_window 575/* Start update of window W. */
581 to the window being updated and set output_cursor to the cursor
582 position of W. */
583 576
584static void 577static void
585x_update_window_begin (struct window *w) 578x_update_window_begin (struct window *w)
@@ -593,8 +586,7 @@ x_update_window_begin (struct window *w)
593 SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0); 586 SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
594 } 587 }
595 588
596 updated_window = w; 589 w->output_cursor = w->cursor;
597 set_output_cursor (&w->cursor);
598 590
599 block_input (); 591 block_input ();
600 592
@@ -664,7 +656,7 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
664} 656}
665 657
666 658
667/* End update of window W (which is equal to updated_window). 659/* End update of window W.
668 660
669 Draw vertical borders between horizontally adjacent windows, and 661 Draw vertical borders between horizontally adjacent windows, and
670 display W's cursor if CURSOR_ON_P is non-zero. 662 display W's cursor if CURSOR_ON_P is non-zero.
@@ -678,19 +670,17 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
678 here. */ 670 here. */
679 671
680static void 672static void
681x_update_window_end (struct window *w, int cursor_on_p, 673x_update_window_end (struct window *w, bool cursor_on_p,
682 int mouse_face_overwritten_p) 674 bool mouse_face_overwritten_p)
683{ 675{
684 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
685
686 if (!w->pseudo_window_p) 676 if (!w->pseudo_window_p)
687 { 677 {
688 block_input (); 678 block_input ();
689 679
690 if (cursor_on_p) 680 if (cursor_on_p)
691 display_and_set_cursor (w, 1, output_cursor.hpos, 681 display_and_set_cursor (w, 1,
692 output_cursor.vpos, 682 w->output_cursor.hpos, w->output_cursor.vpos,
693 output_cursor.x, output_cursor.y); 683 w->output_cursor.x, w->output_cursor.y);
694 684
695 if (draw_window_fringes (w, 1)) 685 if (draw_window_fringes (w, 1))
696 x_draw_vertical_border (w); 686 x_draw_vertical_border (w);
@@ -701,11 +691,7 @@ x_update_window_end (struct window *w, int cursor_on_p,
701 /* If a row with mouse-face was overwritten, arrange for 691 /* If a row with mouse-face was overwritten, arrange for
702 XTframe_up_to_date to redisplay the mouse highlight. */ 692 XTframe_up_to_date to redisplay the mouse highlight. */
703 if (mouse_face_overwritten_p) 693 if (mouse_face_overwritten_p)
704 { 694 reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame)));
705 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
706 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
707 hlinfo->mouse_face_window = Qnil;
708 }
709 695
710 /* Unhide the caret. This won't actually show the cursor, unless it 696 /* Unhide the caret. This won't actually show the cursor, unless it
711 was visible before the corresponding call to HideCaret in 697 was visible before the corresponding call to HideCaret in
@@ -714,8 +700,6 @@ x_update_window_end (struct window *w, int cursor_on_p,
714 { 700 {
715 SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0); 701 SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
716 } 702 }
717
718 updated_window = NULL;
719} 703}
720 704
721 705
@@ -733,9 +717,8 @@ x_update_end (struct frame *f)
733} 717}
734 718
735 719
736/* This function is called from various places in xdisp.c whenever a 720/* This function is called from various places in xdisp.c
737 complete update has been performed. The global variable 721 whenever a complete update has been performed. */
738 updated_window is not available here. */
739 722
740static void 723static void
741w32_frame_up_to_date (struct frame *f) 724w32_frame_up_to_date (struct frame *f)
@@ -747,15 +730,13 @@ w32_frame_up_to_date (struct frame *f)
747 730
748/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay 731/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
749 arrow bitmaps, or clear the fringes if no bitmaps are required 732 arrow bitmaps, or clear the fringes if no bitmaps are required
750 before DESIRED_ROW is made current. The window being updated is 733 before DESIRED_ROW is made current. This function is called from
751 found in updated_window. This function is called from
752 update_window_line only if it is known that there are differences 734 update_window_line only if it is known that there are differences
753 between bitmaps to be drawn between current row and DESIRED_ROW. */ 735 between bitmaps to be drawn between current row and DESIRED_ROW. */
754 736
755static void 737static void
756x_after_update_window_line (struct glyph_row *desired_row) 738x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
757{ 739{
758 struct window *w = updated_window;
759 struct frame *f; 740 struct frame *f;
760 int width, height; 741 int width, height;
761 742
@@ -766,7 +747,7 @@ x_after_update_window_line (struct glyph_row *desired_row)
766 747
767 /* When a window has disappeared, make sure that no rest of 748 /* When a window has disappeared, make sure that no rest of
768 full-width rows stays visible in the internal border. Could 749 full-width rows stays visible in the internal border. Could
769 check here if updated_window is the leftmost/rightmost window, 750 check here if updated window is the leftmost/rightmost window,
770 but I guess it's not worth doing since vertically split windows 751 but I guess it's not worth doing since vertically split windows
771 are almost never used, internal border is rarely set, and the 752 are almost never used, internal border is rarely set, and the
772 overhead is very small. */ 753 overhead is very small. */
@@ -863,7 +844,7 @@ w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
863 } 844 }
864 845
865 /* Must clip because of partially visible lines. */ 846 /* Must clip because of partially visible lines. */
866 w32_clip_to_row (w, row, -1, hdc); 847 w32_clip_to_row (w, row, ANY_AREA, hdc);
867 848
868 if (p->which && p->which < max_fringe_bmp) 849 if (p->which && p->which < max_fringe_bmp)
869 { 850 {
@@ -948,28 +929,6 @@ w32_destroy_fringe_bitmap (int which)
948 fringe_bmp[which] = 0; 929 fringe_bmp[which] = 0;
949} 930}
950 931
951
952
953/* This is called when starting Emacs and when restarting after
954 suspend. When starting Emacs, no window is mapped. And nothing
955 must be done to Emacs's own window if it is suspended (though that
956 rarely happens). */
957
958static void
959w32_set_terminal_modes (struct terminal *term)
960{
961}
962
963/* This is called when exiting or suspending Emacs. Exiting will make
964 the W32 windows go away, and suspending requires no action. */
965
966static void
967w32_reset_terminal_modes (struct terminal *term)
968{
969}
970
971
972
973/*********************************************************************** 932/***********************************************************************
974 Display Iterator 933 Display Iterator
975 ***********************************************************************/ 934 ***********************************************************************/
@@ -2665,11 +2624,7 @@ x_clear_frame (struct frame *f)
2665 /* Clearing the frame will erase any cursor, so mark them all as no 2624 /* Clearing the frame will erase any cursor, so mark them all as no
2666 longer visible. */ 2625 longer visible. */
2667 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); 2626 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
2668 output_cursor.hpos = output_cursor.vpos = 0;
2669 output_cursor.x = -1;
2670 2627
2671 /* We don't set the output cursor here because there will always
2672 follow an explicit cursor_to. */
2673 block_input (); 2628 block_input ();
2674 2629
2675 w32_clear_window (f); 2630 w32_clear_window (f);
@@ -2707,19 +2662,6 @@ w32_ring_bell (struct frame *f)
2707 unblock_input (); 2662 unblock_input ();
2708} 2663}
2709 2664
2710
2711/* Specify how many text lines, from the top of the window,
2712 should be affected by insert-lines and delete-lines operations.
2713 This, and those operations, are used only within an update
2714 that is bounded by calls to x_update_begin and x_update_end. */
2715
2716static void
2717w32_set_terminal_window (struct frame *f, int n)
2718{
2719 /* This function intentionally left blank. */
2720}
2721
2722
2723/*********************************************************************** 2665/***********************************************************************
2724 Line Dance 2666 Line Dance
2725 ***********************************************************************/ 2667 ***********************************************************************/
@@ -2750,7 +2692,7 @@ x_scroll_run (struct window *w, struct run *run)
2750 /* Get frame-relative bounding box of the text display area of W, 2692 /* Get frame-relative bounding box of the text display area of W,
2751 without mode lines. Include in this box the left and right 2693 without mode lines. Include in this box the left and right
2752 fringes of W. */ 2694 fringes of W. */
2753 window_box (w, -1, &x, &y, &width, &height); 2695 window_box (w, ANY_AREA, &x, &y, &width, &height);
2754 2696
2755 /* If the fringe is adjacent to the left (right) scroll bar of a 2697 /* If the fringe is adjacent to the left (right) scroll bar of a
2756 leftmost (rightmost, respectively) window, then extend its 2698 leftmost (rightmost, respectively) window, then extend its
@@ -2806,7 +2748,6 @@ x_scroll_run (struct window *w, struct run *run)
2806 block_input (); 2748 block_input ();
2807 2749
2808 /* Cursor off. Will be switched on again in x_update_window_end. */ 2750 /* Cursor off. Will be switched on again in x_update_window_end. */
2809 updated_window = w;
2810 x_clear_cursor (w); 2751 x_clear_cursor (w);
2811 2752
2812 { 2753 {
@@ -3765,7 +3706,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
3765 HWND hwnd; 3706 HWND hwnd;
3766 SCROLLINFO si; 3707 SCROLLINFO si;
3767 struct scroll_bar *bar 3708 struct scroll_bar *bar
3768 = XSCROLL_BAR (Fmake_vector (make_number (VECSIZE (struct scroll_bar)), Qnil)); 3709 = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, fringe_extended_p, PVEC_OTHER);
3769 Lisp_Object barobj; 3710 Lisp_Object barobj;
3770 3711
3771 block_input (); 3712 block_input ();
@@ -3778,7 +3719,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
3778 XSETINT (bar->start, 0); 3719 XSETINT (bar->start, 0);
3779 XSETINT (bar->end, 0); 3720 XSETINT (bar->end, 0);
3780 bar->dragging = Qnil; 3721 bar->dragging = Qnil;
3781 bar->fringe_extended_p = Qnil; 3722 bar->fringe_extended_p = 0;
3782 3723
3783 /* Requires geometry to be set before call to create the real window */ 3724 /* Requires geometry to be set before call to create the real window */
3784 3725
@@ -3842,10 +3783,10 @@ w32_set_vertical_scroll_bar (struct window *w,
3842 struct scroll_bar *bar; 3783 struct scroll_bar *bar;
3843 int top, height, left, sb_left, width, sb_width; 3784 int top, height, left, sb_left, width, sb_width;
3844 int window_y, window_height; 3785 int window_y, window_height;
3845 int fringe_extended_p; 3786 bool fringe_extended_p;
3846 3787
3847 /* Get window dimensions. */ 3788 /* Get window dimensions. */
3848 window_box (w, -1, 0, &window_y, 0, &window_height); 3789 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
3849 top = window_y; 3790 top = window_y;
3850 width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); 3791 width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
3851 height = window_height; 3792 height = window_height;
@@ -3866,16 +3807,7 @@ w32_set_vertical_scroll_bar (struct window *w,
3866 else 3807 else
3867 sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width); 3808 sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
3868 3809
3869 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) 3810 fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w);
3870 fringe_extended_p = (WINDOW_LEFTMOST_P (w)
3871 && WINDOW_LEFT_FRINGE_WIDTH (w)
3872 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
3873 || WINDOW_LEFT_MARGIN_COLS (w) == 0));
3874 else
3875 fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
3876 && WINDOW_RIGHT_FRINGE_WIDTH (w)
3877 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
3878 || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
3879 3811
3880 /* Does the scroll bar exist yet? */ 3812 /* Does the scroll bar exist yet? */
3881 if (NILP (w->vertical_scroll_bar)) 3813 if (NILP (w->vertical_scroll_bar))
@@ -3904,11 +3836,11 @@ w32_set_vertical_scroll_bar (struct window *w,
3904 hwnd = SCROLL_BAR_W32_WINDOW (bar); 3836 hwnd = SCROLL_BAR_W32_WINDOW (bar);
3905 3837
3906 /* If already correctly positioned, do nothing. */ 3838 /* If already correctly positioned, do nothing. */
3907 if ( XINT (bar->left) == sb_left 3839 if (XINT (bar->left) == sb_left
3908 && XINT (bar->top) == top 3840 && XINT (bar->top) == top
3909 && XINT (bar->width) == sb_width 3841 && XINT (bar->width) == sb_width
3910 && XINT (bar->height) == height 3842 && XINT (bar->height) == height
3911 && !NILP (bar->fringe_extended_p) == fringe_extended_p ) 3843 && bar->fringe_extended_p == fringe_extended_p)
3912 { 3844 {
3913 /* Redraw after clear_frame. */ 3845 /* Redraw after clear_frame. */
3914 if (!my_show_window (f, hwnd, SW_NORMAL)) 3846 if (!my_show_window (f, hwnd, SW_NORMAL))
@@ -3958,7 +3890,7 @@ w32_set_vertical_scroll_bar (struct window *w,
3958 unblock_input (); 3890 unblock_input ();
3959 } 3891 }
3960 } 3892 }
3961 bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil; 3893 bar->fringe_extended_p = fringe_extended_p;
3962 3894
3963 w32_set_scroll_bar_thumb (bar, portion, position, whole); 3895 w32_set_scroll_bar_thumb (bar, portion, position, whole);
3964 XSETVECTOR (barobj, bar); 3896 XSETVECTOR (barobj, bar);
@@ -4568,18 +4500,16 @@ w32_read_socket (struct terminal *terminal,
4568 /* Generate SELECT_WINDOW_EVENTs when needed. */ 4500 /* Generate SELECT_WINDOW_EVENTs when needed. */
4569 if (!NILP (Vmouse_autoselect_window)) 4501 if (!NILP (Vmouse_autoselect_window))
4570 { 4502 {
4571 Lisp_Object window; 4503 static Lisp_Object last_mouse_window;
4572 int x = LOWORD (msg.msg.lParam); 4504 Lisp_Object window = window_from_coordinates
4573 int y = HIWORD (msg.msg.lParam); 4505 (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0);
4574
4575 window = window_from_coordinates (f, x, y, 0, 0);
4576 4506
4577 /* Window will be selected only when it is not 4507 /* Window will be selected only when it is not
4578 selected now and last mouse movement event was 4508 selected now and last mouse movement event was
4579 not in it. Minibuffer window will be selected 4509 not in it. Minibuffer window will be selected
4580 only when it is active. */ 4510 only when it is active. */
4581 if (WINDOWP (window) 4511 if (WINDOWP (window)
4582 && !EQ (window, last_window) 4512 && !EQ (window, last_mouse_window)
4583 && !EQ (window, selected_window) 4513 && !EQ (window, selected_window)
4584 /* For click-to-focus window managers 4514 /* For click-to-focus window managers
4585 create event iff we don't leave the 4515 create event iff we don't leave the
@@ -4591,8 +4521,8 @@ w32_read_socket (struct terminal *terminal,
4591 inev.kind = SELECT_WINDOW_EVENT; 4521 inev.kind = SELECT_WINDOW_EVENT;
4592 inev.frame_or_window = window; 4522 inev.frame_or_window = window;
4593 } 4523 }
4594 4524 /* Remember the last window where we saw the mouse. */
4595 last_window = window; 4525 last_mouse_window = window;
4596 } 4526 }
4597 if (!note_mouse_movement (f, &msg.msg)) 4527 if (!note_mouse_movement (f, &msg.msg))
4598 help_echo_string = previous_help_echo_string; 4528 help_echo_string = previous_help_echo_string;
@@ -5147,7 +5077,8 @@ w32_read_socket (struct terminal *terminal,
5147 mode lines must be clipped to the whole window. */ 5077 mode lines must be clipped to the whole window. */
5148 5078
5149static void 5079static void
5150w32_clip_to_row (struct window *w, struct glyph_row *row, int area, HDC hdc) 5080w32_clip_to_row (struct window *w, struct glyph_row *row,
5081 enum glyph_row_area area, HDC hdc)
5151{ 5082{
5152 RECT clip_rect; 5083 RECT clip_rect;
5153 int window_x, window_y, window_width; 5084 int window_x, window_y, window_width;
@@ -5317,8 +5248,8 @@ w32_clear_frame_area (struct frame *f, int x, int y, int width, int height)
5317 5248
5318static void 5249static void
5319w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, 5250w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
5320 int x, int y, int cursor_type, int cursor_width, 5251 int x, int y, enum text_cursor_kinds cursor_type,
5321 int on_p, int active_p) 5252 int cursor_width, bool on_p, bool active_p)
5322{ 5253{
5323 if (on_p) 5254 if (on_p)
5324 { 5255 {
@@ -5717,7 +5648,9 @@ w32fullscreen_hook (struct frame *f)
5717 w32_fullscreen_rect (hwnd, f->want_fullscreen, 5648 w32_fullscreen_rect (hwnd, f->want_fullscreen,
5718 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); 5649 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
5719 FRAME_PREV_FSMODE (f) = f->want_fullscreen; 5650 FRAME_PREV_FSMODE (f) = f->want_fullscreen;
5720 if (f->want_fullscreen == FULLSCREEN_BOTH) 5651 if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
5652 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0);
5653 else if (f->want_fullscreen == FULLSCREEN_BOTH)
5721 { 5654 {
5722 SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); 5655 SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
5723 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, 5656 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
@@ -6172,16 +6105,8 @@ x_free_frame_resources (struct frame *f)
6172 dpyinfo->w32_focus_event_frame = 0; 6105 dpyinfo->w32_focus_event_frame = 0;
6173 if (f == dpyinfo->x_highlight_frame) 6106 if (f == dpyinfo->x_highlight_frame)
6174 dpyinfo->x_highlight_frame = 0; 6107 dpyinfo->x_highlight_frame = 0;
6175
6176 if (f == hlinfo->mouse_face_mouse_frame) 6108 if (f == hlinfo->mouse_face_mouse_frame)
6177 { 6109 reset_mouse_highlight (hlinfo);
6178 hlinfo->mouse_face_beg_row
6179 = hlinfo->mouse_face_beg_col = -1;
6180 hlinfo->mouse_face_end_row
6181 = hlinfo->mouse_face_end_col = -1;
6182 hlinfo->mouse_face_window = Qnil;
6183 hlinfo->mouse_face_mouse_frame = 0;
6184 }
6185 6110
6186 unblock_input (); 6111 unblock_input ();
6187} 6112}
@@ -6251,7 +6176,6 @@ void
6251w32_initialize_display_info (Lisp_Object display_name) 6176w32_initialize_display_info (Lisp_Object display_name)
6252{ 6177{
6253 struct w32_display_info *dpyinfo = &one_w32_display_info; 6178 struct w32_display_info *dpyinfo = &one_w32_display_info;
6254 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
6255 6179
6256 memset (dpyinfo, 0, sizeof (*dpyinfo)); 6180 memset (dpyinfo, 0, sizeof (*dpyinfo));
6257 6181
@@ -6274,17 +6198,10 @@ w32_initialize_display_info (Lisp_Object display_name)
6274 dpyinfo->n_fonts = 0; 6198 dpyinfo->n_fonts = 0;
6275 dpyinfo->smallest_font_height = 1; 6199 dpyinfo->smallest_font_height = 1;
6276 dpyinfo->smallest_char_width = 1; 6200 dpyinfo->smallest_char_width = 1;
6277
6278 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
6279 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
6280 hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
6281 hlinfo->mouse_face_window = Qnil;
6282 hlinfo->mouse_face_overlay = Qnil;
6283 hlinfo->mouse_face_hidden = 0;
6284
6285 dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW); 6201 dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
6286 /* TODO: dpyinfo->gray */ 6202 /* TODO: dpyinfo->gray */
6287 6203
6204 reset_mouse_highlight (&dpyinfo->mouse_highlight);
6288} 6205}
6289 6206
6290/* Create an xrdb-style database of resources to supersede registry settings. 6207/* Create an xrdb-style database of resources to supersede registry settings.
@@ -6359,7 +6276,6 @@ static struct redisplay_interface w32_redisplay_interface =
6359 x_after_update_window_line, 6276 x_after_update_window_line,
6360 x_update_window_begin, 6277 x_update_window_begin,
6361 x_update_window_end, 6278 x_update_window_end,
6362 x_cursor_to,
6363 x_flush, 6279 x_flush,
6364 0, /* flush_display_optional */ 6280 0, /* flush_display_optional */
6365 x_clear_window_mouse_face, 6281 x_clear_window_mouse_face,
@@ -6396,11 +6312,11 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
6396 terminal->ins_del_lines_hook = x_ins_del_lines; 6312 terminal->ins_del_lines_hook = x_ins_del_lines;
6397 terminal->delete_glyphs_hook = x_delete_glyphs; 6313 terminal->delete_glyphs_hook = x_delete_glyphs;
6398 terminal->ring_bell_hook = w32_ring_bell; 6314 terminal->ring_bell_hook = w32_ring_bell;
6399 terminal->reset_terminal_modes_hook = w32_reset_terminal_modes; 6315 terminal->reset_terminal_modes_hook = NULL;
6400 terminal->set_terminal_modes_hook = w32_set_terminal_modes; 6316 terminal->set_terminal_modes_hook = NULL;
6401 terminal->update_begin_hook = x_update_begin; 6317 terminal->update_begin_hook = x_update_begin;
6402 terminal->update_end_hook = x_update_end; 6318 terminal->update_end_hook = x_update_end;
6403 terminal->set_terminal_window_hook = w32_set_terminal_window; 6319 terminal->set_terminal_window_hook = NULL;
6404 terminal->read_socket_hook = w32_read_socket; 6320 terminal->read_socket_hook = w32_read_socket;
6405 terminal->frame_up_to_date_hook = w32_frame_up_to_date; 6321 terminal->frame_up_to_date_hook = w32_frame_up_to_date;
6406 terminal->mouse_position_hook = w32_mouse_position; 6322 terminal->mouse_position_hook = w32_mouse_position;
@@ -6478,9 +6394,7 @@ w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
6478 terminal = w32_create_terminal (dpyinfo); 6394 terminal = w32_create_terminal (dpyinfo);
6479 6395
6480 /* Set the name of the terminal. */ 6396 /* Set the name of the terminal. */
6481 terminal->name = xmalloc (SBYTES (display_name) + 1); 6397 terminal->name = xlispstrdup (display_name);
6482 strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
6483 terminal->name[SBYTES (display_name)] = 0;
6484 6398
6485 dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL; 6399 dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL;
6486 6400
diff --git a/src/w32term.h b/src/w32term.h
index 3c9cce35221..41c5c71832a 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -451,9 +451,11 @@ struct scroll_bar {
451 being dragged, this is Qnil. */ 451 being dragged, this is Qnil. */
452 Lisp_Object dragging; 452 Lisp_Object dragging;
453 453
454 /* t if the background of the fringe that is adjacent to a scroll 454 /* 1 if the background of the fringe that is adjacent to a scroll
455 bar is extended to the gap between the fringe and the bar. */ 455 bar is extended to the gap between the fringe and the bar. */
456 Lisp_Object fringe_extended_p; 456 /* Note: this could be a bit field, but we need to take its address
457 in ALLOCATE_PSEUDOVECTOR (see x_scroll_bar_create). */
458 bool fringe_extended_p;
457}; 459};
458 460
459/* Turning a lisp vector value into a pointer to a struct scroll_bar. */ 461/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
diff --git a/src/window.c b/src/window.c
index 1b288368884..ef96861dc71 100644
--- a/src/window.c
+++ b/src/window.c
@@ -66,10 +66,9 @@ static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
66static int displayed_window_lines (struct window *); 66static int displayed_window_lines (struct window *);
67static int count_windows (struct window *); 67static int count_windows (struct window *);
68static int get_leaf_windows (struct window *, struct window **, int); 68static int get_leaf_windows (struct window *, struct window **, int);
69static void window_scroll (Lisp_Object, EMACS_INT, int, int); 69static void window_scroll (Lisp_Object, EMACS_INT, bool, int);
70static void window_scroll_pixel_based (Lisp_Object, int, int, int); 70static void window_scroll_pixel_based (Lisp_Object, int, bool, int);
71static void window_scroll_line_based (Lisp_Object, int, int, int); 71static void window_scroll_line_based (Lisp_Object, int, bool, int);
72static int freeze_window_start (struct window *, void *);
73static Lisp_Object window_list (void); 72static Lisp_Object window_list (void);
74static int add_window_to_list (struct window *, void *); 73static int add_window_to_list (struct window *, void *);
75static Lisp_Object next_window (Lisp_Object, Lisp_Object, 74static Lisp_Object next_window (Lisp_Object, Lisp_Object,
@@ -88,6 +87,14 @@ static void window_resize_apply (struct window *, bool);
88static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 87static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
89static void select_window_1 (Lisp_Object, bool); 88static void select_window_1 (Lisp_Object, bool);
90 89
90static struct window *set_window_fringes (struct window *, Lisp_Object,
91 Lisp_Object, Lisp_Object);
92static struct window *set_window_margins (struct window *, Lisp_Object,
93 Lisp_Object);
94static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
95 Lisp_Object, Lisp_Object);
96static void apply_window_adjustment (struct window *);
97
91/* This is the window in which the terminal's cursor should 98/* This is the window in which the terminal's cursor should
92 be left when nothing is being done with it. This must 99 be left when nothing is being done with it. This must
93 always be a leaf window, and its buffer is selected by 100 always be a leaf window, and its buffer is selected by
@@ -152,16 +159,6 @@ wset_display_table (struct window *w, Lisp_Object val)
152 w->display_table = val; 159 w->display_table = val;
153} 160}
154static void 161static void
155wset_left_fringe_width (struct window *w, Lisp_Object val)
156{
157 w->left_fringe_width = val;
158}
159static void
160wset_left_margin_cols (struct window *w, Lisp_Object val)
161{
162 w->left_margin_cols = val;
163}
164static void
165wset_new_normal (struct window *w, Lisp_Object val) 162wset_new_normal (struct window *w, Lisp_Object val)
166{ 163{
167 w->new_normal = val; 164 w->new_normal = val;
@@ -192,21 +189,6 @@ wset_pointm (struct window *w, Lisp_Object val)
192 w->pointm = val; 189 w->pointm = val;
193} 190}
194static void 191static void
195wset_right_fringe_width (struct window *w, Lisp_Object val)
196{
197 w->right_fringe_width = val;
198}
199static void
200wset_right_margin_cols (struct window *w, Lisp_Object val)
201{
202 w->right_margin_cols = val;
203}
204static void
205wset_scroll_bar_width (struct window *w, Lisp_Object val)
206{
207 w->scroll_bar_width = val;
208}
209static void
210wset_start (struct window *w, Lisp_Object val) 192wset_start (struct window *w, Lisp_Object val)
211{ 193{
212 w->start = val; 194 w->start = val;
@@ -239,6 +221,17 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val)
239 w->horizontal = horflag; 221 w->horizontal = horflag;
240} 222}
241 223
224/* Nonzero if leaf window W doesn't reflect the actual state
225 of displayed buffer due to its text or overlays change. */
226
227bool
228window_outdated (struct window *w)
229{
230 struct buffer *b = XBUFFER (w->contents);
231 return (w->last_modified < BUF_MODIFF (b)
232 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b));
233}
234
242struct window * 235struct window *
243decode_live_window (register Lisp_Object window) 236decode_live_window (register Lisp_Object window)
244{ 237{
@@ -488,7 +481,6 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
488 CHECK_LIVE_WINDOW (window); 481 CHECK_LIVE_WINDOW (window);
489 482
490 w = XWINDOW (window); 483 w = XWINDOW (window);
491 w->frozen_window_start_p = 0;
492 484
493 /* Make the selected window's buffer current. */ 485 /* Make the selected window's buffer current. */
494 Fset_buffer (w->contents); 486 Fset_buffer (w->contents);
@@ -557,15 +549,7 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
557 than one window. It also matters when 549 than one window. It also matters when
558 redisplay_window has altered point after scrolling, 550 redisplay_window has altered point after scrolling,
559 because it makes the change only in the window. */ 551 because it makes the change only in the window. */
560 { 552 set_point_from_marker (XWINDOW (window)->pointm);
561 register ptrdiff_t new_point = marker_position (XWINDOW (window)->pointm);
562 if (new_point < BEGV)
563 SET_PT (BEGV);
564 else if (new_point > ZV)
565 SET_PT (ZV);
566 else
567 SET_PT (new_point);
568 }
569} 553}
570 554
571DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, 555DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
@@ -1353,7 +1337,7 @@ struct check_window_data
1353static int 1337static int
1354check_window_containing (struct window *w, void *user_data) 1338check_window_containing (struct window *w, void *user_data)
1355{ 1339{
1356 struct check_window_data *cw = (struct check_window_data *) user_data; 1340 struct check_window_data *cw = user_data;
1357 enum window_part found; 1341 enum window_part found;
1358 int continue_p = 1; 1342 int continue_p = 1;
1359 1343
@@ -1506,12 +1490,10 @@ if it isn't already recorded. */)
1506 || !w->window_end_valid 1490 || !w->window_end_valid
1507 || b->clip_changed 1491 || b->clip_changed
1508 || b->prevent_redisplay_optimizations_p 1492 || b->prevent_redisplay_optimizations_p
1509 || w->last_modified < BUF_MODIFF (b) 1493 || window_outdated (w))
1510 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
1511 && !noninteractive) 1494 && !noninteractive)
1512 { 1495 {
1513 struct text_pos startp; 1496 struct text_pos startp;
1514 ptrdiff_t charpos = marker_position (w->start);
1515 struct it it; 1497 struct it it;
1516 struct buffer *old_buffer = NULL; 1498 struct buffer *old_buffer = NULL;
1517 void *itdata = NULL; 1499 void *itdata = NULL;
@@ -1529,12 +1511,7 @@ if it isn't already recorded. */)
1529 `-l' containing a call to `rmail' with subsequent other 1511 `-l' containing a call to `rmail' with subsequent other
1530 commands. At the end, W->start happened to be BEG, while 1512 commands. At the end, W->start happened to be BEG, while
1531 rmail had already narrowed the buffer. */ 1513 rmail had already narrowed the buffer. */
1532 if (charpos < BEGV) 1514 CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
1533 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
1534 else if (charpos > ZV)
1535 SET_TEXT_POS (startp, ZV, ZV_BYTE);
1536 else
1537 SET_TEXT_POS_FROM_MARKER (startp, w->start);
1538 1515
1539 itdata = bidi_shelve_cache (); 1516 itdata = bidi_shelve_cache ();
1540 start_display (&it, w, startp); 1517 start_display (&it, w, startp);
@@ -1548,7 +1525,7 @@ if it isn't already recorded. */)
1548 set_buffer_internal (old_buffer); 1525 set_buffer_internal (old_buffer);
1549 } 1526 }
1550 else 1527 else
1551 XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos)); 1528 XSETINT (value, BUF_Z (b) - w->window_end_pos);
1552 1529
1553 return value; 1530 return value;
1554} 1531}
@@ -1604,9 +1581,8 @@ overriding motion of point in order to display at this exact start. */)
1604 if (NILP (noforce)) 1581 if (NILP (noforce))
1605 w->force_start = 1; 1582 w->force_start = 1;
1606 w->update_mode_line = 1; 1583 w->update_mode_line = 1;
1607 w->last_modified = 0; 1584 if (w != XWINDOW (selected_window))
1608 w->last_overlay_modified = 0; 1585 /* Enforce full redisplay. FIXME: make it more selective. */
1609 if (!EQ (window, selected_window))
1610 windows_or_buffers_changed++; 1586 windows_or_buffers_changed++;
1611 1587
1612 return pos; 1588 return pos;
@@ -1720,8 +1696,7 @@ Return nil if window display is not up-to-date. In that case, use
1720 || windows_or_buffers_changed 1696 || windows_or_buffers_changed
1721 || b->clip_changed 1697 || b->clip_changed
1722 || b->prevent_redisplay_optimizations_p 1698 || b->prevent_redisplay_optimizations_p
1723 || w->last_modified < BUF_MODIFF (b) 1699 || window_outdated (w))
1724 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
1725 return Qnil; 1700 return Qnil;
1726 1701
1727 if (NILP (line)) 1702 if (NILP (line))
@@ -2038,16 +2013,15 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
2038 n->desired_matrix = n->current_matrix = 0; 2013 n->desired_matrix = n->current_matrix = 0;
2039 n->vscroll = 0; 2014 n->vscroll = 0;
2040 memset (&n->cursor, 0, sizeof (n->cursor)); 2015 memset (&n->cursor, 0, sizeof (n->cursor));
2041 memset (&n->last_cursor, 0, sizeof (n->last_cursor));
2042 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor)); 2016 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
2017 n->last_cursor_vpos = 0;
2043 n->phys_cursor_type = -1; 2018 n->phys_cursor_type = -1;
2044 n->phys_cursor_width = -1; 2019 n->phys_cursor_width = -1;
2045 n->must_be_updated_p = 0; 2020 n->must_be_updated_p = 0;
2046 n->pseudo_window_p = 0; 2021 n->pseudo_window_p = 0;
2047 wset_window_end_vpos (n, make_number (0)); 2022 n->window_end_vpos = 0;
2048 wset_window_end_pos (n, make_number (0)); 2023 n->window_end_pos = 0;
2049 n->window_end_valid = 0; 2024 n->window_end_valid = 0;
2050 n->frozen_window_start_p = 0;
2051 } 2025 }
2052 2026
2053 tem = o->next; 2027 tem = o->next;
@@ -2156,7 +2130,7 @@ delete_deletable_window (Lisp_Object window)
2156static int 2130static int
2157add_window_to_list (struct window *w, void *user_data) 2131add_window_to_list (struct window *w, void *user_data)
2158{ 2132{
2159 Lisp_Object *list = (Lisp_Object *) user_data; 2133 Lisp_Object *list = user_data;
2160 Lisp_Object window; 2134 Lisp_Object window;
2161 XSETWINDOW (window, w); 2135 XSETWINDOW (window, w);
2162 *list = Fcons (window, *list); 2136 *list = Fcons (window, *list);
@@ -2854,7 +2828,7 @@ window-start value is reasonable when this function is called. */)
2854 block_input (); 2828 block_input ();
2855 if (!FRAME_INITIAL_P (f)) 2829 if (!FRAME_INITIAL_P (f))
2856 { 2830 {
2857 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); 2831 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
2858 2832
2859 /* We are going to free the glyph matrices of WINDOW, and with 2833 /* We are going to free the glyph matrices of WINDOW, and with
2860 that we might lose any information about glyph rows that have 2834 that we might lose any information about glyph rows that have
@@ -2864,11 +2838,7 @@ window-start value is reasonable when this function is called. */)
2864 frame's up-to-date hook that mouse highlight was overwritten, 2838 frame's up-to-date hook that mouse highlight was overwritten,
2865 so that it will arrange for redisplaying the highlight. */ 2839 so that it will arrange for redisplaying the highlight. */
2866 if (EQ (hlinfo->mouse_face_window, window)) 2840 if (EQ (hlinfo->mouse_face_window, window))
2867 { 2841 reset_mouse_highlight (hlinfo);
2868 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
2869 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
2870 hlinfo->mouse_face_window = Qnil;
2871 }
2872 } 2842 }
2873 free_window_matrices (r); 2843 free_window_matrices (r);
2874 2844
@@ -3063,15 +3033,12 @@ adjust_window_margins (struct window *w)
3063 if (WINDOW_RIGHT_MARGIN_COLS (w) > 0) 3033 if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
3064 { 3034 {
3065 if (WINDOW_LEFT_MARGIN_COLS (w) > 0) 3035 if (WINDOW_LEFT_MARGIN_COLS (w) > 0)
3066 { 3036 w->left_margin_cols = w->right_margin_cols = margin_cols / 2;
3067 wset_left_margin_cols (w, make_number (margin_cols / 2));
3068 wset_right_margin_cols (w, make_number (margin_cols / 2));
3069 }
3070 else 3037 else
3071 wset_right_margin_cols (w, make_number (margin_cols)); 3038 w->right_margin_cols = margin_cols;
3072 } 3039 }
3073 else 3040 else
3074 wset_left_margin_cols (w, make_number (margin_cols)); 3041 w->left_margin_cols = margin_cols;
3075 return 1; 3042 return 1;
3076} 3043}
3077 3044
@@ -3119,7 +3086,7 @@ run_window_configuration_change_hook (struct frame *f)
3119 3086
3120 if (SELECTED_FRAME () != f) 3087 if (SELECTED_FRAME () != f)
3121 { 3088 {
3122 record_unwind_protect (select_frame_norecord, Fselected_frame ()); 3089 record_unwind_protect (select_frame_norecord, selected_frame);
3123 select_frame_norecord (frame); 3090 select_frame_norecord (frame);
3124 } 3091 }
3125 3092
@@ -3134,7 +3101,7 @@ run_window_configuration_change_hook (struct frame *f)
3134 buffer))) 3101 buffer)))
3135 { 3102 {
3136 ptrdiff_t inner_count = SPECPDL_INDEX (); 3103 ptrdiff_t inner_count = SPECPDL_INDEX ();
3137 record_unwind_protect (select_window_norecord, Fselected_window ()); 3104 record_unwind_protect (select_window_norecord, selected_window);
3138 select_window_norecord (window); 3105 select_window_norecord (window);
3139 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, 3106 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
3140 buffer)); 3107 buffer));
@@ -3185,9 +3152,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3185 bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1)); 3152 bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1));
3186 bset_display_time (b, Fcurrent_time ()); 3153 bset_display_time (b, Fcurrent_time ());
3187 3154
3188 wset_window_end_pos (w, make_number (0)); 3155 w->window_end_pos = 0;
3189 wset_window_end_vpos (w, make_number (0)); 3156 w->window_end_vpos = 0;
3190 memset (&w->last_cursor, 0, sizeof w->last_cursor); 3157 w->last_cursor_vpos = 0;
3191 3158
3192 if (!(keep_margins_p && samebuf)) 3159 if (!(keep_margins_p && samebuf))
3193 { /* If we're not actually changing the buffer, don't reset hscroll and 3160 { /* If we're not actually changing the buffer, don't reset hscroll and
@@ -3206,8 +3173,6 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3206 buffer); 3173 buffer);
3207 w->start_at_line_beg = 0; 3174 w->start_at_line_beg = 0;
3208 w->force_start = 0; 3175 w->force_start = 0;
3209 w->last_modified = 0;
3210 w->last_overlay_modified = 0;
3211 } 3176 }
3212 /* Maybe we could move this into the `if' but it's not obviously safe and 3177 /* Maybe we could move this into the `if' but it's not obviously safe and
3213 I doubt it's worth the trouble. */ 3178 I doubt it's worth the trouble. */
@@ -3227,28 +3192,14 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3227 if (!keep_margins_p) 3192 if (!keep_margins_p)
3228 { 3193 {
3229 /* Set left and right marginal area width etc. from buffer. */ 3194 /* Set left and right marginal area width etc. from buffer. */
3230 3195 set_window_fringes (w, BVAR (b, left_fringe_width),
3231 /* This may call adjust_window_margins three times, so 3196 BVAR (b, right_fringe_width),
3232 temporarily disable window margins. */ 3197 BVAR (b, fringes_outside_margins));
3233 Lisp_Object save_left = w->left_margin_cols; 3198 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
3234 Lisp_Object save_right = w->right_margin_cols; 3199 BVAR (b, vertical_scroll_bar_type), Qnil);
3235 3200 set_window_margins (w, BVAR (b, left_margin_cols),
3236 wset_left_margin_cols (w, Qnil); 3201 BVAR (b, right_margin_cols));
3237 wset_right_margin_cols (w, Qnil); 3202 apply_window_adjustment (w);
3238
3239 Fset_window_fringes (window,
3240 BVAR (b, left_fringe_width), BVAR (b, right_fringe_width),
3241 BVAR (b, fringes_outside_margins));
3242
3243 Fset_window_scroll_bars (window,
3244 BVAR (b, scroll_bar_width),
3245 BVAR (b, vertical_scroll_bar_type), Qnil);
3246
3247 wset_left_margin_cols (w, save_left);
3248 wset_right_margin_cols (w, save_right);
3249
3250 Fset_window_margins (window,
3251 BVAR (b, left_margin_cols), BVAR (b, right_margin_cols));
3252 } 3203 }
3253 3204
3254 if (run_hooks_p) 3205 if (run_hooks_p)
@@ -3384,10 +3335,8 @@ temp_output_buffer_show (register Lisp_Object buf)
3384 3335
3385 if (!NILP (Vtemp_buffer_show_function)) 3336 if (!NILP (Vtemp_buffer_show_function))
3386 call1 (Vtemp_buffer_show_function, buf); 3337 call1 (Vtemp_buffer_show_function, buf);
3387 else 3338 else if (WINDOW_LIVE_P (window = display_buffer (buf, Qnil, Qnil)))
3388 { 3339 {
3389 window = display_buffer (buf, Qnil, Qnil);
3390
3391 if (!EQ (XWINDOW (window)->frame, selected_frame)) 3340 if (!EQ (XWINDOW (window)->frame, selected_frame))
3392 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); 3341 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
3393 Vminibuf_scroll_window = window; 3342 Vminibuf_scroll_window = window;
@@ -3468,8 +3417,6 @@ make_window (void)
3468 wset_start (w, Fmake_marker ()); 3417 wset_start (w, Fmake_marker ());
3469 wset_pointm (w, Fmake_marker ()); 3418 wset_pointm (w, Fmake_marker ());
3470 wset_vertical_scroll_bar_type (w, Qt); 3419 wset_vertical_scroll_bar_type (w, Qt);
3471 wset_window_end_pos (w, make_number (0));
3472 wset_window_end_vpos (w, make_number (0));
3473 /* These Lisp fields are marked specially so they're not set to nil by 3420 /* These Lisp fields are marked specially so they're not set to nil by
3474 allocate_window. */ 3421 allocate_window. */
3475 wset_prev_buffers (w, Qnil); 3422 wset_prev_buffers (w, Qnil);
@@ -3478,8 +3425,10 @@ make_window (void)
3478 /* Initialize non-Lisp data. Note that allocate_window zeroes out all 3425 /* Initialize non-Lisp data. Note that allocate_window zeroes out all
3479 non-Lisp data, so do it only for slots which should not be zero. */ 3426 non-Lisp data, so do it only for slots which should not be zero. */
3480 w->nrows_scale_factor = w->ncols_scale_factor = 1; 3427 w->nrows_scale_factor = w->ncols_scale_factor = 1;
3428 w->left_fringe_width = w->right_fringe_width = -1;
3481 w->phys_cursor_type = -1; 3429 w->phys_cursor_type = -1;
3482 w->phys_cursor_width = -1; 3430 w->phys_cursor_width = -1;
3431 w->scroll_bar_width = -1;
3483 w->column_number_displayed = -1; 3432 w->column_number_displayed = -1;
3484 3433
3485 /* Reset window_list. */ 3434 /* Reset window_list. */
@@ -3668,10 +3617,6 @@ window_resize_apply (struct window *w, bool horflag)
3668 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3617 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3669 } 3618 }
3670 } 3619 }
3671
3672 /* Clear out some redisplay caches. */
3673 w->last_modified = 0;
3674 w->last_overlay_modified = 0;
3675} 3620}
3676 3621
3677 3622
@@ -3946,15 +3891,15 @@ set correctly. See the code of `split-window' for how this is done. */)
3946 } 3891 }
3947 3892
3948 n->window_end_valid = 0; 3893 n->window_end_valid = 0;
3949 memset (&n->last_cursor, 0, sizeof n->last_cursor); 3894 n->last_cursor_vpos = 0;
3950 3895
3951 /* Get special geometry settings from reference window. */ 3896 /* Get special geometry settings from reference window. */
3952 wset_left_margin_cols (n, r->left_margin_cols); 3897 n->left_margin_cols = r->left_margin_cols;
3953 wset_right_margin_cols (n, r->right_margin_cols); 3898 n->right_margin_cols = r->right_margin_cols;
3954 wset_left_fringe_width (n, r->left_fringe_width); 3899 n->left_fringe_width = r->left_fringe_width;
3955 wset_right_fringe_width (n, r->right_fringe_width); 3900 n->right_fringe_width = r->right_fringe_width;
3956 n->fringes_outside_margins = r->fringes_outside_margins; 3901 n->fringes_outside_margins = r->fringes_outside_margins;
3957 wset_scroll_bar_width (n, r->scroll_bar_width); 3902 n->scroll_bar_width = r->scroll_bar_width;
3958 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); 3903 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
3959 3904
3960 /* Directly assign orthogonal coordinates and sizes. */ 3905 /* Directly assign orthogonal coordinates and sizes. */
@@ -4190,9 +4135,7 @@ grow_mini_window (struct window *w, int delta)
4190 /* Grow the mini-window. */ 4135 /* Grow the mini-window. */
4191 w->top_line = r->top_line + r->total_lines; 4136 w->top_line = r->top_line + r->total_lines;
4192 w->total_lines -= XINT (value); 4137 w->total_lines -= XINT (value);
4193 w->last_modified = 0; 4138 /* Enforce full redisplay. FIXME: make it more selective. */
4194 w->last_overlay_modified = 0;
4195
4196 windows_or_buffers_changed++; 4139 windows_or_buffers_changed++;
4197 adjust_glyphs (f); 4140 adjust_glyphs (f);
4198 unblock_input (); 4141 unblock_input ();
@@ -4226,10 +4169,7 @@ shrink_mini_window (struct window *w)
4226 /* Shrink the mini-window. */ 4169 /* Shrink the mini-window. */
4227 w->top_line = r->top_line + r->total_lines; 4170 w->top_line = r->top_line + r->total_lines;
4228 w->total_lines = 1; 4171 w->total_lines = 1;
4229 4172 /* Enforce full redisplay. FIXME: make it more selective. */
4230 w->last_modified = 0;
4231 w->last_overlay_modified = 0;
4232
4233 windows_or_buffers_changed++; 4173 windows_or_buffers_changed++;
4234 adjust_glyphs (f); 4174 adjust_glyphs (f);
4235 unblock_input (); 4175 unblock_input ();
@@ -4336,7 +4276,7 @@ window_internal_height (struct window *w)
4336 respectively. */ 4276 respectively. */
4337 4277
4338static void 4278static void
4339window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) 4279window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
4340{ 4280{
4341 immediate_quit = 1; 4281 immediate_quit = 1;
4342 n = clip_to_bounds (INT_MIN, n, INT_MAX); 4282 n = clip_to_bounds (INT_MIN, n, INT_MAX);
@@ -4357,7 +4297,7 @@ window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror)
4357 descriptions. */ 4297 descriptions. */
4358 4298
4359static void 4299static void
4360window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) 4300window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4361{ 4301{
4362 struct it it; 4302 struct it it;
4363 struct window *w = XWINDOW (window); 4303 struct window *w = XWINDOW (window);
@@ -4455,8 +4395,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4455 w->contents); 4395 w->contents);
4456 w->start_at_line_beg = 1; 4396 w->start_at_line_beg = 1;
4457 w->update_mode_line = 1; 4397 w->update_mode_line = 1;
4458 w->last_modified = 0;
4459 w->last_overlay_modified = 0;
4460 /* Set force_start so that redisplay_window will run the 4398 /* Set force_start so that redisplay_window will run the
4461 window-scroll-functions. */ 4399 window-scroll-functions. */
4462 w->force_start = 1; 4400 w->force_start = 1;
@@ -4601,8 +4539,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4601 bytepos = marker_byte_position (w->start); 4539 bytepos = marker_byte_position (w->start);
4602 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); 4540 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
4603 w->update_mode_line = 1; 4541 w->update_mode_line = 1;
4604 w->last_modified = 0;
4605 w->last_overlay_modified = 0;
4606 /* Set force_start so that redisplay_window will run the 4542 /* Set force_start so that redisplay_window will run the
4607 window-scroll-functions. */ 4543 window-scroll-functions. */
4608 w->force_start = 1; 4544 w->force_start = 1;
@@ -4725,7 +4661,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4725 See the comment of window_scroll for parameter descriptions. */ 4661 See the comment of window_scroll for parameter descriptions. */
4726 4662
4727static void 4663static void
4728window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) 4664window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
4729{ 4665{
4730 register struct window *w = XWINDOW (window); 4666 register struct window *w = XWINDOW (window);
4731 /* Fvertical_motion enters redisplay, which can trigger 4667 /* Fvertical_motion enters redisplay, which can trigger
@@ -4737,7 +4673,7 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4737 register ptrdiff_t pos, pos_byte; 4673 register ptrdiff_t pos, pos_byte;
4738 register int ht = window_internal_height (w); 4674 register int ht = window_internal_height (w);
4739 register Lisp_Object tem; 4675 register Lisp_Object tem;
4740 int lose; 4676 bool lose;
4741 Lisp_Object bolp; 4677 Lisp_Object bolp;
4742 ptrdiff_t startpos = marker_position (w->start); 4678 ptrdiff_t startpos = marker_position (w->start);
4743 ptrdiff_t startbyte = marker_byte_position (w->start); 4679 ptrdiff_t startbyte = marker_byte_position (w->start);
@@ -4801,8 +4737,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4801 set_marker_restricted_both (w->start, w->contents, pos, pos_byte); 4737 set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
4802 w->start_at_line_beg = !NILP (bolp); 4738 w->start_at_line_beg = !NILP (bolp);
4803 w->update_mode_line = 1; 4739 w->update_mode_line = 1;
4804 w->last_modified = 0;
4805 w->last_overlay_modified = 0;
4806 /* Set force_start so that redisplay_window will run 4740 /* Set force_start so that redisplay_window will run
4807 the window-scroll-functions. */ 4741 the window-scroll-functions. */
4808 w->force_start = 1; 4742 w->force_start = 1;
@@ -5098,7 +5032,6 @@ displayed_window_lines (struct window *w)
5098{ 5032{
5099 struct it it; 5033 struct it it;
5100 struct text_pos start; 5034 struct text_pos start;
5101 ptrdiff_t charpos = marker_position (w->start);
5102 int height = window_box_height (w); 5035 int height = window_box_height (w);
5103 struct buffer *old_buffer; 5036 struct buffer *old_buffer;
5104 int bottom_y; 5037 int bottom_y;
@@ -5115,12 +5048,7 @@ displayed_window_lines (struct window *w)
5115 /* In case W->start is out of the accessible range, do something 5048 /* In case W->start is out of the accessible range, do something
5116 reasonable. This happens in Info mode when Info-scroll-down 5049 reasonable. This happens in Info mode when Info-scroll-down
5117 calls (recenter -1) while W->start is 1. */ 5050 calls (recenter -1) while W->start is 1. */
5118 if (charpos < BEGV) 5051 CLIP_TEXT_POS_FROM_MARKER (start, w->start);
5119 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5120 else if (charpos > ZV)
5121 SET_TEXT_POS (start, ZV, ZV_BYTE);
5122 else
5123 SET_TEXT_POS_FROM_MARKER (start, w->start);
5124 5052
5125 itdata = bidi_shelve_cache (); 5053 itdata = bidi_shelve_cache ();
5126 start_display (&it, w, start); 5054 start_display (&it, w, start);
@@ -5454,7 +5382,7 @@ struct save_window_data
5454 Lisp_Object saved_windows; 5382 Lisp_Object saved_windows;
5455 5383
5456 /* All fields above are traced by the GC. 5384 /* All fields above are traced by the GC.
5457 From `fame-cols' down, the fields are ignored by the GC. */ 5385 From `frame-cols' down, the fields are ignored by the GC. */
5458 5386
5459 int frame_cols, frame_lines, frame_menu_bar_lines; 5387 int frame_cols, frame_lines, frame_menu_bar_lines;
5460 int frame_tool_bar_lines; 5388 int frame_tool_bar_lines;
@@ -5703,12 +5631,12 @@ the return value is nil. Otherwise the value is t. */)
5703 w->hscroll = XFASTINT (p->hscroll); 5631 w->hscroll = XFASTINT (p->hscroll);
5704 w->min_hscroll = XFASTINT (p->min_hscroll); 5632 w->min_hscroll = XFASTINT (p->min_hscroll);
5705 wset_display_table (w, p->display_table); 5633 wset_display_table (w, p->display_table);
5706 wset_left_margin_cols (w, p->left_margin_cols); 5634 w->left_margin_cols = XINT (p->left_margin_cols);
5707 wset_right_margin_cols (w, p->right_margin_cols); 5635 w->right_margin_cols = XINT (p->right_margin_cols);
5708 wset_left_fringe_width (w, p->left_fringe_width); 5636 w->left_fringe_width = XINT (p->left_fringe_width);
5709 wset_right_fringe_width (w, p->right_fringe_width); 5637 w->right_fringe_width = XINT (p->right_fringe_width);
5710 w->fringes_outside_margins = !NILP (p->fringes_outside_margins); 5638 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
5711 wset_scroll_bar_width (w, p->scroll_bar_width); 5639 w->scroll_bar_width = XINT (p->scroll_bar_width);
5712 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); 5640 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
5713 wset_dedicated (w, p->dedicated); 5641 wset_dedicated (w, p->dedicated);
5714 wset_combination_limit (w, p->combination_limit); 5642 wset_combination_limit (w, p->combination_limit);
@@ -5734,9 +5662,6 @@ the return value is nil. Otherwise the value is t. */)
5734 } 5662 }
5735 } 5663 }
5736 5664
5737 w->last_modified = 0;
5738 w->last_overlay_modified = 0;
5739
5740 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) 5665 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5741 /* If saved buffer is alive, install it. */ 5666 /* If saved buffer is alive, install it. */
5742 { 5667 {
@@ -6007,12 +5932,12 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6007 XSETFASTINT (p->hscroll, w->hscroll); 5932 XSETFASTINT (p->hscroll, w->hscroll);
6008 XSETFASTINT (p->min_hscroll, w->min_hscroll); 5933 XSETFASTINT (p->min_hscroll, w->min_hscroll);
6009 p->display_table = w->display_table; 5934 p->display_table = w->display_table;
6010 p->left_margin_cols = w->left_margin_cols; 5935 p->left_margin_cols = make_number (w->left_margin_cols);
6011 p->right_margin_cols = w->right_margin_cols; 5936 p->right_margin_cols = make_number (w->right_margin_cols);
6012 p->left_fringe_width = w->left_fringe_width; 5937 p->left_fringe_width = make_number (w->left_fringe_width);
6013 p->right_fringe_width = w->right_fringe_width; 5938 p->right_fringe_width = make_number (w->right_fringe_width);
6014 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; 5939 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
6015 p->scroll_bar_width = w->scroll_bar_width; 5940 p->scroll_bar_width = make_number (w->scroll_bar_width);
6016 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 5941 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
6017 p->dedicated = w->dedicated; 5942 p->dedicated = w->dedicated;
6018 p->combination_limit = w->combination_limit; 5943 p->combination_limit = w->combination_limit;
@@ -6153,11 +6078,46 @@ saved by this function. */)
6153 XSETWINDOW_CONFIGURATION (tem, data); 6078 XSETWINDOW_CONFIGURATION (tem, data);
6154 return (tem); 6079 return (tem);
6155} 6080}
6081
6082/* Called after W's margins, fringes or scroll bars was adjusted. */
6083
6084static void
6085apply_window_adjustment (struct window *w)
6086{
6087 eassert (w);
6088 adjust_window_margins (w);
6089 clear_glyph_matrix (w->current_matrix);
6090 w->window_end_valid = 0;
6091 windows_or_buffers_changed++;
6092 adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
6093}
6094
6156 6095
6157/*********************************************************************** 6096/***********************************************************************
6158 Marginal Areas 6097 Marginal Areas
6159 ***********************************************************************/ 6098 ***********************************************************************/
6160 6099
6100static struct window *
6101set_window_margins (struct window *w, Lisp_Object left_width,
6102 Lisp_Object right_width)
6103{
6104 int left, right;
6105
6106 /* FIXME: what about margins that are too wide? */
6107 left = (NILP (left_width) ? 0
6108 : (CHECK_NATNUM (left_width), XINT (left_width)));
6109 right = (NILP (right_width) ? 0
6110 : (CHECK_NATNUM (right_width), XINT (right_width)));
6111
6112 if (w->left_margin_cols != left || w->right_margin_cols != right)
6113 {
6114 w->left_margin_cols = left;
6115 w->right_margin_cols = right;
6116 return w;
6117 }
6118 return NULL;
6119}
6120
6161DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, 6121DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
6162 2, 3, 0, 6122 2, 3, 0,
6163 doc: /* Set width of marginal areas of window WINDOW. 6123 doc: /* Set width of marginal areas of window WINDOW.
@@ -6166,41 +6126,14 @@ WINDOW must be a live window and defaults to the selected one.
6166Second arg LEFT-WIDTH specifies the number of character cells to 6126Second arg LEFT-WIDTH specifies the number of character cells to
6167reserve for the left marginal area. Optional third arg RIGHT-WIDTH 6127reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6168does the same for the right marginal area. A nil width parameter 6128does the same for the right marginal area. A nil width parameter
6169means no margin. */) 6129means no margin.
6130
6131Return t if any margin was actually changed and nil otherwise. */)
6170 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width) 6132 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width)
6171{ 6133{
6172 struct window *w = decode_live_window (window); 6134 struct window *w = set_window_margins (decode_live_window (window),
6173 6135 left_width, right_width);
6174 /* Translate negative or zero widths to nil. 6136 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6175 Margins that are too wide have to be checked elsewhere. */
6176
6177 if (!NILP (left_width))
6178 {
6179 CHECK_NUMBER (left_width);
6180 if (XINT (left_width) <= 0)
6181 left_width = Qnil;
6182 }
6183
6184 if (!NILP (right_width))
6185 {
6186 CHECK_NUMBER (right_width);
6187 if (XINT (right_width) <= 0)
6188 right_width = Qnil;
6189 }
6190
6191 if (!EQ (w->left_margin_cols, left_width)
6192 || !EQ (w->right_margin_cols, right_width))
6193 {
6194 wset_left_margin_cols (w, left_width);
6195 wset_right_margin_cols (w, right_width);
6196
6197 adjust_window_margins (w);
6198
6199 ++windows_or_buffers_changed;
6200 adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
6201 }
6202
6203 return Qnil;
6204} 6137}
6205 6138
6206 6139
@@ -6215,7 +6148,8 @@ as nil. */)
6215 (Lisp_Object window) 6148 (Lisp_Object window)
6216{ 6149{
6217 struct window *w = decode_live_window (window); 6150 struct window *w = decode_live_window (window);
6218 return Fcons (w->left_margin_cols, w->right_margin_cols); 6151 return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil,
6152 w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil);
6219} 6153}
6220 6154
6221 6155
@@ -6224,6 +6158,31 @@ as nil. */)
6224 Fringes 6158 Fringes
6225 ***********************************************************************/ 6159 ***********************************************************************/
6226 6160
6161static struct window *
6162set_window_fringes (struct window *w, Lisp_Object left_width,
6163 Lisp_Object right_width, Lisp_Object outside_margins)
6164{
6165 int left, right, outside = !NILP (outside_margins);
6166
6167 left = (NILP (left_width) ? -1
6168 : (CHECK_NATNUM (left_width), XINT (left_width)));
6169 right = (NILP (right_width) ? -1
6170 : (CHECK_NATNUM (right_width), XINT (right_width)));
6171
6172 /* Do nothing on a tty or if nothing to actually change. */
6173 if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
6174 && (w->left_fringe_width != left
6175 || w->right_fringe_width != right
6176 || w->fringes_outside_margins != outside))
6177 {
6178 w->left_fringe_width = left;
6179 w->right_fringe_width = right;
6180 w->fringes_outside_margins = outside;
6181 return w;
6182 }
6183 return NULL;
6184}
6185
6227DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 6186DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
6228 2, 4, 0, 6187 2, 4, 0,
6229 doc: /* Set the fringe widths of window WINDOW. 6188 doc: /* Set the fringe widths of window WINDOW.
@@ -6236,37 +6195,16 @@ frame's default fringe width. Default fringe widths can be set with
6236the command `set-fringe-style'. 6195the command `set-fringe-style'.
6237If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes 6196If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6238outside of the display margins. By default, fringes are drawn between 6197outside of the display margins. By default, fringes are drawn between
6239display marginal areas and the text area. */) 6198display marginal areas and the text area.
6240 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins)
6241{
6242 struct window *w = decode_live_window (window);
6243 int outside = !NILP (outside_margins);
6244
6245 if (!NILP (left_width))
6246 CHECK_NATNUM (left_width);
6247 if (!NILP (right_width))
6248 CHECK_NATNUM (right_width);
6249
6250 /* Do nothing on a tty. */
6251 if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
6252 && (!EQ (w->left_fringe_width, left_width)
6253 || !EQ (w->right_fringe_width, right_width)
6254 || w->fringes_outside_margins != outside))
6255 {
6256 wset_left_fringe_width (w, left_width);
6257 wset_right_fringe_width (w, right_width);
6258 w->fringes_outside_margins = outside;
6259 6199
6260 adjust_window_margins (w); 6200Return t if any fringe was actually changed and nil otherwise. */)
6261 6201 (Lisp_Object window, Lisp_Object left_width,
6262 clear_glyph_matrix (w->current_matrix); 6202 Lisp_Object right_width, Lisp_Object outside_margins)
6263 w->window_end_valid = 0; 6203{
6264 6204 struct window *w
6265 ++windows_or_buffers_changed; 6205 = set_window_fringes (decode_live_window (window),
6266 adjust_glyphs (XFRAME (WINDOW_FRAME (w))); 6206 left_width, right_width, outside_margins);
6267 } 6207 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6268
6269 return Qnil;
6270} 6208}
6271 6209
6272 6210
@@ -6291,29 +6229,14 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6291 Scroll bars 6229 Scroll bars
6292 ***********************************************************************/ 6230 ***********************************************************************/
6293 6231
6294DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, 6232static struct window *
6295 Sset_window_scroll_bars, 2, 4, 0, 6233set_window_scroll_bars (struct window *w, Lisp_Object width,
6296 doc: /* Set width and type of scroll bars of window WINDOW. 6234 Lisp_Object vertical_type, Lisp_Object horizontal_type)
6297WINDOW must be a live window and defaults to the selected one.
6298
6299Second parameter WIDTH specifies the pixel width for the scroll bar;
6300this is automatically adjusted to a multiple of the frame column width.
6301Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6302bar: left, right, or nil.
6303If WIDTH is nil, use the frame's scroll-bar width.
6304If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6305Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6306 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, Lisp_Object horizontal_type)
6307{ 6235{
6308 struct window *w = decode_live_window (window); 6236 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
6309 6237
6310 if (!NILP (width)) 6238 if (iwidth == 0)
6311 { 6239 vertical_type = Qnil;
6312 CHECK_RANGED_INTEGER (width, 0, INT_MAX);
6313
6314 if (XINT (width) == 0)
6315 vertical_type = Qnil;
6316 }
6317 6240
6318 if (!(NILP (vertical_type) 6241 if (!(NILP (vertical_type)
6319 || EQ (vertical_type, Qleft) 6242 || EQ (vertical_type, Qleft)
@@ -6321,22 +6244,37 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6321 || EQ (vertical_type, Qt))) 6244 || EQ (vertical_type, Qt)))
6322 error ("Invalid type of vertical scroll bar"); 6245 error ("Invalid type of vertical scroll bar");
6323 6246
6324 if (!EQ (w->scroll_bar_width, width) 6247 if (w->scroll_bar_width != iwidth
6325 || !EQ (w->vertical_scroll_bar_type, vertical_type)) 6248 || !EQ (w->vertical_scroll_bar_type, vertical_type))
6326 { 6249 {
6327 wset_scroll_bar_width (w, width); 6250 w->scroll_bar_width = iwidth;
6328 wset_vertical_scroll_bar_type (w, vertical_type); 6251 wset_vertical_scroll_bar_type (w, vertical_type);
6252 return w;
6253 }
6254 return NULL;
6255}
6329 6256
6330 adjust_window_margins (w); 6257DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6331 6258 Sset_window_scroll_bars, 2, 4, 0,
6332 clear_glyph_matrix (w->current_matrix); 6259 doc: /* Set width and type of scroll bars of window WINDOW.
6333 w->window_end_valid = 0; 6260WINDOW must be a live window and defaults to the selected one.
6334 6261
6335 ++windows_or_buffers_changed; 6262Second parameter WIDTH specifies the pixel width for the scroll bar;
6336 adjust_glyphs (XFRAME (WINDOW_FRAME (w))); 6263this is automatically adjusted to a multiple of the frame column width.
6337 } 6264Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6265bar: left, right, or nil.
6266If WIDTH is nil, use the frame's scroll-bar width.
6267If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6268Fourth parameter HORIZONTAL-TYPE is currently unused.
6338 6269
6339 return Qnil; 6270Return t if scroll bars was actually changed and nil otherwise. */)
6271 (Lisp_Object window, Lisp_Object width,
6272 Lisp_Object vertical_type, Lisp_Object horizontal_type)
6273{
6274 struct window *w
6275 = set_window_scroll_bars (decode_live_window (window),
6276 width, vertical_type, horizontal_type);
6277 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6340} 6278}
6341 6279
6342 6280
@@ -6465,38 +6403,6 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u
6465 return cont; 6403 return cont;
6466} 6404}
6467 6405
6468
6469/* Freeze or unfreeze the window start of W unless it is a
6470 mini-window or the selected window. FREEZE_P non-null means freeze
6471 the window start. */
6472
6473static int
6474freeze_window_start (struct window *w, void *freeze_p)
6475{
6476 if (MINI_WINDOW_P (w)
6477 || (WINDOWP (selected_window) /* Can be nil in corner cases. */
6478 && (w == XWINDOW (selected_window)
6479 || (MINI_WINDOW_P (XWINDOW (selected_window))
6480 && ! NILP (Vminibuf_scroll_window)
6481 && w == XWINDOW (Vminibuf_scroll_window)))))
6482 freeze_p = NULL;
6483
6484 w->frozen_window_start_p = freeze_p != NULL;
6485 return 1;
6486}
6487
6488
6489/* Freeze or unfreeze the window starts of all leaf windows on frame
6490 F, except the selected window and a mini-window. FREEZE_P non-zero
6491 means freeze the window start. */
6492
6493void
6494freeze_window_starts (struct frame *f, bool freeze_p)
6495{
6496 foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
6497}
6498
6499
6500/*********************************************************************** 6406/***********************************************************************
6501 Initialization 6407 Initialization
6502 ***********************************************************************/ 6408 ***********************************************************************/
diff --git a/src/window.h b/src/window.h
index 5da6165c48d..efe03737052 100644
--- a/src/window.h
+++ b/src/window.h
@@ -141,32 +141,10 @@ struct window
141 it yet, or if the frame doesn't have any scroll bars, this is nil. */ 141 it yet, or if the frame doesn't have any scroll bars, this is nil. */
142 Lisp_Object vertical_scroll_bar; 142 Lisp_Object vertical_scroll_bar;
143 143
144 /* Width of left and right marginal areas. A value of nil means
145 no margin. */
146 Lisp_Object left_margin_cols;
147 Lisp_Object right_margin_cols;
148
149 /* Width of left and right fringes.
150 A value of nil or t means use frame values. */
151 Lisp_Object left_fringe_width;
152 Lisp_Object right_fringe_width;
153
154 /* Pixel width of scroll bars.
155 A value of nil or t means use frame values. */
156 Lisp_Object scroll_bar_width;
157
158 /* Type of vertical scroll bar. A value of nil means 144 /* Type of vertical scroll bar. A value of nil means
159 no scroll bar. A value of t means use frame value. */ 145 no scroll bar. A value of t means use frame value. */
160 Lisp_Object vertical_scroll_bar_type; 146 Lisp_Object vertical_scroll_bar_type;
161 147
162 /* Z - the buffer position of the last glyph in the current
163 matrix of W. Only valid if window_end_valid is nonzero. */
164 Lisp_Object window_end_pos;
165
166 /* Glyph matrix row of the last glyph in the current matrix
167 of W. Only valid if window_end_valid is nonzero. */
168 Lisp_Object window_end_vpos;
169
170 /* Display-table to use for displaying chars in this window. 148 /* Display-table to use for displaying chars in this window.
171 Nil means use the buffer's own display-table. */ 149 Nil means use the buffer's own display-table. */
172 Lisp_Object display_table; 150 Lisp_Object display_table;
@@ -251,10 +229,6 @@ struct window
251 as the normal may yield a matrix which is too small. */ 229 as the normal may yield a matrix which is too small. */
252 int nrows_scale_factor, ncols_scale_factor; 230 int nrows_scale_factor, ncols_scale_factor;
253 231
254 /* Cursor position as of last update that completed without
255 pause. This is the position of last_point. */
256 struct cursor_pos last_cursor;
257
258 /* Intended cursor position. This is a position within the 232 /* Intended cursor position. This is a position within the
259 glyph matrix. */ 233 glyph matrix. */
260 struct cursor_pos cursor; 234 struct cursor_pos cursor;
@@ -262,6 +236,13 @@ struct window
262 /* Where the cursor actually is. */ 236 /* Where the cursor actually is. */
263 struct cursor_pos phys_cursor; 237 struct cursor_pos phys_cursor;
264 238
239 /* Internally used for redisplay purposes. */
240 struct cursor_pos output_cursor;
241
242 /* Vertical cursor position as of last update that completed
243 without pause. This is the position of last_point. */
244 int last_cursor_vpos;
245
265 /* Cursor type and width of last cursor drawn on the window. 246 /* Cursor type and width of last cursor drawn on the window.
266 Used for X and w32 frames; -1 initially. */ 247 Used for X and w32 frames; -1 initially. */
267 int phys_cursor_type, phys_cursor_width; 248 int phys_cursor_type, phys_cursor_width;
@@ -269,6 +250,28 @@ struct window
269 /* This is handy for undrawing the cursor. */ 250 /* This is handy for undrawing the cursor. */
270 int phys_cursor_ascent, phys_cursor_height; 251 int phys_cursor_ascent, phys_cursor_height;
271 252
253 /* Width of left and right fringes, in pixels.
254 A value of -1 means use frame values. */
255 int left_fringe_width;
256 int right_fringe_width;
257
258 /* Width of left and right marginal areas in columns.
259 A value of 0 means no margin. */
260 int left_margin_cols;
261 int right_margin_cols;
262
263 /* Pixel width of scroll bars.
264 A value of -1 means use frame values. */
265 int scroll_bar_width;
266
267 /* Z - the buffer position of the last glyph in the current
268 matrix of W. Only valid if window_end_valid is nonzero. */
269 ptrdiff_t window_end_pos;
270
271 /* Glyph matrix row of the last glyph in the current matrix
272 of W. Only valid if window_end_valid is nonzero. */
273 int window_end_vpos;
274
272 /* Non-zero if this window is a minibuffer window. */ 275 /* Non-zero if this window is a minibuffer window. */
273 unsigned mini : 1; 276 unsigned mini : 1;
274 277
@@ -316,11 +319,6 @@ struct window
316 Currently only used for menu bar windows of frames. */ 319 Currently only used for menu bar windows of frames. */
317 unsigned pseudo_window_p : 1; 320 unsigned pseudo_window_p : 1;
318 321
319 /* 1 means the window start of this window is frozen and may not
320 be changed during redisplay. If point is not in the window,
321 accept that. */
322 unsigned frozen_window_start_p : 1;
323
324 /* Non-zero means fringes are drawn outside display margins. 322 /* Non-zero means fringes are drawn outside display margins.
325 Otherwise draw them between margin areas and text. */ 323 Otherwise draw them between margin areas and text. */
326 unsigned fringes_outside_margins : 1; 324 unsigned fringes_outside_margins : 1;
@@ -371,16 +369,6 @@ wset_vertical_scroll_bar (struct window *w, Lisp_Object val)
371 w->vertical_scroll_bar = val; 369 w->vertical_scroll_bar = val;
372} 370}
373WINDOW_INLINE void 371WINDOW_INLINE void
374wset_window_end_pos (struct window *w, Lisp_Object val)
375{
376 w->window_end_pos = val;
377}
378WINDOW_INLINE void
379wset_window_end_vpos (struct window *w, Lisp_Object val)
380{
381 w->window_end_vpos = val;
382}
383WINDOW_INLINE void
384wset_prev_buffers (struct window *w, Lisp_Object val) 372wset_prev_buffers (struct window *w, Lisp_Object val)
385{ 373{
386 w->prev_buffers = val; 374 w->prev_buffers = val;
@@ -605,33 +593,21 @@ wset_next_buffers (struct window *w, Lisp_Object val)
605 593
606/* Width of left margin area in columns. */ 594/* Width of left margin area in columns. */
607 595
608#define WINDOW_LEFT_MARGIN_COLS(W) \ 596#define WINDOW_LEFT_MARGIN_COLS(W) (W->left_margin_cols)
609 (NILP (W->left_margin_cols) \
610 ? 0 \
611 : XINT (W->left_margin_cols))
612 597
613/* Width of right marginal area in columns. */ 598/* Width of right marginal area in columns. */
614 599
615#define WINDOW_RIGHT_MARGIN_COLS(W) \ 600#define WINDOW_RIGHT_MARGIN_COLS(W) (W->right_margin_cols)
616 (NILP (W->right_margin_cols) \
617 ? 0 \
618 : XINT (W->right_margin_cols))
619 601
620/* Width of left margin area in pixels. */ 602/* Width of left margin area in pixels. */
621 603
622#define WINDOW_LEFT_MARGIN_WIDTH(W) \ 604#define WINDOW_LEFT_MARGIN_WIDTH(W) \
623 (NILP (W->left_margin_cols) \ 605 (W->left_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W))
624 ? 0 \
625 : (XINT (W->left_margin_cols) \
626 * WINDOW_FRAME_COLUMN_WIDTH (W)))
627 606
628/* Width of right marginal area in pixels. */ 607/* Width of right marginal area in pixels. */
629 608
630#define WINDOW_RIGHT_MARGIN_WIDTH(W) \ 609#define WINDOW_RIGHT_MARGIN_WIDTH(W) \
631 (NILP (W->right_margin_cols) \ 610 (W->right_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W))
632 ? 0 \
633 : (XINT (W->right_margin_cols) \
634 * WINDOW_FRAME_COLUMN_WIDTH (W)))
635 611
636/* Total width of fringes reserved for drawing truncation bitmaps, 612/* Total width of fringes reserved for drawing truncation bitmaps,
637 continuation bitmaps and alike. The width is in canonical char 613 continuation bitmaps and alike. The width is in canonical char
@@ -640,10 +616,10 @@ wset_next_buffers (struct window *w, Lisp_Object val)
640 able to split windows horizontally nicely. */ 616 able to split windows horizontally nicely. */
641 617
642#define WINDOW_FRINGE_COLS(W) \ 618#define WINDOW_FRINGE_COLS(W) \
643 ((INTEGERP (W->left_fringe_width) \ 619 ((W->left_fringe_width >= 0 \
644 || INTEGERP (W->right_fringe_width)) \ 620 && W->right_fringe_width >= 0) \
645 ? ((WINDOW_LEFT_FRINGE_WIDTH (W) \ 621 ? ((W->left_fringe_width \
646 + WINDOW_RIGHT_FRINGE_WIDTH (W) \ 622 + W->right_fringe_width \
647 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \ 623 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
648 / WINDOW_FRAME_COLUMN_WIDTH (W)) \ 624 / WINDOW_FRAME_COLUMN_WIDTH (W)) \
649 : FRAME_FRINGE_COLS (WINDOW_XFRAME (W))) 625 : FRAME_FRINGE_COLS (WINDOW_XFRAME (W)))
@@ -663,13 +639,11 @@ wset_next_buffers (struct window *w, Lisp_Object val)
663/* Pixel-width of the left and right fringe. */ 639/* Pixel-width of the left and right fringe. */
664 640
665#define WINDOW_LEFT_FRINGE_WIDTH(W) \ 641#define WINDOW_LEFT_FRINGE_WIDTH(W) \
666 (INTEGERP (W->left_fringe_width) \ 642 (W->left_fringe_width >= 0 ? W->left_fringe_width \
667 ? XFASTINT (W->left_fringe_width) \
668 : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W))) 643 : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
669 644
670#define WINDOW_RIGHT_FRINGE_WIDTH(W) \ 645#define WINDOW_RIGHT_FRINGE_WIDTH(W) \
671 (INTEGERP (W->right_fringe_width) \ 646 (W->right_fringe_width >= 0 ? W->right_fringe_width \
672 ? XFASTINT (W->right_fringe_width) \
673 : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W))) 647 : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
674 648
675/* Total width of fringes in pixels. */ 649/* Total width of fringes in pixels. */
@@ -714,8 +688,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
714 nonzero. */ 688 nonzero. */
715 689
716#define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \ 690#define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \
717 (INTEGERP (w->scroll_bar_width) \ 691 (w->scroll_bar_width >= 0 ? w->scroll_bar_width \
718 ? XFASTINT (w->scroll_bar_width) \
719 : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w))) 692 : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w)))
720 693
721/* Width that a scroll bar in window W should have, if there is one. 694/* Width that a scroll bar in window W should have, if there is one.
@@ -723,8 +696,8 @@ wset_next_buffers (struct window *w, Lisp_Object val)
723 this is still nonzero. */ 696 this is still nonzero. */
724 697
725#define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \ 698#define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \
726 (INTEGERP (w->scroll_bar_width) \ 699 (w->scroll_bar_width >= 0 \
727 ? ((XFASTINT (w->scroll_bar_width) \ 700 ? ((w->scroll_bar_width \
728 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) \ 701 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) \
729 / WINDOW_FRAME_COLUMN_WIDTH (w)) \ 702 / WINDOW_FRAME_COLUMN_WIDTH (w)) \
730 : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w))) 703 : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w)))
@@ -847,13 +820,25 @@ wset_next_buffers (struct window *w, Lisp_Object val)
847#define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ 820#define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \
848 (window_box_left ((W), TEXT_AREA) + (X)) 821 (window_box_left ((W), TEXT_AREA) + (X))
849 822
850/* This is the window in which the terminal's cursor should 823/* Nonzero if the background of the window W's fringe that is adjacent to
851 be left when nothing is being done with it. This must 824 a scroll bar is extended to the gap between the fringe and the bar. */
852 always be a leaf window, and its buffer is selected by 825
853 the top level editing loop at the end of each command. 826#define WINDOW_FRINGE_EXTENDED_P(w) \
827 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
828 ? (WINDOW_LEFTMOST_P (w) \
829 && WINDOW_LEFT_FRINGE_WIDTH (w) \
830 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \
831 || WINDOW_LEFT_MARGIN_COLS (w) == 0)) \
832 : (WINDOW_RIGHTMOST_P (w) \
833 && WINDOW_RIGHT_FRINGE_WIDTH (w) \
834 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \
835 || WINDOW_RIGHT_MARGIN_COLS (w) == 0)))
854 836
855 This value is always the same as 837/* This is the window in which the terminal's cursor should be left when
856 FRAME_SELECTED_WINDOW (selected_frame). */ 838 nothing is being done with it. This must always be a leaf window, and its
839 buffer is selected by the top level editing loop at the end of each command.
840
841 This value is always the same as FRAME_SELECTED_WINDOW (selected_frame). */
857 842
858extern Lisp_Object selected_window; 843extern Lisp_Object selected_window;
859 844
@@ -874,21 +859,12 @@ extern Lisp_Object minibuf_window;
874 859
875extern Lisp_Object minibuf_selected_window; 860extern Lisp_Object minibuf_selected_window;
876 861
877/* Window that the mouse is over (nil if no mouse support). */
878
879extern Lisp_Object Vmouse_window;
880
881/* Last mouse-click event (nil if no mouse support). */
882
883extern Lisp_Object Vmouse_event;
884
885extern Lisp_Object make_window (void); 862extern Lisp_Object make_window (void);
886extern Lisp_Object window_from_coordinates (struct frame *, int, int, 863extern Lisp_Object window_from_coordinates (struct frame *, int, int,
887 enum window_part *, bool); 864 enum window_part *, bool);
888extern void resize_frame_windows (struct frame *, int, bool); 865extern void resize_frame_windows (struct frame *, int, bool);
889extern void restore_window_configuration (Lisp_Object); 866extern void restore_window_configuration (Lisp_Object);
890extern void delete_all_child_windows (Lisp_Object); 867extern void delete_all_child_windows (Lisp_Object);
891extern void freeze_window_starts (struct frame *, bool);
892extern void grow_mini_window (struct window *, int); 868extern void grow_mini_window (struct window *, int);
893extern void shrink_mini_window (struct window *); 869extern void shrink_mini_window (struct window *);
894extern int window_relative_x_coord (struct window *, enum window_part, int); 870extern int window_relative_x_coord (struct window *, enum window_part, int);
@@ -925,10 +901,6 @@ extern int update_mode_lines;
925 901
926extern int windows_or_buffers_changed; 902extern int windows_or_buffers_changed;
927 903
928/* Nonzero means a frame's cursor type has been changed. */
929
930extern int cursor_type_changed;
931
932/* If *ROWS or *COLS are too small a size for FRAME, set them to the 904/* If *ROWS or *COLS are too small a size for FRAME, set them to the
933 minimum allowable size. */ 905 minimum allowable size. */
934 906
@@ -973,11 +945,28 @@ extern void replace_buffer_in_windows (Lisp_Object);
973extern void replace_buffer_in_windows_safely (Lisp_Object); 945extern void replace_buffer_in_windows_safely (Lisp_Object);
974/* This looks like a setter, but it is a bit special. */ 946/* This looks like a setter, but it is a bit special. */
975extern void wset_buffer (struct window *, Lisp_Object); 947extern void wset_buffer (struct window *, Lisp_Object);
948extern bool window_outdated (struct window *);
976extern void init_window_once (void); 949extern void init_window_once (void);
977extern void init_window (void); 950extern void init_window (void);
978extern void syms_of_window (void); 951extern void syms_of_window (void);
979extern void keys_of_window (void); 952extern void keys_of_window (void);
980 953
954/* Move cursor to row/column position VPOS/HPOS, pixel coordinates
955 Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y
956 are window-relative pixel positions. This is always done during
957 window update, so the position is the future output cursor position
958 for currently updated window W. */
959
960WINDOW_INLINE void
961output_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
962{
963 eassert (w);
964 w->output_cursor.hpos = hpos;
965 w->output_cursor.vpos = vpos;
966 w->output_cursor.x = x;
967 w->output_cursor.y = y;
968}
969
981INLINE_HEADER_END 970INLINE_HEADER_END
982 971
983#endif /* not WINDOW_H_INCLUDED */ 972#endif /* not WINDOW_H_INCLUDED */
diff --git a/src/xdisp.c b/src/xdisp.c
index 7a1f03ce244..d78e78a58d3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -524,7 +524,7 @@ int windows_or_buffers_changed;
524 524
525/* Nonzero means a frame's cursor type has been changed. */ 525/* Nonzero means a frame's cursor type has been changed. */
526 526
527int cursor_type_changed; 527static int cursor_type_changed;
528 528
529/* Nonzero after display_mode_line if %l was used and it displayed a 529/* Nonzero after display_mode_line if %l was used and it displayed a
530 line number. */ 530 line number. */
@@ -804,7 +804,6 @@ static void pint2str (char *, int, ptrdiff_t);
804static void pint2hrstr (char *, int, ptrdiff_t); 804static void pint2hrstr (char *, int, ptrdiff_t);
805static struct text_pos run_window_scroll_functions (Lisp_Object, 805static struct text_pos run_window_scroll_functions (Lisp_Object,
806 struct text_pos); 806 struct text_pos);
807static void reconsider_clip_changes (struct window *, struct buffer *);
808static int text_outside_line_unchanged_p (struct window *, 807static int text_outside_line_unchanged_p (struct window *,
809 ptrdiff_t, ptrdiff_t); 808 ptrdiff_t, ptrdiff_t);
810static void store_mode_line_noprop_char (char); 809static void store_mode_line_noprop_char (char);
@@ -967,12 +966,12 @@ window_text_bottom_y (struct window *w)
967 return height; 966 return height;
968} 967}
969 968
970/* Return the pixel width of display area AREA of window W. AREA < 0 969/* Return the pixel width of display area AREA of window W.
971 means return the total width of W, not including fringes to 970 ANY_AREA means return the total width of W, not including
972 the left and right of the window. */ 971 fringes to the left and right of the window. */
973 972
974int 973int
975window_box_width (struct window *w, int area) 974window_box_width (struct window *w, enum glyph_row_area area)
976{ 975{
977 int cols = w->total_cols; 976 int cols = w->total_cols;
978 int pixels = 0; 977 int pixels = 0;
@@ -983,22 +982,18 @@ window_box_width (struct window *w, int area)
983 982
984 if (area == TEXT_AREA) 983 if (area == TEXT_AREA)
985 { 984 {
986 if (INTEGERP (w->left_margin_cols)) 985 cols -= max (0, w->left_margin_cols);
987 cols -= XFASTINT (w->left_margin_cols); 986 cols -= max (0, w->right_margin_cols);
988 if (INTEGERP (w->right_margin_cols))
989 cols -= XFASTINT (w->right_margin_cols);
990 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w); 987 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
991 } 988 }
992 else if (area == LEFT_MARGIN_AREA) 989 else if (area == LEFT_MARGIN_AREA)
993 { 990 {
994 cols = (INTEGERP (w->left_margin_cols) 991 cols = max (0, w->left_margin_cols);
995 ? XFASTINT (w->left_margin_cols) : 0);
996 pixels = 0; 992 pixels = 0;
997 } 993 }
998 else if (area == RIGHT_MARGIN_AREA) 994 else if (area == RIGHT_MARGIN_AREA)
999 { 995 {
1000 cols = (INTEGERP (w->right_margin_cols) 996 cols = max (0, w->right_margin_cols);
1001 ? XFASTINT (w->right_margin_cols) : 0);
1002 pixels = 0; 997 pixels = 0;
1003 } 998 }
1004 } 999 }
@@ -1054,11 +1049,11 @@ window_box_height (struct window *w)
1054} 1049}
1055 1050
1056/* Return the window-relative coordinate of the left edge of display 1051/* Return the window-relative coordinate of the left edge of display
1057 area AREA of window W. AREA < 0 means return the left edge of the 1052 area AREA of window W. ANY_AREA means return the left edge of the
1058 whole window, to the right of the left fringe of W. */ 1053 whole window, to the right of the left fringe of W. */
1059 1054
1060int 1055int
1061window_box_left_offset (struct window *w, int area) 1056window_box_left_offset (struct window *w, enum glyph_row_area area)
1062{ 1057{
1063 int x; 1058 int x;
1064 1059
@@ -1086,21 +1081,21 @@ window_box_left_offset (struct window *w, int area)
1086 1081
1087 1082
1088/* Return the window-relative coordinate of the right edge of display 1083/* Return the window-relative coordinate of the right edge of display
1089 area AREA of window W. AREA < 0 means return the right edge of the 1084 area AREA of window W. ANY_AREA means return the right edge of the
1090 whole window, to the left of the right fringe of W. */ 1085 whole window, to the left of the right fringe of W. */
1091 1086
1092int 1087int
1093window_box_right_offset (struct window *w, int area) 1088window_box_right_offset (struct window *w, enum glyph_row_area area)
1094{ 1089{
1095 return window_box_left_offset (w, area) + window_box_width (w, area); 1090 return window_box_left_offset (w, area) + window_box_width (w, area);
1096} 1091}
1097 1092
1098/* Return the frame-relative coordinate of the left edge of display 1093/* Return the frame-relative coordinate of the left edge of display
1099 area AREA of window W. AREA < 0 means return the left edge of the 1094 area AREA of window W. ANY_AREA means return the left edge of the
1100 whole window, to the right of the left fringe of W. */ 1095 whole window, to the right of the left fringe of W. */
1101 1096
1102int 1097int
1103window_box_left (struct window *w, int area) 1098window_box_left (struct window *w, enum glyph_row_area area)
1104{ 1099{
1105 struct frame *f = XFRAME (w->frame); 1100 struct frame *f = XFRAME (w->frame);
1106 int x; 1101 int x;
@@ -1116,25 +1111,25 @@ window_box_left (struct window *w, int area)
1116 1111
1117 1112
1118/* Return the frame-relative coordinate of the right edge of display 1113/* Return the frame-relative coordinate of the right edge of display
1119 area AREA of window W. AREA < 0 means return the right edge of the 1114 area AREA of window W. ANY_AREA means return the right edge of the
1120 whole window, to the left of the right fringe of W. */ 1115 whole window, to the left of the right fringe of W. */
1121 1116
1122int 1117int
1123window_box_right (struct window *w, int area) 1118window_box_right (struct window *w, enum glyph_row_area area)
1124{ 1119{
1125 return window_box_left (w, area) + window_box_width (w, area); 1120 return window_box_left (w, area) + window_box_width (w, area);
1126} 1121}
1127 1122
1128/* Get the bounding box of the display area AREA of window W, without 1123/* Get the bounding box of the display area AREA of window W, without
1129 mode lines, in frame-relative coordinates. AREA < 0 means the 1124 mode lines, in frame-relative coordinates. ANY_AREA means the
1130 whole window, not including the left and right fringes of 1125 whole window, not including the left and right fringes of
1131 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel 1126 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1132 coordinates of the upper-left corner of the box. Return in 1127 coordinates of the upper-left corner of the box. Return in
1133 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */ 1128 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1134 1129
1135void 1130void
1136window_box (struct window *w, int area, int *box_x, int *box_y, 1131window_box (struct window *w, enum glyph_row_area area, int *box_x,
1137 int *box_width, int *box_height) 1132 int *box_y, int *box_width, int *box_height)
1138{ 1133{
1139 if (box_width) 1134 if (box_width)
1140 *box_width = window_box_width (w, area); 1135 *box_width = window_box_width (w, area);
@@ -1152,19 +1147,18 @@ window_box (struct window *w, int area, int *box_x, int *box_y,
1152 1147
1153 1148
1154/* Get the bounding box of the display area AREA of window W, without 1149/* Get the bounding box of the display area AREA of window W, without
1155 mode lines. AREA < 0 means the whole window, not including the 1150 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1156 left and right fringe of the window. Return in *TOP_LEFT_X
1157 and TOP_LEFT_Y the frame-relative pixel coordinates of the 1151 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1158 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and 1152 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1159 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the 1153 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1160 box. */ 1154 box. */
1161 1155
1162static void 1156static void
1163window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y, 1157window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1164 int *bottom_right_x, int *bottom_right_y) 1158 int *bottom_right_x, int *bottom_right_y)
1165{ 1159{
1166 window_box (w, area, top_left_x, top_left_y, bottom_right_x, 1160 window_box (w, ANY_AREA, top_left_x, top_left_y,
1167 bottom_right_y); 1161 bottom_right_x, bottom_right_y);
1168 *bottom_right_x += *top_left_x; 1162 *bottom_right_x += *top_left_x;
1169 *bottom_right_y += *top_left_y; 1163 *bottom_right_y += *top_left_y;
1170} 1164}
@@ -2466,7 +2460,16 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2466 2460
2467#endif /* HAVE_WINDOW_SYSTEM */ 2461#endif /* HAVE_WINDOW_SYSTEM */
2468 2462
2469 2463static void
2464adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2465{
2466 eassert (w);
2467 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2468 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2469 w->window_end_vpos
2470 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2471}
2472
2470/*********************************************************************** 2473/***********************************************************************
2471 Lisp form evaluation 2474 Lisp form evaluation
2472 ***********************************************************************/ 2475 ***********************************************************************/
@@ -2602,8 +2605,7 @@ check_window_end (struct window *w)
2602 if (!MINI_WINDOW_P (w) && w->window_end_valid) 2605 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2603 { 2606 {
2604 struct glyph_row *row; 2607 struct glyph_row *row;
2605 eassert ((row = MATRIX_ROW (w->current_matrix, 2608 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2606 XFASTINT (w->window_end_vpos)),
2607 !row->enabled_p 2609 !row->enabled_p
2608 || MATRIX_ROW_DISPLAYS_TEXT_P (row) 2610 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2609 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0)); 2611 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
@@ -3909,10 +3911,14 @@ handle_face_prop (struct it *it)
3909 /* For strings from a `display' property, use the face at 3911 /* For strings from a `display' property, use the face at
3910 IT's current buffer position as the base face to merge 3912 IT's current buffer position as the base face to merge
3911 with, so that overlay strings appear in the same face as 3913 with, so that overlay strings appear in the same face as
3912 surrounding text, unless they specify their own 3914 surrounding text, unless they specify their own faces.
3913 faces. */ 3915 For strings from wrap-prefix and line-prefix properties,
3916 use the default face, possibly remapped via
3917 Vface_remapping_alist. */
3914 base_face_id = it->string_from_prefix_prop_p 3918 base_face_id = it->string_from_prefix_prop_p
3915 ? DEFAULT_FACE_ID 3919 ? (!NILP (Vface_remapping_alist)
3920 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
3921 : DEFAULT_FACE_ID)
3916 : underlying_face_id (it); 3922 : underlying_face_id (it);
3917 } 3923 }
3918 3924
@@ -5509,8 +5515,8 @@ next_overlay_string (struct it *it)
5509static int 5515static int
5510compare_overlay_entries (const void *e1, const void *e2) 5516compare_overlay_entries (const void *e1, const void *e2)
5511{ 5517{
5512 struct overlay_entry *entry1 = (struct overlay_entry *) e1; 5518 struct overlay_entry const *entry1 = e1;
5513 struct overlay_entry *entry2 = (struct overlay_entry *) e2; 5519 struct overlay_entry const *entry2 = e2;
5514 int result; 5520 int result;
5515 5521
5516 if (entry1->after_string_p != entry2->after_string_p) 5522 if (entry1->after_string_p != entry2->after_string_p)
@@ -7043,7 +7049,9 @@ get_next_display_element (struct it *it)
7043 } 7049 }
7044 } 7050 }
7045 } 7051 }
7046 else 7052 /* next_element_from_display_vector sets this flag according to
7053 faces of the display vector glyphs, see there. */
7054 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7047 { 7055 {
7048 int face_id = face_after_it_pos (it); 7056 int face_id = face_after_it_pos (it);
7049 it->end_of_box_run_p 7057 it->end_of_box_run_p
@@ -7458,6 +7466,8 @@ static int
7458next_element_from_display_vector (struct it *it) 7466next_element_from_display_vector (struct it *it)
7459{ 7467{
7460 Lisp_Object gc; 7468 Lisp_Object gc;
7469 int prev_face_id = it->face_id;
7470 int next_face_id;
7461 7471
7462 /* Precondition. */ 7472 /* Precondition. */
7463 eassert (it->dpvec && it->current.dpvec_index >= 0); 7473 eassert (it->dpvec && it->current.dpvec_index >= 0);
@@ -7470,6 +7480,8 @@ next_element_from_display_vector (struct it *it)
7470 7480
7471 if (GLYPH_CODE_P (gc)) 7481 if (GLYPH_CODE_P (gc))
7472 { 7482 {
7483 struct face *this_face, *prev_face, *next_face;
7484
7473 it->c = GLYPH_CODE_CHAR (gc); 7485 it->c = GLYPH_CODE_CHAR (gc);
7474 it->len = CHAR_BYTES (it->c); 7486 it->len = CHAR_BYTES (it->c);
7475 7487
@@ -7485,6 +7497,41 @@ next_element_from_display_vector (struct it *it)
7485 it->face_id = merge_faces (it->f, Qt, lface_id, 7497 it->face_id = merge_faces (it->f, Qt, lface_id,
7486 it->saved_face_id); 7498 it->saved_face_id);
7487 } 7499 }
7500
7501 /* Glyphs in the display vector could have the box face, so we
7502 need to set the related flags in the iterator, as
7503 appropriate. */
7504 this_face = FACE_FROM_ID (it->f, it->face_id);
7505 prev_face = FACE_FROM_ID (it->f, prev_face_id);
7506
7507 /* Is this character the first character of a box-face run? */
7508 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7509 && (!prev_face
7510 || prev_face->box == FACE_NO_BOX));
7511
7512 /* For the last character of the box-face run, we need to look
7513 either at the next glyph from the display vector, or at the
7514 face we saw before the display vector. */
7515 next_face_id = it->saved_face_id;
7516 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7517 {
7518 if (it->dpvec_face_id >= 0)
7519 next_face_id = it->dpvec_face_id;
7520 else
7521 {
7522 int lface_id =
7523 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7524
7525 if (lface_id > 0)
7526 next_face_id = merge_faces (it->f, Qt, lface_id,
7527 it->saved_face_id);
7528 }
7529 }
7530 next_face = FACE_FROM_ID (it->f, next_face_id);
7531 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7532 && (!next_face
7533 || next_face->box == FACE_NO_BOX));
7534 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7488 } 7535 }
7489 else 7536 else
7490 /* Display table entry is invalid. Return a space. */ 7537 /* Display table entry is invalid. Return a space. */
@@ -9059,7 +9106,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
9059 && it->current_x == it->last_visible_x - 1 9106 && it->current_x == it->last_visible_x - 1
9060 && it->c != '\n' 9107 && it->c != '\n'
9061 && it->c != '\t' 9108 && it->c != '\t'
9062 && it->vpos < XFASTINT (it->w->window_end_vpos)) 9109 && it->vpos < it->w->window_end_vpos)
9063 { 9110 {
9064 it->continuation_lines_width += it->current_x; 9111 it->continuation_lines_width += it->current_x;
9065 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0; 9112 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
@@ -9790,7 +9837,7 @@ message3_nolog (Lisp_Object m)
9790void 9837void
9791message1 (const char *m) 9838message1 (const char *m)
9792{ 9839{
9793 message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil); 9840 message3 (m ? build_unibyte_string (m) : Qnil);
9794} 9841}
9795 9842
9796 9843
@@ -9799,7 +9846,7 @@ message1 (const char *m)
9799void 9846void
9800message1_nolog (const char *m) 9847message1_nolog (const char *m)
9801{ 9848{
9802 message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil); 9849 message3_nolog (m ? build_unibyte_string (m) : Qnil);
9803} 9850}
9804 9851
9805/* Display a message M which contains a single %s 9852/* Display a message M which contains a single %s
@@ -9909,7 +9956,7 @@ vmessage (const char *m, va_list ap)
9909 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f); 9956 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
9910 char *message_buf = alloca (maxsize + 1); 9957 char *message_buf = alloca (maxsize + 1);
9911 9958
9912 len = doprnt (message_buf, maxsize, m, (char *)0, ap); 9959 len = doprnt (message_buf, maxsize, m, 0, ap);
9913 9960
9914 message3 (make_string (message_buf, len)); 9961 message3 (make_string (message_buf, len));
9915 } 9962 }
@@ -10461,7 +10508,8 @@ resize_mini_window (struct window *w, int exact_p)
10461 if (height > WINDOW_TOTAL_LINES (w)) 10508 if (height > WINDOW_TOTAL_LINES (w))
10462 { 10509 {
10463 int old_height = WINDOW_TOTAL_LINES (w); 10510 int old_height = WINDOW_TOTAL_LINES (w);
10464 freeze_window_starts (f, 1); 10511
10512 FRAME_WINDOWS_FROZEN (f) = 1;
10465 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 10513 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10466 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 10514 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10467 } 10515 }
@@ -10469,7 +10517,8 @@ resize_mini_window (struct window *w, int exact_p)
10469 && (exact_p || BEGV == ZV)) 10517 && (exact_p || BEGV == ZV))
10470 { 10518 {
10471 int old_height = WINDOW_TOTAL_LINES (w); 10519 int old_height = WINDOW_TOTAL_LINES (w);
10472 freeze_window_starts (f, 0); 10520
10521 FRAME_WINDOWS_FROZEN (f) = 0;
10473 shrink_mini_window (w); 10522 shrink_mini_window (w);
10474 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 10523 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10475 } 10524 }
@@ -10480,19 +10529,21 @@ resize_mini_window (struct window *w, int exact_p)
10480 if (height > WINDOW_TOTAL_LINES (w)) 10529 if (height > WINDOW_TOTAL_LINES (w))
10481 { 10530 {
10482 int old_height = WINDOW_TOTAL_LINES (w); 10531 int old_height = WINDOW_TOTAL_LINES (w);
10483 freeze_window_starts (f, 1); 10532
10533 FRAME_WINDOWS_FROZEN (f) = 1;
10484 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 10534 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10485 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 10535 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10486 } 10536 }
10487 else if (height < WINDOW_TOTAL_LINES (w)) 10537 else if (height < WINDOW_TOTAL_LINES (w))
10488 { 10538 {
10489 int old_height = WINDOW_TOTAL_LINES (w); 10539 int old_height = WINDOW_TOTAL_LINES (w);
10490 freeze_window_starts (f, 0); 10540
10541 FRAME_WINDOWS_FROZEN (f) = 0;
10491 shrink_mini_window (w); 10542 shrink_mini_window (w);
10492 10543
10493 if (height) 10544 if (height)
10494 { 10545 {
10495 freeze_window_starts (f, 1); 10546 FRAME_WINDOWS_FROZEN (f) = 1;
10496 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 10547 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10497 } 10548 }
10498 10549
@@ -10850,17 +10901,6 @@ buffer_shared_and_changed (void)
10850 && UNCHANGED_MODIFIED < MODIFF); 10901 && UNCHANGED_MODIFIED < MODIFF);
10851} 10902}
10852 10903
10853/* Nonzero if W doesn't reflect the actual state of current buffer due
10854 to its text or overlays change. FIXME: this may be called when
10855 XBUFFER (w->contents) != current_buffer, which looks suspicious. */
10856
10857static int
10858window_outdated (struct window *w)
10859{
10860 return (w->last_modified < MODIFF
10861 || w->last_overlay_modified < OVERLAY_MODIFF);
10862}
10863
10864/* Nonzero if W's buffer was changed but not saved or Transient Mark mode 10904/* Nonzero if W's buffer was changed but not saved or Transient Mark mode
10865 is enabled and mark of W's buffer was changed since last W's update. */ 10905 is enabled and mark of W's buffer was changed since last W's update. */
10866 10906
@@ -10886,6 +10926,31 @@ mode_line_update_needed (struct window *w)
10886 && (w->column_number_displayed != current_column ())); 10926 && (w->column_number_displayed != current_column ()));
10887} 10927}
10888 10928
10929/* Nonzero if window start of W is frozen and may not be changed during
10930 redisplay. */
10931
10932static bool
10933window_frozen_p (struct window *w)
10934{
10935 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
10936 {
10937 Lisp_Object window;
10938
10939 XSETWINDOW (window, w);
10940 if (MINI_WINDOW_P (w))
10941 return 0;
10942 else if (EQ (window, selected_window))
10943 return 0;
10944 else if (MINI_WINDOW_P (XWINDOW (selected_window))
10945 && EQ (window, Vminibuf_scroll_window))
10946 /* This special window can't be frozen too. */
10947 return 0;
10948 else
10949 return 1;
10950 }
10951 return 0;
10952}
10953
10889/*********************************************************************** 10954/***********************************************************************
10890 Mode Lines and Frame Titles 10955 Mode Lines and Frame Titles
10891 ***********************************************************************/ 10956 ***********************************************************************/
@@ -11181,7 +11246,18 @@ prepare_menu_bars (void)
11181 { 11246 {
11182 f = XFRAME (frame); 11247 f = XFRAME (frame);
11183 if (!EQ (frame, tooltip_frame) 11248 if (!EQ (frame, tooltip_frame)
11184 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))) 11249 && (FRAME_ICONIFIED_P (f)
11250 || FRAME_VISIBLE_P (f) == 1
11251 /* Exclude TTY frames that are obscured because they
11252 are not the top frame on their console. This is
11253 because x_consider_frame_title actually switches
11254 to the frame, which for TTY frames means it is
11255 marked as garbaged, and will be completely
11256 redrawn on the next redisplay cycle. This causes
11257 TTY frames to be completely redrawn, when there
11258 are more than one of them, even though nothing
11259 should be changed on display. */
11260 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
11185 x_consider_frame_title (frame); 11261 x_consider_frame_title (frame);
11186 } 11262 }
11187 } 11263 }
@@ -11368,79 +11444,6 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11368 return hooks_run; 11444 return hooks_run;
11369} 11445}
11370 11446
11371
11372
11373/***********************************************************************
11374 Output Cursor
11375 ***********************************************************************/
11376
11377#ifdef HAVE_WINDOW_SYSTEM
11378
11379/* EXPORT:
11380 Nominal cursor position -- where to draw output.
11381 HPOS and VPOS are window relative glyph matrix coordinates.
11382 X and Y are window relative pixel coordinates. */
11383
11384struct cursor_pos output_cursor;
11385
11386
11387/* EXPORT:
11388 Set the global variable output_cursor to CURSOR. All cursor
11389 positions are relative to updated_window. */
11390
11391void
11392set_output_cursor (struct cursor_pos *cursor)
11393{
11394 output_cursor.hpos = cursor->hpos;
11395 output_cursor.vpos = cursor->vpos;
11396 output_cursor.x = cursor->x;
11397 output_cursor.y = cursor->y;
11398}
11399
11400
11401/* EXPORT for RIF:
11402 Set a nominal cursor position.
11403
11404 HPOS and VPOS are column/row positions in a window glyph matrix. X
11405 and Y are window text area relative pixel positions.
11406
11407 If this is done during an update, updated_window will contain the
11408 window that is being updated and the position is the future output
11409 cursor position for that window. If updated_window is null, use
11410 selected_window and display the cursor at the given position. */
11411
11412void
11413x_cursor_to (int vpos, int hpos, int y, int x)
11414{
11415 struct window *w;
11416
11417 /* If updated_window is not set, work on selected_window. */
11418 if (updated_window)
11419 w = updated_window;
11420 else
11421 w = XWINDOW (selected_window);
11422
11423 /* Set the output cursor. */
11424 output_cursor.hpos = hpos;
11425 output_cursor.vpos = vpos;
11426 output_cursor.x = x;
11427 output_cursor.y = y;
11428
11429 /* If not called as part of an update, really display the cursor.
11430 This will also set the cursor position of W. */
11431 if (updated_window == NULL)
11432 {
11433 block_input ();
11434 display_and_set_cursor (w, 1, hpos, vpos, x, y);
11435 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11436 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11437 unblock_input ();
11438 }
11439}
11440
11441#endif /* HAVE_WINDOW_SYSTEM */
11442
11443
11444/*********************************************************************** 11447/***********************************************************************
11445 Tool-bars 11448 Tool-bars
11446 ***********************************************************************/ 11449 ***********************************************************************/
@@ -12324,13 +12327,11 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
12324 hlinfo->mouse_face_beg_col = hpos; 12327 hlinfo->mouse_face_beg_col = hpos;
12325 hlinfo->mouse_face_beg_row = vpos; 12328 hlinfo->mouse_face_beg_row = vpos;
12326 hlinfo->mouse_face_beg_x = x; 12329 hlinfo->mouse_face_beg_x = x;
12327 hlinfo->mouse_face_beg_y = row->y;
12328 hlinfo->mouse_face_past_end = 0; 12330 hlinfo->mouse_face_past_end = 0;
12329 12331
12330 hlinfo->mouse_face_end_col = hpos + 1; 12332 hlinfo->mouse_face_end_col = hpos + 1;
12331 hlinfo->mouse_face_end_row = vpos; 12333 hlinfo->mouse_face_end_row = vpos;
12332 hlinfo->mouse_face_end_x = x + glyph->pixel_width; 12334 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12333 hlinfo->mouse_face_end_y = row->y;
12334 hlinfo->mouse_face_window = window; 12335 hlinfo->mouse_face_window = window;
12335 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; 12336 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12336 12337
@@ -12866,13 +12867,13 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12866 && start < pt && end > pt); 12867 && start < pt && end > pt);
12867} 12868}
12868 12869
12869 12870/* Reconsider the clip changes of buffer which is displayed in W. */
12870/* Reconsider the setting of B->clip_changed which is displayed
12871 in window W. */
12872 12871
12873static void 12872static void
12874reconsider_clip_changes (struct window *w, struct buffer *b) 12873reconsider_clip_changes (struct window *w)
12875{ 12874{
12875 struct buffer *b = XBUFFER (w->contents);
12876
12876 if (b->clip_changed 12877 if (b->clip_changed
12877 && w->window_end_valid 12878 && w->window_end_valid
12878 && w->current_matrix->buffer == b 12879 && w->current_matrix->buffer == b
@@ -12885,24 +12886,17 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
12885 we set b->clip_changed to 1 to force updating the screen. If 12886 we set b->clip_changed to 1 to force updating the screen. If
12886 b->clip_changed has already been set to 1, we can skip this 12887 b->clip_changed has already been set to 1, we can skip this
12887 check. */ 12888 check. */
12888 if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid) 12889 if (!b->clip_changed && w->window_end_valid)
12889 { 12890 {
12890 ptrdiff_t pt; 12891 ptrdiff_t pt = (w == XWINDOW (selected_window)
12891 12892 ? PT : marker_position (w->pointm));
12892 if (w == XWINDOW (selected_window))
12893 pt = PT;
12894 else
12895 pt = marker_position (w->pointm);
12896 12893
12897 if ((w->current_matrix->buffer != XBUFFER (w->contents) 12894 if ((w->current_matrix->buffer != b || pt != w->last_point)
12898 || pt != w->last_point)
12899 && check_point_in_composition (w->current_matrix->buffer, 12895 && check_point_in_composition (w->current_matrix->buffer,
12900 w->last_point, 12896 w->last_point, b, pt))
12901 XBUFFER (w->contents), pt))
12902 b->clip_changed = 1; 12897 b->clip_changed = 1;
12903 } 12898 }
12904} 12899}
12905
12906 12900
12907#define STOP_POLLING \ 12901#define STOP_POLLING \
12908do { if (! polling_stopped_here) stop_polling (); \ 12902do { if (! polling_stopped_here) stop_polling (); \
@@ -12923,10 +12917,10 @@ redisplay_internal (void)
12923 struct window *sw; 12917 struct window *sw;
12924 struct frame *fr; 12918 struct frame *fr;
12925 int pending; 12919 int pending;
12926 int must_finish = 0; 12920 bool must_finish = 0, match_p;
12927 struct text_pos tlbufpos, tlendpos; 12921 struct text_pos tlbufpos, tlendpos;
12928 int number_of_visible_frames; 12922 int number_of_visible_frames;
12929 ptrdiff_t count, count1; 12923 ptrdiff_t count;
12930 struct frame *sf; 12924 struct frame *sf;
12931 int polling_stopped_here = 0; 12925 int polling_stopped_here = 0;
12932 Lisp_Object tail, frame; 12926 Lisp_Object tail, frame;
@@ -12983,7 +12977,6 @@ redisplay_internal (void)
12983 sw = w; 12977 sw = w;
12984 12978
12985 pending = 0; 12979 pending = 0;
12986 reconsider_clip_changes (w, current_buffer);
12987 last_escape_glyph_frame = NULL; 12980 last_escape_glyph_frame = NULL;
12988 last_escape_glyph_face_id = (1 << FACE_ID_BITS); 12981 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12989 last_glyphless_glyph_frame = NULL; 12982 last_glyphless_glyph_frame = NULL;
@@ -13038,10 +13031,7 @@ redisplay_internal (void)
13038 /* do_pending_window_change could change the selected_window due to 13031 /* do_pending_window_change could change the selected_window due to
13039 frame resizing which makes the selected window too small. */ 13032 frame resizing which makes the selected window too small. */
13040 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw) 13033 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13041 { 13034 sw = w;
13042 sw = w;
13043 reconsider_clip_changes (w, current_buffer);
13044 }
13045 13035
13046 /* Clear frames marked as garbaged. */ 13036 /* Clear frames marked as garbaged. */
13047 clear_garbaged_frames (); 13037 clear_garbaged_frames ();
@@ -13053,22 +13043,31 @@ redisplay_internal (void)
13053 if (windows_or_buffers_changed) 13043 if (windows_or_buffers_changed)
13054 update_mode_lines++; 13044 update_mode_lines++;
13055 13045
13056 /* Detect case that we need to write or remove a star in the mode line. */ 13046 reconsider_clip_changes (w);
13057 if ((SAVE_MODIFF < MODIFF) != w->last_had_star) 13047
13048 /* In most cases selected window displays current buffer. */
13049 match_p = XBUFFER (w->contents) == current_buffer;
13050 if (match_p)
13058 { 13051 {
13059 w->update_mode_line = 1; 13052 ptrdiff_t count1;
13060 if (buffer_shared_and_changed ())
13061 update_mode_lines++;
13062 }
13063 13053
13064 /* Avoid invocation of point motion hooks by `current_column' below. */ 13054 /* Detect case that we need to write or remove a star in the mode line. */
13065 count1 = SPECPDL_INDEX (); 13055 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13066 specbind (Qinhibit_point_motion_hooks, Qt); 13056 {
13057 w->update_mode_line = 1;
13058 if (buffer_shared_and_changed ())
13059 update_mode_lines++;
13060 }
13067 13061
13068 if (mode_line_update_needed (w)) 13062 /* Avoid invocation of point motion hooks by `current_column' below. */
13069 w->update_mode_line = 1; 13063 count1 = SPECPDL_INDEX ();
13064 specbind (Qinhibit_point_motion_hooks, Qt);
13070 13065
13071 unbind_to (count1, Qnil); 13066 if (mode_line_update_needed (w))
13067 w->update_mode_line = 1;
13068
13069 unbind_to (count1, Qnil);
13070 }
13072 13071
13073 consider_all_windows_p = (update_mode_lines 13072 consider_all_windows_p = (update_mode_lines
13074 || buffer_shared_and_changed () 13073 || buffer_shared_and_changed ()
@@ -13167,7 +13166,7 @@ redisplay_internal (void)
13167 && !FRAME_OBSCURED_P (XFRAME (w->frame)) 13166 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13168 /* Make sure recorded data applies to current buffer, etc. */ 13167 /* Make sure recorded data applies to current buffer, etc. */
13169 && this_line_buffer == current_buffer 13168 && this_line_buffer == current_buffer
13170 && current_buffer == XBUFFER (w->contents) 13169 && match_p
13171 && !w->force_start 13170 && !w->force_start
13172 && !w->optional_new_start 13171 && !w->optional_new_start
13173 /* Point must be on the line that we have info recorded about. */ 13172 /* Point must be on the line that we have info recorded about. */
@@ -13263,12 +13262,12 @@ redisplay_internal (void)
13263 adjusted. */ 13262 adjusted. */
13264 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1)) 13263 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
13265 { 13264 {
13266 if (XFASTINT (w->window_end_vpos) < this_line_vpos) 13265 if (w->window_end_vpos < this_line_vpos)
13267 wset_window_end_vpos (w, make_number (this_line_vpos)); 13266 w->window_end_vpos = this_line_vpos;
13268 } 13267 }
13269 else if (XFASTINT (w->window_end_vpos) == this_line_vpos 13268 else if (w->window_end_vpos == this_line_vpos
13270 && this_line_vpos > 0) 13269 && this_line_vpos > 0)
13271 wset_window_end_vpos (w, make_number (this_line_vpos - 1)); 13270 w->window_end_vpos = this_line_vpos - 1;
13272 w->window_end_valid = 0; 13271 w->window_end_valid = 0;
13273 13272
13274 /* Update hint: No need to try to scroll in update_window. */ 13273 /* Update hint: No need to try to scroll in update_window. */
@@ -13685,7 +13684,7 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
13685 w->current_matrix->begv = BUF_BEGV (b); 13684 w->current_matrix->begv = BUF_BEGV (b);
13686 w->current_matrix->zv = BUF_ZV (b); 13685 w->current_matrix->zv = BUF_ZV (b);
13687 13686
13688 w->last_cursor = w->cursor; 13687 w->last_cursor_vpos = w->cursor.vpos;
13689 w->last_cursor_off_p = w->cursor_off_p; 13688 w->last_cursor_off_p = w->cursor_off_p;
13690 13689
13691 if (w == XWINDOW (selected_window)) 13690 if (w == XWINDOW (selected_window))
@@ -14458,8 +14457,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14458 struct window *w = XWINDOW (window); 14457 struct window *w = XWINDOW (window);
14459 SET_MARKER_FROM_TEXT_POS (w->start, startp); 14458 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14460 14459
14461 if (current_buffer != XBUFFER (w->contents)) 14460 eassert (current_buffer == XBUFFER (w->contents));
14462 emacs_abort ();
14463 14461
14464 if (!NILP (Vwindow_scroll_functions)) 14462 if (!NILP (Vwindow_scroll_functions))
14465 { 14463 {
@@ -14900,7 +14898,25 @@ compute_window_start_on_continuation_line (struct window *w)
14900 { 14898 {
14901 min_distance = distance; 14899 min_distance = distance;
14902 pos = it.current.pos; 14900 pos = it.current.pos;
14903 move_it_by_lines (&it, 1); 14901 if (it.line_wrap == WORD_WRAP)
14902 {
14903 /* Under WORD_WRAP, move_it_by_lines is likely to
14904 overshoot and stop not at the first, but the
14905 second character from the left margin. So in
14906 that case, we need a more tight control on the X
14907 coordinate of the iterator than move_it_by_lines
14908 promises in its contract. The method is to first
14909 go to the last (rightmost) visible character of a
14910 line, then move to the leftmost character on the
14911 next line in a separate call. */
14912 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
14913 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14914 move_it_to (&it, ZV, 0,
14915 it.current_y + it.max_ascent + it.max_descent, -1,
14916 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14917 }
14918 else
14919 move_it_by_lines (&it, 1);
14904 } 14920 }
14905 14921
14906 /* Set the window start there. */ 14922 /* Set the window start there. */
@@ -14952,6 +14968,10 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
14952 if-statement below. Now, this field is converted to 14968 if-statement below. Now, this field is converted to
14953 ptrdiff_t, thus zero means invalid position in a buffer. */ 14969 ptrdiff_t, thus zero means invalid position in a buffer. */
14954 eassert (w->last_point > 0); 14970 eassert (w->last_point > 0);
14971 /* Likewise there was a check whether window_end_vpos is nil or larger
14972 than the window. Now window_end_vpos is int and so never nil, but
14973 let's leave eassert to check whether it fits in the window. */
14974 eassert (w->window_end_vpos < w->current_matrix->nrows);
14955 14975
14956 /* Handle case where text has not changed, only point, and it has 14976 /* Handle case where text has not changed, only point, and it has
14957 not moved off the frame. */ 14977 not moved off the frame. */
@@ -14979,13 +14999,6 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
14979 since the handling of this_line_start_pos, etc., in redisplay 14999 since the handling of this_line_start_pos, etc., in redisplay
14980 handles the same cases. */ 15000 handles the same cases. */
14981 && !EQ (window, minibuf_window) 15001 && !EQ (window, minibuf_window)
14982 /* When splitting windows or for new windows, it happens that
14983 redisplay is called with a nil window_end_vpos or one being
14984 larger than the window. This should really be fixed in
14985 window.c. I don't have this on my list, now, so we do
14986 approximately the same as the old redisplay code. --gerd. */
14987 && INTEGERP (w->window_end_vpos)
14988 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14989 && (FRAME_WINDOW_P (f) 15002 && (FRAME_WINDOW_P (f)
14990 || !overlay_arrow_in_current_buffer_p ())) 15003 || !overlay_arrow_in_current_buffer_p ()))
14991 { 15004 {
@@ -15015,12 +15028,12 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
15015 15028
15016 /* Start with the row the cursor was displayed during the last 15029 /* Start with the row the cursor was displayed during the last
15017 not paused redisplay. Give up if that row is not valid. */ 15030 not paused redisplay. Give up if that row is not valid. */
15018 if (w->last_cursor.vpos < 0 15031 if (w->last_cursor_vpos < 0
15019 || w->last_cursor.vpos >= w->current_matrix->nrows) 15032 || w->last_cursor_vpos >= w->current_matrix->nrows)
15020 rc = CURSOR_MOVEMENT_MUST_SCROLL; 15033 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15021 else 15034 else
15022 { 15035 {
15023 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos); 15036 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
15024 if (row->mode_line_p) 15037 if (row->mode_line_p)
15025 ++row; 15038 ++row;
15026 if (!row->enabled_p) 15039 if (!row->enabled_p)
@@ -15299,7 +15312,7 @@ set_vertical_scroll_bar (struct window *w)
15299 start = marker_position (w->start) - BUF_BEGV (buf); 15312 start = marker_position (w->start) - BUF_BEGV (buf);
15300 /* I don't think this is guaranteed to be right. For the 15313 /* I don't think this is guaranteed to be right. For the
15301 moment, we'll pretend it is. */ 15314 moment, we'll pretend it is. */
15302 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf); 15315 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
15303 15316
15304 if (end < start) 15317 if (end < start)
15305 end = start; 15318 end = start;
@@ -15360,7 +15373,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15360 eassert (XMARKER (w->pointm)->buffer == buffer); 15373 eassert (XMARKER (w->pointm)->buffer == buffer);
15361 15374
15362 restart: 15375 restart:
15363 reconsider_clip_changes (w, buffer); 15376 reconsider_clip_changes (w);
15364 frame_line_height = default_line_pixel_height (w); 15377 frame_line_height = default_line_pixel_height (w);
15365 15378
15366 /* Has the mode line to be updated? */ 15379 /* Has the mode line to be updated? */
@@ -15440,8 +15453,8 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15440 && !current_buffer->clip_changed 15453 && !current_buffer->clip_changed
15441 && !window_outdated (w)); 15454 && !window_outdated (w));
15442 15455
15443 /* When windows_or_buffers_changed is non-zero, we can't rely on 15456 /* When windows_or_buffers_changed is non-zero, we can't rely
15444 the window end being valid, so set it to nil there. */ 15457 on the window end being valid, so set it to zero there. */
15445 if (windows_or_buffers_changed) 15458 if (windows_or_buffers_changed)
15446 { 15459 {
15447 /* If window starts on a continuation line, maybe adjust the 15460 /* If window starts on a continuation line, maybe adjust the
@@ -15450,6 +15463,9 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15450 compute_window_start_on_continuation_line (w); 15463 compute_window_start_on_continuation_line (w);
15451 15464
15452 w->window_end_valid = 0; 15465 w->window_end_valid = 0;
15466 /* If so, we also can't rely on current matrix
15467 and should not fool try_cursor_movement below. */
15468 current_matrix_up_to_date_p = 0;
15453 } 15469 }
15454 15470
15455 /* Some sanity checks. */ 15471 /* Some sanity checks. */
@@ -15531,7 +15547,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15531 15547
15532 /* Handle case where place to start displaying has been specified, 15548 /* Handle case where place to start displaying has been specified,
15533 unless the specified location is outside the accessible range. */ 15549 unless the specified location is outside the accessible range. */
15534 if (w->force_start || w->frozen_window_start_p) 15550 if (w->force_start || window_frozen_p (w))
15535 { 15551 {
15536 /* We set this later on if we have to adjust point. */ 15552 /* We set this later on if we have to adjust point. */
15537 int new_vpos = -1; 15553 int new_vpos = -1;
@@ -15559,8 +15575,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15559 startp = run_window_scroll_functions (window, startp); 15575 startp = run_window_scroll_functions (window, startp);
15560 } 15576 }
15561 15577
15562 w->last_modified = 0;
15563 w->last_overlay_modified = 0;
15564 if (CHARPOS (startp) < BEGV) 15578 if (CHARPOS (startp) < BEGV)
15565 SET_TEXT_POS (startp, BEGV, BEGV_BYTE); 15579 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15566 else if (CHARPOS (startp) > ZV) 15580 else if (CHARPOS (startp) > ZV)
@@ -15578,7 +15592,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15578 goto need_larger_matrices; 15592 goto need_larger_matrices;
15579 } 15593 }
15580 15594
15581 if (w->cursor.vpos < 0 && !w->frozen_window_start_p) 15595 if (w->cursor.vpos < 0 && !window_frozen_p (w))
15582 { 15596 {
15583 /* If point does not appear, try to move point so it does 15597 /* If point does not appear, try to move point so it does
15584 appear. The desired matrix has been built above, so we 15598 appear. The desired matrix has been built above, so we
@@ -15806,9 +15820,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15806 15820
15807 try_to_scroll: 15821 try_to_scroll:
15808 15822
15809 w->last_modified = 0;
15810 w->last_overlay_modified = 0;
15811
15812 /* Redisplay the mode line. Select the buffer properly for that. */ 15823 /* Redisplay the mode line. Select the buffer properly for that. */
15813 if (!update_mode_line) 15824 if (!update_mode_line)
15814 { 15825 {
@@ -15994,7 +16005,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15994 line.) */ 16005 line.) */
15995 if (w->cursor.vpos < 0) 16006 if (w->cursor.vpos < 0)
15996 { 16007 {
15997 if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos)) 16008 if (w->window_end_valid && PT >= Z - w->window_end_pos)
15998 { 16009 {
15999 clear_glyph_matrix (w->desired_matrix); 16010 clear_glyph_matrix (w->desired_matrix);
16000 move_it_by_lines (&it, 1); 16011 move_it_by_lines (&it, 1);
@@ -16287,8 +16298,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
16287 } 16298 }
16288 16299
16289 /* If bottom moved off end of frame, change mode line percentage. */ 16300 /* If bottom moved off end of frame, change mode line percentage. */
16290 if (XFASTINT (w->window_end_pos) <= 0 16301 if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
16291 && Z != IT_CHARPOS (it))
16292 w->update_mode_line = 1; 16302 w->update_mode_line = 1;
16293 16303
16294 /* Set window_end_pos to the offset of the last character displayed 16304 /* Set window_end_pos to the offset of the last character displayed
@@ -16297,21 +16307,16 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
16297 if (last_text_row) 16307 if (last_text_row)
16298 { 16308 {
16299 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row)); 16309 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16300 w->window_end_bytepos 16310 adjust_window_ends (w, last_text_row, 0);
16301 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16302 wset_window_end_pos
16303 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16304 wset_window_end_vpos
16305 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16306 eassert 16311 eassert
16307 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix, 16312 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
16308 XFASTINT (w->window_end_vpos)))); 16313 w->window_end_vpos)));
16309 } 16314 }
16310 else 16315 else
16311 { 16316 {
16312 w->window_end_bytepos = Z_BYTE - ZV_BYTE; 16317 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16313 wset_window_end_pos (w, make_number (Z - ZV)); 16318 w->window_end_pos = Z - ZV;
16314 wset_window_end_vpos (w, make_number (0)); 16319 w->window_end_vpos = 0;
16315 } 16320 }
16316 16321
16317 /* But that is not valid info until redisplay finishes. */ 16322 /* But that is not valid info until redisplay finishes. */
@@ -16535,32 +16540,15 @@ try_window_reusing_current_matrix (struct window *w)
16535 The value of last_text_row is the last displayed line 16540 The value of last_text_row is the last displayed line
16536 containing text. */ 16541 containing text. */
16537 if (last_reused_text_row) 16542 if (last_reused_text_row)
16538 { 16543 adjust_window_ends (w, last_reused_text_row, 1);
16539 w->window_end_bytepos
16540 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16541 wset_window_end_pos
16542 (w, make_number (Z
16543 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16544 wset_window_end_vpos
16545 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16546 w->current_matrix)));
16547 }
16548 else if (last_text_row) 16544 else if (last_text_row)
16549 { 16545 adjust_window_ends (w, last_text_row, 0);
16550 w->window_end_bytepos
16551 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16552 wset_window_end_pos
16553 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16554 wset_window_end_vpos
16555 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16556 w->desired_matrix)));
16557 }
16558 else 16546 else
16559 { 16547 {
16560 /* This window must be completely empty. */ 16548 /* This window must be completely empty. */
16561 w->window_end_bytepos = Z_BYTE - ZV_BYTE; 16549 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16562 wset_window_end_pos (w, make_number (Z - ZV)); 16550 w->window_end_pos = Z - ZV;
16563 wset_window_end_vpos (w, make_number (0)); 16551 w->window_end_vpos = 0;
16564 } 16552 }
16565 w->window_end_valid = 0; 16553 w->window_end_valid = 0;
16566 16554
@@ -16745,20 +16733,9 @@ try_window_reusing_current_matrix (struct window *w)
16745 the window end is in reused rows which in turn means that 16733 the window end is in reused rows which in turn means that
16746 only its vpos can have changed. */ 16734 only its vpos can have changed. */
16747 if (last_text_row) 16735 if (last_text_row)
16748 { 16736 adjust_window_ends (w, last_text_row, 0);
16749 w->window_end_bytepos
16750 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16751 wset_window_end_pos
16752 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16753 wset_window_end_vpos
16754 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16755 w->desired_matrix)));
16756 }
16757 else 16737 else
16758 { 16738 w->window_end_vpos -= nrows_scrolled;
16759 wset_window_end_vpos
16760 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16761 }
16762 16739
16763 w->window_end_valid = 0; 16740 w->window_end_valid = 0;
16764 w->desired_matrix->no_scrolling_p = 1; 16741 w->desired_matrix->no_scrolling_p = 1;
@@ -16898,11 +16875,11 @@ find_first_unchanged_at_end_row (struct window *w,
16898 /* A value of window_end_pos >= END_UNCHANGED means that the window 16875 /* A value of window_end_pos >= END_UNCHANGED means that the window
16899 end is in the range of changed text. If so, there is no 16876 end is in the range of changed text. If so, there is no
16900 unchanged row at the end of W's current matrix. */ 16877 unchanged row at the end of W's current matrix. */
16901 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED) 16878 if (w->window_end_pos >= END_UNCHANGED)
16902 return NULL; 16879 return NULL;
16903 16880
16904 /* Set row to the last row in W's current matrix displaying text. */ 16881 /* Set row to the last row in W's current matrix displaying text. */
16905 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 16882 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
16906 16883
16907 /* If matrix is entirely empty, no unchanged row exists. */ 16884 /* If matrix is entirely empty, no unchanged row exists. */
16908 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)) 16885 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
@@ -16913,7 +16890,7 @@ find_first_unchanged_at_end_row (struct window *w,
16913 buffer positions in the current matrix to current buffer 16890 buffer positions in the current matrix to current buffer
16914 positions for characters not in changed text. */ 16891 positions for characters not in changed text. */
16915 ptrdiff_t Z_old = 16892 ptrdiff_t Z_old =
16916 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); 16893 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
16917 ptrdiff_t Z_BYTE_old = 16894 ptrdiff_t Z_BYTE_old =
16918 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; 16895 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16919 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old; 16896 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
@@ -17247,7 +17224,7 @@ try_window_id (struct window *w)
17247 This case happens with stealth-fontification. Note that although 17224 This case happens with stealth-fontification. Note that although
17248 the display is unchanged, glyph positions in the matrix have to 17225 the display is unchanged, glyph positions in the matrix have to
17249 be adjusted, of course. */ 17226 be adjusted, of course. */
17250 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 17227 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
17251 if (MATRIX_ROW_DISPLAYS_TEXT_P (row) 17228 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17252 && ((last_changed_charpos < CHARPOS (start) 17229 && ((last_changed_charpos < CHARPOS (start)
17253 && CHARPOS (start) == BEGV) 17230 && CHARPOS (start) == BEGV)
@@ -17259,7 +17236,7 @@ try_window_id (struct window *w)
17259 17236
17260 /* Compute how many chars/bytes have been added to or removed 17237 /* Compute how many chars/bytes have been added to or removed
17261 from the buffer. */ 17238 from the buffer. */
17262 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos); 17239 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
17263 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos; 17240 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17264 Z_delta = Z - Z_old; 17241 Z_delta = Z - Z_old;
17265 Z_delta_bytes = Z_BYTE - Z_BYTE_old; 17242 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
@@ -17330,10 +17307,8 @@ try_window_id (struct window *w)
17330 { 17307 {
17331 /* We have to compute the window end anew since text 17308 /* We have to compute the window end anew since text
17332 could have been added/removed after it. */ 17309 could have been added/removed after it. */
17333 wset_window_end_pos 17310 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17334 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); 17311 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17335 w->window_end_bytepos
17336 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17337 17312
17338 /* Set the cursor. */ 17313 /* Set the cursor. */
17339 row = row_containing_pos (w, PT, r0, NULL, 0); 17314 row = row_containing_pos (w, PT, r0, NULL, 0);
@@ -17366,7 +17341,7 @@ try_window_id (struct window *w)
17366 17341
17367 /* Give up if the window ends in strings. Overlay strings 17342 /* Give up if the window ends in strings. Overlay strings
17368 at the end are difficult to handle, so don't try. */ 17343 at the end are difficult to handle, so don't try. */
17369 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos)); 17344 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
17370 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row)) 17345 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17371 GIVE_UP (20); 17346 GIVE_UP (20);
17372 17347
@@ -17712,7 +17687,7 @@ try_window_id (struct window *w)
17712 /* Set last_row to the glyph row in the current matrix where the 17687 /* Set last_row to the glyph row in the current matrix where the
17713 window end line is found. It has been moved up or down in 17688 window end line is found. It has been moved up or down in
17714 the matrix by dvpos. */ 17689 the matrix by dvpos. */
17715 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos; 17690 int last_vpos = w->window_end_vpos + dvpos;
17716 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos); 17691 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17717 17692
17718 /* If last_row is the window end line, it should display text. */ 17693 /* If last_row is the window end line, it should display text. */
@@ -17756,8 +17731,7 @@ try_window_id (struct window *w)
17756 } 17731 }
17757 17732
17758 /* Update window_end_pos and window_end_vpos. */ 17733 /* Update window_end_pos and window_end_vpos. */
17759 if (first_unchanged_at_end_row 17734 if (first_unchanged_at_end_row && !last_text_row_at_end)
17760 && !last_text_row_at_end)
17761 { 17735 {
17762 /* Window end line if one of the preserved rows from the current 17736 /* Window end line if one of the preserved rows from the current
17763 matrix. Set row to the last row displaying text in current 17737 matrix. Set row to the last row displaying text in current
@@ -17767,23 +17741,13 @@ try_window_id (struct window *w)
17767 row = find_last_row_displaying_text (w->current_matrix, &it, 17741 row = find_last_row_displaying_text (w->current_matrix, &it,
17768 first_unchanged_at_end_row); 17742 first_unchanged_at_end_row);
17769 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); 17743 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17770 17744 adjust_window_ends (w, row, 1);
17771 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17772 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17773 wset_window_end_vpos
17774 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17775 eassert (w->window_end_bytepos >= 0); 17745 eassert (w->window_end_bytepos >= 0);
17776 IF_DEBUG (debug_method_add (w, "A")); 17746 IF_DEBUG (debug_method_add (w, "A"));
17777 } 17747 }
17778 else if (last_text_row_at_end) 17748 else if (last_text_row_at_end)
17779 { 17749 {
17780 wset_window_end_pos 17750 adjust_window_ends (w, last_text_row_at_end, 0);
17781 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17782 w->window_end_bytepos
17783 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17784 wset_window_end_vpos
17785 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17786 desired_matrix)));
17787 eassert (w->window_end_bytepos >= 0); 17751 eassert (w->window_end_bytepos >= 0);
17788 IF_DEBUG (debug_method_add (w, "B")); 17752 IF_DEBUG (debug_method_add (w, "B"));
17789 } 17753 }
@@ -17792,12 +17756,7 @@ try_window_id (struct window *w)
17792 /* We have displayed either to the end of the window or at the 17756 /* We have displayed either to the end of the window or at the
17793 end of the window, i.e. the last row with text is to be found 17757 end of the window, i.e. the last row with text is to be found
17794 in the desired matrix. */ 17758 in the desired matrix. */
17795 wset_window_end_pos 17759 adjust_window_ends (w, last_text_row, 0);
17796 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17797 w->window_end_bytepos
17798 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17799 wset_window_end_vpos
17800 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17801 eassert (w->window_end_bytepos >= 0); 17760 eassert (w->window_end_bytepos >= 0);
17802 } 17761 }
17803 else if (first_unchanged_at_end_row == NULL 17762 else if (first_unchanged_at_end_row == NULL
@@ -17807,7 +17766,7 @@ try_window_id (struct window *w)
17807 /* Displayed to end of window, but no line containing text was 17766 /* Displayed to end of window, but no line containing text was
17808 displayed. Lines were deleted at the end of the window. */ 17767 displayed. Lines were deleted at the end of the window. */
17809 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; 17768 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17810 int vpos = XFASTINT (w->window_end_vpos); 17769 int vpos = w->window_end_vpos;
17811 struct glyph_row *current_row = current_matrix->rows + vpos; 17770 struct glyph_row *current_row = current_matrix->rows + vpos;
17812 struct glyph_row *desired_row = desired_matrix->rows + vpos; 17771 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17813 17772
@@ -17825,8 +17784,8 @@ try_window_id (struct window *w)
17825 } 17784 }
17826 17785
17827 eassert (row != NULL); 17786 eassert (row != NULL);
17828 wset_window_end_vpos (w, make_number (vpos + 1)); 17787 w->window_end_vpos = vpos + 1;
17829 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row))); 17788 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
17830 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); 17789 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17831 eassert (w->window_end_bytepos >= 0); 17790 eassert (w->window_end_bytepos >= 0);
17832 IF_DEBUG (debug_method_add (w, "C")); 17791 IF_DEBUG (debug_method_add (w, "C"));
@@ -17834,8 +17793,8 @@ try_window_id (struct window *w)
17834 else 17793 else
17835 emacs_abort (); 17794 emacs_abort ();
17836 17795
17837 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos); 17796 IF_DEBUG (debug_end_pos = w->window_end_pos;
17838 debug_end_vpos = XFASTINT (w->window_end_vpos)); 17797 debug_end_vpos = w->window_end_vpos);
17839 17798
17840 /* Record that display has not been completed. */ 17799 /* Record that display has not been completed. */
17841 w->window_end_valid = 0; 17800 w->window_end_valid = 0;
@@ -20115,7 +20074,7 @@ Value is the new character position of point. */)
20115 (Lisp_Object direction) 20074 (Lisp_Object direction)
20116{ 20075{
20117 struct window *w = XWINDOW (selected_window); 20076 struct window *w = XWINDOW (selected_window);
20118 struct buffer *b = NULL; 20077 struct buffer *b = XBUFFER (w->contents);
20119 struct glyph_row *row; 20078 struct glyph_row *row;
20120 int dir; 20079 int dir;
20121 Lisp_Object paragraph_dir; 20080 Lisp_Object paragraph_dir;
@@ -20135,9 +20094,6 @@ Value is the new character position of point. */)
20135 else 20094 else
20136 dir = -1; 20095 dir = -1;
20137 20096
20138 if (BUFFERP (w->contents))
20139 b = XBUFFER (w->contents);
20140
20141 /* If current matrix is up-to-date, we can use the information 20097 /* If current matrix is up-to-date, we can use the information
20142 recorded in the glyphs, at least as long as the goal is on the 20098 recorded in the glyphs, at least as long as the goal is on the
20143 screen. */ 20099 screen. */
@@ -20146,8 +20102,7 @@ Value is the new character position of point. */)
20146 && b 20102 && b
20147 && !b->clip_changed 20103 && !b->clip_changed
20148 && !b->prevent_redisplay_optimizations_p 20104 && !b->prevent_redisplay_optimizations_p
20149 && w->last_modified >= BUF_MODIFF (b) 20105 && !window_outdated (w)
20150 && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b)
20151 && w->cursor.vpos >= 0 20106 && w->cursor.vpos >= 0
20152 && w->cursor.vpos < w->current_matrix->nrows 20107 && w->cursor.vpos < w->current_matrix->nrows
20153 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p) 20108 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
@@ -20651,13 +20606,8 @@ redisplay_mode_lines (Lisp_Object window, int force)
20651 { 20606 {
20652 struct text_pos pt; 20607 struct text_pos pt;
20653 20608
20654 SET_TEXT_POS_FROM_MARKER (pt, w->pointm); 20609 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
20655 if (CHARPOS (pt) < BEGV) 20610 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20656 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20657 else if (CHARPOS (pt) > (ZV - 1))
20658 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20659 else
20660 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20661 } 20611 }
20662 20612
20663 /* Display mode lines. */ 20613 /* Display mode lines. */
@@ -22007,7 +21957,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
22007 ptrdiff_t pos = marker_position (w->start); 21957 ptrdiff_t pos = marker_position (w->start);
22008 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); 21958 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22009 21959
22010 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b)) 21960 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
22011 { 21961 {
22012 if (pos <= BUF_BEGV (b)) 21962 if (pos <= BUF_BEGV (b))
22013 return "All"; 21963 return "All";
@@ -22036,7 +21986,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
22036 case 'P': 21986 case 'P':
22037 { 21987 {
22038 ptrdiff_t toppos = marker_position (w->start); 21988 ptrdiff_t toppos = marker_position (w->start);
22039 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos); 21989 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
22040 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); 21990 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
22041 21991
22042 if (botpos >= BUF_ZV (b)) 21992 if (botpos >= BUF_ZV (b))
@@ -23856,17 +23806,15 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
23856 && hlinfo->mouse_face_beg_row >= 0 23806 && hlinfo->mouse_face_beg_row >= 0
23857 && hlinfo->mouse_face_end_row >= 0) 23807 && hlinfo->mouse_face_end_row >= 0)
23858 { 23808 {
23859 struct glyph_row *mouse_beg_row, *mouse_end_row; 23809 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
23860
23861 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23862 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23863 23810
23864 if (row >= mouse_beg_row && row <= mouse_end_row) 23811 if (row_vpos >= hlinfo->mouse_face_beg_row
23812 && row_vpos <= hlinfo->mouse_face_end_row)
23865 { 23813 {
23866 check_mouse_face = 1; 23814 check_mouse_face = 1;
23867 mouse_beg_col = (row == mouse_beg_row) 23815 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
23868 ? hlinfo->mouse_face_beg_col : 0; 23816 ? hlinfo->mouse_face_beg_col : 0;
23869 mouse_end_col = (row == mouse_end_row) 23817 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
23870 ? hlinfo->mouse_face_end_col 23818 ? hlinfo->mouse_face_end_col
23871 : row->used[TEXT_AREA]; 23819 : row->used[TEXT_AREA];
23872 } 23820 }
@@ -25757,17 +25705,16 @@ x_produce_glyphs (struct it *it)
25757 25705
25758/* EXPORT for RIF: 25706/* EXPORT for RIF:
25759 Output LEN glyphs starting at START at the nominal cursor position. 25707 Output LEN glyphs starting at START at the nominal cursor position.
25760 Advance the nominal cursor over the text. The global variable 25708 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
25761 updated_window contains the window being updated, updated_row is 25709 being updated, and UPDATED_AREA is the area of that row being updated. */
25762 the glyph row being updated, and updated_area is the area of that
25763 row being updated. */
25764 25710
25765void 25711void
25766x_write_glyphs (struct glyph *start, int len) 25712x_write_glyphs (struct window *w, struct glyph_row *updated_row,
25713 struct glyph *start, enum glyph_row_area updated_area, int len)
25767{ 25714{
25768 int x, hpos, chpos = updated_window->phys_cursor.hpos; 25715 int x, hpos, chpos = w->phys_cursor.hpos;
25769 25716
25770 eassert (updated_window && updated_row); 25717 eassert (updated_row);
25771 /* When the window is hscrolled, cursor hpos can legitimately be out 25718 /* When the window is hscrolled, cursor hpos can legitimately be out
25772 of bounds, but we draw the cursor at the corresponding window 25719 of bounds, but we draw the cursor at the corresponding window
25773 margin in that case. */ 25720 margin in that case. */
@@ -25781,24 +25728,24 @@ x_write_glyphs (struct glyph *start, int len)
25781 /* Write glyphs. */ 25728 /* Write glyphs. */
25782 25729
25783 hpos = start - updated_row->glyphs[updated_area]; 25730 hpos = start - updated_row->glyphs[updated_area];
25784 x = draw_glyphs (updated_window, output_cursor.x, 25731 x = draw_glyphs (w, w->output_cursor.x,
25785 updated_row, updated_area, 25732 updated_row, updated_area,
25786 hpos, hpos + len, 25733 hpos, hpos + len,
25787 DRAW_NORMAL_TEXT, 0); 25734 DRAW_NORMAL_TEXT, 0);
25788 25735
25789 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ 25736 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25790 if (updated_area == TEXT_AREA 25737 if (updated_area == TEXT_AREA
25791 && updated_window->phys_cursor_on_p 25738 && w->phys_cursor_on_p
25792 && updated_window->phys_cursor.vpos == output_cursor.vpos 25739 && w->phys_cursor.vpos == w->output_cursor.vpos
25793 && chpos >= hpos 25740 && chpos >= hpos
25794 && chpos < hpos + len) 25741 && chpos < hpos + len)
25795 updated_window->phys_cursor_on_p = 0; 25742 w->phys_cursor_on_p = 0;
25796 25743
25797 unblock_input (); 25744 unblock_input ();
25798 25745
25799 /* Advance the output cursor. */ 25746 /* Advance the output cursor. */
25800 output_cursor.hpos += len; 25747 w->output_cursor.hpos += len;
25801 output_cursor.x = x; 25748 w->output_cursor.x = x;
25802} 25749}
25803 25750
25804 25751
@@ -25806,19 +25753,18 @@ x_write_glyphs (struct glyph *start, int len)
25806 Insert LEN glyphs from START at the nominal cursor position. */ 25753 Insert LEN glyphs from START at the nominal cursor position. */
25807 25754
25808void 25755void
25809x_insert_glyphs (struct glyph *start, int len) 25756x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
25757 struct glyph *start, enum glyph_row_area updated_area, int len)
25810{ 25758{
25811 struct frame *f; 25759 struct frame *f;
25812 struct window *w;
25813 int line_height, shift_by_width, shifted_region_width; 25760 int line_height, shift_by_width, shifted_region_width;
25814 struct glyph_row *row; 25761 struct glyph_row *row;
25815 struct glyph *glyph; 25762 struct glyph *glyph;
25816 int frame_x, frame_y; 25763 int frame_x, frame_y;
25817 ptrdiff_t hpos; 25764 ptrdiff_t hpos;
25818 25765
25819 eassert (updated_window && updated_row); 25766 eassert (updated_row);
25820 block_input (); 25767 block_input ();
25821 w = updated_window;
25822 f = XFRAME (WINDOW_FRAME (w)); 25768 f = XFRAME (WINDOW_FRAME (w));
25823 25769
25824 /* Get the height of the line we are in. */ 25770 /* Get the height of the line we are in. */
@@ -25832,25 +25778,25 @@ x_insert_glyphs (struct glyph *start, int len)
25832 25778
25833 /* Get the width of the region to shift right. */ 25779 /* Get the width of the region to shift right. */
25834 shifted_region_width = (window_box_width (w, updated_area) 25780 shifted_region_width = (window_box_width (w, updated_area)
25835 - output_cursor.x 25781 - w->output_cursor.x
25836 - shift_by_width); 25782 - shift_by_width);
25837 25783
25838 /* Shift right. */ 25784 /* Shift right. */
25839 frame_x = window_box_left (w, updated_area) + output_cursor.x; 25785 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
25840 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y); 25786 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
25841 25787
25842 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width, 25788 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25843 line_height, shift_by_width); 25789 line_height, shift_by_width);
25844 25790
25845 /* Write the glyphs. */ 25791 /* Write the glyphs. */
25846 hpos = start - row->glyphs[updated_area]; 25792 hpos = start - row->glyphs[updated_area];
25847 draw_glyphs (w, output_cursor.x, row, updated_area, 25793 draw_glyphs (w, w->output_cursor.x, row, updated_area,
25848 hpos, hpos + len, 25794 hpos, hpos + len,
25849 DRAW_NORMAL_TEXT, 0); 25795 DRAW_NORMAL_TEXT, 0);
25850 25796
25851 /* Advance the output cursor. */ 25797 /* Advance the output cursor. */
25852 output_cursor.hpos += len; 25798 w->output_cursor.hpos += len;
25853 output_cursor.x += shift_by_width; 25799 w->output_cursor.x += shift_by_width;
25854 unblock_input (); 25800 unblock_input ();
25855} 25801}
25856 25802
@@ -25860,18 +25806,18 @@ x_insert_glyphs (struct glyph *start, int len)
25860 (inclusive) to pixel column TO_X (exclusive). The idea is that 25806 (inclusive) to pixel column TO_X (exclusive). The idea is that
25861 everything from TO_X onward is already erased. 25807 everything from TO_X onward is already erased.
25862 25808
25863 TO_X is a pixel position relative to updated_area of 25809 TO_X is a pixel position relative to UPDATED_AREA of currently
25864 updated_window. TO_X == -1 means clear to the end of this area. */ 25810 updated window W. TO_X == -1 means clear to the end of this area. */
25865 25811
25866void 25812void
25867x_clear_end_of_line (int to_x) 25813x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
25814 enum glyph_row_area updated_area, int to_x)
25868{ 25815{
25869 struct frame *f; 25816 struct frame *f;
25870 struct window *w = updated_window;
25871 int max_x, min_y, max_y; 25817 int max_x, min_y, max_y;
25872 int from_x, from_y, to_y; 25818 int from_x, from_y, to_y;
25873 25819
25874 eassert (updated_window && updated_row); 25820 eassert (updated_row);
25875 f = XFRAME (w->frame); 25821 f = XFRAME (w->frame);
25876 25822
25877 if (updated_row->full_width_p) 25823 if (updated_row->full_width_p)
@@ -25889,16 +25835,16 @@ x_clear_end_of_line (int to_x)
25889 else 25835 else
25890 to_x = min (to_x, max_x); 25836 to_x = min (to_x, max_x);
25891 25837
25892 to_y = min (max_y, output_cursor.y + updated_row->height); 25838 to_y = min (max_y, w->output_cursor.y + updated_row->height);
25893 25839
25894 /* Notice if the cursor will be cleared by this operation. */ 25840 /* Notice if the cursor will be cleared by this operation. */
25895 if (!updated_row->full_width_p) 25841 if (!updated_row->full_width_p)
25896 notice_overwritten_cursor (w, updated_area, 25842 notice_overwritten_cursor (w, updated_area,
25897 output_cursor.x, -1, 25843 w->output_cursor.x, -1,
25898 updated_row->y, 25844 updated_row->y,
25899 MATRIX_ROW_BOTTOM_Y (updated_row)); 25845 MATRIX_ROW_BOTTOM_Y (updated_row));
25900 25846
25901 from_x = output_cursor.x; 25847 from_x = w->output_cursor.x;
25902 25848
25903 /* Translate to frame coordinates. */ 25849 /* Translate to frame coordinates. */
25904 if (updated_row->full_width_p) 25850 if (updated_row->full_width_p)
@@ -25914,7 +25860,7 @@ x_clear_end_of_line (int to_x)
25914 } 25860 }
25915 25861
25916 min_y = WINDOW_HEADER_LINE_HEIGHT (w); 25862 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25917 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y)); 25863 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
25918 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y); 25864 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25919 25865
25920 /* Prevent inadvertently clearing to end of the X window. */ 25866 /* Prevent inadvertently clearing to end of the X window. */
@@ -26010,6 +25956,9 @@ set_frame_cursor_types (struct frame *f, Lisp_Object arg)
26010 } 25956 }
26011 else 25957 else
26012 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR; 25958 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25959
25960 /* Make sure the cursor gets redrawn. */
25961 cursor_type_changed = 1;
26013} 25962}
26014 25963
26015 25964
@@ -26458,7 +26407,7 @@ erase_phys_cursor (struct window *w)
26458 where to put the cursor is specified by HPOS, VPOS, X and Y. */ 26407 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26459 26408
26460void 26409void
26461display_and_set_cursor (struct window *w, int on, 26410display_and_set_cursor (struct window *w, bool on,
26462 int hpos, int vpos, int x, int y) 26411 int hpos, int vpos, int x, int y)
26463{ 26412{
26464 struct frame *f = XFRAME (w->frame); 26413 struct frame *f = XFRAME (w->frame);
@@ -26542,7 +26491,7 @@ display_and_set_cursor (struct window *w, int on,
26542 of ON. */ 26491 of ON. */
26543 26492
26544static void 26493static void
26545update_window_cursor (struct window *w, int on) 26494update_window_cursor (struct window *w, bool on)
26546{ 26495{
26547 /* Don't update cursor in windows whose frame is in the process 26496 /* Don't update cursor in windows whose frame is in the process
26548 of being deleted. */ 26497 of being deleted. */
@@ -26578,7 +26527,7 @@ update_window_cursor (struct window *w, int on)
26578 in the window tree rooted at W. */ 26527 in the window tree rooted at W. */
26579 26528
26580static void 26529static void
26581update_cursor_in_window_tree (struct window *w, int on_p) 26530update_cursor_in_window_tree (struct window *w, bool on_p)
26582{ 26531{
26583 while (w) 26532 while (w)
26584 { 26533 {
@@ -26597,7 +26546,7 @@ update_cursor_in_window_tree (struct window *w, int on_p)
26597 Don't change the cursor's position. */ 26546 Don't change the cursor's position. */
26598 26547
26599void 26548void
26600x_update_cursor (struct frame *f, int on_p) 26549x_update_cursor (struct frame *f, bool on_p)
26601{ 26550{
26602 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p); 26551 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26603} 26552}
@@ -26784,10 +26733,7 @@ clear_mouse_face (Mouse_HLInfo *hlinfo)
26784 cleared = 1; 26733 cleared = 1;
26785 } 26734 }
26786 26735
26787 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; 26736 reset_mouse_highlight (hlinfo);
26788 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26789 hlinfo->mouse_face_window = Qnil;
26790 hlinfo->mouse_face_overlay = Qnil;
26791 return cleared; 26737 return cleared;
26792} 26738}
26793 26739
@@ -27048,7 +26994,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
27048 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */ 26994 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
27049 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2); 26995 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
27050 if (r1 == NULL) 26996 if (r1 == NULL)
27051 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 26997 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27052 /* If the before-string or display-string contains newlines, 26998 /* If the before-string or display-string contains newlines,
27053 rows_from_pos_range skips to its last row. Move back. */ 26999 rows_from_pos_range skips to its last row. Move back. */
27054 if (!NILP (before_string) || !NILP (disp_string)) 27000 if (!NILP (before_string) || !NILP (disp_string))
@@ -27070,7 +27016,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
27070 } 27016 }
27071 if (r2 == NULL) 27017 if (r2 == NULL)
27072 { 27018 {
27073 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 27019 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27074 hlinfo->mouse_face_past_end = 1; 27020 hlinfo->mouse_face_past_end = 1;
27075 } 27021 }
27076 else if (!NILP (after_string)) 27022 else if (!NILP (after_string))
@@ -27078,7 +27024,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
27078 /* If the after-string has newlines, advance to its last row. */ 27024 /* If the after-string has newlines, advance to its last row. */
27079 struct glyph_row *next; 27025 struct glyph_row *next;
27080 struct glyph_row *last 27026 struct glyph_row *last
27081 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos)); 27027 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
27082 27028
27083 for (next = r2 + 1; 27029 for (next = r2 + 1;
27084 next <= last 27030 next <= last
@@ -27100,9 +27046,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
27100 r1 = tem; 27046 r1 = tem;
27101 } 27047 }
27102 27048
27103 hlinfo->mouse_face_beg_y = r1->y;
27104 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix); 27049 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
27105 hlinfo->mouse_face_end_y = r2->y;
27106 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix); 27050 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
27107 27051
27108 /* For a bidi-reordered row, the positions of BEFORE_STRING, 27052 /* For a bidi-reordered row, the positions of BEFORE_STRING,
@@ -27466,7 +27410,6 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27466 { 27410 {
27467 hlinfo->mouse_face_beg_row 27411 hlinfo->mouse_face_beg_row
27468 = MATRIX_ROW_VPOS (r, w->current_matrix); 27412 = MATRIX_ROW_VPOS (r, w->current_matrix);
27469 hlinfo->mouse_face_beg_y = r->y;
27470 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA]; 27413 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27471 hlinfo->mouse_face_beg_x = gx; 27414 hlinfo->mouse_face_beg_x = gx;
27472 found = 1; 27415 found = 1;
@@ -27485,7 +27428,6 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27485 { 27428 {
27486 hlinfo->mouse_face_beg_row 27429 hlinfo->mouse_face_beg_row
27487 = MATRIX_ROW_VPOS (r, w->current_matrix); 27430 = MATRIX_ROW_VPOS (r, w->current_matrix);
27488 hlinfo->mouse_face_beg_y = r->y;
27489 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA]; 27431 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27490 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1) 27432 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27491 gx += g1->pixel_width; 27433 gx += g1->pixel_width;
@@ -27522,9 +27464,8 @@ mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27522 /* The highlighted region ends on the previous row. */ 27464 /* The highlighted region ends on the previous row. */
27523 r--; 27465 r--;
27524 27466
27525 /* Set the end row and its vertical pixel coordinate. */ 27467 /* Set the end row. */
27526 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix); 27468 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
27527 hlinfo->mouse_face_end_y = r->y;
27528 27469
27529 /* Compute and set the end column and the end column's horizontal 27470 /* Compute and set the end column and the end column's horizontal
27530 pixel coordinate. */ 27471 pixel coordinate. */
@@ -28022,8 +27963,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
28022 27963
28023 hlinfo->mouse_face_beg_row = vpos; 27964 hlinfo->mouse_face_beg_row = vpos;
28024 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row; 27965 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
28025 hlinfo->mouse_face_beg_y = 0;
28026 hlinfo->mouse_face_end_y = 0;
28027 hlinfo->mouse_face_past_end = 0; 27966 hlinfo->mouse_face_past_end = 0;
28028 hlinfo->mouse_face_window = window; 27967 hlinfo->mouse_face_window = window;
28029 27968
@@ -28142,10 +28081,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
28142 /* Are we in a window whose display is up to date? 28081 /* Are we in a window whose display is up to date?
28143 And verify the buffer's text has not changed. */ 28082 And verify the buffer's text has not changed. */
28144 b = XBUFFER (w->contents); 28083 b = XBUFFER (w->contents);
28145 if (part == ON_TEXT 28084 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
28146 && w->window_end_valid
28147 && w->last_modified == BUF_MODIFF (b)
28148 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
28149 { 28085 {
28150 int hpos, vpos, dx, dy, area = LAST_AREA; 28086 int hpos, vpos, dx, dy, area = LAST_AREA;
28151 ptrdiff_t pos; 28087 ptrdiff_t pos;
@@ -28387,8 +28323,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
28387 : Qnil; 28323 : Qnil;
28388 Lisp_Object lim2 = 28324 Lisp_Object lim2 =
28389 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering)) 28325 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28390 ? make_number (BUF_Z (XBUFFER (buffer)) 28326 ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
28391 - XFASTINT (w->window_end_pos))
28392 : Qnil; 28327 : Qnil;
28393 28328
28394 if (NILP (overlay)) 28329 if (NILP (overlay))
@@ -28586,11 +28521,7 @@ cancel_mouse_face (struct frame *f)
28586 28521
28587 window = hlinfo->mouse_face_window; 28522 window = hlinfo->mouse_face_window;
28588 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) 28523 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28589 { 28524 reset_mouse_highlight (hlinfo);
28590 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28591 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28592 hlinfo->mouse_face_window = Qnil;
28593 }
28594} 28525}
28595 28526
28596 28527
@@ -28790,7 +28721,7 @@ x_draw_vertical_border (struct window *w)
28790 { 28721 {
28791 int x0, x1, y0, y1; 28722 int x0, x1, y0, y1;
28792 28723
28793 window_box_edges (w, -1, &x0, &y0, &x1, &y1); 28724 window_box_edges (w, &x0, &y0, &x1, &y1);
28794 y1 -= 1; 28725 y1 -= 1;
28795 28726
28796 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) 28727 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
@@ -28803,7 +28734,7 @@ x_draw_vertical_border (struct window *w)
28803 { 28734 {
28804 int x0, x1, y0, y1; 28735 int x0, x1, y0, y1;
28805 28736
28806 window_box_edges (w, -1, &x0, &y0, &x1, &y1); 28737 window_box_edges (w, &x0, &y0, &x1, &y1);
28807 y1 -= 1; 28738 y1 -= 1;
28808 28739
28809 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) 28740 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
@@ -28836,7 +28767,7 @@ expose_window (struct window *w, XRectangle *fr)
28836 /* When we're currently updating the window, display and current 28767 /* When we're currently updating the window, display and current
28837 matrix usually don't agree. Arrange for a thorough display 28768 matrix usually don't agree. Arrange for a thorough display
28838 later. */ 28769 later. */
28839 if (w == updated_window) 28770 if (w->must_be_updated_p)
28840 { 28771 {
28841 SET_FRAME_GARBAGED (f); 28772 SET_FRAME_GARBAGED (f);
28842 return 0; 28773 return 0;
@@ -29722,10 +29653,6 @@ cursor shapes. */);
29722 DEFSYM (Qzero_width, "zero-width"); 29653 DEFSYM (Qzero_width, "zero-width");
29723 29654
29724 DEFSYM (Qglyphless_char_display, "glyphless-char-display"); 29655 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29725 /* Intern this now in case it isn't already done.
29726 Setting this variable twice is harmless.
29727 But don't staticpro it here--that is done in alloc.c. */
29728 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29729 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1)); 29656 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29730 29657
29731 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display, 29658 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
@@ -29811,20 +29738,20 @@ void
29811start_hourglass (void) 29738start_hourglass (void)
29812{ 29739{
29813#if defined (HAVE_WINDOW_SYSTEM) 29740#if defined (HAVE_WINDOW_SYSTEM)
29814 EMACS_TIME delay; 29741 struct timespec delay;
29815 29742
29816 cancel_hourglass (); 29743 cancel_hourglass ();
29817 29744
29818 if (INTEGERP (Vhourglass_delay) 29745 if (INTEGERP (Vhourglass_delay)
29819 && XINT (Vhourglass_delay) > 0) 29746 && XINT (Vhourglass_delay) > 0)
29820 delay = make_emacs_time (min (XINT (Vhourglass_delay), 29747 delay = make_timespec (min (XINT (Vhourglass_delay),
29821 TYPE_MAXIMUM (time_t)), 29748 TYPE_MAXIMUM (time_t)),
29822 0); 29749 0);
29823 else if (FLOATP (Vhourglass_delay) 29750 else if (FLOATP (Vhourglass_delay)
29824 && XFLOAT_DATA (Vhourglass_delay) > 0) 29751 && XFLOAT_DATA (Vhourglass_delay) > 0)
29825 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay)); 29752 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
29826 else 29753 else
29827 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0); 29754 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
29828 29755
29829#ifdef HAVE_NTGUI 29756#ifdef HAVE_NTGUI
29830 { 29757 {
diff --git a/src/xfaces.c b/src/xfaces.c
index acd2d2b1116..a55ac90086d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -236,7 +236,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
236#ifdef HAVE_NS 236#ifdef HAVE_NS
237#undef FRAME_X_DISPLAY_INFO 237#undef FRAME_X_DISPLAY_INFO
238#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO 238#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
239#define x_display_info ns_display_info
240#define GCGraphicsExposures 0 239#define GCGraphicsExposures 0
241#endif /* HAVE_NS */ 240#endif /* HAVE_NS */
242#endif /* HAVE_WINDOW_SYSTEM */ 241#endif /* HAVE_WINDOW_SYSTEM */
@@ -759,11 +758,6 @@ clear_face_cache (int clear_fonts_p)
759 if (clear_fonts_p 758 if (clear_fonts_p
760 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) 759 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
761 { 760 {
762#if 0
763 /* Not yet implemented. */
764 clear_font_cache (frame);
765#endif
766
767 /* From time to time see if we can unload some fonts. This also 761 /* From time to time see if we can unload some fonts. This also
768 frees all realized faces on all frames. Fonts needed by 762 frees all realized faces on all frames. Fonts needed by
769 faces will be loaded again when faces are realized again. */ 763 faces will be loaded again when faces are realized again. */
@@ -774,7 +768,10 @@ clear_face_cache (int clear_fonts_p)
774 struct frame *f = XFRAME (frame); 768 struct frame *f = XFRAME (frame);
775 if (FRAME_WINDOW_P (f) 769 if (FRAME_WINDOW_P (f)
776 && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS) 770 && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
777 free_all_realized_faces (frame); 771 {
772 clear_font_cache (f);
773 free_all_realized_faces (frame);
774 }
778 } 775 }
779 } 776 }
780 else 777 else
diff --git a/src/xfns.c b/src/xfns.c
index a1e9e916aba..b08fc76524c 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -22,10 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <math.h> 22#include <math.h>
23#include <unistd.h> 23#include <unistd.h>
24 24
25/* This makes the fields of a Display accessible, in Xlib header files. */
26
27#define XLIB_ILLEGAL_ACCESS
28
29#include "lisp.h" 25#include "lisp.h"
30#include "xterm.h" 26#include "xterm.h"
31#include "frame.h" 27#include "frame.h"
@@ -1053,11 +1049,8 @@ static void
1053x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 1049x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1054{ 1050{
1055 set_frame_cursor_types (f, arg); 1051 set_frame_cursor_types (f, arg);
1056
1057 /* Make sure the cursor gets redrawn. */
1058 cursor_type_changed = 1;
1059} 1052}
1060 1053
1061static void 1054static void
1062x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 1055x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1063{ 1056{
@@ -1189,7 +1182,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1189 1182
1190 block_input (); 1183 block_input ();
1191 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 1184 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1192 0, y, width, height, False); 1185 0, y, width, height);
1193 unblock_input (); 1186 unblock_input ();
1194 } 1187 }
1195 1188
@@ -1200,7 +1193,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1200 1193
1201 block_input (); 1194 block_input ();
1202 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 1195 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1203 0, y, width, height, False); 1196 0, y, width, height);
1204 unblock_input (); 1197 unblock_input ();
1205 } 1198 }
1206 1199
@@ -1298,8 +1291,8 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1298 if (height > 0 && width > 0) 1291 if (height > 0 && width > 0)
1299 { 1292 {
1300 block_input (); 1293 block_input ();
1301 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 1294 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1302 0, y, width, height, False); 1295 0, y, width, height);
1303 unblock_input (); 1296 unblock_input ();
1304 } 1297 }
1305 1298
@@ -2313,12 +2306,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
2313 for the window manager, so GC relocation won't bother it. 2306 for the window manager, so GC relocation won't bother it.
2314 2307
2315 Elsewhere we specify the window name for the window manager. */ 2308 Elsewhere we specify the window name for the window manager. */
2316 2309 f->namebuf = xstrdup (SSDATA (Vx_resource_name));
2317 {
2318 char *str = SSDATA (Vx_resource_name);
2319 f->namebuf = xmalloc (strlen (str) + 1);
2320 strcpy (f->namebuf, str);
2321 }
2322 2310
2323 ac = 0; 2311 ac = 0;
2324 XtSetArg (al[ac], XtNallowShellResize, 1); ac++; 2312 XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
@@ -2336,12 +2324,8 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
2336 /* maybe_set_screen_title_format (shell_widget); */ 2324 /* maybe_set_screen_title_format (shell_widget); */
2337 2325
2338 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++, 2326 pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
2339 (widget_value *) NULL, 2327 NULL, shell_widget, False,
2340 shell_widget, False, 2328 NULL, NULL, NULL, NULL);
2341 (lw_callback) NULL,
2342 (lw_callback) NULL,
2343 (lw_callback) NULL,
2344 (lw_callback) NULL);
2345 2329
2346 ac = 0; 2330 ac = 0;
2347 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++; 2331 XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
@@ -2488,8 +2472,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
2488 */ 2472 */
2489 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget), 2473 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
2490 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols, 2474 FRAME_X_DISPLAY_INFO (f)->Xatom_wm_protocols,
2491 XA_ATOM, 32, PropModeAppend, 2475 XA_ATOM, 32, PropModeAppend, NULL, 0);
2492 (unsigned char*) NULL, 0);
2493 2476
2494 /* Make all the standard events reach the Emacs frame. */ 2477 /* Make all the standard events reach the Emacs frame. */
2495 attributes.event_mask = STANDARD_EVENT_SET; 2478 attributes.event_mask = STANDARD_EVENT_SET;
@@ -4014,7 +3997,7 @@ x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
4014 / x_display_pixel_width (dpyinfo)); 3997 / x_display_pixel_width (dpyinfo));
4015 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen) 3998 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
4016 / x_display_pixel_height (dpyinfo)); 3999 / x_display_pixel_height (dpyinfo));
4017 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); 4000 monitors = xzalloc (n_monitors * sizeof *monitors);
4018 for (i = 0; i < n_monitors; ++i) 4001 for (i = 0; i < n_monitors; ++i)
4019 { 4002 {
4020 struct MonitorInfo *mi = &monitors[i]; 4003 struct MonitorInfo *mi = &monitors[i];
@@ -4074,7 +4057,7 @@ x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
4074 return Qnil; 4057 return Qnil;
4075 } 4058 }
4076 n_monitors = resources->noutput; 4059 n_monitors = resources->noutput;
4077 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); 4060 monitors = xzalloc (n_monitors * sizeof *monitors);
4078 4061
4079#ifdef HAVE_XRRGETOUTPUTPRIMARY 4062#ifdef HAVE_XRRGETOUTPUTPRIMARY
4080 pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window); 4063 pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
@@ -4230,7 +4213,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4230#endif 4213#endif
4231 n_monitors = gdk_screen_get_n_monitors (gscreen); 4214 n_monitors = gdk_screen_get_n_monitors (gscreen);
4232 monitor_frames = Fmake_vector (make_number (n_monitors), Qnil); 4215 monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
4233 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors)); 4216 monitors = xzalloc (n_monitors * sizeof *monitors);
4234 4217
4235 FOR_EACH_FRAME (rest, frame) 4218 FOR_EACH_FRAME (rest, frame)
4236 { 4219 {
@@ -4468,8 +4451,7 @@ x_display_info_for_name (Lisp_Object name)
4468 4451
4469 validate_x_resource_name (); 4452 validate_x_resource_name ();
4470 4453
4471 dpyinfo = x_term_init (name, (char *)0, 4454 dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name));
4472 SSDATA (Vx_resource_name));
4473 4455
4474 if (dpyinfo == 0) 4456 if (dpyinfo == 0)
4475 error ("Cannot connect to X server %s", SDATA (name)); 4457 error ("Cannot connect to X server %s", SDATA (name));
@@ -4502,10 +4484,7 @@ terminate Emacs if we can't open the connection.
4502 error ("Not using X Windows"); /* That doesn't stop us anymore. */ 4484 error ("Not using X Windows"); /* That doesn't stop us anymore. */
4503#endif 4485#endif
4504 4486
4505 if (! NILP (xrm_string)) 4487 xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string);
4506 xrm_option = SSDATA (xrm_string);
4507 else
4508 xrm_option = (char *) 0;
4509 4488
4510 validate_x_resource_name (); 4489 validate_x_resource_name ();
4511 4490
@@ -5729,8 +5708,8 @@ DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5729static void 5708static void
5730file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data) 5709file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5731{ 5710{
5732 int *result = (int *) client_data; 5711 int *result = client_data;
5733 XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data; 5712 XmAnyCallbackStruct *cb = call_data;
5734 *result = cb->reason; 5713 *result = cb->reason;
5735} 5714}
5736 5715
@@ -5743,7 +5722,7 @@ file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5743static void 5722static void
5744file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data) 5723file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
5745{ 5724{
5746 int *result = (int *) client_data; 5725 int *result = client_data;
5747 *result = XmCR_CANCEL; 5726 *result = XmCR_CANCEL;
5748} 5727}
5749 5728
diff --git a/src/xfont.c b/src/xfont.c
index f673adbbd5e..1aface6f972 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -593,9 +593,7 @@ xfont_match (struct frame *f, Lisp_Object spec)
593 { 593 {
594 if (XGetFontProperty (xfont, XA_FONT, &value)) 594 if (XGetFontProperty (xfont, XA_FONT, &value))
595 { 595 {
596 char *s; 596 char *s = XGetAtomName (display, (Atom) value);
597
598 s = (char *) XGetAtomName (display, (Atom) value);
599 597
600 /* If DXPC (a Differential X Protocol Compressor) 598 /* If DXPC (a Differential X Protocol Compressor)
601 Ver.3.7 is running, XGetAtomName will return null 599 Ver.3.7 is running, XGetAtomName will return null
@@ -760,7 +758,7 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
760 char *p0, *p; 758 char *p0, *p;
761 int dashes = 0; 759 int dashes = 0;
762 760
763 p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value); 761 p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
764 /* Count the number of dashes in the "full name". 762 /* Count the number of dashes in the "full name".
765 If it is too few, this isn't really the font's full name, 763 If it is too few, this isn't really the font's full name,
766 so don't use it. 764 so don't use it.
diff --git a/src/xgselect.c b/src/xgselect.c
index 4d90298a9d9..7a754bd75c0 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -25,14 +25,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 25
26#include <glib.h> 26#include <glib.h>
27#include <errno.h> 27#include <errno.h>
28#include <timespec.h>
28#include "frame.h" 29#include "frame.h"
29 30
30int 31int
31xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, 32xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
32 EMACS_TIME *timeout, sigset_t *sigmask) 33 struct timespec const *timeout, sigset_t const *sigmask)
33{ 34{
34 SELECT_TYPE all_rfds, all_wfds; 35 fd_set all_rfds, all_wfds;
35 EMACS_TIME tmo, *tmop = timeout; 36 struct timespec tmo;
37 struct timespec const *tmop = timeout;
36 38
37 GMainContext *context; 39 GMainContext *context;
38 int have_wfds = wfds != NULL; 40 int have_wfds = wfds != NULL;
@@ -85,9 +87,9 @@ xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
85 87
86 if (tmo_in_millisec >= 0) 88 if (tmo_in_millisec >= 0)
87 { 89 {
88 tmo = make_emacs_time (tmo_in_millisec / 1000, 90 tmo = make_timespec (tmo_in_millisec / 1000,
89 1000 * 1000 * (tmo_in_millisec % 1000)); 91 1000 * 1000 * (tmo_in_millisec % 1000));
90 if (!timeout || EMACS_TIME_LT (tmo, *timeout)) 92 if (!timeout || timespec_cmp (tmo, *timeout) < 0)
91 tmop = &tmo; 93 tmop = &tmo;
92 } 94 }
93 95
diff --git a/src/xgselect.h b/src/xgselect.h
index f142e85d877..1f8555591d0 100644
--- a/src/xgselect.h
+++ b/src/xgselect.h
@@ -21,14 +21,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#define XGSELECT_H 21#define XGSELECT_H
22 22
23#include "lisp.h" 23#include "lisp.h"
24#include "systime.h" 24#include <time.h>
25#include "sysselect.h" 25#include "sysselect.h"
26 26
27extern int xg_select (int max_fds, 27extern int xg_select (int max_fds,
28 SELECT_TYPE *rfds, 28 fd_set *rfds, fd_set *wfds, fd_set *efds,
29 SELECT_TYPE *wfds, 29 struct timespec const *timeout,
30 SELECT_TYPE *efds, 30 sigset_t const *sigmask);
31 EMACS_TIME *timeout,
32 sigset_t *sigmask);
33 31
34#endif /* XGSELECT_H */ 32#endif /* XGSELECT_H */
diff --git a/src/xmenu.c b/src/xmenu.c
index cad892444ff..823c63bfc6f 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -373,12 +373,12 @@ x_menu_wait_for_event (void *data)
373#elif defined USE_GTK 373#elif defined USE_GTK
374 ! gtk_events_pending () 374 ! gtk_events_pending ()
375#else 375#else
376 ! XPending ((Display*) data) 376 ! XPending (data)
377#endif 377#endif
378 ) 378 )
379 { 379 {
380 EMACS_TIME next_time = timer_check (), *ntp; 380 struct timespec next_time = timer_check (), *ntp;
381 SELECT_TYPE read_fds; 381 fd_set read_fds;
382 struct x_display_info *dpyinfo; 382 struct x_display_info *dpyinfo;
383 int n = 0; 383 int n = 0;
384 384
@@ -391,7 +391,7 @@ x_menu_wait_for_event (void *data)
391 XFlush (dpyinfo->display); 391 XFlush (dpyinfo->display);
392 } 392 }
393 393
394 if (! EMACS_TIME_VALID_P (next_time)) 394 if (! timespec_valid_p (next_time))
395 ntp = 0; 395 ntp = 0;
396 else 396 else
397 ntp = &next_time; 397 ntp = &next_time;
@@ -722,8 +722,7 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data)
722 xg_menu_item_cb_data *cb_data; 722 xg_menu_item_cb_data *cb_data;
723 Lisp_Object help; 723 Lisp_Object help;
724 724
725 cb_data = (xg_menu_item_cb_data*) g_object_get_data (G_OBJECT (widget), 725 cb_data = g_object_get_data (G_OBJECT (widget), XG_ITEM_DATA);
726 XG_ITEM_DATA);
727 if (! cb_data) return; 726 if (! cb_data) return;
728 727
729 help = call_data ? cb_data->help : Qnil; 728 help = call_data ? cb_data->help : Qnil;
@@ -741,15 +740,11 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data)
741static void 740static void
742menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data) 741menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data)
743{ 742{
744 struct frame *f; 743 widget_value *wv = call_data;
745 Lisp_Object help; 744 Lisp_Object help = wv ? wv->help : Qnil;
746
747 widget_value *wv = (widget_value *) call_data;
748
749 help = wv ? wv->help : Qnil;
750 745
751 /* Determine the frame for the help event. */ 746 /* Determine the frame for the help event. */
752 f = menubar_id_to_frame (id); 747 struct frame *f = menubar_id_to_frame (id);
753 748
754 show_help_event (f, widget, help); 749 show_help_event (f, widget, help);
755} 750}
@@ -769,7 +764,7 @@ static int xg_crazy_callback_abort;
769static void 764static void
770menubar_selection_callback (GtkWidget *widget, gpointer client_data) 765menubar_selection_callback (GtkWidget *widget, gpointer client_data)
771{ 766{
772 xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data; 767 xg_menu_item_cb_data *cb_data = client_data;
773 768
774 if (xg_crazy_callback_abort) 769 if (xg_crazy_callback_abort)
775 return; 770 return;
@@ -1370,7 +1365,7 @@ struct next_popup_x_y
1370static void 1365static void
1371menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) 1366menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
1372{ 1367{
1373 struct next_popup_x_y* data = (struct next_popup_x_y*)user_data; 1368 struct next_popup_x_y *data = user_data;
1374 GtkRequisition req; 1369 GtkRequisition req;
1375 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (data->f); 1370 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (data->f);
1376 int disp_width = x_display_pixel_width (dpyinfo); 1371 int disp_width = x_display_pixel_width (dpyinfo);
@@ -1391,10 +1386,10 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer
1391static void 1386static void
1392popup_selection_callback (GtkWidget *widget, gpointer client_data) 1387popup_selection_callback (GtkWidget *widget, gpointer client_data)
1393{ 1388{
1394 xg_menu_item_cb_data *cb_data = (xg_menu_item_cb_data*) client_data; 1389 xg_menu_item_cb_data *cb_data = client_data;
1395 1390
1396 if (xg_crazy_callback_abort) return; 1391 if (xg_crazy_callback_abort) return;
1397 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; 1392 if (cb_data) menu_item_selection = cb_data->call_data;
1398} 1393}
1399 1394
1400static void 1395static void
@@ -1497,7 +1492,7 @@ LWLIB_ID widget_id_tick;
1497static void 1492static void
1498popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) 1493popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
1499{ 1494{
1500 menu_item_selection = (Lisp_Object *) client_data; 1495 menu_item_selection = client_data;
1501} 1496}
1502 1497
1503/* ARG is the LWLIB ID of the dialog box, represented 1498/* ARG is the LWLIB ID of the dialog box, represented
@@ -1583,7 +1578,7 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
1583 make_number (menu_id & ~(-1 << (fact))))); 1578 make_number (menu_id & ~(-1 << (fact)))));
1584 1579
1585 /* Process events that apply to the menu. */ 1580 /* Process events that apply to the menu. */
1586 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1); 1581 popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), menu_id, 1);
1587 1582
1588 unbind_to (specpdl_count, Qnil); 1583 unbind_to (specpdl_count, Qnil);
1589 } 1584 }
@@ -1882,7 +1877,7 @@ dialog_selection_callback (GtkWidget *widget, gpointer client_data)
1882 /* Treat the pointer as an integer. There's no problem 1877 /* Treat the pointer as an integer. There's no problem
1883 as long as pointers have enough bits to hold small integers. */ 1878 as long as pointers have enough bits to hold small integers. */
1884 if ((intptr_t) client_data != -1) 1879 if ((intptr_t) client_data != -1)
1885 menu_item_selection = (Lisp_Object *) client_data; 1880 menu_item_selection = client_data;
1886 1881
1887 popup_activated_flag = 0; 1882 popup_activated_flag = 0;
1888} 1883}
@@ -1924,7 +1919,7 @@ dialog_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
1924 /* Treat the pointer as an integer. There's no problem 1919 /* Treat the pointer as an integer. There's no problem
1925 as long as pointers have enough bits to hold small integers. */ 1920 as long as pointers have enough bits to hold small integers. */
1926 if ((intptr_t) client_data != -1) 1921 if ((intptr_t) client_data != -1)
1927 menu_item_selection = (Lisp_Object *) client_data; 1922 menu_item_selection = client_data;
1928 1923
1929 block_input (); 1924 block_input ();
1930 lw_destroy_all_widgets (id); 1925 lw_destroy_all_widgets (id);
@@ -1967,8 +1962,7 @@ create_and_show_dialog (struct frame *f, widget_value *first_wv)
1967 Fcons (make_number (dialog_id >> (fact)), 1962 Fcons (make_number (dialog_id >> (fact)),
1968 make_number (dialog_id & ~(-1 << (fact))))); 1963 make_number (dialog_id & ~(-1 << (fact)))));
1969 1964
1970 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), 1965 popup_get_selection (0, FRAME_X_DISPLAY_INFO (f), dialog_id, 1);
1971 dialog_id, 1);
1972 1966
1973 unbind_to (count, Qnil); 1967 unbind_to (count, Qnil);
1974 } 1968 }
diff --git a/src/xrdb.c b/src/xrdb.c
index 7c9cd53fa8c..60dcdae080d 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -75,18 +75,9 @@ x_get_customization_string (XrmDatabase db, const char *name,
75 sprintf (full_class, "%s.%s", class, "Customization"); 75 sprintf (full_class, "%s.%s", class, "Customization");
76 76
77 result = x_get_string_resource (db, full_name, full_class); 77 result = x_get_string_resource (db, full_name, full_class);
78 78 return result ? xstrdup (result) : NULL;
79 if (result)
80 {
81 char *copy = xmalloc (strlen (result) + 1);
82 strcpy (copy, result);
83 return copy;
84 }
85 else
86 return 0;
87} 79}
88 80
89
90/* Expand all the Xt-style %-escapes in STRING, whose length is given 81/* Expand all the Xt-style %-escapes in STRING, whose length is given
91 by STRING_LEN. Here are the escapes we're supposed to recognize: 82 by STRING_LEN. Here are the escapes we're supposed to recognize:
92 83
@@ -605,7 +596,7 @@ x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
605 if (x_get_resource (rdb, name, class, x_rm_string, &value)) 596 if (x_get_resource (rdb, name, class, x_rm_string, &value))
606 return (char *) value.addr; 597 return (char *) value.addr;
607 598
608 return (char *) 0; 599 return 0;
609} 600}
610 601
611/* Stand-alone test facilities. */ 602/* Stand-alone test facilities. */
@@ -655,10 +646,7 @@ main (int argc, char **argv)
655 displayname = "localhost:0.0"; 646 displayname = "localhost:0.0";
656 647
657 lp = member ("-xrm", arg_list); 648 lp = member ("-xrm", arg_list);
658 if (! NIL (lp)) 649 resource_string = NIL (lp) ? 0 : car (cdr (lp));
659 resource_string = car (cdr (lp));
660 else
661 resource_string = (char *) 0;
662 650
663 lp = member ("-c", arg_list); 651 lp = member ("-c", arg_list);
664 if (! NIL (lp)) 652 if (! NIL (lp))
diff --git a/src/xselect.c b/src/xselect.c
index 3a16d7d3496..e5f2e214fba 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2628,6 +2628,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
2628 2628
2629 block_input (); 2629 block_input ();
2630 2630
2631 event.xclient.send_event = True;
2632 event.xclient.serial = 0;
2631 event.xclient.message_type = message_type; 2633 event.xclient.message_type = message_type;
2632 event.xclient.display = dpyinfo->display; 2634 event.xclient.display = dpyinfo->display;
2633 2635
@@ -2635,19 +2637,19 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
2635 when sending to the root window. */ 2637 when sending to the root window. */
2636 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; 2638 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
2637 2639
2638 2640 memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l));
2639 memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b));
2640 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, 2641 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
2641 event.xclient.format); 2642 event.xclient.format);
2642 2643
2643 /* If event mask is 0 the event is sent to the client that created 2644 /* If event mask is 0 the event is sent to the client that created
2644 the destination window. But if we are sending to the root window, 2645 the destination window. But if we are sending to the root window,
2645 there is no such client. Then we set the event mask to 0xffff. The 2646 there is no such client. Then we set the event mask to 0xffffff. The
2646 event then goes to clients selecting for events on the root window. */ 2647 event then goes to clients selecting for events on the root window. */
2647 x_catch_errors (dpyinfo->display); 2648 x_catch_errors (dpyinfo->display);
2648 { 2649 {
2649 int propagate = to_root ? False : True; 2650 int propagate = to_root ? False : True;
2650 unsigned mask = to_root ? 0xffff : 0; 2651 long mask = to_root ? 0xffffff : 0;
2652
2651 XSendEvent (dpyinfo->display, wdest, propagate, mask, &event); 2653 XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
2652 XFlush (dpyinfo->display); 2654 XFlush (dpyinfo->display);
2653 } 2655 }
diff --git a/src/xsmfns.c b/src/xsmfns.c
index cb7122202df..526d4c3610b 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -107,8 +107,7 @@ x_session_check_input (int fd, void *data)
107 will be called. */ 107 will be called. */
108 emacs_event.kind = NO_EVENT; 108 emacs_event.kind = NO_EVENT;
109 109
110 ret = IceProcessMessages (SmcGetIceConnection (smc_conn), 110 ret = IceProcessMessages (SmcGetIceConnection (smc_conn), 0, 0);
111 (IceReplyWaitInfo *)0, (Bool *)0);
112 if (ret != IceProcessMessagesSuccess) 111 if (ret != IceProcessMessagesSuccess)
113 { 112 {
114 /* Either IO error or Connection closed. */ 113 /* Either IO error or Connection closed. */
diff --git a/src/xterm.c b/src/xterm.c
index a486242b8c3..bd990014cea 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -140,16 +140,11 @@ int use_xim = 1;
140int use_xim = 0; /* configure --without-xim */ 140int use_xim = 0; /* configure --without-xim */
141#endif 141#endif
142 142
143
144
145/* Non-zero means that a HELP_EVENT has been generated since Emacs 143/* Non-zero means that a HELP_EVENT has been generated since Emacs
146 start. */ 144 start. */
147 145
148static bool any_help_event_p; 146static bool any_help_event_p;
149 147
150/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
151static Lisp_Object last_window;
152
153/* This is a chain of structures for all the X displays currently in 148/* This is a chain of structures for all the X displays currently in
154 use. */ 149 use. */
155 150
@@ -292,15 +287,11 @@ static void x_set_window_size_1 (struct frame *, int, int, int);
292static void x_raise_frame (struct frame *); 287static void x_raise_frame (struct frame *);
293static void x_lower_frame (struct frame *); 288static void x_lower_frame (struct frame *);
294static const XColor *x_color_cells (Display *, int *); 289static const XColor *x_color_cells (Display *, int *);
295static void x_update_window_end (struct window *, int, int);
296
297static int x_io_error_quitter (Display *); 290static int x_io_error_quitter (Display *);
298static struct terminal *x_create_terminal (struct x_display_info *); 291static struct terminal *x_create_terminal (struct x_display_info *);
299void x_delete_terminal (struct terminal *); 292void x_delete_terminal (struct terminal *);
300static void x_update_end (struct frame *); 293static void x_update_end (struct frame *);
301static void XTframe_up_to_date (struct frame *); 294static void XTframe_up_to_date (struct frame *);
302static void XTset_terminal_modes (struct terminal *);
303static void XTreset_terminal_modes (struct terminal *);
304static void x_clear_frame (struct frame *); 295static void x_clear_frame (struct frame *);
305static _Noreturn void x_ins_del_lines (struct frame *, int, int); 296static _Noreturn void x_ins_del_lines (struct frame *, int, int);
306static void frame_highlight (struct frame *); 297static void frame_highlight (struct frame *);
@@ -316,11 +307,11 @@ static void x_draw_hollow_cursor (struct window *, struct glyph_row *);
316static void x_draw_bar_cursor (struct window *, struct glyph_row *, int, 307static void x_draw_bar_cursor (struct window *, struct glyph_row *, int,
317 enum text_cursor_kinds); 308 enum text_cursor_kinds);
318 309
319static void x_clip_to_row (struct window *, struct glyph_row *, int, GC); 310static void x_clip_to_row (struct window *, struct glyph_row *,
311 enum glyph_row_area, GC);
320static void x_flush (struct frame *f); 312static void x_flush (struct frame *f);
321static void x_update_begin (struct frame *); 313static void x_update_begin (struct frame *);
322static void x_update_window_begin (struct window *); 314static void x_update_window_begin (struct window *);
323static void x_after_update_window_line (struct glyph_row *);
324static struct scroll_bar *x_window_to_scroll_bar (Display *, Window); 315static struct scroll_bar *x_window_to_scroll_bar (Display *, Window);
325static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, 316static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
326 enum scroll_bar_part *, 317 enum scroll_bar_part *,
@@ -554,9 +545,7 @@ x_update_begin (struct frame *f)
554} 545}
555 546
556 547
557/* Start update of window W. Set the global variable updated_window 548/* Start update of window W. */
558 to the window being updated and set output_cursor to the cursor
559 position of W. */
560 549
561static void 550static void
562x_update_window_begin (struct window *w) 551x_update_window_begin (struct window *w)
@@ -564,8 +553,7 @@ x_update_window_begin (struct window *w)
564 struct frame *f = XFRAME (WINDOW_FRAME (w)); 553 struct frame *f = XFRAME (WINDOW_FRAME (w));
565 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); 554 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
566 555
567 updated_window = w; 556 w->output_cursor = w->cursor;
568 set_output_cursor (&w->cursor);
569 557
570 block_input (); 558 block_input ();
571 559
@@ -601,7 +589,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
601 f->output_data.x->normal_gc, x, y0, x, y1); 589 f->output_data.x->normal_gc, x, y0, x, y1);
602} 590}
603 591
604/* End update of window W (which is equal to updated_window). 592/* End update of window W.
605 593
606 Draw vertical borders between horizontally adjacent windows, and 594 Draw vertical borders between horizontally adjacent windows, and
607 display W's cursor if CURSOR_ON_P is non-zero. 595 display W's cursor if CURSOR_ON_P is non-zero.
@@ -615,18 +603,17 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
615 here. */ 603 here. */
616 604
617static void 605static void
618x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritten_p) 606x_update_window_end (struct window *w, bool cursor_on_p,
607 bool mouse_face_overwritten_p)
619{ 608{
620 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
621
622 if (!w->pseudo_window_p) 609 if (!w->pseudo_window_p)
623 { 610 {
624 block_input (); 611 block_input ();
625 612
626 if (cursor_on_p) 613 if (cursor_on_p)
627 display_and_set_cursor (w, 1, output_cursor.hpos, 614 display_and_set_cursor (w, 1,
628 output_cursor.vpos, 615 w->output_cursor.hpos, w->output_cursor.vpos,
629 output_cursor.x, output_cursor.y); 616 w->output_cursor.x, w->output_cursor.y);
630 617
631 if (draw_window_fringes (w, 1)) 618 if (draw_window_fringes (w, 1))
632 x_draw_vertical_border (w); 619 x_draw_vertical_border (w);
@@ -637,13 +624,7 @@ x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritt
637 /* If a row with mouse-face was overwritten, arrange for 624 /* If a row with mouse-face was overwritten, arrange for
638 XTframe_up_to_date to redisplay the mouse highlight. */ 625 XTframe_up_to_date to redisplay the mouse highlight. */
639 if (mouse_face_overwritten_p) 626 if (mouse_face_overwritten_p)
640 { 627 reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame)));
641 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
642 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
643 hlinfo->mouse_face_window = Qnil;
644 }
645
646 updated_window = NULL;
647} 628}
648 629
649 630
@@ -664,9 +645,8 @@ x_update_end (struct frame *f)
664} 645}
665 646
666 647
667/* This function is called from various places in xdisp.c whenever a 648/* This function is called from various places in xdisp.c
668 complete update has been performed. The global variable 649 whenever a complete update has been performed. */
669 updated_window is not available here. */
670 650
671static void 651static void
672XTframe_up_to_date (struct frame *f) 652XTframe_up_to_date (struct frame *f)
@@ -678,15 +658,13 @@ XTframe_up_to_date (struct frame *f)
678 658
679/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay 659/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
680 arrow bitmaps, or clear the fringes if no bitmaps are required 660 arrow bitmaps, or clear the fringes if no bitmaps are required
681 before DESIRED_ROW is made current. The window being updated is 661 before DESIRED_ROW is made current. This function is called from
682 found in updated_window. This function It is called from
683 update_window_line only if it is known that there are differences 662 update_window_line only if it is known that there are differences
684 between bitmaps to be drawn between current row and DESIRED_ROW. */ 663 between bitmaps to be drawn between current row and DESIRED_ROW. */
685 664
686static void 665static void
687x_after_update_window_line (struct glyph_row *desired_row) 666x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
688{ 667{
689 struct window *w = updated_window;
690 struct frame *f; 668 struct frame *f;
691 int width, height; 669 int width, height;
692 670
@@ -697,7 +675,7 @@ x_after_update_window_line (struct glyph_row *desired_row)
697 675
698 /* When a window has disappeared, make sure that no rest of 676 /* When a window has disappeared, make sure that no rest of
699 full-width rows stays visible in the internal border. Could 677 full-width rows stays visible in the internal border. Could
700 check here if updated_window is the leftmost/rightmost window, 678 check here if updated window is the leftmost/rightmost window,
701 but I guess it's not worth doing since vertically split windows 679 but I guess it's not worth doing since vertically split windows
702 are almost never used, internal border is rarely set, and the 680 are almost never used, internal border is rarely set, and the
703 overhead is very small. */ 681 overhead is very small. */
@@ -713,10 +691,10 @@ x_after_update_window_line (struct glyph_row *desired_row)
713 691
714 block_input (); 692 block_input ();
715 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 693 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
716 0, y, width, height, False); 694 0, y, width, height);
717 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 695 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
718 FRAME_PIXEL_WIDTH (f) - width, 696 FRAME_PIXEL_WIDTH (f) - width,
719 y, width, height, False); 697 y, width, height);
720 unblock_input (); 698 unblock_input ();
721 } 699 }
722} 700}
@@ -731,7 +709,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
731 struct face *face = p->face; 709 struct face *face = p->face;
732 710
733 /* Must clip because of partially visible lines. */ 711 /* Must clip because of partially visible lines. */
734 x_clip_to_row (w, row, -1, gc); 712 x_clip_to_row (w, row, ANY_AREA, gc);
735 713
736 if (!p->overlay_p) 714 if (!p->overlay_p)
737 { 715 {
@@ -848,27 +826,6 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
848 XSetClipMask (display, gc, None); 826 XSetClipMask (display, gc, None);
849} 827}
850 828
851
852
853/* This is called when starting Emacs and when restarting after
854 suspend. When starting Emacs, no X window is mapped. And nothing
855 must be done to Emacs's own window if it is suspended (though that
856 rarely happens). */
857
858static void
859XTset_terminal_modes (struct terminal *terminal)
860{
861}
862
863/* This is called when exiting or suspending Emacs. Exiting will make
864 the X-windows go away, and suspending requires no action. */
865
866static void
867XTreset_terminal_modes (struct terminal *terminal)
868{
869}
870
871
872/*********************************************************************** 829/***********************************************************************
873 Glyph display 830 Glyph display
874 ***********************************************************************/ 831 ***********************************************************************/
@@ -1374,7 +1331,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1374 } 1331 }
1375 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE) 1332 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1376 { 1333 {
1377 sprintf ((char *) buf, "%0*X", 1334 sprintf (buf, "%0*X",
1378 glyph->u.glyphless.ch < 0x10000 ? 4 : 6, 1335 glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
1379 glyph->u.glyphless.ch); 1336 glyph->u.glyphless.ch);
1380 str = buf; 1337 str = buf;
@@ -2983,10 +2940,10 @@ x_delete_glyphs (struct frame *f, register int n)
2983 If they are <= 0, this is probably an error. */ 2940 If they are <= 0, this is probably an error. */
2984 2941
2985void 2942void
2986x_clear_area (Display *dpy, Window window, int x, int y, int width, int height, int exposures) 2943x_clear_area (Display *dpy, Window window, int x, int y, int width, int height)
2987{ 2944{
2988 eassert (width > 0 && height > 0); 2945 eassert (width > 0 && height > 0);
2989 XClearArea (dpy, window, x, y, width, height, exposures); 2946 XClearArea (dpy, window, x, y, width, height, False);
2990} 2947}
2991 2948
2992 2949
@@ -2998,11 +2955,7 @@ x_clear_frame (struct frame *f)
2998 /* Clearing the frame will erase any cursor, so mark them all as no 2955 /* Clearing the frame will erase any cursor, so mark them all as no
2999 longer visible. */ 2956 longer visible. */
3000 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); 2957 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
3001 output_cursor.hpos = output_cursor.vpos = 0;
3002 output_cursor.x = -1;
3003 2958
3004 /* We don't set the output cursor here because there will always
3005 follow an explicit cursor_to. */
3006 block_input (); 2959 block_input ();
3007 2960
3008 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 2961 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
@@ -3127,22 +3080,22 @@ XTflash (struct frame *f)
3127 x_flush (f); 3080 x_flush (f);
3128 3081
3129 { 3082 {
3130 EMACS_TIME delay = make_emacs_time (0, 150 * 1000 * 1000); 3083 struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
3131 EMACS_TIME wakeup = add_emacs_time (current_emacs_time (), delay); 3084 struct timespec wakeup = timespec_add (current_timespec (), delay);
3132 3085
3133 /* Keep waiting until past the time wakeup or any input gets 3086 /* Keep waiting until past the time wakeup or any input gets
3134 available. */ 3087 available. */
3135 while (! detect_input_pending ()) 3088 while (! detect_input_pending ())
3136 { 3089 {
3137 EMACS_TIME current = current_emacs_time (); 3090 struct timespec current = current_timespec ();
3138 EMACS_TIME timeout; 3091 struct timespec timeout;
3139 3092
3140 /* Break if result would not be positive. */ 3093 /* Break if result would not be positive. */
3141 if (EMACS_TIME_LE (wakeup, current)) 3094 if (timespec_cmp (wakeup, current) <= 0)
3142 break; 3095 break;
3143 3096
3144 /* How long `select' should wait. */ 3097 /* How long `select' should wait. */
3145 timeout = make_emacs_time (0, 10 * 1000 * 1000); 3098 timeout = make_timespec (0, 10 * 1000 * 1000);
3146 3099
3147 /* Try to wait that long--but we might wake up sooner. */ 3100 /* Try to wait that long--but we might wake up sooner. */
3148 pselect (0, NULL, NULL, NULL, &timeout, NULL); 3101 pselect (0, NULL, NULL, NULL, &timeout, NULL);
@@ -3228,20 +3181,6 @@ XTring_bell (struct frame *f)
3228 } 3181 }
3229} 3182}
3230 3183
3231
3232/* Specify how many text lines, from the top of the window,
3233 should be affected by insert-lines and delete-lines operations.
3234 This, and those operations, are used only within an update
3235 that is bounded by calls to x_update_begin and x_update_end. */
3236
3237static void
3238XTset_terminal_window (struct frame *f, int n)
3239{
3240 /* This function intentionally left blank. */
3241}
3242
3243
3244
3245/*********************************************************************** 3184/***********************************************************************
3246 Line Dance 3185 Line Dance
3247 ***********************************************************************/ 3186 ***********************************************************************/
@@ -3267,7 +3206,7 @@ x_scroll_run (struct window *w, struct run *run)
3267 /* Get frame-relative bounding box of the text display area of W, 3206 /* Get frame-relative bounding box of the text display area of W,
3268 without mode lines. Include in this box the left and right 3207 without mode lines. Include in this box the left and right
3269 fringe of W. */ 3208 fringe of W. */
3270 window_box (w, -1, &x, &y, &width, &height); 3209 window_box (w, ANY_AREA, &x, &y, &width, &height);
3271 3210
3272#ifdef USE_TOOLKIT_SCROLL_BARS 3211#ifdef USE_TOOLKIT_SCROLL_BARS
3273 /* If the fringe is adjacent to the left (right) scroll bar of a 3212 /* If the fringe is adjacent to the left (right) scroll bar of a
@@ -3323,7 +3262,6 @@ x_scroll_run (struct window *w, struct run *run)
3323 block_input (); 3262 block_input ();
3324 3263
3325 /* Cursor off. Will be switched on again in x_update_window_end. */ 3264 /* Cursor off. Will be switched on again in x_update_window_end. */
3326 updated_window = w;
3327 x_clear_cursor (w); 3265 x_clear_cursor (w);
3328 3266
3329 XCopyArea (FRAME_X_DISPLAY (f), 3267 XCopyArea (FRAME_X_DISPLAY (f),
@@ -3784,7 +3722,6 @@ construct_mouse_click (struct input_event *result, XButtonEvent *event, struct f
3784 return Qnil; 3722 return Qnil;
3785} 3723}
3786 3724
3787
3788/* Function to report a mouse movement to the mainstream Emacs code. 3725/* Function to report a mouse movement to the mainstream Emacs code.
3789 The input handler calls this. 3726 The input handler calls this.
3790 3727
@@ -4204,9 +4141,9 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
4204 scroll_bar_end_scroll, 0, 0); 4141 scroll_bar_end_scroll, 0, 0);
4205 w = XWINDOW (window_being_scrolled); 4142 w = XWINDOW (window_being_scrolled);
4206 4143
4207 if (!NILP (XSCROLL_BAR (w->vertical_scroll_bar)->dragging)) 4144 if (XSCROLL_BAR (w->vertical_scroll_bar)->dragging != -1)
4208 { 4145 {
4209 XSCROLL_BAR (w->vertical_scroll_bar)->dragging = Qnil; 4146 XSCROLL_BAR (w->vertical_scroll_bar)->dragging = -1;
4210 /* The thumb size is incorrect while dragging: fix it. */ 4147 /* The thumb size is incorrect while dragging: fix it. */
4211 set_vertical_scroll_bar (w); 4148 set_vertical_scroll_bar (w);
4212 } 4149 }
@@ -4337,39 +4274,39 @@ x_scroll_bar_to_input_event (XEvent *event, struct input_event *ievent)
4337static void 4274static void
4338xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) 4275xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4339{ 4276{
4340 struct scroll_bar *bar = (struct scroll_bar *) client_data; 4277 struct scroll_bar *bar = client_data;
4341 XmScrollBarCallbackStruct *cs = (XmScrollBarCallbackStruct *) call_data; 4278 XmScrollBarCallbackStruct *cs = call_data;
4342 int part = -1, whole = 0, portion = 0; 4279 int part = -1, whole = 0, portion = 0;
4343 4280
4344 switch (cs->reason) 4281 switch (cs->reason)
4345 { 4282 {
4346 case XmCR_DECREMENT: 4283 case XmCR_DECREMENT:
4347 bar->dragging = Qnil; 4284 bar->dragging = -1;
4348 part = scroll_bar_up_arrow; 4285 part = scroll_bar_up_arrow;
4349 break; 4286 break;
4350 4287
4351 case XmCR_INCREMENT: 4288 case XmCR_INCREMENT:
4352 bar->dragging = Qnil; 4289 bar->dragging = -1;
4353 part = scroll_bar_down_arrow; 4290 part = scroll_bar_down_arrow;
4354 break; 4291 break;
4355 4292
4356 case XmCR_PAGE_DECREMENT: 4293 case XmCR_PAGE_DECREMENT:
4357 bar->dragging = Qnil; 4294 bar->dragging = -1;
4358 part = scroll_bar_above_handle; 4295 part = scroll_bar_above_handle;
4359 break; 4296 break;
4360 4297
4361 case XmCR_PAGE_INCREMENT: 4298 case XmCR_PAGE_INCREMENT:
4362 bar->dragging = Qnil; 4299 bar->dragging = -1;
4363 part = scroll_bar_below_handle; 4300 part = scroll_bar_below_handle;
4364 break; 4301 break;
4365 4302
4366 case XmCR_TO_TOP: 4303 case XmCR_TO_TOP:
4367 bar->dragging = Qnil; 4304 bar->dragging = -1;
4368 part = scroll_bar_to_top; 4305 part = scroll_bar_to_top;
4369 break; 4306 break;
4370 4307
4371 case XmCR_TO_BOTTOM: 4308 case XmCR_TO_BOTTOM:
4372 bar->dragging = Qnil; 4309 bar->dragging = -1;
4373 part = scroll_bar_to_bottom; 4310 part = scroll_bar_to_bottom;
4374 break; 4311 break;
4375 4312
@@ -4385,7 +4322,7 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4385 whole = XM_SB_MAX - slider_size; 4322 whole = XM_SB_MAX - slider_size;
4386 portion = min (cs->value, whole); 4323 portion = min (cs->value, whole);
4387 part = scroll_bar_handle; 4324 part = scroll_bar_handle;
4388 bar->dragging = make_number (cs->value); 4325 bar->dragging = cs->value;
4389 } 4326 }
4390 break; 4327 break;
4391 4328
@@ -4412,12 +4349,11 @@ xg_scroll_callback (GtkRange *range,
4412 gdouble value, 4349 gdouble value,
4413 gpointer user_data) 4350 gpointer user_data)
4414{ 4351{
4415 struct scroll_bar *bar = (struct scroll_bar *) user_data; 4352 struct scroll_bar *bar = user_data;
4416 gdouble position; 4353 gdouble position;
4417 int part = -1, whole = 0, portion = 0; 4354 int part = -1, whole = 0, portion = 0;
4418 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range)); 4355 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
4419 struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (range), 4356 struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
4420 XG_FRAME_DATA);
4421 4357
4422 if (xg_ignore_gtk_scrollbar) return FALSE; 4358 if (xg_ignore_gtk_scrollbar) return FALSE;
4423 position = gtk_adjustment_get_value (adj); 4359 position = gtk_adjustment_get_value (adj);
@@ -4434,24 +4370,24 @@ xg_scroll_callback (GtkRange *range,
4434 whole = gtk_adjustment_get_upper (adj) - 4370 whole = gtk_adjustment_get_upper (adj) -
4435 gtk_adjustment_get_page_size (adj); 4371 gtk_adjustment_get_page_size (adj);
4436 portion = min ((int)position, whole); 4372 portion = min ((int)position, whole);
4437 bar->dragging = make_number ((int)portion); 4373 bar->dragging = portion;
4438 } 4374 }
4439 break; 4375 break;
4440 case GTK_SCROLL_STEP_BACKWARD: 4376 case GTK_SCROLL_STEP_BACKWARD:
4441 part = scroll_bar_up_arrow; 4377 part = scroll_bar_up_arrow;
4442 bar->dragging = Qnil; 4378 bar->dragging = -1;
4443 break; 4379 break;
4444 case GTK_SCROLL_STEP_FORWARD: 4380 case GTK_SCROLL_STEP_FORWARD:
4445 part = scroll_bar_down_arrow; 4381 part = scroll_bar_down_arrow;
4446 bar->dragging = Qnil; 4382 bar->dragging = -1;
4447 break; 4383 break;
4448 case GTK_SCROLL_PAGE_BACKWARD: 4384 case GTK_SCROLL_PAGE_BACKWARD:
4449 part = scroll_bar_above_handle; 4385 part = scroll_bar_above_handle;
4450 bar->dragging = Qnil; 4386 bar->dragging = -1;
4451 break; 4387 break;
4452 case GTK_SCROLL_PAGE_FORWARD: 4388 case GTK_SCROLL_PAGE_FORWARD:
4453 part = scroll_bar_below_handle; 4389 part = scroll_bar_below_handle;
4454 bar->dragging = Qnil; 4390 bar->dragging = -1;
4455 break; 4391 break;
4456 } 4392 }
4457 4393
@@ -4465,15 +4401,15 @@ xg_scroll_callback (GtkRange *range,
4465 return FALSE; 4401 return FALSE;
4466} 4402}
4467 4403
4468/* Callback for button release. Sets dragging to Qnil when dragging is done. */ 4404/* Callback for button release. Sets dragging to -1 when dragging is done. */
4469 4405
4470static gboolean 4406static gboolean
4471xg_end_scroll_callback (GtkWidget *widget, 4407xg_end_scroll_callback (GtkWidget *widget,
4472 GdkEventButton *event, 4408 GdkEventButton *event,
4473 gpointer user_data) 4409 gpointer user_data)
4474{ 4410{
4475 struct scroll_bar *bar = (struct scroll_bar *) user_data; 4411 struct scroll_bar *bar = user_data;
4476 bar->dragging = Qnil; 4412 bar->dragging = -1;
4477 if (WINDOWP (window_being_scrolled)) 4413 if (WINDOWP (window_being_scrolled))
4478 { 4414 {
4479 x_send_scroll_bar_event (window_being_scrolled, 4415 x_send_scroll_bar_event (window_being_scrolled,
@@ -4495,8 +4431,9 @@ xg_end_scroll_callback (GtkWidget *widget,
4495static void 4431static void
4496xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data) 4432xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4497{ 4433{
4498 struct scroll_bar *bar = (struct scroll_bar *) client_data; 4434 struct scroll_bar *bar = client_data;
4499 float top = *(float *) call_data; 4435 float *top_addr = call_data;
4436 float top = *top_addr;
4500 float shown; 4437 float shown;
4501 int whole, portion, height; 4438 int whole, portion, height;
4502 int part; 4439 int part;
@@ -4520,7 +4457,7 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4520 part = scroll_bar_handle; 4457 part = scroll_bar_handle;
4521 4458
4522 window_being_scrolled = bar->window; 4459 window_being_scrolled = bar->window;
4523 bar->dragging = make_number (portion); 4460 bar->dragging = portion;
4524 last_scroll_bar_part = part; 4461 last_scroll_bar_part = part;
4525 x_send_scroll_bar_event (bar->window, part, portion, whole); 4462 x_send_scroll_bar_event (bar->window, part, portion, whole);
4526} 4463}
@@ -4537,9 +4474,9 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4537static void 4474static void
4538xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data) 4475xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4539{ 4476{
4540 struct scroll_bar *bar = (struct scroll_bar *) client_data; 4477 struct scroll_bar *bar = client_data;
4541 /* The position really is stored cast to a pointer. */ 4478 /* The position really is stored cast to a pointer. */
4542 int position = (long) call_data; 4479 int position = (intptr_t) call_data;
4543 Dimension height; 4480 Dimension height;
4544 int part; 4481 int part;
4545 4482
@@ -4559,7 +4496,7 @@ xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4559 part = scroll_bar_move_ratio; 4496 part = scroll_bar_move_ratio;
4560 4497
4561 window_being_scrolled = bar->window; 4498 window_being_scrolled = bar->window;
4562 bar->dragging = Qnil; 4499 bar->dragging = -1;
4563 last_scroll_bar_part = part; 4500 last_scroll_bar_part = part;
4564 x_send_scroll_bar_event (bar->window, part, position, height); 4501 x_send_scroll_bar_event (bar->window, part, position, height);
4565} 4502}
@@ -4835,7 +4772,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
4835 shown = (float) portion / whole; 4772 shown = (float) portion / whole;
4836 } 4773 }
4837 4774
4838 if (NILP (bar->dragging)) 4775 if (bar->dragging == -1)
4839 { 4776 {
4840 int size, value; 4777 int size, value;
4841 4778
@@ -4870,7 +4807,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
4870 NULL); 4807 NULL);
4871 4808
4872 /* Massage the top+shown values. */ 4809 /* Massage the top+shown values. */
4873 if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow) 4810 if (bar->dragging == -1 || last_scroll_bar_part == scroll_bar_down_arrow)
4874 top = max (0, min (1, top)); 4811 top = max (0, min (1, top));
4875 else 4812 else
4876 top = old_top; 4813 top = old_top;
@@ -4882,7 +4819,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
4882 for `NARROWPROTO'. See s/freebsd.h for an example. */ 4819 for `NARROWPROTO'. See s/freebsd.h for an example. */
4883 if (top != old_top || shown != old_shown) 4820 if (top != old_top || shown != old_shown)
4884 { 4821 {
4885 if (NILP (bar->dragging)) 4822 if (bar->dragging == -1)
4886 XawScrollbarSetThumb (widget, top, shown); 4823 XawScrollbarSetThumb (widget, top, shown);
4887 else 4824 else
4888 { 4825 {
@@ -4947,8 +4884,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
4947 this case, no clear_frame is generated to reduce flickering. */ 4884 this case, no clear_frame is generated to reduce flickering. */
4948 if (width > 0 && height > 0) 4885 if (width > 0 && height > 0)
4949 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 4886 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4950 left, top, width, 4887 left, top, width, window_box_height (w));
4951 window_box_height (w), False);
4952 4888
4953 window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 4889 window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4954 /* Position and size of scroll bar. */ 4890 /* Position and size of scroll bar. */
@@ -4974,7 +4910,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
4974 bar->height = height; 4910 bar->height = height;
4975 bar->start = 0; 4911 bar->start = 0;
4976 bar->end = 0; 4912 bar->end = 0;
4977 bar->dragging = Qnil; 4913 bar->dragging = -1;
4978 bar->fringe_extended_p = 0; 4914 bar->fringe_extended_p = 0;
4979 4915
4980 /* Add bar to its frame's list of scroll bars. */ 4916 /* Add bar to its frame's list of scroll bars. */
@@ -5032,7 +4968,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
5032static void 4968static void
5033x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild) 4969x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild)
5034{ 4970{
5035 int dragging = ! NILP (bar->dragging); 4971 bool dragging = bar->dragging != -1;
5036 Window w = bar->x_window; 4972 Window w = bar->x_window;
5037 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 4973 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
5038 GC gc = f->output_data.x->normal_gc; 4974 GC gc = f->output_data.x->normal_gc;
@@ -5084,11 +5020,9 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
5084 zero-height areas; that means "clear to end of window." */ 5020 zero-height areas; that means "clear to end of window." */
5085 if (start > 0) 5021 if (start > 0)
5086 x_clear_area (FRAME_X_DISPLAY (f), w, 5022 x_clear_area (FRAME_X_DISPLAY (f), w,
5087 /* x, y, width, height, and exposures. */
5088 VERTICAL_SCROLL_BAR_LEFT_BORDER, 5023 VERTICAL_SCROLL_BAR_LEFT_BORDER,
5089 VERTICAL_SCROLL_BAR_TOP_BORDER, 5024 VERTICAL_SCROLL_BAR_TOP_BORDER,
5090 inside_width, start, 5025 inside_width, start);
5091 False);
5092 5026
5093 /* Change to proper foreground color if one is specified. */ 5027 /* Change to proper foreground color if one is specified. */
5094 if (f->output_data.x->scroll_bar_foreground_pixel != -1) 5028 if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -5111,12 +5045,9 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
5111 clear zero-height areas; that means "clear to end of window." */ 5045 clear zero-height areas; that means "clear to end of window." */
5112 if (end < inside_height) 5046 if (end < inside_height)
5113 x_clear_area (FRAME_X_DISPLAY (f), w, 5047 x_clear_area (FRAME_X_DISPLAY (f), w,
5114 /* x, y, width, height, and exposures. */
5115 VERTICAL_SCROLL_BAR_LEFT_BORDER, 5048 VERTICAL_SCROLL_BAR_LEFT_BORDER,
5116 VERTICAL_SCROLL_BAR_TOP_BORDER + end, 5049 VERTICAL_SCROLL_BAR_TOP_BORDER + end,
5117 inside_width, inside_height - end, 5050 inside_width, inside_height - end);
5118 False);
5119
5120 } 5051 }
5121 5052
5122 unblock_input (); 5053 unblock_input ();
@@ -5164,11 +5095,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5164 int top, height, left, sb_left, width, sb_width; 5095 int top, height, left, sb_left, width, sb_width;
5165 int window_y, window_height; 5096 int window_y, window_height;
5166#ifdef USE_TOOLKIT_SCROLL_BARS 5097#ifdef USE_TOOLKIT_SCROLL_BARS
5167 int fringe_extended_p; 5098 bool fringe_extended_p;
5168#endif 5099#endif
5169 5100
5170 /* Get window dimensions. */ 5101 /* Get window dimensions. */
5171 window_box (w, -1, 0, &window_y, 0, &window_height); 5102 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
5172 top = window_y; 5103 top = window_y;
5173 width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); 5104 width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
5174 height = window_height; 5105 height = window_height;
@@ -5197,16 +5128,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5197#endif 5128#endif
5198 5129
5199#ifdef USE_TOOLKIT_SCROLL_BARS 5130#ifdef USE_TOOLKIT_SCROLL_BARS
5200 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) 5131 fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w);
5201 fringe_extended_p = (WINDOW_LEFTMOST_P (w)
5202 && WINDOW_LEFT_FRINGE_WIDTH (w)
5203 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5204 || WINDOW_LEFT_MARGIN_COLS (w) == 0));
5205 else
5206 fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
5207 && WINDOW_RIGHT_FRINGE_WIDTH (w)
5208 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5209 || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
5210#endif 5132#endif
5211 5133
5212 /* Does the scroll bar exist yet? */ 5134 /* Does the scroll bar exist yet? */
@@ -5218,11 +5140,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5218#ifdef USE_TOOLKIT_SCROLL_BARS 5140#ifdef USE_TOOLKIT_SCROLL_BARS
5219 if (fringe_extended_p) 5141 if (fringe_extended_p)
5220 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5142 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5221 sb_left, top, sb_width, height, False); 5143 sb_left, top, sb_width, height);
5222 else 5144 else
5223#endif 5145#endif
5224 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5146 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5225 left, top, width, height, False); 5147 left, top, width, height);
5226 unblock_input (); 5148 unblock_input ();
5227 } 5149 }
5228 5150
@@ -5257,10 +5179,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5257 { 5179 {
5258 if (fringe_extended_p) 5180 if (fringe_extended_p)
5259 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5181 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5260 sb_left, top, sb_width, height, False); 5182 sb_left, top, sb_width, height);
5261 else 5183 else
5262 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5184 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5263 left, top, width, height, False); 5185 left, top, width, height);
5264 } 5186 }
5265#ifdef USE_GTK 5187#ifdef USE_GTK
5266 xg_update_scrollbar_pos (f, 5188 xg_update_scrollbar_pos (f,
@@ -5284,12 +5206,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5284 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM) 5206 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM)
5285 { 5207 {
5286 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5208 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5287 left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, 5209 left, top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, height);
5288 height, False);
5289 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5210 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5290 left + width - VERTICAL_SCROLL_BAR_WIDTH_TRIM, 5211 left + width - VERTICAL_SCROLL_BAR_WIDTH_TRIM,
5291 top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, 5212 top, VERTICAL_SCROLL_BAR_WIDTH_TRIM, height);
5292 height, False);
5293 } 5213 }
5294 5214
5295 /* Clear areas not covered by the scroll bar because it's not as 5215 /* Clear areas not covered by the scroll bar because it's not as
@@ -5303,11 +5223,10 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5303 { 5223 {
5304 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) 5224 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
5305 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5225 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5306 left + area_width - rest, top, 5226 left + area_width - rest, top, rest, height);
5307 rest, height, False);
5308 else 5227 else
5309 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 5228 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5310 left, top, rest, height, False); 5229 left, top, rest, height);
5311 } 5230 }
5312 } 5231 }
5313 5232
@@ -5342,7 +5261,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5342#else /* not USE_TOOLKIT_SCROLL_BARS */ 5261#else /* not USE_TOOLKIT_SCROLL_BARS */
5343 /* Set the scroll bar's current state, unless we're currently being 5262 /* Set the scroll bar's current state, unless we're currently being
5344 dragged. */ 5263 dragged. */
5345 if (NILP (bar->dragging)) 5264 if (bar->dragging == -1)
5346 { 5265 {
5347 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height); 5266 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
5348 5267
@@ -5552,14 +5471,13 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e
5552 5471
5553#ifndef USE_TOOLKIT_SCROLL_BARS 5472#ifndef USE_TOOLKIT_SCROLL_BARS
5554 /* If the user has released the handle, set it to its final position. */ 5473 /* If the user has released the handle, set it to its final position. */
5555 if (event->type == ButtonRelease 5474 if (event->type == ButtonRelease && bar->dragging != -1)
5556 && ! NILP (bar->dragging))
5557 { 5475 {
5558 int new_start = y - XINT (bar->dragging); 5476 int new_start = y - XINT (bar->dragging);
5559 int new_end = new_start + bar->end - bar->start; 5477 int new_end = new_start + bar->end - bar->start;
5560 5478
5561 x_scroll_bar_set_handle (bar, new_start, new_end, 0); 5479 x_scroll_bar_set_handle (bar, new_start, new_end, 0);
5562 bar->dragging = Qnil; 5480 bar->dragging = -1;
5563 } 5481 }
5564#endif 5482#endif
5565 5483
@@ -5576,20 +5494,20 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e
5576 mark bits. */ 5494 mark bits. */
5577 5495
5578static void 5496static void
5579x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event) 5497x_scroll_bar_note_movement (struct scroll_bar *bar, XMotionEvent *event)
5580{ 5498{
5581 struct frame *f = XFRAME (XWINDOW (bar->window)->frame); 5499 struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
5582 5500
5583 last_mouse_movement_time = event->xmotion.time; 5501 last_mouse_movement_time = event->time;
5584 5502
5585 f->mouse_moved = 1; 5503 f->mouse_moved = 1;
5586 XSETVECTOR (last_mouse_scroll_bar, bar); 5504 XSETVECTOR (last_mouse_scroll_bar, bar);
5587 5505
5588 /* If we're dragging the bar, display it. */ 5506 /* If we're dragging the bar, display it. */
5589 if (! NILP (bar->dragging)) 5507 if (bar->dragging != -1)
5590 { 5508 {
5591 /* Where should the handle be now? */ 5509 /* Where should the handle be now? */
5592 int new_start = event->xmotion.y - XINT (bar->dragging); 5510 int new_start = event->y - bar->dragging;
5593 5511
5594 if (new_start != bar->start) 5512 if (new_start != bar->start)
5595 { 5513 {
@@ -5641,8 +5559,8 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
5641 5559
5642 win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER; 5560 win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
5643 5561
5644 if (! NILP (bar->dragging)) 5562 if (bar->dragging != -1)
5645 win_y -= XINT (bar->dragging); 5563 win_y -= bar->dragging;
5646 5564
5647 if (win_y < 0) 5565 if (win_y < 0)
5648 win_y = 0; 5566 win_y = 0;
@@ -5652,7 +5570,7 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
5652 *fp = f; 5570 *fp = f;
5653 *bar_window = bar->window; 5571 *bar_window = bar->window;
5654 5572
5655 if (! NILP (bar->dragging)) 5573 if (bar->dragging != -1)
5656 *part = scroll_bar_handle; 5574 *part = scroll_bar_handle;
5657 else if (win_y < bar->start) 5575 else if (win_y < bar->start)
5658 *part = scroll_bar_above_handle; 5576 *part = scroll_bar_above_handle;
@@ -5697,18 +5615,7 @@ x_scroll_bar_clear (struct frame *f)
5697#endif /* not USE_TOOLKIT_SCROLL_BARS */ 5615#endif /* not USE_TOOLKIT_SCROLL_BARS */
5698} 5616}
5699 5617
5700 5618#ifdef ENABLE_CHECKING
5701/* The main X event-reading loop - XTread_socket. */
5702
5703/* This holds the state XLookupString needs to implement dead keys
5704 and other tricks known as "compose processing". _X Window System_
5705 says that a portable program can't use this, but Stephen Gildea assures
5706 me that letting the compiler initialize it to zeros will work okay.
5707
5708 This must be defined outside of XTread_socket, for the same reasons
5709 given for enter_timestamp, above. */
5710
5711static XComposeStatus compose_status;
5712 5619
5713/* Record the last 100 characters stored 5620/* Record the last 100 characters stored
5714 to help debug the loss-of-chars-during-GC problem. */ 5621 to help debug the loss-of-chars-during-GC problem. */
@@ -5721,6 +5628,12 @@ static short temp_buffer[100];
5721 temp_index = 0; \ 5628 temp_index = 0; \
5722 temp_buffer[temp_index++] = (keysym) 5629 temp_buffer[temp_index++] = (keysym)
5723 5630
5631#else /* not ENABLE_CHECKING */
5632
5633#define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
5634
5635#endif /* ENABLE_CHECKING */
5636
5724/* Set this to nonzero to fake an "X I/O error" 5637/* Set this to nonzero to fake an "X I/O error"
5725 on a particular display. */ 5638 on a particular display. */
5726 5639
@@ -5858,6 +5771,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
5858 struct coding_system coding; 5771 struct coding_system coding;
5859 XEvent event = *eventptr; 5772 XEvent event = *eventptr;
5860 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; 5773 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
5774 /* This holds the state XLookupString needs to implement dead keys
5775 and other tricks known as "compose processing". _X Window System_
5776 says that a portable program can't use this, but Stephen Gildea assures
5777 me that letting the compiler initialize it to zeros will work okay. */
5778 static XComposeStatus compose_status;
5779
5861 USE_SAFE_ALLOCA; 5780 USE_SAFE_ALLOCA;
5862 5781
5863 *finish = X_EVENT_NORMAL; 5782 *finish = X_EVENT_NORMAL;
@@ -6151,11 +6070,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6151 { 6070 {
6152#ifdef USE_GTK 6071#ifdef USE_GTK
6153 /* This seems to be needed for GTK 2.6. */ 6072 /* This seems to be needed for GTK 2.6. */
6154 x_clear_area (event.xexpose.display, 6073 x_clear_area (event.xexpose.display,
6155 event.xexpose.window, 6074 event.xexpose.window,
6156 event.xexpose.x, event.xexpose.y, 6075 event.xexpose.x, event.xexpose.y,
6157 event.xexpose.width, event.xexpose.height, 6076 event.xexpose.width, event.xexpose.height);
6158 FALSE);
6159#endif 6077#endif
6160 if (!FRAME_VISIBLE_P (f)) 6078 if (!FRAME_VISIBLE_P (f))
6161 { 6079 {
@@ -6227,7 +6145,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6227 6145
6228 case UnmapNotify: 6146 case UnmapNotify:
6229 /* Redo the mouse-highlight after the tooltip has gone. */ 6147 /* Redo the mouse-highlight after the tooltip has gone. */
6230 if (event.xmap.window == tip_window) 6148 if (event.xunmap.window == tip_window)
6231 { 6149 {
6232 tip_window = 0; 6150 tip_window = 0;
6233 redo_mouse_highlight (); 6151 redo_mouse_highlight ();
@@ -6731,18 +6649,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6731 /* Generate SELECT_WINDOW_EVENTs when needed. 6649 /* Generate SELECT_WINDOW_EVENTs when needed.
6732 Don't let popup menus influence things (bug#1261). */ 6650 Don't let popup menus influence things (bug#1261). */
6733 if (!NILP (Vmouse_autoselect_window) && !popup_activated ()) 6651 if (!NILP (Vmouse_autoselect_window) && !popup_activated ())
6734 { 6652 {
6735 Lisp_Object window; 6653 static Lisp_Object last_mouse_window;
6736 6654 Lisp_Object window = window_from_coordinates
6737 window = window_from_coordinates (f, 6655 (f, event.xmotion.x, event.xmotion.y, 0, 0);
6738 event.xmotion.x, event.xmotion.y, 6656
6739 0, 0); 6657 /* Window will be selected only when it is not selected now and
6740 6658 last mouse movement event was not in it. Minibuffer window
6741 /* Window will be selected only when it is not selected now and 6659 will be selected only when it is active. */
6742 last mouse movement event was not in it. Minibuffer window 6660 if (WINDOWP (window)
6743 will be selected only when it is active. */ 6661 && !EQ (window, last_mouse_window)
6744 if (WINDOWP (window)
6745 && !EQ (window, last_window)
6746 && !EQ (window, selected_window) 6662 && !EQ (window, selected_window)
6747 /* For click-to-focus window managers 6663 /* For click-to-focus window managers
6748 create event iff we don't leave the 6664 create event iff we don't leave the
@@ -6750,13 +6666,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6750 && (focus_follows_mouse 6666 && (focus_follows_mouse
6751 || (EQ (XWINDOW (window)->frame, 6667 || (EQ (XWINDOW (window)->frame,
6752 XWINDOW (selected_window)->frame)))) 6668 XWINDOW (selected_window)->frame))))
6753 { 6669 {
6754 inev.ie.kind = SELECT_WINDOW_EVENT; 6670 inev.ie.kind = SELECT_WINDOW_EVENT;
6755 inev.ie.frame_or_window = window; 6671 inev.ie.frame_or_window = window;
6756 } 6672 }
6757 6673 /* Remember the last window where we saw the mouse. */
6758 last_window=window; 6674 last_mouse_window = window;
6759 } 6675 }
6760 if (!note_mouse_movement (f, &event.xmotion)) 6676 if (!note_mouse_movement (f, &event.xmotion))
6761 help_echo_string = previous_help_echo_string; 6677 help_echo_string = previous_help_echo_string;
6762 } 6678 }
@@ -6768,7 +6684,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6768 event.xmotion.window); 6684 event.xmotion.window);
6769 6685
6770 if (bar) 6686 if (bar)
6771 x_scroll_bar_note_movement (bar, &event); 6687 x_scroll_bar_note_movement (bar, &event.xmotion);
6772#endif /* USE_TOOLKIT_SCROLL_BARS */ 6688#endif /* USE_TOOLKIT_SCROLL_BARS */
6773 6689
6774 /* If we move outside the frame, then we're 6690 /* If we move outside the frame, then we're
@@ -7200,7 +7116,8 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
7200 mode lines must be clipped to the whole window. */ 7116 mode lines must be clipped to the whole window. */
7201 7117
7202static void 7118static void
7203x_clip_to_row (struct window *w, struct glyph_row *row, int area, GC gc) 7119x_clip_to_row (struct window *w, struct glyph_row *row,
7120 enum glyph_row_area area, GC gc)
7204{ 7121{
7205 struct frame *f = XFRAME (WINDOW_FRAME (w)); 7122 struct frame *f = XFRAME (WINDOW_FRAME (w));
7206 XRectangle clip_rect; 7123 XRectangle clip_rect;
@@ -7377,8 +7294,7 @@ x_define_frame_cursor (struct frame *f, Cursor cursor)
7377static void 7294static void
7378x_clear_frame_area (struct frame *f, int x, int y, int width, int height) 7295x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
7379{ 7296{
7380 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 7297 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), x, y, width, height);
7381 x, y, width, height, False);
7382#ifdef USE_GTK 7298#ifdef USE_GTK
7383 /* Must queue a redraw, because scroll bars might have been cleared. */ 7299 /* Must queue a redraw, because scroll bars might have been cleared. */
7384 if (FRAME_GTK_WIDGET (f)) 7300 if (FRAME_GTK_WIDGET (f))
@@ -7390,7 +7306,9 @@ x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
7390/* RIF: Draw cursor on window W. */ 7306/* RIF: Draw cursor on window W. */
7391 7307
7392static void 7308static void
7393x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, int y, int cursor_type, int cursor_width, int on_p, int active_p) 7309x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
7310 int y, enum text_cursor_kinds cursor_type,
7311 int cursor_width, bool on_p, bool active_p)
7394{ 7312{
7395 struct frame *f = XFRAME (WINDOW_FRAME (w)); 7313 struct frame *f = XFRAME (WINDOW_FRAME (w));
7396 7314
@@ -7817,9 +7735,8 @@ static int
7817x_error_handler (Display *display, XErrorEvent *event) 7735x_error_handler (Display *display, XErrorEvent *event)
7818{ 7736{
7819#if defined USE_GTK && defined HAVE_GTK3 7737#if defined USE_GTK && defined HAVE_GTK3
7820 if (event->error_code == BadMatch 7738 if ((event->error_code == BadMatch || event->error_code == BadWindow)
7821 && event->request_code == X_SetInputFocus 7739 && event->request_code == X_SetInputFocus)
7822 && event->minor_code == 0)
7823 { 7740 {
7824 return 0; 7741 return 0;
7825 } 7742 }
@@ -8090,13 +8007,10 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
8090 { 8007 {
8091#ifdef HAVE_X11R6_XIM 8008#ifdef HAVE_X11R6_XIM
8092 struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst); 8009 struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst);
8093 ptrdiff_t len;
8094 8010
8095 dpyinfo->xim_callback_data = xim_inst; 8011 dpyinfo->xim_callback_data = xim_inst;
8096 xim_inst->dpyinfo = dpyinfo; 8012 xim_inst->dpyinfo = dpyinfo;
8097 len = strlen (resource_name); 8013 xim_inst->resource_name = xstrdup (resource_name);
8098 xim_inst->resource_name = xmalloc (len + 1);
8099 memcpy (xim_inst->resource_name, resource_name, len + 1);
8100 XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb, 8014 XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
8101 resource_name, emacs_class, 8015 resource_name, emacs_class,
8102 xim_instantiate_callback, 8016 xim_instantiate_callback,
@@ -8202,9 +8116,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
8202 8116
8203 if (change_gravity > 0) 8117 if (change_gravity > 0)
8204 { 8118 {
8205 FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
8206 FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
8207
8208 f->top_pos = yoff; 8119 f->top_pos = yoff;
8209 f->left_pos = xoff; 8120 f->left_pos = xoff;
8210 f->size_hint_flags &= ~ (XNegative | YNegative); 8121 f->size_hint_flags &= ~ (XNegative | YNegative);
@@ -8703,8 +8614,8 @@ x_wait_for_event (struct frame *f, int eventtype)
8703{ 8614{
8704 int level = interrupt_input_blocked; 8615 int level = interrupt_input_blocked;
8705 8616
8706 SELECT_TYPE fds; 8617 fd_set fds;
8707 EMACS_TIME tmo, tmo_at, time_now; 8618 struct timespec tmo, tmo_at, time_now;
8708 int fd = ConnectionNumber (FRAME_X_DISPLAY (f)); 8619 int fd = ConnectionNumber (FRAME_X_DISPLAY (f));
8709 8620
8710 pending_event_wait.f = f; 8621 pending_event_wait.f = f;
@@ -8712,8 +8623,8 @@ x_wait_for_event (struct frame *f, int eventtype)
8712 8623
8713 /* Set timeout to 0.1 second. Hopefully not noticeable. 8624 /* Set timeout to 0.1 second. Hopefully not noticeable.
8714 Maybe it should be configurable. */ 8625 Maybe it should be configurable. */
8715 tmo = make_emacs_time (0, 100 * 1000 * 1000); 8626 tmo = make_timespec (0, 100 * 1000 * 1000);
8716 tmo_at = add_emacs_time (current_emacs_time (), tmo); 8627 tmo_at = timespec_add (current_timespec (), tmo);
8717 8628
8718 while (pending_event_wait.eventtype) 8629 while (pending_event_wait.eventtype)
8719 { 8630 {
@@ -8726,11 +8637,11 @@ x_wait_for_event (struct frame *f, int eventtype)
8726 FD_ZERO (&fds); 8637 FD_ZERO (&fds);
8727 FD_SET (fd, &fds); 8638 FD_SET (fd, &fds);
8728 8639
8729 time_now = current_emacs_time (); 8640 time_now = current_timespec ();
8730 if (EMACS_TIME_LT (tmo_at, time_now)) 8641 if (timespec_cmp (tmo_at, time_now) < 0)
8731 break; 8642 break;
8732 8643
8733 tmo = sub_emacs_time (tmo_at, time_now); 8644 tmo = timespec_sub (tmo_at, time_now);
8734 if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0) 8645 if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
8735 break; /* Timeout */ 8646 break; /* Timeout */
8736 } 8647 }
@@ -9466,16 +9377,8 @@ x_free_frame_resources (struct frame *f)
9466 dpyinfo->x_focus_event_frame = 0; 9377 dpyinfo->x_focus_event_frame = 0;
9467 if (f == dpyinfo->x_highlight_frame) 9378 if (f == dpyinfo->x_highlight_frame)
9468 dpyinfo->x_highlight_frame = 0; 9379 dpyinfo->x_highlight_frame = 0;
9469
9470 if (f == hlinfo->mouse_face_mouse_frame) 9380 if (f == hlinfo->mouse_face_mouse_frame)
9471 { 9381 reset_mouse_highlight (hlinfo);
9472 hlinfo->mouse_face_beg_row
9473 = hlinfo->mouse_face_beg_col = -1;
9474 hlinfo->mouse_face_end_row
9475 = hlinfo->mouse_face_end_col = -1;
9476 hlinfo->mouse_face_window = Qnil;
9477 hlinfo->mouse_face_mouse_frame = 0;
9478 }
9479 9382
9480 unblock_input (); 9383 unblock_input ();
9481} 9384}
@@ -9847,7 +9750,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9847 struct terminal *terminal; 9750 struct terminal *terminal;
9848 struct x_display_info *dpyinfo; 9751 struct x_display_info *dpyinfo;
9849 XrmDatabase xrdb; 9752 XrmDatabase xrdb;
9850 Mouse_HLInfo *hlinfo;
9851 ptrdiff_t lim; 9753 ptrdiff_t lim;
9852 9754
9853 block_input (); 9755 block_input ();
@@ -9988,8 +9890,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9988 /* We have definitely succeeded. Record the new connection. */ 9890 /* We have definitely succeeded. Record the new connection. */
9989 9891
9990 dpyinfo = xzalloc (sizeof *dpyinfo); 9892 dpyinfo = xzalloc (sizeof *dpyinfo);
9991 hlinfo = &dpyinfo->mouse_highlight;
9992
9993 terminal = x_create_terminal (dpyinfo); 9893 terminal = x_create_terminal (dpyinfo);
9994 9894
9995 { 9895 {
@@ -10060,9 +9960,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10060 dpyinfo->display = dpy; 9960 dpyinfo->display = dpy;
10061 9961
10062 /* Set the name of the terminal. */ 9962 /* Set the name of the terminal. */
10063 terminal->name = xmalloc (SBYTES (display_name) + 1); 9963 terminal->name = xlispstrdup (display_name);
10064 memcpy (terminal->name, SSDATA (display_name), SBYTES (display_name));
10065 terminal->name[SBYTES (display_name)] = 0;
10066 9964
10067#if 0 9965#if 0
10068 XSetAfterFunction (x_current_display, x_trace_wire); 9966 XSetAfterFunction (x_current_display, x_trace_wire);
@@ -10104,33 +10002,12 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10104 select_visual (dpyinfo); 10002 select_visual (dpyinfo);
10105 dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen); 10003 dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen);
10106 dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen); 10004 dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen);
10107 dpyinfo->client_leader_window = 0;
10108 dpyinfo->grabbed = 0;
10109 dpyinfo->reference_count = 0;
10110 dpyinfo->icon_bitmap_id = -1; 10005 dpyinfo->icon_bitmap_id = -1;
10111 dpyinfo->n_fonts = 0;
10112 dpyinfo->bitmaps = 0;
10113 dpyinfo->bitmaps_size = 0;
10114 dpyinfo->bitmaps_last = 0;
10115 dpyinfo->scratch_cursor_gc = 0;
10116 hlinfo->mouse_face_mouse_frame = 0;
10117 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
10118 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
10119 hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
10120 hlinfo->mouse_face_window = Qnil;
10121 hlinfo->mouse_face_overlay = Qnil;
10122 hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
10123 hlinfo->mouse_face_defer = 0;
10124 hlinfo->mouse_face_hidden = 0;
10125 dpyinfo->x_focus_frame = 0;
10126 dpyinfo->x_focus_event_frame = 0;
10127 dpyinfo->x_highlight_frame = 0;
10128 dpyinfo->wm_type = X_WMTYPE_UNKNOWN; 10006 dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
10129 10007
10130 /* See if we can construct pixel values from RGB values. */ 10008 reset_mouse_highlight (&dpyinfo->mouse_highlight);
10131 dpyinfo->red_bits = dpyinfo->blue_bits = dpyinfo->green_bits = 0;
10132 dpyinfo->red_offset = dpyinfo->blue_offset = dpyinfo->green_offset = 0;
10133 10009
10010 /* See if we can construct pixel values from RGB values. */
10134 if (dpyinfo->visual->class == TrueColor) 10011 if (dpyinfo->visual->class == TrueColor)
10135 { 10012 {
10136 get_bits_and_offset (dpyinfo->visual->red_mask, 10013 get_bits_and_offset (dpyinfo->visual->red_mask,
@@ -10291,14 +10168,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10291 } 10168 }
10292 10169
10293 dpyinfo->x_dnd_atoms_size = 8; 10170 dpyinfo->x_dnd_atoms_size = 8;
10294 dpyinfo->x_dnd_atoms_length = 0;
10295 dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms 10171 dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
10296 * dpyinfo->x_dnd_atoms_size); 10172 * dpyinfo->x_dnd_atoms_size);
10297 10173
10298 dpyinfo->net_supported_atoms = NULL;
10299 dpyinfo->nr_net_supported_atoms = 0;
10300 dpyinfo->net_supported_window = 0;
10301
10302 connection = ConnectionNumber (dpyinfo->display); 10174 connection = ConnectionNumber (dpyinfo->display);
10303 dpyinfo->connection = connection; 10175 dpyinfo->connection = connection;
10304 dpyinfo->gray 10176 dpyinfo->gray
@@ -10491,7 +10363,7 @@ x_activate_timeout_atimer (void)
10491 block_input (); 10363 block_input ();
10492 if (!x_timeout_atimer_activated_flag) 10364 if (!x_timeout_atimer_activated_flag)
10493 { 10365 {
10494 EMACS_TIME interval = make_emacs_time (0, 100 * 1000 * 1000); 10366 struct timespec interval = make_timespec (0, 100 * 1000 * 1000);
10495 start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0); 10367 start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
10496 x_timeout_atimer_activated_flag = 1; 10368 x_timeout_atimer_activated_flag = 1;
10497 } 10369 }
@@ -10514,7 +10386,6 @@ static struct redisplay_interface x_redisplay_interface =
10514 x_after_update_window_line, 10386 x_after_update_window_line,
10515 x_update_window_begin, 10387 x_update_window_begin,
10516 x_update_window_end, 10388 x_update_window_end,
10517 x_cursor_to,
10518 x_flush, 10389 x_flush,
10519#ifdef XFlush 10390#ifdef XFlush
10520 x_flush, 10391 x_flush,
@@ -10627,11 +10498,11 @@ x_create_terminal (struct x_display_info *dpyinfo)
10627 terminal->delete_glyphs_hook = x_delete_glyphs; 10498 terminal->delete_glyphs_hook = x_delete_glyphs;
10628 terminal->ring_bell_hook = XTring_bell; 10499 terminal->ring_bell_hook = XTring_bell;
10629 terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer; 10500 terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer;
10630 terminal->reset_terminal_modes_hook = XTreset_terminal_modes; 10501 terminal->reset_terminal_modes_hook = NULL;
10631 terminal->set_terminal_modes_hook = XTset_terminal_modes; 10502 terminal->set_terminal_modes_hook = NULL;
10632 terminal->update_begin_hook = x_update_begin; 10503 terminal->update_begin_hook = x_update_begin;
10633 terminal->update_end_hook = x_update_end; 10504 terminal->update_end_hook = x_update_end;
10634 terminal->set_terminal_window_hook = XTset_terminal_window; 10505 terminal->set_terminal_window_hook = NULL;
10635 terminal->read_socket_hook = XTread_socket; 10506 terminal->read_socket_hook = XTread_socket;
10636 terminal->frame_up_to_date_hook = XTframe_up_to_date; 10507 terminal->frame_up_to_date_hook = XTframe_up_to_date;
10637 terminal->mouse_position_hook = XTmouse_position; 10508 terminal->mouse_position_hook = XTmouse_position;
diff --git a/src/xterm.h b/src/xterm.h
index 5324ef628e7..c579d342215 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -71,14 +71,13 @@ typedef GtkWidget *xt_or_gtk_widget;
71#define USE_GTK_TOOLTIP 71#define USE_GTK_TOOLTIP
72#endif 72#endif
73 73
74
75/* Bookkeeping to distinguish X versions. */
76
77
78#ifdef HAVE_X_I18N 74#ifdef HAVE_X_I18N
79#include <X11/Xlocale.h> 75#include <X11/Xlocale.h>
80#endif 76#endif
81 77
78#include "dispextern.h"
79#include "termhooks.h"
80
82#define BLACK_PIX_DEFAULT(f) BlackPixel (FRAME_X_DISPLAY (f), \ 81#define BLACK_PIX_DEFAULT(f) BlackPixel (FRAME_X_DISPLAY (f), \
83 XScreenNumberOfScreen (FRAME_X_SCREEN (f))) 82 XScreenNumberOfScreen (FRAME_X_SCREEN (f)))
84#define WHITE_PIX_DEFAULT(f) WhitePixel (FRAME_X_DISPLAY (f), \ 83#define WHITE_PIX_DEFAULT(f) WhitePixel (FRAME_X_DISPLAY (f), \
@@ -407,9 +406,6 @@ extern bool x_display_ok (const char *);
407 406
408extern void select_visual (struct x_display_info *); 407extern void select_visual (struct x_display_info *);
409 408
410
411struct font;
412
413/* Each X frame object points to its own struct x_output object 409/* Each X frame object points to its own struct x_output object
414 in the output_data.x field. The x_output structure contains 410 in the output_data.x field. The x_output structure contains
415 the information that is specific to X windows. */ 411 the information that is specific to X windows. */
@@ -630,11 +626,6 @@ struct x_output
630 int move_offset_top; 626 int move_offset_top;
631 int move_offset_left; 627 int move_offset_left;
632 628
633 /* The frame's left/top offsets before we call XMoveWindow. See
634 x_check_expected_move. */
635 int left_before_move;
636 int top_before_move;
637
638 /* Non-zero if _NET_WM_STATE_HIDDEN is set for this frame. */ 629 /* Non-zero if _NET_WM_STATE_HIDDEN is set for this frame. */
639 unsigned net_wm_state_hidden_seen : 1; 630 unsigned net_wm_state_hidden_seen : 1;
640}; 631};
@@ -810,12 +801,12 @@ struct scroll_bar
810 /* If the scroll bar handle is currently being dragged by the user, 801 /* If the scroll bar handle is currently being dragged by the user,
811 this is the number of pixels from the top of the handle to the 802 this is the number of pixels from the top of the handle to the
812 place where the user grabbed it. If the handle isn't currently 803 place where the user grabbed it. If the handle isn't currently
813 being dragged, this is Qnil. */ 804 being dragged, this is -1. */
814 Lisp_Object dragging; 805 int dragging;
815 806
816 /* 1 if the background of the fringe that is adjacent to a scroll 807 /* 1 if the background of the fringe that is adjacent to a scroll
817 bar is extended to the gap between the fringe and the bar. */ 808 bar is extended to the gap between the fringe and the bar. */
818 unsigned int fringe_extended_p : 1; 809 unsigned fringe_extended_p : 1;
819}; 810};
820 811
821/* Turning a lisp vector value into a pointer to a struct scroll_bar. */ 812/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
@@ -917,14 +908,6 @@ struct selection_input_event
917#define SELECTION_EVENT_TIME(eventp) \ 908#define SELECTION_EVENT_TIME(eventp) \
918 (((struct selection_input_event *) (eventp))->time) 909 (((struct selection_input_event *) (eventp))->time)
919 910
920
921struct window;
922struct glyph_matrix;
923struct frame;
924struct input_event;
925struct face;
926struct image;
927
928/* From xselect.c. */ 911/* From xselect.c. */
929 912
930void x_handle_selection_notify (XSelectionEvent *); 913void x_handle_selection_notify (XSelectionEvent *);
@@ -966,7 +949,7 @@ extern bool x_alloc_lighter_color_for_widget (Widget, Display *, Colormap,
966#endif 949#endif
967extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *); 950extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *);
968extern void x_query_color (struct frame *f, XColor *); 951extern void x_query_color (struct frame *f, XColor *);
969extern void x_clear_area (Display *, Window, int, int, int, int, int); 952extern void x_clear_area (Display *, Window, int, int, int, int);
970#if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK 953#if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK
971extern void x_mouse_leave (struct x_display_info *); 954extern void x_mouse_leave (struct x_display_info *);
972#endif 955#endif
@@ -1076,10 +1059,6 @@ extern Lisp_Object Qx_gtk_map_stock;
1076 1059
1077#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0) 1060#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)
1078 1061
1079
1080#define FONT_TYPE_FOR_UNIBYTE(font, ch) 0
1081#define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0
1082
1083#define STORE_XCHAR2B(chp, b1, b2) \ 1062#define STORE_XCHAR2B(chp, b1, b2) \
1084 ((chp)->byte1 = (b1), (chp)->byte2 = (b2)) 1063 ((chp)->byte1 = (b1), (chp)->byte2 = (b2))
1085 1064
@@ -1089,7 +1068,6 @@ extern Lisp_Object Qx_gtk_map_stock;
1089#define XCHAR2B_BYTE2(chp) \ 1068#define XCHAR2B_BYTE2(chp) \
1090 ((chp)->byte2) 1069 ((chp)->byte2)
1091 1070
1092
1093#define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \ 1071#define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight) \
1094 ((nr).x = (rx), \ 1072 ((nr).x = (rx), \
1095 (nr).y = (ry), \ 1073 (nr).y = (ry), \