aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Tromey2013-06-03 12:25:05 -0600
committerTom Tromey2013-06-03 12:25:05 -0600
commit68359abba96d7ec4db8aab3d3dd9cf1105c3bab5 (patch)
tree862703e7e1a1888170136a8296a5750d6b2ae2eb /src
parentcbcba8ce7f980b01c18c0fd561ef6687b1361507 (diff)
parente2d8a6f0a229b4ebe26484b892ec4f14888f58b6 (diff)
downloademacs-68359abba96d7ec4db8aab3d3dd9cf1105c3bab5.tar.gz
emacs-68359abba96d7ec4db8aab3d3dd9cf1105c3bab5.zip
merge from trunk; clean up some issues
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit21
-rw-r--r--src/ChangeLog1342
-rw-r--r--src/ChangeLog.102
-rw-r--r--src/ChangeLog.112
-rw-r--r--src/Makefile.in75
-rw-r--r--src/alloc.c129
-rw-r--r--src/blockinput.h2
-rw-r--r--src/buffer.c55
-rw-r--r--src/bytecode.c7
-rw-r--r--src/callint.c38
-rw-r--r--src/callproc.c16
-rw-r--r--src/casetab.c14
-rw-r--r--src/ccl.c2
-rw-r--r--src/cm.c4
-rw-r--r--src/coding.c409
-rw-r--r--src/coding.h2
-rw-r--r--src/data.c62
-rw-r--r--src/dbusbind.c2
-rw-r--r--src/dired.c14
-rw-r--r--src/dispextern.h50
-rw-r--r--src/dispnew.c155
-rw-r--r--src/doc.c26
-rw-r--r--src/editfns.c17
-rw-r--r--src/emacs.c15
-rw-r--r--src/emacsgtkfixed.c2
-rw-r--r--src/eval.c494
-rw-r--r--src/fileio.c117
-rw-r--r--src/filelock.c10
-rw-r--r--src/floatfns.c4
-rw-r--r--src/fns.c7
-rw-r--r--src/font.c44
-rw-r--r--src/fontset.c9
-rw-r--r--src/fontset.h3
-rw-r--r--src/frame.c199
-rw-r--r--src/frame.h92
-rw-r--r--src/fringe.c12
-rw-r--r--src/ftfont.c6
-rw-r--r--src/gfilenotify.c266
-rw-r--r--src/gtkutil.c13
-rw-r--r--src/image.c86
-rw-r--r--src/indent.c35
-rw-r--r--src/insdel.c26
-rw-r--r--src/intervals.c54
-rw-r--r--src/keyboard.c412
-rw-r--r--src/keymap.c9
-rw-r--r--src/lisp.h305
-rw-r--r--src/lread.c42
-rw-r--r--src/makefile.w32-in8
-rw-r--r--src/menu.c5
-rw-r--r--src/minibuf.c46
-rw-r--r--src/msdos.c13
-rw-r--r--src/nsfns.m762
-rw-r--r--src/nsfont.m49
-rw-r--r--src/nsimage.m4
-rw-r--r--src/nsmenu.m133
-rw-r--r--src/nsselect.m18
-rw-r--r--src/nsterm.h46
-rw-r--r--src/nsterm.m346
-rw-r--r--src/print.c94
-rw-r--r--src/process.c502
-rw-r--r--src/process.h1
-rw-r--r--src/profiler.c21
-rw-r--r--src/puresize.h4
-rw-r--r--src/regex.c398
-rw-r--r--src/regex.h2
-rw-r--r--src/search.c22
-rw-r--r--src/sysdep.c6
-rw-r--r--src/systime.h4
-rw-r--r--src/term.c2
-rw-r--r--src/termhooks.h2
-rw-r--r--src/textprop.c3
-rw-r--r--src/thread.c12
-rw-r--r--src/thread.h3
-rw-r--r--src/undo.c6
-rw-r--r--src/unexcw.c17
-rw-r--r--src/unexelf.c204
-rw-r--r--src/unexw32.c8
-rw-r--r--src/w32.c92
-rw-r--r--src/w32fns.c166
-rw-r--r--src/w32font.c4
-rw-r--r--src/w32menu.c6
-rw-r--r--src/w32term.c104
-rw-r--r--src/w32term.h14
-rw-r--r--src/window.c739
-rw-r--r--src/window.h128
-rw-r--r--src/xdisp.c451
-rw-r--r--src/xfaces.c47
-rw-r--r--src/xfns.c653
-rw-r--r--src/xgselect.c3
-rw-r--r--src/xmenu.c15
-rw-r--r--src/xselect.c14
-rw-r--r--src/xsettings.c9
-rw-r--r--src/xterm.c21
-rw-r--r--src/xterm.h27
94 files changed, 6483 insertions, 3459 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index c4604e6e2b0..1bfc293c466 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -1150,17 +1150,18 @@ Print $ assuming it is a list font (font-spec, font-entity, or font-object).
1150end 1150end
1151 1151
1152define xbacktrace 1152define xbacktrace
1153 set $bt = backtrace_list 1153 set $bt = backtrace_top ()
1154 while $bt 1154 while backtrace_p ($bt)
1155 xgettype ($bt->function) 1155 set $fun = backtrace_function ($bt)
1156 xgettype $fun
1156 if $type == Lisp_Symbol 1157 if $type == Lisp_Symbol
1157 xprintsym ($bt->function) 1158 xprintsym $fun
1158 printf " (0x%x)\n", $bt->args 1159 printf " (0x%x)\n", backtrace_args ($bt)
1159 else 1160 else
1160 xgetptr $bt->function 1161 xgetptr $fun
1161 printf "0x%x ", $ptr 1162 printf "0x%x ", $ptr
1162 if $type == Lisp_Vectorlike 1163 if $type == Lisp_Vectorlike
1163 xgetptr ($bt->function) 1164 xgetptr $fun
1164 set $size = ((struct Lisp_Vector *) $ptr)->header.size 1165 set $size = ((struct Lisp_Vector *) $ptr)->header.size
1165 if ($size & PSEUDOVECTOR_FLAG) 1166 if ($size & PSEUDOVECTOR_FLAG)
1166 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS) 1167 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
@@ -1172,7 +1173,7 @@ define xbacktrace
1172 end 1173 end
1173 echo \n 1174 echo \n
1174 end 1175 end
1175 set $bt = $bt->next 1176 set $bt = backtrace_next ($bt)
1176 end 1177 end
1177end 1178end
1178document xbacktrace 1179document xbacktrace
@@ -1220,8 +1221,8 @@ end
1220 1221
1221# Show Lisp backtrace after normal backtrace. 1222# Show Lisp backtrace after normal backtrace.
1222define hookpost-backtrace 1223define hookpost-backtrace
1223 set $bt = backtrace_list 1224 set $bt = backtrace_top ()
1224 if $bt 1225 if backtrace_p ($bt)
1225 echo \n 1226 echo \n
1226 echo Lisp Backtrace:\n 1227 echo Lisp Backtrace:\n
1227 xbacktrace 1228 xbacktrace
diff --git a/src/ChangeLog b/src/ChangeLog
index 3a2a36c0cf7..a1aa4efcc86 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,1319 @@
12013-06-03 Eli Zaretskii <eliz@gnu.org>
2
3 * w32.c (gettimeofday): Make the signature identical to prototype
4 in nt/inc/sys/time.h.
5
62013-06-03 Stefan Monnier <monnier@iro.umontreal.ca>
7
8 * eval.c (backtrace_p, backtrace_top, backtrace_next): Export them to
9 .gdbinit.
10
11 * keyboard.c (safe_run_hooks_error): Improve error message.
12
13 * data.c (pure_write_error): Add `object' argument.
14 * puresize.h (CHECK_IMPURE): Use it.
15
162013-06-03 Michael Albinus <michael.albinus@gmx.de>
17
18 * Makefile.in (NOTIFY_OBJ): New variable.
19 (base_obj): Replace inotify.o by $(NOTIFY_OBJ).
20
21 * emacs.c (main): Use HAVE_W32NOTIFY to wrap respective code.
22 Call syms_of_gfilenotify.
23
24 * gfilenotify.c: New file.
25
26 * keyboard.c (Qfile_notify): New variable. Replaces Qfile_inotify
27 and Qfile_w32notify.
28 (top): Wrap respective code by HAVE_GFILENOTIFY, HAVE_INOTIFY,
29 HAVE_W32NOTIFY and USE_FILE_NOTIFY.
30
31 * lisp.h: Declare syms_of_gfilenotify.
32
33 * termhooks.h (e): Wrap enum by USE_FILE_NOTIFY.
34
352013-06-03 Stefan Monnier <monnier@iro.umontreal.ca>
36
37 Merge the specpdl and backtrace stacks. Make the structure of the
38 specpdl entries more obvious via a tagged union of structs.
39 * lisp.h (BITS_PER_PTRDIFF_T): New constant.
40 (enum specbind_tag): New enum.
41 (struct specbinding): Make it a tagged union of structs.
42 Add a case for backtrace records.
43 (specpdl_symbol, specpdl_old_value, specpdl_where, specpdl_arg)
44 (specpdl_func, backtrace_function, backtrace_nargs, backtrace_args)
45 (backtrace_debug_on_exit): New accessors.
46 (struct backtrace): Remove.
47 (struct catchtag): Remove backlist field.
48 * data.c (let_shadows_buffer_binding_p, let_shadows_global_binding_p):
49 Move to eval.c.
50 (Flocal_variable_p): Speed up the common case where the binding is
51 already loaded.
52 * eval.c (backtrace_list): Remove.
53 (set_specpdl_symbol, set_specpdl_old_value): Remove.
54 (set_backtrace_args, set_backtrace_nargs)
55 (set_backtrace_debug_on_exit, backtrace_p, backtrace_top)
56 (backtrace_next): New functions.
57 (Fdefvaralias, Fdefvar): Adjust to new specpdl format.
58 (unwind_to_catch, internal_lisp_condition_case)
59 (internal_condition_case, internal_condition_case_1)
60 (internal_condition_case_2, internal_condition_case_n): Don't bother
61 with backtrace_list any more.
62 (Fsignal): Adjust to new backtrace format.
63 (grow_specpdl): Move up.
64 (record_in_backtrace): New function.
65 (eval_sub, Ffuncall): Use it.
66 (apply_lambda): Adjust to new backtrace format.
67 (let_shadows_buffer_binding_p, let_shadows_global_binding_p): Move from
68 data.c.
69 (specbind): Adjust to new specpdl format. Simplify.
70 (record_unwind_protect, unbind_to): Adjust to new specpdl format.
71 (Fbacktrace_debug, Fbacktrace, Fbacktrace_frame): Adjust to new
72 backtrace format.
73 (mark_backtrace): Remove.
74 (mark_specpdl, get_backtrace, backtrace_top_function): New functions.
75 * xdisp.c (redisplay_internal): Use record_in_backtrace.
76 * alloc.c (Fgarbage_collect): Use record_in_backtrace.
77 Use mark_specpdl.
78 * profiler.c (record_backtrace): Use get_backtrace.
79 (handle_profiler_signal): Use backtrace_top_function.
80 * .gdbinit (xbacktrace, hookpost-backtrace): Use new backtrace
81 accessor functions.
82
832013-06-02 Jan Djärv <jan.h.d@swipnet.se>
84
85 * process.h (catch_child_signal): Declare.
86
87 * process.c (catch_child_signal): New function.
88 (init_process_emacs): Call it.
89
90 * nsterm.m: Include process.h if NS_IMPL_GNUSTEP.
91 (ns_menu_bar_is_hidden, menu_will_open_state): Define only if
92 NS_IMPL_COCOA.
93 (x_set_cursor_type): Remove declaration.
94 (ns_update_begin): Only use r and bp if NS_IMPL_COCOA.
95 (ns_update_end, ns_focus, ns_unfocus): Remove GNUStep specific code.
96 (x_set_window_size): Remove 3 pixels from toolbar if NS_IMPL_GNUSTEP.
97 (ns_get_color): Use F suffix on float.
98 (ns_color_to_lisp, ns_query_color): Use EmacsCGFloat.
99 (ns_get_rgb_color): Remove.
100 (x_set_frame_alpha): Move view inside NS_IMPL_COCOA.
101 (note_mouse_movement): x and y are CGFloat.
102 (ns_draw_fringe_bitmap): Remove unused rowY.
103 Change #if to COCOA && >= 10_6.
104 (ns_draw_window_cursor): Remove unused overspill.
105 (ns_draw_underwave): width and x are EamcsCGFloat.
106 (ns_draw_box): thickness is CGFloat.
107 (ns_dumpglyphs_image): Change #if to COCOA && >= 10_6.
108 (ns_send_appdefined): When NS_IMPL_GNUSTEP, redirect to main thread
109 if not in main thread.
110 (ns_get_pending_menu_title, ns_check_menu_open)
111 (ns_check_pending_open_menu): Put inside #if COCOA && >= 10_5.
112 (ns_term_init): Call catch_child_signal if NS_IMPL_GNUSTEP && SIGCHLD.
113 (sendFromMainThread:): New method.
114 (changeFont:): size is CGFloat.
115 (keyDown:): Check for Delete when NS_IMPL_GNUSTEP.
116 Disable warning about permanent text.
117 (characterIndexForPoint:): Adjust return type depending on GNUStep
118 version.
119 (mouseDown:): delta is CGFloat.
120 (updateFrameSize): Remove unised variable f.
121 (initFrameFromEmacs): Move toggleButton inside NS_IMPL_COCOA.
122 Cast float to EmacsCGFloat.
123 (windowWillUseStandardFrame:defaultFrame:): Set maximized_height
124 also to -1 when restoring.
125 (windowDidExitFullScreen:): Put call to updateCollectionBehaviour
126 inside NS_IMPL_COCOA.
127 (toggleFullScreen:): Put call to toggleFullScreen inside
128 NS_IMPL_COCOA. Cast float to EmacsCGFloat.
129 (setPosition:portion:whole:): por is CGFloat.
130 (getMouseMotionPart:window:x:y:): Add F suffix to float.
131 (mouseDown:): Use CGFloat.
132 (mouseDragged:): Remove unised variable edge.
133 (EmacsDocument): Implement for NS_IMPL_GNUSTEP.
134
135 * nsterm.h (EmacsCGFloat): Typedef for OSX and GNUStep when the size
136 of CGFloat differs.
137 (EmacsApp): New variable nextappdefined. Declare sendFromMainThread
138 when NS_IMPL_GNUSTEP.
139 (EmacsDocument): Declare when NS_IMPL_GNUSTEP.
140 (EmacsView): Remove unlockFocusNeedsFlush, add windowDidMove.
141 (EmacsToolbar): Add clearAll. Add tag argument to
142 addDisplayItemWithImage.
143 (EmacsSavePanel, EmacsOpenPanel): Remove getFilename and getDirectory.
144
145 * nsselect.m (ns_get_local_selection): Remove unused variable type.
146
147 * nsmenu.m (ns_update_menubar): Make static.
148 (x_activate_menubar): Surround with ifdef NS_IMPL_COCOA
149 (fillWithWidgetValue:): Add cast to SEL for setAction.
150 (addSubmenuWithTitle:forFrame:): Add cast to SEL for action.
151 (update_frame_tool_bar): Update code for GNUStep.
152 (clearAll): New method.
153 (addDisplayItemWithImage:idx:tag:helpText:enabled:): Handle new tag
154 argument. Call insertItemWithItemIdentifier when NS_IMPL_GNUSTEP. Move
155 identifierToItem setObject and activeIdentifiers addObject before
156 call to insertItemWithItemIdentifier.
157 (validateVisibleItems): Fix indentation.
158 (toolbarAllowedItemIdentifiers:): Return activeIdentifiers.
159 (initWithContentRect:styleMask:backing:defer:): Add ClosableWindow and
160 UtilityWindow to aStyle, remove call to setStyleMask.
161
162 * nsimage.m (setXBMColor:, getPixelAtX:Y:): Use EmacsCGFloat.
163
164 * nsfont.m (ns_attribute_fvalue, ns_spec_to_descriptor)
165 (ns_charset_covers, ns_get_covering_families, nsfont_open):
166 Use F suffix on floats.
167 (ns_char_width): Returns CGFloat.
168 (ns_ascii_average_width): w is CGFloat instead of float.
169 (nsfont_draw): cbuf and c are unsigned. Cast to char* in call to
170 DPSxshow.
171 (ns_glyph_metrics): CGFloat instead of float.
172
173 * nsfns.m (x_set_foreground_color, x_set_background_color): Use
174 EmacsCGFloat.
175 (ns_implicitly_set_icon_type, Fx_create_frame): Make static, remove
176 unused variables.
177 (Fns_read_file_name): Keep track if panel is for save. Use
178 ns_filename_from_panel/ns_directory_from_panel.
179 (Fns_list_services): delegate only used for COCOA.
180 (Fns_convert_utf8_nfd_to_nfc): Remove warning for GNUStep. Just
181 return the input if GNUStep.
182 (x_screen_planes): Remove.
183 (Fxw_color_values): Use EmacsCGFloat
184 (Fns_display_monitor_attributes_list): Only get screen number for
185 Cocoa.
186 (getDirectory, getFilename): Removed from EmacsOpenPanel and
187 EmacsSavePanel.
188 (EmacsOpenPanel:ok:): Use ns_filename_from_panel and
189 ns_directory_from_panel.
190
1912013-06-01 Paul Eggert <eggert@cs.ucla.edu>
192
193 * process.c (handle_child_signal): Also use WCONTINUED.
194 This is so that list-processes doesn't mistakenly list the process
195 as stopped, when the process has actually been continued and is
196 now running.
197
1982013-05-31 Paul Eggert <eggert@cs.ucla.edu>
199
200 Don't let D-bus autolaunch mess up SIGCHLD handling (Bug#14474).
201 * xterm.c (x_term_init): Inhibit D-Bus autolaunch if D-Bus is
202 not already configured.
203
204 * fileio.c (Finsert_file_contents): Remove unused local (Bug#8447).
205
2062013-05-29 Eli Zaretskii <eliz@gnu.org>
207
208 * Makefile.in (mostlyclean): Remove *.res files.
209
2102013-05-29 Stefan Monnier <monnier@iro.umontreal.ca>
211
212 * fileio.c (Finsert_file_contents): Preserve undo info when reverting
213 a buffer (bug#8447).
214
2152013-05-27 Eli Zaretskii <eliz@gnu.org>
216
217 * xdisp.c (pos_visible_p): When CHARPOS is displayed frrom a
218 display vector, and we backtrack, handle the case that the
219 previous character position is also displayed from a display
220 vector or covered by a display string or image. (Bug#14476)
221
2222013-05-25 Jan Djärv <jan.h.d@swipnet.se>
223
224 * xfns.c (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Remove.
225 (struct MonitorInfo, free_monitors): Remove.
226 (x_make_monitor_attribute_list): Call make_monitor_attribute_list.
227 (Fx_display_monitor_attributes_list): Call make_monitor_attribute_list.
228 (syms_of_xfns): Remove DEFSYM for Qgeometry, Qworkarea, Qmm_size,
229 Qframes, Qsource.
230
231 * nsfns.m (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Remove.
232 (struct MonitorInfo, free_monitors): Remove.
233 (ns_screen_name): Make static.
234 (ns_make_monitor_attribute_list): Call make_monitor_attribute_list.
235 (syms_of_nsfns): Remove DEFSYM for Qgeometry, Qworkarea, Qmm_size,
236 Qframes, Qsource.
237
238 * frame.h (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare.
239 (struct MonitorInfo): New struct.
240 (free_monitors, make_monitor_attribute_list): Declare.
241
242 * frame.c (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource):
243 New Lisp_Object:s.
244 (free_monitors, make_monitor_attribute_list): New functions.
245 (syms_of_frame): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes,
246 Qsource.
247
2482013-05-25 Xue Fuqiao <xfq.free@gmail.com>
249
250 * callproc.c (call_process): Refine the doc string. (Bug#14045)
251
2522013-05-23 Stefan Monnier <monnier@iro.umontreal.ca>
253
254 * keyboard.c: Apply keyboard decoding only to events that come directly
255 from the tty, not from unread-command-events (bug#14368).
256 (read_event_from_main_queue): New function, extracted from read_char).
257 (read_decoded_char): Remove.
258 (read_decoded_event_from_main_queue): New function to replace it.
259 (read_char): Use it.
260 (read_key_sequence): Use read_char rather than read_decoded_char.
261
262 * keyboard.c (read_decoded_char): Don't decode under w32 (bug#14403).
263
2642013-05-22 Barry OReilly <gundaetiapo@gmail.com> (tiny change)
265
266 * casetab.c (init_casetab_once): Fix last change (bug#14424).
267
2682013-05-22 Kenichi Handa <handa@gnu.org>
269
270 The following changes are to fix the setting of
271 buffer-file-coding-system on, for instance, C-x RET c unix RET
272 _FILE_OF_DOS_EOL_TYPE_ RET.
273
274 * coding.h (struct coding_system): New member detected_utf8_chars.
275
276 * coding.c (detect_coding_utf_8): Count characters and check EOL
277 format. Include CATEGORY_MASK_UTF_8_AUTO in detect_info->found if
278 BOM is there.
279 (setup_coding_system): Do not initialize coding->head_ascii.
280 (check_ascii): Do not set coding->eol_seen but update it. Do not
281 call adjust_coding_eol_type here.
282 (detect_coding): Fix detection of BOM for utf-8 and utf-16.
283 If the eol-type of CODING is already specified, adjust the eol type
284 of the found coding-system.
285 (decode_coding_gap): Cancel previous change. Utilize the
286 character numbers counted by detect_coding_utf_8. Fix detection
287 of BOM for utf-8.
288
2892013-05-21 Barry OReilly <gundaetiapo@gmail.com> (tiny change)
290
291 * search.c (looking_at_1): Only set last_thing_searched if the match
292 changed the match-data (bug#14281).
293
2942013-05-21 Dmitry Antipov <dmantipov@yandex.ru>
295
296 * xdisp.c (reseat_at_previous_visible_line_start):
297 Already declared in dispextern.h, so remove it here.
298 (move_it_vertically_backward): Likewise.
299
3002013-05-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
301
302 * xfns.c (check_x_display_info): Don't use XINT for terminal object.
303 (Fx_display_pixel_width, Fx_display_pixel_height)
304 (Fx_display_mm_width, Fx_display_mm_height):
305 Mention `display-monitor-attributes-list' in docstrings.
306
307 * nsfns.m (ns_get_screen): Remove function. All uses removed.
308 (check_ns_display_info): Sync with check_x_display_info in xfns.c.
309 (Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
310 (Fx_display_screens, Fx_display_mm_width, Fx_display_mm_height)
311 (Fx_display_backing_store, Fx_display_visual_class)
312 (Fx_display_save_under, Fx_close_connection, Fxw_display_color_p)
313 (Fx_display_grayscale_p, Fx_display_pixel_width)
314 (Fx_display_pixel_height, Fx_display_planes)
315 (Fx_display_color_cells): Sync args and docstrings with xfns.c.
316 (Fx_display_screens): Don't confuse X11 screens with NS screens.
317 (Fx_display_mm_width, Fx_display_mm_height)
318 (Fx_display_pixel_width, Fx_display_pixel_width): Return width or
319 height for all physical monitors as in X11.
320
321 * nsterm.m (x_display_pixel_width, x_display_pixel_height):
322 Return pixel width or height for all physical monitors as in X11.
323
3242013-05-18 Paul Eggert <eggert@cs.ucla.edu>
325
326 Port --enable-gcc-warnings to clang.
327 * bytecode.c (exec_byte_code):
328 * regex.c:
329 Redo diagnostic pragmas to pacify clang, too.
330 * dbusbind.c (xd_retrieve_arg): Do not use uninitialized variable.
331 * editfns.c (Fencode_time):
332 * fileio.c (file_accessible_directory_p):
333 * font.c (font_unparse_xlfd):
334 Use '&"string"[index]' instead of '"string" + (index)'.
335 * undo.c (user_error): Remove; unused.
336
3372013-05-16 Eli Zaretskii <eliz@gnu.org>
338
339 * insdel.c (insert_1_both): Document the arguments, instead of
340 referring to insert_1, which no longer exists.
341
342 * xdisp.c (message_dolog): If the *Messages* buffer is shown in
343 some window, increment windows_or_buffers_changed, so that
344 *Messages* display in that window is updated. (Bug#14408)
345
346 * w32.c: Include epaths.h.
347 (init_environment): Use cmdproxy.exe without leading directories.
348 Support emacs.exe in src; point SHELL to cmdproxy in ../nt in that
349 case.
350 (gettimeofday): Adjust signature and return value to Posix
351 expectations.
352
353 * unexw32.c (open_output_file): Delete the existing emacs.exe
354 before creating it, to break the hard link to the versioned
355 executable.
356
357 * Makefile.in (EMACS_MANIFEST, CM_OBJ, TEMACS_POST_LINK)
358 (ADDSECTION, EMACS_HEAPSIZE, MINGW_TEMACS_POST_LINK)
359 (FIRSTFILE_OBJ): New variables.
360 (W32_RES): Rename to EMACSRES. All users changed.
361 (base_obj): Use $(CM_OBJ).
362 (ALLOBJS): Use $(FIRSTFILE_OBJ).
363 (emacs$(EXEEXT)): Depend on $(ADDSECTION).
364 (temacs$(EXEEXT)): Use $(TEMACS_POST_LINK), and move
365 $(W32_RES_LINK) before $(LIBES).
366 (emacs.res): Depend on $(EMACS_MANIFEST). Put emacs.rc in nt.
367
3682013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
369
370 * makefile.w32-in (DOC): Use just "DOC".
371
372 * Makefile.in (bootstrap-clean): DOC-* doesn't exist any more.
373
374 * process.c: Export default filters and sentinels to Elisp.
375 (Qinternal_default_process_sentinel, Qinternal_default_process_filter):
376 New constants.
377 (pset_filter, pset_sentinel, make_process, Fset_process_filter)
378 (Fset_process_sentinel, Fformat_network_address):
379 Default to them instead of nil.
380 (server_accept_connection): Sentinels can't be nil any more.
381 (read_and_dispose_of_process_output): New function, extracted from
382 read_process_output.
383 (read_process_output): Use it; filters can't be nil.
384 (Finternal_default_process_filter): New function, extracted from
385 read_process_output.
386 (exec_sentinel_unwind): Remove function.
387 (exec_sentinel): Don't zilch sentinel while running.
388 (status_notify): Sentinels can't be nil.
389 (Finternal_default_process_sentinel): New function extracted from
390 status_notify.
391 (setup_process_coding_systems): Default filter is not nil any more.
392 (syms_of_process): Export new Elisp functions and initialize
393 new constants.
394 * lisp.h (make_lisp_proc): New function.
395
3962013-05-15 Stefan Monnier <monnier@iro.umontreal.ca>
397
398 * regex.c (regex_compile) [\=, \>, \<]: Don't forget to set laststart.
399
4002013-05-14 Eli Zaretskii <eliz@gnu.org>
401
402 * w32fns.c (w32_wnd_proc): Don't call WINDOW_HEADER_LINE_HEIGHT
403 unless we know that the window w is a leaf window.
404 Another attempt at solving bug#14062.
405
4062013-05-14 Jan Djärv <jan.h.d@swipnet.se>
407
408 * nsfont.m (ns_spec_to_descriptor): Retain and autorelease
409 fdesc (Bug#14375).
410
4112013-05-12 Paul Eggert <eggert@cs.ucla.edu>
412
413 * image.c (gif_load): Check that subimages fit (Bug#14345).
414
4152013-05-09 Stefan Monnier <monnier@iro.umontreal.ca>
416
417 * lread.c (skip_dyn_eof): New function.
418 (read1): Use it to skip the end of a file in response to #@00.
419
420 * doc.c (get_doc_string): Slightly relax the sanity checking.
421
4222013-05-09 Jan Djärv <jan.h.d@swipnet.se>
423
424 * nsfns.m: Include IOGraphicsLib.h if Cocoa.
425 (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): Declare.
426 (MonitorInfo): New struct.
427 (free_monitors, ns_screen_name, ns_make_monitor_attribute_list)
428 (Fns_display_monitor_attributes_list): New functions.
429 (display-usable-bounds): Remove.
430 (syms_of_nsfns): DEFSYM Qgeometry, Qworkarea, Qmm_size, Qframes and
431 Qsource.
432
4332013-05-09 Paul Eggert <eggert@cs.ucla.edu>
434
435 * xterm.h (GTK_PREREQ): Remove, replacing with GTK_CHECK_VERSION.
436 (GTK_CHECK_VERSION): New macro, if not already defined.
437 All uses of GTK_PREREQ, GTK_MAJOR_VERSION, etc.
438 replaced by GTK_CHECK_VERSION.
439
4402013-05-08 Paul Eggert <eggert@cs.ucla.edu>
441
442 * xterm.h (GTK_PREREQ): New macro.
443 All simple uses of GTK_MAJOR_VERSION and GTK_MINOR_VERSION changed
444 to use this macro instead, for consistency and clarity.
445
4462013-05-08 Eli Zaretskii <eliz@gnu.org>
447
448 * xdisp.c (row_for_charpos_p): New function, with code of
449 cursor_row_p, but accepts an additional argument CHARPOS instead
450 of using a hardcoded PT.
451 (cursor_row_p): Call row_for_charpos_p with 2nd argument PT.
452 (row_containing_pos): Call row_for_charpos_p instead of partially
453 doing the same. Fixes cursor positioning under longlines-mode
454 when longlines-show-effect includes more than one newline, when
455 moving the cursor vertically up.
456
4572013-05-08 Juanma Barranquero <lekktu@gmail.com>
458
459 * makefile.w32-in (ACL_H): New macro.
460 ($(BLD)/fileio.$(O)): Update dependencies.
461
4622013-05-07 Paul Eggert <eggert@cs.ucla.edu>
463
464 Use Gnulib ACL implementation, for benefit of Solaris etc. (Bug#14295)
465 * Makefile.in (LIB_ACL): New macro.
466 (LIBACL_LIBS): Remove.
467 (LIBES): Use LIB_ACL, not LIBACL_LIBS.
468 * fileio.c: Include <acl.h>.
469 Use HAVE_ACL_SET_FILE rather than HAVE_POSIX_ACL.
470 (ACL_NOT_WELL_SUPPORTED): Remove. All uses replaced by
471 !acl_errno_valid.
472 (Fcopy_file) [!WINDOWSNT]: Use qcopy_acl instead of rolling
473 it ourselves.
474
475 * unexelf.c: Don't assume ElfW (Half) fits in int.
476 (entry_address, find_section, unexec): Use ptrdiff_t, not int,
477 when dealing with ElfW (Half) values, since they can exceed 2**31
478 on 64-bit OpenBSD hosts. Problem reported privately by Han Boetes.
479 (entry_address): Omit unused NUM arg. All uses changed.
480
4812013-05-07 Juri Linkov <juri@jurta.org>
482
483 * callint.c (Fcall_interactively): Set `visargs[i]' for code 'n'
484 to the string converted from number with `Fnumber_to_string'.
485 (Bug#14254)
486
4872013-05-07 Paul Eggert <eggert@cs.ucla.edu>
488
489 * xfns.c (x_get_net_workarea): Define only if !GTK || GTK<3.4.
490 This fixes a problem introduced by my previous change.
491
4922013-05-07 Glenn Morris <rgm@gnu.org>
493
494 * lread.c (readchar): Don't read from a dead buffer. (Bug#14280)
495
4962013-05-07 Jan Djärv <jan.h.d@swipnet.se>
497
498 * xfns.c: Move misplaced ifndef USE_GTK from previous checkin.
499
5002013-05-07 Paul Eggert <eggert@cs.ucla.edu>
501
502 Static checking by GCC 4.8.0.
503 * xfns.c (x_get_net_workarea, struct MonitorInfo, free_monitors)
504 (x_get_monitor_for_frame, x_make_monitor_attribute_list)
505 (x_get_monitor_attributes_fallback)
506 (x_get_monitor_attributes_xinerama)
507 (x_get_monitor_attributes_xrandr, x_get_monitor_attributes):
508 Define only if USE_GTK.
509 (free_monitors): Define only if HAVE_XINERAMA || HAVE_XRANDR.
510 (x_get_monitor_attributes_fallback): Omit unused locals.
511 (x_get_monitor_attributes_xinerama, Fx_display_monitor_attributes_list):
512 Use double, not float, to avoid mixed-mode floating point arithmetic.
513
5142013-05-07 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
515 Jan Djärv <jan.h.d@swipnet.se>
516
517 * Makefile.in (XRANDR_LIBS, XRANDR_CFLAGS, XINERAMA_LIBS)
518 (XINERAMA_CFLAGS): New macros.
519 (ALL_CFLAGS, LIBES): Use them.
520
521 * xfns.c: Include <X11/extensions/Xrandr.h> if HAVE_XRANDR, and
522 include <X11/extensions/Xinerama.h> if HAVE_XINERAMA.
523 (Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource): New variables.
524 (syms_of_xfns): DEFSYM them.
525 (struct MonitorInfo): New struct.
526 (x_get_net_workarea, free_monitors, x_get_monitor_for_frame)
527 (x_make_monitor_attribute_list, x_get_monitor_attributes_fallback)
528 (x_get_monitor_attributes_xrandr, x_get_monitor_attributes)
529 (x_get_monitor_attributes_xinerama): New functions.
530 (Fx_display_monitor_attributes_list): New primitive.
531 (syms_of_xfns): Defsubr it.
532
533 * xterm.h (x_display_info): Add Xatom_net_workarea and
534 Xatom_net_current_desktop.
535
536 * xterm.c (x_term_init): Initialize dpyinfo->Xatom_net_workarea
537 and dpyinfo->Xatom_net_current_desktop.
538
5392013-05-06 Eli Zaretskii <eliz@gnu.org>
540
541 * xdisp.c (pos_visible_p): Use the special code for finding the
542 beginning of a display property or overlay for any "replacing"
543 display property, not just for display strings. This solves
544 incorrect reporting of position by posn-at-point. (Bug#14241)
545
5462013-05-06 Paul Eggert <eggert@cs.ucla.edu>
547
548 * unexelf.c: Fix some 32-bit integer problems, notably when debugging.
549 Include <limits.h>, <stdbool.h>, <intprops.h>, <verify.h>.
550 Verify that ElfW (Half) fits in int.
551 (fatal): Use same signature as lisp.h.
552 (UNEXELF_DEBUG): New macro, replacing DEBUG, so that people can
553 configure and build with -DUNEXELF_DEBUG without worrying about
554 other modules that use DEBUG.
555 (DEBUG_LOG) [UNEXELF_DEBUG]: New macro. All debug code that prints
556 possibly-wide integers now uses it instead of plain fprintf.
557 (entry_address): New function, which avoids problems with 32-bit
558 overflow on 64-bit hosts.
559 (OLD_SECTION_H, NEW_SECTION_H, NEW_PROGRAM_H): Use it.
560 (round_up): Don't assume the remainder fits in int.
561 (find_section): Use bool for boolean. Simplify debug code.
562 (unexec): Don't assume file sizes fit in int or size_t.
563 Omit unnecessary trailing newline in 'fatal' format.
564 Use strerror rather than outputting decimal error number.
565 Remove unused code when emacs is not defined;
566 this file relies on Emacs now.
567 Don't assume e_phnum and e_shnum are positive.
568
569 * regex.c: Fix problems when DEBUG is defined.
570 (extract_number, extract_number_and_incr): Define regardless of
571 whether DEBUG is defined; that's simpler and makes the code less
572 likely to go stale in the normal case when DEBUG is not defined.
573 Return int rather than taking an int * arg. All callers changed.
574 (DEBUG_PRINT1, DEBUG_PRINT2, DEBUG_PRINT3, DEBUG_PRINT4):
575 Remove, replacing with ...
576 (DEBUG_PRINT): New macro. All callers changed.
577 (DEBUG_COMPILES_ARGUMENTS): New macro.
578 (print_fastmap, print_partial_compiled_pattern) [DEBUG]:
579 (print_compiled_pattern, print_double_string) [DEBUG]:
580 Use prototype rather than old-style definition.
581 (print_partial_compiled_pattern, print_compiled_pattern) [DEBUG]:
582 (ENSURE_FAIL_STACK, PUSH_FAILURE_REG) [DEBUG]:
583 (POP_FAILURE_REG_OR_COUNT, PUSH_FAILURE_POINT) [DEBUG]:
584 (POP_FAILURE_POINT, re_match_2_internal) [DEBUG]:
585 Don't assume ptrdiff_t, size_t, and long are the same width as int.
586 (POINTER_TO_OFFSET): Return ptrdiff_t, not regoff_t.
587 This matters only when DEBUG is defined.
588
5892013-05-05 Eli Zaretskii <eliz@gnu.org>
590
591 * xdisp.c (set_iterator_to_next): Set the
592 ignore_overlay_strings_at_pos_p flag only if we are _really_
593 iterating over an overlay string, as indicated by the
594 current.overlay_string_index member. (Bug#14306)
595
5962013-05-05 Jan Djärv <jan.h.d@swipnet.se>
597
598 * nsmenu.m (ns_update_menubar): Move initialization of submenuTitle
599 to where it is used, to avoid autorelease issues (Bug#14050).
600
6012013-05-05 Paul Eggert <eggert@cs.ucla.edu>
602
603 `write-region-inhibit-fsync' defaults to noninteractive (Bug#14273).
604 * fileio.c (syms_of_fileio): Implement this.
605 * filelock.c (create_lock_file): If symbolic links don't work, so
606 we use a regular file as a lock file, do not fsync the lock file;
607 it's not needed.
608
6092013-05-04 Stefan Monnier <monnier@iro.umontreal.ca>
610
611 * minibuf.c (Fread_minibuffer, Feval_minibuffer): Move to Elisp.
612 (syms_of_minibuf): Adjust accodingly.
613 * lread.c (Fread):
614 * callint.c (Fcall_interactively): Adjust calls accordingly.
615
6162013-05-04 Eli Zaretskii <eliz@gnu.org>
617
618 * dispextern.h (WINDOW_WANTS_HEADER_LINE_P): Verify that
619 w->contents is a buffer before computing everything else.
620 Use parentheses to disambiguate last part of the condition.
621
622 * w32fns.c (w32_wnd_proc): Remove temporary code used to trap
623 assertion violations. (Bug#14062)
624
6252013-05-01 David Reitter <david.reitter@gmail.com>
626
627 * nsfns.m (ns_tooltip): Initialize.
628
6292013-04-28 Eli Zaretskii <eliz@gnu.org>
630
631 * coding.c (decode_coding_gap): Don't remove the character before
632 a newline unless it's a CR character. (Bug#14287)
633
6342013-04-28 Dan Nicolaescu <dann@gnu.org>
635
636 * dispextern.h (struct face): Move enum face_underline_type
637 earlier so that bitfields can be in the same word.
638
6392013-04-28 Jan Djärv <jan.h.d@swipnet.se>
640
641 * nsfns.m (handlePanelKeys): New function.
642 (EmacsOpenPanel:performKeyEquivalent:)
643 (EmacsSavePanel:performKeyEquivalent:): Call handlePanelKeys to handle
644 arrows/function/control and copy/paste keys (Bug#14296).
645
6462013-04-27 Juri Linkov <juri@jurta.org>
647
648 * callint.c (Fcall_interactively): Call `Qread_number' for
649 interactive code letter `n' instead of using duplicate code.
650 (Bug#14254)
651
6522013-04-27 Paul Eggert <eggert@cs.ucla.edu>
653
654 * systime.h (make_timeval): Declare as 'const'.
655
6562013-04-27 Kenichi Handa <handa@gnu.org>
657
658 * font.c (font_open_entity): Always open a font of manageable
659 size.
660
6612013-04-26 Paul Eggert <eggert@cs.ucla.edu>
662
663 Port better to AIX (Bug#14258).
664 * lisp.h (ENUM_BF) [__IBMC__]: Make it 'unsigned int' here, too,
665 to pacify AIX xlc.
666
6672013-04-24 Kenichi Handa <handa@gnu.org>
668
669 * coding.c (decode_coding_iso_2022): When an invalid escape
670 sequence is encountered, reset the invocation and designation
671 status to the safest one.
672
6732013-04-22 Paul Eggert <eggert@cs.ucla.edu>
674
675 * Makefile.in (bootstrap-clean): Remove stamp-h1 too.
676 Without this fix, "make distclean" leaves stamp-h1 behind.
677
6782013-04-20 Erik Charlebois <erikcharlebois@gmail.com>
679
680 * w32fns.c (w32_fullscreen_rect): New function to compute the
681 window rectangle for the given fullscreen mode.
682 (w32_wnd_proc): When in a fullscreen mode, WM_WINDOWPOSCHANGING no
683 longer tunes the window size. This keeps the window's edges flush
684 with the screen and allows the taskbar to hide itself in fullboth.
685
686 * w32term.c (w32fullscreen_hook): 'fullboth' now shows without
687 window decorations and uses the entire screen.
688
689 * w32term.h (w32_fullscreen_rect) Add prototype.
690 (struct w32_output): Replace normal_width, normal_height,
691 normal_top, and normal_left members with a single normal_placement
692 struct.
693 (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP):
694 Remove macros.
695 (FRAME_NORMAL_PLACEMENT): New macro.
696
6972013-04-16 Juanma Barranquero <lekktu@gmail.com>
698
699 * minibuf.c (Ftest_completion): Silence compiler warning.
700
7012013-04-15 Eli Zaretskii <eliz@gnu.org>
702
703 * w32fns.c (w32_wnd_proc): Add more assertions to investigate
704 bug#14062.
705
706 * frame.h (WINDOW_FRAME): Protect macro and its argument with
707 parentheses.
708
709 * dispextern.h (CURRENT_MODE_LINE_HEIGHT)
710 (CURRENT_HEADER_LINE_HEIGHT, WINDOW_WANTS_MODELINE_P)
711 (WINDOW_WANTS_HEADER_LINE_P): Protect macro arguments with
712 parentheses where appropriate.
713
7142013-04-14 Paul Eggert <eggert@cs.ucla.edu>
715
716 * keyboard.c (timer_start_idle): Remove no-longer-used local.
717
7182013-04-14 Eli Zaretskii <eliz@gnu.org>
719
720 * buffer.c (syms_of_buffer) <left-margin-width, right-margin-width>
721 <left-fringe-width, right-fringe-width, fringes-outside-margins>:
722 Mention in the doc string that setting these variables takes
723 effect only after a call to set-window-buffer. (Bug#14200)
724
7252013-04-13 Eli Zaretskii <eliz@gnu.org>
726
727 * indent.c (Fvertical_motion): Don't consider display strings on
728 overlay strings as display strings on the buffer position we
729 started from. This prevents vertical cursor motion from jumping
730 more than one line when there's an overlay string with a display
731 property at end of line.
732 Reported by Karl Chen <Karl.Chen@quarl.org> in
733 http://lists.gnu.org/archive/html/emacs-devel/2013-04/msg00362.html.
734
7352013-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
736
737 * window.c (select_window): `record_buffer' even if window is
738 already selected (bug#14191).
739
7402013-04-11 Eli Zaretskii <eliz@gnu.org>
741
742 * window.c (Fwindow_end): Test more flags, including the buffer's
743 last_overlay_modified flag, to determine whether the window's
744 display is really up-to-date. Prevents the function from
745 returning a stale value. (Bug#14170)
746 (Fwindow_line_height): Fix the test for up-to-date-ness of the
747 current matrix.
748
7492013-04-10 Eli Zaretskii <eliz@gnu.org>
750
751 * frame.c (do_switch_frame): Mark the TTY frame we switch to as
752 garbaged only if it is not already the top frame on its TTY.
753 This prevents flickering due to constant redrawing of TTY frames when
754 there are GUI frames open in the same session. (Bug#13864)
755
7562013-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
757
758 * keyboard.c (timer_start_idle): Call internal-timer-start-idle instead
759 of marking the idle timers directly.
760
7612013-04-09 Stefan Monnier <monnier@iro.umontreal.ca>
762
763 * minibuf.c (Ftest_completion): Ignore non-string/symbol keys in hash
764 tables (bug#14054).
765
7662013-04-08 Stefan Monnier <monnier@iro.umontreal.ca>
767
768 * window.c (select_window): Don't record_buffer while the invariant is
769 temporarily broken (bug#14161).
770
771 * fns.c (Fdelq): Don't assume !NILP => CONSP.
772
7732013-04-07 Eli Zaretskii <eliz@gnu.org>
774
775 * fileio.c (ACL_NOT_WELL_SUPPORTED): Define macro for WINDOWSNT.
776
7772013-04-07 Romain Francoise <romain@orebokech.com>
778
779 Ignore additional platform-specific ACL errors (Bug#13702).
780 * fileio.c (ACL_NOT_WELL_SUPPORTED): New macro copied from gnulib.
781 (Fcopy_file, Fset_file_acl) [HAVE_POSIX_ACL]: Use it.
782
7832013-03-31 Jan Djärv <jan.h.d@swipnet.se>
784
785 * nsterm.m (ns_mouse_position): Use NS_FRAME_P instead of checking
786 f->output_data.ns.
787
7882013-04-07 Paul Eggert <eggert@cs.ucla.edu>
789
790 Fix --enable-profiling bug introduced by 2013-02-25 change (Bug#13783).
791 This bug was introduced by my 2013-02-25 change that simplified
792 data_start configuration. Without this change, on GNU/Linux
793 an Emacs configured with --enable-profiling fails immediately
794 due to a profiler signal.
795 * Makefile.in: Compile with $(PROFILING_CFLAGS), but do not link
796 with these flags. On platforms where special flags are needed
797 when linking temacs, the flags are now in LD_SWITCH_SYSTEM_TEMACS.
798 (ALL_CFLAGS): Remove $(PROFILING_CFLAGS).
799 (.c.o, .m.o): Compile with $(PROFILING_CFLAGS).
800
8012013-04-07 Dmitry Antipov <dmantipov@yandex.ru>
802
803 Get rid of some platform-specific functions examining window
804 system and its capabilities. This is a partial rework of the
805 2013-04-05 change.
806 * lisp.h (have_menus_p): Remove prototype. This function is
807 replaced with platform-independent window_system_available.
808 (check_window_system): Move to...
809 * frame.h (decode_window_system_frame, window_system_available):
810 ...here, add new prototypes.
811 * frame.c (window_system_available, decode_window_system_frame):
812 New functions.
813 (check_window_system): Platform-independent now.
814 * xterm.h (x_in_use): Remove declaration.
815 (check_x_frame):
816 * w32term.h (check_x_frame):
817 * nsterm.h (check_x_frame): Remove prototypes. This function
818 is replaced with platform-independent decode_window_system_frame.
819 * msdos.c (have_menus_p): Remove.
820 * nsfns.m (check_window_system, have_menus_p, check_ns_frame):
821 Remove platform-specific functions. Use check_window_system,
822 decode_window_system_frame and check_ns_display_info where
823 appropriate. Minor style and comment tweaks.
824 * w32fns.c (w32_in_use, check_window_system, have_menus_p)
825 (check_x_frame): Likewise.
826 * xfns.c (x_in_use, check_window_system, have_menus_p, check_x_frame):
827 Likewise.
828 * fileio.c, fns.c, font.c, fontset.c, image.c, menu.c, nsmenu.m:
829 * nsselect.m, nsterm.m, w32font.c, w32menu.c, xfaces.c, xgselect.c:
830 * xmenu.c, xselect.c: All related users changed.
831
8322013-04-03 Kenichi Handa <handa@gnu.org>
833
834 The following changes is to optimize the code for reading UTF-8
835 files.
836
837 * coding.c (check_ascii): Rename from detect_ascii. Return value
838 changed. Check EOL format. Do not call adjust_coding_eol_type
839 here.
840 (check_utf_8): New function.
841 (adjust_coding_eol_type): Do nothing if already adjusted.
842 (detect_coding): Compare the return value of check_ascii with
843 coding->src_bytes. Call adjust_coding_eol_type if necessary.
844 (decode_coding_gap): Optimize for valid UTF-8.
845
8462013-03-21 Kenichi Handa <handa@gnu.org>
847
848 * coding.c (syms_of_coding): Cancel previous change.
849
850 * insdel.c (insert_from_gap): Fix previous change.
851
8522013-04-05 Dmitry Antipov <dmantipov@yandex.ru>
853
854 Consistently use platform-specific function to detect window system.
855 * lisp.h (check_window_system): New prototype. This function is
856 going to replace check_x, check_w32 and check_ns.
857 (have_menus_p): Mention msdos.c in comment.
858 * fontset.c (check_window_system_func): Remove. Adjust all users.
859 * fontset.h (check_window_system_func): Remove prototype.
860 * nsterm.h (check_ns):
861 * xterm.h (check_x):
862 * w32term.h (check_w32): Likewise.
863 * menu.c (Fx_popup_menu): Use check_window_system.
864 * msdos.c (check_window_system): Define for MS-DOS.
865 * nsfns.m (check_window_system): Define for NS. Adjust all users.
866 * w32fns.c (check_window_system): Likewise for MS-Windows.
867 * xfns.c (check_window_system): Likewise for X.
868 * font.c, frame.c, nsmenu.m, nsselect.m, nsterm.m, w32menu.c:
869 * xfaces.c, xmenu.c: Use check_window_system where appropriate.
870
8712013-04-02 Paul Eggert <eggert@cs.ucla.edu>
872
873 Prefer < to > in range checks such as 0 <= i && i < N.
874 This makes it easier to visualize quantities on a number line.
875 This patch doesn't apply to all such range checks,
876 only to the range checks affected by the 2013-03-24 change.
877 This patch reverts most of the 2013-03-24 change.
878 * alloc.c (xpalloc, Fgarbage_collect):
879 * ccl.c (ccl_driver, resolve_symbol_ccl_program):
880 * character.c (string_escape_byte8):
881 * charset.c (read_hex):
882 * data.c (cons_to_unsigned):
883 * dispnew.c (update_frame_1):
884 * doc.c (Fsubstitute_command_keys):
885 * doprnt.c (doprnt):
886 * editfns.c (hi_time, decode_time_components):
887 * fileio.c (file_offset):
888 * fns.c (larger_vector, make_hash_table, Fmake_hash_table):
889 * font.c (font_intern_prop):
890 * frame.c (x_set_alpha):
891 * gtkutil.c (get_utf8_string):
892 * indent.c (check_display_width):
893 * keymap.c (Fkey_description):
894 * lisp.h (FIXNUM_OVERFLOW_P, vcopy):
895 * lread.c (read1):
896 * minibuf.c (read_minibuf_noninteractive):
897 * process.c (wait_reading_process_output):
898 * search.c (Freplace_match):
899 * window.c (get_phys_cursor_glyph):
900 * xdisp.c (redisplay_internal):
901 * xsmfns.c (smc_save_yourself_CB):
902 Prefer < to > for range checks.
903 * dispnew.c (sit_for): Don't mishandle NaNs.
904 This fixes a bug introduced in the 2013-03-24 change.
905 * editfns.c (decode_time_components): Don't hoist comparison.
906 This fixes another bug introduced in the 2013-03-24 change.
907
9082013-03-31 Dmitry Antipov <dmantipov@yandex.ru>
909
910 * frame.h (struct frame): Drop scroll_bottom_vpos
911 member becaue all real users are dead long ago.
912 (FRAME_SCROLL_BOTTOM_VPOS): Remove.
913 * xdisp.c (redisplay_internal): Adjust user.
914
9152013-03-30 Darren Ho <darren.hoo@gmail.com> (tiny change)
916
917 * nsmenu.m (showAtX:Y:for:): setLevel to
918 NSPopUpMenuWindowLevel (Bug#13998).
919
9202013-03-30 Jan Djärv <jan.h.d@swipnet.se>
921
922 * nsterm.h (ns_get_pending_menu_title, ns_check_menu_open)
923 (ns_check_pending_open_menu): Declare.
924
925 * nsmenu.m (ns_update_menubar): Correct NSTRACE.
926 (x_activate_menubar): Update the menu with title that matches
927 ns_get_pending_menu_title, and call
928 ns_check_pending_openmenu (Bug#12698).
929 (menuWillOpen:): New method.
930 (menuNeedsUpdate:): Add check for ! COCOA || OSX < 10.5 (Bug#12698).
931
932 * nsterm.m (menu_will_open_state, menu_mouse_point)
933 (menu_pending_title): New varaibles.
934 (ns_get_pending_menu_title, ns_check_menu_open)
935 (ns_check_pending_open_menu): New functions.
936
9372013-03-29 Dmitry Antipov <dmantipov@yandex.ru>
938
939 * indent.c (current_column_bol_cache): Remove leftover which is not
940 used in Fmove_to_column any more.
941 (current_column, scan_for_column): Adjust users.
942 * keyboard.c (last_point_position_buffer, last_point_position_window):
943 Remove leftovers which are not used for recording undo any more.
944 (command_loop_1, syms_of_keyboard): Adjust users.
945 * xdisp.c (last_max_ascent): Remove leftover which is not used in
946 redisplay_window any more.
947 (move_it_to): Adjust user.
948
9492013-03-29 Juanma Barranquero <lekktu@gmail.com>
950
951 * makefile.w32-in ($(BLD)/filelock.$(O), $(BLD)/filelock.$(O)):
952 Update dependencies.
953
9542013-03-28 Stefan Monnier <monnier@iro.umontreal.ca>
955
956 * lisp.h (save_type, XSAVE_POINTER, set_save_pointer, XSAVE_INTEGER)
957 (set_save_integer, XSAVE_OBJECT, XSAVE_VALUE): Move to avoid
958 forward references.
959
9602013-03-28 Dmitry Antipov <dmantipov@yandex.ru>
961
962 * window.h (struct window): Replace hchild, vchild and buffer slots
963 with the only contents slot. This is possible because each valid
964 window may have either the child window (in vertical or horizontal
965 combination) or buffer to display (for the leaf window). Using that,
966 a lof of operations to traverse and/or change window hierarchies may
967 be simplified. New member horizontal is used to distinguish between
968 horizontal and vertical combinations of internal windows.
969 (WINDOW_LEAF_P, WINDOW_HORIZONTAL_COMBINATION_P)
970 (WINDOW_VERTICAL_COMBINATION_P): New macros.
971 (WINDOW_VALID_P, WINDOW_LIVE_P): Adjust to match struct window changes.
972 * window.c (wset_hchild, wset_vchild): Remove. Adjust all users.
973 Use contents slot, not buffer, where appropriate.
974 (wset_combination): New function.
975 (wset_buffer): Add eassert.
976 (Fframe_first_window): Simplify the loop reaching first window.
977 (Fwindow_buffer): Use WINDOW_LEAF_P.
978 (Fwindow_top_child): Use WINDOW_VERTICAL_COMBINATION_P.
979 (Fwindow_left_child): Use WINDOW_HORIZONTAL_COMBINATION_P.
980 (unshow_buffer): Convert initial debugging check to eassert.
981 (replace_window, recombine_windows, Fdelete_other_windows_internal)
982 (make_parent_window, window_resize_check, window_resize_apply)
983 (resize_frame_windows, Fsplit_window_internal, Fdelete_window_internal)
984 (Fset_window_configuration, delete_all_child_windows, save_window_save):
985 Adjust to match struct window changes.
986 (window_loop): Check for broken markers in CHECK_ALL_WINDOWS.
987 (mark_window_cursors_off, count_windows, get_leaf_windows)
988 (foreach_window_1): Simplify the loop.
989 * alloc.c (mark_object): Do not check for the leaf window because
990 internal windows has no glyph matrices anyway.
991 * dispnew.c (clear_window_matrices, showing_window_margins_p)
992 (allocate_matrices_for_window_redisplay, fake_current_matrices)
993 (allocate_matrices_for_frame_redisplay, free_window_matrices)
994 (build_frame_matrix_from_window_tree, mirror_make_current)
995 (frame_row_to_window, mirror_line_dance, check_window_matrix_pointers)
996 (update_window_tree, set_window_update_flags): Simplify the loop.
997 (sync_window_with_frame_matrix_rows): Enforce live window.
998 Use contents slot, not buffer, where appropriate.
999 * frame.c (set_menu_bar_lines_1): Use WINDOW_VERTICAL_COMBINATION_P
1000 and WINDOW_HORIZONTAL_COMBINATION_P.
1001 (make_frame_visible_1): Simplify the loop.
1002 Use contents slot, not buffer, where appropriate.
1003 * xdisp.c (hscroll_window_tree, mark_window_display_accurate)
1004 (redisplay_windows, redisplay_mode_lines, update_cursor_in_window_tree)
1005 (expose_window_tree): Likewise.
1006 Use contents slot, not buffer, where appropriate.
1007 * textprop.c (get_char_property_and_overlay): Add CHECK_LIVE_WINDOW
1008 to avoid deleted windows. Use contents slot instead of buffer.
1009 * buffer.c, dispextern.h, editfns.c, fileio.c, font.c, fringe.c:
1010 * indent.c, insdel.c, keyboard.c, keymap.c, minibuf.c, msdos.c:
1011 * nsfns.m, nsmenu.m, nsterm.m, print.c, w32fns.c, w32menu.c, xfaces.c:
1012 * xfns.c, xmenu.c: Use contents slot, not buffer, where appropriate.
1013
10142013-03-28 Eli Zaretskii <eliz@gnu.org>
1015
1016 * w32fns.c (w32_wnd_proc) [ENABLE_CHECKING]: Add code to help
1017 identify the reasons for assertion violations in bug#14062 and
1018 similar ones.
1019 (Fx_show_tip): Fix compilation error under
1020 "--enable-check-lisp-object-type". (Bug#14073)
1021
1022 * image.c (g_error_free) [WINDOWSNT]: Add DEF_IMGLIB_FN.
1023 Reported by <rzl24ozi@gmail.com>.
1024
10252013-03-28 Dmitry Antipov <dmantipov@yandex.ru>
1026
1027 * xdisp.c (with_echo_area_buffer_unwind_data): Save window
1028 start marker...
1029 (unwind_with_echo_area_buffer): ...to restore it here.
1030 This is needed to ensure that...
1031 (redisplay_window): ...both window markers are valid here,
1032 which is verified by eassert.
1033 * editfns.c (save_excursion_save): Do not assume that
1034 selected_window always displays the buffer.
1035 * buffer.c (Fbuffer_swap_text): Adjust window start markers.
1036 Fix comment.
1037
10382013-03-27 Stefan Monnier <monnier@iro.umontreal.ca>
1039
1040 * casetab.c (init_casetab_once): Don't abuse the ascii eqv table for
1041 the upcase table.
1042
10432013-03-27 rzl24ozi <rzl24ozi@gmail.com> (tiny changes)
1044
1045 * image.c [WINDOWSNT]: Fix calls to DEF_IMGLIB_FN for SVG function.
1046
10472013-03-27 Eli Zaretskii <eliz@gnu.org>
1048
1049 * w32proc.c (IsValidLocale) [__GNUC__]: Don't declare prototype,
1050 since MinGW's w32api headers do. This avoids compiler warnings.
1051
1052 * w32.c (FSCTL_GET_REPARSE_POINT) [_MSC_VER || _W64]: Don't define
1053 if already defined.
1054
10552013-03-26 Eli Zaretskii <eliz@gnu.org>
1056
1057 * w32.c (_REPARSE_DATA_BUFFER): Condition by _MSVC and _W64.
1058
10592013-03-26 Jan Djärv <jan.h.d@swipnet.se>
1060
1061 * gtkutil.c (style_changed_cb): Check if frame is live and an
1062 X frame (Bug#14038).
1063
10642013-03-26 Eli Zaretskii <eliz@gnu.org>
1065
1066 * w32.c (_PROCESS_MEMORY_COUNTERS_EX) [_WIN32_WINNT < 0x0500]:
1067 Define only for _WIN32_WINNT less than 0x0500.
1068 (_ANONYMOUS_UNION, _ANONYMOUS_STRUCT) [!_W64]: Don't define for
1069 MinGW64.
1070 Move inclusion of time.h before sys/time.h, so that MinGW64 could
1071 see its own definitions of 'struct timeval' and 'struct timezone'.
1072
1073 Fix incompatibilities between MinGW.org and MinGW64 headers.
1074 * w32term.c (WCRANGE, GLYPHSET): Don't define if _W64 is defined.
1075
1076 * w32.c (REPARSE_DATA_BUFFER): Guard with
1077 MAXIMUM_REPARSE_DATA_BUFFER_SIZE being defined.
1078
10792013-03-25 Jan Djärv <jan.h.d@swipnet.se>
1080
1081 * xterm.c: Include X11/XKBlib.h
1082 (XTring_bell): Use XkbBell if HAVE_XKB (Bug#14041).
1083
10842013-03-24 Andreas Schwab <schwab@linux-m68k.org>
1085
1086 * alloc.c (xpalloc, Fgarbage_collect): Reorder conditions that are
1087 written backwards.
1088 * blockinput.h (input_blocked_p): Likewise.
1089 * bytecode.c (exec_byte_code): Likewise.
1090 * callproc.c (call_process_kill, call_process_cleanup)
1091 (Fcall_process): Likewise.
1092 * ccl.c (ccl_driver, resolve_symbol_ccl_program)
1093 (Fccl_execute_on_string): Likewise.
1094 * character.c (string_escape_byte8): Likewise.
1095 * charset.c (read_hex): Likewise.
1096 * cm.c (calccost): Likewise.
1097 * data.c (cons_to_unsigned): Likewise.
1098 * dired.c (directory_files_internal, file_name_completion):
1099 Likewise.
1100 * dispnew.c (scrolling_window, update_frame_1, Fsleep_for)
1101 (sit_for): Likewise.
1102 * doc.c (Fsubstitute_command_keys): Likewise.
1103 * doprnt.c (doprnt): Likewise.
1104 * editfns.c (hi_time, decode_time_components, Fformat): Likewise.
1105 * emacsgtkfixed.c: Likewise.
1106 * fileio.c (file_offset, Fwrite_region): Likewise.
1107 * floatfns.c (Fexpt, fmod_float): Likewise.
1108 * fns.c (larger_vector, make_hash_table, Fmake_hash_table):
1109 Likewise.
1110 * font.c (font_intern_prop): Likewise.
1111 * frame.c (x_set_alpha): Likewise.
1112 * gtkutil.c (get_utf8_string): Likewise.
1113 * indent.c (check_display_width): Likewise.
1114 * intervals.c (create_root_interval, rotate_right, rotate_left)
1115 (split_interval_right, split_interval_left)
1116 (adjust_intervals_for_insertion, delete_node)
1117 (interval_deletion_adjustment, adjust_intervals_for_deletion)
1118 (merge_interval_right, merge_interval_left, copy_intervals)
1119 (set_intervals_multibyte_1): Likewise.
1120 * keyboard.c (gobble_input, append_tool_bar_item): Likewise.
1121 * keymap.c (Fkey_description): Likewise.
1122 * lisp.h (FIXNUM_OVERFLOW_P, vcopy): Likewise.
1123 * lread.c (openp, read_integer, read1, string_to_number):
1124 Likewise.
1125 * menu.c (ensure_menu_items): Likewise.
1126 * minibuf.c (read_minibuf_noninteractive): Likewise.
1127 * print.c (printchar, strout): Likewise.
1128 * process.c (create_process, Faccept_process_output)
1129 (wait_reading_process_output, read_process_output, send_process)
1130 (wait_reading_process_output): Likewise.
1131 * profiler.c (make_log, handle_profiler_signal): Likewise.
1132 * regex.c (re_exec): Likewise.
1133 * regex.h: Likewise.
1134 * search.c (looking_at_1, Freplace_match): Likewise.
1135 * sysdep.c (get_child_status, procfs_ttyname)
1136 (procfs_get_total_memory): Likewise.
1137 * systime.h (EMACS_TIME_VALID_P): Likewise.
1138 * term.c (dissociate_if_controlling_tty): Likewise.
1139 * window.c (get_phys_cursor_glyph): Likewise.
1140 * xdisp.c (init_iterator, redisplay_internal, redisplay_window)
1141 (try_window_reusing_current_matrix, try_window_id, pint2hrstr):
1142 Likewise.
1143 * xfns.c (Fx_window_property): Likewise.
1144 * xmenu.c (set_frame_menubar): Likewise.
1145 * xselect.c (x_get_window_property, x_handle_dnd_message):
1146 Likewise.
1147 * xsmfns.c (smc_save_yourself_CB): Likewise.
1148 * xterm.c (x_scroll_bar_set_handle): Likewise.
1149
11502013-03-24 Dmitry Antipov <dmantipov@yandex.ru>
1151
1152 * xfaces.c (Finternal_face_x_get_resource): Allow 3rd (frame) argument
1153 to be optional or nil. Adjust comment and convert it to docstring.
1154 * xselect.c (Fx_send_client_event): Rename to Fx_send_client_message.
1155 * frame.c (display_x_get_resource, Fx_get_resource): Break long line.
1156
11572013-03-24 Paul Eggert <eggert@cs.ucla.edu>
1158
1159 Static checking by GCC 4.8-20130319.
1160 * image.c (gif_load): Assume pass < 3 to pacify GCC.
1161 * process.c (Fset_process_datagram_address)
1162 (Fmake_network_process): Check get_lisp_to_sockaddr_size return value.
1163 * xdisp.c (get_char_face_and_encoding):
1164 (get_glyph_face_and_encoding): Ensure that *CHAR2B is initialized.
1165 (get_glyph_face_and_encoding): Prepare face before possibly using it.
1166 (get_per_char_metric): Don't use CHAR2B if it might not be initialized.
1167
11682013-03-24 Ken Brown <kbrown@cornell.edu>
1169
1170 * w32fns.c (emacs_abort) [CYGWIN]: Define `_open' as a macro to
1171 fix compilation on 64-bit Cygwin, where underscores are not
1172 automatically prepended.
1173
1174 * w32term.c (w32_initialize): Silence compiler warning.
1175
11762013-03-23 Eli Zaretskii <eliz@gnu.org>
1177
1178 * w32term.c (w32fullscreen_hook): Use FRAME_NORMAL_WIDTH,
1179 FRAME_NORMAL_HEIGHT, and FRAME_PREV_FSMODE, instead of static
1180 variables, to save and restore frame dimensions.
1181 Use FRAME_NORMAL_LEFT and FRAME_NORMAL_TOP to restore frame position
1182 after returning from a 'fullscreen' configuration.
1183 use SendMessage instead of PostMessage to send the SC_RESTORE message,
1184 to avoid races between the main thread and the input thread.
1185
1186 * w32term.h (struct w32_output): New members normal_width,
1187 normal_height, normal_top, normal_left, and prev_fsmode.
1188 (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP)
1189 (FRAME_NORMAL_LEFT, FRAME_PREV_FSMODE): New macros to access these
1190 members of a frame.
1191
1192 * w32term.c (w32fullscreen_hook): Record last value of the frame's
1193 'fullscreen' parameter. Always record previous width and height
1194 of the frame, except when switching out of maximized modes, so
1195 that they could be restored correctly, instead of resetting to the
1196 default frame dimensions. Send SC_RESTORE command to the frame,
1197 unless we are going to send SC_MAXIMIZE, to restore the frame
1198 resize hints in the mouse pointer shown by the window manager.
1199 (Bug#14032)
1200
1201 * frame.c (get_frame_param): Now extern for WINDOWSNT as well.
1202
1203 * lisp.h (get_frame_param): Adjust conditions for prototype
1204 declaration.
1205
12062013-03-22 Ken Brown <kbrown@cornell.edu>
1207
1208 * unexcw.c: Drop unneeded inclusion of w32common.h.
1209 (report_sheap_usage): Declare.
1210 (read_exe_header): Add magic numbers for x86_64.
1211 (fixup_executable): Fix printf format specifier for unsigned long
1212 argument.
1213
12142013-03-22 Dmitry Antipov <dmantipov@yandex.ru>
1215
1216 * frame.h (struct frame): Put menu_bar_window under #ifdef
1217 because this member is not needed when X toolkit is in use.
1218 (fset_menu_bar_window):
1219 * dispnew.c (clear_current_matrices, clear_desired_matrices)
1220 (free_glyphs, update_frame):
1221 * xdisp.c (expose_frame): Likewise.
1222 (display_menu_bar): Likewise. Remove redundant eassert.
1223 * window.h (WINDOW_MENU_BAR_P): Always define to 0 if X
1224 toolkit is in use.
1225
12262013-03-21 Paul Eggert <eggert@cs.ucla.edu>
1227
1228 Use functions and constants to manipulate Lisp_Save_Value objects.
1229 This replaces code that used macros and strings and token-pasting.
1230 The change makes the C source a bit easier to follow,
1231 and shrinks the Emacs executable a bit.
1232 * alloc.c: Verify some properties of Lisp_Save_Value's representation.
1233 (make_save_value): Change 1st arg from string to enum. All callers
1234 changed.
1235 (INTX): Remove.
1236 (mark_object): Use if, not #if, for GC_MARK_STACK.
1237 * lisp.h (SAVE_VALUEP, XSAVE_VALUE, XSAVE_POINTER, XSAVE_INTEGER)
1238 (XSAVE_OBJECT): Now functions, not macros.
1239 (STRING_BYTES_BOUND): Now just a macro, not a constant too;
1240 the constant was never used.
1241 (SAVE_SLOT_BITS, SAVE_VALUE_SLOTS, SAVE_TYPE_BITS, SAVE_TYPE_INT_INT)
1242 (SAVE_TYPE_INT_INT_INT, SAVE_TYPE_OBJ_OBJ, SAVE_TYPE_OBJ_OBJ_OBJ)
1243 (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, SAVE_TYPE_PTR_INT, SAVE_TYPE_PTR_OBJ)
1244 (SAVE_TYPE_PTR_PTR, SAVE_TYPE_PTR_PTR_OBJ, SAVE_TYPE_MEMORY):
1245 New constants.
1246 (struct Lisp_Save_Value): Replace members area, type0, type1, type2,
1247 type3 with a single member save_type. All uses changed.
1248 (save_type, set_save_pointer, set_save_integer): New functions.
1249 * print.c (PRINTX): Remove.
1250
1251 * alloc.c: Remove redundant static declarations.
1252
12532013-03-20 Dmitry Antipov <dmantipov@yandex.ru>
1254
1255 * window.h (struct window): Convert left_col, top_line, total_lines
1256 and total_cols from Lisp_Objects to integers. Adjust comments.
1257 (wset_left_col, wset_top_line, wset_total_cols, wset_total_lines):
1258 Remove.
1259 (WINDOW_TOTAL_COLS, WINDOW_TOTAL_LINES, WINDOW_LEFT_EDGE_COL)
1260 (WINDOW_TOP_EDGE_LINE): Drop Lisp_Object to integer conversion.
1261 * dispnew.c, frame.c, w32fns.c, window.c, xdisp.c, xfns.c:
1262 Adjust users where appropriate.
1263
12642013-03-20 Dmitry Antipov <dmantipov@yandex.ru>
1265
1266 * frame.h (struct frame): Drop resx and resy because the same data is
1267 available from window system-specific output context. Adjust users.
1268 (default_pixels_per_inch_x, default_pixels_per_inch_y):
1269 New functions to provide defaults when no window system available.
1270 (FRAME_RES_X, FRAME_RES_Y): New macros.
1271 (NUMVAL): Move from xdisp.c.
1272 * font.c (font_pixel_size, font_find_for_lface, font_open_for_lface)
1273 (Ffont_face_attributes, Fopen_font):
1274 * image.c (gs_load):
1275 * w32font.c (fill_in_logfont):
1276 * xdisp.c (calc_pixel_width_or_height):
1277 * xfaces.c (Fx_family_fonts, set_lface_from_font): Use them.
1278 * xsettings.c (apply_xft_settings): Drop frame loop and adjust comment.
1279
12802013-03-20 Kenichi Handa <handa@gnu.org>
1281
1282 * coding.c (syms_of_coding): Initialize disable_ascii_optimization
1283 to 1 (temporary workaround until a bug related to ASCII
1284 optimization is fixed).
1285
12862013-03-19 Dmitry Antipov <dmantipov@yandex.ru>
1287
1288 * window.c (Fwindow_combination_limit, Fset_window_combination_limit):
1289 Signal error if window is not internal. Adjust docstring.
1290 (delete_all_child_windows): Use combination_limit to save the buffer.
1291 (Fset_window_configuration): Adjust accordingly.
1292 * print.c (syms_of_print): Initialize debugging output not here...
1293 (init_print_once): ...but in a new function here.
1294 * lisp.h (init_print_once): Add prototype.
1295 * emacs.c (main): Add call to init_print_once. Adjust comments.
1296
12972013-03-18 Dmitry Antipov <dmantipov@yandex.ru>
1298
1299 * window.c (window_resize_check, window_resize_apply)
1300 (window_from_coordinates, recombine_windows, set_window_buffer)
1301 (make_parent_window, Fwindow_resize_apply, resize_frame_windows)
1302 (Fsplit_window_internal, Fdelete_window_internal)
1303 (freeze_window_starts): Use bool for booleans.
1304 * window.h (window_frame_coordinates, resize_frame_windows)
1305 (freeze_window_starts, set_window_buffer): Adjust prototypes.
1306
13072013-03-17 Stefan Monnier <monnier@iro.umontreal.ca>
1308
1309 * dispnew.c (bitch_at_user): Use `user-error'.
1310
13112013-03-17 Ken Brown <kbrown@cornell.edu>
1312
1313 * dispextern.h (RGB_PIXEL_COLOR): Move here from image.c. Use it
1314 as return type of image_background. (Bug#13981)
1315 * image.c (RGB_PIXEL_COLOR): Move to dispextern.h.
1316
12013-03-16 Jan Djärv <jan.h.d@swipnet.se> 13172013-03-16 Jan Djärv <jan.h.d@swipnet.se>
2 1318
3 * nsterm.m (updateFrameSize:): Change resize increments if needed. 1319 * nsterm.m (updateFrameSize:): Change resize increments if needed.
@@ -6,8 +1322,8 @@
6 * nsterm.h (EmacsSavePanel, EmacsOpenPanel): Add getFilename 1322 * nsterm.h (EmacsSavePanel, EmacsOpenPanel): Add getFilename
7 and getDirectory. 1323 and getDirectory.
8 1324
9 * nsfns.m (ns_filename_from_panel, ns_directory_from_panel): New 1325 * nsfns.m (ns_filename_from_panel, ns_directory_from_panel):
10 functions. 1326 New functions.
11 (Fns_read_file_name): ret is BOOL. If ! dir_only_p, don't choose 1327 (Fns_read_file_name): ret is BOOL. If ! dir_only_p, don't choose
12 directories. If filename is nil, get directory name (Bug#13932). 1328 directories. If filename is nil, get directory name (Bug#13932).
13 Use getFilename and getDirectory. 1329 Use getFilename and getDirectory.
@@ -19,7 +1335,7 @@
19 1335
20 * coding.c (decode_coding_gap): Fix typo caught by static checking. 1336 * coding.c (decode_coding_gap): Fix typo caught by static checking.
21 1337
222013-03-15 handa <handa@gnu.org> 13382013-03-15 Kenichi Handa <handa@gnu.org>
23 1339
24 * insdel.c (insert_from_gap): New arg text_at_gap_tail. 1340 * insdel.c (insert_from_gap): New arg text_at_gap_tail.
25 (adjust_after_replace): Make it back to static. Delete the third 1341 (adjust_after_replace): Make it back to static. Delete the third
@@ -40,10 +1356,6 @@
40 (syms_of_coding): Declare disable-ascii-optimization as a Lisp 1356 (syms_of_coding): Declare disable-ascii-optimization as a Lisp
41 variable. 1357 variable.
42 1358
43 * global.h (struct emacs_globals): New member
44 f_disable_ascii_optimization.
45 (disable_ascii_optimization): New macro.
46
47 * lisp.h (adjust_after_replace): Cancel externing it. 1359 * lisp.h (adjust_after_replace): Cancel externing it.
48 (insert_from_gap): Adjust prototype. 1360 (insert_from_gap): Adjust prototype.
49 1361
@@ -645,7 +1957,7 @@
645 (Fcommand_execute): Remove, replace by an Elisp implementation. 1957 (Fcommand_execute): Remove, replace by an Elisp implementation.
646 (syms_of_keyboard): Adjust accordingly. 1958 (syms_of_keyboard): Adjust accordingly.
647 1959
6482013-02-19 Daniel Colascione <dancol@dancol.org> 19602013-02-19 Daniel Colascione <dancol@dancol.org>
649 1961
650 * sheap.c (report_sheap_usage): Use message, not message1, so 1962 * sheap.c (report_sheap_usage): Use message, not message1, so
651 that we don't try to create a buffer while we're in the middle 1963 that we don't try to create a buffer while we're in the middle
@@ -2431,7 +3743,7 @@
2431 Use xputenv instead of setenv or putenv, to detect memory exhaustion. 3743 Use xputenv instead of setenv or putenv, to detect memory exhaustion.
2432 * editfns.c (initial_tz): Move static var decl up. 3744 * editfns.c (initial_tz): Move static var decl up.
2433 (tzvalbuf_in_environ): New static var. 3745 (tzvalbuf_in_environ): New static var.
2434 (init_editfns): Initialize these two static vars. 3746 (init_editfns): Initialize these two static vars.
2435 (Fencode_time): Don't assume arbitrary limit on EMACS_INT width. 3747 (Fencode_time): Don't assume arbitrary limit on EMACS_INT width.
2436 Save old TZ value on stack, if it's small. 3748 Save old TZ value on stack, if it's small.
2437 (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly; 3749 (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly;
@@ -2710,7 +4022,7 @@
2710 Use execve to avoid need to munge environ (Bug#13054). 4022 Use execve to avoid need to munge environ (Bug#13054).
2711 * callproc.c (Fcall_process): 4023 * callproc.c (Fcall_process):
2712 * process.c (create_process): 4024 * process.c (create_process):
2713 Don't save and restore environ; no longer needed. 4025 Don't save and restore environ; no longer needed.
2714 * callproc.c (child_setup): 4026 * callproc.c (child_setup):
2715 Use execve, not execvp, to preserve environ. 4027 Use execve, not execvp, to preserve environ.
2716 4028
@@ -5110,8 +6422,8 @@
5110 a public macro and no need to inline by hand. 6422 a public macro and no need to inline by hand.
5111 6423
51122012-09-26 Tomohiro Matsuyama <tomo@cx4a.org> 64242012-09-26 Tomohiro Matsuyama <tomo@cx4a.org>
5113 Stefan Monnier <monnier@iro.umontreal.ca> 6425 Stefan Monnier <monnier@iro.umontreal.ca>
5114 Juanma Barranquero <lekktu@gmail.com> 6426 Juanma Barranquero <lekktu@gmail.com>
5115 6427
5116 * profiler.c: New file. 6428 * profiler.c: New file.
5117 * Makefile.in (base_obj): Add profiler.o. 6429 * Makefile.in (base_obj): Add profiler.o.
@@ -11469,9 +12781,9 @@
11469 to denote vector blocks. Adjust users (live_vector_p, 12781 to denote vector blocks. Adjust users (live_vector_p,
11470 mark_maybe_pointer, valid_lisp_object_p) accordingly. 12782 mark_maybe_pointer, valid_lisp_object_p) accordingly.
11471 (COMMON_MULTIPLE): Move outside #if USE_LSB_TAG. 12783 (COMMON_MULTIPLE): Move outside #if USE_LSB_TAG.
11472 (VECTOR_BLOCK_SIZE, vroundup, VECTOR_BLOCK_BYTES), 12784 (VECTOR_BLOCK_SIZE, vroundup, VECTOR_BLOCK_BYTES)
11473 (VBLOCK_BYTES_MIN, VBLOCK_BYTES_MAX, VECTOR_MAX_FREE_LIST_INDEX), 12785 (VBLOCK_BYTES_MIN, VBLOCK_BYTES_MAX, VECTOR_MAX_FREE_LIST_INDEX)
11474 (VECTOR_FREE_LIST_FLAG, ADVANCE, VINDEX, SETUP_ON_FREE_LIST), 12786 (VECTOR_FREE_LIST_FLAG, ADVANCE, VINDEX, SETUP_ON_FREE_LIST)
11475 (VECTOR_SIZE, VECTOR_IN_BLOCK): New macros. 12787 (VECTOR_SIZE, VECTOR_IN_BLOCK): New macros.
11476 (roundup_size): New constant. 12788 (roundup_size): New constant.
11477 (struct vector_block): New data type. 12789 (struct vector_block): New data type.
diff --git a/src/ChangeLog.10 b/src/ChangeLog.10
index 508a2a9dd4c..57c1cbf1299 100644
--- a/src/ChangeLog.10
+++ b/src/ChangeLog.10
@@ -1865,7 +1865,7 @@
1865 1865
18662006-10-07 Ralf Angeli <angeli@caeruleus.net> 18662006-10-07 Ralf Angeli <angeli@caeruleus.net>
1867 1867
1868 * w32fns.c (w32_createwindow): Honour left and top positions if 1868 * w32fns.c (w32_createwindow): Honor left and top positions if
1869 supplied explicitly. 1869 supplied explicitly.
1870 1870
18712006-10-06 Kim F. Storm <storm@cua.dk> 18712006-10-06 Kim F. Storm <storm@cua.dk>
diff --git a/src/ChangeLog.11 b/src/ChangeLog.11
index 1195a8f9592..a67dd2cc458 100644
--- a/src/ChangeLog.11
+++ b/src/ChangeLog.11
@@ -14366,7 +14366,7 @@
143662009-01-10 Chong Yidong <cyd@stupidchicken.com> 143662009-01-10 Chong Yidong <cyd@stupidchicken.com>
14367 14367
14368 * xdisp.c (pos_visible_p): When iterator stops on the last glyph 14368 * xdisp.c (pos_visible_p): When iterator stops on the last glyph
14369 of a display vector, backtrack. 14369 of a display vector, backtrack. (Bug#1810)
14370 (try_window_reusing_current_matrix): Check glyph type before 14370 (try_window_reusing_current_matrix): Check glyph type before
14371 referencing charpos member. 14371 referencing charpos member.
14372 14372
diff --git a/src/Makefile.in b/src/Makefile.in
index eeb2b88bf32..86e5aca36ec 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -137,6 +137,7 @@ LIBOTF_LIBS = @LIBOTF_LIBS@
137M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@ 137M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@
138M17N_FLT_LIBS = @M17N_FLT_LIBS@ 138M17N_FLT_LIBS = @M17N_FLT_LIBS@
139 139
140LIB_ACL=@LIB_ACL@
140LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@ 141LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@
141LIB_EACCESS=@LIB_EACCESS@ 142LIB_EACCESS=@LIB_EACCESS@
142LIB_FDATASYNC=@LIB_FDATASYNC@ 143LIB_FDATASYNC=@LIB_FDATASYNC@
@@ -155,6 +156,11 @@ SETTINGS_LIBS = @SETTINGS_LIBS@
155## gtkutil.o if USE_GTK, else empty. 156## gtkutil.o if USE_GTK, else empty.
156GTK_OBJ=@GTK_OBJ@ 157GTK_OBJ=@GTK_OBJ@
157 158
159## gfilenotify.o if HAVE_GFILENOTIFY.
160## inotify.o if HAVE_INOTIFY.
161## w32notify.o if HAVE_W32NOTIFY.
162NOTIFY_OBJ = @NOTIFY_OBJ@
163
158## -ltermcap, or -lncurses, or -lcurses, or "". 164## -ltermcap, or -lncurses, or -lcurses, or "".
159LIBS_TERMCAP=@LIBS_TERMCAP@ 165LIBS_TERMCAP=@LIBS_TERMCAP@
160## terminfo.o if TERMINFO, else tparam.o. 166## terminfo.o if TERMINFO, else tparam.o.
@@ -232,6 +238,12 @@ IMAGEMAGICK_CFLAGS= @IMAGEMAGICK_CFLAGS@
232LIBXML2_LIBS = @LIBXML2_LIBS@ 238LIBXML2_LIBS = @LIBXML2_LIBS@
233LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ 239LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
234 240
241XRANDR_LIBS = @XRANDR_LIBS@
242XRANDR_CFLAGS = @XRANDR_CFLAGS@
243
244XINERAMA_LIBS = @XINERAMA_LIBS@
245XINERAMA_CFLAGS = @XINERAMA_CFLAGS@
246
235## widget.o if USE_X_TOOLKIT, otherwise empty. 247## widget.o if USE_X_TOOLKIT, otherwise empty.
236WIDGET_OBJ=@WIDGET_OBJ@ 248WIDGET_OBJ=@WIDGET_OBJ@
237 249
@@ -260,10 +272,13 @@ W32_OBJ=@W32_OBJ@
260W32_LIBS=@W32_LIBS@ 272W32_LIBS=@W32_LIBS@
261 273
262## emacs.res if HAVE_W32 274## emacs.res if HAVE_W32
263W32_RES=@W32_RES@ 275EMACSRES = @EMACSRES@
276## emacs-*.manifest if HAVE_W32
277EMACS_MANIFEST = @EMACS_MANIFEST@
264## If HAVE_W32, compiler arguments for including 278## If HAVE_W32, compiler arguments for including
265## the resource file in the binary. 279## the resource file in the binary.
266## XXX -Wl,-b -Wl,pe-i386 -Wl,emacs.res 280## Cygwin: -Wl,emacs.res
281## MinGW: emacs.res
267W32_RES_LINK=@W32_RES_LINK@ 282W32_RES_LINK=@W32_RES_LINK@
268 283
269## Empty if !HAVE_X_WINDOWS 284## Empty if !HAVE_X_WINDOWS
@@ -272,6 +287,9 @@ W32_RES_LINK=@W32_RES_LINK@
272## else xfont.o 287## else xfont.o
273FONT_OBJ=@FONT_OBJ@ 288FONT_OBJ=@FONT_OBJ@
274 289
290## Empty for MinGW, cm.o for the rest.
291CM_OBJ=@CM_OBJ@
292
275LIBGPM = @LIBGPM@ 293LIBGPM = @LIBGPM@
276 294
277## -lresolv, or empty. 295## -lresolv, or empty.
@@ -282,8 +300,6 @@ LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
282LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ 300LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
283LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ 301LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
284 302
285LIBACL_LIBS = @LIBACL_LIBS@
286
287LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@ 303LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
288 304
289INTERVALS_H = dispextern.h intervals.h composite.h 305INTERVALS_H = dispextern.h intervals.h composite.h
@@ -292,6 +308,14 @@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
292 308
293RUN_TEMACS = `/bin/pwd`/temacs 309RUN_TEMACS = `/bin/pwd`/temacs
294 310
311## Invoke ../nt/addsection for MinGW, ":" elsewhere.
312TEMACS_POST_LINK = @TEMACS_POST_LINK@
313ADDSECTION = @ADDSECTION@
314EMACS_HEAPSIZE = @EMACS_HEAPSIZE@
315MINGW_TEMACS_POST_LINK = \
316 mv temacs$(EXEEXT) temacs.tmp; \
317 ../nt/addsection temacs.tmp temacs$(EXEEXT) EMHEAP $(EMACS_HEAPSIZE)
318
295UNEXEC_OBJ = @UNEXEC_OBJ@ 319UNEXEC_OBJ = @UNEXEC_OBJ@
296 320
297CANNOT_DUMP=@CANNOT_DUMP@ 321CANNOT_DUMP=@CANNOT_DUMP@
@@ -315,9 +339,9 @@ ALL_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
315 -I$(lib) -I$(srcdir)/../lib \ 339 -I$(lib) -I$(srcdir)/../lib \
316 $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \ 340 $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
317 $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ 341 $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
318 $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \ 342 $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) \
319 $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ 343 $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
320 $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \ 344 $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
321 $(LIBGNUTLS_CFLAGS) \ 345 $(LIBGNUTLS_CFLAGS) \
322 $(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS) 346 $(WARN_CFLAGS) $(WERROR_CFLAGS) $(CFLAGS)
323ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS) 347ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
@@ -325,16 +349,16 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS)
325.SUFFIXES: .m 349.SUFFIXES: .m
326.c.o: 350.c.o:
327 @$(MKDEPDIR) 351 @$(MKDEPDIR)
328 $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $< 352 $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) $<
329.m.o: 353.m.o:
330 @$(MKDEPDIR) 354 @$(MKDEPDIR)
331 $(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $< 355 $(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $(PROFILING_CFLAGS) $<
332 356
333## lastfile must follow all files whose initialized data areas should 357## lastfile must follow all files whose initialized data areas should
334## be dumped as pure by dump-emacs. 358## be dumped as pure by dump-emacs.
335base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ 359base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
336 charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \ 360 charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
337 cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \ 361 $(CM_OBJ) term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
338 emacs.o keyboard.o macros.o keymap.o sysdep.o \ 362 emacs.o keyboard.o macros.o keymap.o sysdep.o \
339 buffer.o filelock.o insdel.o marker.o \ 363 buffer.o filelock.o insdel.o marker.o \
340 minibuf.o fileio.o dired.o \ 364 minibuf.o fileio.o dired.o \
@@ -344,7 +368,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
344 syntax.o $(UNEXEC_OBJ) bytecode.o \ 368 syntax.o $(UNEXEC_OBJ) bytecode.o \
345 process.o gnutls.o callproc.o \ 369 process.o gnutls.o callproc.o \
346 region-cache.o sound.o atimer.o \ 370 region-cache.o sound.o atimer.o \
347 doprnt.o intervals.o textprop.o composite.o xml.o inotify.o \ 371 doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \
348 profiler.o \ 372 profiler.o \
349 thread.o systhread.o \ 373 thread.o systhread.o \
350 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ 374 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
@@ -373,9 +397,9 @@ VMLIMIT_OBJ=@VMLIMIT_OBJ@
373## ralloc.o if !SYSTEM_MALLOC && REL_ALLOC, else empty. 397## ralloc.o if !SYSTEM_MALLOC && REL_ALLOC, else empty.
374RALLOC_OBJ=@RALLOC_OBJ@ 398RALLOC_OBJ=@RALLOC_OBJ@
375 399
376## Empty on Cygwin, lastfile.o elsewhere. 400## Empty on Cygwin and MinGW, lastfile.o elsewhere.
377PRE_ALLOC_OBJ=@PRE_ALLOC_OBJ@ 401PRE_ALLOC_OBJ=@PRE_ALLOC_OBJ@
378## lastfile.o on Cygwin, empty elsewhere. 402## lastfile.o on Cygwin and MinGW, empty elsewhere.
379POST_ALLOC_OBJ=@POST_ALLOC_OBJ@ 403POST_ALLOC_OBJ=@POST_ALLOC_OBJ@
380 404
381## List of object files that make-docfile should not be told about. 405## List of object files that make-docfile should not be told about.
@@ -383,7 +407,9 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
383 $(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS) 407 $(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS)
384 408
385## All object files linked into temacs. $(VMLIMIT_OBJ) should be first. 409## All object files linked into temacs. $(VMLIMIT_OBJ) should be first.
386ALLOBJS = $(VMLIMIT_OBJ) $(obj) $(otherobj) 410## (On MinGW, firstfile.o should be before vm-limit.o.)
411FIRSTFILE_OBJ=@FIRSTFILE_OBJ@
412ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj)
387 413
388## Configure inserts the file lisp.mk at this point, defining $lisp. 414## Configure inserts the file lisp.mk at this point, defining $lisp.
389@lisp_frag@ 415@lisp_frag@
@@ -392,13 +418,13 @@ ALLOBJS = $(VMLIMIT_OBJ) $(obj) $(otherobj)
392## Construct full set of libraries to be linked. 418## Construct full set of libraries to be linked.
393LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ 419LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
394 $(LIBX_OTHER) $(LIBSOUND) \ 420 $(LIBX_OTHER) $(LIBSOUND) \
395 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \ 421 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(LIB_CLOCK_GETTIME) \
396 $(LIB_EACCESS) $(LIB_FDATASYNC) $(LIB_TIMER_TIME) $(DBUS_LIBS) \ 422 $(LIB_EACCESS) $(LIB_FDATASYNC) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
397 $(LIB_EXECINFO) \ 423 $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) \
398 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ 424 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
399 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 425 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
400 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 426 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
401 $(LIBACL_LIBS) $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \ 427 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \
402 $(LIB_MATH) 428 $(LIB_MATH)
403 429
404all: emacs$(EXEEXT) $(OTHER_FILES) 430all: emacs$(EXEEXT) $(OTHER_FILES)
@@ -412,7 +438,8 @@ $(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
412## Strictly speaking, emacs does not depend directly on all of $lisp, 438## Strictly speaking, emacs does not depend directly on all of $lisp,
413## since not all pieces are used on all platforms. But DOC depends 439## since not all pieces are used on all platforms. But DOC depends
414## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here. 440## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here.
415emacs$(EXEEXT): temacs$(EXEEXT) $(etc)/DOC $(lisp) $(leimdir)/leim-list.el 441emacs$(EXEEXT): temacs$(EXEEXT) $(ADDSECTION) \
442 $(etc)/DOC $(lisp) $(leimdir)/leim-list.el
416 if test "$(CANNOT_DUMP)" = "yes"; then \ 443 if test "$(CANNOT_DUMP)" = "yes"; then \
417 rm -f emacs$(EXEEXT); \ 444 rm -f emacs$(EXEEXT); \
418 ln temacs$(EXEEXT) emacs$(EXEEXT); \ 445 ln temacs$(EXEEXT) emacs$(EXEEXT); \
@@ -464,10 +491,10 @@ $(lib)/libgnu.a: $(config_h)
464 cd $(lib) && $(MAKE) libgnu.a 491 cd $(lib) && $(MAKE) libgnu.a
465 492
466temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \ 493temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \
467 $(lib)/libgnu.a $(W32_RES) 494 $(lib)/libgnu.a $(EMACSRES)
468 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \ 495 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
469 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(LIBES) \ 496 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES)
470 $(W32_RES_LINK) 497 $(TEMACS_POST_LINK)
471 test "$(CANNOT_DUMP)" = "yes" || \ 498 test "$(CANNOT_DUMP)" = "yes" || \
472 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT) 499 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT)
473 500
@@ -510,8 +537,9 @@ doc.o: buildobj.h
510 537
511emacs.res: $(ntsource)/emacs.rc \ 538emacs.res: $(ntsource)/emacs.rc \
512 $(ntsource)/icons/emacs.ico \ 539 $(ntsource)/icons/emacs.ico \
513 $(ntsource)/emacs-x86.manifest 540 $(ntsource)/$(EMACS_MANIFEST)
514 $(WINDRES) -O COFF -o $@ $(ntsource)/emacs.rc 541 $(WINDRES) -O COFF --include-dir=$(srcdir)/../nt \
542 -o $@ $(ntsource)/emacs.rc
515 543
516ns-app: emacs$(EXEEXT) 544ns-app: emacs$(EXEEXT)
517 cd ../nextstep && $(MAKE) $(MFLAGS) all 545 cd ../nextstep && $(MAKE) $(MFLAGS) all
@@ -525,6 +553,7 @@ mostlyclean:
525 rm -f bootstrap-emacs$(EXEEXT) emacs-$(version)$(EXEEXT) 553 rm -f bootstrap-emacs$(EXEEXT) emacs-$(version)$(EXEEXT)
526 rm -f buildobj.h 554 rm -f buildobj.h
527 rm -f globals.h gl-stamp 555 rm -f globals.h gl-stamp
556 rm -f *.res
528clean: mostlyclean 557clean: mostlyclean
529 rm -f emacs-*.*.*$(EXEEXT) emacs$(EXEEXT) 558 rm -f emacs-*.*.*$(EXEEXT) emacs$(EXEEXT)
530 -rm -rf $(DEPDIR) 559 -rm -rf $(DEPDIR)
@@ -533,7 +562,7 @@ clean: mostlyclean
533## It should remove all files generated during a compilation/bootstrap, 562## It should remove all files generated during a compilation/bootstrap,
534## but not things like config.status or TAGS. 563## but not things like config.status or TAGS.
535bootstrap-clean: clean 564bootstrap-clean: clean
536 rm -f epaths.h config.h config.stamp stamp-oldxmenu ../etc/DOC-* 565 rm -f epaths.h config.h config.stamp stamp-h1 stamp-oldxmenu
537 if test -f ./.gdbinit; then \ 566 if test -f ./.gdbinit; then \
538 mv ./.gdbinit ./.gdbinit.save; \ 567 mv ./.gdbinit ./.gdbinit.save; \
539 if test -f "$(srcdir)/.gdbinit"; then rm -f ./.gdbinit.save; \ 568 if test -f "$(srcdir)/.gdbinit"; then rm -f ./.gdbinit.save; \
diff --git a/src/alloc.c b/src/alloc.c
index 6da0ac428ab..b5885bdb283 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -319,19 +319,7 @@ static void *min_heap_address, *max_heap_address;
319static struct mem_node mem_z; 319static struct mem_node mem_z;
320#define MEM_NIL &mem_z 320#define MEM_NIL &mem_z
321 321
322static struct Lisp_Vector *allocate_vectorlike (ptrdiff_t);
323static void lisp_free (void *);
324static bool live_vector_p (struct mem_node *, void *);
325static bool live_buffer_p (struct mem_node *, void *);
326static bool live_string_p (struct mem_node *, void *);
327static bool live_cons_p (struct mem_node *, void *);
328static bool live_symbol_p (struct mem_node *, void *);
329static bool live_float_p (struct mem_node *, void *);
330static bool live_misc_p (struct mem_node *, void *);
331static void mark_maybe_object (Lisp_Object);
332static void mark_memory (void *, void *);
333#if GC_MARK_STACK || defined GC_MALLOC_CHECK 322#if GC_MARK_STACK || defined GC_MALLOC_CHECK
334static void mem_init (void);
335static struct mem_node *mem_insert (void *, void *, enum mem_type); 323static struct mem_node *mem_insert (void *, void *, enum mem_type);
336static void mem_insert_fixup (struct mem_node *); 324static void mem_insert_fixup (struct mem_node *);
337static void mem_rotate_left (struct mem_node *); 325static void mem_rotate_left (struct mem_node *);
@@ -341,11 +329,6 @@ static void mem_delete_fixup (struct mem_node *);
341static struct mem_node *mem_find (void *); 329static struct mem_node *mem_find (void *);
342#endif 330#endif
343 331
344
345#if GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS
346static void check_gcpros (void);
347#endif
348
349#endif /* GC_MARK_STACK || GC_MALLOC_CHECK */ 332#endif /* GC_MARK_STACK || GC_MALLOC_CHECK */
350 333
351#ifndef DEADP 334#ifndef DEADP
@@ -1153,7 +1136,7 @@ lisp_align_free (void *block)
1153#define INTERVAL_BLOCK_SIZE \ 1136#define INTERVAL_BLOCK_SIZE \
1154 ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval)) 1137 ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval))
1155 1138
1156/* Intervals are allocated in chunks in form of an interval_block 1139/* Intervals are allocated in chunks in the form of an interval_block
1157 structure. */ 1140 structure. */
1158 1141
1159struct interval_block 1142struct interval_block
@@ -3342,56 +3325,50 @@ free_misc (Lisp_Object misc)
3342 total_free_markers++; 3325 total_free_markers++;
3343} 3326}
3344 3327
3328/* Verify properties of Lisp_Save_Value's representation
3329 that are assumed here and elsewhere. */
3330
3331verify (SAVE_UNUSED == 0);
3332verify ((SAVE_INTEGER | SAVE_POINTER | SAVE_OBJECT) >> SAVE_SLOT_BITS == 0);
3333
3345/* Return a Lisp_Save_Value object with the data saved according to 3334/* Return a Lisp_Save_Value object with the data saved according to
3346 FMT. Format specifiers are `i' for an integer, `p' for a pointer 3335 DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */
3347 and `o' for Lisp_Object. Up to 4 objects can be specified. */
3348 3336
3349Lisp_Object 3337Lisp_Object
3350make_save_value (const char *fmt, ...) 3338make_save_value (enum Lisp_Save_Type save_type, ...)
3351{ 3339{
3352 va_list ap; 3340 va_list ap;
3353 int len = strlen (fmt); 3341 int i;
3354 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3342 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3355 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3343 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3356 3344
3357 eassert (0 < len && len < 5); 3345 eassert (0 < save_type
3358 va_start (ap, fmt); 3346 && (save_type < 1 << (SAVE_TYPE_BITS - 1)
3359 3347 || save_type == SAVE_TYPE_MEMORY));
3360#define INITX(index) \ 3348 p->save_type = save_type;
3361 do { \ 3349 va_start (ap, save_type);
3362 if (len <= index) \ 3350 save_type &= ~ (1 << (SAVE_TYPE_BITS - 1));
3363 p->type ## index = SAVE_UNUSED; \ 3351
3364 else \ 3352 for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS)
3365 { \ 3353 switch (save_type & ((1 << SAVE_SLOT_BITS) - 1))
3366 if (fmt[index] == 'i') \ 3354 {
3367 { \ 3355 case SAVE_POINTER:
3368 p->type ## index = SAVE_INTEGER; \ 3356 p->data[i].pointer = va_arg (ap, void *);
3369 p->data[index].integer = va_arg (ap, ptrdiff_t); \ 3357 break;
3370 } \
3371 else if (fmt[index] == 'p') \
3372 { \
3373 p->type ## index = SAVE_POINTER; \
3374 p->data[index].pointer = va_arg (ap, void *); \
3375 } \
3376 else if (fmt[index] == 'o') \
3377 { \
3378 p->type ## index = SAVE_OBJECT; \
3379 p->data[index].object = va_arg (ap, Lisp_Object); \
3380 } \
3381 else \
3382 emacs_abort (); \
3383 } \
3384 } while (0)
3385 3358
3386 INITX (0); 3359 case SAVE_INTEGER:
3387 INITX (1); 3360 p->data[i].integer = va_arg (ap, ptrdiff_t);
3388 INITX (2); 3361 break;
3389 INITX (3);
3390 3362
3391#undef INITX 3363 case SAVE_OBJECT:
3364 p->data[i].object = va_arg (ap, Lisp_Object);
3365 break;
3366
3367 default:
3368 emacs_abort ();
3369 }
3392 3370
3393 va_end (ap); 3371 va_end (ap);
3394 p->area = 0;
3395 return val; 3372 return val;
3396} 3373}
3397 3374
@@ -3402,11 +3379,8 @@ make_save_pointer (void *pointer)
3402{ 3379{
3403 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3380 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3404 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3381 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3405 3382 p->save_type = SAVE_POINTER;
3406 p->area = 0;
3407 p->type0 = SAVE_POINTER;
3408 p->data[0].pointer = pointer; 3383 p->data[0].pointer = pointer;
3409 p->type1 = p->type2 = p->type3 = SAVE_UNUSED;
3410 return val; 3384 return val;
3411} 3385}
3412 3386
@@ -5197,7 +5171,6 @@ returns nil, because real GC can't be done.
5197See Info node `(elisp)Garbage Collection'. */) 5171See Info node `(elisp)Garbage Collection'. */)
5198 (void) 5172 (void)
5199{ 5173{
5200 struct specbinding *bind;
5201 struct buffer *nextb; 5174 struct buffer *nextb;
5202 char stack_top_variable; 5175 char stack_top_variable;
5203 ptrdiff_t i; 5176 ptrdiff_t i;
@@ -5206,7 +5179,6 @@ See Info node `(elisp)Garbage Collection'. */)
5206 EMACS_TIME start; 5179 EMACS_TIME start;
5207 Lisp_Object retval = Qnil; 5180 Lisp_Object retval = Qnil;
5208 size_t tot_before = 0; 5181 size_t tot_before = 0;
5209 struct backtrace backtrace;
5210 5182
5211 if (abort_on_gc) 5183 if (abort_on_gc)
5212 emacs_abort (); 5184 emacs_abort ();
@@ -5217,12 +5189,7 @@ See Info node `(elisp)Garbage Collection'. */)
5217 return Qnil; 5189 return Qnil;
5218 5190
5219 /* Record this function, so it appears on the profiler's backtraces. */ 5191 /* Record this function, so it appears on the profiler's backtraces. */
5220 backtrace.next = backtrace_list; 5192 record_in_backtrace (Qautomatic_gc, &Qnil, 0);
5221 backtrace.function = Qautomatic_gc;
5222 backtrace.args = &Qnil;
5223 backtrace.nargs = 0;
5224 backtrace.debug_on_exit = 0;
5225 backtrace_list = &backtrace;
5226 5193
5227 check_cons_list (); 5194 check_cons_list ();
5228 5195
@@ -5486,7 +5453,6 @@ See Info node `(elisp)Garbage Collection'. */)
5486 malloc_probe (swept); 5453 malloc_probe (swept);
5487 } 5454 }
5488 5455
5489 backtrace_list = backtrace.next;
5490 return retval; 5456 return retval;
5491} 5457}
5492 5458
@@ -5810,14 +5776,13 @@ mark_object (Lisp_Object arg)
5810 case PVEC_WINDOW: 5776 case PVEC_WINDOW:
5811 { 5777 {
5812 struct window *w = (struct window *) ptr; 5778 struct window *w = (struct window *) ptr;
5813 bool leaf = NILP (w->hchild) && NILP (w->vchild);
5814 5779
5815 mark_vectorlike (ptr); 5780 mark_vectorlike (ptr);
5816 5781
5817 /* Mark glyphs for leaf windows. Marking window 5782 /* Mark glyph matrices, if any. Marking window
5818 matrices is sufficient because frame matrices 5783 matrices is sufficient because frame matrices
5819 use the same glyph memory. */ 5784 use the same glyph memory. */
5820 if (leaf && w->current_matrix) 5785 if (w->current_matrix)
5821 { 5786 {
5822 mark_glyph_matrix (w->current_matrix); 5787 mark_glyph_matrix (w->current_matrix);
5823 mark_glyph_matrix (w->desired_matrix); 5788 mark_glyph_matrix (w->desired_matrix);
@@ -5949,12 +5914,11 @@ mark_object (Lisp_Object arg)
5949 case Lisp_Misc_Save_Value: 5914 case Lisp_Misc_Save_Value:
5950 XMISCANY (obj)->gcmarkbit = 1; 5915 XMISCANY (obj)->gcmarkbit = 1;
5951 { 5916 {
5952 register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); 5917 struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj);
5953 /* If `area' is nonzero, `data[0].pointer' is the address 5918 /* If `save_type' is zero, `data[0].pointer' is the address
5954 of a memory area containing `data[1].integer' potential 5919 of a memory area containing `data[1].integer' potential
5955 Lisp_Objects. */ 5920 Lisp_Objects. */
5956#if GC_MARK_STACK 5921 if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY)
5957 if (ptr->area)
5958 { 5922 {
5959 Lisp_Object *p = ptr->data[0].pointer; 5923 Lisp_Object *p = ptr->data[0].pointer;
5960 ptrdiff_t nelt; 5924 ptrdiff_t nelt;
@@ -5962,17 +5926,12 @@ mark_object (Lisp_Object arg)
5962 mark_maybe_object (*p); 5926 mark_maybe_object (*p);
5963 } 5927 }
5964 else 5928 else
5965#endif /* GC_MARK_STACK */
5966 { 5929 {
5967 /* Find Lisp_Objects in `data[N]' slots and mark them. */ 5930 /* Find Lisp_Objects in `data[N]' slots and mark them. */
5968 if (ptr->type0 == SAVE_OBJECT) 5931 int i;
5969 mark_object (ptr->data[0].object); 5932 for (i = 0; i < SAVE_VALUE_SLOTS; i++)
5970 if (ptr->type1 == SAVE_OBJECT) 5933 if (save_type (ptr, i) == SAVE_OBJECT)
5971 mark_object (ptr->data[1].object); 5934 mark_object (ptr->data[i].object);
5972 if (ptr->type2 == SAVE_OBJECT)
5973 mark_object (ptr->data[2].object);
5974 if (ptr->type3 == SAVE_OBJECT)
5975 mark_object (ptr->data[3].object);
5976 } 5935 }
5977 } 5936 }
5978 break; 5937 break;
diff --git a/src/blockinput.h b/src/blockinput.h
index 192c813073d..6dc22c6f5dd 100644
--- a/src/blockinput.h
+++ b/src/blockinput.h
@@ -67,7 +67,7 @@ extern void unblock_input_to (int);
67BLOCKINPUT_INLINE bool 67BLOCKINPUT_INLINE bool
68input_blocked_p (void) 68input_blocked_p (void)
69{ 69{
70 return 0 < interrupt_input_blocked; 70 return interrupt_input_blocked > 0;
71} 71}
72 72
73INLINE_HEADER_END 73INLINE_HEADER_END
diff --git a/src/buffer.c b/src/buffer.c
index b7b471d6d46..e78962e1550 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1770,7 +1770,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1770 since anything can happen within do_yes_or_no_p. */ 1770 since anything can happen within do_yes_or_no_p. */
1771 1771
1772 /* Don't kill the minibuffer now current. */ 1772 /* Don't kill the minibuffer now current. */
1773 if (EQ (buffer, XWINDOW (minibuf_window)->buffer)) 1773 if (EQ (buffer, XWINDOW (minibuf_window)->contents))
1774 return Qnil; 1774 return Qnil;
1775 1775
1776 /* When we kill an ordinary buffer which shares it's buffer text 1776 /* When we kill an ordinary buffer which shares it's buffer text
@@ -1821,7 +1821,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1821 /* If the buffer now current is shown in the minibuffer and our buffer 1821 /* If the buffer now current is shown in the minibuffer and our buffer
1822 is the sole other buffer give up. */ 1822 is the sole other buffer give up. */
1823 XSETBUFFER (tem, current_buffer); 1823 XSETBUFFER (tem, current_buffer);
1824 if (EQ (tem, XWINDOW (minibuf_window)->buffer) 1824 if (EQ (tem, XWINDOW (minibuf_window)->contents)
1825 && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil))) 1825 && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
1826 return Qnil; 1826 return Qnil;
1827 1827
@@ -2395,8 +2395,9 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2395 BUF_MARKERS(buf) should either be for `buf' or dead. */ 2395 BUF_MARKERS(buf) should either be for `buf' or dead. */
2396 eassert (!m->buffer); 2396 eassert (!m->buffer);
2397 } 2397 }
2398 { /* Some of the C code expects that w->buffer == w->pointm->buffer. 2398 { /* Some of the C code expects that both window markers of a
2399 So since we just swapped the markers between the two buffers, we need 2399 live window points to that window's buffer. So since we
2400 just swapped the markers between the two buffers, we need
2400 to undo the effect of this swap for window markers. */ 2401 to undo the effect of this swap for window markers. */
2401 Lisp_Object w = Fselected_window (), ws = Qnil; 2402 Lisp_Object w = Fselected_window (), ws = Qnil;
2402 Lisp_Object buf1, buf2; 2403 Lisp_Object buf1, buf2;
@@ -2406,12 +2407,19 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2406 { 2407 {
2407 ws = Fcons (w, ws); 2408 ws = Fcons (w, ws);
2408 if (MARKERP (XWINDOW (w)->pointm) 2409 if (MARKERP (XWINDOW (w)->pointm)
2409 && (EQ (XWINDOW (w)->buffer, buf1) 2410 && (EQ (XWINDOW (w)->contents, buf1)
2410 || EQ (XWINDOW (w)->buffer, buf2))) 2411 || EQ (XWINDOW (w)->contents, buf2)))
2411 Fset_marker (XWINDOW (w)->pointm, 2412 Fset_marker (XWINDOW (w)->pointm,
2412 make_number 2413 make_number
2413 (BUF_BEGV (XBUFFER (XWINDOW (w)->buffer))), 2414 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2414 XWINDOW (w)->buffer); 2415 XWINDOW (w)->contents);
2416 if (MARKERP (XWINDOW (w)->start)
2417 && (EQ (XWINDOW (w)->contents, buf1)
2418 || EQ (XWINDOW (w)->contents, buf2)))
2419 Fset_marker (XWINDOW (w)->start,
2420 make_number
2421 (XBUFFER (XWINDOW (w)->contents)->last_window_start),
2422 XWINDOW (w)->contents);
2415 w = Fnext_window (w, Qt, Qt); 2423 w = Fnext_window (w, Qt, Qt);
2416 } 2424 }
2417 } 2425 }
@@ -3894,7 +3902,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
3894 if (buffer_window_count (buf) > 0) 3902 if (buffer_window_count (buf) > 0)
3895 { 3903 {
3896 /* ... it's visible in other window than selected, */ 3904 /* ... it's visible in other window than selected, */
3897 if (buf != XBUFFER (XWINDOW (selected_window)->buffer)) 3905 if (buf != XBUFFER (XWINDOW (selected_window)->contents))
3898 windows_or_buffers_changed = 1; 3906 windows_or_buffers_changed = 1;
3899 /* ... or if we modify an overlay at the end of the buffer 3907 /* ... or if we modify an overlay at the end of the buffer
3900 and so we cannot be sure that window end is still valid. */ 3908 and so we cannot be sure that window end is still valid. */
@@ -5494,6 +5502,8 @@ This is the same as (default-value 'left-margin). */);
5494 DEFVAR_BUFFER_DEFAULTS ("default-tab-width", 5502 DEFVAR_BUFFER_DEFAULTS ("default-tab-width",
5495 tab_width, 5503 tab_width,
5496 doc: /* Default value of `tab-width' for buffers that do not override it. 5504 doc: /* Default value of `tab-width' for buffers that do not override it.
5505NOTE: This controls the display width of a TAB character, and not
5506the size of an indentation step.
5497This is the same as (default-value 'tab-width). */); 5507This is the same as (default-value 'tab-width). */);
5498 5508
5499 DEFVAR_BUFFER_DEFAULTS ("default-case-fold-search", 5509 DEFVAR_BUFFER_DEFAULTS ("default-case-fold-search",
@@ -5685,6 +5695,8 @@ Linefeed indents to this column in Fundamental mode. */);
5685 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width), 5695 DEFVAR_PER_BUFFER ("tab-width", &BVAR (current_buffer, tab_width),
5686 Qintegerp, 5696 Qintegerp,
5687 doc: /* Distance between tab stops (for display of tab characters), in columns. 5697 doc: /* Distance between tab stops (for display of tab characters), in columns.
5698NOTE: This controls the display width of a TAB character, and not
5699the size of an indentation step.
5688This should be an integer greater than zero. */); 5700This should be an integer greater than zero. */);
5689 5701
5690 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil, 5702 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
@@ -5876,29 +5888,44 @@ See also the functions `display-table-slot' and `set-display-table-slot'. */);
5876 DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols), 5888 DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols),
5877 Qintegerp, 5889 Qintegerp,
5878 doc: /* Width of left marginal area for display of a buffer. 5890 doc: /* Width of left marginal area for display of a buffer.
5879A value of nil means no marginal area. */); 5891A value of nil means no marginal area.
5892
5893Setting this variable does not take effect until a new buffer is displayed
5894in a window. To make the change take effect, call `set-window-buffer'. */);
5880 5895
5881 DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols), 5896 DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols),
5882 Qintegerp, 5897 Qintegerp,
5883 doc: /* Width of right marginal area for display of a buffer. 5898 doc: /* Width of right marginal area for display of a buffer.
5884A value of nil means no marginal area. */); 5899A value of nil means no marginal area.
5900
5901Setting this variable does not take effect until a new buffer is displayed
5902in a window. To make the change take effect, call `set-window-buffer'. */);
5885 5903
5886 DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width), 5904 DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width),
5887 Qintegerp, 5905 Qintegerp,
5888 doc: /* Width of this buffer's left fringe (in pixels). 5906 doc: /* Width of this buffer's left fringe (in pixels).
5889A value of 0 means no left fringe is shown in this buffer's window. 5907A value of 0 means no left fringe is shown in this buffer's window.
5890A value of nil means to use the left fringe width from the window's frame. */); 5908A value of nil means to use the left fringe width from the window's frame.
5909
5910Setting this variable does not take effect until a new buffer is displayed
5911in a window. To make the change take effect, call `set-window-buffer'. */);
5891 5912
5892 DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width), 5913 DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width),
5893 Qintegerp, 5914 Qintegerp,
5894 doc: /* Width of this buffer's right fringe (in pixels). 5915 doc: /* Width of this buffer's right fringe (in pixels).
5895A value of 0 means no right fringe is shown in this buffer's window. 5916A value of 0 means no right fringe is shown in this buffer's window.
5896A value of nil means to use the right fringe width from the window's frame. */); 5917A value of nil means to use the right fringe width from the window's frame.
5918
5919Setting this variable does not take effect until a new buffer is displayed
5920in a window. To make the change take effect, call `set-window-buffer'. */);
5897 5921
5898 DEFVAR_PER_BUFFER ("fringes-outside-margins", &BVAR (current_buffer, fringes_outside_margins), 5922 DEFVAR_PER_BUFFER ("fringes-outside-margins", &BVAR (current_buffer, fringes_outside_margins),
5899 Qnil, 5923 Qnil,
5900 doc: /* Non-nil means to display fringes outside display margins. 5924 doc: /* Non-nil means to display fringes outside display margins.
5901A value of nil means to display fringes between margins and buffer text. */); 5925A value of nil means to display fringes between margins and buffer text.
5926
5927Setting this variable does not take effect until a new buffer is displayed
5928in a window. To make the change take effect, call `set-window-buffer'. */);
5902 5929
5903 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width), 5930 DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
5904 Qintegerp, 5931 Qintegerp,
diff --git a/src/bytecode.c b/src/bytecode.c
index 45fe5d49154..9e5f4d1434f 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -657,9 +657,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
657 the table clearer. */ 657 the table clearer. */
658#define LABEL(OP) [OP] = &&insn_ ## OP 658#define LABEL(OP) [OP] = &&insn_ ## OP
659 659
660#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ 660#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
661# pragma GCC diagnostic push 661# pragma GCC diagnostic push
662# pragma GCC diagnostic ignored "-Woverride-init" 662# pragma GCC diagnostic ignored "-Woverride-init"
663#elif defined __clang__
664# pragma GCC diagnostic push
665# pragma GCC diagnostic ignored "-Winitializer-overrides"
663#endif 666#endif
664 667
665 /* This is the dispatch table for the threaded interpreter. */ 668 /* This is the dispatch table for the threaded interpreter. */
@@ -673,7 +676,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
673#undef DEFINE 676#undef DEFINE
674 }; 677 };
675 678
676#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ 679#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) || defined __clang__
677# pragma GCC diagnostic pop 680# pragma GCC diagnostic pop
678#endif 681#endif
679 682
diff --git a/src/callint.c b/src/callint.c
index 212dd2e3d62..0651b68dc05 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -34,6 +34,7 @@ static Lisp_Object Qcommand_debug_status;
34static Lisp_Object Qenable_recursive_minibuffers; 34static Lisp_Object Qenable_recursive_minibuffers;
35 35
36static Lisp_Object Qhandle_shift_selection; 36static Lisp_Object Qhandle_shift_selection;
37static Lisp_Object Qread_number;
37 38
38Lisp_Object Qmouse_leave_buffer_hook; 39Lisp_Object Qmouse_leave_buffer_hook;
39 40
@@ -250,6 +251,9 @@ invoke it. If KEYS is omitted or nil, the return value of
250`this-command-keys-vector' is used. */) 251`this-command-keys-vector' is used. */)
251 (Lisp_Object function, Lisp_Object record_flag, Lisp_Object keys) 252 (Lisp_Object function, Lisp_Object record_flag, Lisp_Object keys)
252{ 253{
254 /* `args' will contain the array of arguments to pass to the function.
255 `visargs' will contain the same list but in a nicer form, so that if we
256 pass it to `Fformat' it will be understandable to a human. */
253 Lisp_Object *args, *visargs; 257 Lisp_Object *args, *visargs;
254 Lisp_Object specs; 258 Lisp_Object specs;
255 Lisp_Object filter_specs; 259 Lisp_Object filter_specs;
@@ -683,29 +687,10 @@ invoke it. If KEYS is omitted or nil, the return value of
683 if (!NILP (prefix_arg)) 687 if (!NILP (prefix_arg))
684 goto have_prefix_arg; 688 goto have_prefix_arg;
685 case 'n': /* Read number from minibuffer. */ 689 case 'n': /* Read number from minibuffer. */
686 { 690 args[i] = call1 (Qread_number, callint_message);
687 bool first = 1; 691 /* Passing args[i] directly stimulates compiler bug. */
688 do 692 teml = args[i];
689 { 693 visargs[i] = Fnumber_to_string (teml);
690 Lisp_Object str;
691 if (! first)
692 {
693 message1 ("Please enter a number.");
694 sit_for (make_number (1), 0, 0);
695 }
696 first = 0;
697
698 str = Fread_from_minibuffer (callint_message,
699 Qnil, Qnil, Qnil, Qnil, Qnil,
700 Qnil);
701 if (! STRINGP (str) || SCHARS (str) == 0)
702 args[i] = Qnil;
703 else
704 args[i] = Fread (str);
705 }
706 while (! NUMBERP (args[i]));
707 }
708 visargs[i] = args[i];
709 break; 694 break;
710 695
711 case 'P': /* Prefix arg in raw form. Does no I/O. */ 696 case 'P': /* Prefix arg in raw form. Does no I/O. */
@@ -754,12 +739,12 @@ invoke it. If KEYS is omitted or nil, the return value of
754 break; 739 break;
755 740
756 case 'x': /* Lisp expression read but not evaluated. */ 741 case 'x': /* Lisp expression read but not evaluated. */
757 args[i] = Fread_minibuffer (callint_message, Qnil); 742 args[i] = call1 (intern ("read-minibuffer"), callint_message);
758 visargs[i] = last_minibuf_string; 743 visargs[i] = last_minibuf_string;
759 break; 744 break;
760 745
761 case 'X': /* Lisp expression read and evaluated. */ 746 case 'X': /* Lisp expression read and evaluated. */
762 args[i] = Feval_minibuffer (callint_message, Qnil); 747 args[i] = call1 (intern ("eval-minibuffer"), callint_message);
763 visargs[i] = last_minibuf_string; 748 visargs[i] = last_minibuf_string;
764 break; 749 break;
765 750
@@ -811,6 +796,8 @@ invoke it. If KEYS is omitted or nil, the return value of
811 796
812 if (arg_from_tty || !NILP (record_flag)) 797 if (arg_from_tty || !NILP (record_flag))
813 { 798 {
799 /* We don't need `visargs' any more, so let's recycle it since we need
800 an array of just the same size. */
814 visargs[0] = function; 801 visargs[0] = function;
815 for (i = 1; i < nargs; i++) 802 for (i = 1; i < nargs; i++)
816 { 803 {
@@ -903,6 +890,7 @@ syms_of_callint (void)
903 DEFSYM (Qminus, "-"); 890 DEFSYM (Qminus, "-");
904 DEFSYM (Qplus, "+"); 891 DEFSYM (Qplus, "+");
905 DEFSYM (Qhandle_shift_selection, "handle-shift-selection"); 892 DEFSYM (Qhandle_shift_selection, "handle-shift-selection");
893 DEFSYM (Qread_number, "read-number");
906 DEFSYM (Qcall_interactively, "call-interactively"); 894 DEFSYM (Qcall_interactively, "call-interactively");
907 DEFSYM (Qcommand_debug_status, "command-debug-status"); 895 DEFSYM (Qcommand_debug_status, "command-debug-status");
908 DEFSYM (Qenable_recursive_minibuffers, "enable-recursive-minibuffers"); 896 DEFSYM (Qenable_recursive_minibuffers, "enable-recursive-minibuffers");
diff --git a/src/callproc.c b/src/callproc.c
index 9132c0dd976..745d58c45f4 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1,5 +1,5 @@
1/* Synchronous subprocess invocation for GNU Emacs. 1/* Synchronous subprocess invocation for GNU Emacs.
2 Copyright (C) 1985-1988, 1993-1995, 1999-2012 2 Copyright (C) 1985-1988, 1993-1995, 1999-2013
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -125,7 +125,7 @@ record_kill_process (struct Lisp_Process *p)
125static Lisp_Object 125static Lisp_Object
126call_process_kill (Lisp_Object ignored) 126call_process_kill (Lisp_Object ignored)
127{ 127{
128 if (0 <= synch_process_fd) 128 if (synch_process_fd >= 0)
129 emacs_close (synch_process_fd); 129 emacs_close (synch_process_fd);
130 130
131 if (synch_process_pid) 131 if (synch_process_pid)
@@ -173,7 +173,7 @@ call_process_cleanup (Lisp_Object arg)
173 } 173 }
174#endif 174#endif
175 175
176 if (0 <= synch_process_fd) 176 if (synch_process_fd >= 0)
177 emacs_close (synch_process_fd); 177 emacs_close (synch_process_fd);
178 178
179#ifdef MSDOS 179#ifdef MSDOS
@@ -190,11 +190,11 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0,
190 doc: /* Call PROGRAM synchronously in separate process. 190 doc: /* Call PROGRAM synchronously in separate process.
191The remaining arguments are optional. 191The remaining arguments are optional.
192The program's input comes from file INFILE (nil means `/dev/null'). 192The program's input comes from file INFILE (nil means `/dev/null').
193Insert output in BUFFER before point; t means current buffer; nil for BUFFER 193Insert output in DESTINATION before point; t means current buffer; nil for DESTINATION
194 means discard it; 0 means discard and don't wait; and `(:file FILE)', where 194 means discard it; 0 means discard and don't wait; and `(:file FILE)', where
195 FILE is a file name string, means that it should be written to that file 195 FILE is a file name string, means that it should be written to that file
196 \(if the file already exists it is overwritten). 196 \(if the file already exists it is overwritten).
197BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, 197DESTINATION can also have the form (REAL-BUFFER STDERR-FILE); in that case,
198REAL-BUFFER says what to do with standard output, as above, 198REAL-BUFFER says what to do with standard output, as above,
199while STDERR-FILE says what to do with standard error in the child. 199while STDERR-FILE says what to do with standard error in the child.
200STDERR-FILE may be nil (discard standard error output), 200STDERR-FILE may be nil (discard standard error output),
@@ -207,12 +207,12 @@ If executable PROGRAM can't be found as an executable, `call-process'
207signals a Lisp error. `call-process' reports errors in execution of 207signals a Lisp error. `call-process' reports errors in execution of
208the program only through its return and output. 208the program only through its return and output.
209 209
210If BUFFER is 0, `call-process' returns immediately with value nil. 210If DESTINATION is 0, `call-process' returns immediately with value nil.
211Otherwise it waits for PROGRAM to terminate 211Otherwise it waits for PROGRAM to terminate
212and returns a numeric exit status or a signal description string. 212and returns a numeric exit status or a signal description string.
213If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. 213If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
214 214
215usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) 215usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */)
216 (ptrdiff_t nargs, Lisp_Object *args) 216 (ptrdiff_t nargs, Lisp_Object *args)
217{ 217{
218 Lisp_Object infile, buffer, current_dir, path; 218 Lisp_Object infile, buffer, current_dir, path;
@@ -682,7 +682,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
682 682
683 child_errno = errno; 683 child_errno = errno;
684 684
685 if (0 < pid) 685 if (pid > 0)
686 { 686 {
687 if (INTEGERP (buffer)) 687 if (INTEGERP (buffer))
688 record_deleted_pid (pid); 688 record_deleted_pid (pid);
diff --git a/src/casetab.c b/src/casetab.c
index 76f72b26db3..5f3c8db2869 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -246,7 +246,7 @@ void
246init_casetab_once (void) 246init_casetab_once (void)
247{ 247{
248 register int i; 248 register int i;
249 Lisp_Object down, up; 249 Lisp_Object down, up, eqv;
250 DEFSYM (Qcase_table, "case-table"); 250 DEFSYM (Qcase_table, "case-table");
251 251
252 /* Intern this now in case it isn't already done. 252 /* Intern this now in case it isn't already done.
@@ -275,13 +275,21 @@ init_casetab_once (void)
275 275
276 for (i = 0; i < 128; i++) 276 for (i = 0; i < 128; i++)
277 { 277 {
278 int c = (i >= 'a' && i <= 'z') ? i + ('A' - 'a') : i;
279 CHAR_TABLE_SET (up, i, make_number (c));
280 }
281
282 eqv = Fmake_char_table (Qcase_table, Qnil);
283
284 for (i = 0; i < 128; i++)
285 {
278 int c = ((i >= 'A' && i <= 'Z') ? i + ('a' - 'A') 286 int c = ((i >= 'A' && i <= 'Z') ? i + ('a' - 'A')
279 : ((i >= 'a' && i <= 'z') ? i + ('A' - 'a') 287 : ((i >= 'a' && i <= 'z') ? i + ('A' - 'a')
280 : i)); 288 : i));
281 CHAR_TABLE_SET (up, i, make_number (c)); 289 CHAR_TABLE_SET (eqv, i, make_number (c));
282 } 290 }
283 291
284 set_char_table_extras (down, 2, Fcopy_sequence (up)); 292 set_char_table_extras (down, 2, eqv);
285 293
286 /* Fill in what isn't filled in. */ 294 /* Fill in what isn't filled in. */
287 set_case_table (down, 1); 295 set_case_table (down, 1);
diff --git a/src/ccl.c b/src/ccl.c
index 7f77e1d22fa..8fec18296a6 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -2130,7 +2130,7 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
2130 produced_chars += ccl.produced; 2130 produced_chars += ccl.produced;
2131 offset = outp - outbuf; 2131 offset = outp - outbuf;
2132 shortfall = ccl.produced * max_expansion - (outbufsize - offset); 2132 shortfall = ccl.produced * max_expansion - (outbufsize - offset);
2133 if (0 < shortfall) 2133 if (shortfall > 0)
2134 { 2134 {
2135 outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1); 2135 outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1);
2136 outp = outbuf + offset; 2136 outp = outbuf + offset;
diff --git a/src/cm.c b/src/cm.c
index 3a5f927eda3..481ac15e435 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -214,7 +214,7 @@ calccost (struct tty_display_info *tty,
214 if (doit) 214 if (doit)
215 do 215 do
216 emacs_tputs (tty, p, 1, cmputc); 216 emacs_tputs (tty, p, 1, cmputc);
217 while (0 < --deltay); 217 while (--deltay > 0);
218x: 218x:
219 if ((deltax = dstx - srcx) == 0) 219 if ((deltax = dstx - srcx) == 0)
220 goto done; 220 goto done;
@@ -297,7 +297,7 @@ fail:
297 if (doit) 297 if (doit)
298 do 298 do
299 emacs_tputs (tty, p, 1, cmputc); 299 emacs_tputs (tty, p, 1, cmputc);
300 while (0 < --deltax); 300 while (--deltax > 0);
301done: 301done:
302 return totalcost; 302 return totalcost;
303} 303}
diff --git a/src/coding.c b/src/coding.c
index 6cfcec905a1..42fd81b6322 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -1125,6 +1125,14 @@ alloc_destination (struct coding_system *coding, ptrdiff_t nbytes,
1125 *buf++ = id; \ 1125 *buf++ = id; \
1126 } while (0) 1126 } while (0)
1127 1127
1128
1129/* Bitmasks for coding->eol_seen. */
1130
1131#define EOL_SEEN_NONE 0
1132#define EOL_SEEN_LF 1
1133#define EOL_SEEN_CR 2
1134#define EOL_SEEN_CRLF 4
1135
1128 1136
1129/*** 2. Emacs' internal format (emacs-utf-8) ***/ 1137/*** 2. Emacs' internal format (emacs-utf-8) ***/
1130 1138
@@ -1147,6 +1155,9 @@ alloc_destination (struct coding_system *coding, ptrdiff_t nbytes,
1147#define UTF_8_BOM_2 0xBB 1155#define UTF_8_BOM_2 0xBB
1148#define UTF_8_BOM_3 0xBF 1156#define UTF_8_BOM_3 0xBF
1149 1157
1158/* Unlike the other detect_coding_XXX, this function counts number of
1159 characters and check EOL format. */
1160
1150static bool 1161static bool
1151detect_coding_utf_8 (struct coding_system *coding, 1162detect_coding_utf_8 (struct coding_system *coding,
1152 struct coding_detection_info *detect_info) 1163 struct coding_detection_info *detect_info)
@@ -1156,11 +1167,23 @@ detect_coding_utf_8 (struct coding_system *coding,
1156 bool multibytep = coding->src_multibyte; 1167 bool multibytep = coding->src_multibyte;
1157 ptrdiff_t consumed_chars = 0; 1168 ptrdiff_t consumed_chars = 0;
1158 bool bom_found = 0; 1169 bool bom_found = 0;
1159 bool found = 0; 1170 int nchars = coding->head_ascii;
1171 int eol_seen = coding->eol_seen;
1160 1172
1161 detect_info->checked |= CATEGORY_MASK_UTF_8; 1173 detect_info->checked |= CATEGORY_MASK_UTF_8;
1162 /* A coding system of this category is always ASCII compatible. */ 1174 /* A coding system of this category is always ASCII compatible. */
1163 src += coding->head_ascii; 1175 src += nchars;
1176
1177 if (src == coding->source /* BOM should be at the head. */
1178 && src + 3 < src_end /* BOM is 3-byte long. */
1179 && src[0] == UTF_8_BOM_1
1180 && src[1] == UTF_8_BOM_2
1181 && src[2] == UTF_8_BOM_3)
1182 {
1183 bom_found = 1;
1184 src += 3;
1185 nchars++;
1186 }
1164 1187
1165 while (1) 1188 while (1)
1166 { 1189 {
@@ -1169,13 +1192,29 @@ detect_coding_utf_8 (struct coding_system *coding,
1169 src_base = src; 1192 src_base = src;
1170 ONE_MORE_BYTE (c); 1193 ONE_MORE_BYTE (c);
1171 if (c < 0 || UTF_8_1_OCTET_P (c)) 1194 if (c < 0 || UTF_8_1_OCTET_P (c))
1172 continue; 1195 {
1196 nchars++;
1197 if (c == '\r')
1198 {
1199 if (src < src_end && *src == '\n')
1200 {
1201 eol_seen |= EOL_SEEN_CRLF;
1202 src++;
1203 nchars++;
1204 }
1205 else
1206 eol_seen |= EOL_SEEN_CR;
1207 }
1208 else if (c == '\n')
1209 eol_seen |= EOL_SEEN_LF;
1210 continue;
1211 }
1173 ONE_MORE_BYTE (c1); 1212 ONE_MORE_BYTE (c1);
1174 if (c1 < 0 || ! UTF_8_EXTRA_OCTET_P (c1)) 1213 if (c1 < 0 || ! UTF_8_EXTRA_OCTET_P (c1))
1175 break; 1214 break;
1176 if (UTF_8_2_OCTET_LEADING_P (c)) 1215 if (UTF_8_2_OCTET_LEADING_P (c))
1177 { 1216 {
1178 found = 1; 1217 nchars++;
1179 continue; 1218 continue;
1180 } 1219 }
1181 ONE_MORE_BYTE (c2); 1220 ONE_MORE_BYTE (c2);
@@ -1183,10 +1222,7 @@ detect_coding_utf_8 (struct coding_system *coding,
1183 break; 1222 break;
1184 if (UTF_8_3_OCTET_LEADING_P (c)) 1223 if (UTF_8_3_OCTET_LEADING_P (c))
1185 { 1224 {
1186 found = 1; 1225 nchars++;
1187 if (src_base == coding->source
1188 && c == UTF_8_BOM_1 && c1 == UTF_8_BOM_2 && c2 == UTF_8_BOM_3)
1189 bom_found = 1;
1190 continue; 1226 continue;
1191 } 1227 }
1192 ONE_MORE_BYTE (c3); 1228 ONE_MORE_BYTE (c3);
@@ -1194,7 +1230,7 @@ detect_coding_utf_8 (struct coding_system *coding,
1194 break; 1230 break;
1195 if (UTF_8_4_OCTET_LEADING_P (c)) 1231 if (UTF_8_4_OCTET_LEADING_P (c))
1196 { 1232 {
1197 found = 1; 1233 nchars++;
1198 continue; 1234 continue;
1199 } 1235 }
1200 ONE_MORE_BYTE (c4); 1236 ONE_MORE_BYTE (c4);
@@ -1202,7 +1238,7 @@ detect_coding_utf_8 (struct coding_system *coding,
1202 break; 1238 break;
1203 if (UTF_8_5_OCTET_LEADING_P (c)) 1239 if (UTF_8_5_OCTET_LEADING_P (c))
1204 { 1240 {
1205 found = 1; 1241 nchars++;
1206 continue; 1242 continue;
1207 } 1243 }
1208 break; 1244 break;
@@ -1219,14 +1255,17 @@ detect_coding_utf_8 (struct coding_system *coding,
1219 if (bom_found) 1255 if (bom_found)
1220 { 1256 {
1221 /* The first character 0xFFFE doesn't necessarily mean a BOM. */ 1257 /* The first character 0xFFFE doesn't necessarily mean a BOM. */
1222 detect_info->found |= CATEGORY_MASK_UTF_8_SIG | CATEGORY_MASK_UTF_8_NOSIG; 1258 detect_info->found |= CATEGORY_MASK_UTF_8_AUTO | CATEGORY_MASK_UTF_8_SIG | CATEGORY_MASK_UTF_8_NOSIG;
1223 } 1259 }
1224 else 1260 else
1225 { 1261 {
1226 detect_info->rejected |= CATEGORY_MASK_UTF_8_SIG; 1262 detect_info->rejected |= CATEGORY_MASK_UTF_8_SIG;
1227 if (found) 1263 if (nchars < src_end - coding->source)
1228 detect_info->found |= CATEGORY_MASK_UTF_8_NOSIG; 1264 /* The found characters are less than source bytes, which
1265 means that we found a valid non-ASCII characters. */
1266 detect_info->found |= CATEGORY_MASK_UTF_8_AUTO | CATEGORY_MASK_UTF_8_NOSIG;
1229 } 1267 }
1268 coding->detected_utf8_chars = nchars;
1230 return 1; 1269 return 1;
1231} 1270}
1232 1271
@@ -3887,6 +3926,14 @@ decode_coding_iso_2022 (struct coding_system *coding)
3887 *charbuf++ = c < 0 ? -c : ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c); 3926 *charbuf++ = c < 0 ? -c : ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
3888 char_offset++; 3927 char_offset++;
3889 coding->errors++; 3928 coding->errors++;
3929 /* Reset the invocation and designation status to the safest
3930 one; i.e. designate ASCII to the graphic register 0, and
3931 invoke that register to the graphic plane 0. This typically
3932 helps the case that an designation sequence for ASCII "ESC (
3933 B" is somehow broken (e.g. broken by a newline). */
3934 CODING_ISO_INVOCATION (coding, 0) = 0;
3935 CODING_ISO_DESIGNATION (coding, 0) = charset_ascii;
3936 charset_id_0 = charset_ascii;
3890 continue; 3937 continue;
3891 3938
3892 break_loop: 3939 break_loop:
@@ -5614,7 +5661,6 @@ setup_coding_system (Lisp_Object coding_system, struct coding_system *coding)
5614 eol_type = inhibit_eol_conversion ? Qunix : CODING_ID_EOL_TYPE (coding->id); 5661 eol_type = inhibit_eol_conversion ? Qunix : CODING_ID_EOL_TYPE (coding->id);
5615 5662
5616 coding->mode = 0; 5663 coding->mode = 0;
5617 coding->head_ascii = -1;
5618 if (VECTORP (eol_type)) 5664 if (VECTORP (eol_type))
5619 coding->common_flags = (CODING_REQUIRE_DECODING_MASK 5665 coding->common_flags = (CODING_REQUIRE_DECODING_MASK
5620 | CODING_REQUIRE_DETECTION_MASK); 5666 | CODING_REQUIRE_DETECTION_MASK);
@@ -6066,51 +6112,40 @@ complement_process_encoding_system (Lisp_Object coding_system)
6066 6112
6067*/ 6113*/
6068 6114
6069#define EOL_SEEN_NONE 0 6115static Lisp_Object adjust_coding_eol_type (struct coding_system *coding,
6070#define EOL_SEEN_LF 1 6116 int eol_seen);
6071#define EOL_SEEN_CR 2
6072#define EOL_SEEN_CRLF 4
6073 6117
6074 6118
6075static Lisp_Object adjust_coding_eol_type (struct coding_system *coding, int eol_seen); 6119/* Return the number of ASCII characters at the head of the source.
6120 By side effects, set coding->head_ascii and update
6121 coding->eol_seen. The value of coding->eol_seen is "logical or" of
6122 EOL_SEEN_LF, EOL_SEEN_CR, and EOL_SEEN_CRLF, but the value is
6123 reliable only when all the source bytes are ASCII. */
6076 6124
6077 6125static int
6078/* Return 1 if all the source bytes are ASCII, and return 0 otherwize. 6126check_ascii (struct coding_system *coding)
6079 By side effects, set coding->head_ascii and coding->eol_seen. The
6080 value of coding->eol_seen is "logical or" of EOL_SEEN_LF,
6081 EOL_SEEN_CR, and EOL_SEEN_CRLF, but the value is reliable only when
6082 all the source bytes are ASCII. */
6083
6084static bool
6085detect_ascii (struct coding_system *coding)
6086{ 6127{
6087 const unsigned char *src, *end; 6128 const unsigned char *src, *end;
6088 Lisp_Object eol_type = CODING_ID_EOL_TYPE (coding->id); 6129 Lisp_Object eol_type = CODING_ID_EOL_TYPE (coding->id);
6089 int eol_seen; 6130 int eol_seen = coding->eol_seen;
6090 6131
6091 eol_seen = (VECTORP (eol_type) ? EOL_SEEN_NONE
6092 : EQ (eol_type, Qunix) ? EOL_SEEN_LF
6093 : EQ (eol_type, Qdos) ? EOL_SEEN_CRLF
6094 : EOL_SEEN_CR);
6095 coding_set_source (coding); 6132 coding_set_source (coding);
6096 src = coding->source; 6133 src = coding->source;
6097 end = src + coding->src_bytes; 6134 end = src + coding->src_bytes;
6098 6135
6099 if (inhibit_eol_conversion) 6136 if (inhibit_eol_conversion
6137 || SYMBOLP (eol_type))
6100 { 6138 {
6101 /* We don't have to check EOL format. */ 6139 /* We don't have to check EOL format. */
6102 while (src < end && !( *src & 0x80)) src++; 6140 while (src < end && !( *src & 0x80))
6103 eol_seen = EOL_SEEN_LF; 6141 {
6104 adjust_coding_eol_type (coding, eol_seen); 6142 if (*src++ == '\n')
6105 } 6143 eol_seen |= EOL_SEEN_LF;
6106 else if (eol_seen != EOL_SEEN_NONE) 6144 }
6107 {
6108 /* We don't have to check EOL format either. */
6109 while (src < end && !(*src & 0x80)) src++;
6110 } 6145 }
6111 else 6146 else
6112 { 6147 {
6113 end--; /* We look ahead one byte. */ 6148 end--; /* We look ahead one byte for "CR LF". */
6114 while (src < end) 6149 while (src < end)
6115 { 6150 {
6116 int c = *src; 6151 int c = *src;
@@ -6118,6 +6153,69 @@ detect_ascii (struct coding_system *coding)
6118 if (c & 0x80) 6153 if (c & 0x80)
6119 break; 6154 break;
6120 src++; 6155 src++;
6156 if (c == '\r')
6157 {
6158 if (*src == '\n')
6159 {
6160 eol_seen |= EOL_SEEN_CRLF;
6161 src++;
6162 }
6163 else
6164 eol_seen |= EOL_SEEN_CR;
6165 }
6166 else if (c == '\n')
6167 eol_seen |= EOL_SEEN_LF;
6168 }
6169 if (src == end)
6170 {
6171 int c = *src;
6172
6173 /* All bytes but the last one C are ASCII. */
6174 if (! (c & 0x80))
6175 {
6176 if (c == '\r')
6177 eol_seen |= EOL_SEEN_CR;
6178 else if (c == '\n')
6179 eol_seen |= EOL_SEEN_LF;
6180 src++;
6181 }
6182 }
6183 }
6184 coding->head_ascii = src - coding->source;
6185 coding->eol_seen = eol_seen;
6186 return (coding->head_ascii);
6187}
6188
6189
6190/* Return the number of characters at the source if all the bytes are
6191 valid UTF-8 (of Unicode range). Otherwise, return -1. By side
6192 effects, update coding->eol_seen. The value of coding->eol_seen is
6193 "logical or" of EOL_SEEN_LF, EOL_SEEN_CR, and EOL_SEEN_CRLF, but
6194 the value is reliable only when all the source bytes are valid
6195 UTF-8. */
6196
6197static int
6198check_utf_8 (struct coding_system *coding)
6199{
6200 const unsigned char *src, *end;
6201 int eol_seen;
6202 int nchars = coding->head_ascii;
6203
6204 if (coding->head_ascii < 0)
6205 check_ascii (coding);
6206 else
6207 coding_set_source (coding);
6208 src = coding->source + coding->head_ascii;
6209 /* We look ahead one byte for CR LF. */
6210 end = coding->source + coding->src_bytes - 1;
6211 eol_seen = coding->eol_seen;
6212 while (src < end)
6213 {
6214 int c = *src;
6215
6216 if (UTF_8_1_OCTET_P (*src))
6217 {
6218 src++;
6121 if (c < 0x20) 6219 if (c < 0x20)
6122 { 6220 {
6123 if (c == '\r') 6221 if (c == '\r')
@@ -6126,6 +6224,7 @@ detect_ascii (struct coding_system *coding)
6126 { 6224 {
6127 eol_seen |= EOL_SEEN_CRLF; 6225 eol_seen |= EOL_SEEN_CRLF;
6128 src++; 6226 src++;
6227 nchars++;
6129 } 6228 }
6130 else 6229 else
6131 eol_seen |= EOL_SEEN_CR; 6230 eol_seen |= EOL_SEEN_CR;
@@ -6134,27 +6233,58 @@ detect_ascii (struct coding_system *coding)
6134 eol_seen |= EOL_SEEN_LF; 6233 eol_seen |= EOL_SEEN_LF;
6135 } 6234 }
6136 } 6235 }
6137 if (src > end) 6236 else if (UTF_8_2_OCTET_LEADING_P (c))
6138 /* The last two bytes are CR LF, which means that we have
6139 scanned all bytes. */
6140 end++;
6141 else if (src == end)
6142 { 6237 {
6143 end++; 6238 if (c < 0xC2 /* overlong sequence */
6144 if (! (*src & 0x80)) 6239 || src + 1 >= end
6145 { 6240 || ! UTF_8_EXTRA_OCTET_P (src[1]))
6146 if (*src == '\r') 6241 return -1;
6147 eol_seen |= EOL_SEEN_CR; 6242 src += 2;
6148 else if (*src == '\n')
6149 eol_seen |= EOL_SEEN_LF;
6150 src++;
6151 }
6152 } 6243 }
6153 adjust_coding_eol_type (coding, eol_seen); 6244 else if (UTF_8_3_OCTET_LEADING_P (c))
6245 {
6246 if (src + 2 >= end
6247 || ! (UTF_8_EXTRA_OCTET_P (src[1])
6248 && UTF_8_EXTRA_OCTET_P (src[2])))
6249 return -1;
6250 c = (((c & 0xF) << 12)
6251 | ((src[1] & 0x3F) << 6) | (src[2] & 0x3F));
6252 if (c < 0x800 /* overlong sequence */
6253 || (c >= 0xd800 && c < 0xe000)) /* surrogates (invalid) */
6254 return -1;
6255 src += 3;
6256 }
6257 else if (UTF_8_4_OCTET_LEADING_P (c))
6258 {
6259 if (src + 3 >= end
6260 || ! (UTF_8_EXTRA_OCTET_P (src[1])
6261 && UTF_8_EXTRA_OCTET_P (src[2])
6262 && UTF_8_EXTRA_OCTET_P (src[3])))
6263 return -1;
6264 c = (((c & 0x7) << 18) | ((src[1] & 0x3F) << 12)
6265 | ((src[2] & 0x3F) << 6) | (src[3] & 0x3F));
6266 if (c < 0x10000 /* overlong sequence */
6267 || c >= 0x110000) /* non-Unicode character */
6268 return -1;
6269 src += 4;
6270 }
6271 else
6272 return -1;
6273 nchars++;
6274 }
6275
6276 if (src == end)
6277 {
6278 if (! UTF_8_1_OCTET_P (*src))
6279 return -1;
6280 nchars++;
6281 if (*src == '\r')
6282 eol_seen |= EOL_SEEN_CR;
6283 else if (*src == '\n')
6284 eol_seen |= EOL_SEEN_LF;
6154 } 6285 }
6155 coding->head_ascii = src - coding->source;
6156 coding->eol_seen = eol_seen; 6286 coding->eol_seen = eol_seen;
6157 return (src == end); 6287 return nchars;
6158} 6288}
6159 6289
6160 6290
@@ -6269,6 +6399,9 @@ adjust_coding_eol_type (struct coding_system *coding, int eol_seen)
6269 Lisp_Object eol_type; 6399 Lisp_Object eol_type;
6270 6400
6271 eol_type = CODING_ID_EOL_TYPE (coding->id); 6401 eol_type = CODING_ID_EOL_TYPE (coding->id);
6402 if (! VECTORP (eol_type))
6403 /* Already adjusted. */
6404 return eol_type;
6272 if (eol_seen & EOL_SEEN_LF) 6405 if (eol_seen & EOL_SEEN_LF)
6273 { 6406 {
6274 coding->id = CODING_SYSTEM_ID (AREF (eol_type, 0)); 6407 coding->id = CODING_SYSTEM_ID (AREF (eol_type, 0));
@@ -6296,6 +6429,8 @@ detect_coding (struct coding_system *coding)
6296{ 6429{
6297 const unsigned char *src, *src_end; 6430 const unsigned char *src, *src_end;
6298 unsigned int saved_mode = coding->mode; 6431 unsigned int saved_mode = coding->mode;
6432 Lisp_Object found = Qnil;
6433 Lisp_Object eol_type = CODING_ID_EOL_TYPE (coding->id);
6299 6434
6300 coding->consumed = coding->consumed_char = 0; 6435 coding->consumed = coding->consumed_char = 0;
6301 coding->produced = coding->produced_char = 0; 6436 coding->produced = coding->produced_char = 0;
@@ -6303,6 +6438,7 @@ detect_coding (struct coding_system *coding)
6303 6438
6304 src_end = coding->source + coding->src_bytes; 6439 src_end = coding->source + coding->src_bytes;
6305 6440
6441 coding->eol_seen = EOL_SEEN_NONE;
6306 /* If we have not yet decided the text encoding type, detect it 6442 /* If we have not yet decided the text encoding type, detect it
6307 now. */ 6443 now. */
6308 if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qundecided)) 6444 if (EQ (CODING_ATTR_TYPE (CODING_ID_ATTRS (coding->id)), Qundecided))
@@ -6312,7 +6448,6 @@ detect_coding (struct coding_system *coding)
6312 bool null_byte_found = 0, eight_bit_found = 0; 6448 bool null_byte_found = 0, eight_bit_found = 0;
6313 6449
6314 coding->head_ascii = 0; 6450 coding->head_ascii = 0;
6315 coding->eol_seen = EOL_SEEN_NONE;
6316 detect_info.checked = detect_info.found = detect_info.rejected = 0; 6451 detect_info.checked = detect_info.found = detect_info.rejected = 0;
6317 for (src = coding->source; src < src_end; src++) 6452 for (src = coding->source; src < src_end; src++)
6318 { 6453 {
@@ -6360,7 +6495,8 @@ detect_coding (struct coding_system *coding)
6360 { 6495 {
6361 coding->eol_seen |= EOL_SEEN_CRLF; 6496 coding->eol_seen |= EOL_SEEN_CRLF;
6362 src++; 6497 src++;
6363 coding->head_ascii++; 6498 if (! eight_bit_found)
6499 coding->head_ascii++;
6364 } 6500 }
6365 else 6501 else
6366 coding->eol_seen |= EOL_SEEN_CR; 6502 coding->eol_seen |= EOL_SEEN_CR;
@@ -6422,32 +6558,58 @@ detect_coding (struct coding_system *coding)
6422 } 6558 }
6423 else if ((*(this->detector)) (coding, &detect_info) 6559 else if ((*(this->detector)) (coding, &detect_info)
6424 && detect_info.found & (1 << category)) 6560 && detect_info.found & (1 << category))
6425 { 6561 break;
6426 if (category == coding_category_utf_16_auto)
6427 {
6428 if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
6429 category = coding_category_utf_16_le;
6430 else
6431 category = coding_category_utf_16_be;
6432 }
6433 break;
6434 }
6435 } 6562 }
6436 } 6563 }
6437 6564
6438 if (i < coding_category_raw_text) 6565 if (i < coding_category_raw_text)
6439 setup_coding_system (CODING_ID_NAME (this->id), coding); 6566 {
6567 if (category == coding_category_utf_8_auto)
6568 {
6569 Lisp_Object coding_systems;
6570
6571 coding_systems = AREF (CODING_ID_ATTRS (this->id),
6572 coding_attr_utf_bom);
6573 if (CONSP (coding_systems))
6574 {
6575 if (detect_info.found & CATEGORY_MASK_UTF_8_SIG)
6576 found = XCAR (coding_systems);
6577 else
6578 found = XCDR (coding_systems);
6579 }
6580 else
6581 found = CODING_ID_NAME (this->id);
6582 }
6583 else if (category == coding_category_utf_16_auto)
6584 {
6585 Lisp_Object coding_systems;
6586
6587 coding_systems = AREF (CODING_ID_ATTRS (this->id),
6588 coding_attr_utf_bom);
6589 if (CONSP (coding_systems))
6590 {
6591 if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
6592 found = XCAR (coding_systems);
6593 else if (detect_info.found & CATEGORY_MASK_UTF_16_BE)
6594 found = XCDR (coding_systems);
6595 }
6596 else
6597 found = CODING_ID_NAME (this->id);
6598 }
6599 else
6600 found = CODING_ID_NAME (this->id);
6601 }
6440 else if (null_byte_found) 6602 else if (null_byte_found)
6441 setup_coding_system (Qno_conversion, coding); 6603 found = Qno_conversion;
6442 else if ((detect_info.rejected & CATEGORY_MASK_ANY) 6604 else if ((detect_info.rejected & CATEGORY_MASK_ANY)
6443 == CATEGORY_MASK_ANY) 6605 == CATEGORY_MASK_ANY)
6444 setup_coding_system (Qraw_text, coding); 6606 found = Qraw_text;
6445 else if (detect_info.rejected) 6607 else if (detect_info.rejected)
6446 for (i = 0; i < coding_category_raw_text; i++) 6608 for (i = 0; i < coding_category_raw_text; i++)
6447 if (! (detect_info.rejected & (1 << coding_priorities[i]))) 6609 if (! (detect_info.rejected & (1 << coding_priorities[i])))
6448 { 6610 {
6449 this = coding_categories + coding_priorities[i]; 6611 this = coding_categories + coding_priorities[i];
6450 setup_coding_system (CODING_ID_NAME (this->id), coding); 6612 found = CODING_ID_NAME (this->id);
6451 break; 6613 break;
6452 } 6614 }
6453 } 6615 }
@@ -6461,9 +6623,10 @@ detect_coding (struct coding_system *coding)
6461 coding_systems 6623 coding_systems
6462 = AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_bom); 6624 = AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_bom);
6463 detect_info.found = detect_info.rejected = 0; 6625 detect_info.found = detect_info.rejected = 0;
6464 if (detect_ascii (coding)) 6626 if (check_ascii (coding) == coding->src_bytes)
6465 { 6627 {
6466 setup_coding_system (XCDR (coding_systems), coding); 6628 if (CONSP (coding_systems))
6629 found = XCDR (coding_systems);
6467 } 6630 }
6468 else 6631 else
6469 { 6632 {
@@ -6471,9 +6634,9 @@ detect_coding (struct coding_system *coding)
6471 && detect_coding_utf_8 (coding, &detect_info)) 6634 && detect_coding_utf_8 (coding, &detect_info))
6472 { 6635 {
6473 if (detect_info.found & CATEGORY_MASK_UTF_8_SIG) 6636 if (detect_info.found & CATEGORY_MASK_UTF_8_SIG)
6474 setup_coding_system (XCAR (coding_systems), coding); 6637 found = XCAR (coding_systems);
6475 else 6638 else
6476 setup_coding_system (XCDR (coding_systems), coding); 6639 found = XCDR (coding_systems);
6477 } 6640 }
6478 } 6641 }
6479 } 6642 }
@@ -6487,16 +6650,28 @@ detect_coding (struct coding_system *coding)
6487 = AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_bom); 6650 = AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_bom);
6488 detect_info.found = detect_info.rejected = 0; 6651 detect_info.found = detect_info.rejected = 0;
6489 coding->head_ascii = 0; 6652 coding->head_ascii = 0;
6490 coding->eol_seen = EOL_SEEN_NONE;
6491 if (CONSP (coding_systems) 6653 if (CONSP (coding_systems)
6492 && detect_coding_utf_16 (coding, &detect_info)) 6654 && detect_coding_utf_16 (coding, &detect_info))
6493 { 6655 {
6494 if (detect_info.found & CATEGORY_MASK_UTF_16_LE) 6656 if (detect_info.found & CATEGORY_MASK_UTF_16_LE)
6495 setup_coding_system (XCAR (coding_systems), coding); 6657 found = XCAR (coding_systems);
6496 else if (detect_info.found & CATEGORY_MASK_UTF_16_BE) 6658 else if (detect_info.found & CATEGORY_MASK_UTF_16_BE)
6497 setup_coding_system (XCDR (coding_systems), coding); 6659 found = XCDR (coding_systems);
6498 } 6660 }
6499 } 6661 }
6662
6663 if (! NILP (found))
6664 {
6665 int specified_eol = (VECTORP (eol_type) ? EOL_SEEN_NONE
6666 : EQ (eol_type, Qdos) ? EOL_SEEN_CRLF
6667 : EQ (eol_type, Qmac) ? EOL_SEEN_CR
6668 : EOL_SEEN_LF);
6669
6670 setup_coding_system (found, coding);
6671 if (specified_eol != EOL_SEEN_NONE)
6672 adjust_coding_eol_type (coding, specified_eol);
6673 }
6674
6500 coding->mode = saved_mode; 6675 coding->mode = saved_mode;
6501} 6676}
6502 6677
@@ -7617,19 +7792,55 @@ decode_coding_gap (struct coding_system *coding,
7617 coding->dst_pos_byte = PT_BYTE; 7792 coding->dst_pos_byte = PT_BYTE;
7618 coding->dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 7793 coding->dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
7619 7794
7795 coding->head_ascii = -1;
7796 coding->detected_utf8_chars = -1;
7797 coding->eol_seen = EOL_SEEN_NONE;
7620 if (CODING_REQUIRE_DETECTION (coding)) 7798 if (CODING_REQUIRE_DETECTION (coding))
7621 detect_coding (coding); 7799 detect_coding (coding);
7622 attrs = CODING_ID_ATTRS (coding->id); 7800 attrs = CODING_ID_ATTRS (coding->id);
7623 if (! disable_ascii_optimization) 7801 if (! disable_ascii_optimization
7624 { 7802 && ! coding->src_multibyte
7625 if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)) 7803 && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs))
7626 && NILP (CODING_ATTR_POST_READ (attrs)) 7804 && NILP (CODING_ATTR_POST_READ (attrs))
7627 && NILP (get_translation_table (attrs, 0, NULL)) 7805 && NILP (get_translation_table (attrs, 0, NULL)))
7628 && (coding->head_ascii >= 0 /* We've already called detect_coding */ 7806 {
7629 ? coding->head_ascii == bytes 7807 chars = coding->head_ascii;
7630 : detect_ascii (coding))) 7808 if (chars < 0)
7809 chars = check_ascii (coding);
7810 if (chars != bytes)
7811 {
7812 /* There exists a non-ASCII byte. */
7813 if (EQ (CODING_ATTR_TYPE (attrs), Qutf_8))
7814 {
7815 if (coding->detected_utf8_chars >= 0)
7816 chars = coding->detected_utf8_chars;
7817 else
7818 chars = check_utf_8 (coding);
7819 if (CODING_UTF_8_BOM (coding) != utf_without_bom
7820 && coding->head_ascii == 0
7821 && coding->source[0] == UTF_8_BOM_1
7822 && coding->source[1] == UTF_8_BOM_2
7823 && coding->source[2] == UTF_8_BOM_3)
7824 {
7825 chars--;
7826 bytes -= 3;
7827 coding->src_bytes -= 3;
7828 }
7829 }
7830 else
7831 chars = -1;
7832 }
7833 if (chars >= 0)
7631 { 7834 {
7632 if (coding->eol_seen == EOL_SEEN_CR) 7835 Lisp_Object eol_type;
7836
7837 eol_type = CODING_ID_EOL_TYPE (coding->id);
7838 if (VECTORP (eol_type))
7839 {
7840 if (coding->eol_seen != EOL_SEEN_NONE)
7841 eol_type = adjust_coding_eol_type (coding, coding->eol_seen);
7842 }
7843 if (EQ (eol_type, Qmac))
7633 { 7844 {
7634 unsigned char *src_end = GAP_END_ADDR; 7845 unsigned char *src_end = GAP_END_ADDR;
7635 unsigned char *src = src_end - coding->src_bytes; 7846 unsigned char *src = src_end - coding->src_bytes;
@@ -7640,22 +7851,26 @@ decode_coding_gap (struct coding_system *coding,
7640 src[-1] = '\n'; 7851 src[-1] = '\n';
7641 } 7852 }
7642 } 7853 }
7643 else if (coding->eol_seen == EOL_SEEN_CRLF) 7854 else if (EQ (eol_type, Qdos))
7644 { 7855 {
7645 unsigned char *src = GAP_END_ADDR; 7856 unsigned char *src = GAP_END_ADDR;
7646 unsigned char *src_beg = src - coding->src_bytes; 7857 unsigned char *src_beg = src - coding->src_bytes;
7647 unsigned char *dst = src; 7858 unsigned char *dst = src;
7859 ptrdiff_t diff;
7648 7860
7649 while (src_beg < src) 7861 while (src_beg < src)
7650 { 7862 {
7651 *--dst = *--src; 7863 *--dst = *--src;
7652 if (*src == '\n') 7864 if (*src == '\n' && src > src_beg && src[-1] == '\r')
7653 src--; 7865 src--;
7654 } 7866 }
7655 bytes -= dst - src; 7867 diff = dst - src;
7868 bytes -= diff;
7869 chars -= diff;
7656 } 7870 }
7657 coding->produced_char = coding->produced = bytes; 7871 coding->produced = bytes;
7658 insert_from_gap (bytes, bytes, 1); 7872 coding->produced_char = chars;
7873 insert_from_gap (chars, bytes, 1);
7659 return; 7874 return;
7660 } 7875 }
7661 } 7876 }
diff --git a/src/coding.h b/src/coding.h
index d40209be68f..d13fd42fe4f 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -444,6 +444,8 @@ struct coding_system
444 the eol format. */ 444 the eol format. */
445 ptrdiff_t head_ascii; 445 ptrdiff_t head_ascii;
446 446
447 ptrdiff_t detected_utf8_chars;
448
447 /* Used internally in coding.c. See the comment of detect_ascii. */ 449 /* Used internally in coding.c. See the comment of detect_ascii. */
448 int eol_seen; 450 int eol_seen;
449 451
diff --git a/src/data.c b/src/data.c
index 8a66cbe9197..c6cb1b43dd6 100644
--- a/src/data.c
+++ b/src/data.c
@@ -101,9 +101,10 @@ wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
101} 101}
102 102
103void 103void
104pure_write_error (void) 104pure_write_error (Lisp_Object obj)
105{ 105{
106 error ("Attempt to modify read-only object"); 106 Fsignal (Qerror, Fcons (build_string ("Attempt to modify read-only object"),
107 Fcons (obj, Qnil)));
107} 108}
108 109
109void 110void
@@ -1106,40 +1107,6 @@ DEFUN ("set", Fset, Sset, 2, 2, 0,
1106 return newval; 1107 return newval;
1107} 1108}
1108 1109
1109/* Return true if SYMBOL currently has a let-binding
1110 which was made in the buffer that is now current. */
1111
1112static bool
1113let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
1114{
1115 struct specbinding *p;
1116
1117 for (p = specpdl_ptr; p > specpdl; )
1118 if ((--p)->func == NULL
1119 && CONSP (p->symbol))
1120 {
1121 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (XCAR (p->symbol));
1122 eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS);
1123 if (symbol == let_bound_symbol
1124 && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer)
1125 return 1;
1126 }
1127
1128 return 0;
1129}
1130
1131static bool
1132let_shadows_global_binding_p (Lisp_Object symbol)
1133{
1134 struct specbinding *p;
1135
1136 for (p = specpdl_ptr; p > specpdl; )
1137 if ((--p)->func == NULL && EQ (p->symbol, symbol))
1138 return 1;
1139
1140 return 0;
1141}
1142
1143/* Store the value NEWVAL into SYMBOL. 1110/* Store the value NEWVAL into SYMBOL.
1144 If buffer/frame-locality is an issue, WHERE specifies which context to use. 1111 If buffer/frame-locality is an issue, WHERE specifies which context to use.
1145 (nil stands for the current buffer/frame). 1112 (nil stands for the current buffer/frame).
@@ -1878,17 +1845,18 @@ BUFFER defaults to the current buffer. */)
1878 XSETBUFFER (tmp, buf); 1845 XSETBUFFER (tmp, buf);
1879 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */ 1846 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
1880 1847
1881 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail)) 1848 if (EQ (blv->where, tmp)) /* The binding is already loaded. */
1882 { 1849 return blv_found (blv) ? Qt : Qnil;
1883 elt = XCAR (tail); 1850 else
1884 if (EQ (variable, XCAR (elt))) 1851 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
1885 { 1852 {
1886 eassert (!blv->frame_local); 1853 elt = XCAR (tail);
1887 eassert (blv_found (blv) || !EQ (blv->where, tmp)); 1854 if (EQ (variable, XCAR (elt)))
1888 return Qt; 1855 {
1889 } 1856 eassert (!blv->frame_local);
1890 } 1857 return Qt;
1891 eassert (!blv_found (blv) || !EQ (blv->where, tmp)); 1858 }
1859 }
1892 return Qnil; 1860 return Qnil;
1893 } 1861 }
1894 case SYMBOL_FORWARDED: 1862 case SYMBOL_FORWARDED:
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 863f7634eb5..3ec3c28431b 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -882,7 +882,7 @@ xd_retrieve_arg (int dtype, DBusMessageIter *iter)
882#endif 882#endif
883 { 883 {
884 dbus_uint32_t val; 884 dbus_uint32_t val;
885 unsigned int pval = val; 885 unsigned int pval;
886 dbus_message_iter_get_basic (iter, &val); 886 dbus_message_iter_get_basic (iter, &val);
887 pval = val; 887 pval = val;
888 XD_DEBUG_MESSAGE ("%c %u", dtype, pval); 888 XD_DEBUG_MESSAGE ("%c %u", dtype, pval);
diff --git a/src/dired.c b/src/dired.c
index 0e37568f211..7bbfee7e5b0 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -258,7 +258,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
258 QUIT; 258 QUIT;
259 259
260 if (NILP (match) 260 if (NILP (match)
261 || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0))) 261 || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0)
262 wanted = 1; 262 wanted = 1;
263 263
264 immediate_quit = 0; 264 immediate_quit = 0;
@@ -517,8 +517,9 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
517 517
518 QUIT; 518 QUIT;
519 if (len < SCHARS (encoded_file) 519 if (len < SCHARS (encoded_file)
520 || 0 <= scmp (dp->d_name, SSDATA (encoded_file), 520 || (scmp (dp->d_name, SSDATA (encoded_file),
521 SCHARS (encoded_file))) 521 SCHARS (encoded_file))
522 >= 0))
522 continue; 523 continue;
523 524
524 if (file_name_completion_stat (fd, dp, &st) < 0) 525 if (file_name_completion_stat (fd, dp, &st) < 0)
@@ -580,7 +581,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
580 if (skip < 0) 581 if (skip < 0)
581 continue; 582 continue;
582 583
583 if (0 <= scmp (dp->d_name + skip, p1, elt_len)) 584 if (scmp (dp->d_name + skip, p1, elt_len) >= 0)
584 continue; 585 continue;
585 break; 586 break;
586 } 587 }
@@ -602,9 +603,8 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
602 skip = len - SCHARS (elt); 603 skip = len - SCHARS (elt);
603 if (skip < 0) continue; 604 if (skip < 0) continue;
604 605
605 if (0 <= scmp (dp->d_name + skip, 606 if (scmp (dp->d_name + skip, SSDATA (elt), SCHARS (elt))
606 SSDATA (elt), 607 >= 0)
607 SCHARS (elt)))
608 continue; 608 continue;
609 break; 609 break;
610 } 610 }
diff --git a/src/dispextern.h b/src/dispextern.h
index 46878745c07..50a32ffaf8f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -602,8 +602,8 @@ struct glyph_pool
602 602
603 2. Window glyph matrices on frames having frame glyph matrices. 603 2. Window glyph matrices on frames having frame glyph matrices.
604 Such matrices are sub-matrices of their corresponding frame matrix, 604 Such matrices are sub-matrices of their corresponding frame matrix,
605 i.e. frame glyph matrices and window glyph matrices share the same 605 i.e., frame glyph matrices and window glyph matrices share the same
606 glyph memory which is allocated in form of a glyph_pool structure. 606 glyph memory, which is allocated in the form of a glyph_pool structure.
607 Glyph rows in such a window matrix are slices of frame matrix rows. 607 Glyph rows in such a window matrix are slices of frame matrix rows.
608 608
609 2. Free-standing window glyph matrices managing their own glyph 609 2. Free-standing window glyph matrices managing their own glyph
@@ -1384,7 +1384,7 @@ struct glyph_string
1384 ? current_mode_line_height \ 1384 ? current_mode_line_height \
1385 : (MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \ 1385 : (MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \
1386 ? MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \ 1386 ? MATRIX_MODE_LINE_HEIGHT ((W)->current_matrix) \
1387 : estimate_mode_line_height (XFRAME (W->frame), \ 1387 : estimate_mode_line_height (XFRAME ((W)->frame), \
1388 CURRENT_MODE_LINE_FACE_ID (W)))) 1388 CURRENT_MODE_LINE_FACE_ID (W))))
1389 1389
1390/* Return the current height of the header line of window W. If not 1390/* Return the current height of the header line of window W. If not
@@ -1397,7 +1397,7 @@ struct glyph_string
1397 ? current_header_line_height \ 1397 ? current_header_line_height \
1398 : (MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \ 1398 : (MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \
1399 ? MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \ 1399 ? MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \
1400 : estimate_mode_line_height (XFRAME (W->frame),\ 1400 : estimate_mode_line_height (XFRAME ((W)->frame), \
1401 HEADER_LINE_FACE_ID))) 1401 HEADER_LINE_FACE_ID)))
1402 1402
1403/* Return the height of the desired mode line of window W. */ 1403/* Return the height of the desired mode line of window W. */
@@ -1412,25 +1412,25 @@ struct glyph_string
1412 1412
1413/* Value is non-zero if window W wants a mode line. */ 1413/* Value is non-zero if window W wants a mode line. */
1414 1414
1415#define WINDOW_WANTS_MODELINE_P(W) \ 1415#define WINDOW_WANTS_MODELINE_P(W) \
1416 (!MINI_WINDOW_P ((W)) \ 1416 (!MINI_WINDOW_P ((W)) \
1417 && !(W)->pseudo_window_p \ 1417 && !(W)->pseudo_window_p \
1418 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \ 1418 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
1419 && BUFFERP (W->buffer) \ 1419 && BUFFERP ((W)->contents) \
1420 && !NILP (BVAR (XBUFFER (W->buffer), mode_line_format)) \ 1420 && !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
1421 && WINDOW_TOTAL_LINES (W) > 1) 1421 && WINDOW_TOTAL_LINES (W) > 1)
1422 1422
1423/* Value is true if window W wants a header line. */ 1423/* Value is true if window W wants a header line. */
1424 1424
1425#define WINDOW_WANTS_HEADER_LINE_P(W) \ 1425#define WINDOW_WANTS_HEADER_LINE_P(W) \
1426 (!MINI_WINDOW_P ((W)) \ 1426 (BUFFERP ((W)->contents) \
1427 ? (!MINI_WINDOW_P ((W)) \
1427 && !(W)->pseudo_window_p \ 1428 && !(W)->pseudo_window_p \
1428 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \ 1429 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
1429 && BUFFERP (W->buffer) \ 1430 && !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \
1430 && !NILP (BVAR (XBUFFER (W->buffer), header_line_format)) \ 1431 && WINDOW_TOTAL_LINES (W) > \
1431 && WINDOW_TOTAL_LINES (W) > 1 \ 1432 (1 + !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)))) \
1432 + !NILP (BVAR (XBUFFER (W->buffer), mode_line_format))) 1433 : 0)
1433
1434 1434
1435/* Return proper value to be used as baseline offset of font that has 1435/* Return proper value to be used as baseline offset of font that has
1436 ASCENT and DESCENT to draw characters by the font at the vertical 1436 ASCENT and DESCENT to draw characters by the font at the vertical
@@ -1592,13 +1592,13 @@ struct face
1592 shadow colors derived from the background color of the face. */ 1592 shadow colors derived from the background color of the face. */
1593 enum face_box_type box; 1593 enum face_box_type box;
1594 1594
1595 /* Style of underlining. */
1596 enum face_underline_type underline_type;
1597
1595 /* If `box' above specifies a 3D type, 1 means use box_color for 1598 /* If `box' above specifies a 3D type, 1 means use box_color for
1596 drawing shadows. */ 1599 drawing shadows. */
1597 unsigned use_box_color_for_shadows_p : 1; 1600 unsigned use_box_color_for_shadows_p : 1;
1598 1601
1599 /* Style of underlining. */
1600 enum face_underline_type underline_type;
1601
1602 /* Non-zero if text in this face should be underlined, overlined, 1602 /* Non-zero if text in this face should be underlined, overlined,
1603 strike-through or have a box drawn around it. */ 1603 strike-through or have a box drawn around it. */
1604 unsigned underline_p : 1; 1604 unsigned underline_p : 1;
@@ -3186,7 +3186,15 @@ bool valid_image_p (Lisp_Object);
3186void prepare_image_for_display (struct frame *, struct image *); 3186void prepare_image_for_display (struct frame *, struct image *);
3187ptrdiff_t lookup_image (struct frame *, Lisp_Object); 3187ptrdiff_t lookup_image (struct frame *, Lisp_Object);
3188 3188
3189unsigned long image_background (struct image *, struct frame *, 3189#if defined (HAVE_X_WINDOWS) || defined (HAVE_NS)
3190#define RGB_PIXEL_COLOR unsigned long
3191#endif
3192
3193#ifdef HAVE_NTGUI
3194#define RGB_PIXEL_COLOR COLORREF
3195#endif
3196
3197RGB_PIXEL_COLOR image_background (struct image *, struct frame *,
3190 XImagePtr_or_DC ximg); 3198 XImagePtr_or_DC ximg);
3191int image_background_transparent (struct image *, struct frame *, 3199int image_background_transparent (struct image *, struct frame *,
3192 XImagePtr_or_DC mask); 3200 XImagePtr_or_DC mask);
diff --git a/src/dispnew.c b/src/dispnew.c
index 47adab6b8f7..b4ca654a8f7 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -223,9 +223,9 @@ add_window_display_history (struct window *w, const char *msg, bool paused_p)
223 "%"pMu": window %p (`%s')%s\n%s", 223 "%"pMu": window %p (`%s')%s\n%s",
224 history_tick++, 224 history_tick++,
225 w, 225 w,
226 ((BUFFERP (w->buffer) 226 ((BUFFERP (w->contents)
227 && STRINGP (BVAR (XBUFFER (w->buffer), name))) 227 && STRINGP (BVAR (XBUFFER (w->contents), name)))
228 ? SSDATA (BVAR (XBUFFER (w->buffer), name)) 228 ? SSDATA (BVAR (XBUFFER (w->contents), name))
229 : "???"), 229 : "???"),
230 paused_p ? " ***paused***" : "", 230 paused_p ? " ***paused***" : "",
231 msg); 231 msg);
@@ -363,7 +363,7 @@ margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin
363 363
364 if (NUMBERP (margin)) 364 if (NUMBERP (margin))
365 { 365 {
366 int width = XFASTINT (w->total_cols); 366 int width = w->total_cols;
367 double d = max (0, XFLOATINT (margin)); 367 double d = max (0, XFLOATINT (margin));
368 d = min (width / 2 - 1, d); 368 d = min (width / 2 - 1, d);
369 n = (int) ((double) total_glyphs / width * d); 369 n = (int) ((double) total_glyphs / width * d);
@@ -794,11 +794,13 @@ clear_current_matrices (register struct frame *f)
794 if (f->current_matrix) 794 if (f->current_matrix)
795 clear_glyph_matrix (f->current_matrix); 795 clear_glyph_matrix (f->current_matrix);
796 796
797#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
797 /* Clear the matrix of the menu bar window, if such a window exists. 798 /* Clear the matrix of the menu bar window, if such a window exists.
798 The menu bar window is currently used to display menus on X when 799 The menu bar window is currently used to display menus on X when
799 no toolkit support is compiled in. */ 800 no toolkit support is compiled in. */
800 if (WINDOWP (f->menu_bar_window)) 801 if (WINDOWP (f->menu_bar_window))
801 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix); 802 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
803#endif
802 804
803 /* Clear the matrix of the tool-bar window, if any. */ 805 /* Clear the matrix of the tool-bar window, if any. */
804 if (WINDOWP (f->tool_bar_window)) 806 if (WINDOWP (f->tool_bar_window))
@@ -818,8 +820,10 @@ clear_desired_matrices (register struct frame *f)
818 if (f->desired_matrix) 820 if (f->desired_matrix)
819 clear_glyph_matrix (f->desired_matrix); 821 clear_glyph_matrix (f->desired_matrix);
820 822
823#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
821 if (WINDOWP (f->menu_bar_window)) 824 if (WINDOWP (f->menu_bar_window))
822 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix); 825 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
826#endif
823 827
824 if (WINDOWP (f->tool_bar_window)) 828 if (WINDOWP (f->tool_bar_window))
825 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix); 829 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
@@ -838,16 +842,8 @@ clear_window_matrices (struct window *w, bool desired_p)
838{ 842{
839 while (w) 843 while (w)
840 { 844 {
841 if (!NILP (w->hchild)) 845 if (WINDOWP (w->contents))
842 { 846 clear_window_matrices (XWINDOW (w->contents), desired_p);
843 eassert (WINDOWP (w->hchild));
844 clear_window_matrices (XWINDOW (w->hchild), desired_p);
845 }
846 else if (!NILP (w->vchild))
847 {
848 eassert (WINDOWP (w->vchild));
849 clear_window_matrices (XWINDOW (w->vchild), desired_p);
850 }
851 else 847 else
852 { 848 {
853 if (desired_p) 849 if (desired_p)
@@ -1468,7 +1464,7 @@ check_matrix_invariants (struct window *w)
1468 struct glyph_row *row = matrix->rows; 1464 struct glyph_row *row = matrix->rows;
1469 struct glyph_row *last_text_row = NULL; 1465 struct glyph_row *last_text_row = NULL;
1470 struct buffer *saved = current_buffer; 1466 struct buffer *saved = current_buffer;
1471 struct buffer *buffer = XBUFFER (w->buffer); 1467 struct buffer *buffer = XBUFFER (w->contents);
1472 int c; 1468 int c;
1473 1469
1474 /* This can sometimes happen for a fresh window. */ 1470 /* This can sometimes happen for a fresh window. */
@@ -1632,7 +1628,7 @@ allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
1632 vertically below other windows. */ 1628 vertically below other windows. */
1633 in_horz_combination_p 1629 in_horz_combination_p
1634 = (!NILP (XWINDOW (window)->parent) 1630 = (!NILP (XWINDOW (window)->parent)
1635 && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild)); 1631 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (XWINDOW (window)->parent)));
1636 1632
1637 /* For WINDOW and all windows on the same level. */ 1633 /* For WINDOW and all windows on the same level. */
1638 do 1634 do
@@ -1641,12 +1637,8 @@ allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
1641 1637
1642 /* Get the dimension of the window sub-matrix for W, depending 1638 /* Get the dimension of the window sub-matrix for W, depending
1643 on whether this is a combination or a leaf window. */ 1639 on whether this is a combination or a leaf window. */
1644 if (!NILP (w->hchild)) 1640 if (WINDOWP (w->contents))
1645 dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y, 1641 dim = allocate_matrices_for_frame_redisplay (w->contents, x, y,
1646 dim_only_p,
1647 window_change_flags);
1648 else if (!NILP (w->vchild))
1649 dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
1650 dim_only_p, 1642 dim_only_p,
1651 window_change_flags); 1643 window_change_flags);
1652 else 1644 else
@@ -1776,7 +1768,7 @@ required_matrix_width (struct window *w)
1776 } 1768 }
1777#endif /* HAVE_WINDOW_SYSTEM */ 1769#endif /* HAVE_WINDOW_SYSTEM */
1778 1770
1779 return XINT (w->total_cols); 1771 return w->total_cols;
1780} 1772}
1781 1773
1782 1774
@@ -1788,10 +1780,8 @@ allocate_matrices_for_window_redisplay (struct window *w)
1788{ 1780{
1789 while (w) 1781 while (w)
1790 { 1782 {
1791 if (!NILP (w->vchild)) 1783 if (WINDOWP (w->contents))
1792 allocate_matrices_for_window_redisplay (XWINDOW (w->vchild)); 1784 allocate_matrices_for_window_redisplay (XWINDOW (w->contents));
1793 else if (!NILP (w->hchild))
1794 allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
1795 else 1785 else
1796 { 1786 {
1797 /* W is a leaf window. */ 1787 /* W is a leaf window. */
@@ -1863,18 +1853,12 @@ showing_window_margins_p (struct window *w)
1863{ 1853{
1864 while (w) 1854 while (w)
1865 { 1855 {
1866 if (!NILP (w->hchild)) 1856 if (WINDOWP (w->contents))
1867 { 1857 {
1868 if (showing_window_margins_p (XWINDOW (w->hchild))) 1858 if (showing_window_margins_p (XWINDOW (w->contents)))
1869 return 1; 1859 return 1;
1870 } 1860 }
1871 else if (!NILP (w->vchild)) 1861 else if (!NILP (w->left_margin_cols) || !NILP (w->right_margin_cols))
1872 {
1873 if (showing_window_margins_p (XWINDOW (w->vchild)))
1874 return 1;
1875 }
1876 else if (!NILP (w->left_margin_cols)
1877 || !NILP (w->right_margin_cols))
1878 return 1; 1862 return 1;
1879 1863
1880 w = NILP (w->next) ? 0 : XWINDOW (w->next); 1864 w = NILP (w->next) ? 0 : XWINDOW (w->next);
@@ -1895,10 +1879,8 @@ fake_current_matrices (Lisp_Object window)
1895 { 1879 {
1896 w = XWINDOW (window); 1880 w = XWINDOW (window);
1897 1881
1898 if (!NILP (w->hchild)) 1882 if (WINDOWP (w->contents))
1899 fake_current_matrices (w->hchild); 1883 fake_current_matrices (w->contents);
1900 else if (!NILP (w->vchild))
1901 fake_current_matrices (w->vchild);
1902 else 1884 else
1903 { 1885 {
1904 int i; 1886 int i;
@@ -2114,10 +2096,10 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2114 2096
2115 /* Set window dimensions to frame dimensions and allocate or 2097 /* Set window dimensions to frame dimensions and allocate or
2116 adjust glyph matrices of W. */ 2098 adjust glyph matrices of W. */
2117 wset_top_line (w, make_number (0)); 2099 w->top_line = 0;
2118 wset_left_col (w, make_number (0)); 2100 w->left_col = 0;
2119 wset_total_lines (w, make_number (FRAME_MENU_BAR_LINES (f))); 2101 w->total_lines = FRAME_MENU_BAR_LINES (f);
2120 wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f))); 2102 w->total_cols = FRAME_TOTAL_COLS (f);
2121 allocate_matrices_for_window_redisplay (w); 2103 allocate_matrices_for_window_redisplay (w);
2122 } 2104 }
2123#endif /* not USE_X_TOOLKIT && not USE_GTK */ 2105#endif /* not USE_X_TOOLKIT && not USE_GTK */
@@ -2140,10 +2122,10 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2140 else 2122 else
2141 w = XWINDOW (f->tool_bar_window); 2123 w = XWINDOW (f->tool_bar_window);
2142 2124
2143 wset_top_line (w, make_number (FRAME_MENU_BAR_LINES (f))); 2125 w->top_line = FRAME_MENU_BAR_LINES (f);
2144 wset_left_col (w, make_number (0)); 2126 w->left_col = 0;
2145 wset_total_lines (w, make_number (FRAME_TOOL_BAR_LINES (f))); 2127 w->total_lines = FRAME_TOOL_BAR_LINES (f);
2146 wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f))); 2128 w->total_cols = FRAME_TOTAL_COLS (f);
2147 allocate_matrices_for_window_redisplay (w); 2129 allocate_matrices_for_window_redisplay (w);
2148 } 2130 }
2149#endif 2131#endif
@@ -2184,6 +2166,7 @@ free_glyphs (struct frame *f)
2184 if (!NILP (f->root_window)) 2166 if (!NILP (f->root_window))
2185 free_window_matrices (XWINDOW (f->root_window)); 2167 free_window_matrices (XWINDOW (f->root_window));
2186 2168
2169#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
2187 /* Free the dummy window for menu bars without X toolkit and its 2170 /* Free the dummy window for menu bars without X toolkit and its
2188 glyph matrices. */ 2171 glyph matrices. */
2189 if (!NILP (f->menu_bar_window)) 2172 if (!NILP (f->menu_bar_window))
@@ -2194,6 +2177,7 @@ free_glyphs (struct frame *f)
2194 w->desired_matrix = w->current_matrix = NULL; 2177 w->desired_matrix = w->current_matrix = NULL;
2195 fset_menu_bar_window (f, Qnil); 2178 fset_menu_bar_window (f, Qnil);
2196 } 2179 }
2180#endif
2197 2181
2198 /* Free the tool bar window and its glyph matrices. */ 2182 /* Free the tool bar window and its glyph matrices. */
2199 if (!NILP (f->tool_bar_window)) 2183 if (!NILP (f->tool_bar_window))
@@ -2236,10 +2220,8 @@ free_window_matrices (struct window *w)
2236{ 2220{
2237 while (w) 2221 while (w)
2238 { 2222 {
2239 if (!NILP (w->hchild)) 2223 if (WINDOWP (w->contents))
2240 free_window_matrices (XWINDOW (w->hchild)); 2224 free_window_matrices (XWINDOW (w->contents));
2241 else if (!NILP (w->vchild))
2242 free_window_matrices (XWINDOW (w->vchild));
2243 else 2225 else
2244 { 2226 {
2245 /* This is a leaf window. Free its memory and reset fields 2227 /* This is a leaf window. Free its memory and reset fields
@@ -2372,10 +2354,8 @@ build_frame_matrix_from_window_tree (struct glyph_matrix *matrix, struct window
2372{ 2354{
2373 while (w) 2355 while (w)
2374 { 2356 {
2375 if (!NILP (w->hchild)) 2357 if (WINDOWP (w->contents))
2376 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild)); 2358 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->contents));
2377 else if (!NILP (w->vchild))
2378 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
2379 else 2359 else
2380 build_frame_matrix_from_leaf_window (matrix, w); 2360 build_frame_matrix_from_leaf_window (matrix, w);
2381 2361
@@ -2639,10 +2619,8 @@ mirror_make_current (struct window *w, int frame_row)
2639{ 2619{
2640 while (w) 2620 while (w)
2641 { 2621 {
2642 if (!NILP (w->hchild)) 2622 if (WINDOWP (w->contents))
2643 mirror_make_current (XWINDOW (w->hchild), frame_row); 2623 mirror_make_current (XWINDOW (w->contents), frame_row);
2644 else if (!NILP (w->vchild))
2645 mirror_make_current (XWINDOW (w->vchild), frame_row);
2646 else 2624 else
2647 { 2625 {
2648 /* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS 2626 /* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
@@ -2738,8 +2716,8 @@ sync_window_with_frame_matrix_rows (struct window *w)
2738 struct glyph_row *window_row, *window_row_end, *frame_row; 2716 struct glyph_row *window_row, *window_row_end, *frame_row;
2739 int left, right, x, width; 2717 int left, right, x, width;
2740 2718
2741 /* Preconditions: W must be a leaf window on a tty frame. */ 2719 /* Preconditions: W must be a live window on a tty frame. */
2742 eassert (NILP (w->hchild) && NILP (w->vchild)); 2720 eassert (BUFFERP (w->contents));
2743 eassert (!FRAME_WINDOW_P (f)); 2721 eassert (!FRAME_WINDOW_P (f));
2744 2722
2745 left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols); 2723 left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
@@ -2775,10 +2753,8 @@ frame_row_to_window (struct window *w, int row)
2775 2753
2776 while (w && !found) 2754 while (w && !found)
2777 { 2755 {
2778 if (!NILP (w->hchild)) 2756 if (WINDOWP (w->contents))
2779 found = frame_row_to_window (XWINDOW (w->hchild), row); 2757 found = frame_row_to_window (XWINDOW (w->contents), row);
2780 else if (!NILP (w->vchild))
2781 found = frame_row_to_window (XWINDOW (w->vchild), row);
2782 else if (row >= WINDOW_TOP_EDGE_LINE (w) 2758 else if (row >= WINDOW_TOP_EDGE_LINE (w)
2783 && row < WINDOW_BOTTOM_EDGE_LINE (w)) 2759 && row < WINDOW_BOTTOM_EDGE_LINE (w))
2784 found = w; 2760 found = w;
@@ -2806,11 +2782,8 @@ mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy
2806{ 2782{
2807 while (w) 2783 while (w)
2808 { 2784 {
2809 if (!NILP (w->hchild)) 2785 if (WINDOWP (w->contents))
2810 mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top, 2786 mirror_line_dance (XWINDOW (w->contents), unchanged_at_top,
2811 nlines, copy_from, retained_p);
2812 else if (!NILP (w->vchild))
2813 mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
2814 nlines, copy_from, retained_p); 2787 nlines, copy_from, retained_p);
2815 else 2788 else
2816 { 2789 {
@@ -2919,10 +2892,8 @@ check_window_matrix_pointers (struct window *w)
2919{ 2892{
2920 while (w) 2893 while (w)
2921 { 2894 {
2922 if (!NILP (w->hchild)) 2895 if (WINDOWP (w->contents))
2923 check_window_matrix_pointers (XWINDOW (w->hchild)); 2896 check_window_matrix_pointers (XWINDOW (w->contents));
2924 else if (!NILP (w->vchild))
2925 check_window_matrix_pointers (XWINDOW (w->vchild));
2926 else 2897 else
2927 { 2898 {
2928 struct frame *f = XFRAME (w->frame); 2899 struct frame *f = XFRAME (w->frame);
@@ -3092,10 +3063,12 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
3092 when pending input is detected. */ 3063 when pending input is detected. */
3093 update_begin (f); 3064 update_begin (f);
3094 3065
3066#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
3095 /* Update the menu bar on X frames that don't have toolkit 3067 /* Update the menu bar on X frames that don't have toolkit
3096 support. */ 3068 support. */
3097 if (WINDOWP (f->menu_bar_window)) 3069 if (WINDOWP (f->menu_bar_window))
3098 update_window (XWINDOW (f->menu_bar_window), 1); 3070 update_window (XWINDOW (f->menu_bar_window), 1);
3071#endif
3099 3072
3100 /* Update the tool-bar window, if present. */ 3073 /* Update the tool-bar window, if present. */
3101 if (WINDOWP (f->tool_bar_window)) 3074 if (WINDOWP (f->tool_bar_window))
@@ -3186,10 +3159,8 @@ update_window_tree (struct window *w, bool force_p)
3186 3159
3187 while (w && !paused_p) 3160 while (w && !paused_p)
3188 { 3161 {
3189 if (!NILP (w->hchild)) 3162 if (WINDOWP (w->contents))
3190 paused_p |= update_window_tree (XWINDOW (w->hchild), force_p); 3163 paused_p |= update_window_tree (XWINDOW (w->contents), force_p);
3191 else if (!NILP (w->vchild))
3192 paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
3193 else if (w->must_be_updated_p) 3164 else if (w->must_be_updated_p)
3194 paused_p |= update_window (w, force_p); 3165 paused_p |= update_window (w, force_p);
3195 3166
@@ -3967,10 +3938,8 @@ set_window_update_flags (struct window *w, bool on_p)
3967{ 3938{
3968 while (w) 3939 while (w)
3969 { 3940 {
3970 if (!NILP (w->hchild)) 3941 if (WINDOWP (w->contents))
3971 set_window_update_flags (XWINDOW (w->hchild), on_p); 3942 set_window_update_flags (XWINDOW (w->contents), on_p);
3972 else if (!NILP (w->vchild))
3973 set_window_update_flags (XWINDOW (w->vchild), on_p);
3974 else 3943 else
3975 w->must_be_updated_p = on_p; 3944 w->must_be_updated_p = on_p;
3976 3945
@@ -4451,7 +4420,7 @@ scrolling_window (struct window *w, bool header_line_p)
4451 row_table[row_entry_pool[i].bucket] = NULL; 4420 row_table[row_entry_pool[i].bucket] = NULL;
4452 4421
4453 /* Value is 1 to indicate that we scrolled the display. */ 4422 /* Value is 1 to indicate that we scrolled the display. */
4454 return 0 < nruns; 4423 return nruns > 0;
4455} 4424}
4456 4425
4457 4426
@@ -5117,7 +5086,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5117 5086
5118 /* We used to set current_buffer directly here, but that does the 5087 /* We used to set current_buffer directly here, but that does the
5119 wrong thing with `face-remapping-alist' (bug#2044). */ 5088 wrong thing with `face-remapping-alist' (bug#2044). */
5120 Fset_buffer (w->buffer); 5089 Fset_buffer (w->contents);
5121 itdata = bidi_shelve_cache (); 5090 itdata = bidi_shelve_cache ();
5122 SET_TEXT_POS_FROM_MARKER (startp, w->start); 5091 SET_TEXT_POS_FROM_MARKER (startp, w->start);
5123 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); 5092 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
@@ -5163,7 +5132,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5163 *dx = x0 + it.first_visible_x - it.current_x; 5132 *dx = x0 + it.first_visible_x - it.current_x;
5164 *dy = *y - it.current_y; 5133 *dy = *y - it.current_y;
5165 5134
5166 string = w->buffer; 5135 string = w->contents;
5167 if (STRINGP (it.string)) 5136 if (STRINGP (it.string))
5168 string = it.string; 5137 string = it.string;
5169 *pos = it.current; 5138 *pos = it.current;
@@ -5181,7 +5150,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5181 if (STRINGP (it.string)) 5150 if (STRINGP (it.string))
5182 BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos)); 5151 BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
5183 else 5152 else
5184 BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->buffer), 5153 BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->contents),
5185 CHARPOS (pos->pos)); 5154 CHARPOS (pos->pos));
5186 } 5155 }
5187 5156
@@ -5583,7 +5552,7 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
5583 FrameCols (FRAME_TTY (f)) = newwidth; 5552 FrameCols (FRAME_TTY (f)) = newwidth;
5584 5553
5585 if (WINDOWP (f->tool_bar_window)) 5554 if (WINDOWP (f->tool_bar_window))
5586 wset_total_cols (XWINDOW (f->tool_bar_window), make_number (newwidth)); 5555 XWINDOW (f->tool_bar_window)->total_cols = newwidth;
5587 } 5556 }
5588 5557
5589 FRAME_LINES (f) = newheight; 5558 FRAME_LINES (f) = newheight;
@@ -5725,7 +5694,11 @@ bitch_at_user (void)
5725 if (noninteractive) 5694 if (noninteractive)
5726 putchar (07); 5695 putchar (07);
5727 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */ 5696 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
5728 error ("Keyboard macro terminated by a command ringing the bell"); 5697 {
5698 const char *msg
5699 = "Keyboard macro terminated by a command ringing the bell";
5700 Fsignal (Quser_error, Fcons (build_string (msg), Qnil));
5701 }
5729 else 5702 else
5730 ring_bell (XFRAME (selected_frame)); 5703 ring_bell (XFRAME (selected_frame));
5731} 5704}
@@ -5752,7 +5725,7 @@ additional wait period, in milliseconds; this is for backwards compatibility.
5752 duration += XINT (milliseconds) / 1000.0; 5725 duration += XINT (milliseconds) / 1000.0;
5753 } 5726 }
5754 5727
5755 if (0 < duration) 5728 if (duration > 0)
5756 { 5729 {
5757 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration); 5730 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
5758 wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX), 5731 wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX),
@@ -5792,7 +5765,7 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
5792 if (INTEGERP (timeout)) 5765 if (INTEGERP (timeout))
5793 { 5766 {
5794 sec = XINT (timeout); 5767 sec = XINT (timeout);
5795 if (! (0 < sec)) 5768 if (sec <= 0)
5796 return Qt; 5769 return Qt;
5797 nsec = 0; 5770 nsec = 0;
5798 } 5771 }
diff --git a/src/doc.c b/src/doc.c
index 7234fb38bf9..e45481944f0 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -58,7 +58,7 @@ read_bytecode_char (bool unreadflag)
58} 58}
59 59
60/* Extract a doc string from a file. FILEPOS says where to get it. 60/* Extract a doc string from a file. FILEPOS says where to get it.
61 If it is an integer, use that position in the standard DOC-... file. 61 If it is an integer, use that position in the standard DOC file.
62 If it is (FILE . INTEGER), use FILE as the file name 62 If it is (FILE . INTEGER), use FILE as the file name
63 and INTEGER as the position in that file. 63 and INTEGER as the position in that file.
64 But if INTEGER is negative, make it positive. 64 But if INTEGER is negative, make it positive.
@@ -215,14 +215,20 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
215 if (CONSP (filepos)) 215 if (CONSP (filepos))
216 { 216 {
217 int test = 1; 217 int test = 1;
218 if (get_doc_string_buffer[offset - test++] != ' ') 218 /* A dynamic docstring should be either at the very beginning of a "#@
219 return Qnil; 219 comment" or right after a dynamic docstring delimiter (in case we
220 while (get_doc_string_buffer[offset - test] >= '0' 220 pack several such docstrings within the same comment). */
221 && get_doc_string_buffer[offset - test] <= '9') 221 if (get_doc_string_buffer[offset - test] != '\037')
222 test++; 222 {
223 if (get_doc_string_buffer[offset - test++] != '@' 223 if (get_doc_string_buffer[offset - test++] != ' ')
224 || get_doc_string_buffer[offset - test] != '#') 224 return Qnil;
225 return Qnil; 225 while (get_doc_string_buffer[offset - test] >= '0'
226 && get_doc_string_buffer[offset - test] <= '9')
227 test++;
228 if (get_doc_string_buffer[offset - test++] != '@'
229 || get_doc_string_buffer[offset - test] != '#')
230 return Qnil;
231 }
226 } 232 }
227 else 233 else
228 { 234 {
@@ -602,7 +608,7 @@ the same file name is found in the `doc-directory'. */)
602 while (*beg && c_isspace (*beg)) ++beg; 608 while (*beg && c_isspace (*beg)) ++beg;
603 609
604 for (end = beg; *end && ! c_isspace (*end); ++end) 610 for (end = beg; *end && ! c_isspace (*end); ++end)
605 if (*end == '/') beg = end+1; /* skip directory part */ 611 if (*end == '/') beg = end + 1; /* Skip directory part. */
606 612
607 len = end - beg; 613 len = end - beg;
608 if (len > 4 && end[-4] == '.' && end[-3] == 'o') 614 if (len > 4 && end[-4] == '.' && end[-3] == 'o')
diff --git a/src/editfns.c b/src/editfns.c
index f34c574cae3..cc6b4cff895 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -373,7 +373,7 @@ get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object o
373 if (NILP (object)) 373 if (NILP (object))
374 XSETBUFFER (object, current_buffer); 374 XSETBUFFER (object, current_buffer);
375 else if (WINDOWP (object)) 375 else if (WINDOWP (object))
376 object = XWINDOW (object)->buffer; 376 object = XWINDOW (object)->contents;
377 377
378 if (!BUFFERP (object)) 378 if (!BUFFERP (object))
379 /* pos-property only makes sense in buffers right now, since strings 379 /* pos-property only makes sense in buffers right now, since strings
@@ -839,14 +839,14 @@ Lisp_Object
839save_excursion_save (void) 839save_excursion_save (void)
840{ 840{
841 return make_save_value 841 return make_save_value
842 ("oooo", 842 (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ,
843 Fpoint_marker (), 843 Fpoint_marker (),
844 /* Do not copy the mark if it points to nowhere. */ 844 /* Do not copy the mark if it points to nowhere. */
845 (XMARKER (BVAR (current_buffer, mark))->buffer 845 (XMARKER (BVAR (current_buffer, mark))->buffer
846 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) 846 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
847 : Qnil), 847 : Qnil),
848 /* Selected window if current buffer is shown in it, nil otherwise. */ 848 /* Selected window if current buffer is shown in it, nil otherwise. */
849 ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) 849 (EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ())
850 ? selected_window : Qnil), 850 ? selected_window : Qnil),
851 BVAR (current_buffer, mark_active)); 851 BVAR (current_buffer, mark_active));
852} 852}
@@ -915,7 +915,7 @@ save_excursion_restore (Lisp_Object info)
915 tem = XSAVE_OBJECT (info, 2); 915 tem = XSAVE_OBJECT (info, 2);
916 if (WINDOWP (tem) 916 if (WINDOWP (tem)
917 && !EQ (tem, selected_window) 917 && !EQ (tem, selected_window)
918 && (tem1 = XWINDOW (tem)->buffer, 918 && (tem1 = XWINDOW (tem)->contents,
919 (/* Window is live... */ 919 (/* Window is live... */
920 BUFFERP (tem1) 920 BUFFERP (tem1)
921 /* ...and it shows the current buffer. */ 921 /* ...and it shows the current buffer. */
@@ -1946,7 +1946,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1946 EMACS_INT zone_hr = abszone / (60*60); 1946 EMACS_INT zone_hr = abszone / (60*60);
1947 int zone_min = (abszone/60) % 60; 1947 int zone_min = (abszone/60) % 60;
1948 int zone_sec = abszone % 60; 1948 int zone_sec = abszone % 60;
1949 sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0), 1949 sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0],
1950 zone_hr, zone_min, zone_sec); 1950 zone_hr, zone_min, zone_sec);
1951 tzstring = tzbuf; 1951 tzstring = tzbuf;
1952 } 1952 }
@@ -3958,7 +3958,7 @@ usage: (format STRING &rest OBJECTS) */)
3958 trailing "d"). */ 3958 trailing "d"). */
3959 pMlen = sizeof pMd - 2 3959 pMlen = sizeof pMd - 2
3960 }; 3960 };
3961 verify (0 < USEFUL_PRECISION_MAX); 3961 verify (USEFUL_PRECISION_MAX > 0);
3962 3962
3963 int prec; 3963 int prec;
3964 ptrdiff_t padding, sprintf_bytes; 3964 ptrdiff_t padding, sprintf_bytes;
@@ -4241,7 +4241,10 @@ usage: (format STRING &rest OBJECTS) */)
4241 memcpy (buf, initial_buffer, used); 4241 memcpy (buf, initial_buffer, used);
4242 } 4242 }
4243 else 4243 else
4244 XSAVE_POINTER (buf_save_value, 0) = buf = xrealloc (buf, bufsize); 4244 {
4245 buf = xrealloc (buf, bufsize);
4246 set_save_pointer (buf_save_value, 0, buf);
4247 }
4245 4248
4246 p = buf + used; 4249 p = buf + used;
4247 } 4250 }
diff --git a/src/emacs.c b/src/emacs.c
index 148bb836927..b4b726183cf 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1069,7 +1069,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1069 1069
1070 noninteractive1 = noninteractive; 1070 noninteractive1 = noninteractive;
1071 1071
1072/* Perform basic initializations (not merely interning symbols). */ 1072 /* Perform basic initializations (not merely interning symbols). */
1073 1073
1074 if (!initialized) 1074 if (!initialized)
1075 { 1075 {
@@ -1081,8 +1081,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1081 init_coding_once (); 1081 init_coding_once ();
1082 init_syntax_once (); /* Create standard syntax table. */ 1082 init_syntax_once (); /* Create standard syntax table. */
1083 init_category_once (); /* Create standard category table. */ 1083 init_category_once (); /* Create standard category table. */
1084 /* Must be done before init_buffer. */ 1084 init_casetab_once (); /* Must be done before init_buffer_once. */
1085 init_casetab_once ();
1086 init_buffer_once (); /* Create buffer table and some buffers. */ 1085 init_buffer_once (); /* Create buffer table and some buffers. */
1087 init_minibuf_once (); /* Create list of minibuffers. */ 1086 init_minibuf_once (); /* Create list of minibuffers. */
1088 /* Must precede init_window_once. */ 1087 /* Must precede init_window_once. */
@@ -1107,6 +1106,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1107 syms_of_fileio (); 1106 syms_of_fileio ();
1108 /* Before syms_of_coding to initialize Vgc_cons_threshold. */ 1107 /* Before syms_of_coding to initialize Vgc_cons_threshold. */
1109 syms_of_alloc (); 1108 syms_of_alloc ();
1109 /* May call Ffuncall and so GC, thus the latter should be initialized. */
1110 init_print_once ();
1110 /* Before syms_of_coding because it initializes Qcharsetp. */ 1111 /* Before syms_of_coding because it initializes Qcharsetp. */
1111 syms_of_charset (); 1112 syms_of_charset ();
1112 /* Before init_window_once, because it sets up the 1113 /* Before init_window_once, because it sets up the
@@ -1242,7 +1243,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1242 1243
1243#ifdef WINDOWSNT 1244#ifdef WINDOWSNT
1244 globals_of_w32 (); 1245 globals_of_w32 ();
1246#ifdef HAVE_W32NOTIFY
1245 globals_of_w32notify (); 1247 globals_of_w32notify ();
1248#endif
1246 /* Initialize environment from registry settings. */ 1249 /* Initialize environment from registry settings. */
1247 init_environment (argv); 1250 init_environment (argv);
1248 init_ntproc (dumping); /* must precede init_editfns. */ 1251 init_ntproc (dumping); /* must precede init_editfns. */
@@ -1399,6 +1402,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1399 syms_of_gnutls (); 1402 syms_of_gnutls ();
1400#endif 1403#endif
1401 1404
1405#ifdef HAVE_GFILENOTIFY
1406 syms_of_gfilenotify ();
1407#endif /* HAVE_GFILENOTIFY */
1408
1402#ifdef HAVE_INOTIFY 1409#ifdef HAVE_INOTIFY
1403 syms_of_inotify (); 1410 syms_of_inotify ();
1404#endif /* HAVE_INOTIFY */ 1411#endif /* HAVE_INOTIFY */
@@ -1409,7 +1416,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1409 1416
1410#ifdef WINDOWSNT 1417#ifdef WINDOWSNT
1411 syms_of_ntterm (); 1418 syms_of_ntterm ();
1419#ifdef HAVE_W32NOTIFY
1412 syms_of_w32notify (); 1420 syms_of_w32notify ();
1421#endif /* HAVE_W32NOTIFY */
1413#endif /* WINDOWSNT */ 1422#endif /* WINDOWSNT */
1414 1423
1415 syms_of_threads (); 1424 syms_of_threads ();
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index 6a8c751e306..970683da9c4 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -28,7 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include "xterm.h" 28#include "xterm.h"
29 29
30/* Silence a bogus diagnostic; see GNOME bug 683906. */ 30/* Silence a bogus diagnostic; see GNOME bug 683906. */
31#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ 31#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
32# pragma GCC diagnostic push 32# pragma GCC diagnostic push
33# pragma GCC diagnostic ignored "-Wunused-local-typedefs" 33# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
34#endif 34#endif
diff --git a/src/eval.c b/src/eval.c
index a58a1508aaf..be9de93bf1f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -32,8 +32,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "xterm.h" 32#include "xterm.h"
33#endif 33#endif
34 34
35/* static struct backtrace *backtrace_list; */
36
37/* #if !BYTE_MARK_STACK */ 35/* #if !BYTE_MARK_STACK */
38/* static */ 36/* static */
39/* #endif */ 37/* #endif */
@@ -105,7 +103,7 @@ static EMACS_INT when_entered_debugger;
105 103
106/* The function from which the last `signal' was called. Set in 104/* The function from which the last `signal' was called. Set in
107 Fsignal. */ 105 Fsignal. */
108 106/* FIXME: We should probably get rid of this! */
109Lisp_Object Vsignaling_function; 107Lisp_Object Vsignaling_function;
110 108
111/* If non-nil, Lisp code must not be run since some part of Emacs is 109/* If non-nil, Lisp code must not be run since some part of Emacs is
@@ -117,26 +115,39 @@ Lisp_Object inhibit_lisp_code;
117static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); 115static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
118static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); 116static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args);
119 117
120/* Functions to set Lisp_Object slots of struct specbinding. */ 118/* Functions to modify slots of backtrace records. */
121 119
122static void 120static void set_backtrace_args (struct specbinding *pdl, Lisp_Object *args)
123set_specpdl_symbol (Lisp_Object symbol) 121{ eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.args = args; }
124{
125 specpdl_ptr->symbol = symbol;
126}
127 122
128static void 123static void set_backtrace_nargs (struct specbinding *pdl, ptrdiff_t n)
129set_specpdl_old_value (Lisp_Object oldval) 124{ eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.nargs = n; }
125
126void set_backtrace_debug_on_exit (struct specbinding *pdl, bool doe)
127{ eassert (pdl->kind == SPECPDL_BACKTRACE); pdl->v.bt.debug_on_exit = doe; }
128
129/* Helper functions to scan the backtrace. */
130
131EXTERN_INLINE bool backtrace_p (struct specbinding *pdl)
132{ return pdl >= specpdl; }
133
134EXTERN_INLINE struct specbinding *backtrace_top (void)
130{ 135{
131 specpdl_ptr->old_value = oldval; 136 struct specbinding *pdl = specpdl_ptr - 1;
137 while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE)
138 pdl--;
139 return pdl;
132} 140}
133 141
134static inline void 142EXTERN_INLINE struct specbinding *backtrace_next (struct specbinding *pdl)
135set_specpdl_saved_value (Lisp_Object savedval)
136{ 143{
137 specpdl_ptr->saved_value = savedval; 144 pdl--;
145 while (backtrace_p (pdl) && pdl->kind != SPECPDL_BACKTRACE)
146 pdl--;
147 return pdl;
138} 148}
139 149
150
140void 151void
141init_eval_once (void) 152init_eval_once (void)
142{ 153{
@@ -157,7 +168,6 @@ init_eval (void)
157 specpdl_ptr = specpdl; 168 specpdl_ptr = specpdl;
158 catchlist = 0; 169 catchlist = 0;
159 handlerlist = 0; 170 handlerlist = 0;
160 backtrace_list = 0;
161 Vquit_flag = Qnil; 171 Vquit_flag = Qnil;
162 debug_on_next_call = 0; 172 debug_on_next_call = 0;
163 lisp_eval_depth = 0; 173 lisp_eval_depth = 0;
@@ -253,7 +263,7 @@ static void
253do_debug_on_call (Lisp_Object code) 263do_debug_on_call (Lisp_Object code)
254{ 264{
255 debug_on_next_call = 0; 265 debug_on_next_call = 0;
256 backtrace_list->debug_on_exit = 1; 266 set_backtrace_debug_on_exit (specpdl_ptr - 1, true);
257 call_debugger (Fcons (code, Qnil)); 267 call_debugger (Fcons (code, Qnil));
258} 268}
259 269
@@ -549,9 +559,8 @@ The return value is BASE-VARIABLE. */)
549 struct specbinding *p; 559 struct specbinding *p;
550 560
551 for (p = specpdl_ptr; p > specpdl; ) 561 for (p = specpdl_ptr; p > specpdl; )
552 if ((--p)->func == NULL 562 if ((--p)->kind >= SPECPDL_LET
553 && (EQ (new_alias, 563 && (EQ (new_alias, specpdl_symbol (p))))
554 CONSP (p->symbol) ? XCAR (p->symbol) : p->symbol)))
555 error ("Don't know how to make a let-bound variable an alias"); 564 error ("Don't know how to make a let-bound variable an alias");
556 } 565 }
557 566
@@ -616,8 +625,9 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
616 struct specbinding *pdl = specpdl_ptr; 625 struct specbinding *pdl = specpdl_ptr;
617 while (pdl > specpdl) 626 while (pdl > specpdl)
618 { 627 {
619 if (EQ ((--pdl)->symbol, sym) && !pdl->func 628 if ((--pdl)->kind >= SPECPDL_LET
620 && EQ (pdl->old_value, Qunbound)) 629 && EQ (specpdl_symbol (pdl), sym)
630 && EQ (specpdl_old_value (pdl), Qunbound))
621 { 631 {
622 message_with_string 632 message_with_string
623 ("Warning: defvar ignored because %s is let-bound", 633 ("Warning: defvar ignored because %s is let-bound",
@@ -956,7 +966,7 @@ usage: (catch TAG BODY...) */)
956 966
957/* Set up a catch, then call C function FUNC on argument ARG. 967/* Set up a catch, then call C function FUNC on argument ARG.
958 FUNC should return a Lisp_Object. 968 FUNC should return a Lisp_Object.
959 This is how catches are done from within C code. */ 969 This is how catches are done from within C code. */
960 970
961Lisp_Object 971Lisp_Object
962internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) 972internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg)
@@ -968,7 +978,6 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object
968 c.next = catchlist; 978 c.next = catchlist;
969 c.tag = tag; 979 c.tag = tag;
970 c.val = Qnil; 980 c.val = Qnil;
971 c.backlist = backtrace_list;
972 c.f_handlerlist = handlerlist; 981 c.f_handlerlist = handlerlist;
973 c.f_lisp_eval_depth = lisp_eval_depth; 982 c.f_lisp_eval_depth = lisp_eval_depth;
974 c.pdlcount = SPECPDL_INDEX (); 983 c.pdlcount = SPECPDL_INDEX ();
@@ -1033,7 +1042,6 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
1033#ifdef DEBUG_GCPRO 1042#ifdef DEBUG_GCPRO
1034 gcpro_level = gcprolist ? gcprolist->level + 1 : 0; 1043 gcpro_level = gcprolist ? gcprolist->level + 1 : 0;
1035#endif 1044#endif
1036 backtrace_list = catch->backlist;
1037 lisp_eval_depth = catch->f_lisp_eval_depth; 1045 lisp_eval_depth = catch->f_lisp_eval_depth;
1038 1046
1039 sys_longjmp (catch->jmp, 1); 1047 sys_longjmp (catch->jmp, 1);
@@ -1134,7 +1142,6 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1134 1142
1135 c.tag = Qnil; 1143 c.tag = Qnil;
1136 c.val = Qnil; 1144 c.val = Qnil;
1137 c.backlist = backtrace_list;
1138 c.f_handlerlist = handlerlist; 1145 c.f_handlerlist = handlerlist;
1139 c.f_lisp_eval_depth = lisp_eval_depth; 1146 c.f_lisp_eval_depth = lisp_eval_depth;
1140 c.pdlcount = SPECPDL_INDEX (); 1147 c.pdlcount = SPECPDL_INDEX ();
@@ -1150,7 +1157,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1150 1157
1151 /* Note that this just undoes the binding of h.var; whoever 1158 /* Note that this just undoes the binding of h.var; whoever
1152 longjumped to us unwound the stack to c.pdlcount before 1159 longjumped to us unwound the stack to c.pdlcount before
1153 throwing. */ 1160 throwing. */
1154 unbind_to (c.pdlcount, Qnil); 1161 unbind_to (c.pdlcount, Qnil);
1155 return val; 1162 return val;
1156 } 1163 }
@@ -1189,7 +1196,6 @@ internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers,
1189 1196
1190 c.tag = Qnil; 1197 c.tag = Qnil;
1191 c.val = Qnil; 1198 c.val = Qnil;
1192 c.backlist = backtrace_list;
1193 c.f_handlerlist = handlerlist; 1199 c.f_handlerlist = handlerlist;
1194 c.f_lisp_eval_depth = lisp_eval_depth; 1200 c.f_lisp_eval_depth = lisp_eval_depth;
1195 c.pdlcount = SPECPDL_INDEX (); 1201 c.pdlcount = SPECPDL_INDEX ();
@@ -1227,7 +1233,6 @@ internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg,
1227 1233
1228 c.tag = Qnil; 1234 c.tag = Qnil;
1229 c.val = Qnil; 1235 c.val = Qnil;
1230 c.backlist = backtrace_list;
1231 c.f_handlerlist = handlerlist; 1236 c.f_handlerlist = handlerlist;
1232 c.f_lisp_eval_depth = lisp_eval_depth; 1237 c.f_lisp_eval_depth = lisp_eval_depth;
1233 c.pdlcount = SPECPDL_INDEX (); 1238 c.pdlcount = SPECPDL_INDEX ();
@@ -1269,7 +1274,6 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object),
1269 1274
1270 c.tag = Qnil; 1275 c.tag = Qnil;
1271 c.val = Qnil; 1276 c.val = Qnil;
1272 c.backlist = backtrace_list;
1273 c.f_handlerlist = handlerlist; 1277 c.f_handlerlist = handlerlist;
1274 c.f_lisp_eval_depth = lisp_eval_depth; 1278 c.f_lisp_eval_depth = lisp_eval_depth;
1275 c.pdlcount = SPECPDL_INDEX (); 1279 c.pdlcount = SPECPDL_INDEX ();
@@ -1313,7 +1317,6 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
1313 1317
1314 c.tag = Qnil; 1318 c.tag = Qnil;
1315 c.val = Qnil; 1319 c.val = Qnil;
1316 c.backlist = backtrace_list;
1317 c.f_handlerlist = handlerlist; 1320 c.f_handlerlist = handlerlist;
1318 c.f_lisp_eval_depth = lisp_eval_depth; 1321 c.f_lisp_eval_depth = lisp_eval_depth;
1319 c.pdlcount = SPECPDL_INDEX (); 1322 c.pdlcount = SPECPDL_INDEX ();
@@ -1381,7 +1384,6 @@ See also the function `condition-case'. */)
1381 = (NILP (error_symbol) ? Fcar (data) : error_symbol); 1384 = (NILP (error_symbol) ? Fcar (data) : error_symbol);
1382 register Lisp_Object clause = Qnil; 1385 register Lisp_Object clause = Qnil;
1383 struct handler *h; 1386 struct handler *h;
1384 struct backtrace *bp;
1385 1387
1386 immediate_quit = 0; 1388 immediate_quit = 0;
1387 abort_on_gc = 0; 1389 abort_on_gc = 0;
@@ -1417,13 +1419,13 @@ See also the function `condition-case'. */)
1417 too. Don't do this when ERROR_SYMBOL is nil, because that 1419 too. Don't do this when ERROR_SYMBOL is nil, because that
1418 is a memory-full error. */ 1420 is a memory-full error. */
1419 Vsignaling_function = Qnil; 1421 Vsignaling_function = Qnil;
1420 if (backtrace_list && !NILP (error_symbol)) 1422 if (!NILP (error_symbol))
1421 { 1423 {
1422 bp = backtrace_list->next; 1424 struct specbinding *pdl = backtrace_next (backtrace_top ());
1423 if (bp && EQ (bp->function, Qerror)) 1425 if (backtrace_p (pdl) && EQ (backtrace_function (pdl), Qerror))
1424 bp = bp->next; 1426 pdl = backtrace_next (pdl);
1425 if (bp) 1427 if (backtrace_p (pdl))
1426 Vsignaling_function = bp->function; 1428 Vsignaling_function = backtrace_function (pdl);
1427 } 1429 }
1428 1430
1429 for (h = handlerlist; h; h = h->next) 1431 for (h = handlerlist; h; h = h->next)
@@ -1920,6 +1922,36 @@ If LEXICAL is t, evaluate using lexical scoping. */)
1920 return unbind_to (count, eval_sub (form)); 1922 return unbind_to (count, eval_sub (form));
1921} 1923}
1922 1924
1925static void
1926grow_specpdl (void)
1927{
1928 register ptrdiff_t count = SPECPDL_INDEX ();
1929 ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX);
1930 if (max_size <= specpdl_size)
1931 {
1932 if (max_specpdl_size < 400)
1933 max_size = max_specpdl_size = 400;
1934 if (max_size <= specpdl_size)
1935 signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil);
1936 }
1937 specpdl = xpalloc (specpdl, &specpdl_size, 1, max_size, sizeof *specpdl);
1938 specpdl_ptr = specpdl + count;
1939}
1940
1941LISP_INLINE void
1942record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
1943{
1944 eassert (nargs >= UNEVALLED);
1945 if (specpdl_ptr == specpdl + specpdl_size)
1946 grow_specpdl ();
1947 specpdl_ptr->kind = SPECPDL_BACKTRACE;
1948 specpdl_ptr->v.bt.function = function;
1949 specpdl_ptr->v.bt.args = args;
1950 specpdl_ptr->v.bt.nargs = nargs;
1951 specpdl_ptr->v.bt.debug_on_exit = false;
1952 specpdl_ptr++;
1953}
1954
1923/* Eval a sub-expression of the current expression (i.e. in the same 1955/* Eval a sub-expression of the current expression (i.e. in the same
1924 lexical scope). */ 1956 lexical scope). */
1925Lisp_Object 1957Lisp_Object
@@ -1927,7 +1959,6 @@ eval_sub (Lisp_Object form)
1927{ 1959{
1928 Lisp_Object fun, val, original_fun, original_args; 1960 Lisp_Object fun, val, original_fun, original_args;
1929 Lisp_Object funcar; 1961 Lisp_Object funcar;
1930 struct backtrace backtrace;
1931 struct gcpro gcpro1, gcpro2, gcpro3; 1962 struct gcpro gcpro1, gcpro2, gcpro3;
1932 1963
1933 if (SYMBOLP (form)) 1964 if (SYMBOLP (form))
@@ -1965,12 +1996,8 @@ eval_sub (Lisp_Object form)
1965 original_fun = XCAR (form); 1996 original_fun = XCAR (form);
1966 original_args = XCDR (form); 1997 original_args = XCDR (form);
1967 1998
1968 backtrace.next = backtrace_list; 1999 /* This also protects them from gc. */
1969 backtrace.function = original_fun; /* This also protects them from gc. */ 2000 record_in_backtrace (original_fun, &original_args, UNEVALLED);
1970 backtrace.args = &original_args;
1971 backtrace.nargs = UNEVALLED;
1972 backtrace.debug_on_exit = 0;
1973 backtrace_list = &backtrace;
1974 2001
1975 if (debug_on_next_call) 2002 if (debug_on_next_call)
1976 do_debug_on_call (Qt); 2003 do_debug_on_call (Qt);
@@ -2024,8 +2051,8 @@ eval_sub (Lisp_Object form)
2024 gcpro3.nvars = argnum; 2051 gcpro3.nvars = argnum;
2025 } 2052 }
2026 2053
2027 backtrace.args = vals; 2054 set_backtrace_args (specpdl_ptr - 1, vals);
2028 backtrace.nargs = XINT (numargs); 2055 set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
2029 2056
2030 val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); 2057 val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals);
2031 UNGCPRO; 2058 UNGCPRO;
@@ -2046,8 +2073,8 @@ eval_sub (Lisp_Object form)
2046 2073
2047 UNGCPRO; 2074 UNGCPRO;
2048 2075
2049 backtrace.args = argvals; 2076 set_backtrace_args (specpdl_ptr - 1, argvals);
2050 backtrace.nargs = XINT (numargs); 2077 set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
2051 2078
2052 switch (i) 2079 switch (i)
2053 { 2080 {
@@ -2137,9 +2164,9 @@ eval_sub (Lisp_Object form)
2137 check_cons_list (); 2164 check_cons_list ();
2138 2165
2139 lisp_eval_depth--; 2166 lisp_eval_depth--;
2140 if (backtrace.debug_on_exit) 2167 if (backtrace_debug_on_exit (specpdl_ptr - 1))
2141 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); 2168 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil)));
2142 backtrace_list = backtrace.next; 2169 specpdl_ptr--;
2143 2170
2144 return val; 2171 return val;
2145} 2172}
@@ -2619,7 +2646,6 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2619 ptrdiff_t numargs = nargs - 1; 2646 ptrdiff_t numargs = nargs - 1;
2620 Lisp_Object lisp_numargs; 2647 Lisp_Object lisp_numargs;
2621 Lisp_Object val; 2648 Lisp_Object val;
2622 struct backtrace backtrace;
2623 register Lisp_Object *internal_args; 2649 register Lisp_Object *internal_args;
2624 ptrdiff_t i; 2650 ptrdiff_t i;
2625 2651
@@ -2633,12 +2659,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2633 error ("Lisp nesting exceeds `max-lisp-eval-depth'"); 2659 error ("Lisp nesting exceeds `max-lisp-eval-depth'");
2634 } 2660 }
2635 2661
2636 backtrace.next = backtrace_list; 2662 /* This also GCPROs them. */
2637 backtrace.function = args[0]; 2663 record_in_backtrace (args[0], &args[1], nargs - 1);
2638 backtrace.args = &args[1]; /* This also GCPROs them. */
2639 backtrace.nargs = nargs - 1;
2640 backtrace.debug_on_exit = 0;
2641 backtrace_list = &backtrace;
2642 2664
2643 /* Call GC after setting up the backtrace, so the latter GCPROs the args. */ 2665 /* Call GC after setting up the backtrace, so the latter GCPROs the args. */
2644 maybe_gc (); 2666 maybe_gc ();
@@ -2763,9 +2785,9 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2763 } 2785 }
2764 check_cons_list (); 2786 check_cons_list ();
2765 lisp_eval_depth--; 2787 lisp_eval_depth--;
2766 if (backtrace.debug_on_exit) 2788 if (backtrace_debug_on_exit (specpdl_ptr - 1))
2767 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); 2789 val = call_debugger (Fcons (Qexit, Fcons (val, Qnil)));
2768 backtrace_list = backtrace.next; 2790 specpdl_ptr--;
2769 return val; 2791 return val;
2770} 2792}
2771 2793
@@ -2797,15 +2819,17 @@ apply_lambda (Lisp_Object fun, Lisp_Object args)
2797 2819
2798 UNGCPRO; 2820 UNGCPRO;
2799 2821
2800 backtrace_list->args = arg_vector; 2822 set_backtrace_args (specpdl_ptr - 1, arg_vector);
2801 backtrace_list->nargs = i; 2823 set_backtrace_nargs (specpdl_ptr - 1, i);
2802 tem = funcall_lambda (fun, numargs, arg_vector); 2824 tem = funcall_lambda (fun, numargs, arg_vector);
2803 2825
2804 /* Do the debug-on-exit now, while arg_vector still exists. */ 2826 /* Do the debug-on-exit now, while arg_vector still exists. */
2805 if (backtrace_list->debug_on_exit) 2827 if (backtrace_debug_on_exit (specpdl_ptr - 1))
2806 tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil))); 2828 {
2807 /* Don't do it again when we return to eval. */ 2829 /* Don't do it again when we return to eval. */
2808 backtrace_list->debug_on_exit = 0; 2830 set_backtrace_debug_on_exit (specpdl_ptr - 1, false);
2831 tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil)));
2832 }
2809 SAFE_FREE (); 2833 SAFE_FREE ();
2810 return tem; 2834 return tem;
2811} 2835}
@@ -2955,20 +2979,38 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode,
2955 return object; 2979 return object;
2956} 2980}
2957 2981
2958static void 2982/* Return true if SYMBOL currently has a let-binding
2959grow_specpdl (void) 2983 which was made in the buffer that is now current. */
2984
2985bool
2986let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
2960{ 2987{
2961 register ptrdiff_t count = SPECPDL_INDEX (); 2988 struct specbinding *p;
2962 ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX); 2989 Lisp_Object buf = Fcurrent_buffer ();
2963 if (max_size <= specpdl_size) 2990
2964 { 2991 for (p = specpdl_ptr; p > specpdl; )
2965 if (max_specpdl_size < 400) 2992 if ((--p)->kind > SPECPDL_LET)
2966 max_size = max_specpdl_size = 400; 2993 {
2967 if (max_size <= specpdl_size) 2994 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p));
2968 signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil); 2995 eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS);
2969 } 2996 if (symbol == let_bound_symbol
2970 specpdl = xpalloc (specpdl, &specpdl_size, 1, max_size, sizeof *specpdl); 2997 && EQ (specpdl_where (p), buf))
2971 specpdl_ptr = specpdl + count; 2998 return 1;
2999 }
3000
3001 return 0;
3002}
3003
3004bool
3005let_shadows_global_binding_p (Lisp_Object symbol)
3006{
3007 struct specbinding *p;
3008
3009 for (p = specpdl_ptr; p > specpdl; )
3010 if ((--p)->kind >= SPECPDL_LET && EQ (specpdl_symbol (p), symbol))
3011 return 1;
3012
3013 return 0;
2972} 3014}
2973 3015
2974static Lisp_Object 3016static Lisp_Object
@@ -3050,10 +3092,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3050 case SYMBOL_PLAINVAL: 3092 case SYMBOL_PLAINVAL:
3051 /* The most common case is that of a non-constant symbol with a 3093 /* The most common case is that of a non-constant symbol with a
3052 trivial value. Make that as fast as we can. */ 3094 trivial value. Make that as fast as we can. */
3053 set_specpdl_symbol (symbol); 3095 specpdl_ptr->kind = SPECPDL_LET;
3054 set_specpdl_old_value (SYMBOL_VAL (sym)); 3096 specpdl_ptr->v.let.symbol = symbol;
3055 specpdl_ptr->func = NULL; 3097 specpdl_ptr->v.let.old_value = SYMBOL_VAL (sym);
3056 specpdl_ptr->saved_value = Qnil; 3098 specpdl_ptr->v.let.saved_value = Qnil;
3057 ++specpdl_ptr; 3099 ++specpdl_ptr;
3058 do_specbind (sym, specpdl_ptr - 1, value); 3100 do_specbind (sym, specpdl_ptr - 1, value);
3059 break; 3101 break;
@@ -3063,59 +3105,36 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3063 case SYMBOL_FORWARDED: 3105 case SYMBOL_FORWARDED:
3064 { 3106 {
3065 Lisp_Object ovalue = find_symbol_value (symbol); 3107 Lisp_Object ovalue = find_symbol_value (symbol);
3066 specpdl_ptr->func = 0; 3108 specpdl_ptr->kind = SPECPDL_LET_LOCAL;
3067 set_specpdl_old_value (ovalue); 3109 specpdl_ptr->v.let.symbol = symbol;
3110 specpdl_ptr->v.let.old_value = ovalue;
3111 specpdl_ptr->v.let.where = Fcurrent_buffer ();
3068 3112
3069 eassert (sym->redirect != SYMBOL_LOCALIZED 3113 eassert (sym->redirect != SYMBOL_LOCALIZED
3070 || (EQ (SYMBOL_BLV (sym)->where, 3114 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ())));
3071 SYMBOL_BLV (sym)->frame_local ?
3072 Fselected_frame () : Fcurrent_buffer ())));
3073 3115
3074 if (sym->redirect == SYMBOL_LOCALIZED 3116 if (sym->redirect == SYMBOL_LOCALIZED)
3075 || BUFFER_OBJFWDP (SYMBOL_FWD (sym))) 3117 {
3118 if (!blv_found (SYMBOL_BLV (sym)))
3119 specpdl_ptr->kind = SPECPDL_LET_DEFAULT;
3120 }
3121 else if (BUFFER_OBJFWDP (SYMBOL_FWD (sym)))
3076 { 3122 {
3077 Lisp_Object where, cur_buf = Fcurrent_buffer ();
3078
3079 /* For a local variable, record both the symbol and which
3080 buffer's or frame's value we are saving. */
3081 if (!NILP (Flocal_variable_p (symbol, Qnil)))
3082 {
3083 eassert (sym->redirect != SYMBOL_LOCALIZED
3084 || (blv_found (SYMBOL_BLV (sym))
3085 && EQ (cur_buf, SYMBOL_BLV (sym)->where)));
3086 where = cur_buf;
3087 }
3088 else if (sym->redirect == SYMBOL_LOCALIZED
3089 && blv_found (SYMBOL_BLV (sym)))
3090 where = SYMBOL_BLV (sym)->where;
3091 else
3092 where = Qnil;
3093
3094 /* We're not using the `unused' slot in the specbinding
3095 structure because this would mean we have to do more
3096 work for simple variables. */
3097 /* FIXME: The third value `current_buffer' is only used in
3098 let_shadows_buffer_binding_p which is itself only used
3099 in set_internal for local_if_set. */
3100 eassert (NILP (where) || EQ (where, cur_buf));
3101 set_specpdl_symbol (Fcons (symbol, Fcons (where, cur_buf)));
3102
3103 /* If SYMBOL is a per-buffer variable which doesn't have a 3123 /* If SYMBOL is a per-buffer variable which doesn't have a
3104 buffer-local value here, make the `let' change the global 3124 buffer-local value here, make the `let' change the global
3105 value by changing the value of SYMBOL in all buffers not 3125 value by changing the value of SYMBOL in all buffers not
3106 having their own value. This is consistent with what 3126 having their own value. This is consistent with what
3107 happens with other buffer-local variables. */ 3127 happens with other buffer-local variables. */
3108 if (NILP (where) 3128 if (NILP (Flocal_variable_p (symbol, Qnil)))
3109 && sym->redirect == SYMBOL_FORWARDED)
3110 { 3129 {
3111 eassert (BUFFER_OBJFWDP (SYMBOL_FWD (sym))); 3130 specpdl_ptr->kind = SPECPDL_LET_DEFAULT;
3112 ++specpdl_ptr; 3131 ++specpdl_ptr;
3113 do_specbind (sym, specpdl_ptr - 1, value); 3132 do_specbind (sym, specpdl_ptr - 1, value);
3114 return; 3133 return;
3115 } 3134 }
3116 } 3135 }
3117 else 3136 else
3118 set_specpdl_symbol (symbol); 3137 specpdl_ptr->kind = SPECPDL_LET;
3119 3138
3120 specpdl_ptr++; 3139 specpdl_ptr++;
3121 do_specbind (sym, specpdl_ptr - 1, value); 3140 do_specbind (sym, specpdl_ptr - 1, value);
@@ -3130,10 +3149,9 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg)
3130{ 3149{
3131 if (specpdl_ptr == specpdl + specpdl_size) 3150 if (specpdl_ptr == specpdl + specpdl_size)
3132 grow_specpdl (); 3151 grow_specpdl ();
3133 specpdl_ptr->func = function; 3152 specpdl_ptr->kind = SPECPDL_UNWIND;
3134 set_specpdl_symbol (Qnil); 3153 specpdl_ptr->v.unwind.func = function;
3135 set_specpdl_old_value (arg); 3154 specpdl_ptr->v.unwind.arg = arg;
3136 set_specpdl_saved_value (Qnil);
3137 specpdl_ptr++; 3155 specpdl_ptr++;
3138} 3156}
3139 3157
@@ -3144,7 +3162,7 @@ rebind_for_thread_switch (void)
3144 3162
3145 for (bind = specpdl; bind != specpdl_ptr; ++bind) 3163 for (bind = specpdl; bind != specpdl_ptr; ++bind)
3146 { 3164 {
3147 if (bind->func == NULL) 3165 if (bind->kind >= SPECPDL_LET)
3148 { 3166 {
3149 Lisp_Object value = bind->saved_value; 3167 Lisp_Object value = bind->saved_value;
3150 3168
@@ -3157,41 +3175,50 @@ rebind_for_thread_switch (void)
3157static void 3175static void
3158do_one_unbind (const struct specbinding *this_binding, int unwinding) 3176do_one_unbind (const struct specbinding *this_binding, int unwinding)
3159{ 3177{
3160 if (this_binding->func != 0) 3178 switch (this_binding->kind)
3161 (*this_binding->func) (this_binding->old_value); 3179 {
3162 /* If the symbol is a list, it is really (SYMBOL WHERE 3180 case SPECPDL_UNWIND:
3163 . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a 3181 (*specpdl_func (this_binding)) (specpdl_arg (this_binding));
3164 frame. If WHERE is a buffer or frame, this indicates we 3182 break;
3165 bound a variable that had a buffer-local or frame-local 3183 case SPECPDL_LET:
3166 binding. WHERE nil means that the variable had the default 3184 /* If variable has a trivial value (no forwarding), we can
3167 value when it was bound. CURRENT-BUFFER is the buffer that 3185 just set it. No need to check for constant symbols here,
3168 was current when the variable was bound. */ 3186 since that was already done by specbind. */
3169 else if (CONSP (this_binding->symbol)) 3187 if (XSYMBOL (specpdl_symbol (this_binding))->redirect
3170 { 3188 == SYMBOL_PLAINVAL)
3171 Lisp_Object symbol, where; 3189 SET_SYMBOL_VAL (XSYMBOL (specpdl_symbol (this_binding)),
3172 3190 specpdl_old_value (this_binding));
3173 symbol = XCAR (this_binding->symbol); 3191 else
3174 where = XCAR (XCDR (this_binding->symbol)); 3192 /* NOTE: we only ever come here if make_local_foo was used for
3175 3193 the first time on this var within this let. */
3176 if (NILP (where)) 3194 Fset_default (specpdl_symbol (this_binding),
3177 Fset_default (symbol, this_binding->old_value); 3195 specpdl_old_value (this_binding));
3178 /* If `where' is non-nil, reset the value in the appropriate 3196 break;
3179 local binding, but only if that binding still exists. */ 3197 case SPECPDL_BACKTRACE:
3180 else if (BUFFERP (where) 3198 break;
3181 ? !NILP (Flocal_variable_p (symbol, where)) 3199 case SPECPDL_LET_LOCAL:
3182 : !NILP (Fassq (symbol, XFRAME (where)->param_alist))) 3200 case SPECPDL_LET_DEFAULT:
3183 set_internal (symbol, this_binding->old_value, where, 1); 3201 { /* If the symbol is a list, it is really (SYMBOL WHERE
3184 } 3202 . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
3185 /* If variable has a trivial value (no forwarding), we can 3203 frame. If WHERE is a buffer or frame, this indicates we
3186 just set it. No need to check for constant symbols here, 3204 bound a variable that had a buffer-local or frame-local
3187 since that was already done by specbind. */ 3205 binding. WHERE nil means that the variable had the default
3188 else if (XSYMBOL (this_binding->symbol)->redirect == SYMBOL_PLAINVAL) 3206 value when it was bound. CURRENT-BUFFER is the buffer that
3189 SET_SYMBOL_VAL (XSYMBOL (this_binding->symbol), 3207 was current when the variable was bound. */
3190 this_binding->old_value); 3208 Lisp_Object symbol = specpdl_symbol (this_binding);
3191 else 3209 Lisp_Object where = specpdl_where (this_binding);
3192 /* NOTE: we only ever come here if make_local_foo was used for 3210 eassert (BUFFERP (where));
3193 the first time on this var within this let. */ 3211
3194 Fset_default (this_binding->symbol, this_binding->old_value); 3212 if (this_binding->kind == SPECPDL_LET_DEFAULT)
3213 Fset_default (symbol, specpdl_old_value (this_binding));
3214 /* If this was a local binding, reset the value in the appropriate
3215 buffer, but only if that buffer's binding still exists. */
3216 else if (!NILP (Flocal_variable_p (symbol, where)))
3217 set_internal (symbol, specpdl_old_value (this_binding),
3218 where, 1);
3219 }
3220 break;
3221 }
3195} 3222}
3196 3223
3197Lisp_Object 3224Lisp_Object
@@ -3231,7 +3258,7 @@ unbind_for_thread_switch (void)
3231 3258
3232 for (bind = specpdl_ptr; bind != specpdl; --bind) 3259 for (bind = specpdl_ptr; bind != specpdl; --bind)
3233 { 3260 {
3234 if (bind->func == NULL) 3261 if (bind->kind >= SPECPDL_LET)
3235 { 3262 {
3236 bind->saved_value = find_symbol_value (binding_symbol (bind)); 3263 bind->saved_value = find_symbol_value (binding_symbol (bind));
3237 do_one_unbind (bind, 0); 3264 do_one_unbind (bind, 0);
@@ -3255,18 +3282,16 @@ DEFUN ("backtrace-debug", Fbacktrace_debug, Sbacktrace_debug, 2, 2, 0,
3255The debugger is entered when that frame exits, if the flag is non-nil. */) 3282The debugger is entered when that frame exits, if the flag is non-nil. */)
3256 (Lisp_Object level, Lisp_Object flag) 3283 (Lisp_Object level, Lisp_Object flag)
3257{ 3284{
3258 register struct backtrace *backlist = backtrace_list; 3285 struct specbinding *pdl = backtrace_top ();
3259 register EMACS_INT i; 3286 register EMACS_INT i;
3260 3287
3261 CHECK_NUMBER (level); 3288 CHECK_NUMBER (level);
3262 3289
3263 for (i = 0; backlist && i < XINT (level); i++) 3290 for (i = 0; backtrace_p (pdl) && i < XINT (level); i++)
3264 { 3291 pdl = backtrace_next (pdl);
3265 backlist = backlist->next;
3266 }
3267 3292
3268 if (backlist) 3293 if (backtrace_p (pdl))
3269 backlist->debug_on_exit = !NILP (flag); 3294 set_backtrace_debug_on_exit (pdl, !NILP (flag));
3270 3295
3271 return flag; 3296 return flag;
3272} 3297}
@@ -3276,58 +3301,41 @@ DEFUN ("backtrace", Fbacktrace, Sbacktrace, 0, 0, "",
3276Output stream used is value of `standard-output'. */) 3301Output stream used is value of `standard-output'. */)
3277 (void) 3302 (void)
3278{ 3303{
3279 register struct backtrace *backlist = backtrace_list; 3304 struct specbinding *pdl = backtrace_top ();
3280 Lisp_Object tail;
3281 Lisp_Object tem; 3305 Lisp_Object tem;
3282 struct gcpro gcpro1;
3283 Lisp_Object old_print_level = Vprint_level; 3306 Lisp_Object old_print_level = Vprint_level;
3284 3307
3285 if (NILP (Vprint_level)) 3308 if (NILP (Vprint_level))
3286 XSETFASTINT (Vprint_level, 8); 3309 XSETFASTINT (Vprint_level, 8);
3287 3310
3288 tail = Qnil; 3311 while (backtrace_p (pdl))
3289 GCPRO1 (tail);
3290
3291 while (backlist)
3292 { 3312 {
3293 write_string (backlist->debug_on_exit ? "* " : " ", 2); 3313 write_string (backtrace_debug_on_exit (pdl) ? "* " : " ", 2);
3294 if (backlist->nargs == UNEVALLED) 3314 if (backtrace_nargs (pdl) == UNEVALLED)
3295 { 3315 {
3296 Fprin1 (Fcons (backlist->function, *backlist->args), Qnil); 3316 Fprin1 (Fcons (backtrace_function (pdl), *backtrace_args (pdl)),
3317 Qnil);
3297 write_string ("\n", -1); 3318 write_string ("\n", -1);
3298 } 3319 }
3299 else 3320 else
3300 { 3321 {
3301 tem = backlist->function; 3322 tem = backtrace_function (pdl);
3302 Fprin1 (tem, Qnil); /* This can QUIT. */ 3323 Fprin1 (tem, Qnil); /* This can QUIT. */
3303 write_string ("(", -1); 3324 write_string ("(", -1);
3304 if (backlist->nargs == MANY) 3325 {
3305 { /* FIXME: Can this happen? */ 3326 ptrdiff_t i;
3306 bool later_arg = 0; 3327 for (i = 0; i < backtrace_nargs (pdl); i++)
3307 for (tail = *backlist->args; !NILP (tail); tail = Fcdr (tail)) 3328 {
3308 { 3329 if (i) write_string (" ", -1);
3309 if (later_arg) 3330 Fprin1 (backtrace_args (pdl)[i], Qnil);
3310 write_string (" ", -1); 3331 }
3311 Fprin1 (Fcar (tail), Qnil); 3332 }
3312 later_arg = 1;
3313 }
3314 }
3315 else
3316 {
3317 ptrdiff_t i;
3318 for (i = 0; i < backlist->nargs; i++)
3319 {
3320 if (i) write_string (" ", -1);
3321 Fprin1 (backlist->args[i], Qnil);
3322 }
3323 }
3324 write_string (")\n", -1); 3333 write_string (")\n", -1);
3325 } 3334 }
3326 backlist = backlist->next; 3335 pdl = backtrace_next (pdl);
3327 } 3336 }
3328 3337
3329 Vprint_level = old_print_level; 3338 Vprint_level = old_print_level;
3330 UNGCPRO;
3331 return Qnil; 3339 return Qnil;
3332} 3340}
3333 3341
@@ -3343,53 +3351,85 @@ or a lambda expression for macro calls.
3343If NFRAMES is more than the number of frames, the value is nil. */) 3351If NFRAMES is more than the number of frames, the value is nil. */)
3344 (Lisp_Object nframes) 3352 (Lisp_Object nframes)
3345{ 3353{
3346 register struct backtrace *backlist = backtrace_list; 3354 struct specbinding *pdl = backtrace_top ();
3347 register EMACS_INT i; 3355 register EMACS_INT i;
3348 Lisp_Object tem;
3349 3356
3350 CHECK_NATNUM (nframes); 3357 CHECK_NATNUM (nframes);
3351 3358
3352 /* Find the frame requested. */ 3359 /* Find the frame requested. */
3353 for (i = 0; backlist && i < XFASTINT (nframes); i++) 3360 for (i = 0; backtrace_p (pdl) && i < XFASTINT (nframes); i++)
3354 backlist = backlist->next; 3361 pdl = backtrace_next (pdl);
3355 3362
3356 if (!backlist) 3363 if (!backtrace_p (pdl))
3357 return Qnil; 3364 return Qnil;
3358 if (backlist->nargs == UNEVALLED) 3365 if (backtrace_nargs (pdl) == UNEVALLED)
3359 return Fcons (Qnil, Fcons (backlist->function, *backlist->args)); 3366 return Fcons (Qnil,
3367 Fcons (backtrace_function (pdl), *backtrace_args (pdl)));
3360 else 3368 else
3361 { 3369 {
3362 if (backlist->nargs == MANY) /* FIXME: Can this happen? */ 3370 Lisp_Object tem = Flist (backtrace_nargs (pdl), backtrace_args (pdl));
3363 tem = *backlist->args;
3364 else
3365 tem = Flist (backlist->nargs, backlist->args);
3366 3371
3367 return Fcons (Qt, Fcons (backlist->function, tem)); 3372 return Fcons (Qt, Fcons (backtrace_function (pdl), tem));
3368 } 3373 }
3369} 3374}
3370 3375
3371 3376
3372#if BYTE_MARK_STACK
3373void 3377void
3374mark_backtrace (void) 3378mark_specpdl (struct specbinding *first, struct specbinding *ptr)
3375{ 3379{
3376 register struct backtrace *backlist; 3380 struct specbinding *pdl;
3377 ptrdiff_t i; 3381 for (pdl = first; pdl != ptr; pdl++)
3378
3379 for (backlist = backtrace_list; backlist; backlist = backlist->next)
3380 { 3382 {
3381 mark_object (backlist->function); 3383 switch (pdl->kind)
3384 {
3385 case SPECPDL_UNWIND:
3386 mark_object (specpdl_arg (pdl));
3387 break;
3388 case SPECPDL_BACKTRACE:
3389 {
3390 ptrdiff_t nargs = backtrace_nargs (pdl);
3391 mark_object (backtrace_function (pdl));
3392 if (nargs == UNEVALLED)
3393 nargs = 1;
3394 while (nargs--)
3395 mark_object (backtrace_args (pdl)[nargs]);
3396 }
3397 break;
3398 case SPECPDL_LET_DEFAULT:
3399 case SPECPDL_LET_LOCAL:
3400 mark_object (specpdl_where (pdl));
3401 case SPECPDL_LET:
3402 mark_object (specpdl_symbol (pdl));
3403 mark_object (specpdl_old_value (pdl));
3404 mark_object (specpdl_saved_value (pdl));
3405 }
3406 }
3407}
3408
3409void
3410get_backtrace (Lisp_Object array)
3411{
3412 struct specbinding *pdl = backtrace_next (backtrace_top ());
3413 ptrdiff_t i = 0, asize = ASIZE (array);
3382 3414
3383 if (backlist->nargs == UNEVALLED 3415 /* Copy the backtrace contents into working memory. */
3384 || backlist->nargs == MANY) /* FIXME: Can this happen? */ 3416 for (; i < asize; i++)
3385 i = 1; 3417 {
3418 if (backtrace_p (pdl))
3419 {
3420 ASET (array, i, backtrace_function (pdl));
3421 pdl = backtrace_next (pdl);
3422 }
3386 else 3423 else
3387 i = backlist->nargs; 3424 ASET (array, i, Qnil);
3388 while (i--)
3389 mark_object (backlist->args[i]);
3390 } 3425 }
3391} 3426}
3392#endif 3427
3428Lisp_Object backtrace_top_function (void)
3429{
3430 struct specbinding *pdl = backtrace_top ();
3431 return (backtrace_p (pdl) ? backtrace_function (pdl) : Qnil);
3432}
3393 3433
3394void 3434void
3395syms_of_eval (void) 3435syms_of_eval (void)
diff --git a/src/fileio.c b/src/fileio.c
index 724250c8aaa..75e1f13a09b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -36,7 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
36#include <selinux/context.h> 36#include <selinux/context.h>
37#endif 37#endif
38 38
39#ifdef HAVE_POSIX_ACL 39#ifdef HAVE_ACL_SET_FILE
40#include <sys/acl.h> 40#include <sys/acl.h>
41#endif 41#endif
42 42
@@ -82,6 +82,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
82#endif 82#endif
83 83
84#include "systime.h" 84#include "systime.h"
85#include <acl.h>
85#include <allocator.h> 86#include <allocator.h>
86#include <careadlinkat.h> 87#include <careadlinkat.h>
87#include <stat-time.h> 88#include <stat-time.h>
@@ -1969,7 +1970,7 @@ entries (depending on how Emacs was built). */)
1969 security_context_t con; 1970 security_context_t con;
1970 int conlength = 0; 1971 int conlength = 0;
1971#endif 1972#endif
1972#ifdef HAVE_POSIX_ACL 1973#ifdef WINDOWSNT
1973 acl_t acl = NULL; 1974 acl_t acl = NULL;
1974#endif 1975#endif
1975 1976
@@ -2009,11 +2010,9 @@ entries (depending on how Emacs was built). */)
2009#ifdef WINDOWSNT 2010#ifdef WINDOWSNT
2010 if (!NILP (preserve_extended_attributes)) 2011 if (!NILP (preserve_extended_attributes))
2011 { 2012 {
2012#ifdef HAVE_POSIX_ACL
2013 acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS); 2013 acl = acl_get_file (SDATA (encoded_file), ACL_TYPE_ACCESS);
2014 if (acl == NULL && errno != ENOTSUP) 2014 if (acl == NULL && acl_errno_valid (errno))
2015 report_file_error ("Getting ACL", Fcons (file, Qnil)); 2015 report_file_error ("Getting ACL", Fcons (file, Qnil));
2016#endif
2017 } 2016 }
2018 if (!CopyFile (SDATA (encoded_file), 2017 if (!CopyFile (SDATA (encoded_file),
2019 SDATA (encoded_newname), 2018 SDATA (encoded_newname),
@@ -2050,17 +2049,15 @@ entries (depending on how Emacs was built). */)
2050 /* Restore original attributes. */ 2049 /* Restore original attributes. */
2051 SetFileAttributes (filename, attributes); 2050 SetFileAttributes (filename, attributes);
2052 } 2051 }
2053#ifdef HAVE_POSIX_ACL
2054 if (acl != NULL) 2052 if (acl != NULL)
2055 { 2053 {
2056 bool fail = 2054 bool fail =
2057 acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0; 2055 acl_set_file (SDATA (encoded_newname), ACL_TYPE_ACCESS, acl) != 0;
2058 if (fail && errno != ENOTSUP) 2056 if (fail && acl_errno_valid (errno))
2059 report_file_error ("Setting ACL", Fcons (newname, Qnil)); 2057 report_file_error ("Setting ACL", Fcons (newname, Qnil));
2060 2058
2061 acl_free (acl); 2059 acl_free (acl);
2062 } 2060 }
2063#endif
2064#else /* not WINDOWSNT */ 2061#else /* not WINDOWSNT */
2065 immediate_quit = 1; 2062 immediate_quit = 1;
2066 ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0); 2063 ifd = emacs_open (SSDATA (encoded_file), O_RDONLY, 0);
@@ -2084,12 +2081,6 @@ entries (depending on how Emacs was built). */)
2084 report_file_error ("Doing fgetfilecon", Fcons (file, Qnil)); 2081 report_file_error ("Doing fgetfilecon", Fcons (file, Qnil));
2085 } 2082 }
2086#endif 2083#endif
2087
2088#ifdef HAVE_POSIX_ACL
2089 acl = acl_get_fd (ifd);
2090 if (acl == NULL && errno != ENOTSUP)
2091 report_file_error ("Getting ACL", Fcons (file, Qnil));
2092#endif
2093 } 2084 }
2094 2085
2095 if (out_st.st_mode != 0 2086 if (out_st.st_mode != 0
@@ -2137,7 +2128,7 @@ entries (depending on how Emacs was built). */)
2137 immediate_quit = 0; 2128 immediate_quit = 0;
2138 2129
2139#ifndef MSDOS 2130#ifndef MSDOS
2140 /* Preserve the original file modes, and if requested, also its 2131 /* Preserve the original file permissions, and if requested, also its
2141 owner and group. */ 2132 owner and group. */
2142 { 2133 {
2143 mode_t mode_mask = 07777; 2134 mode_t mode_mask = 07777;
@@ -2154,8 +2145,16 @@ entries (depending on how Emacs was built). */)
2154 mode_mask |= 02000; 2145 mode_mask |= 02000;
2155 } 2146 }
2156 } 2147 }
2157 if (fchmod (ofd, st.st_mode & mode_mask) != 0) 2148
2158 report_file_error ("Doing chmod", Fcons (newname, Qnil)); 2149 switch (!NILP (preserve_extended_attributes)
2150 ? qcopy_acl (SSDATA (encoded_file), ifd,
2151 SSDATA (encoded_newname), ofd,
2152 st.st_mode & mode_mask)
2153 : fchmod (ofd, st.st_mode & mode_mask))
2154 {
2155 case -2: report_file_error ("Copying permissions from", list1 (file));
2156 case -1: report_file_error ("Copying permissions to", list1 (newname));
2157 }
2159 } 2158 }
2160#endif /* not MSDOS */ 2159#endif /* not MSDOS */
2161 2160
@@ -2172,17 +2171,6 @@ entries (depending on how Emacs was built). */)
2172 } 2171 }
2173#endif 2172#endif
2174 2173
2175#ifdef HAVE_POSIX_ACL
2176 if (acl != NULL)
2177 {
2178 bool fail = acl_set_fd (ofd, acl) != 0;
2179 if (fail && errno != ENOTSUP)
2180 report_file_error ("Setting ACL", Fcons (newname, Qnil));
2181
2182 acl_free (acl);
2183 }
2184#endif
2185
2186 if (!NILP (keep_time)) 2174 if (!NILP (keep_time))
2187 { 2175 {
2188 EMACS_TIME atime = get_stat_atime (&st); 2176 EMACS_TIME atime = get_stat_atime (&st);
@@ -2885,7 +2873,7 @@ file_accessible_directory_p (char const *file)
2885 and it's a safe optimization here. */ 2873 and it's a safe optimization here. */
2886 char *buf = SAFE_ALLOCA (len + 3); 2874 char *buf = SAFE_ALLOCA (len + 3);
2887 memcpy (buf, file, len); 2875 memcpy (buf, file, len);
2888 strcpy (buf + len, "/." + (file[len - 1] == '/')); 2876 strcpy (buf + len, &"/."[file[len - 1] == '/']);
2889 dir = buf; 2877 dir = buf;
2890 } 2878 }
2891 2879
@@ -3092,7 +3080,7 @@ was unable to determine the ACL entries. */)
3092{ 3080{
3093 Lisp_Object absname; 3081 Lisp_Object absname;
3094 Lisp_Object handler; 3082 Lisp_Object handler;
3095#ifdef HAVE_POSIX_ACL 3083#ifdef HAVE_ACL_SET_FILE
3096 acl_t acl; 3084 acl_t acl;
3097 Lisp_Object acl_string; 3085 Lisp_Object acl_string;
3098 char *str; 3086 char *str;
@@ -3107,7 +3095,7 @@ was unable to determine the ACL entries. */)
3107 if (!NILP (handler)) 3095 if (!NILP (handler))
3108 return call2 (handler, Qfile_acl, absname); 3096 return call2 (handler, Qfile_acl, absname);
3109 3097
3110#ifdef HAVE_POSIX_ACL 3098#ifdef HAVE_ACL_SET_FILE
3111 absname = ENCODE_FILE (absname); 3099 absname = ENCODE_FILE (absname);
3112 3100
3113 acl = acl_get_file (SSDATA (absname), ACL_TYPE_ACCESS); 3101 acl = acl_get_file (SSDATA (absname), ACL_TYPE_ACCESS);
@@ -3145,7 +3133,7 @@ support. */)
3145{ 3133{
3146 Lisp_Object absname; 3134 Lisp_Object absname;
3147 Lisp_Object handler; 3135 Lisp_Object handler;
3148#ifdef HAVE_POSIX_ACL 3136#ifdef HAVE_ACL_SET_FILE
3149 Lisp_Object encoded_absname; 3137 Lisp_Object encoded_absname;
3150 acl_t acl; 3138 acl_t acl;
3151 bool fail; 3139 bool fail;
@@ -3159,7 +3147,7 @@ support. */)
3159 if (!NILP (handler)) 3147 if (!NILP (handler))
3160 return call3 (handler, Qset_file_acl, absname, acl_string); 3148 return call3 (handler, Qset_file_acl, absname, acl_string);
3161 3149
3162#ifdef HAVE_POSIX_ACL 3150#ifdef HAVE_ACL_SET_FILE
3163 if (STRINGP (acl_string)) 3151 if (STRINGP (acl_string))
3164 { 3152 {
3165 acl = acl_from_text (SSDATA (acl_string)); 3153 acl = acl_from_text (SSDATA (acl_string));
@@ -3174,7 +3162,7 @@ support. */)
3174 fail = (acl_set_file (SSDATA (encoded_absname), ACL_TYPE_ACCESS, 3162 fail = (acl_set_file (SSDATA (encoded_absname), ACL_TYPE_ACCESS,
3175 acl) 3163 acl)
3176 != 0); 3164 != 0);
3177 if (fail && errno != ENOTSUP) 3165 if (fail && acl_errno_valid (errno))
3178 report_file_error ("Setting ACL", Fcons (absname, Qnil)); 3166 report_file_error ("Setting ACL", Fcons (absname, Qnil));
3179 3167
3180 acl_free (acl); 3168 acl_free (acl);
@@ -3501,7 +3489,6 @@ by calling `format-decode', which see. */)
3501 EMACS_TIME mtime; 3489 EMACS_TIME mtime;
3502 int fd; 3490 int fd;
3503 ptrdiff_t inserted = 0; 3491 ptrdiff_t inserted = 0;
3504 bool nochange = 0;
3505 ptrdiff_t how_much; 3492 ptrdiff_t how_much;
3506 off_t beg_offset, end_offset; 3493 off_t beg_offset, end_offset;
3507 int unprocessed; 3494 int unprocessed;
@@ -3518,6 +3505,11 @@ by calling `format-decode', which see. */)
3518 bool set_coding_system = 0; 3505 bool set_coding_system = 0;
3519 Lisp_Object coding_system; 3506 Lisp_Object coding_system;
3520 bool read_quit = 0; 3507 bool read_quit = 0;
3508 /* If the undo log only contains the insertion, there's no point
3509 keeping it. It's typically when we first fill a file-buffer. */
3510 bool empty_undo_list_p
3511 = (!NILP (visit) && NILP (BVAR (current_buffer, undo_list))
3512 && BEG == Z);
3521 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark; 3513 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
3522 bool we_locked_file = 0; 3514 bool we_locked_file = 0;
3523 bool deferred_remove_unwind_protect = 0; 3515 bool deferred_remove_unwind_protect = 0;
@@ -3958,7 +3950,7 @@ by calling `format-decode', which see. */)
3958 3950
3959 /* If display currently starts at beginning of line, 3951 /* If display currently starts at beginning of line,
3960 keep it that way. */ 3952 keep it that way. */
3961 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) 3953 if (XBUFFER (XWINDOW (selected_window)->contents) == current_buffer)
3962 XWINDOW (selected_window)->start_at_line_beg = !NILP (Fbolp ()); 3954 XWINDOW (selected_window)->start_at_line_beg = !NILP (Fbolp ());
3963 3955
3964 replace_handled = 1; 3956 replace_handled = 1;
@@ -4067,9 +4059,7 @@ by calling `format-decode', which see. */)
4067 if (bufpos == inserted) 4059 if (bufpos == inserted)
4068 { 4060 {
4069 /* Truncate the buffer to the size of the file. */ 4061 /* Truncate the buffer to the size of the file. */
4070 if (same_at_start == same_at_end) 4062 if (same_at_start != same_at_end)
4071 nochange = 1;
4072 else
4073 del_range_byte (same_at_start, same_at_end, 0); 4063 del_range_byte (same_at_start, same_at_end, 0);
4074 inserted = 0; 4064 inserted = 0;
4075 4065
@@ -4108,7 +4098,7 @@ by calling `format-decode', which see. */)
4108 4098
4109 /* If display currently starts at beginning of line, 4099 /* If display currently starts at beginning of line,
4110 keep it that way. */ 4100 keep it that way. */
4111 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) 4101 if (XBUFFER (XWINDOW (selected_window)->contents) == current_buffer)
4112 XWINDOW (selected_window)->start_at_line_beg = !NILP (Fbolp ()); 4102 XWINDOW (selected_window)->start_at_line_beg = !NILP (Fbolp ());
4113 4103
4114 /* Replace the chars that we need to replace, 4104 /* Replace the chars that we need to replace,
@@ -4120,6 +4110,7 @@ by calling `format-decode', which see. */)
4120 { 4110 {
4121 del_range_byte (same_at_start, same_at_end, 0); 4111 del_range_byte (same_at_start, same_at_end, 0);
4122 temp = GPT; 4112 temp = GPT;
4113 eassert (same_at_start == GPT_BYTE);
4123 same_at_start = GPT_BYTE; 4114 same_at_start = GPT_BYTE;
4124 } 4115 }
4125 else 4116 else
@@ -4132,6 +4123,7 @@ by calling `format-decode', which see. */)
4132 = buf_bytepos_to_charpos (XBUFFER (conversion_buffer), 4123 = buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4133 same_at_start - BEGV_BYTE 4124 same_at_start - BEGV_BYTE
4134 + BUF_BEG_BYTE (XBUFFER (conversion_buffer))); 4125 + BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
4126 eassert (same_at_start_charpos == temp - (BEGV - BEG));
4135 inserted_chars 4127 inserted_chars
4136 = (buf_bytepos_to_charpos (XBUFFER (conversion_buffer), 4128 = (buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4137 same_at_start + inserted - BEGV_BYTE 4129 same_at_start + inserted - BEGV_BYTE
@@ -4218,7 +4210,8 @@ by calling `format-decode', which see. */)
4218 to be signaled after decoding the text we read. */ 4210 to be signaled after decoding the text we read. */
4219 nbytes = internal_condition_case_1 4211 nbytes = internal_condition_case_1
4220 (read_non_regular, 4212 (read_non_regular,
4221 make_save_value ("iii", (ptrdiff_t) fd, inserted, trytry), 4213 make_save_value (SAVE_TYPE_INT_INT_INT, (ptrdiff_t) fd,
4214 inserted, trytry),
4222 Qerror, read_non_regular_quit); 4215 Qerror, read_non_regular_quit);
4223 4216
4224 if (NILP (nbytes)) 4217 if (NILP (nbytes))
@@ -4415,7 +4408,7 @@ by calling `format-decode', which see. */)
4415 4408
4416 if (!NILP (visit)) 4409 if (!NILP (visit))
4417 { 4410 {
4418 if (!EQ (BVAR (current_buffer, undo_list), Qt) && !nochange) 4411 if (empty_undo_list_p)
4419 bset_undo_list (current_buffer, Qnil); 4412 bset_undo_list (current_buffer, Qnil);
4420 4413
4421 if (NILP (handler)) 4414 if (NILP (handler))
@@ -4557,7 +4550,7 @@ by calling `format-decode', which see. */)
4557 p = XCDR (p); 4550 p = XCDR (p);
4558 } 4551 }
4559 4552
4560 if (NILP (visit)) 4553 if (!empty_undo_list_p)
4561 { 4554 {
4562 bset_undo_list (current_buffer, old_undo); 4555 bset_undo_list (current_buffer, old_undo);
4563 if (CONSP (old_undo) && inserted != old_inserted) 4556 if (CONSP (old_undo) && inserted != old_inserted)
@@ -4959,15 +4952,14 @@ This calls `write-region-annotate-functions' at the start, and
4959 4952
4960 immediate_quit = 0; 4953 immediate_quit = 0;
4961 4954
4962 /* fsync appears to change the modtime on BSD4.2. 4955 /* fsync is not crucial for auto-save files, since they might lose
4963 Disk full in NFS may be reported here. */ 4956 some work anyway. */
4964 /* mib says that closing the file will try to write as fast as NFS can do
4965 it, and that means the fsync here is not crucial for autosave files. */
4966 if (!auto_saving && !write_region_inhibit_fsync) 4957 if (!auto_saving && !write_region_inhibit_fsync)
4967 { 4958 {
4968 /* Transfer data and metadata to disk, retrying if interrupted. Also, 4959 /* Transfer data and metadata to disk, retrying if interrupted.
4969 ignore EINVAL which happens when fsync is not supported on this 4960 fsync can report a write failure here, e.g., due to disk full
4970 file. */ 4961 under NFS. But ignore EINVAL, which means fsync is not
4962 supported on this file. */
4971 while (fsync (desc) != 0) 4963 while (fsync (desc) != 0)
4972 if (errno != EINTR) 4964 if (errno != EINTR)
4973 { 4965 {
@@ -5012,7 +5004,7 @@ This calls `write-region-annotate-functions' at the start, and
5012 && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system)) 5004 && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system))
5013 { 5005 {
5014 int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0); 5006 int desc1 = emacs_open (fn, O_WRONLY | O_BINARY, 0);
5015 if (0 <= desc1) 5007 if (desc1 >= 0)
5016 { 5008 {
5017 struct stat st1; 5009 struct stat st1;
5018 if (fstat (desc1, &st1) == 0 5010 if (fstat (desc1, &st1) == 0
@@ -5815,7 +5807,7 @@ before any other event (mouse or keypress) is handled. */)
5815 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 5807 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
5816 && use_dialog_box 5808 && use_dialog_box
5817 && use_file_dialog 5809 && use_file_dialog
5818 && have_menus_p ()) 5810 && window_system_available (SELECTED_FRAME ()))
5819 return Qt; 5811 return Qt;
5820#endif 5812#endif
5821 return Qnil; 5813 return Qnil;
@@ -6049,11 +6041,28 @@ in the buffer; this is the default behavior, because the auto-save
6049file is usually more useful if it contains the deleted text. */); 6041file is usually more useful if it contains the deleted text. */);
6050 Vauto_save_include_big_deletions = Qnil; 6042 Vauto_save_include_big_deletions = Qnil;
6051 6043
6044 /* fsync can be a significant performance hit. Often it doesn't
6045 suffice to make the file-save operation survive a crash. For
6046 batch scripts, which are typically part of larger shell commands
6047 that don't fsync other files, its effect on performance can be
6048 significant so its utility is particularly questionable.
6049 Hence, for now by default fsync is used only when interactive.
6050
6051 For more on why fsync often fails to work on today's hardware, see:
6052 Zheng M et al. Understanding the robustness of SSDs under power fault.
6053 11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
6054 http://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
6055
6056 For more on why fsync does not suffice even if it works properly, see:
6057 Roche X. Necessary step(s) to synchronize filename operations on disk.
6058 Austin Group Defect 672, 2013-03-19
6059 http://austingroupbugs.net/view.php?id=672 */
6052 DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync, 6060 DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync,
6053 doc: /* Non-nil means don't call fsync in `write-region'. 6061 doc: /* Non-nil means don't call fsync in `write-region'.
6054This variable affects calls to `write-region' as well as save commands. 6062This variable affects calls to `write-region' as well as save commands.
6055A non-nil value may result in data loss! */); 6063Setting this to nil may avoid data loss if the system loses power or
6056 write_region_inhibit_fsync = 0; 6064the operating system crashes. */);
6065 write_region_inhibit_fsync = noninteractive;
6057 6066
6058 DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash, 6067 DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
6059 doc: /* Specifies whether to use the system's trash can. 6068 doc: /* Specifies whether to use the system's trash can.
diff --git a/src/filelock.c b/src/filelock.c
index f17d3182eab..de6aba8385c 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -437,14 +437,8 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
437 if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len 437 if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len
438 || (need_fchmod && fchmod (fd, world_readable) != 0)) 438 || (need_fchmod && fchmod (fd, world_readable) != 0))
439 err = errno; 439 err = errno;
440 else 440 /* There is no need to call fsync here, as the contents of
441 while (fsync (fd) != 0) 441 the lock file need not survive system crashes. */
442 if (errno != EINTR)
443 {
444 if (errno != EINVAL)
445 err = errno;
446 break;
447 }
448 if (emacs_close (fd) != 0) 442 if (emacs_close (fd) != 0)
449 err = errno; 443 err = errno;
450 if (!err && rename_lock_file (nonce, lfname, force) != 0) 444 if (!err && rename_lock_file (nonce, lfname, force) != 0)
diff --git a/src/floatfns.c b/src/floatfns.c
index 43576a16248..6113758f964 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -193,7 +193,7 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
193 CHECK_NUMBER_OR_FLOAT (arg2); 193 CHECK_NUMBER_OR_FLOAT (arg2);
194 if (INTEGERP (arg1) /* common lisp spec */ 194 if (INTEGERP (arg1) /* common lisp spec */
195 && INTEGERP (arg2) /* don't promote, if both are ints, and */ 195 && INTEGERP (arg2) /* don't promote, if both are ints, and */
196 && 0 <= XINT (arg2)) /* we are sure the result is not fractional */ 196 && XINT (arg2) >= 0) /* we are sure the result is not fractional */
197 { /* this can be improved by pre-calculating */ 197 { /* this can be improved by pre-calculating */
198 EMACS_INT y; /* some binary powers of x then accumulating */ 198 EMACS_INT y; /* some binary powers of x then accumulating */
199 EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */ 199 EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */
@@ -475,7 +475,7 @@ fmod_float (Lisp_Object x, Lisp_Object y)
475 f1 = fmod (f1, f2); 475 f1 = fmod (f1, f2);
476 476
477 /* If the "remainder" comes out with the wrong sign, fix it. */ 477 /* If the "remainder" comes out with the wrong sign, fix it. */
478 if (f2 < 0 ? 0 < f1 : f1 < 0) 478 if (f2 < 0 ? f1 > 0 : f1 < 0)
479 f1 += f2; 479 f1 += f2;
480 480
481 return make_float (f1); 481 return make_float (f1);
diff --git a/src/fns.c b/src/fns.c
index b3a1dc2317a..08c6f055f38 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1551,7 +1551,7 @@ the value of a list `foo'. */)
1551 1551
1552 tail = list; 1552 tail = list;
1553 prev = Qnil; 1553 prev = Qnil;
1554 while (!NILP (tail)) 1554 while (CONSP (tail))
1555 { 1555 {
1556 CHECK_LIST_CONS (tail, list); 1556 CHECK_LIST_CONS (tail, list);
1557 tem = XCAR (tail); 1557 tem = XCAR (tail);
@@ -2443,10 +2443,9 @@ is nil, and `use-dialog-box' is non-nil. */)
2443 CHECK_STRING (prompt); 2443 CHECK_STRING (prompt);
2444 2444
2445#ifdef HAVE_MENUS 2445#ifdef HAVE_MENUS
2446 if (FRAME_WINDOW_P (SELECTED_FRAME ()) 2446 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2447 && (NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2448 && use_dialog_box 2447 && use_dialog_box
2449 && have_menus_p ()) 2448 && window_system_available (SELECTED_FRAME ()))
2450 { 2449 {
2451 Lisp_Object pane, menu, obj; 2450 Lisp_Object pane, menu, obj;
2452 redisplay_preserve_echo_area (4); 2451 redisplay_preserve_echo_area (4);
diff --git a/src/font.c b/src/font.c
index db7bf352c94..7bd44a5e52f 100644
--- a/src/font.c
+++ b/src/font.c
@@ -287,7 +287,7 @@ font_pixel_size (FRAME_PTR f, Lisp_Object spec)
287 if (INTEGERP (val)) 287 if (INTEGERP (val))
288 dpi = XINT (val); 288 dpi = XINT (val);
289 else 289 else
290 dpi = f->resy; 290 dpi = FRAME_RES_Y (f);
291 pixel_size = POINT_TO_PIXEL (point_size, dpi); 291 pixel_size = POINT_TO_PIXEL (point_size, dpi);
292 return pixel_size; 292 return pixel_size;
293#else 293#else
@@ -1219,7 +1219,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1219 return -1; 1219 return -1;
1220 f[j] = p = alloca (alloc); 1220 f[j] = p = alloca (alloc);
1221 sprintf (p, "%s%s-*", SDATA (val), 1221 sprintf (p, "%s%s-*", SDATA (val),
1222 "*" + (SDATA (val)[SBYTES (val) - 1] == '*')); 1222 &"*"[SDATA (val)[SBYTES (val) - 1] == '*']);
1223 } 1223 }
1224 else 1224 else
1225 f[j] = SSDATA (val); 1225 f[j] = SSDATA (val);
@@ -1618,7 +1618,7 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
1618 } 1618 }
1619 if (point_size > 0) 1619 if (point_size > 0)
1620 { 1620 {
1621 int len = snprintf (p, lim - p, "-%d" + (p == name), point_size); 1621 int len = snprintf (p, lim - p, &"-%d"[p == name], point_size);
1622 if (! (0 <= len && len < lim - p)) 1622 if (! (0 <= len && len < lim - p))
1623 return -1; 1623 return -1;
1624 p += len; 1624 p += len;
@@ -2819,7 +2819,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
2819 struct font_driver_list *driver_list; 2819 struct font_driver_list *driver_list;
2820 Lisp_Object objlist, size, val, font_object; 2820 Lisp_Object objlist, size, val, font_object;
2821 struct font *font; 2821 struct font *font;
2822 int min_width, height; 2822 int min_width, height, psize;
2823 2823
2824 eassert (FONT_ENTITY_P (entity)); 2824 eassert (FONT_ENTITY_P (entity));
2825 size = AREF (entity, FONT_SIZE_INDEX); 2825 size = AREF (entity, FONT_SIZE_INDEX);
@@ -2846,12 +2846,19 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
2846 } 2846 }
2847 } 2847 }
2848 2848
2849 font_object = driver_list->driver->open (f, entity, pixel_size); 2849 /* We always open a font of manageable size; i.e non-zero average
2850 if (!NILP (font_object)) 2850 width and height. */
2851 ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size)); 2851 for (psize = pixel_size; ; psize++)
2852 {
2853 font_object = driver_list->driver->open (f, entity, psize);
2854 if (NILP (font_object))
2855 return Qnil;
2856 font = XFONT_OBJECT (font_object);
2857 if (font->average_width > 0 && font->height > 0)
2858 break;
2859 }
2860 ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
2852 FONT_ADD_LOG ("open", entity, font_object); 2861 FONT_ADD_LOG ("open", entity, font_object);
2853 if (NILP (font_object))
2854 return Qnil;
2855 ASET (entity, FONT_OBJLIST_INDEX, 2862 ASET (entity, FONT_OBJLIST_INDEX,
2856 Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX))); 2863 Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX)));
2857 2864
@@ -3117,7 +3124,9 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
3117 { 3124 {
3118 double pt = XINT (attrs[LFACE_HEIGHT_INDEX]); 3125 double pt = XINT (attrs[LFACE_HEIGHT_INDEX]);
3119 3126
3120 pixel_size = POINT_TO_PIXEL (pt / 10, f->resy); 3127 pixel_size = POINT_TO_PIXEL (pt / 10, FRAME_RES_Y (f));
3128 if (pixel_size < 1)
3129 pixel_size = 1;
3121 } 3130 }
3122 ASET (work, FONT_SIZE_INDEX, Qnil); 3131 ASET (work, FONT_SIZE_INDEX, Qnil);
3123 foundry[0] = AREF (work, FONT_FOUNDRY_INDEX); 3132 foundry[0] = AREF (work, FONT_FOUNDRY_INDEX);
@@ -3247,12 +3256,13 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
3247 } 3256 }
3248 3257
3249 pt /= 10; 3258 pt /= 10;
3250 size = POINT_TO_PIXEL (pt, f->resy); 3259 size = POINT_TO_PIXEL (pt, FRAME_RES_Y (f));
3251#ifdef HAVE_NS 3260#ifdef HAVE_NS
3252 if (size == 0) 3261 if (size == 0)
3253 { 3262 {
3254 Lisp_Object ffsize = get_frame_param (f, Qfontsize); 3263 Lisp_Object ffsize = get_frame_param (f, Qfontsize);
3255 size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0; 3264 size = (NUMBERP (ffsize)
3265 ? POINT_TO_PIXEL (XINT (ffsize), FRAME_RES_Y (f)) : 0);
3256 } 3266 }
3257#endif 3267#endif
3258 } 3268 }
@@ -4021,7 +4031,7 @@ are to be displayed on. If omitted, the selected frame is used. */)
4021 if (INTEGERP (val)) 4031 if (INTEGERP (val))
4022 { 4032 {
4023 Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX); 4033 Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX);
4024 int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : f->resy; 4034 int dpi = INTEGERP (font_dpi) ? XINT (font_dpi) : FRAME_RES_Y (f);
4025 plist[n++] = QCheight; 4035 plist[n++] = QCheight;
4026 plist[n++] = make_number (PIXEL_TO_POINT (XINT (val) * 10, dpi)); 4036 plist[n++] = make_number (PIXEL_TO_POINT (XINT (val) * 10, dpi));
4027 } 4037 }
@@ -4532,7 +4542,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
4532 { 4542 {
4533 CHECK_NUMBER_OR_FLOAT (size); 4543 CHECK_NUMBER_OR_FLOAT (size);
4534 if (FLOATP (size)) 4544 if (FLOATP (size))
4535 isize = POINT_TO_PIXEL (XFLOAT_DATA (size), f->resy); 4545 isize = POINT_TO_PIXEL (XFLOAT_DATA (size), FRAME_RES_Y (f));
4536 else 4546 else
4537 isize = XINT (size); 4547 isize = XINT (size);
4538 if (! (INT_MIN <= isize && isize <= INT_MAX)) 4548 if (! (INT_MIN <= isize && isize <= INT_MAX))
@@ -4760,7 +4770,7 @@ character at index specified by POSITION. */)
4760 4770
4761 if (NILP (string)) 4771 if (NILP (string))
4762 { 4772 {
4763 if (XBUFFER (w->buffer) != current_buffer) 4773 if (XBUFFER (w->contents) != current_buffer)
4764 error ("Specified window is not displaying the current buffer."); 4774 error ("Specified window is not displaying the current buffer.");
4765 CHECK_NUMBER_COERCE_MARKER (position); 4775 CHECK_NUMBER_COERCE_MARKER (position);
4766 if (! (BEGV <= XINT (position) && XINT (position) < ZV)) 4776 if (! (BEGV <= XINT (position) && XINT (position) < ZV))
@@ -4843,11 +4853,9 @@ If the named font is not yet loaded, return nil. */)
4843 Lisp_Object info; 4853 Lisp_Object info;
4844 Lisp_Object font_object; 4854 Lisp_Object font_object;
4845 4855
4846 (*check_window_system_func) ();
4847
4848 if (! FONTP (name)) 4856 if (! FONTP (name))
4849 CHECK_STRING (name); 4857 CHECK_STRING (name);
4850 f = decode_live_frame (frame); 4858 f = decode_window_system_frame (frame);
4851 4859
4852 if (STRINGP (name)) 4860 if (STRINGP (name))
4853 { 4861 {
diff --git a/src/fontset.c b/src/fontset.c
index 3578bc9403d..2f6313c4214 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -179,10 +179,6 @@ static int next_fontset_id;
179 font for each character. */ 179 font for each character. */
180static Lisp_Object Vdefault_fontset; 180static Lisp_Object Vdefault_fontset;
181 181
182/* Check if any window system is used now. */
183void (*check_window_system_func) (void);
184
185
186/* Prototype declarations for static functions. */ 182/* Prototype declarations for static functions. */
187static Lisp_Object make_fontset (Lisp_Object, Lisp_Object, Lisp_Object); 183static Lisp_Object make_fontset (Lisp_Object, Lisp_Object, Lisp_Object);
188 184
@@ -1213,7 +1209,7 @@ If REGEXPP is non-nil, PATTERN is a regular expression. */)
1213 Lisp_Object fontset; 1209 Lisp_Object fontset;
1214 int id; 1210 int id;
1215 1211
1216 (*check_window_system_func) (); 1212 check_window_system (NULL);
1217 1213
1218 CHECK_STRING (pattern); 1214 CHECK_STRING (pattern);
1219 1215
@@ -1919,8 +1915,7 @@ format is the same as above. */)
1919 Lisp_Object val, elt; 1915 Lisp_Object val, elt;
1920 int c, i, j, k; 1916 int c, i, j, k;
1921 1917
1922 (*check_window_system_func) (); 1918 check_window_system (NULL);
1923
1924 fontset = check_fontset_name (fontset, &frame); 1919 fontset = check_fontset_name (fontset, &frame);
1925 1920
1926 /* Recode fontsets realized on FRAME from the base fontset FONTSET 1921 /* Recode fontsets realized on FRAME from the base fontset FONTSET
diff --git a/src/fontset.h b/src/fontset.h
index 07ee5d65c25..926520c8001 100644
--- a/src/fontset.h
+++ b/src/fontset.h
@@ -26,9 +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
29/* Check if any window system is used now. */
30extern void (*check_window_system_func) (void);
31
32struct face; 29struct face;
33 30
34extern void free_face_fontset (FRAME_PTR, struct face *); 31extern void free_face_fontset (FRAME_PTR, struct face *);
diff --git a/src/frame.c b/src/frame.c
index 0fa821682f3..e88432b9802 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -76,7 +76,6 @@ Lisp_Object Qterminal_live_p;
76Lisp_Object Qauto_raise, Qauto_lower; 76Lisp_Object Qauto_raise, Qauto_lower;
77Lisp_Object Qborder_color, Qborder_width; 77Lisp_Object Qborder_color, Qborder_width;
78Lisp_Object Qcursor_color, Qcursor_type; 78Lisp_Object Qcursor_color, Qcursor_type;
79static Lisp_Object Qgeometry; /* Not used */
80Lisp_Object Qheight, Qwidth; 79Lisp_Object Qheight, Qwidth;
81Lisp_Object Qleft, Qright; 80Lisp_Object Qleft, Qright;
82Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; 81Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
@@ -115,6 +114,8 @@ Lisp_Object Qface_set_after_frame_default;
115 114
116static Lisp_Object Qdelete_frame_functions; 115static Lisp_Object Qdelete_frame_functions;
117 116
117Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
118
118#ifdef HAVE_WINDOW_SYSTEM 119#ifdef HAVE_WINDOW_SYSTEM
119static void x_report_frame_params (struct frame *, Lisp_Object *); 120static void x_report_frame_params (struct frame *, Lisp_Object *);
120#endif 121#endif
@@ -149,25 +150,56 @@ decode_any_frame (register Lisp_Object frame)
149 return XFRAME (frame); 150 return XFRAME (frame);
150} 151}
151 152
153bool
154window_system_available (struct frame *f)
155{
156 if (f)
157 return FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f);
158 else
159#ifdef HAVE_WINDOW_SYSTEM
160 return x_display_list != NULL;
161#else
162 return 0;
163#endif
164}
165
166struct frame *
167decode_window_system_frame (Lisp_Object frame)
168{
169 struct frame *f = decode_live_frame (frame);
170
171 if (!window_system_available (f))
172 error ("Window system frame should be used");
173 return f;
174}
175
176void
177check_window_system (struct frame *f)
178{
179 if (!window_system_available (f))
180 error (f ? "Window system frame should be used"
181 : "Window system is not in use or not initialized");
182}
183
152static void 184static void
153set_menu_bar_lines_1 (Lisp_Object window, int n) 185set_menu_bar_lines_1 (Lisp_Object window, int n)
154{ 186{
155 struct window *w = XWINDOW (window); 187 struct window *w = XWINDOW (window);
156 188
157 w->last_modified = 0; 189 w->last_modified = 0;
158 wset_top_line (w, make_number (XFASTINT (w->top_line) + n)); 190 w->top_line += n;
159 wset_total_lines (w, make_number (XFASTINT (w->total_lines) - n)); 191 w->total_lines -= n;
160 192
161 /* Handle just the top child in a vertical split. */ 193 /* Handle just the top child in a vertical split. */
162 if (!NILP (w->vchild)) 194 if (WINDOW_VERTICAL_COMBINATION_P (w))
163 set_menu_bar_lines_1 (w->vchild, n); 195 set_menu_bar_lines_1 (w->contents, n);
164 196 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
165 /* Adjust all children in a horizontal split. */ 197 /* Adjust all children in a horizontal split. */
166 for (window = w->hchild; !NILP (window); window = w->next) 198 for (window = w->contents; !NILP (window); window = w->next)
167 { 199 {
168 w = XWINDOW (window); 200 w = XWINDOW (window);
169 set_menu_bar_lines_1 (window, n); 201 set_menu_bar_lines_1 (window, n);
170 } 202 }
171} 203}
172 204
173void 205void
@@ -332,14 +364,14 @@ make_frame (int mini_p)
332 SET_FRAME_COLS (f, 10); 364 SET_FRAME_COLS (f, 10);
333 FRAME_LINES (f) = 10; 365 FRAME_LINES (f) = 10;
334 366
335 wset_total_cols (XWINDOW (root_window), make_number (10)); 367 XWINDOW (root_window)->total_cols = 10;
336 wset_total_lines (XWINDOW (root_window), make_number (mini_p ? 9 : 10)); 368 XWINDOW (root_window)->total_lines = mini_p ? 9 : 10;
337 369
338 if (mini_p) 370 if (mini_p)
339 { 371 {
340 wset_total_cols (XWINDOW (mini_window), make_number (10)); 372 XWINDOW (mini_window)->total_cols = 10;
341 wset_top_line (XWINDOW (mini_window), make_number (9)); 373 XWINDOW (mini_window)->top_line = 9;
342 wset_total_lines (XWINDOW (mini_window), make_number (1)); 374 XWINDOW (mini_window)->total_lines = 1;
343 } 375 }
344 376
345 /* Choose a buffer for the frame's root window. */ 377 /* Choose a buffer for the frame's root window. */
@@ -421,7 +453,7 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis
421 453
422 /* Make the chosen minibuffer window display the proper minibuffer, 454 /* Make the chosen minibuffer window display the proper minibuffer,
423 unless it is already showing a minibuffer. */ 455 unless it is already showing a minibuffer. */
424 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list))) 456 if (NILP (Fmemq (XWINDOW (mini_window)->contents, Vminibuffer_list)))
425 /* Use set_window_buffer instead of Fset_window_buffer (see 457 /* Use set_window_buffer instead of Fset_window_buffer (see
426 discussion of bug#11984, bug#12025, bug#12026). */ 458 discussion of bug#11984, bug#12025, bug#12026). */
427 set_window_buffer (mini_window, 459 set_window_buffer (mini_window,
@@ -803,10 +835,18 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
803 835
804 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame))) 836 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
805 { 837 {
806 if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame)) 838 Lisp_Object top_frame = FRAME_TTY (XFRAME (frame))->top_frame;
807 /* Mark previously displayed frame as now obscured. */ 839
808 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (XFRAME (frame))->top_frame), 2); 840 /* Don't mark the frame garbaged and/or obscured if we are
809 SET_FRAME_VISIBLE (XFRAME (frame), 1); 841 switching to the frame that is already the top frame of that
842 TTY. */
843 if (!EQ (frame, top_frame))
844 {
845 if (FRAMEP (top_frame))
846 /* Mark previously displayed frame as now obscured. */
847 SET_FRAME_VISIBLE (XFRAME (top_frame), 2);
848 SET_FRAME_VISIBLE (XFRAME (frame), 1);
849 }
810 FRAME_TTY (XFRAME (frame))->top_frame = frame; 850 FRAME_TTY (XFRAME (frame))->top_frame = frame;
811 } 851 }
812 852
@@ -889,7 +929,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
889/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the 929/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
890 same tty (for tty frames) or among frames which uses FRAME's keyboard. 930 same tty (for tty frames) or among frames which uses FRAME's keyboard.
891 If MINIBUF is nil, do not consider minibuffer-only candidate. 931 If MINIBUF is nil, do not consider minibuffer-only candidate.
892 If MINIBUF is `visible', do not consider an invisible candidate. 932 If MINIBUF is `visible', do not consider an invisible candidate.
893 If MINIBUF is a window, consider only its own frame and candidate now 933 If MINIBUF is a window, consider only its own frame and candidate now
894 using that window as the minibuffer. 934 using that window as the minibuffer.
895 If MINIBUF is 0, consider candidate if it is visible or iconified. 935 If MINIBUF is 0, consider candidate if it is visible or iconified.
@@ -1189,7 +1229,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1189 /* Use set_window_buffer instead of Fset_window_buffer (see 1229 /* Use set_window_buffer instead of Fset_window_buffer (see
1190 discussion of bug#11984, bug#12025, bug#12026). */ 1230 discussion of bug#11984, bug#12025, bug#12026). */
1191 set_window_buffer (sf->minibuffer_window, 1231 set_window_buffer (sf->minibuffer_window,
1192 XWINDOW (minibuf_window)->buffer, 0, 0); 1232 XWINDOW (minibuf_window)->contents, 0, 0);
1193 minibuf_window = sf->minibuffer_window; 1233 minibuf_window = sf->minibuffer_window;
1194 1234
1195 /* If the dying minibuffer window was selected, 1235 /* If the dying minibuffer window was selected,
@@ -1593,17 +1633,13 @@ make_frame_visible_1 (Lisp_Object window)
1593{ 1633{
1594 struct window *w; 1634 struct window *w;
1595 1635
1596 for (;!NILP (window); window = w->next) 1636 for (; !NILP (window); window = w->next)
1597 { 1637 {
1598 w = XWINDOW (window); 1638 w = XWINDOW (window);
1599 1639 if (WINDOWP (w->contents))
1600 if (!NILP (w->buffer)) 1640 make_frame_visible_1 (w->contents);
1601 bset_display_time (XBUFFER (w->buffer), Fcurrent_time ()); 1641 else
1602 1642 bset_display_time (XBUFFER (w->contents), Fcurrent_time ());
1603 if (!NILP (w->vchild))
1604 make_frame_visible_1 (w->vchild);
1605 if (!NILP (w->hchild))
1606 make_frame_visible_1 (w->hchild);
1607 } 1643 }
1608} 1644}
1609 1645
@@ -1634,7 +1670,7 @@ displayed in the terminal. */)
1634 /* Use set_window_buffer instead of Fset_window_buffer (see 1670 /* Use set_window_buffer instead of Fset_window_buffer (see
1635 discussion of bug#11984, bug#12025, bug#12026). */ 1671 discussion of bug#11984, bug#12025, bug#12026). */
1636 set_window_buffer (sf->minibuffer_window, 1672 set_window_buffer (sf->minibuffer_window,
1637 XWINDOW (minibuf_window)->buffer, 0, 0); 1673 XWINDOW (minibuf_window)->contents, 0, 0);
1638 minibuf_window = sf->minibuffer_window; 1674 minibuf_window = sf->minibuffer_window;
1639 } 1675 }
1640 1676
@@ -1665,7 +1701,7 @@ If omitted, FRAME defaults to the currently selected frame. */)
1665 /* Use set_window_buffer instead of Fset_window_buffer (see 1701 /* Use set_window_buffer instead of Fset_window_buffer (see
1666 discussion of bug#11984, bug#12025, bug#12026). */ 1702 discussion of bug#11984, bug#12025, bug#12026). */
1667 set_window_buffer (sf->minibuffer_window, 1703 set_window_buffer (sf->minibuffer_window,
1668 XWINDOW (minibuf_window)->buffer, 0, 0); 1704 XWINDOW (minibuf_window)->contents, 0, 0);
1669 minibuf_window = sf->minibuffer_window; 1705 minibuf_window = sf->minibuffer_window;
1670 } 1706 }
1671 1707
@@ -1819,7 +1855,7 @@ See `redirect-frame-focus'. */)
1819/* Return the value of frame parameter PROP in frame FRAME. */ 1855/* Return the value of frame parameter PROP in frame FRAME. */
1820 1856
1821#ifdef HAVE_WINDOW_SYSTEM 1857#ifdef HAVE_WINDOW_SYSTEM
1822#if !HAVE_NS 1858#if !HAVE_NS && !defined(WINDOWSNT)
1823static 1859static
1824#endif 1860#endif
1825Lisp_Object 1861Lisp_Object
@@ -3315,16 +3351,15 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3315 else if (FLOATP (item)) 3351 else if (FLOATP (item))
3316 { 3352 {
3317 alpha = XFLOAT_DATA (item); 3353 alpha = XFLOAT_DATA (item);
3318 if (alpha < 0.0 || 1.0 < alpha) 3354 if (! (0 <= alpha && alpha <= 1.0))
3319 args_out_of_range (make_float (0.0), make_float (1.0)); 3355 args_out_of_range (make_float (0.0), make_float (1.0));
3320 } 3356 }
3321 else if (INTEGERP (item)) 3357 else if (INTEGERP (item))
3322 { 3358 {
3323 EMACS_INT ialpha = XINT (item); 3359 EMACS_INT ialpha = XINT (item);
3324 if (ialpha < 0 || 100 < ialpha) 3360 if (! (0 <= ialpha && alpha <= 100))
3325 args_out_of_range (make_number (0), make_number (100)); 3361 args_out_of_range (make_number (0), make_number (100));
3326 else 3362 alpha = ialpha / 100.0;
3327 alpha = ialpha / 100.0;
3328 } 3363 }
3329 else 3364 else
3330 wrong_type_argument (Qnumberp, item); 3365 wrong_type_argument (Qnumberp, item);
@@ -3495,11 +3530,10 @@ The optional arguments COMPONENT and SUBCLASS add to the key and the
3495class, respectively. You must specify both of them or neither. 3530class, respectively. You must specify both of them or neither.
3496If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE' 3531If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3497and the class is `Emacs.CLASS.SUBCLASS'. */) 3532and the class is `Emacs.CLASS.SUBCLASS'. */)
3498 (Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) 3533 (Lisp_Object attribute, Lisp_Object class, Lisp_Object component,
3534 Lisp_Object subclass)
3499{ 3535{
3500#ifdef HAVE_X_WINDOWS 3536 check_window_system (NULL);
3501 check_x ();
3502#endif
3503 3537
3504 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb, 3538 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3505 attribute, class, component, subclass); 3539 attribute, class, component, subclass);
@@ -3508,7 +3542,9 @@ and the class is `Emacs.CLASS.SUBCLASS'. */)
3508/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */ 3542/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3509 3543
3510Lisp_Object 3544Lisp_Object
3511display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) 3545display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
3546 Lisp_Object class, Lisp_Object component,
3547 Lisp_Object subclass)
3512{ 3548{
3513 return xrdb_get_resource (dpyinfo->xrdb, 3549 return xrdb_get_resource (dpyinfo->xrdb,
3514 attribute, class, component, subclass); 3550 attribute, class, component, subclass);
@@ -4094,6 +4130,73 @@ selected frame. This is useful when `make-pointer-invisible' is set. */)
4094 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt; 4130 return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
4095} 4131}
4096 4132
4133
4134
4135/***********************************************************************
4136 Multimonitor data
4137 ***********************************************************************/
4138
4139#ifdef HAVE_WINDOW_SYSTEM
4140
4141void
4142free_monitors (struct MonitorInfo *monitors, int n_monitors)
4143{
4144 int i;
4145 for (i = 0; i < n_monitors; ++i)
4146 xfree (monitors[i].name);
4147 xfree (monitors);
4148}
4149
4150Lisp_Object
4151make_monitor_attribute_list (struct MonitorInfo *monitors,
4152 int n_monitors,
4153 int primary_monitor,
4154 Lisp_Object monitor_frames,
4155 const char *source)
4156{
4157 Lisp_Object attributes_list = Qnil;
4158 Lisp_Object primary_monitor_attributes = Qnil;
4159 int i;
4160
4161 for (i = 0; i < n_monitors; ++i)
4162 {
4163 Lisp_Object geometry, workarea, attributes = Qnil;
4164 struct MonitorInfo *mi = &monitors[i];
4165
4166 if (mi->geom.width == 0) continue;
4167
4168 workarea = list4i (mi->work.x, mi->work.y,
4169 mi->work.width, mi->work.height);
4170 geometry = list4i (mi->geom.x, mi->geom.y,
4171 mi->geom.width, mi->geom.height);
4172 attributes = Fcons (Fcons (Qsource,
4173 make_string (source, strlen (source))),
4174 attributes);
4175 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
4176 attributes);
4177 attributes = Fcons (Fcons (Qmm_size,
4178 list2i (mi->mm_width, mi->mm_height)),
4179 attributes);
4180 attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
4181 attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
4182 if (mi->name)
4183 attributes = Fcons (Fcons (Qname, make_string (mi->name,
4184 strlen (mi->name))),
4185 attributes);
4186
4187 if (i == primary_monitor)
4188 primary_monitor_attributes = attributes;
4189 else
4190 attributes_list = Fcons (attributes, attributes_list);
4191 }
4192
4193 if (!NILP (primary_monitor_attributes))
4194 attributes_list = Fcons (primary_monitor_attributes, attributes_list);
4195 return attributes_list;
4196}
4197
4198#endif /* HAVE_WINDOW_SYSTEM */
4199
4097 4200
4098/*********************************************************************** 4201/***********************************************************************
4099 Initialization 4202 Initialization
@@ -4152,6 +4255,12 @@ syms_of_frame (void)
4152 DEFSYM (Qterminal, "terminal"); 4255 DEFSYM (Qterminal, "terminal");
4153 DEFSYM (Qterminal_live_p, "terminal-live-p"); 4256 DEFSYM (Qterminal_live_p, "terminal-live-p");
4154 4257
4258 DEFSYM (Qgeometry, "geometry");
4259 DEFSYM (Qworkarea, "workarea");
4260 DEFSYM (Qmm_size, "mm-size");
4261 DEFSYM (Qframes, "frames");
4262 DEFSYM (Qsource, "source");
4263
4155#ifdef HAVE_NS 4264#ifdef HAVE_NS
4156 DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); 4265 DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
4157#endif 4266#endif
diff --git a/src/frame.h b/src/frame.h
index c18b7662079..12aa48b2d92 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -170,9 +170,11 @@ struct frame
170 most recently buried buffer is first. For last-buffer. */ 170 most recently buried buffer is first. For last-buffer. */
171 Lisp_Object buried_buffer_list; 171 Lisp_Object buried_buffer_list;
172 172
173#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
173 /* A dummy window used to display menu bars under X when no X 174 /* A dummy window used to display menu bars under X when no X
174 toolkit support is available. */ 175 toolkit support is available. */
175 Lisp_Object menu_bar_window; 176 Lisp_Object menu_bar_window;
177#endif
176 178
177 /* A window used to display the tool-bar of a frame. */ 179 /* A window used to display the tool-bar of a frame. */
178 Lisp_Object tool_bar_window; 180 Lisp_Object tool_bar_window;
@@ -276,9 +278,6 @@ struct frame
276 /* Size of the frame window in pixels. */ 278 /* Size of the frame window in pixels. */
277 int pixel_height, pixel_width; 279 int pixel_height, pixel_width;
278 280
279 /* Dots per inch of the screen the frame is on. */
280 double resx, resy;
281
282 /* These many pixels are the difference between the outer window (i.e. the 281 /* These many pixels are the difference between the outer window (i.e. the
283 left and top of the window manager decoration) and FRAME_X_WINDOW. */ 282 left and top of the window manager decoration) and FRAME_X_WINDOW. */
284 int x_pixels_diff, y_pixels_diff; 283 int x_pixels_diff, y_pixels_diff;
@@ -428,10 +427,6 @@ struct frame
428 /* Width of bar cursor (if we are using that) for blink-off state. */ 427 /* Width of bar cursor (if we are using that) for blink-off state. */
429 int blink_off_cursor_width; 428 int blink_off_cursor_width;
430 429
431 /* Nonnegative if current redisplay should not do scroll computation
432 for lines beyond a certain vpos. This is the vpos. */
433 int scroll_bottom_vpos;
434
435 /* Configured width of the scroll bar, in pixels and in characters. 430 /* Configured width of the scroll bar, in pixels and in characters.
436 config_scroll_bar_cols tracks config_scroll_bar_width if the 431 config_scroll_bar_cols tracks config_scroll_bar_width if the
437 latter is positive; a zero value in config_scroll_bar_width means 432 latter is positive; a zero value in config_scroll_bar_width means
@@ -518,11 +513,13 @@ fset_menu_bar_vector (struct frame *f, Lisp_Object val)
518{ 513{
519 f->menu_bar_vector = val; 514 f->menu_bar_vector = val;
520} 515}
516#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
521FRAME_INLINE void 517FRAME_INLINE void
522fset_menu_bar_window (struct frame *f, Lisp_Object val) 518fset_menu_bar_window (struct frame *f, Lisp_Object val)
523{ 519{
524 f->menu_bar_window = val; 520 f->menu_bar_window = val;
525} 521}
522#endif
526FRAME_INLINE void 523FRAME_INLINE void
527fset_name (struct frame *f, Lisp_Object val) 524fset_name (struct frame *f, Lisp_Object val)
528{ 525{
@@ -569,6 +566,26 @@ fset_tool_bar_window (struct frame *f, Lisp_Object val)
569 f->tool_bar_window = val; 566 f->tool_bar_window = val;
570} 567}
571 568
569#define NUMVAL(X) ((INTEGERP (X) || FLOATP (X)) ? XFLOATINT (X) : -1)
570
571FRAME_INLINE double
572default_pixels_per_inch_x (void)
573{
574 Lisp_Object v = (CONSP (Vdisplay_pixels_per_inch)
575 ? XCAR (Vdisplay_pixels_per_inch)
576 : Vdisplay_pixels_per_inch);
577 return NUMVAL (v) > 0 ? NUMVAL (v) : 72.0;
578}
579
580FRAME_INLINE double
581default_pixels_per_inch_y (void)
582{
583 Lisp_Object v = (CONSP (Vdisplay_pixels_per_inch)
584 ? XCDR (Vdisplay_pixels_per_inch)
585 : Vdisplay_pixels_per_inch);
586 return NUMVAL (v) > 0 ? NUMVAL (v) : 72.0;
587}
588
572#define FRAME_KBOARD(f) ((f)->terminal->kboard) 589#define FRAME_KBOARD(f) ((f)->terminal->kboard)
573 590
574/* Return a pointer to the image cache of frame F. */ 591/* Return a pointer to the image cache of frame F. */
@@ -581,7 +598,7 @@ typedef struct frame *FRAME_PTR;
581#define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME)) 598#define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME))
582 599
583/* Given a window, return its frame as a Lisp_Object. */ 600/* Given a window, return its frame as a Lisp_Object. */
584#define WINDOW_FRAME(w) w->frame 601#define WINDOW_FRAME(w) ((w)->frame)
585 602
586/* Test a frame for particular kinds of display methods. */ 603/* Test a frame for particular kinds of display methods. */
587#define FRAME_INITIAL_P(f) ((f)->output_method == output_initial) 604#define FRAME_INITIAL_P(f) ((f)->output_method == output_initial)
@@ -602,6 +619,37 @@ typedef struct frame *FRAME_PTR;
602#else 619#else
603#define FRAME_NS_P(f) ((f)->output_method == output_ns) 620#define FRAME_NS_P(f) ((f)->output_method == output_ns)
604#endif 621#endif
622
623/* Dots per inch of the screen the frame F is on. */
624
625#ifdef HAVE_X_WINDOWS
626#define FRAME_RES_X(f) \
627 (eassert (FRAME_X_P (f)), FRAME_X_DISPLAY_INFO (f)->resx)
628#define FRAME_RES_Y(f) \
629 (eassert (FRAME_X_P (f)), FRAME_X_DISPLAY_INFO (f)->resy)
630#endif
631
632#ifdef HAVE_NTGUI
633#define FRAME_RES_X(f) \
634 (eassert (FRAME_W32_P (f)), FRAME_W32_DISPLAY_INFO (f)->resx)
635#define FRAME_RES_Y(f) \
636 (eassert (FRAME_W32_P (f)), FRAME_W32_DISPLAY_INFO (f)->resy)
637#endif
638
639#ifdef HAVE_NS
640#define FRAME_RES_X(f) \
641 (eassert (FRAME_NS_P (f)), FRAME_NS_DISPLAY_INFO (f)->resx)
642#define FRAME_RES_Y(f) \
643 (eassert (FRAME_NS_P (f)), FRAME_NS_DISPLAY_INFO (f)->resy)
644#endif
645
646/* Defaults when no window system available. */
647
648#ifndef FRAME_RES_X
649#define FRAME_RES_X(f) default_pixels_per_inch_x ()
650#define FRAME_RES_Y(f) default_pixels_per_inch_y ()
651#endif
652
605/* FRAME_WINDOW_P tests whether the frame is a window, and is 653/* FRAME_WINDOW_P tests whether the frame is a window, and is
606 defined to be the predicate for the window system being used. */ 654 defined to be the predicate for the window system being used. */
607 655
@@ -733,7 +781,6 @@ typedef struct frame *FRAME_PTR;
733#define FRAME_DELETE_COST(f) (f)->delete_line_cost 781#define FRAME_DELETE_COST(f) (f)->delete_line_cost
734#define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost 782#define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost
735#define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost 783#define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost
736#define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos
737#define FRAME_FOCUS_FRAME(f) f->focus_frame 784#define FRAME_FOCUS_FRAME(f) f->focus_frame
738 785
739/* This frame slot says whether scroll bars are currently enabled for frame F, 786/* This frame slot says whether scroll bars are currently enabled for frame F,
@@ -911,6 +958,7 @@ extern Lisp_Object Qnoelisp;
911extern struct frame *last_nonminibuf_frame; 958extern struct frame *last_nonminibuf_frame;
912 959
913extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); 960extern void set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
961extern struct frame *decode_window_system_frame (Lisp_Object);
914extern struct frame *decode_live_frame (Lisp_Object); 962extern struct frame *decode_live_frame (Lisp_Object);
915extern struct frame *decode_any_frame (Lisp_Object); 963extern struct frame *decode_any_frame (Lisp_Object);
916extern struct frame *make_initial_frame (void); 964extern struct frame *make_initial_frame (void);
@@ -921,6 +969,8 @@ extern struct frame *make_frame_without_minibuffer (Lisp_Object,
921 struct kboard *, 969 struct kboard *,
922 Lisp_Object); 970 Lisp_Object);
923#endif /* HAVE_WINDOW_SYSTEM */ 971#endif /* HAVE_WINDOW_SYSTEM */
972extern bool window_system_available (struct frame *);
973extern void check_window_system (struct frame *);
924extern void frame_make_pointer_invisible (void); 974extern void frame_make_pointer_invisible (void);
925extern void frame_make_pointer_visible (void); 975extern void frame_make_pointer_visible (void);
926extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); 976extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
@@ -1148,6 +1198,8 @@ extern Lisp_Object Qdisplay;
1148 1198
1149extern Lisp_Object Qrun_hook_with_args; 1199extern Lisp_Object Qrun_hook_with_args;
1150 1200
1201extern Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
1202
1151#ifdef HAVE_WINDOW_SYSTEM 1203#ifdef HAVE_WINDOW_SYSTEM
1152 1204
1153/* The class of this X application. */ 1205/* The class of this X application. */
@@ -1238,6 +1290,28 @@ extern void x_query_colors (struct frame *f, XColor *, int);
1238extern void x_query_color (struct frame *f, XColor *); 1290extern void x_query_color (struct frame *f, XColor *);
1239 1291
1240#endif /* HAVE_WINDOW_SYSTEM */ 1292#endif /* HAVE_WINDOW_SYSTEM */
1293
1294/***********************************************************************
1295 Multimonitor data
1296 ***********************************************************************/
1297
1298#ifdef HAVE_WINDOW_SYSTEM
1299
1300struct MonitorInfo {
1301 XRectangle geom, work;
1302 int mm_width, mm_height;
1303 char *name;
1304};
1305
1306extern void free_monitors (struct MonitorInfo *monitors, int n_monitors);
1307extern Lisp_Object make_monitor_attribute_list (struct MonitorInfo *monitors,
1308 int n_monitors,
1309 int primary_monitor,
1310 Lisp_Object monitor_frames,
1311 const char *source);
1312
1313#endif /* HAVE_WINDOW_SYSTEM */
1314
1241 1315
1242INLINE_HEADER_END 1316INLINE_HEADER_END
1243 1317
diff --git a/src/fringe.c b/src/fringe.c
index fa6f889ba69..f728cd6d5ff 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -699,7 +699,7 @@ get_logical_cursor_bitmap (struct window *w, Lisp_Object cursor)
699{ 699{
700 Lisp_Object cmap, bm = Qnil; 700 Lisp_Object cmap, bm = Qnil;
701 701
702 if ((cmap = BVAR (XBUFFER (w->buffer), fringe_cursor_alist)), !NILP (cmap)) 702 if ((cmap = BVAR (XBUFFER (w->contents), fringe_cursor_alist)), !NILP (cmap))
703 { 703 {
704 bm = Fassq (cursor, cmap); 704 bm = Fassq (cursor, cmap);
705 if (CONSP (bm)) 705 if (CONSP (bm))
@@ -736,7 +736,7 @@ get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, in
736 If partial, lookup partial bitmap in default value if not found here. 736 If partial, lookup partial bitmap in default value if not found here.
737 If not partial, or no partial spec is present, use non-partial bitmap. */ 737 If not partial, or no partial spec is present, use non-partial bitmap. */
738 738
739 if ((cmap = BVAR (XBUFFER (w->buffer), fringe_indicator_alist)), !NILP (cmap)) 739 if ((cmap = BVAR (XBUFFER (w->contents), fringe_indicator_alist)), !NILP (cmap))
740 { 740 {
741 bm1 = Fassq (bitmap, cmap); 741 bm1 = Fassq (bitmap, cmap);
742 if (CONSP (bm1)) 742 if (CONSP (bm1))
@@ -963,7 +963,7 @@ update_window_fringes (struct window *w, int keep_current_p)
963 return 0; 963 return 0;
964 964
965 if (!MINI_WINDOW_P (w) 965 if (!MINI_WINDOW_P (w)
966 && (ind = BVAR (XBUFFER (w->buffer), indicate_buffer_boundaries), !NILP (ind))) 966 && (ind = BVAR (XBUFFER (w->contents), indicate_buffer_boundaries), !NILP (ind)))
967 { 967 {
968 if (EQ (ind, Qleft) || EQ (ind, Qright)) 968 if (EQ (ind, Qleft) || EQ (ind, Qright))
969 boundary_top = boundary_bot = arrow_top = arrow_bot = ind; 969 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
@@ -1004,7 +1004,7 @@ update_window_fringes (struct window *w, int keep_current_p)
1004 { 1004 {
1005 if (top_ind_rn < 0 && row->visible_height > 0) 1005 if (top_ind_rn < 0 && row->visible_height > 0)
1006 { 1006 {
1007 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)) 1007 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->contents))
1008 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row)) 1008 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
1009 row->indicate_bob_p = !NILP (boundary_top); 1009 row->indicate_bob_p = !NILP (boundary_top);
1010 else 1010 else
@@ -1014,7 +1014,7 @@ update_window_fringes (struct window *w, int keep_current_p)
1014 1014
1015 if (bot_ind_rn < 0) 1015 if (bot_ind_rn < 0)
1016 { 1016 {
1017 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)) 1017 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->contents))
1018 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) 1018 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
1019 row->indicate_eob_p = !NILP (boundary_bot), bot_ind_rn = rn; 1019 row->indicate_eob_p = !NILP (boundary_bot), bot_ind_rn = rn;
1020 else if (y + row->height >= yb) 1020 else if (y + row->height >= yb)
@@ -1024,7 +1024,7 @@ update_window_fringes (struct window *w, int keep_current_p)
1024 } 1024 }
1025 } 1025 }
1026 1026
1027 empty_pos = BVAR (XBUFFER (w->buffer), indicate_empty_lines); 1027 empty_pos = BVAR (XBUFFER (w->contents), indicate_empty_lines);
1028 if (!NILP (empty_pos) && !EQ (empty_pos, Qright)) 1028 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
1029 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft; 1029 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
1030 1030
diff --git a/src/ftfont.c b/src/ftfont.c
index 867e25a7a25..0ad173af98a 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -393,7 +393,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
393 cache_data = xmalloc (sizeof *cache_data); 393 cache_data = xmalloc (sizeof *cache_data);
394 cache_data->ft_face = NULL; 394 cache_data->ft_face = NULL;
395 cache_data->fc_charset = NULL; 395 cache_data->fc_charset = NULL;
396 val = make_save_value ("pi", cache_data, 0); 396 val = make_save_value (SAVE_TYPE_PTR_INT, cache_data, 0);
397 cache = Fcons (Qnil, val); 397 cache = Fcons (Qnil, val);
398 Fputhash (key, cache, ft_face_cache); 398 Fputhash (key, cache, ft_face_cache);
399 } 399 }
@@ -1211,7 +1211,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
1211 return Qnil; 1211 return Qnil;
1212 } 1212 }
1213 } 1213 }
1214 XSAVE_INTEGER (val, 1)++; 1214 set_save_integer (val, 1, XSAVE_INTEGER (val, 1) + 1);
1215 size = XINT (AREF (entity, FONT_SIZE_INDEX)); 1215 size = XINT (AREF (entity, FONT_SIZE_INDEX));
1216 if (size == 0) 1216 if (size == 0)
1217 size = pixel_size; 1217 size = pixel_size;
@@ -1326,7 +1326,7 @@ ftfont_close (FRAME_PTR f, struct font *font)
1326 cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE); 1326 cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE);
1327 eassert (CONSP (cache)); 1327 eassert (CONSP (cache));
1328 val = XCDR (cache); 1328 val = XCDR (cache);
1329 XSAVE_INTEGER (val, 1)--; 1329 set_save_integer (val, 1, XSAVE_INTEGER (val, 1) - 1);
1330 if (XSAVE_INTEGER (val, 1) == 0) 1330 if (XSAVE_INTEGER (val, 1) == 0)
1331 { 1331 {
1332 struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0); 1332 struct ftfont_cache_data *cache_data = XSAVE_POINTER (val, 0);
diff --git a/src/gfilenotify.c b/src/gfilenotify.c
new file mode 100644
index 00000000000..4ccc430d815
--- /dev/null
+++ b/src/gfilenotify.c
@@ -0,0 +1,266 @@
1/* Filesystem notifications support with glib API.
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_GFILENOTIFY
22#include <stdio.h>
23#include <gio/gio.h>
24#include "lisp.h"
25#include "coding.h"
26#include "frame.h"
27#include "termhooks.h"
28#include "keyboard.h"
29#include "process.h"
30
31
32/* Subroutines. */
33static Lisp_Object Qgfile_add_watch;
34static Lisp_Object Qgfile_rm_watch;
35
36/* Filter objects. */
37static Lisp_Object Qwatch_mounts; /* G_FILE_MONITOR_WATCH_MOUNTS */
38static Lisp_Object Qsend_moved; /* G_FILE_MONITOR_SEND_MOVED */
39
40/* Event types. */
41static Lisp_Object Qchanged; /* G_FILE_MONITOR_EVENT_CHANGED */
42static Lisp_Object Qchanges_done_hint; /* G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT */
43static Lisp_Object Qdeleted; /* G_FILE_MONITOR_EVENT_DELETED */
44static Lisp_Object Qcreated; /* G_FILE_MONITOR_EVENT_CREATED */
45static Lisp_Object Qattribute_changed; /* G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED */
46static Lisp_Object Qpre_unmount; /* G_FILE_MONITOR_EVENT_PRE_UNMOUNT */
47static Lisp_Object Qunmounted; /* G_FILE_MONITOR_EVENT_UNMOUNTED */
48static Lisp_Object Qmoved; /* G_FILE_MONITOR_EVENT_MOVED */
49
50static Lisp_Object watch_list;
51
52/* This is the callback function for arriving signals from
53 g_file_monitor. It shall create a Lisp event, and put it into
54 Emacs input queue. */
55static gboolean
56dir_monitor_callback (GFileMonitor* monitor,
57 GFile* file,
58 GFile* other_file,
59 GFileMonitorEvent event_type,
60 gpointer user_data)
61{
62 Lisp_Object symbol, watch_object;
63 char *name = g_file_get_parse_name (file);
64 char *oname = other_file ? g_file_get_parse_name (other_file) : NULL;
65
66 /* Determine event symbol. */
67 switch (event_type)
68 {
69 case G_FILE_MONITOR_EVENT_CHANGED:
70 symbol = Qchanged;
71 break;
72 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
73 symbol = Qchanges_done_hint;
74 break;
75 case G_FILE_MONITOR_EVENT_DELETED:
76 symbol = Qdeleted;
77 break;
78 case G_FILE_MONITOR_EVENT_CREATED:
79 symbol = Qcreated;
80 break;
81 case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
82 symbol = Qattribute_changed;
83 break;
84 case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
85 symbol = Qpre_unmount;
86 break;
87 case G_FILE_MONITOR_EVENT_UNMOUNTED:
88 symbol = Qunmounted;
89 break;
90 case G_FILE_MONITOR_EVENT_MOVED:
91 symbol = Qmoved;
92 break;
93 default:
94 goto cleanup;
95 }
96
97 /* Determine callback function. */
98 watch_object = Fassoc (XIL ((EMACS_INT) monitor), watch_list);
99
100 if (FUNCTIONP (CDR_SAFE (watch_object)))
101 {
102 /* Construct an event. */
103 struct input_event event;
104 EVENT_INIT (event);
105 event.kind = FILE_NOTIFY_EVENT;
106 event.frame_or_window = Qnil;
107 event.arg = oname
108 ? list2 (list4 (XIL ((EMACS_INT) monitor), symbol,
109 build_string (name), build_string (oname)),
110 CDR_SAFE (watch_object))
111 : list2 (list3 (XIL ((EMACS_INT) monitor), symbol, build_string (name)),
112 CDR_SAFE (watch_object));
113
114 /* Store it into the input event queue. */
115 kbd_buffer_store_event (&event);
116 }
117
118 /* Cleanup. */
119 cleanup:
120 g_free (name);
121 g_free (oname);
122
123 return TRUE;
124}
125
126DEFUN ("gfile-add-watch", Fgfile_add_watch, Sgfile_add_watch, 3, 3, 0,
127 doc: /* Add a watch for filesystem events pertaining to FILE.
128
129This arranges for filesystem events pertaining to FILE to be reported
130to Emacs. Use `gfile-rm-watch' to cancel the watch.
131
132Value is a descriptor for the added watch. If the file cannot be
133watched for some reason, this function signals a `file-error' error.
134
135FLAGS is a list of conditions to set what will be watched for. It can
136include the following symbols:
137
138 'watch-mounts' -- watch for mount events
139 'send-moved' -- pair 'deleted' and 'created' events caused by file
140 renames (moves) and send a single 'event-moved'
141 event instead
142
143When any event happens, Emacs will call the CALLBACK function passing
144it a single argument EVENT, which is of the form
145
146 (DESCRIPTOR ACTION FILE [FILE1])
147
148DESCRIPTOR is the same object as the one returned by this function.
149ACTION is the description of the event. It could be any one of the
150following:
151
152 'changed' -- FILE has changed
153 'changes-done-hint' -- a hint that this was probably the last change
154 in a set of changes
155 'deleted' -- FILE was deleted
156 'created' -- FILE was created
157 'attribute-changed' -- a FILE attribute was changed
158 'pre-unmount' -- the FILE location will soon be unmounted
159 'unmounted' -- the FILE location was unmounted
160 'moved' -- FILE was moved to FILE1
161
162FILE is the name of the file whose event is being reported. FILE1
163will be reported only in case of the 'moved' event. */)
164 (Lisp_Object file, Lisp_Object flags, Lisp_Object callback)
165{
166 Lisp_Object watch_descriptor, watch_object;
167 GFile *gfile;
168 GFileMonitor* monitor;
169 GFileMonitorFlags gflags = G_FILE_MONITOR_NONE;
170
171 /* Check parameters. */
172 CHECK_STRING (file);
173 file = Fdirectory_file_name (Fexpand_file_name (file, Qnil));
174 if (NILP (Ffile_exists_p (file)))
175 report_file_error ("File does not exists", Fcons (file, Qnil));
176
177 CHECK_LIST (flags);
178
179 if (!FUNCTIONP (callback))
180 wrong_type_argument (Qinvalid_function, callback);
181
182 /* Create GFile name. */
183 gfile = g_file_new_for_path (SSDATA (ENCODE_FILE (file)));
184
185 /* Assemble flags. */
186 if (!NILP (Fmember (Qwatch_mounts, flags)))
187 gflags |= G_FILE_MONITOR_WATCH_MOUNTS;
188 if (!NILP (Fmember (Qsend_moved, flags)))
189 gflags |= G_FILE_MONITOR_SEND_MOVED;
190
191 /* Enable watch. */
192 monitor = g_file_monitor (gfile, gflags, NULL, NULL);
193 if (monitor != NULL)
194 g_signal_connect (monitor, "changed",
195 (GCallback) dir_monitor_callback, NULL);
196 else
197 report_file_error ("Cannot watch file", Fcons (file, Qnil));
198
199 /* Store watch object in watch list. */
200 watch_descriptor = XIL ((EMACS_INT) monitor);
201 watch_object = Fcons (watch_descriptor, callback);
202 watch_list = Fcons (watch_object, watch_list);
203
204 return watch_descriptor;
205}
206
207DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
208 doc: /* Remove an existing WATCH-DESCRIPTOR.
209
210WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */)
211 (Lisp_Object watch_descriptor)
212{
213 Lisp_Object watch_object;
214 GFileMonitor *monitor = (GFileMonitor *) XLI (watch_descriptor);
215
216 watch_object = Fassoc (watch_descriptor, watch_list);
217 if (NILP (watch_object))
218 report_file_error ("Not a watch descriptor",
219 Fcons (watch_descriptor, Qnil));
220
221 if (!g_file_monitor_cancel (monitor))
222 report_file_error ("Could not rm watch",
223 Fcons (watch_descriptor, Qnil));
224
225 /* Remove watch descriptor from watch list. */
226 watch_list = Fdelete (watch_object, watch_list);
227
228 /* Cleanup. */
229 g_object_unref (monitor);
230
231 return Qt;
232}
233
234
235void
236syms_of_gfilenotify (void)
237{
238
239 g_type_init ();
240
241 DEFSYM (Qgfile_add_watch, "gfile-add-watch");
242 defsubr (&Sgfile_add_watch);
243
244 DEFSYM (Qgfile_rm_watch, "gfile-rm-watch");
245 defsubr (&Sgfile_rm_watch);
246
247 DEFSYM (Qwatch_mounts, "watch-mounts");
248 DEFSYM (Qsend_moved, "send-moved");
249 DEFSYM (Qchanged, "changed");
250 DEFSYM (Qchanges_done_hint, "changes-done-hint");
251 DEFSYM (Qdeleted, "deleted");
252 DEFSYM (Qcreated, "created");
253 DEFSYM (Qattribute_changed, "attribute-changed");
254 DEFSYM (Qpre_unmount, "pre-unmount");
255 DEFSYM (Qunmounted, "unmounted");
256 DEFSYM (Qmoved, "moved");
257
258 /* Initialize internal objects. */
259 watch_list = Qnil;
260 staticpro (&watch_list);
261
262 Fprovide (intern_c_string ("gfilenotify"), Qnil);
263
264}
265
266#endif /* HAVE_GFILENOTIFY */
diff --git a/src/gtkutil.c b/src/gtkutil.c
index d6e4dcebcd3..8ac58f18158 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -70,13 +70,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
70#define gtk_adjustment_get_step_increment(w) ((w)->step_increment) 70#define gtk_adjustment_get_step_increment(w) ((w)->step_increment)
71#define gtk_adjustment_set_step_increment(w, s) ((w)->step_increment = (s)) 71#define gtk_adjustment_set_step_increment(w, s) ((w)->step_increment = (s))
72#endif 72#endif
73#if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 11 73#if GTK_CHECK_VERSION (2, 12, 0)
74#define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL) 74#define remove_submenu(w) gtk_menu_item_set_submenu ((w), NULL)
75#else 75#else
76#define remove_submenu(w) gtk_menu_item_remove_submenu ((w)) 76#define remove_submenu(w) gtk_menu_item_remove_submenu ((w))
77#endif 77#endif
78 78
79#if GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 2) 79#if GTK_CHECK_VERSION (3, 2, 0)
80#define USE_NEW_GTK_FONT_CHOOSER 1 80#define USE_NEW_GTK_FONT_CHOOSER 1
81#else 81#else
82#define USE_NEW_GTK_FONT_CHOOSER 0 82#define USE_NEW_GTK_FONT_CHOOSER 0
@@ -202,7 +202,7 @@ xg_display_close (Display *dpy)
202 gdpy_def = gdpy_new; 202 gdpy_def = gdpy_new;
203 } 203 }
204 204
205#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 10 205#if GTK_CHECK_VERSION (2, 0, 0) && ! GTK_CHECK_VERSION (2, 10, 0)
206 /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug 206 /* GTK 2.2-2.8 has a bug that makes gdk_display_close crash (bug
207 http://bugzilla.gnome.org/show_bug.cgi?id=85715). This way we 207 http://bugzilla.gnome.org/show_bug.cgi?id=85715). This way we
208 can continue running, but there will be memory leaks. */ 208 can continue running, but there will be memory leaks. */
@@ -1094,7 +1094,9 @@ style_changed_cb (GObject *go,
1094 FOR_EACH_FRAME (rest, frame) 1094 FOR_EACH_FRAME (rest, frame)
1095 { 1095 {
1096 FRAME_PTR f = XFRAME (frame); 1096 FRAME_PTR f = XFRAME (frame);
1097 if (FRAME_X_DISPLAY (f) == dpy) 1097 if (FRAME_LIVE_P (f)
1098 && FRAME_X_P (f)
1099 && FRAME_X_DISPLAY (f) == dpy)
1098 { 1100 {
1099 x_set_scroll_bar_default_width (f); 1101 x_set_scroll_bar_default_width (f);
1100 xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f)); 1102 xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
@@ -1153,7 +1155,8 @@ xg_create_frame_widgets (FRAME_PTR f)
1153 has backported it to Gtk+ 2.0 and they add the resize grip for 1155 has backported it to Gtk+ 2.0 and they add the resize grip for
1154 Gtk+ 2.0 applications also. But it has a bug that makes Emacs loop 1156 Gtk+ 2.0 applications also. But it has a bug that makes Emacs loop
1155 forever, so disable the grip. */ 1157 forever, so disable the grip. */
1156#if GTK_MAJOR_VERSION < 3 && defined (HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP) 1158#if (! GTK_CHECK_VERSION (3, 0, 0) \
1159 && defined HAVE_GTK_WINDOW_SET_HAS_RESIZE_GRIP)
1157 gtk_window_set_has_resize_grip (GTK_WINDOW (wtop), FALSE); 1160 gtk_window_set_has_resize_grip (GTK_WINDOW (wtop), FALSE);
1158#endif 1161#endif
1159 1162
diff --git a/src/image.c b/src/image.c
index 2d4e7e731ad..f9f6ce70040 100644
--- a/src/image.c
+++ b/src/image.c
@@ -68,8 +68,6 @@ typedef struct x_bitmap_record Bitmap_Record;
68#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) 68#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
69#define NO_PIXMAP None 69#define NO_PIXMAP None
70 70
71#define RGB_PIXEL_COLOR unsigned long
72
73#define PIX_MASK_RETAIN 0 71#define PIX_MASK_RETAIN 0
74#define PIX_MASK_DRAW 1 72#define PIX_MASK_DRAW 1
75#endif /* HAVE_X_WINDOWS */ 73#endif /* HAVE_X_WINDOWS */
@@ -88,8 +86,6 @@ typedef struct w32_bitmap_record Bitmap_Record;
88#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y) 86#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
89#define NO_PIXMAP 0 87#define NO_PIXMAP 0
90 88
91#define RGB_PIXEL_COLOR COLORREF
92
93#define PIX_MASK_RETAIN 0 89#define PIX_MASK_RETAIN 0
94#define PIX_MASK_DRAW 1 90#define PIX_MASK_DRAW 1
95 91
@@ -110,7 +106,6 @@ typedef struct ns_bitmap_record Bitmap_Record;
110#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) 106#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
111#define NO_PIXMAP 0 107#define NO_PIXMAP 0
112 108
113#define RGB_PIXEL_COLOR unsigned long
114#define ZPixmap 0 109#define ZPixmap 0
115 110
116#define PIX_MASK_RETAIN 0 111#define PIX_MASK_RETAIN 0
@@ -159,15 +154,15 @@ XGetImage (Display *display, Pixmap pixmap, int x, int y,
159 return pixmap; 154 return pixmap;
160} 155}
161 156
162/* use with imgs created by ns_image_for_XPM */ 157/* Use with images created by ns_image_for_XPM. */
163unsigned long 158unsigned long
164XGetPixel (XImagePtr ximage, int x, int y) 159XGetPixel (XImagePtr ximage, int x, int y)
165{ 160{
166 return ns_get_pixel (ximage, x, y); 161 return ns_get_pixel (ximage, x, y);
167} 162}
168 163
169/* use with imgs created by ns_image_for_XPM; alpha set to 1; 164/* Use with images created by ns_image_for_XPM; alpha set to 1;
170 pixel is assumed to be in form RGB */ 165 pixel is assumed to be in RGB form. */
171void 166void
172XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel) 167XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
173{ 168{
@@ -894,7 +889,7 @@ or omitted means use the selected frame. */)
894 size = Qnil; 889 size = Qnil;
895 if (valid_image_p (spec)) 890 if (valid_image_p (spec))
896 { 891 {
897 struct frame *f = check_x_frame (frame); 892 struct frame *f = decode_window_system_frame (frame);
898 ptrdiff_t id = lookup_image (f, spec); 893 ptrdiff_t id = lookup_image (f, spec);
899 struct image *img = IMAGE_FROM_ID (f, id); 894 struct image *img = IMAGE_FROM_ID (f, id);
900 int width = img->width + 2 * img->hmargin; 895 int width = img->width + 2 * img->hmargin;
@@ -924,7 +919,7 @@ or omitted means use the selected frame. */)
924 mask = Qnil; 919 mask = Qnil;
925 if (valid_image_p (spec)) 920 if (valid_image_p (spec))
926 { 921 {
927 struct frame *f = check_x_frame (frame); 922 struct frame *f = decode_window_system_frame (frame);
928 ptrdiff_t id = lookup_image (f, spec); 923 ptrdiff_t id = lookup_image (f, spec);
929 struct image *img = IMAGE_FROM_ID (f, id); 924 struct image *img = IMAGE_FROM_ID (f, id);
930 if (img->mask) 925 if (img->mask)
@@ -947,7 +942,7 @@ or omitted means use the selected frame. */)
947 ext = Qnil; 942 ext = Qnil;
948 if (valid_image_p (spec)) 943 if (valid_image_p (spec))
949 { 944 {
950 struct frame *f = check_x_frame (frame); 945 struct frame *f = decode_window_system_frame (frame);
951 ptrdiff_t id = lookup_image (f, spec); 946 ptrdiff_t id = lookup_image (f, spec);
952 struct image *img = IMAGE_FROM_ID (f, id); 947 struct image *img = IMAGE_FROM_ID (f, id);
953 ext = img->lisp_data; 948 ext = img->lisp_data;
@@ -1555,7 +1550,7 @@ which is then usually a filename. */)
1555 if (!(EQ (filter, Qnil) || FRAMEP (filter))) 1550 if (!(EQ (filter, Qnil) || FRAMEP (filter)))
1556 clear_image_caches (filter); 1551 clear_image_caches (filter);
1557 else 1552 else
1558 clear_image_cache (check_x_frame (filter), Qt); 1553 clear_image_cache (decode_window_system_frame (filter), Qt);
1559 1554
1560 return Qnil; 1555 return Qnil;
1561} 1556}
@@ -1586,7 +1581,7 @@ FRAME t means refresh the image on all frames. */)
1586 } 1581 }
1587 } 1582 }
1588 else 1583 else
1589 uncache_image (check_x_frame (frame), spec); 1584 uncache_image (decode_window_system_frame (frame), spec);
1590 1585
1591 return Qnil; 1586 return Qnil;
1592} 1587}
@@ -7268,6 +7263,25 @@ gif_load (struct frame *f, struct image *img)
7268 return 0; 7263 return 0;
7269 } 7264 }
7270 7265
7266 /* Check that the selected subimages fit. It's not clear whether
7267 the GIF spec requires this, but Emacs can crash if they don't fit. */
7268 for (j = 0; j <= idx; ++j)
7269 {
7270 struct SavedImage *subimage = gif->SavedImages + j;
7271 int subimg_width = subimage->ImageDesc.Width;
7272 int subimg_height = subimage->ImageDesc.Height;
7273 int subimg_top = subimage->ImageDesc.Top;
7274 int subimg_left = subimage->ImageDesc.Left;
7275 if (! (0 <= subimg_width && 0 <= subimg_height
7276 && 0 <= subimg_top && subimg_top <= height - subimg_height
7277 && 0 <= subimg_left && subimg_left <= width - subimg_width))
7278 {
7279 image_error ("Subimage does not fit in image", Qnil, Qnil);
7280 fn_DGifCloseFile (gif);
7281 return 0;
7282 }
7283 }
7284
7271 /* Create the X image and pixmap. */ 7285 /* Create the X image and pixmap. */
7272 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 7286 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7273 { 7287 {
@@ -7378,11 +7392,10 @@ gif_load (struct frame *f, struct image *img)
7378 y < subimg_height; 7392 y < subimg_height;
7379 y++, row += interlace_increment[pass]) 7393 y++, row += interlace_increment[pass])
7380 { 7394 {
7381 if (row >= subimg_height) 7395 while (subimg_height <= row)
7382 { 7396 {
7397 lint_assume (pass < 3);
7383 row = interlace_start[++pass]; 7398 row = interlace_start[++pass];
7384 while (row >= subimg_height)
7385 row = interlace_start[++pass];
7386 } 7399 }
7387 7400
7388 for (x = 0; x < subimg_width; x++) 7401 for (x = 0; x < subimg_width; x++)
@@ -8126,24 +8139,25 @@ svg_image_p (Lisp_Object object)
8126#ifdef WINDOWSNT 8139#ifdef WINDOWSNT
8127 8140
8128/* SVG library functions. */ 8141/* SVG library functions. */
8129DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new); 8142DEF_IMGLIB_FN (RsvgHandle *, rsvg_handle_new, (void));
8130DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions); 8143DEF_IMGLIB_FN (void, rsvg_handle_get_dimensions, (RsvgHandle *, RsvgDimensionData *));
8131DEF_IMGLIB_FN (gboolean, rsvg_handle_write); 8144DEF_IMGLIB_FN (gboolean, rsvg_handle_write, (RsvgHandle *, const guchar *, gsize, GError **));
8132DEF_IMGLIB_FN (gboolean, rsvg_handle_close); 8145DEF_IMGLIB_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
8133DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf); 8146DEF_IMGLIB_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
8134 8147DEF_IMGLIB_FN (void *, rsvg_handle_set_size_callback, (RsvgHandle *, RsvgSizeFunc, gpointer, GDestroyNotify));
8135DEF_IMGLIB_FN (int, gdk_pixbuf_get_width); 8148
8136DEF_IMGLIB_FN (int, gdk_pixbuf_get_height); 8149DEF_IMGLIB_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
8137DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels); 8150DEF_IMGLIB_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
8138DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride); 8151DEF_IMGLIB_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
8139DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace); 8152DEF_IMGLIB_FN (int, gdk_pixbuf_get_rowstride, (const GdkPixbuf *));
8140DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels); 8153DEF_IMGLIB_FN (GdkColorspace, gdk_pixbuf_get_colorspace, (const GdkPixbuf *));
8141DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha); 8154DEF_IMGLIB_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *));
8142DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample); 8155DEF_IMGLIB_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *));
8143 8156DEF_IMGLIB_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
8144DEF_IMGLIB_FN (void, g_type_init); 8157
8145DEF_IMGLIB_FN (void, g_object_unref); 8158DEF_IMGLIB_FN (void, g_type_init, (void));
8146DEF_IMGLIB_FN (void, g_error_free); 8159DEF_IMGLIB_FN (void, g_object_unref, (gpointer));
8160DEF_IMGLIB_FN (void, g_error_free, (GError *));
8147 8161
8148Lisp_Object Qgdk_pixbuf, Qglib, Qgobject; 8162Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
8149 8163
@@ -8559,10 +8573,10 @@ gs_load (struct frame *f, struct image *img)
8559 info. */ 8573 info. */
8560 pt_width = image_spec_value (img->spec, QCpt_width, NULL); 8574 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
8561 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0; 8575 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
8562 in_width *= FRAME_X_DISPLAY_INFO (f)->resx; 8576 in_width *= FRAME_RES_X (f);
8563 pt_height = image_spec_value (img->spec, QCpt_height, NULL); 8577 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
8564 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0; 8578 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
8565 in_height *= FRAME_X_DISPLAY_INFO (f)->resy; 8579 in_height *= FRAME_RES_Y (f);
8566 8580
8567 if (! (in_width <= INT_MAX && in_height <= INT_MAX 8581 if (! (in_width <= INT_MAX && in_height <= INT_MAX
8568 && check_image_size (f, in_width, in_height))) 8582 && check_image_size (f, in_width, in_height)))
diff --git a/src/indent.c b/src/indent.c
index d1f95da6bcf..47358e17db8 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -56,11 +56,6 @@ static EMACS_INT last_known_column_modified;
56static ptrdiff_t current_column_1 (void); 56static ptrdiff_t current_column_1 (void);
57static ptrdiff_t position_indentation (ptrdiff_t); 57static ptrdiff_t position_indentation (ptrdiff_t);
58 58
59/* Cache of beginning of line found by the last call of
60 current_column. */
61
62static ptrdiff_t current_column_bol_cache;
63
64/* Get the display table to use for the current buffer. */ 59/* Get the display table to use for the current buffer. */
65 60
66struct Lisp_Char_Table * 61struct Lisp_Char_Table *
@@ -254,7 +249,7 @@ skip_invisible (ptrdiff_t pos, ptrdiff_t *next_boundary_p, ptrdiff_t to, Lisp_Ob
254 the next property change */ 249 the next property change */
255 prop = Fget_char_property (position, Qinvisible, 250 prop = Fget_char_property (position, Qinvisible,
256 (!NILP (window) 251 (!NILP (window)
257 && EQ (XWINDOW (window)->buffer, buffer)) 252 && EQ (XWINDOW (window)->contents, buffer))
258 ? window : buffer); 253 ? window : buffer);
259 inv_p = TEXT_PROP_MEANS_INVISIBLE (prop); 254 inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
260 /* When counting columns (window == nil), don't skip over ellipsis text. */ 255 /* When counting columns (window == nil), don't skip over ellipsis text. */
@@ -439,11 +434,6 @@ current_column (void)
439 col += post_tab; 434 col += post_tab;
440 } 435 }
441 436
442 if (ptr == BEGV_ADDR)
443 current_column_bol_cache = BEGV;
444 else
445 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
446
447 last_known_column = col; 437 last_known_column = col;
448 last_known_column_point = PT; 438 last_known_column_point = PT;
449 last_known_column_modified = MODIFF; 439 last_known_column_modified = MODIFF;
@@ -525,7 +515,6 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol)
525 { 515 {
526 ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; 516 ptrdiff_t opoint = PT, opoint_byte = PT_BYTE;
527 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); 517 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
528 current_column_bol_cache = PT;
529 scan = PT, scan_byte = PT_BYTE; 518 scan = PT, scan_byte = PT_BYTE;
530 SET_PT_BOTH (opoint, opoint_byte); 519 SET_PT_BOTH (opoint, opoint_byte);
531 next_boundary = scan; 520 next_boundary = scan;
@@ -1088,8 +1077,8 @@ static struct position val_compute_motion;
1088 : (window_width + window_left != frame_cols)) 1077 : (window_width + window_left != frame_cols))
1089 1078
1090 where 1079 where
1091 window_width is XFASTINT (w->total_cols), 1080 window_width is w->total_cols,
1092 window_left is XFASTINT (w->left_col), 1081 window_left is w->left_col,
1093 has_vertical_scroll_bars is 1082 has_vertical_scroll_bars is
1094 WINDOW_HAS_VERTICAL_SCROLL_BAR (window) 1083 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1095 and frame_cols = FRAME_COLS (XFRAME (window->frame)) 1084 and frame_cols = FRAME_COLS (XFRAME (window->frame))
@@ -1826,7 +1815,7 @@ vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
1826 1815
1827 /* If the window contains this buffer, use it for getting text properties. 1816 /* If the window contains this buffer, use it for getting text properties.
1828 Otherwise use the current buffer as arg for doing that. */ 1817 Otherwise use the current buffer as arg for doing that. */
1829 if (EQ (w->buffer, Fcurrent_buffer ())) 1818 if (EQ (w->contents, Fcurrent_buffer ()))
1830 text_prop_object = window; 1819 text_prop_object = window;
1831 else 1820 else
1832 text_prop_object = Fcurrent_buffer (); 1821 text_prop_object = Fcurrent_buffer ();
@@ -1979,14 +1968,14 @@ whether or not it is currently displayed in some window. */)
1979 1968
1980 old_buffer = Qnil; 1969 old_buffer = Qnil;
1981 GCPRO1 (old_buffer); 1970 GCPRO1 (old_buffer);
1982 if (XBUFFER (w->buffer) != current_buffer) 1971 if (XBUFFER (w->contents) != current_buffer)
1983 { 1972 {
1984 /* Set the window's buffer temporarily to the current buffer. */ 1973 /* Set the window's buffer temporarily to the current buffer. */
1985 old_buffer = w->buffer; 1974 old_buffer = w->contents;
1986 old_charpos = marker_position (w->pointm); 1975 old_charpos = marker_position (w->pointm);
1987 old_bytepos = marker_byte_position (w->pointm); 1976 old_bytepos = marker_byte_position (w->pointm);
1988 wset_buffer (w, Fcurrent_buffer ()); 1977 wset_buffer (w, Fcurrent_buffer ());
1989 set_marker_both (w->pointm, w->buffer, 1978 set_marker_both (w->pointm, w->contents,
1990 BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer)); 1979 BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
1991 } 1980 }
1992 1981
@@ -2017,11 +2006,15 @@ whether or not it is currently displayed in some window. */)
2017 const char *s = SSDATA (it.string); 2006 const char *s = SSDATA (it.string);
2018 const char *e = s + SBYTES (it.string); 2007 const char *e = s + SBYTES (it.string);
2019 2008
2009 disp_string_at_start_p =
2020 /* If it.area is anything but TEXT_AREA, we need not bother 2010 /* If it.area is anything but TEXT_AREA, we need not bother
2021 about the display string, as it doesn't affect cursor 2011 about the display string, as it doesn't affect cursor
2022 positioning. */ 2012 positioning. */
2023 disp_string_at_start_p = 2013 it.area == TEXT_AREA
2024 it.string_from_display_prop_p && it.area == TEXT_AREA; 2014 && it.string_from_display_prop_p
2015 /* A display string on anything but buffer text (e.g., on
2016 an overlay string) doesn't affect cursor positioning. */
2017 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER);
2025 while (s < e) 2018 while (s < e)
2026 { 2019 {
2027 if (*s++ == '\n') 2020 if (*s++ == '\n')
@@ -2139,7 +2132,7 @@ whether or not it is currently displayed in some window. */)
2139 if (BUFFERP (old_buffer)) 2132 if (BUFFERP (old_buffer))
2140 { 2133 {
2141 wset_buffer (w, old_buffer); 2134 wset_buffer (w, old_buffer);
2142 set_marker_both (w->pointm, w->buffer, 2135 set_marker_both (w->pointm, w->contents,
2143 old_charpos, old_bytepos); 2136 old_charpos, old_bytepos);
2144 } 2137 }
2145 2138
diff --git a/src/insdel.c b/src/insdel.c
index a60fed0c32e..ed684264249 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -771,8 +771,13 @@ count_combining_after (const unsigned char *string,
771 771
772 772
773/* Insert a sequence of NCHARS chars which occupy NBYTES bytes 773/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
774 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS 774 starting at STRING. INHERIT non-zero means inherit the text
775 are the same as in insert_1. */ 775 properties from neighboring characters; zero means inserted text
776 will have no text properties. PREPARE non-zero means call
777 prepare_to_modify_buffer, which checks that the region is not
778 read-only, and calls before-change-function and any modification
779 properties the text may have. BEFORE_MARKERS non-zero means adjust
780 all markers that point at the insertion place to point after it. */
776 781
777void 782void
778insert_1_both (const char *string, 783insert_1_both (const char *string,
@@ -983,6 +988,9 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
983void 988void
984insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail) 989insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
985{ 990{
991 int ins_charpos = GPT;
992 int ins_bytepos = GPT_BYTE;
993
986 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) 994 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
987 nchars = nbytes; 995 nchars = nbytes;
988 996
@@ -1003,18 +1011,18 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
1003 1011
1004 eassert (GPT <= GPT_BYTE); 1012 eassert (GPT <= GPT_BYTE);
1005 1013
1006 adjust_overlays_for_insert (GPT - nchars, nchars); 1014 adjust_overlays_for_insert (ins_charpos, nchars);
1007 adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes, 1015 adjust_markers_for_insert (ins_charpos, ins_bytepos,
1008 GPT, GPT_BYTE, 0); 1016 ins_charpos + nchars, ins_bytepos + nbytes, 0);
1009 1017
1010 if (buffer_intervals (current_buffer)) 1018 if (buffer_intervals (current_buffer))
1011 { 1019 {
1012 offset_intervals (current_buffer, GPT - nchars, nchars); 1020 offset_intervals (current_buffer, ins_charpos, nchars);
1013 graft_intervals_into_buffer (NULL, GPT - nchars, nchars, 1021 graft_intervals_into_buffer (NULL, ins_charpos, nchars,
1014 current_buffer, 0); 1022 current_buffer, 0);
1015 } 1023 }
1016 1024
1017 if (! text_at_gap_tail && GPT - nchars < PT) 1025 if (ins_charpos < PT)
1018 adjust_point (nchars, nbytes); 1026 adjust_point (nchars, nbytes);
1019 1027
1020 check_markers (); 1028 check_markers ();
@@ -1798,7 +1806,7 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1798 1806
1799 /* If we're modifying the buffer other than shown in a selected window, 1807 /* If we're modifying the buffer other than shown in a selected window,
1800 let redisplay consider other windows if this buffer is visible. */ 1808 let redisplay consider other windows if this buffer is visible. */
1801 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer 1809 if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer
1802 && buffer_window_count (current_buffer)) 1810 && buffer_window_count (current_buffer))
1803 ++windows_or_buffers_changed; 1811 ++windows_or_buffers_changed;
1804 1812
diff --git a/src/intervals.c b/src/intervals.c
index db38c86c00b..f65ce0ecc77 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -110,14 +110,14 @@ create_root_interval (Lisp_Object parent)
110 { 110 {
111 new->total_length = (BUF_Z (XBUFFER (parent)) 111 new->total_length = (BUF_Z (XBUFFER (parent))
112 - BUF_BEG (XBUFFER (parent))); 112 - BUF_BEG (XBUFFER (parent)));
113 eassert (0 <= TOTAL_LENGTH (new)); 113 eassert (TOTAL_LENGTH (new) >= 0);
114 set_buffer_intervals (XBUFFER (parent), new); 114 set_buffer_intervals (XBUFFER (parent), new);
115 new->position = BEG; 115 new->position = BEG;
116 } 116 }
117 else if (STRINGP (parent)) 117 else if (STRINGP (parent))
118 { 118 {
119 new->total_length = SCHARS (parent); 119 new->total_length = SCHARS (parent);
120 eassert (0 <= TOTAL_LENGTH (new)); 120 eassert (TOTAL_LENGTH (new) >= 0);
121 set_string_intervals (parent, new); 121 set_string_intervals (parent, new);
122 new->position = 0; 122 new->position = 0;
123 } 123 }
@@ -371,11 +371,11 @@ rotate_right (INTERVAL interval)
371 371
372 /* A's total length is decreased by the length of B and its left child. */ 372 /* A's total length is decreased by the length of B and its left child. */
373 interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval); 373 interval->total_length -= B->total_length - LEFT_TOTAL_LENGTH (interval);
374 eassert (0 <= TOTAL_LENGTH (interval)); 374 eassert (TOTAL_LENGTH (interval) >= 0);
375 375
376 /* B must have the same total length of A. */ 376 /* B must have the same total length of A. */
377 B->total_length = old_total; 377 B->total_length = old_total;
378 eassert (0 <= TOTAL_LENGTH (B)); 378 eassert (TOTAL_LENGTH (B) >= 0);
379 379
380 return B; 380 return B;
381} 381}
@@ -418,11 +418,11 @@ rotate_left (INTERVAL interval)
418 418
419 /* A's total length is decreased by the length of B and its right child. */ 419 /* A's total length is decreased by the length of B and its right child. */
420 interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval); 420 interval->total_length -= B->total_length - RIGHT_TOTAL_LENGTH (interval);
421 eassert (0 <= TOTAL_LENGTH (interval)); 421 eassert (TOTAL_LENGTH (interval) >= 0);
422 422
423 /* B must have the same total length of A. */ 423 /* B must have the same total length of A. */
424 B->total_length = old_total; 424 B->total_length = old_total;
425 eassert (0 <= TOTAL_LENGTH (B)); 425 eassert (TOTAL_LENGTH (B) >= 0);
426 426
427 return B; 427 return B;
428} 428}
@@ -556,7 +556,7 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
556 { 556 {
557 set_interval_right (interval, new); 557 set_interval_right (interval, new);
558 new->total_length = new_length; 558 new->total_length = new_length;
559 eassert (0 <= TOTAL_LENGTH (new)); 559 eassert (TOTAL_LENGTH (new) >= 0);
560 } 560 }
561 else 561 else
562 { 562 {
@@ -565,7 +565,7 @@ split_interval_right (INTERVAL interval, ptrdiff_t offset)
565 set_interval_parent (interval->right, new); 565 set_interval_parent (interval->right, new);
566 set_interval_right (interval, new); 566 set_interval_right (interval, new);
567 new->total_length = new_length + new->right->total_length; 567 new->total_length = new_length + new->right->total_length;
568 eassert (0 <= TOTAL_LENGTH (new)); 568 eassert (TOTAL_LENGTH (new) >= 0);
569 balance_an_interval (new); 569 balance_an_interval (new);
570 } 570 }
571 571
@@ -601,7 +601,7 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
601 { 601 {
602 set_interval_left (interval, new); 602 set_interval_left (interval, new);
603 new->total_length = new_length; 603 new->total_length = new_length;
604 eassert (0 <= TOTAL_LENGTH (new)); 604 eassert (TOTAL_LENGTH (new) >= 0);
605 } 605 }
606 else 606 else
607 { 607 {
@@ -610,7 +610,7 @@ split_interval_left (INTERVAL interval, ptrdiff_t offset)
610 set_interval_parent (new->left, new); 610 set_interval_parent (new->left, new);
611 set_interval_left (interval, new); 611 set_interval_left (interval, new);
612 new->total_length = new_length + new->left->total_length; 612 new->total_length = new_length + new->left->total_length;
613 eassert (0 <= TOTAL_LENGTH (new)); 613 eassert (TOTAL_LENGTH (new) >= 0);
614 balance_an_interval (new); 614 balance_an_interval (new);
615 } 615 }
616 616
@@ -960,7 +960,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
960 for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) 960 for (temp = prev ? prev : i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
961 { 961 {
962 temp->total_length += length; 962 temp->total_length += length;
963 eassert (0 <= TOTAL_LENGTH (temp)); 963 eassert (TOTAL_LENGTH (temp) >= 0);
964 temp = balance_possible_root_interval (temp); 964 temp = balance_possible_root_interval (temp);
965 } 965 }
966 966
@@ -1016,7 +1016,7 @@ adjust_intervals_for_insertion (INTERVAL tree,
1016 for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp)) 1016 for (temp = i; temp; temp = INTERVAL_PARENT_OR_NULL (temp))
1017 { 1017 {
1018 temp->total_length += length; 1018 temp->total_length += length;
1019 eassert (0 <= TOTAL_LENGTH (temp)); 1019 eassert (TOTAL_LENGTH (temp) >= 0);
1020 temp = balance_possible_root_interval (temp); 1020 temp = balance_possible_root_interval (temp);
1021 } 1021 }
1022 } 1022 }
@@ -1218,7 +1218,7 @@ delete_node (register INTERVAL i)
1218 this = this->left; 1218 this = this->left;
1219 this->total_length += migrate_amt; 1219 this->total_length += migrate_amt;
1220 } 1220 }
1221 eassert (0 <= TOTAL_LENGTH (this)); 1221 eassert (TOTAL_LENGTH (this) >= 0);
1222 set_interval_left (this, migrate); 1222 set_interval_left (this, migrate);
1223 set_interval_parent (migrate, this); 1223 set_interval_parent (migrate, this);
1224 1224
@@ -1300,7 +1300,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
1300 relative_position, 1300 relative_position,
1301 amount); 1301 amount);
1302 tree->total_length -= subtract; 1302 tree->total_length -= subtract;
1303 eassert (0 <= TOTAL_LENGTH (tree)); 1303 eassert (TOTAL_LENGTH (tree) >= 0);
1304 return subtract; 1304 return subtract;
1305 } 1305 }
1306 /* Right branch. */ 1306 /* Right branch. */
@@ -1315,7 +1315,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
1315 relative_position, 1315 relative_position,
1316 amount); 1316 amount);
1317 tree->total_length -= subtract; 1317 tree->total_length -= subtract;
1318 eassert (0 <= TOTAL_LENGTH (tree)); 1318 eassert (TOTAL_LENGTH (tree) >= 0);
1319 return subtract; 1319 return subtract;
1320 } 1320 }
1321 /* Here -- this node. */ 1321 /* Here -- this node. */
@@ -1330,7 +1330,7 @@ interval_deletion_adjustment (register INTERVAL tree, register ptrdiff_t from,
1330 amount = my_amount; 1330 amount = my_amount;
1331 1331
1332 tree->total_length -= amount; 1332 tree->total_length -= amount;
1333 eassert (0 <= TOTAL_LENGTH (tree)); 1333 eassert (TOTAL_LENGTH (tree) >= 0);
1334 if (LENGTH (tree) == 0) 1334 if (LENGTH (tree) == 0)
1335 delete_interval (tree); 1335 delete_interval (tree);
1336 1336
@@ -1372,7 +1372,7 @@ adjust_intervals_for_deletion (struct buffer *buffer,
1372 if (ONLY_INTERVAL_P (tree)) 1372 if (ONLY_INTERVAL_P (tree))
1373 { 1373 {
1374 tree->total_length -= length; 1374 tree->total_length -= length;
1375 eassert (0 <= TOTAL_LENGTH (tree)); 1375 eassert (TOTAL_LENGTH (tree) >= 0);
1376 return; 1376 return;
1377 } 1377 }
1378 1378
@@ -1435,19 +1435,19 @@ merge_interval_right (register INTERVAL i)
1435 while (! NULL_LEFT_CHILD (successor)) 1435 while (! NULL_LEFT_CHILD (successor))
1436 { 1436 {
1437 successor->total_length += absorb; 1437 successor->total_length += absorb;
1438 eassert (0 <= TOTAL_LENGTH (successor)); 1438 eassert (TOTAL_LENGTH (successor) >= 0);
1439 successor = successor->left; 1439 successor = successor->left;
1440 } 1440 }
1441 1441
1442 successor->total_length += absorb; 1442 successor->total_length += absorb;
1443 eassert (0 <= TOTAL_LENGTH (successor)); 1443 eassert (TOTAL_LENGTH (successor) >= 0);
1444 delete_interval (i); 1444 delete_interval (i);
1445 return successor; 1445 return successor;
1446 } 1446 }
1447 1447
1448 /* Zero out this interval. */ 1448 /* Zero out this interval. */
1449 i->total_length -= absorb; 1449 i->total_length -= absorb;
1450 eassert (0 <= TOTAL_LENGTH (i)); 1450 eassert (TOTAL_LENGTH (i) >= 0);
1451 1451
1452 successor = i; 1452 successor = i;
1453 while (! NULL_PARENT (successor)) /* It's above us. Subtract as 1453 while (! NULL_PARENT (successor)) /* It's above us. Subtract as
@@ -1462,7 +1462,7 @@ merge_interval_right (register INTERVAL i)
1462 1462
1463 successor = INTERVAL_PARENT (successor); 1463 successor = INTERVAL_PARENT (successor);
1464 successor->total_length -= absorb; 1464 successor->total_length -= absorb;
1465 eassert (0 <= TOTAL_LENGTH (successor)); 1465 eassert (TOTAL_LENGTH (successor) >= 0);
1466 } 1466 }
1467 1467
1468 /* This must be the rightmost or last interval and cannot 1468 /* This must be the rightmost or last interval and cannot
@@ -1491,19 +1491,19 @@ merge_interval_left (register INTERVAL i)
1491 while (! NULL_RIGHT_CHILD (predecessor)) 1491 while (! NULL_RIGHT_CHILD (predecessor))
1492 { 1492 {
1493 predecessor->total_length += absorb; 1493 predecessor->total_length += absorb;
1494 eassert (0 <= TOTAL_LENGTH (predecessor)); 1494 eassert (TOTAL_LENGTH (predecessor) >= 0);
1495 predecessor = predecessor->right; 1495 predecessor = predecessor->right;
1496 } 1496 }
1497 1497
1498 predecessor->total_length += absorb; 1498 predecessor->total_length += absorb;
1499 eassert (0 <= TOTAL_LENGTH (predecessor)); 1499 eassert (TOTAL_LENGTH (predecessor) >= 0);
1500 delete_interval (i); 1500 delete_interval (i);
1501 return predecessor; 1501 return predecessor;
1502 } 1502 }
1503 1503
1504 /* Zero out this interval. */ 1504 /* Zero out this interval. */
1505 i->total_length -= absorb; 1505 i->total_length -= absorb;
1506 eassert (0 <= TOTAL_LENGTH (i)); 1506 eassert (TOTAL_LENGTH (i) >= 0);
1507 1507
1508 predecessor = i; 1508 predecessor = i;
1509 while (! NULL_PARENT (predecessor)) /* It's above us. Go up, 1509 while (! NULL_PARENT (predecessor)) /* It's above us. Go up,
@@ -1518,7 +1518,7 @@ merge_interval_left (register INTERVAL i)
1518 1518
1519 predecessor = INTERVAL_PARENT (predecessor); 1519 predecessor = INTERVAL_PARENT (predecessor);
1520 predecessor->total_length -= absorb; 1520 predecessor->total_length -= absorb;
1521 eassert (0 <= TOTAL_LENGTH (predecessor)); 1521 eassert (TOTAL_LENGTH (predecessor) >= 0);
1522 } 1522 }
1523 1523
1524 /* This must be the leftmost or first interval and cannot 1524 /* This must be the leftmost or first interval and cannot
@@ -2272,7 +2272,7 @@ copy_intervals (INTERVAL tree, ptrdiff_t start, ptrdiff_t length)
2272 new->position = 0; 2272 new->position = 0;
2273 got = (LENGTH (i) - (start - i->position)); 2273 got = (LENGTH (i) - (start - i->position));
2274 new->total_length = length; 2274 new->total_length = length;
2275 eassert (0 <= TOTAL_LENGTH (new)); 2275 eassert (TOTAL_LENGTH (new) >= 0);
2276 copy_properties (i, new); 2276 copy_properties (i, new);
2277 2277
2278 t = new; 2278 t = new;
@@ -2355,7 +2355,7 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
2355 i->total_length = end - start; 2355 i->total_length = end - start;
2356 else 2356 else
2357 i->total_length = end_byte - start_byte; 2357 i->total_length = end_byte - start_byte;
2358 eassert (0 <= TOTAL_LENGTH (i)); 2358 eassert (TOTAL_LENGTH (i) >= 0);
2359 2359
2360 if (TOTAL_LENGTH (i) == 0) 2360 if (TOTAL_LENGTH (i) == 0)
2361 { 2361 {
diff --git a/src/keyboard.c b/src/keyboard.c
index e43b7a73172..8dd109d252d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -72,7 +72,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
72#include TERM_HEADER 72#include TERM_HEADER
73#endif /* HAVE_WINDOW_SYSTEM */ 73#endif /* HAVE_WINDOW_SYSTEM */
74 74
75/* Variables for blockinput.h: */ 75/* Variables for blockinput.h: */
76 76
77/* Positive if interrupt input is blocked right now. */ 77/* Positive if interrupt input is blocked right now. */
78volatile int interrupt_input_blocked; 78volatile int interrupt_input_blocked;
@@ -210,12 +210,6 @@ static EMACS_INT last_auto_save;
210/* The value of point when the last command was started. */ 210/* The value of point when the last command was started. */
211static ptrdiff_t last_point_position; 211static ptrdiff_t last_point_position;
212 212
213/* The buffer that was current when the last command was started. */
214static Lisp_Object last_point_position_buffer;
215
216/* The window that was selected when the last command was started. */
217static Lisp_Object last_point_position_window;
218
219/* The frame in which the last input event occurred, or Qmacro if the 213/* The frame in which the last input event occurred, or Qmacro if the
220 last event came from a macro. We use this to determine when to 214 last event came from a macro. We use this to determine when to
221 generate switch-frame events. This may be cleared by functions 215 generate switch-frame events. This may be cleared by functions
@@ -314,18 +308,15 @@ static Lisp_Object Qfunction_key;
314Lisp_Object Qmouse_click; 308Lisp_Object Qmouse_click;
315#ifdef HAVE_NTGUI 309#ifdef HAVE_NTGUI
316Lisp_Object Qlanguage_change; 310Lisp_Object Qlanguage_change;
317#ifdef WINDOWSNT
318Lisp_Object Qfile_w32notify;
319#endif
320#endif 311#endif
321static Lisp_Object Qdrag_n_drop; 312static Lisp_Object Qdrag_n_drop;
322static Lisp_Object Qsave_session; 313static Lisp_Object Qsave_session;
323#ifdef HAVE_DBUS 314#ifdef HAVE_DBUS
324static Lisp_Object Qdbus_event; 315static Lisp_Object Qdbus_event;
325#endif 316#endif
326#ifdef HAVE_INOTIFY 317#ifdef USE_FILE_NOTIFY
327static Lisp_Object Qfile_inotify; 318static Lisp_Object Qfile_notify;
328#endif /* HAVE_INOTIFY */ 319#endif /* USE_FILE_NOTIFY */
329static Lisp_Object Qconfig_changed_event; 320static Lisp_Object Qconfig_changed_event;
330 321
331/* Lisp_Object Qmouse_movement; - also an event header */ 322/* Lisp_Object Qmouse_movement; - also an event header */
@@ -833,7 +824,7 @@ This function is called by the editor initialization to begin editing. */)
833 update_mode_lines = 1; 824 update_mode_lines = 1;
834 825
835 if (command_loop_level 826 if (command_loop_level
836 && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) 827 && current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
837 buffer = Fcurrent_buffer (); 828 buffer = Fcurrent_buffer ();
838 else 829 else
839 buffer = Qnil; 830 buffer = Qnil;
@@ -1395,7 +1386,7 @@ command_loop_1 (void)
1395 Fkill_emacs (Qnil); 1386 Fkill_emacs (Qnil);
1396 1387
1397 /* Make sure the current window's buffer is selected. */ 1388 /* Make sure the current window's buffer is selected. */
1398 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer)); 1389 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
1399 1390
1400 /* Display any malloc warning that just came out. Use while because 1391 /* Display any malloc warning that just came out. Use while because
1401 displaying one warning can cause another. */ 1392 displaying one warning can cause another. */
@@ -1461,7 +1452,7 @@ command_loop_1 (void)
1461 /* A filter may have run while we were reading the input. */ 1452 /* A filter may have run while we were reading the input. */
1462 if (! FRAME_LIVE_P (XFRAME (selected_frame))) 1453 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
1463 Fkill_emacs (Qnil); 1454 Fkill_emacs (Qnil);
1464 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer)); 1455 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
1465 1456
1466 ++num_input_keys; 1457 ++num_input_keys;
1467 1458
@@ -1492,7 +1483,7 @@ command_loop_1 (void)
1492 { 1483 {
1493 struct buffer *b; 1484 struct buffer *b;
1494 XWINDOW (selected_window)->force_start = 0; 1485 XWINDOW (selected_window)->force_start = 0;
1495 b = XBUFFER (XWINDOW (selected_window)->buffer); 1486 b = XBUFFER (XWINDOW (selected_window)->contents);
1496 BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0; 1487 BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
1497 } 1488 }
1498 1489
@@ -1512,8 +1503,6 @@ command_loop_1 (void)
1512 prev_buffer = current_buffer; 1503 prev_buffer = current_buffer;
1513 prev_modiff = MODIFF; 1504 prev_modiff = MODIFF;
1514 last_point_position = PT; 1505 last_point_position = PT;
1515 last_point_position_window = selected_window;
1516 XSETBUFFER (last_point_position_buffer, prev_buffer);
1517 1506
1518 /* By default, we adjust point to a boundary of a region that 1507 /* By default, we adjust point to a boundary of a region that
1519 has such a property that should be treated intangible 1508 has such a property that should be treated intangible
@@ -1893,7 +1882,7 @@ safe_run_hooks_error (Lisp_Object error_data)
1893 = CONSP (Vinhibit_quit) ? XCAR (Vinhibit_quit) : Vinhibit_quit; 1882 = CONSP (Vinhibit_quit) ? XCAR (Vinhibit_quit) : Vinhibit_quit;
1894 Lisp_Object fun = CONSP (Vinhibit_quit) ? XCDR (Vinhibit_quit) : Qnil; 1883 Lisp_Object fun = CONSP (Vinhibit_quit) ? XCDR (Vinhibit_quit) : Qnil;
1895 Lisp_Object args[4]; 1884 Lisp_Object args[4];
1896 args[0] = build_string ("Error in %s (%s): %S"); 1885 args[0] = build_string ("Error in %s (%S): %S");
1897 args[1] = hook; 1886 args[1] = hook;
1898 args[2] = fun; 1887 args[2] = fun;
1899 args[3] = error_data; 1888 args[3] = error_data;
@@ -2230,6 +2219,160 @@ do { if (! polling_stopped_here) stop_polling (); \
2230do { if (polling_stopped_here) start_polling (); \ 2219do { if (polling_stopped_here) start_polling (); \
2231 polling_stopped_here = 0; } while (0) 2220 polling_stopped_here = 0; } while (0)
2232 2221
2222static Lisp_Object
2223read_event_from_main_queue (EMACS_TIME *end_time,
2224 sys_jmp_buf local_getcjmp,
2225 bool *used_mouse_menu)
2226{
2227 Lisp_Object c = Qnil;
2228 sys_jmp_buf save_jump;
2229 KBOARD *kb IF_LINT (= NULL);
2230
2231 start:
2232
2233 /* Read from the main queue, and if that gives us something we can't use yet,
2234 we put it on the appropriate side queue and try again. */
2235
2236 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
2237 return c;
2238
2239 /* Actually read a character, waiting if necessary. */
2240 save_getcjmp (save_jump);
2241 restore_getcjmp (local_getcjmp);
2242 if (!end_time)
2243 timer_start_idle ();
2244 c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
2245 restore_getcjmp (save_jump);
2246
2247 if (! NILP (c) && (kb != current_kboard))
2248 {
2249 Lisp_Object last = KVAR (kb, kbd_queue);
2250 if (CONSP (last))
2251 {
2252 while (CONSP (XCDR (last)))
2253 last = XCDR (last);
2254 if (!NILP (XCDR (last)))
2255 emacs_abort ();
2256 }
2257 if (!CONSP (last))
2258 kset_kbd_queue (kb, Fcons (c, Qnil));
2259 else
2260 XSETCDR (last, Fcons (c, Qnil));
2261 kb->kbd_queue_has_data = 1;
2262 c = Qnil;
2263 if (single_kboard)
2264 goto start;
2265 current_kboard = kb;
2266 /* This is going to exit from read_char
2267 so we had better get rid of this frame's stuff. */
2268 return make_number (-2);
2269 }
2270
2271 /* Terminate Emacs in batch mode if at eof. */
2272 if (noninteractive && INTEGERP (c) && XINT (c) < 0)
2273 Fkill_emacs (make_number (1));
2274
2275 if (INTEGERP (c))
2276 {
2277 /* Add in any extra modifiers, where appropriate. */
2278 if ((extra_keyboard_modifiers & CHAR_CTL)
2279 || ((extra_keyboard_modifiers & 0177) < ' '
2280 && (extra_keyboard_modifiers & 0177) != 0))
2281 XSETINT (c, make_ctrl_char (XINT (c)));
2282
2283 /* Transfer any other modifier bits directly from
2284 extra_keyboard_modifiers to c. Ignore the actual character code
2285 in the low 16 bits of extra_keyboard_modifiers. */
2286 XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
2287 }
2288
2289 /* FIXME: Decode tty keyboard input here. */
2290 return c;
2291}
2292
2293
2294
2295/* Like `read_event_from_main_queue' but applies keyboard-coding-system
2296 to tty input. */
2297static Lisp_Object
2298read_decoded_event_from_main_queue (EMACS_TIME *end_time,
2299 sys_jmp_buf local_getcjmp,
2300 Lisp_Object prev_event,
2301 bool *used_mouse_menu)
2302{
2303#define MAX_ENCODED_BYTES 16
2304 Lisp_Object events[MAX_ENCODED_BYTES];
2305 int n = 0;
2306 while (true)
2307 {
2308 Lisp_Object nextevt
2309 = read_event_from_main_queue (end_time, local_getcjmp,
2310 used_mouse_menu);
2311#ifdef WINDOWSNT
2312 /* w32_console already returns decoded events. It either reads
2313 Unicode characters from the Windows keyboard input, or
2314 converts characters encoded in the current codepage into
2315 Unicode. See w32inevt.c:key_event, near its end. */
2316 return nextevt;
2317#else
2318 struct frame *frame = XFRAME (selected_frame);
2319 struct terminal *terminal = frame->terminal;
2320 if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
2321 /* Don't apply decoding if we're just reading a raw event
2322 (e.g. reading bytes sent by the xterm to specify the position
2323 of a mouse click). */
2324 && (!EQ (prev_event, Qt))
2325 && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
2326 & CODING_REQUIRE_DECODING_MASK)))
2327 return nextevt; /* No decoding needed. */
2328 else
2329 {
2330 int meta_key = terminal->display_info.tty->meta_key;
2331 eassert (n < MAX_ENCODED_BYTES);
2332 events[n++] = nextevt;
2333 if (NATNUMP (nextevt)
2334 && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
2335 { /* An encoded byte sequence, let's try to decode it. */
2336 struct coding_system *coding
2337 = TERMINAL_KEYBOARD_CODING (terminal);
2338 unsigned char *src = alloca (n);
2339 int i;
2340 for (i = 0; i < n; i++)
2341 src[i] = XINT (events[i]);
2342 if (meta_key != 2)
2343 for (i = 0; i < n; i++)
2344 src[i] &= ~0x80;
2345 coding->destination = alloca (n * 4);
2346 coding->dst_bytes = n * 4;
2347 decode_coding_c_string (coding, src, n, Qnil);
2348 eassert (coding->produced_char <= n);
2349 if (coding->produced_char == 0)
2350 { /* The encoded sequence is incomplete. */
2351 if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
2352 continue; /* Read on! */
2353 }
2354 else
2355 {
2356 const unsigned char *p = coding->destination;
2357 eassert (coding->carryover_bytes == 0);
2358 n = 0;
2359 while (n < coding->produced_char)
2360 events[n++] = make_number (STRING_CHAR_ADVANCE (p));
2361 }
2362 }
2363 /* Now `events' should hold decoded events.
2364 Normally, n should be equal to 1, but better not rely on it.
2365 We can only return one event here, so return the first we
2366 had and keep the others (if any) for later. */
2367 while (n > 1)
2368 Vunread_command_events
2369 = Fcons (events[--n], Vunread_command_events);
2370 return events[0];
2371 }
2372#endif
2373 }
2374}
2375
2233/* Read a character from the keyboard; call the redisplay if needed. */ 2376/* Read a character from the keyboard; call the redisplay if needed. */
2234/* commandflag 0 means do not autosave, but do redisplay. 2377/* commandflag 0 means do not autosave, but do redisplay.
2235 -1 means do not redisplay, but do autosave. 2378 -1 means do not redisplay, but do autosave.
@@ -2747,68 +2890,20 @@ read_char (int commandflag, Lisp_Object map,
2747 2890
2748 STOP_POLLING; 2891 STOP_POLLING;
2749 2892
2750 /* Finally, we read from the main queue,
2751 and if that gives us something we can't use yet, we put it on the
2752 appropriate side queue and try again. */
2753
2754 if (NILP (c)) 2893 if (NILP (c))
2755 { 2894 {
2756 KBOARD *kb IF_LINT (= NULL); 2895 c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
2757 2896 prev_event, used_mouse_menu);
2758 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) 2897 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
2759 goto exit; 2898 goto exit;
2760 2899 if (EQ (c, make_number (-2)))
2761 /* Actually read a character, waiting if necessary. */ 2900 {
2762 save_getcjmp (save_jump);
2763 restore_getcjmp (local_getcjmp);
2764 if (!end_time)
2765 timer_start_idle ();
2766 c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
2767 restore_getcjmp (save_jump);
2768
2769 if (! NILP (c) && (kb != current_kboard))
2770 {
2771 Lisp_Object last = KVAR (kb, kbd_queue);
2772 if (CONSP (last))
2773 {
2774 while (CONSP (XCDR (last)))
2775 last = XCDR (last);
2776 if (!NILP (XCDR (last)))
2777 emacs_abort ();
2778 }
2779 if (!CONSP (last))
2780 kset_kbd_queue (kb, Fcons (c, Qnil));
2781 else
2782 XSETCDR (last, Fcons (c, Qnil));
2783 kb->kbd_queue_has_data = 1;
2784 c = Qnil;
2785 if (single_kboard)
2786 goto wrong_kboard;
2787 current_kboard = kb;
2788 /* This is going to exit from read_char 2901 /* This is going to exit from read_char
2789 so we had better get rid of this frame's stuff. */ 2902 so we had better get rid of this frame's stuff. */
2790 UNGCPRO; 2903 UNGCPRO;
2791 return make_number (-2); 2904 return c;
2792 } 2905 }
2793 } 2906 }
2794
2795 /* Terminate Emacs in batch mode if at eof. */
2796 if (noninteractive && INTEGERP (c) && XINT (c) < 0)
2797 Fkill_emacs (make_number (1));
2798
2799 if (INTEGERP (c))
2800 {
2801 /* Add in any extra modifiers, where appropriate. */
2802 if ((extra_keyboard_modifiers & CHAR_CTL)
2803 || ((extra_keyboard_modifiers & 0177) < ' '
2804 && (extra_keyboard_modifiers & 0177) != 0))
2805 XSETINT (c, make_ctrl_char (XINT (c)));
2806
2807 /* Transfer any other modifier bits directly from
2808 extra_keyboard_modifiers to c. Ignore the actual character code
2809 in the low 16 bits of extra_keyboard_modifiers. */
2810 XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
2811 }
2812 2907
2813 non_reread: 2908 non_reread:
2814 2909
@@ -3915,18 +4010,22 @@ kbd_buffer_get_event (KBOARD **kbp,
3915 kbd_fetch_ptr = event + 1; 4010 kbd_fetch_ptr = event + 1;
3916 } 4011 }
3917#endif 4012#endif
3918#ifdef WINDOWSNT 4013#ifdef USE_FILE_NOTIFY
3919 else if (event->kind == FILE_NOTIFY_EVENT) 4014 else if (event->kind == FILE_NOTIFY_EVENT)
3920 { 4015 {
4016#ifdef HAVE_W32NOTIFY
3921 /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */ 4017 /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
3922 obj = Fcons (Qfile_w32notify, 4018 obj = Fcons (Qfile_notify,
3923 list2 (list3 (make_number (event->code), 4019 list2 (list3 (make_number (event->code),
3924 XCAR (event->arg), 4020 XCAR (event->arg),
3925 XCDR (event->arg)), 4021 XCDR (event->arg)),
3926 event->frame_or_window)); 4022 event->frame_or_window));
4023#else
4024 obj = make_lispy_event (event);
4025#endif
3927 kbd_fetch_ptr = event + 1; 4026 kbd_fetch_ptr = event + 1;
3928 } 4027 }
3929#endif 4028#endif /* USE_FILE_NOTIFY */
3930 else if (event->kind == SAVE_SESSION_EVENT) 4029 else if (event->kind == SAVE_SESSION_EVENT)
3931 { 4030 {
3932 obj = Fcons (Qsave_session, Fcons (event->arg, Qnil)); 4031 obj = Fcons (Qsave_session, Fcons (event->arg, Qnil));
@@ -3984,13 +4083,6 @@ kbd_buffer_get_event (KBOARD **kbp,
3984 kbd_fetch_ptr = event + 1; 4083 kbd_fetch_ptr = event + 1;
3985 } 4084 }
3986#endif 4085#endif
3987#ifdef HAVE_INOTIFY
3988 else if (event->kind == FILE_NOTIFY_EVENT)
3989 {
3990 obj = make_lispy_event (event);
3991 kbd_fetch_ptr = event + 1;
3992 }
3993#endif
3994 else if (event->kind == CONFIG_CHANGED_EVENT) 4086 else if (event->kind == CONFIG_CHANGED_EVENT)
3995 { 4087 {
3996 obj = make_lispy_event (event); 4088 obj = make_lispy_event (event);
@@ -4196,8 +4288,6 @@ swallow_events (bool do_display)
4196static void 4288static void
4197timer_start_idle (void) 4289timer_start_idle (void)
4198{ 4290{
4199 Lisp_Object timers;
4200
4201 /* If we are already in the idle state, do nothing. */ 4291 /* If we are already in the idle state, do nothing. */
4202 if (EMACS_TIME_VALID_P (timer_idleness_start_time)) 4292 if (EMACS_TIME_VALID_P (timer_idleness_start_time))
4203 return; 4293 return;
@@ -4206,16 +4296,7 @@ timer_start_idle (void)
4206 timer_last_idleness_start_time = timer_idleness_start_time; 4296 timer_last_idleness_start_time = timer_idleness_start_time;
4207 4297
4208 /* Mark all idle-time timers as once again candidates for running. */ 4298 /* Mark all idle-time timers as once again candidates for running. */
4209 for (timers = Vtimer_idle_list; CONSP (timers); timers = XCDR (timers)) 4299 call0 (intern ("internal-timer-start-idle"));
4210 {
4211 Lisp_Object timer;
4212
4213 timer = XCAR (timers);
4214
4215 if (!VECTORP (timer) || ASIZE (timer) != 9)
4216 continue;
4217 ASET (timer, 0, Qnil);
4218 }
4219} 4300}
4220 4301
4221/* Record that Emacs is no longer idle, so stop running idle-time timers. */ 4302/* Record that Emacs is no longer idle, so stop running idle-time timers. */
@@ -4345,10 +4426,10 @@ timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4345 } 4426 }
4346 4427
4347 idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now); 4428 idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
4348 idle_timer_difference = 4429 idle_timer_difference
4349 (idle_timer_ripe 4430 = (idle_timer_ripe
4350 ? sub_emacs_time (idleness_now, idle_timer_time) 4431 ? sub_emacs_time (idleness_now, idle_timer_time)
4351 : sub_emacs_time (idle_timer_time, idleness_now)); 4432 : sub_emacs_time (idle_timer_time, idleness_now));
4352 } 4433 }
4353 4434
4354 /* Decide which timer is the next timer, 4435 /* Decide which timer is the next timer,
@@ -5142,7 +5223,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5142 if (STRINGP (string)) 5223 if (STRINGP (string))
5143 string_info = Fcons (string, make_number (charpos)); 5224 string_info = Fcons (string, make_number (charpos));
5144 textpos = (w == XWINDOW (selected_window) 5225 textpos = (w == XWINDOW (selected_window)
5145 && current_buffer == XBUFFER (w->buffer)) 5226 && current_buffer == XBUFFER (w->contents))
5146 ? PT : marker_position (w->pointm); 5227 ? PT : marker_position (w->pointm);
5147 5228
5148 xret = wx; 5229 xret = wx;
@@ -5904,12 +5985,12 @@ make_lispy_event (struct input_event *event)
5904 } 5985 }
5905#endif /* HAVE_DBUS */ 5986#endif /* HAVE_DBUS */
5906 5987
5907#ifdef HAVE_INOTIFY 5988#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY
5908 case FILE_NOTIFY_EVENT: 5989 case FILE_NOTIFY_EVENT:
5909 { 5990 {
5910 return Fcons (Qfile_inotify, event->arg); 5991 return Fcons (Qfile_notify, event->arg);
5911 } 5992 }
5912#endif /* HAVE_INOTIFY */ 5993#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
5913 5994
5914 case CONFIG_CHANGED_EVENT: 5995 case CONFIG_CHANGED_EVENT:
5915 return Fcons (Qconfig_changed_event, 5996 return Fcons (Qconfig_changed_event,
@@ -6766,7 +6847,7 @@ gobble_input (void)
6766 hold_quit.kind = NO_EVENT; 6847 hold_quit.kind = NO_EVENT;
6767 6848
6768 /* No need for FIONREAD or fcntl; just say don't wait. */ 6849 /* No need for FIONREAD or fcntl; just say don't wait. */
6769 while (0 < (nr = (*t->read_socket_hook) (t, &hold_quit))) 6850 while ((nr = (*t->read_socket_hook) (t, &hold_quit)) > 0)
6770 nread += nr; 6851 nread += nr;
6771 6852
6772 if (nr == -1) /* Not OK to read input now. */ 6853 if (nr == -1) /* Not OK to read input now. */
@@ -6846,6 +6927,8 @@ tty_read_avail_input (struct terminal *terminal,
6846 /* XXX I think the following code should be moved to separate hook 6927 /* XXX I think the following code should be moved to separate hook
6847 functions in system-dependent files. */ 6928 functions in system-dependent files. */
6848#ifdef WINDOWSNT 6929#ifdef WINDOWSNT
6930 /* FIXME: AFAIK, tty_read_avail_input is not used under w32 since the non-GUI
6931 code sets read_socket_hook to w32_console_read_socket instead! */
6849 return 0; 6932 return 0;
6850#else /* not WINDOWSNT */ 6933#else /* not WINDOWSNT */
6851 if (! tty->term_initted) /* In case we get called during bootstrap. */ 6934 if (! tty->term_initted) /* In case we get called during bootstrap. */
@@ -8240,9 +8323,8 @@ append_tool_bar_item (void)
8240 - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS)); 8323 - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
8241 8324
8242 /* Enlarge tool_bar_items_vector if necessary. */ 8325 /* Enlarge tool_bar_items_vector if necessary. */
8243 if (0 < incr) 8326 if (incr > 0)
8244 tool_bar_items_vector 8327 tool_bar_items_vector = larger_vector (tool_bar_items_vector, incr, -1);
8245 = larger_vector (tool_bar_items_vector, incr, -1);
8246 8328
8247 /* Append entries from tool_bar_item_properties to the end of 8329 /* Append entries from tool_bar_item_properties to the end of
8248 tool_bar_items_vector. */ 8330 tool_bar_items_vector. */
@@ -8708,71 +8790,6 @@ test_undefined (Lisp_Object binding)
8708 && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); 8790 && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
8709} 8791}
8710 8792
8711/* Like `read_char' but applies keyboard-coding-system to tty input. */
8712static Lisp_Object
8713read_decoded_char (int commandflag, Lisp_Object map,
8714 Lisp_Object prev_event, bool *used_mouse_menu)
8715{
8716#define MAX_ENCODED_BYTES 16
8717 Lisp_Object events[MAX_ENCODED_BYTES];
8718 int n = 0;
8719 while (true)
8720 {
8721 Lisp_Object nextevt
8722 = read_char (commandflag, map, prev_event, used_mouse_menu, NULL);
8723 struct frame *frame = XFRAME (selected_frame);
8724 struct terminal *terminal = frame->terminal;
8725 if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
8726 && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
8727 & CODING_REQUIRE_DECODING_MASK)))
8728 return nextevt; /* No decoding needed. */
8729 else
8730 {
8731 int meta_key = terminal->display_info.tty->meta_key;
8732 eassert (n < MAX_ENCODED_BYTES);
8733 events[n++] = nextevt;
8734 if (NATNUMP (nextevt)
8735 && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
8736 { /* An encoded byte sequence, let's try to decode it. */
8737 struct coding_system *coding
8738 = TERMINAL_KEYBOARD_CODING (terminal);
8739 unsigned char *src = alloca (n);
8740 int i;
8741 for (i = 0; i < n; i++)
8742 src[i] = XINT (events[i]);
8743 if (meta_key != 2)
8744 for (i = 0; i < n; i++)
8745 src[i] &= ~0x80;
8746 coding->destination = alloca (n * 4);
8747 coding->dst_bytes = n * 4;
8748 decode_coding_c_string (coding, src, n, Qnil);
8749 eassert (coding->produced_char <= n);
8750 if (coding->produced_char == 0)
8751 { /* The encoded sequence is incomplete. */
8752 if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
8753 continue; /* Read on! */
8754 }
8755 else
8756 {
8757 const unsigned char *p = coding->destination;
8758 eassert (coding->carryover_bytes == 0);
8759 n = 0;
8760 while (n < coding->produced_char)
8761 events[n++] = make_number (STRING_CHAR_ADVANCE (p));
8762 }
8763 }
8764 /* Now `events' should hold decoded events.
8765 Normally, n should be equal to 1, but better not rely on it.
8766 We can only return one event here, so return the first we
8767 had and keep the others (if any) for later. */
8768 while (n > 1)
8769 Vunread_command_events
8770 = Fcons (events[--n], Vunread_command_events);
8771 return events[0];
8772 }
8773 }
8774}
8775
8776/* Read a sequence of keys that ends with a non prefix character, 8793/* Read a sequence of keys that ends with a non prefix character,
8777 storing it in KEYBUF, a buffer of size BUFSIZE. 8794 storing it in KEYBUF, a buffer of size BUFSIZE.
8778 Prompt with PROMPT. 8795 Prompt with PROMPT.
@@ -9050,9 +9067,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9050 { 9067 {
9051 KBOARD *interrupted_kboard = current_kboard; 9068 KBOARD *interrupted_kboard = current_kboard;
9052 struct frame *interrupted_frame = SELECTED_FRAME (); 9069 struct frame *interrupted_frame = SELECTED_FRAME ();
9053 key = read_decoded_char (NILP (prompt), 9070 key = read_char (NILP (prompt),
9054 current_binding, last_nonmenu_event, 9071 current_binding, last_nonmenu_event,
9055 &used_mouse_menu); 9072 &used_mouse_menu, NULL);
9056 if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ 9073 if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
9057 /* When switching to a new tty (with a new keyboard), 9074 /* When switching to a new tty (with a new keyboard),
9058 read_char returns the new buffer, rather than -2 9075 read_char returns the new buffer, rather than -2
@@ -9146,9 +9163,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9146 { 9163 {
9147 if (! FRAME_LIVE_P (XFRAME (selected_frame))) 9164 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
9148 Fkill_emacs (Qnil); 9165 Fkill_emacs (Qnil);
9149 if (XBUFFER (XWINDOW (selected_window)->buffer) 9166 if (XBUFFER (XWINDOW (selected_window)->contents)
9150 != current_buffer) 9167 != current_buffer)
9151 Fset_buffer (XWINDOW (selected_window)->buffer); 9168 Fset_buffer (XWINDOW (selected_window)->contents);
9152 } 9169 }
9153 9170
9154 goto replay_sequence; 9171 goto replay_sequence;
@@ -9196,9 +9213,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9196 special-event-map, ...) might have switched the current buffer 9213 special-event-map, ...) might have switched the current buffer
9197 or the selected window from under us in the mean time. */ 9214 or the selected window from under us in the mean time. */
9198 if (fix_current_buffer 9215 if (fix_current_buffer
9199 && (XBUFFER (XWINDOW (selected_window)->buffer) 9216 && (XBUFFER (XWINDOW (selected_window)->contents)
9200 != current_buffer)) 9217 != current_buffer))
9201 Fset_buffer (XWINDOW (selected_window)->buffer); 9218 Fset_buffer (XWINDOW (selected_window)->contents);
9202 current_binding = active_maps (first_event); 9219 current_binding = active_maps (first_event);
9203 } 9220 }
9204 9221
@@ -9247,8 +9264,8 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9247 not the current buffer. If we're at the 9264 not the current buffer. If we're at the
9248 beginning of a key sequence, switch buffers. */ 9265 beginning of a key sequence, switch buffers. */
9249 if (WINDOWP (window) 9266 if (WINDOWP (window)
9250 && BUFFERP (XWINDOW (window)->buffer) 9267 && BUFFERP (XWINDOW (window)->contents)
9251 && XBUFFER (XWINDOW (window)->buffer) != current_buffer) 9268 && XBUFFER (XWINDOW (window)->contents) != current_buffer)
9252 { 9269 {
9253 ASET (raw_keybuf, raw_keybuf_count, key); 9270 ASET (raw_keybuf, raw_keybuf_count, key);
9254 raw_keybuf_count++; 9271 raw_keybuf_count++;
@@ -9269,7 +9286,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9269 9286
9270 if (! FRAME_LIVE_P (XFRAME (selected_frame))) 9287 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
9271 Fkill_emacs (Qnil); 9288 Fkill_emacs (Qnil);
9272 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); 9289 set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
9273 goto replay_sequence; 9290 goto replay_sequence;
9274 } 9291 }
9275 } 9292 }
@@ -10983,17 +11000,13 @@ syms_of_keyboard (void)
10983 DEFSYM (Qlanguage_change, "language-change"); 11000 DEFSYM (Qlanguage_change, "language-change");
10984#endif 11001#endif
10985 11002
10986#ifdef WINDOWSNT
10987 DEFSYM (Qfile_w32notify, "file-w32notify");
10988#endif
10989
10990#ifdef HAVE_DBUS 11003#ifdef HAVE_DBUS
10991 DEFSYM (Qdbus_event, "dbus-event"); 11004 DEFSYM (Qdbus_event, "dbus-event");
10992#endif 11005#endif
10993 11006
10994#ifdef HAVE_INOTIFY 11007#ifdef USE_FILE_NOTIFY
10995 DEFSYM (Qfile_inotify, "file-inotify"); 11008 DEFSYM (Qfile_notify, "file-notify");
10996#endif /* HAVE_INOTIFY */ 11009#endif /* USE_FILE_NOTIFY */
10997 11010
10998 DEFSYM (QCenable, ":enable"); 11011 DEFSYM (QCenable, ":enable");
10999 DEFSYM (QCvisible, ":visible"); 11012 DEFSYM (QCvisible, ":visible");
@@ -11048,9 +11061,6 @@ syms_of_keyboard (void)
11048 Fset (Qinput_method_exit_on_first_char, Qnil); 11061 Fset (Qinput_method_exit_on_first_char, Qnil);
11049 Fset (Qinput_method_use_echo_area, Qnil); 11062 Fset (Qinput_method_use_echo_area, Qnil);
11050 11063
11051 last_point_position_buffer = Qnil;
11052 last_point_position_window = Qnil;
11053
11054 { 11064 {
11055 int i; 11065 int i;
11056 int len = sizeof (head_table) / sizeof (head_table[0]); 11066 int len = sizeof (head_table) / sizeof (head_table[0]);
@@ -11742,20 +11752,18 @@ keys_of_keyboard (void)
11742 "dbus-handle-event"); 11752 "dbus-handle-event");
11743#endif 11753#endif
11744 11754
11745#ifdef HAVE_INOTIFY 11755#ifdef USE_FILE_NOTIFY
11746 /* Define a special event which is raised for inotify callback 11756 /* Define a special event which is raised for notification callback
11747 functions. */ 11757 functions. */
11748 initial_define_lispy_key (Vspecial_event_map, "file-inotify", 11758 initial_define_lispy_key (Vspecial_event_map, "file-notify",
11749 "inotify-handle-event"); 11759 "file-notify-handle-event");
11750#endif /* HAVE_INOTIFY */ 11760#endif /* USE_FILE_NOTIFY */
11751 11761
11752 initial_define_lispy_key (Vspecial_event_map, "config-changed-event", 11762 initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
11753 "ignore"); 11763 "ignore");
11754#if defined (WINDOWSNT) 11764#if defined (WINDOWSNT)
11755 initial_define_lispy_key (Vspecial_event_map, "language-change", 11765 initial_define_lispy_key (Vspecial_event_map, "language-change",
11756 "ignore"); 11766 "ignore");
11757 initial_define_lispy_key (Vspecial_event_map, "file-w32notify",
11758 "w32notify-handle-event");
11759#endif 11767#endif
11760} 11768}
11761 11769
diff --git a/src/keymap.c b/src/keymap.c
index 00eefb375ef..c43d528b25b 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -611,7 +611,8 @@ map_keymap_internal (Lisp_Object map,
611 } 611 }
612 else if (CHAR_TABLE_P (binding)) 612 else if (CHAR_TABLE_P (binding))
613 map_char_table (map_keymap_char_table_item, Qnil, binding, 613 map_char_table (map_keymap_char_table_item, Qnil, binding,
614 make_save_value ("ppo", fun, data, args)); 614 make_save_value (SAVE_TYPE_PTR_PTR_OBJ,
615 fun, data, args));
615 } 616 }
616 UNGCPRO; 617 UNGCPRO;
617 return tail; 618 return tail;
@@ -1555,8 +1556,8 @@ like in the respective argument of `key-binding'. */)
1555 window = POSN_WINDOW (position); 1556 window = POSN_WINDOW (position);
1556 1557
1557 if (WINDOWP (window) 1558 if (WINDOWP (window)
1558 && BUFFERP (XWINDOW (window)->buffer) 1559 && BUFFERP (XWINDOW (window)->contents)
1559 && XBUFFER (XWINDOW (window)->buffer) != current_buffer) 1560 && XBUFFER (XWINDOW (window)->contents) != current_buffer)
1560 { 1561 {
1561 /* Arrange to go back to the original buffer once we're done 1562 /* Arrange to go back to the original buffer once we're done
1562 processing the key sequence. We don't use 1563 processing the key sequence. We don't use
@@ -1566,7 +1567,7 @@ like in the respective argument of `key-binding'. */)
1566 things the same. 1567 things the same.
1567 */ 1568 */
1568 record_unwind_current_buffer (); 1569 record_unwind_current_buffer ();
1569 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer)); 1570 set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
1570 } 1571 }
1571 } 1572 }
1572 1573
diff --git a/src/lisp.h b/src/lisp.h
index 44dde1860cc..c8732d125cc 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -75,6 +75,7 @@ enum
75 BITS_PER_SHORT = CHAR_BIT * sizeof (short), 75 BITS_PER_SHORT = CHAR_BIT * sizeof (short),
76 BITS_PER_INT = CHAR_BIT * sizeof (int), 76 BITS_PER_INT = CHAR_BIT * sizeof (int),
77 BITS_PER_LONG = CHAR_BIT * sizeof (long int), 77 BITS_PER_LONG = CHAR_BIT * sizeof (long int),
78 BITS_PER_PTRDIFF_T = CHAR_BIT * sizeof (ptrdiff_t),
78 BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) 79 BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT)
79 }; 80 };
80 81
@@ -233,9 +234,9 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
233#define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 234#define case_Lisp_Int case Lisp_Int0: case Lisp_Int1
234#define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0) 235#define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0)
235 236
236/* Stolen from GDB. The only known compiler that doesn't support 237/* Idea stolen from GDB. MSVC doesn't support enums in bitfields,
237 enums in bitfields is MSVC. */ 238 and xlc complains vociferously about them. */
238#ifdef _MSC_VER 239#if defined _MSC_VER || defined __IBMC__
239#define ENUM_BF(TYPE) unsigned int 240#define ENUM_BF(TYPE) unsigned int
240#else 241#else
241#define ENUM_BF(TYPE) enum TYPE 242#define ENUM_BF(TYPE) enum TYPE
@@ -556,6 +557,7 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
556 return num < lower ? lower : num <= upper ? num : upper; 557 return num < lower ? lower : num <= upper ? num : upper;
557} 558}
558 559
560
559/* Extract a value or address from a Lisp_Object. */ 561/* Extract a value or address from a Lisp_Object. */
560 562
561#define XCONS(a) (eassert (CONSP (a)), \ 563#define XCONS(a) (eassert (CONSP (a)), \
@@ -576,7 +578,6 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
576#define XMISCTYPE(a) (XMISCANY (a)->type) 578#define XMISCTYPE(a) (XMISCANY (a)->type)
577#define XMARKER(a) (eassert (MARKERP (a)), &(XMISC (a)->u_marker)) 579#define XMARKER(a) (eassert (MARKERP (a)), &(XMISC (a)->u_marker))
578#define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay)) 580#define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay))
579#define XSAVE_VALUE(a) (eassert (SAVE_VALUEP (a)), &(XMISC (a)->u_save_value))
580 581
581/* Forwarding object types. */ 582/* Forwarding object types. */
582 583
@@ -590,10 +591,12 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
590 (eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd)) 591 (eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd))
591 592
592/* Pseudovector types. */ 593/* Pseudovector types. */
593 594struct Lisp_Process;
595LISP_INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p)
596{ return make_lisp_ptr (p, Lisp_Vectorlike); }
594#define XPROCESS(a) (eassert (PROCESSP (a)), \ 597#define XPROCESS(a) (eassert (PROCESSP (a)), \
595 (struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike)) 598 (struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike))
596#define XWINDOW(a) (eassert (WINDOWP (a)), \ 599#define XWINDOW(a) (eassert (WINDOWP (a)), \
597 (struct window *) XUNTAG (a, Lisp_Vectorlike)) 600 (struct window *) XUNTAG (a, Lisp_Vectorlike))
598#define XTERMINAL(a) (eassert (TERMINALP (a)), \ 601#define XTERMINAL(a) (eassert (TERMINALP (a)), \
599 (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) 602 (struct terminal *) XUNTAG (a, Lisp_Vectorlike))
@@ -792,13 +795,10 @@ extern ptrdiff_t string_bytes (struct Lisp_String *);
792 would expose alloc.c internal details that we'd rather keep 795 would expose alloc.c internal details that we'd rather keep
793 private. 796 private.
794 797
795 This is a macro for use in static initializers, and a constant for 798 This is a macro for use in static initializers. The cast to
796 visibility to GDB. The cast to ptrdiff_t ensures that 799 ptrdiff_t ensures that the macro is signed. */
797 the macro is signed. */
798static ptrdiff_t const STRING_BYTES_BOUND =
799#define STRING_BYTES_BOUND \ 800#define STRING_BYTES_BOUND \
800 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1)) 801 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1))
801 STRING_BYTES_BOUND;
802 802
803/* Mark STR as a unibyte string. */ 803/* Mark STR as a unibyte string. */
804#define STRING_SET_UNIBYTE(STR) \ 804#define STRING_SET_UNIBYTE(STR) \
@@ -1403,6 +1403,35 @@ enum
1403 SAVE_OBJECT 1403 SAVE_OBJECT
1404 }; 1404 };
1405 1405
1406/* Number of bits needed to store one of the above values. */
1407enum { SAVE_SLOT_BITS = 2 };
1408
1409/* Number of slots in a save value where save_type is nonzero. */
1410enum { SAVE_VALUE_SLOTS = 4 };
1411
1412/* Bit-width and values for struct Lisp_Save_Value's save_type member. */
1413
1414enum { SAVE_TYPE_BITS = SAVE_VALUE_SLOTS * SAVE_SLOT_BITS + 1 };
1415
1416enum Lisp_Save_Type
1417 {
1418 SAVE_TYPE_INT_INT = SAVE_INTEGER + (SAVE_INTEGER << SAVE_SLOT_BITS),
1419 SAVE_TYPE_INT_INT_INT
1420 = (SAVE_INTEGER + (SAVE_TYPE_INT_INT << SAVE_SLOT_BITS)),
1421 SAVE_TYPE_OBJ_OBJ = SAVE_OBJECT + (SAVE_OBJECT << SAVE_SLOT_BITS),
1422 SAVE_TYPE_OBJ_OBJ_OBJ = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ << SAVE_SLOT_BITS),
1423 SAVE_TYPE_OBJ_OBJ_OBJ_OBJ
1424 = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ_OBJ << SAVE_SLOT_BITS),
1425 SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS),
1426 SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS),
1427 SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS),
1428 SAVE_TYPE_PTR_PTR_OBJ
1429 = SAVE_POINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS),
1430
1431 /* This has an extra bit indicating it's raw memory. */
1432 SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1))
1433 };
1434
1406/* Special object used to hold a different values for later use. 1435/* Special object used to hold a different values for later use.
1407 1436
1408 This is mostly used to package C integers and pointers to call 1437 This is mostly used to package C integers and pointers to call
@@ -1423,74 +1452,50 @@ enum
1423 1452
1424 If yon need to pass more than just one C pointer, you should 1453 If yon need to pass more than just one C pointer, you should
1425 use make_save_value. This function allows you to pack up to 1454 use make_save_value. This function allows you to pack up to
1426 4 integers, pointers or Lisp_Objects and conveniently get them 1455 SAVE_VALUE_SLOTS integers, pointers or Lisp_Objects and
1427 back with XSAVE_POINTER, XSAVE_INTEGER and XSAVE_OBJECT macros: 1456 conveniently get them back with XSAVE_POINTER, XSAVE_INTEGER and
1457 XSAVE_OBJECT macros:
1428 1458
1429 ... 1459 ...
1430 struct my_data *md = get_my_data (); 1460 struct my_data *md = get_my_data ();
1431 ptrdiff_t my_offset = get_my_offset ();
1432 Lisp_Object my_object = get_my_object (); 1461 Lisp_Object my_object = get_my_object ();
1433 record_unwind_protect 1462 record_unwind_protect
1434 (my_unwind, make_save_value ("pio", md, my_offset, my_object)); 1463 (my_unwind, make_save_value (SAVE_TYPE_PTR_OBJ, md, my_object));
1435 ... 1464 ...
1436 1465
1437 Lisp_Object my_unwind (Lisp_Object arg) 1466 Lisp_Object my_unwind (Lisp_Object arg)
1438 { 1467 {
1439 struct my_data *md = XSAVE_POINTER (arg, 0); 1468 struct my_data *md = XSAVE_POINTER (arg, 0);
1440 ptrdiff_t my_offset = XSAVE_INTEGER (arg, 1); 1469 Lisp_Object my_object = XSAVE_OBJECT (arg, 1);
1441 Lisp_Object my_object = XSAVE_OBJECT (arg, 2);
1442 ... 1470 ...
1443 } 1471 }
1444 1472
1445 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the 1473 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the
1446 saved objects and raise eassert if type of the saved object doesn't match 1474 saved objects and raise eassert if type of the saved object doesn't match
1447 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) 1475 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2)
1448 or XSAVE_OBJECT (arg, 1) are wrong because integer was saved in slot 1 and 1476 or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and
1449 Lisp_Object was saved in slot 2 of ARG. */ 1477 Lisp_Object was saved in slot 1 of ARG. */
1450 1478
1451struct Lisp_Save_Value 1479struct Lisp_Save_Value
1452 { 1480 {
1453 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ 1481 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */
1454 unsigned gcmarkbit : 1; 1482 unsigned gcmarkbit : 1;
1455 int spacer : 6; 1483 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
1456 /* If `area' is nonzero, `data[0].pointer' is the address of a memory area 1484
1457 containing `data[1].integer' potential Lisp_Objects. The rest of `data' 1485 /* DATA[N] may hold up to SAVE_VALUE_SLOTS entries. The type of
1458 fields are unused. */ 1486 V's Ith entry is given by save_type (V, I). E.g., if save_type
1459 unsigned area : 1; 1487 (V, 3) == SAVE_INTEGER, V->data[3].integer is in use.
1460 /* If `area' is zero, `data[N]' may hold different objects which type is 1488
1461 encoded in `typeN' fields as described by the anonymous enum above. 1489 If SAVE_TYPE == SAVE_TYPE_MEMORY, DATA[0].pointer is the address of
1462 E.g. if `type0' is SAVE_INTEGER, `data[0].integer' is in use. */ 1490 a memory area containing DATA[1].integer potential Lisp_Objects. */
1463 unsigned type0 : 2; 1491 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS;
1464 unsigned type1 : 2;
1465 unsigned type2 : 2;
1466 unsigned type3 : 2;
1467 union { 1492 union {
1468 void *pointer; 1493 void *pointer;
1469 ptrdiff_t integer; 1494 ptrdiff_t integer;
1470 Lisp_Object object; 1495 Lisp_Object object;
1471 } data[4]; 1496 } data[SAVE_VALUE_SLOTS];
1472 }; 1497 };
1473 1498
1474/* Macro to set and extract Nth saved pointer. Type
1475 checking is ugly because it's used as an lvalue. */
1476
1477#define XSAVE_POINTER(obj, n) \
1478 XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
1479 ## n == SAVE_POINTER), n)].pointer
1480
1481/* Likewise for the saved integer. */
1482
1483#define XSAVE_INTEGER(obj, n) \
1484 XSAVE_VALUE (obj)->data[(eassert (XSAVE_VALUE (obj)->type \
1485 ## n == SAVE_INTEGER), n)].integer
1486
1487/* Macro to extract Nth saved object. This is never used as
1488 an lvalue, so we can do more convenient type checking. */
1489
1490#define XSAVE_OBJECT(obj, n) \
1491 (eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT), \
1492 XSAVE_VALUE (obj)->data[n].object)
1493
1494/* A miscellaneous object, when it's on the free list. */ 1499/* A miscellaneous object, when it's on the free list. */
1495struct Lisp_Free 1500struct Lisp_Free
1496 { 1501 {
@@ -1797,7 +1802,66 @@ typedef struct {
1797#define VECTORP(x) (VECTORLIKEP (x) && !(ASIZE (x) & PSEUDOVECTOR_FLAG)) 1802#define VECTORP(x) (VECTORLIKEP (x) && !(ASIZE (x) & PSEUDOVECTOR_FLAG))
1798#define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay) 1803#define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay)
1799#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) 1804#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
1800#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) 1805
1806LISP_INLINE bool
1807SAVE_VALUEP (Lisp_Object x)
1808{
1809 return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value;
1810}
1811
1812LISP_INLINE struct Lisp_Save_Value *
1813XSAVE_VALUE (Lisp_Object a)
1814{
1815 eassert (SAVE_VALUEP (a));
1816 return & XMISC (a)->u_save_value;
1817}
1818
1819/* Return the type of V's Nth saved value. */
1820LISP_INLINE int
1821save_type (struct Lisp_Save_Value *v, int n)
1822{
1823 eassert (0 <= n && n < SAVE_VALUE_SLOTS);
1824 return (v->save_type >> (SAVE_SLOT_BITS * n) & ((1 << SAVE_SLOT_BITS) - 1));
1825}
1826
1827/* Get and set the Nth saved pointer. */
1828
1829LISP_INLINE void *
1830XSAVE_POINTER (Lisp_Object obj, int n)
1831{
1832 eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER);
1833 return XSAVE_VALUE (obj)->data[n].pointer;;
1834}
1835LISP_INLINE void
1836set_save_pointer (Lisp_Object obj, int n, void *val)
1837{
1838 eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER);
1839 XSAVE_VALUE (obj)->data[n].pointer = val;
1840}
1841
1842/* Likewise for the saved integer. */
1843
1844LISP_INLINE ptrdiff_t
1845XSAVE_INTEGER (Lisp_Object obj, int n)
1846{
1847 eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER);
1848 return XSAVE_VALUE (obj)->data[n].integer;
1849}
1850LISP_INLINE void
1851set_save_integer (Lisp_Object obj, int n, ptrdiff_t val)
1852{
1853 eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER);
1854 XSAVE_VALUE (obj)->data[n].integer = val;
1855}
1856
1857/* Extract Nth saved object. */
1858
1859LISP_INLINE Lisp_Object
1860XSAVE_OBJECT (Lisp_Object obj, int n)
1861{
1862 eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_OBJECT);
1863 return XSAVE_VALUE (obj)->data[n].object;
1864}
1801 1865
1802#define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x))) 1866#define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x)))
1803 1867
@@ -2136,12 +2200,24 @@ typedef jmp_buf sys_jmp_buf;
2136#endif 2200#endif
2137 2201
2138 2202
2203/* Elisp uses several stacks:
2204 - the C stack.
2205 - the bytecode stack: used internally by the bytecode interpreter.
2206 Allocated from the C stack.
2207 - The specpdl stack: keeps track of active unwind-protect and
2208 dynamic-let-bindings. Allocated from the `specpdl' array, a manually
2209 managed stack.
2210 - The catch stack: keeps track of active catch tags.
2211 Allocated on the C stack. This is where the setmp data is kept.
2212 - The handler stack: keeps track of active condition-case handlers.
2213 Allocated on the C stack. Every entry there also uses an entry in
2214 the catch stack. */
2215
2139/* Structure for recording Lisp call stack for backtrace purposes. */ 2216/* Structure for recording Lisp call stack for backtrace purposes. */
2140 2217
2141/* The special binding stack holds the outer values of variables while 2218/* The special binding stack holds the outer values of variables while
2142 they are bound by a function application or a let form, stores the 2219 they are bound by a function application or a let form, stores the
2143 code to be executed for Lisp unwind-protect forms, and stores the C 2220 code to be executed for unwind-protect forms.
2144 functions to be called for record_unwind_protect.
2145 2221
2146 If func is non-zero, undoing this binding applies func to old_value; 2222 If func is non-zero, undoing this binding applies func to old_value;
2147 This implements record_unwind_protect. 2223 This implements record_unwind_protect.
@@ -2154,32 +2230,82 @@ typedef jmp_buf sys_jmp_buf;
2154 which means having bound a local value while CURRENT-BUFFER was active. 2230 which means having bound a local value while CURRENT-BUFFER was active.
2155 If WHERE is nil this means we saw the default value when binding SYMBOL. 2231 If WHERE is nil this means we saw the default value when binding SYMBOL.
2156 WHERE being a buffer or frame means we saw a buffer-local or frame-local 2232 WHERE being a buffer or frame means we saw a buffer-local or frame-local
2157 value. Other values of WHERE mean an internal error. */ 2233 value. Other values of WHERE mean an internal error.
2234
2235 NOTE: The specbinding struct is defined here, because SPECPDL_INDEX is
2236 used all over the place, needs to be fast, and needs to know the size of
2237 struct specbinding. But only eval.c should access it. */
2158 2238
2159typedef Lisp_Object (*specbinding_func) (Lisp_Object); 2239typedef Lisp_Object (*specbinding_func) (Lisp_Object);
2160 2240
2241enum specbind_tag {
2242 SPECPDL_UNWIND, /* An unwind_protect function. */
2243 SPECPDL_BACKTRACE, /* An element of the backtrace. */
2244 SPECPDL_LET, /* A plain and simple dynamic let-binding. */
2245 /* Tags greater than SPECPDL_LET must be "subkinds" of LET. */
2246 SPECPDL_LET_LOCAL, /* A buffer-local let-binding. */
2247 SPECPDL_LET_DEFAULT /* A global binding for a localized var. */
2248};
2249
2161struct specbinding 2250struct specbinding
2162 { 2251 {
2163 Lisp_Object symbol, old_value; 2252 enum specbind_tag kind;
2164 specbinding_func func; 2253 union {
2165 /* Normally this is unused; but it is to the symbol's current 2254 struct {
2166 value when a thread is swapped out. */ 2255 Lisp_Object arg;
2167 Lisp_Object saved_value; 2256 specbinding_func func;
2257 } unwind;
2258 struct {
2259 /* `where' is not used in the case of SPECPDL_LET. */
2260 Lisp_Object symbol, old_value, where;
2261 /* Normally this is unused; but it is to the symbol's current
2262 value when a thread is swapped out. */
2263 Lisp_Object saved_value;
2264 } let;
2265 struct {
2266 Lisp_Object function;
2267 Lisp_Object *args;
2268 ptrdiff_t nargs : BITS_PER_PTRDIFF_T - 1;
2269 bool debug_on_exit : 1;
2270 } bt;
2271 } v;
2168 }; 2272 };
2169 2273
2170#define SPECPDL_INDEX() (specpdl_ptr - specpdl) 2274LISP_INLINE Lisp_Object specpdl_symbol (struct specbinding *pdl)
2275{ eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.symbol; }
2171 2276
2172struct backtrace 2277LISP_INLINE Lisp_Object specpdl_old_value (struct specbinding *pdl)
2173{ 2278{ eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.old_value; }
2174 struct backtrace *next; 2279
2175 Lisp_Object function; 2280LISP_INLINE Lisp_Object specpdl_saved_value (struct specbinding *pdl)
2176 Lisp_Object *args; /* Points to vector of args. */ 2281{ eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.saved_value; }
2177 ptrdiff_t nargs; /* Length of vector. */
2178 /* Nonzero means call value of debugger when done with this operation. */
2179 unsigned int debug_on_exit : 1;
2180};
2181 2282
2182extern struct backtrace *backtrace_list; 2283LISP_INLINE Lisp_Object specpdl_where (struct specbinding *pdl)
2284{ eassert (pdl->kind > SPECPDL_LET); return pdl->v.let.where; }
2285
2286LISP_INLINE Lisp_Object specpdl_arg (struct specbinding *pdl)
2287{ eassert (pdl->kind == SPECPDL_UNWIND); return pdl->v.unwind.arg; }
2288
2289LISP_INLINE specbinding_func specpdl_func (struct specbinding *pdl)
2290{ eassert (pdl->kind == SPECPDL_UNWIND); return pdl->v.unwind.func; }
2291
2292LISP_INLINE Lisp_Object backtrace_function (struct specbinding *pdl)
2293{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.function; }
2294
2295LISP_INLINE ptrdiff_t backtrace_nargs (struct specbinding *pdl)
2296{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.nargs; }
2297
2298LISP_INLINE Lisp_Object *backtrace_args (struct specbinding *pdl)
2299{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.args; }
2300
2301LISP_INLINE bool backtrace_debug_on_exit (struct specbinding *pdl)
2302{ eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.debug_on_exit; }
2303
2304/* extern struct specbinding *specpdl; */
2305/* extern struct specbinding *specpdl_ptr; */
2306/* extern ptrdiff_t specpdl_size; */
2307
2308#define SPECPDL_INDEX() (specpdl_ptr - specpdl)
2183 2309
2184/* Everything needed to describe an active condition case. 2310/* Everything needed to describe an active condition case.
2185 2311
@@ -2235,9 +2361,10 @@ struct catchtag
2235 Lisp_Object tag; 2361 Lisp_Object tag;
2236 Lisp_Object volatile val; 2362 Lisp_Object volatile val;
2237 struct catchtag *volatile next; 2363 struct catchtag *volatile next;
2364#if 1 /* GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS, but they're defined later. */
2238 struct gcpro *gcpro; 2365 struct gcpro *gcpro;
2366#endif
2239 sys_jmp_buf jmp; 2367 sys_jmp_buf jmp;
2240 struct backtrace *backlist;
2241 struct handler *f_handlerlist; 2368 struct handler *f_handlerlist;
2242 EMACS_INT f_lisp_eval_depth; 2369 EMACS_INT f_lisp_eval_depth;
2243 ptrdiff_t volatile pdlcount; 2370 ptrdiff_t volatile pdlcount;
@@ -3122,7 +3249,7 @@ extern bool abort_on_gc;
3122extern Lisp_Object make_float (double); 3249extern Lisp_Object make_float (double);
3123extern void display_malloc_warning (void); 3250extern void display_malloc_warning (void);
3124extern ptrdiff_t inhibit_garbage_collection (void); 3251extern ptrdiff_t inhibit_garbage_collection (void);
3125extern Lisp_Object make_save_value (const char *, ...); 3252extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...);
3126extern Lisp_Object make_save_pointer (void *); 3253extern Lisp_Object make_save_pointer (void *);
3127extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 3254extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
3128extern void free_marker (Lisp_Object); 3255extern void free_marker (Lisp_Object);
@@ -3180,6 +3307,7 @@ extern Lisp_Object internal_with_output_to_temp_buffer
3180 (const char *, Lisp_Object (*) (Lisp_Object), Lisp_Object); 3307 (const char *, Lisp_Object (*) (Lisp_Object), Lisp_Object);
3181enum FLOAT_TO_STRING_BUFSIZE { FLOAT_TO_STRING_BUFSIZE = 350 }; 3308enum FLOAT_TO_STRING_BUFSIZE { FLOAT_TO_STRING_BUFSIZE = 350 };
3182extern int float_to_string (char *, double); 3309extern int float_to_string (char *, double);
3310extern void init_print_once (void);
3183extern void syms_of_print (void); 3311extern void syms_of_print (void);
3184 3312
3185/* Defined in doprnt.c. */ 3313/* Defined in doprnt.c. */
@@ -3294,6 +3422,14 @@ extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
3294extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object); 3422extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
3295extern void init_eval (void); 3423extern void init_eval (void);
3296extern void syms_of_eval (void); 3424extern void syms_of_eval (void);
3425extern void record_in_backtrace (Lisp_Object function,
3426 Lisp_Object *args, ptrdiff_t nargs);
3427extern void mark_specpdl (struct specbinding *first, struct specbinding *ptr);
3428extern void get_backtrace (Lisp_Object array);
3429Lisp_Object backtrace_top_function (void);
3430extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
3431extern bool let_shadows_global_binding_p (Lisp_Object symbol);
3432
3297 3433
3298/* Defined in thread.c. */ 3434/* Defined in thread.c. */
3299extern void mark_threads (void); 3435extern void mark_threads (void);
@@ -3464,7 +3600,7 @@ extern Lisp_Object Qvisible;
3464extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object); 3600extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object);
3465extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object); 3601extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
3466extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object); 3602extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
3467#if HAVE_NS 3603#if HAVE_NS || defined(WINDOWSNT)
3468extern Lisp_Object get_frame_param (struct frame *, Lisp_Object); 3604extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
3469#endif 3605#endif
3470extern void frames_discard_buffer (Lisp_Object); 3606extern void frames_discard_buffer (Lisp_Object);
@@ -3678,9 +3814,9 @@ extern void syms_of_fontset (void);
3678extern Lisp_Object Qfont_param; 3814extern Lisp_Object Qfont_param;
3679#endif 3815#endif
3680 3816
3681#ifdef WINDOWSNT 3817/* Defined in gfilenotify.c */
3682/* Defined on w32notify.c. */ 3818#ifdef HAVE_GFILENOTIFY
3683extern void syms_of_w32notify (void); 3819extern void syms_of_gfilenotify (void);
3684#endif 3820#endif
3685 3821
3686/* Defined in inotify.c */ 3822/* Defined in inotify.c */
@@ -3688,6 +3824,11 @@ extern void syms_of_w32notify (void);
3688extern void syms_of_inotify (void); 3824extern void syms_of_inotify (void);
3689#endif 3825#endif
3690 3826
3827#ifdef HAVE_W32NOTIFY
3828/* Defined on w32notify.c. */
3829extern void syms_of_w32notify (void);
3830#endif
3831
3691/* Defined in xfaces.c. */ 3832/* Defined in xfaces.c. */
3692extern Lisp_Object Qdefault, Qtool_bar, Qfringe; 3833extern Lisp_Object Qdefault, Qtool_bar, Qfringe;
3693extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; 3834extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
@@ -3728,11 +3869,6 @@ extern void syms_of_xml (void);
3728extern void xml_cleanup_parser (void); 3869extern void xml_cleanup_parser (void);
3729#endif 3870#endif
3730 3871
3731#ifdef HAVE_MENUS
3732/* Defined in (x|w32)fns.c, nsfns.m... */
3733extern int have_menus_p (void);
3734#endif
3735
3736#ifdef HAVE_DBUS 3872#ifdef HAVE_DBUS
3737/* Defined in dbusbind.c. */ 3873/* Defined in dbusbind.c. */
3738void syms_of_dbusbind (void); 3874void syms_of_dbusbind (void);
@@ -3840,8 +3976,7 @@ extern void *record_xmalloc (size_t);
3840 { \ 3976 { \
3841 Lisp_Object arg_; \ 3977 Lisp_Object arg_; \
3842 buf = xmalloc ((nelt) * word_size); \ 3978 buf = xmalloc ((nelt) * word_size); \
3843 arg_ = make_save_value ("pi", buf, nelt); \ 3979 arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \
3844 XSAVE_VALUE (arg_)->area = 1; \
3845 sa_must_free = 1; \ 3980 sa_must_free = 1; \
3846 record_unwind_protect (safe_alloca_unwind, arg_); \ 3981 record_unwind_protect (safe_alloca_unwind, arg_); \
3847 } \ 3982 } \
diff --git a/src/lread.c b/src/lread.c
index f8ab03af218..3ca644bb45b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -201,6 +201,9 @@ readchar (Lisp_Object readcharfun, bool *multibyte)
201 201
202 ptrdiff_t pt_byte = BUF_PT_BYTE (inbuffer); 202 ptrdiff_t pt_byte = BUF_PT_BYTE (inbuffer);
203 203
204 if (! BUFFER_LIVE_P (inbuffer))
205 return -1;
206
204 if (pt_byte >= BUF_ZV_BYTE (inbuffer)) 207 if (pt_byte >= BUF_ZV_BYTE (inbuffer))
205 return -1; 208 return -1;
206 209
@@ -375,6 +378,19 @@ skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n)
375 } 378 }
376} 379}
377 380
381static void
382skip_dyn_eof (Lisp_Object readcharfun)
383{
384 if (FROM_FILE_P (readcharfun))
385 {
386 block_input (); /* FIXME: Not sure if it's needed. */
387 fseek (instream, 0, SEEK_END);
388 unblock_input ();
389 }
390 else
391 while (READCHAR >= 0);
392}
393
378/* Unread the character C in the way appropriate for the stream READCHARFUN. 394/* Unread the character C in the way appropriate for the stream READCHARFUN.
379 If the stream is a user function, call it with the char as argument. */ 395 If the stream is a user function, call it with the char as argument. */
380 396
@@ -1571,7 +1587,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1571 { 1587 {
1572 struct stat st; 1588 struct stat st;
1573 fd = emacs_open (pfn, O_RDONLY, 0); 1589 fd = emacs_open (pfn, O_RDONLY, 0);
1574 if (0 <= fd 1590 if (fd >= 0
1575 && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode))) 1591 && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode)))
1576 { 1592 {
1577 emacs_close (fd); 1593 emacs_close (fd);
@@ -1976,7 +1992,9 @@ STREAM or the value of `standard-input' may be:
1976 if (EQ (stream, Qt)) 1992 if (EQ (stream, Qt))
1977 stream = Qread_char; 1993 stream = Qread_char;
1978 if (EQ (stream, Qread_char)) 1994 if (EQ (stream, Qread_char))
1979 return Fread_minibuffer (build_string ("Lisp expression: "), Qnil); 1995 /* FIXME: ¿¡ When is this used !? */
1996 return call1 (intern ("read-minibuffer"),
1997 build_string ("Lisp expression: "));
1980 1998
1981 return read_internal_start (stream, Qnil, Qnil); 1999 return read_internal_start (stream, Qnil, Qnil);
1982} 2000}
@@ -2359,7 +2377,7 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
2359 while (c == '0'); 2377 while (c == '0');
2360 } 2378 }
2361 2379
2362 while (-1 <= (digit = digit_to_number (c, radix))) 2380 while ((digit = digit_to_number (c, radix)) >= -1)
2363 { 2381 {
2364 if (digit == -1) 2382 if (digit == -1)
2365 valid = 0; 2383 valid = 0;
@@ -2617,7 +2635,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2617 if (c == '@') 2635 if (c == '@')
2618 { 2636 {
2619 enum { extra = 100 }; 2637 enum { extra = 100 };
2620 ptrdiff_t i, nskip = 0; 2638 ptrdiff_t i, nskip = 0, digits = 0;
2621 2639
2622 /* Read a decimal integer. */ 2640 /* Read a decimal integer. */
2623 while ((c = READCHAR) >= 0 2641 while ((c = READCHAR) >= 0
@@ -2625,8 +2643,14 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2625 { 2643 {
2626 if ((STRING_BYTES_BOUND - extra) / 10 <= nskip) 2644 if ((STRING_BYTES_BOUND - extra) / 10 <= nskip)
2627 string_overflow (); 2645 string_overflow ();
2646 digits++;
2628 nskip *= 10; 2647 nskip *= 10;
2629 nskip += c - '0'; 2648 nskip += c - '0';
2649 if (digits == 2 && nskip == 0)
2650 { /* We've just seen #@00, which means "skip to end". */
2651 skip_dyn_eof (readcharfun);
2652 return Qnil;
2653 }
2630 } 2654 }
2631 if (nskip > 0) 2655 if (nskip > 0)
2632 /* We can't use UNREAD here, because in the code below we side-step 2656 /* We can't use UNREAD here, because in the code below we side-step
@@ -2636,7 +2660,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2636 nskip--; 2660 nskip--;
2637 else 2661 else
2638 UNREAD (c); 2662 UNREAD (c);
2639 2663
2640 if (load_force_doc_strings 2664 if (load_force_doc_strings
2641 && (FROM_FILE_P (readcharfun))) 2665 && (FROM_FILE_P (readcharfun)))
2642 { 2666 {
@@ -3298,12 +3322,12 @@ string_to_number (char const *string, int base, bool ignore_trailing)
3298 state = 0; 3322 state = 0;
3299 3323
3300 leading_digit = digit_to_number (*cp, base); 3324 leading_digit = digit_to_number (*cp, base);
3301 if (0 <= leading_digit) 3325 if (leading_digit >= 0)
3302 { 3326 {
3303 state |= LEAD_INT; 3327 state |= LEAD_INT;
3304 do 3328 do
3305 ++cp; 3329 ++cp;
3306 while (0 <= digit_to_number (*cp, base)); 3330 while (digit_to_number (*cp, base) >= 0);
3307 } 3331 }
3308 if (*cp == '.') 3332 if (*cp == '.')
3309 { 3333 {
@@ -3380,7 +3404,7 @@ string_to_number (char const *string, int base, bool ignore_trailing)
3380 3404
3381 /* If the number uses integer and not float syntax, and is in C-language 3405 /* If the number uses integer and not float syntax, and is in C-language
3382 range, use its value, preferably as a fixnum. */ 3406 range, use its value, preferably as a fixnum. */
3383 if (0 <= leading_digit && ! float_syntax) 3407 if (leading_digit >= 0 && ! float_syntax)
3384 { 3408 {
3385 uintmax_t n; 3409 uintmax_t n;
3386 3410
@@ -3533,7 +3557,7 @@ read_list (bool flag, Lisp_Object readcharfun)
3533 { 3557 {
3534 if (NILP (Vdoc_file_name)) 3558 if (NILP (Vdoc_file_name))
3535 /* We have not yet called Snarf-documentation, so assume 3559 /* We have not yet called Snarf-documentation, so assume
3536 this file is described in the DOC-MM.NN file 3560 this file is described in the DOC file
3537 and Snarf-documentation will fill in the right value later. 3561 and Snarf-documentation will fill in the right value later.
3538 For now, replace the whole list with 0. */ 3562 For now, replace the whole list with 0. */
3539 doc_reference = 1; 3563 doc_reference = 1;
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 93f12900dde..272b053ed12 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -41,7 +41,7 @@ TRES = $(BLD)/emacs.res
41TLASTLIB = $(BLD)/lastfile.$(A) 41TLASTLIB = $(BLD)/lastfile.$(A)
42GNULIB = ../lib/$(BLD)/libgnu.$(A) 42GNULIB = ../lib/$(BLD)/libgnu.$(A)
43 43
44DOC = $(OBJDIR)/etc/DOC-X 44DOC = $(OBJDIR)/etc/DOC
45 45
46FULL_LINK_FLAGS = $(LINK_FLAGS) $(TEMACS_EXTRA_LINK) 46FULL_LINK_FLAGS = $(LINK_FLAGS) $(TEMACS_EXTRA_LINK)
47 47
@@ -388,6 +388,9 @@ EMACS_ROOT = ..
388GNU_LIB = $(EMACS_ROOT)/lib 388GNU_LIB = $(EMACS_ROOT)/lib
389NT_INC = $(EMACS_ROOT)/nt/inc 389NT_INC = $(EMACS_ROOT)/nt/inc
390 390
391ACL_H = $(GNU_LIB)/acl.h \
392 $(NT_INC)/sys/stat.h \
393 $(NT_INC)/stdbool.h
391SYSTIME_H = $(SRC)/systime.h \ 394SYSTIME_H = $(SRC)/systime.h \
392 $(NT_INC)/sys/time.h \ 395 $(NT_INC)/sys/time.h \
393 $(GNU_LIB)/timespec.h 396 $(GNU_LIB)/timespec.h
@@ -848,6 +851,7 @@ $(BLD)/fileio.$(O) : \
848 $(NT_INC)/sys/stat.h \ 851 $(NT_INC)/sys/stat.h \
849 $(NT_INC)/unistd.h \ 852 $(NT_INC)/unistd.h \
850 $(GNU_LIB)/allocator.h \ 853 $(GNU_LIB)/allocator.h \
854 $(ACL_H) \
851 $(BUFFER_H) \ 855 $(BUFFER_H) \
852 $(CAREADLINKAT_H) \ 856 $(CAREADLINKAT_H) \
853 $(CHARACTER_H) \ 857 $(CHARACTER_H) \
@@ -873,6 +877,7 @@ $(BLD)/filelock.$(O) : \
873 $(CHARACTER_H) \ 877 $(CHARACTER_H) \
874 $(CODING_H) \ 878 $(CODING_H) \
875 $(CONFIG_H) \ 879 $(CONFIG_H) \
880 $(C_CTYPE_H) \
876 $(LISP_H) \ 881 $(LISP_H) \
877 $(SYSTIME_H) 882 $(SYSTIME_H)
878 883
@@ -1398,6 +1403,7 @@ $(BLD)/sysdep.$(O) : \
1398 $(NT_INC)/netdb.h \ 1403 $(NT_INC)/netdb.h \
1399 $(NT_INC)/pwd.h \ 1404 $(NT_INC)/pwd.h \
1400 $(NT_INC)/sys/file.h \ 1405 $(NT_INC)/sys/file.h \
1406 $(NT_INC)/sys/param.h \
1401 $(NT_INC)/sys/stat.h \ 1407 $(NT_INC)/sys/stat.h \
1402 $(NT_INC)/unistd.h \ 1408 $(NT_INC)/unistd.h \
1403 $(GNU_LIB)/execinfo.h \ 1409 $(GNU_LIB)/execinfo.h \
diff --git a/src/menu.c b/src/menu.c
index fdef54dd657..58558d5aedd 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -173,7 +173,7 @@ static void
173ensure_menu_items (int items) 173ensure_menu_items (int items)
174{ 174{
175 int incr = items - (menu_items_allocated - menu_items_used); 175 int incr = items - (menu_items_allocated - menu_items_used);
176 if (0 < incr) 176 if (incr > 0)
177 { 177 {
178 menu_items = larger_vector (menu_items, incr, INT_MAX); 178 menu_items = larger_vector (menu_items, incr, INT_MAX);
179 menu_items_allocated = ASIZE (menu_items); 179 menu_items_allocated = ASIZE (menu_items);
@@ -1085,7 +1085,8 @@ no quit occurs and `x-popup-menu' returns nil. */)
1085#ifdef HAVE_MENUS 1085#ifdef HAVE_MENUS
1086 { 1086 {
1087 bool get_current_pos_p = 0; 1087 bool get_current_pos_p = 0;
1088 /* FIXME!! check_w32 (); or check_x (); or check_ns (); */ 1088
1089 check_window_system (SELECTED_FRAME ());
1089 1090
1090 /* Decode the first argument: find the window and the coordinates. */ 1091 /* Decode the first argument: find the window and the coordinates. */
1091 if (EQ (position, Qt) 1092 if (EQ (position, Qt)
diff --git a/src/minibuf.c b/src/minibuf.c
index 25425cb97dc..b69a16eff42 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -114,7 +114,7 @@ choose_minibuf_frame (void)
114 /* Under X, we come here with minibuf_window being the 114 /* Under X, we come here with minibuf_window being the
115 minibuffer window of the unused termcap window created in 115 minibuffer window of the unused termcap window created in
116 init_window_once. That window doesn't have a buffer. */ 116 init_window_once. That window doesn't have a buffer. */
117 buffer = XWINDOW (minibuf_window)->buffer; 117 buffer = XWINDOW (minibuf_window)->contents;
118 if (BUFFERP (buffer)) 118 if (BUFFERP (buffer))
119 /* Use set_window_buffer instead of Fset_window_buffer (see 119 /* Use set_window_buffer instead of Fset_window_buffer (see
120 discussion of bug#11984, bug#12025, bug#12026). */ 120 discussion of bug#11984, bug#12025, bug#12026). */
@@ -844,7 +844,7 @@ read_minibuf_unwind (Lisp_Object data)
844 window = minibuf_window; 844 window = minibuf_window;
845 /* To keep things predictable, in case it matters, let's be in the 845 /* To keep things predictable, in case it matters, let's be in the
846 minibuffer when we reset the relevant variables. */ 846 minibuffer when we reset the relevant variables. */
847 Fset_buffer (XWINDOW (window)->buffer); 847 Fset_buffer (XWINDOW (window)->contents);
848 848
849 /* Restore prompt, etc, from outer minibuffer level. */ 849 /* Restore prompt, etc, from outer minibuffer level. */
850 minibuf_prompt = Fcar (minibuf_save_list); 850 minibuf_prompt = Fcar (minibuf_save_list);
@@ -986,34 +986,6 @@ and some related functions, which use zero-indexing for POSITION. */)
986 return val; 986 return val;
987} 987}
988 988
989DEFUN ("read-minibuffer", Fread_minibuffer, Sread_minibuffer, 1, 2, 0,
990 doc: /* Return a Lisp object read using the minibuffer, unevaluated.
991Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
992is a string to insert in the minibuffer before reading.
993\(INITIAL-CONTENTS can also be a cons of a string and an integer.
994Such arguments are used as in `read-from-minibuffer'.) */)
995 (Lisp_Object prompt, Lisp_Object initial_contents)
996{
997 CHECK_STRING (prompt);
998 return read_minibuf (Vminibuffer_local_map, initial_contents,
999 prompt, 1, Qminibuffer_history,
1000 make_number (0), Qnil, 0, 0);
1001}
1002
1003DEFUN ("eval-minibuffer", Feval_minibuffer, Seval_minibuffer, 1, 2, 0,
1004 doc: /* Return value of Lisp expression read using the minibuffer.
1005Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
1006is a string to insert in the minibuffer before reading.
1007\(INITIAL-CONTENTS can also be a cons of a string and an integer.
1008Such arguments are used as in `read-from-minibuffer'.) */)
1009 (Lisp_Object prompt, Lisp_Object initial_contents)
1010{
1011 return Feval (read_minibuf (Vread_expression_map, initial_contents,
1012 prompt, 1, Qread_expression_history,
1013 make_number (0), Qnil, 0, 0),
1014 Qnil);
1015}
1016
1017/* Functions that use the minibuffer to read various things. */ 989/* Functions that use the minibuffer to read various things. */
1018 990
1019DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0, 991DEFUN ("read-string", Fread_string, Sread_string, 1, 5, 0,
@@ -1799,18 +1771,22 @@ the values STRING, PREDICATE and `lambda'. */)
1799 else if (HASH_TABLE_P (collection)) 1771 else if (HASH_TABLE_P (collection))
1800 { 1772 {
1801 struct Lisp_Hash_Table *h = XHASH_TABLE (collection); 1773 struct Lisp_Hash_Table *h = XHASH_TABLE (collection);
1774 Lisp_Object key = Qnil;
1802 i = hash_lookup (h, string, NULL); 1775 i = hash_lookup (h, string, NULL);
1803 if (i >= 0) 1776 if (i >= 0)
1804 tem = HASH_KEY (h, i); 1777 tem = HASH_KEY (h, i);
1805 else 1778 else
1806 for (i = 0; i < HASH_TABLE_SIZE (h); ++i) 1779 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
1807 if (!NILP (HASH_HASH (h, i)) 1780 if (!NILP (HASH_HASH (h, i))
1781 && (key = HASH_KEY (h, i),
1782 SYMBOLP (key) ? key = Fsymbol_name (key) : key,
1783 STRINGP (key))
1808 && EQ (Fcompare_strings (string, make_number (0), Qnil, 1784 && EQ (Fcompare_strings (string, make_number (0), Qnil,
1809 HASH_KEY (h, i), make_number (0) , Qnil, 1785 key, make_number (0) , Qnil,
1810 completion_ignore_case ? Qt : Qnil), 1786 completion_ignore_case ? Qt : Qnil),
1811 Qt)) 1787 Qt))
1812 { 1788 {
1813 tem = HASH_KEY (h, i); 1789 tem = key;
1814 break; 1790 break;
1815 } 1791 }
1816 if (!STRINGP (tem)) 1792 if (!STRINGP (tem))
@@ -2133,15 +2109,9 @@ properties. */);
2133 Vminibuffer_prompt_properties 2109 Vminibuffer_prompt_properties
2134 = Fcons (intern_c_string ("read-only"), Fcons (Qt, Qnil)); 2110 = Fcons (intern_c_string ("read-only"), Fcons (Qt, Qnil));
2135 2111
2136 DEFVAR_LISP ("read-expression-map", Vread_expression_map,
2137 doc: /* Minibuffer keymap used for reading Lisp expressions. */);
2138 Vread_expression_map = Qnil;
2139
2140 defsubr (&Sactive_minibuffer_window); 2112 defsubr (&Sactive_minibuffer_window);
2141 defsubr (&Sset_minibuffer_window); 2113 defsubr (&Sset_minibuffer_window);
2142 defsubr (&Sread_from_minibuffer); 2114 defsubr (&Sread_from_minibuffer);
2143 defsubr (&Seval_minibuffer);
2144 defsubr (&Sread_minibuffer);
2145 defsubr (&Sread_string); 2115 defsubr (&Sread_string);
2146 defsubr (&Sread_command); 2116 defsubr (&Sread_command);
2147 defsubr (&Sread_variable); 2117 defsubr (&Sread_variable);
diff --git a/src/msdos.c b/src/msdos.c
index ee47109d5f2..a2bcc06ac17 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -1261,7 +1261,7 @@ IT_update_begin (struct frame *f)
1261 /* If the mouse highlight is in the window that was deleted 1261 /* If the mouse highlight is in the window that was deleted
1262 (e.g., if it was popped by completion), clear highlight 1262 (e.g., if it was popped by completion), clear highlight
1263 unconditionally. */ 1263 unconditionally. */
1264 if (NILP (w->buffer)) 1264 if (NILP (w->contents))
1265 hlinfo->mouse_face_window = Qnil; 1265 hlinfo->mouse_face_window = Qnil;
1266 else 1266 else
1267 { 1267 {
@@ -1271,7 +1271,7 @@ IT_update_begin (struct frame *f)
1271 break; 1271 break;
1272 } 1272 }
1273 1273
1274 if (NILP (w->buffer) || i < w->desired_matrix->nrows) 1274 if (NILP (w->contents) || i < w->desired_matrix->nrows)
1275 clear_mouse_face (hlinfo); 1275 clear_mouse_face (hlinfo);
1276 } 1276 }
1277 } 1277 }
@@ -1321,7 +1321,7 @@ IT_frame_up_to_date (struct frame *f)
1321 new_cursor = frame_desired_cursor; 1321 new_cursor = frame_desired_cursor;
1322 else 1322 else
1323 { 1323 {
1324 struct buffer *b = XBUFFER (sw->buffer); 1324 struct buffer *b = XBUFFER (sw->contents);
1325 1325
1326 if (EQ (BVAR (b,cursor_type), Qt)) 1326 if (EQ (BVAR (b,cursor_type), Qt))
1327 new_cursor = frame_desired_cursor; 1327 new_cursor = frame_desired_cursor;
@@ -1920,7 +1920,7 @@ dos_get_saved_screen (char **screen, int *rows, int *cols)
1920 1920
1921/* We are not X, but we can emulate it well enough for our needs... */ 1921/* We are not X, but we can emulate it well enough for our needs... */
1922void 1922void
1923check_x (void) 1923check_window_system (void)
1924{ 1924{
1925 if (! FRAME_MSDOS_P (SELECTED_FRAME ())) 1925 if (! FRAME_MSDOS_P (SELECTED_FRAME ()))
1926 error ("Not running under a window system"); 1926 error ("Not running under a window system");
@@ -2983,11 +2983,6 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
2983 2983
2984/* --------------------------- X Menu emulation ---------------------- */ 2984/* --------------------------- X Menu emulation ---------------------- */
2985 2985
2986/* Report availability of menus. */
2987
2988int
2989have_menus_p (void) { return 1; }
2990
2991/* Create a brand new menu structure. */ 2986/* Create a brand new menu structure. */
2992 2987
2993XMenu * 2988XMenu *
diff --git a/src/nsfns.m b/src/nsfns.m
index ef18acaa045..94339183159 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -44,6 +44,10 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
44#include "fontset.h" 44#include "fontset.h"
45#include "font.h" 45#include "font.h"
46 46
47#ifdef NS_IMPL_COCOA
48#include <IOKit/graphics/IOGraphicsLib.h>
49#endif
50
47#if 0 51#if 0
48int fns_trace_num = 1; 52int fns_trace_num = 1;
49#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \ 53#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
@@ -88,7 +92,7 @@ Lisp_Object Qfontsize;
88/* hack for OS X file panels */ 92/* hack for OS X file panels */
89char panelOK = 0; 93char panelOK = 0;
90 94
91EmacsTooltip *ns_tooltip; 95EmacsTooltip *ns_tooltip = nil;
92 96
93/* Need forward declaration here to preserve organizational integrity of file */ 97/* Need forward declaration here to preserve organizational integrity of file */
94Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object); 98Lisp_Object Fx_open_connection (Lisp_Object, Lisp_Object, Lisp_Object);
@@ -101,87 +105,52 @@ static int as_status;
101static ptrdiff_t image_cache_refcount; 105static ptrdiff_t image_cache_refcount;
102#endif 106#endif
103 107
108
104/* ========================================================================== 109/* ==========================================================================
105 110
106 Internal utility functions 111 Internal utility functions
107 112
108 ========================================================================== */ 113 ========================================================================== */
109 114
115/* Let the user specify a Nextstep display with a Lisp object.
116 OBJECT may be nil, a frame or a terminal object.
117 nil stands for the selected frame--or, if that is not a Nextstep frame,
118 the first Nextstep display on the list. */
110 119
111void 120static struct ns_display_info *
112check_ns (void) 121check_ns_display_info (Lisp_Object object)
113{
114 if (NSApp == nil)
115 error ("OpenStep is not in use or not initialized");
116}
117
118
119/* Nonzero if we can use mouse menus. */
120int
121have_menus_p (void)
122{
123 return NSApp != nil;
124}
125
126
127/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
128 and checking validity for NS. */
129static FRAME_PTR
130check_ns_frame (Lisp_Object frame)
131{ 122{
132 FRAME_PTR f; 123 struct ns_display_info *dpyinfo = NULL;
133 124
134 if (NILP (frame)) 125 if (NILP (object))
135 f = SELECTED_FRAME ();
136 else
137 { 126 {
138 CHECK_LIVE_FRAME (frame); 127 struct frame *sf = XFRAME (selected_frame);
139 f = XFRAME (frame);
140 }
141 if (! FRAME_NS_P (f))
142 error ("non-Nextstep frame used");
143 return f;
144}
145
146 128
147/* Let the user specify an Nextstep display with a frame. 129 if (FRAME_NS_P (sf) && FRAME_LIVE_P (sf))
148 nil stands for the selected frame--or, if that is not an Nextstep frame, 130 dpyinfo = FRAME_NS_DISPLAY_INFO (sf);
149 the first Nextstep display on the list. */
150static struct ns_display_info *
151check_ns_display_info (Lisp_Object frame)
152{
153 if (NILP (frame))
154 {
155 struct frame *f = SELECTED_FRAME ();
156 if (FRAME_NS_P (f) && FRAME_LIVE_P (f) )
157 return FRAME_NS_DISPLAY_INFO (f);
158 else if (x_display_list != 0) 131 else if (x_display_list != 0)
159 return x_display_list; 132 dpyinfo = x_display_list;
160 else 133 else
161 error ("Nextstep windows are not in use or not initialized"); 134 error ("Nextstep windows are not in use or not initialized");
162 } 135 }
163 else if (INTEGERP (frame)) 136 else if (TERMINALP (object))
164 { 137 {
165 struct terminal *t = get_terminal (frame, 1); 138 struct terminal *t = get_terminal (object, 1);
166 139
167 if (t->type != output_ns) 140 if (t->type != output_ns)
168 error ("Terminal %"pI"d is not a Nextstep display", XINT (frame)); 141 error ("Terminal %d is not a Nextstep display", t->id);
169 142
170 return t->display_info.ns; 143 dpyinfo = t->display_info.ns;
171 } 144 }
172 else if (STRINGP (frame)) 145 else if (STRINGP (object))
173 return ns_display_info_for_name (frame); 146 dpyinfo = ns_display_info_for_name (object);
174 else 147 else
175 { 148 {
176 FRAME_PTR f; 149 FRAME_PTR f = decode_window_system_frame (object);
177 150 dpyinfo = FRAME_NS_DISPLAY_INFO (f);
178 CHECK_LIVE_FRAME (frame);
179 f = XFRAME (frame);
180 if (! FRAME_NS_P (f))
181 error ("non-Nextstep frame used");
182 return FRAME_NS_DISPLAY_INFO (f);
183 } 151 }
184 return NULL; /* shut compiler up */ 152
153 return dpyinfo;
185} 154}
186 155
187 156
@@ -201,35 +170,6 @@ ns_get_window (Lisp_Object maybeFrame)
201} 170}
202 171
203 172
204static NSScreen *
205ns_get_screen (Lisp_Object screen)
206{
207 struct frame *f;
208 struct terminal *terminal;
209
210 if (EQ (Qt, screen)) /* not documented */
211 return [NSScreen mainScreen];
212
213 terminal = get_terminal (screen, 1);
214 if (terminal->type != output_ns)
215 return NULL;
216
217 if (NILP (screen))
218 f = SELECTED_FRAME ();
219 else if (FRAMEP (screen))
220 f = XFRAME (screen);
221 else
222 {
223 struct ns_display_info *dpyinfo = terminal->display_info.ns;
224 f = dpyinfo->x_focus_frame
225 ? dpyinfo->x_focus_frame : dpyinfo->x_highlight_frame;
226 }
227
228 return ((f && FRAME_NS_P (f)) ? [[FRAME_NS_VIEW (f) window] screen]
229 : NULL);
230}
231
232
233/* Return the X display structure for the display named NAME. 173/* Return the X display structure for the display named NAME.
234 Open a new connection if necessary. */ 174 Open a new connection if necessary. */
235struct ns_display_info * 175struct ns_display_info *
@@ -347,7 +287,7 @@ static void
347x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 287x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
348{ 288{
349 NSColor *col; 289 NSColor *col;
350 CGFloat r, g, b, alpha; 290 EmacsCGFloat r, g, b, alpha;
351 291
352 if (ns_lisp_to_color (arg, &col)) 292 if (ns_lisp_to_color (arg, &col))
353 { 293 {
@@ -379,7 +319,7 @@ x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
379 struct face *face; 319 struct face *face;
380 NSColor *col; 320 NSColor *col;
381 NSView *view = FRAME_NS_VIEW (f); 321 NSView *view = FRAME_NS_VIEW (f);
382 CGFloat r, g, b, alpha; 322 EmacsCGFloat r, g, b, alpha;
383 323
384 if (ns_lisp_to_color (arg, &col)) 324 if (ns_lisp_to_color (arg, &col))
385 { 325 {
@@ -404,7 +344,7 @@ x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
404 { 344 {
405 [[view window] setBackgroundColor: col]; 345 [[view window] setBackgroundColor: col];
406 346
407 if (alpha != 1.0) 347 if (alpha != (EmacsCGFloat) 1.0)
408 [[view window] setOpaque: NO]; 348 [[view window] setOpaque: NO];
409 else 349 else
410 [[view window] setOpaque: YES]; 350 [[view window] setOpaque: YES];
@@ -619,7 +559,7 @@ ns_set_name_as_filename (struct frame *f)
619{ 559{
620 NSView *view; 560 NSView *view;
621 Lisp_Object name, filename; 561 Lisp_Object name, filename;
622 Lisp_Object buf = XWINDOW (f->selected_window)->buffer; 562 Lisp_Object buf = XWINDOW (f->selected_window)->contents;
623 const char *title; 563 const char *title;
624 NSAutoreleasePool *pool; 564 NSAutoreleasePool *pool;
625 struct gcpro gcpro1; 565 struct gcpro gcpro1;
@@ -774,7 +714,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
774} 714}
775 715
776 716
777void 717static void
778ns_implicitly_set_icon_type (struct frame *f) 718ns_implicitly_set_icon_type (struct frame *f)
779{ 719{
780 Lisp_Object tem; 720 Lisp_Object tem;
@@ -919,7 +859,7 @@ ns_cursor_type_to_lisp (int arg)
919} 859}
920 860
921/* This is the same as the xfns.c definition. */ 861/* This is the same as the xfns.c definition. */
922void 862static void
923x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval) 863x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
924{ 864{
925 set_frame_cursor_types (f, arg); 865 set_frame_cursor_types (f, arg);
@@ -1142,11 +1082,8 @@ This function is an internal primitive--use `make-frame' instead. */)
1142 struct ns_display_info *dpyinfo = NULL; 1082 struct ns_display_info *dpyinfo = NULL;
1143 Lisp_Object parent; 1083 Lisp_Object parent;
1144 struct kboard *kb; 1084 struct kboard *kb;
1145 Lisp_Object tfont, tfontsize;
1146 static int desc_ctr = 1; 1085 static int desc_ctr = 1;
1147 1086
1148 check_ns ();
1149
1150 /* x_get_arg modifies parms. */ 1087 /* x_get_arg modifies parms. */
1151 parms = Fcopy_alist (parms); 1088 parms = Fcopy_alist (parms);
1152 1089
@@ -1243,9 +1180,6 @@ This function is an internal primitive--use `make-frame' instead. */)
1243 specbind (Qx_resource_name, name); 1180 specbind (Qx_resource_name, name);
1244 } 1181 }
1245 1182
1246 f->resx = dpyinfo->resx;
1247 f->resy = dpyinfo->resy;
1248
1249 block_input (); 1183 block_input ();
1250 register_font_driver (&nsfont_driver, f); 1184 register_font_driver (&nsfont_driver, f);
1251 x_default_parameter (f, parms, Qfont_backend, Qnil, 1185 x_default_parameter (f, parms, Qfont_backend, Qnil,
@@ -1254,10 +1188,10 @@ This function is an internal primitive--use `make-frame' instead. */)
1254 { 1188 {
1255 /* use for default font name */ 1189 /* use for default font name */
1256 id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */ 1190 id font = [NSFont userFixedPitchFontOfSize: -1.0]; /* default */
1257 tfontsize = x_default_parameter (f, parms, Qfontsize, 1191 x_default_parameter (f, parms, Qfontsize,
1258 make_number (0 /*(int)[font pointSize]*/), 1192 make_number (0 /*(int)[font pointSize]*/),
1259 "fontSize", "FontSize", RES_TYPE_NUMBER); 1193 "fontSize", "FontSize", RES_TYPE_NUMBER);
1260 tfont = x_default_parameter (f, parms, Qfont, 1194 x_default_parameter (f, parms, Qfont,
1261 build_string ([[font fontName] UTF8String]), 1195 build_string ([[font fontName] UTF8String]),
1262 "font", "Font", RES_TYPE_STRING); 1196 "font", "Font", RES_TYPE_STRING);
1263 } 1197 }
@@ -1421,7 +1355,7 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
1421FRAME nil means use the selected frame. */) 1355FRAME nil means use the selected frame. */)
1422 (Lisp_Object frame) 1356 (Lisp_Object frame)
1423{ 1357{
1424 struct frame *f = check_ns_frame (frame); 1358 struct frame *f = decode_window_system_frame (frame);
1425 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); 1359 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
1426 1360
1427 if (dpyinfo->x_focus_frame != f) 1361 if (dpyinfo->x_focus_frame != f)
@@ -1442,18 +1376,8 @@ DEFUN ("ns-popup-font-panel", Fns_popup_font_panel, Sns_popup_font_panel,
1442 doc: /* Pop up the font panel. */) 1376 doc: /* Pop up the font panel. */)
1443 (Lisp_Object frame) 1377 (Lisp_Object frame)
1444{ 1378{
1445 id fm; 1379 struct frame *f = decode_window_system_frame (frame);
1446 struct frame *f; 1380 id fm = [NSFontManager sharedFontManager];
1447
1448 check_ns ();
1449 fm = [NSFontManager sharedFontManager];
1450 if (NILP (frame))
1451 f = SELECTED_FRAME ();
1452 else
1453 {
1454 CHECK_FRAME (frame);
1455 f = XFRAME (frame);
1456 }
1457 1381
1458 [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont 1382 [fm setSelectedFont: ((struct nsfont_info *)f->output_data.ns->font)->nsfont
1459 isMultiple: NO]; 1383 isMultiple: NO];
@@ -1467,17 +1391,7 @@ DEFUN ("ns-popup-color-panel", Fns_popup_color_panel, Sns_popup_color_panel,
1467 doc: /* Pop up the color panel. */) 1391 doc: /* Pop up the color panel. */)
1468 (Lisp_Object frame) 1392 (Lisp_Object frame)
1469{ 1393{
1470 struct frame *f; 1394 check_window_system (NULL);
1471
1472 check_ns ();
1473 if (NILP (frame))
1474 f = SELECTED_FRAME ();
1475 else
1476 {
1477 CHECK_FRAME (frame);
1478 f = XFRAME (frame);
1479 }
1480
1481 [NSApp orderFrontColorPanel: NSApp]; 1395 [NSApp orderFrontColorPanel: NSApp];
1482 return Qnil; 1396 return Qnil;
1483} 1397}
@@ -1495,6 +1409,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1495{ 1409{
1496 static id fileDelegate = nil; 1410 static id fileDelegate = nil;
1497 BOOL ret; 1411 BOOL ret;
1412 BOOL isSave = NILP (mustmatch) && NILP (dir_only_p);
1498 id panel; 1413 id panel;
1499 Lisp_Object fname; 1414 Lisp_Object fname;
1500 1415
@@ -1506,7 +1421,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1506 NSString *initS = NILP (init) || !STRINGP (init) ? nil : 1421 NSString *initS = NILP (init) || !STRINGP (init) ? nil :
1507 [NSString stringWithUTF8String: SSDATA (init)]; 1422 [NSString stringWithUTF8String: SSDATA (init)];
1508 1423
1509 check_ns (); 1424 check_window_system (NULL);
1510 1425
1511 if (fileDelegate == nil) 1426 if (fileDelegate == nil)
1512 fileDelegate = [EmacsFileDelegate new]; 1427 fileDelegate = [EmacsFileDelegate new];
@@ -1516,7 +1431,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1516 if ([dirS characterAtIndex: 0] == '~') 1431 if ([dirS characterAtIndex: 0] == '~')
1517 dirS = [dirS stringByExpandingTildeInPath]; 1432 dirS = [dirS stringByExpandingTildeInPath];
1518 1433
1519 panel = NILP (mustmatch) && NILP (dir_only_p) ? 1434 panel = isSave ?
1520 (id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel]; 1435 (id)[EmacsSavePanel savePanel] : (id)[EmacsOpenPanel openPanel];
1521 1436
1522 [panel setTitle: promptS]; 1437 [panel setTitle: promptS];
@@ -1531,7 +1446,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1531 [panel setCanChooseDirectories: YES]; 1446 [panel setCanChooseDirectories: YES];
1532 [panel setCanChooseFiles: NO]; 1447 [panel setCanChooseFiles: NO];
1533 } 1448 }
1534 else 1449 else if (! isSave)
1535 { 1450 {
1536 /* This is not quite what the documentation says, but it is compatible 1451 /* This is not quite what the documentation says, but it is compatible
1537 with the Gtk+ code. Also, the menu entry says "Open File...". */ 1452 with the Gtk+ code. Also, the menu entry says "Open File...". */
@@ -1539,7 +1454,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1539 [panel setCanChooseFiles: YES]; 1454 [panel setCanChooseFiles: YES];
1540 } 1455 }
1541 1456
1542 block_input (); 1457 block_input ();
1543#if defined (NS_IMPL_COCOA) && \ 1458#if defined (NS_IMPL_COCOA) && \
1544 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 1459 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
1545 if (! NILP (mustmatch) || ! NILP (dir_only_p)) 1460 if (! NILP (mustmatch) || ! NILP (dir_only_p))
@@ -1564,10 +1479,10 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */)
1564 1479
1565 ret = (ret == NSOKButton) || panelOK; 1480 ret = (ret == NSOKButton) || panelOK;
1566 1481
1567 if (ret) 1482 if (ret)
1568 { 1483 {
1569 NSString *str = [panel getFilename]; 1484 NSString *str = ns_filename_from_panel (panel);
1570 if (! str) str = [panel getDirectory]; 1485 if (! str) str = ns_directory_from_panel (panel);
1571 if (! str) ret = NO; 1486 if (! str) ret = NO;
1572 else fname = build_string ([str UTF8String]); 1487 else fname = build_string ([str UTF8String]);
1573 } 1488 }
@@ -1597,11 +1512,10 @@ If OWNER is nil, Emacs is assumed. */)
1597{ 1512{
1598 const char *value; 1513 const char *value;
1599 1514
1600 check_ns (); 1515 check_window_system (NULL);
1601 if (NILP (owner)) 1516 if (NILP (owner))
1602 owner = build_string([ns_app_name UTF8String]); 1517 owner = build_string([ns_app_name UTF8String]);
1603 CHECK_STRING (name); 1518 CHECK_STRING (name);
1604/*fprintf (stderr, "ns-get-resource checking resource '%s'\n", SSDATA (name)); */
1605 1519
1606 value = ns_get_defaults_value (SSDATA (name)); 1520 value = ns_get_defaults_value (SSDATA (name));
1607 1521
@@ -1617,7 +1531,7 @@ If OWNER is nil, Emacs is assumed.
1617If VALUE is nil, the default is removed. */) 1531If VALUE is nil, the default is removed. */)
1618 (Lisp_Object owner, Lisp_Object name, Lisp_Object value) 1532 (Lisp_Object owner, Lisp_Object name, Lisp_Object value)
1619{ 1533{
1620 check_ns (); 1534 check_window_system (NULL);
1621 if (NILP (owner)) 1535 if (NILP (owner))
1622 owner = build_string ([ns_app_name UTF8String]); 1536 owner = build_string ([ns_app_name UTF8String]);
1623 CHECK_STRING (name); 1537 CHECK_STRING (name);
@@ -1643,9 +1557,9 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
1643 Sx_server_max_request_size, 1557 Sx_server_max_request_size,
1644 0, 1, 0, 1558 0, 1, 0,
1645 doc: /* This function is a no-op. It is only present for completeness. */) 1559 doc: /* This function is a no-op. It is only present for completeness. */)
1646 (Lisp_Object display) 1560 (Lisp_Object terminal)
1647{ 1561{
1648 check_ns (); 1562 check_ns_display_info (terminal);
1649 /* This function has no real equivalent under NeXTstep. Return nil to 1563 /* This function has no real equivalent under NeXTstep. Return nil to
1650 indicate this. */ 1564 indicate this. */
1651 return Qnil; 1565 return Qnil;
@@ -1653,11 +1567,15 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
1653 1567
1654 1568
1655DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0, 1569DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
1656 doc: /* Return the vendor ID string of Nextstep display server DISPLAY. 1570 doc: /* Return the "vendor ID" string of Nextstep display server TERMINAL.
1657DISPLAY should be either a frame or a display name (a string). 1571\(Labeling every distributor as a "vendor" embodies the false assumption
1658If omitted or nil, the selected frame's display is used. */) 1572that operating systems cannot be developed and distributed noncommercially.)
1659 (Lisp_Object display) 1573The optional argument TERMINAL specifies which display to ask about.
1574TERMINAL should be a terminal object, a frame or a display name (a string).
1575If omitted or nil, that stands for the selected frame's display. */)
1576 (Lisp_Object terminal)
1660{ 1577{
1578 check_ns_display_info (terminal);
1661#ifdef NS_IMPL_GNUSTEP 1579#ifdef NS_IMPL_GNUSTEP
1662 return build_string ("GNU"); 1580 return build_string ("GNU");
1663#else 1581#else
@@ -1667,16 +1585,17 @@ If omitted or nil, the selected frame's display is used. */)
1667 1585
1668 1586
1669DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0, 1587DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
1670 doc: /* Return the version numbers of the server of DISPLAY. 1588 doc: /* Return the version numbers of the server of display TERMINAL.
1671The value is a list of three integers: the major and minor 1589The value is a list of three integers: the major and minor
1672version numbers of the X Protocol in use, and the distributor-specific 1590version numbers of the X Protocol in use, and the distributor-specific release
1673release number. See also the function `x-server-vendor'. 1591number. See also the function `x-server-vendor'.
1674 1592
1675The optional argument DISPLAY specifies which display to ask about. 1593The optional argument TERMINAL specifies which display to ask about.
1676DISPLAY should be either a frame or a display name (a string). 1594TERMINAL should be a terminal object, a frame or a display name (a string).
1677If omitted or nil, that stands for the selected frame's display. */) 1595If omitted or nil, that stands for the selected frame's display. */)
1678 (Lisp_Object display) 1596 (Lisp_Object terminal)
1679{ 1597{
1598 check_ns_display_info (terminal);
1680 /*NOTE: it is unclear what would best correspond with "protocol"; 1599 /*NOTE: it is unclear what would best correspond with "protocol";
1681 we return 10.3, meaning Panther, since this is roughly the 1600 we return 10.3, meaning Panther, since this is roughly the
1682 level that GNUstep's APIs correspond to. 1601 level that GNUstep's APIs correspond to.
@@ -1688,56 +1607,66 @@ If omitted or nil, that stands for the selected frame's display. */)
1688 1607
1689 1608
1690DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0, 1609DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
1691 doc: /* Return the number of screens on Nextstep display server DISPLAY. 1610 doc: /* Return the number of screens on Nextstep display server TERMINAL.
1692DISPLAY should be a frame, the display name as a string, or a terminal ID. 1611The optional argument TERMINAL specifies which display to ask about.
1693If omitted or nil, the selected frame's display is used. */) 1612TERMINAL should be a terminal object, a frame or a display name (a string).
1694 (Lisp_Object display) 1613If omitted or nil, that stands for the selected frame's display.
1695{
1696 int num;
1697
1698 check_ns ();
1699 num = [[NSScreen screens] count];
1700 1614
1701 return (num != 0) ? make_number (num) : Qnil; 1615Note: "screen" here is not in Nextstep terminology but in X11's. For
1616the number of physical monitors, use `(length
1617(display-monitor-attributes-list TERMINAL))' instead. */)
1618 (Lisp_Object terminal)
1619{
1620 check_ns_display_info (terminal);
1621 return make_number (1);
1702} 1622}
1703 1623
1704 1624
1705DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 1625DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
1706 0, 1, 0, 1626 doc: /* Return the height in millimeters of the Nextstep display TERMINAL.
1707 doc: /* Return the height of Nextstep display server DISPLAY, in millimeters. 1627The optional argument TERMINAL specifies which display to ask about.
1708DISPLAY should be a frame, the display name as a string, or a terminal ID. 1628TERMINAL should be a terminal object, a frame or a display name (a string).
1709If omitted or nil, the selected frame's display is used. */) 1629If omitted or nil, that stands for the selected frame's display.
1710 (Lisp_Object display) 1630
1631On \"multi-monitor\" setups this refers to the height in millimeters for
1632all physical monitors associated with TERMINAL. To get information
1633for each physical monitor, use `display-monitor-attributes-list'. */)
1634 (Lisp_Object terminal)
1711{ 1635{
1712 check_ns (); 1636 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1713 return make_number ((int) 1637
1714 ([ns_get_screen (display) frame].size.height/(92.0/25.4))); 1638 return make_number (x_display_pixel_height (dpyinfo) / (92.0/25.4));
1715} 1639}
1716 1640
1717 1641
1718DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 1642DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
1719 0, 1, 0, 1643 doc: /* Return the width in millimeters of the Nextstep display TERMINAL.
1720 doc: /* Return the width of Nextstep display server DISPLAY, in millimeters. 1644The optional argument TERMINAL specifies which display to ask about.
1721DISPLAY should be a frame, the display name as a string, or a terminal ID. 1645TERMINAL should be a terminal object, a frame or a display name (a string).
1722If omitted or nil, the selected frame's display is used. */) 1646If omitted or nil, that stands for the selected frame's display.
1723 (Lisp_Object display) 1647
1648On \"multi-monitor\" setups this refers to the width in millimeters for
1649all physical monitors associated with TERMINAL. To get information
1650for each physical monitor, use `display-monitor-attributes-list'. */)
1651 (Lisp_Object terminal)
1724{ 1652{
1725 check_ns (); 1653 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
1726 return make_number ((int) 1654
1727 ([ns_get_screen (display) frame].size.width/(92.0/25.4))); 1655 return make_number (x_display_pixel_width (dpyinfo) / (92.0/25.4));
1728} 1656}
1729 1657
1730 1658
1731DEFUN ("x-display-backing-store", Fx_display_backing_store, 1659DEFUN ("x-display-backing-store", Fx_display_backing_store,
1732 Sx_display_backing_store, 0, 1, 0, 1660 Sx_display_backing_store, 0, 1, 0,
1733 doc: /* Return whether the Nextstep display DISPLAY supports backing store. 1661 doc: /* Return an indication of whether the Nextstep display TERMINAL does backing store.
1734The value may be `buffered', `retained', or `non-retained'. 1662The value may be `buffered', `retained', or `non-retained'.
1735DISPLAY should be a frame, the display name as a string, or a terminal ID. 1663The optional argument TERMINAL specifies which display to ask about.
1736If omitted or nil, the selected frame's display is used. */) 1664TERMINAL should be a terminal object, a frame or a display name (a string).
1737 (Lisp_Object display) 1665If omitted or nil, that stands for the selected frame's display. */)
1666 (Lisp_Object terminal)
1738{ 1667{
1739 check_ns (); 1668 check_ns_display_info (terminal);
1740 switch ([ns_get_window (display) backingType]) 1669 switch ([ns_get_window (terminal) backingType])
1741 { 1670 {
1742 case NSBackingStoreBuffered: 1671 case NSBackingStoreBuffered:
1743 return intern ("buffered"); 1672 return intern ("buffered");
@@ -1754,16 +1683,19 @@ If omitted or nil, the selected frame's display is used. */)
1754 1683
1755DEFUN ("x-display-visual-class", Fx_display_visual_class, 1684DEFUN ("x-display-visual-class", Fx_display_visual_class,
1756 Sx_display_visual_class, 0, 1, 0, 1685 Sx_display_visual_class, 0, 1, 0,
1757 doc: /* Return the visual class of the Nextstep display server DISPLAY. 1686 doc: /* Return the visual class of the Nextstep display TERMINAL.
1758The value is one of the symbols `static-gray', `gray-scale', 1687The value is one of the symbols `static-gray', `gray-scale',
1759`static-color', `pseudo-color', `true-color', or `direct-color'. 1688`static-color', `pseudo-color', `true-color', or `direct-color'.
1760DISPLAY should be a frame, the display name as a string, or a terminal ID. 1689
1761If omitted or nil, the selected frame's display is used. */) 1690The optional argument TERMINAL specifies which display to ask about.
1762 (Lisp_Object display) 1691TERMINAL should a terminal object, a frame or a display name (a string).
1692If omitted or nil, that stands for the selected frame's display. */)
1693 (Lisp_Object terminal)
1763{ 1694{
1764 NSWindowDepth depth; 1695 NSWindowDepth depth;
1765 check_ns (); 1696
1766 depth = [ns_get_screen (display) depth]; 1697 check_ns_display_info (terminal);
1698 depth = [[[NSScreen screens] objectAtIndex:0] depth];
1767 1699
1768 if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL)) 1700 if ( depth == NSBestDepth (NSCalibratedWhiteColorSpace, 2, 2, YES, NULL))
1769 return intern ("static-gray"); 1701 return intern ("static-gray");
@@ -1783,14 +1715,14 @@ If omitted or nil, the selected frame's display is used. */)
1783 1715
1784DEFUN ("x-display-save-under", Fx_display_save_under, 1716DEFUN ("x-display-save-under", Fx_display_save_under,
1785 Sx_display_save_under, 0, 1, 0, 1717 Sx_display_save_under, 0, 1, 0,
1786 doc: /* Return t if DISPLAY supports the save-under feature. 1718 doc: /* Return t if TERMINAL supports the save-under feature.
1787The optional argument DISPLAY specifies which display to ask about. 1719The optional argument TERMINAL specifies which display to ask about.
1788DISPLAY should be a frame, the display name as a string, or a terminal ID. 1720TERMINAL should be a terminal object, a frame or a display name (a string).
1789If omitted or nil, the selected frame's display is used. */) 1721If omitted or nil, that stands for the selected frame's display. */)
1790 (Lisp_Object display) 1722 (Lisp_Object terminal)
1791{ 1723{
1792 check_ns (); 1724 check_ns_display_info (terminal);
1793 switch ([ns_get_window (display) backingType]) 1725 switch ([ns_get_window (terminal) backingType])
1794 { 1726 {
1795 case NSBackingStoreBuffered: 1727 case NSBackingStoreBuffered:
1796 return Qt; 1728 return Qt;
@@ -1838,12 +1770,13 @@ terminate Emacs if we can't open the connection.
1838 1770
1839DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1771DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection,
1840 1, 1, 0, 1772 1, 1, 0,
1841 doc: /* Close the connection to the current Nextstep display server. 1773 doc: /* Close the connection to TERMINAL's Nextstep display server.
1842The argument DISPLAY is currently ignored. */) 1774For TERMINAL, specify a terminal object, a frame or a display name (a
1843 (Lisp_Object display) 1775string). If TERMINAL is nil, that stands for the selected frame's
1776terminal. */)
1777 (Lisp_Object terminal)
1844{ 1778{
1845 check_ns (); 1779 check_ns_display_info (terminal);
1846 /*ns_delete_terminal (dpyinfo->terminal); */
1847 [NSApp terminate: NSApp]; 1780 [NSApp terminate: NSApp];
1848 return Qnil; 1781 return Qnil;
1849} 1782}
@@ -1868,7 +1801,7 @@ DEFUN ("ns-hide-others", Fns_hide_others, Sns_hide_others,
1868 doc: /* Hides all applications other than Emacs. */) 1801 doc: /* Hides all applications other than Emacs. */)
1869 (void) 1802 (void)
1870{ 1803{
1871 check_ns (); 1804 check_window_system (NULL);
1872 [NSApp hideOtherApplications: NSApp]; 1805 [NSApp hideOtherApplications: NSApp];
1873 return Qnil; 1806 return Qnil;
1874} 1807}
@@ -1881,7 +1814,7 @@ If ON is equal to `activate', Emacs is unhidden and becomes
1881the active application. */) 1814the active application. */)
1882 (Lisp_Object on) 1815 (Lisp_Object on)
1883{ 1816{
1884 check_ns (); 1817 check_window_system (NULL);
1885 if (EQ (on, intern ("activate"))) 1818 if (EQ (on, intern ("activate")))
1886 { 1819 {
1887 [NSApp unhide: NSApp]; 1820 [NSApp unhide: NSApp];
@@ -1900,7 +1833,7 @@ DEFUN ("ns-emacs-info-panel", Fns_emacs_info_panel, Sns_emacs_info_panel,
1900 doc: /* Shows the 'Info' or 'About' panel for Emacs. */) 1833 doc: /* Shows the 'Info' or 'About' panel for Emacs. */)
1901 (void) 1834 (void)
1902{ 1835{
1903 check_ns (); 1836 check_window_system (NULL);
1904 [NSApp orderFrontStandardAboutPanel: nil]; 1837 [NSApp orderFrontStandardAboutPanel: nil];
1905 return Qnil; 1838 return Qnil;
1906} 1839}
@@ -1976,9 +1909,11 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
1976#else 1909#else
1977 Lisp_Object ret = Qnil; 1910 Lisp_Object ret = Qnil;
1978 NSMenu *svcs; 1911 NSMenu *svcs;
1912#ifdef NS_IMPL_COCOA
1979 id delegate; 1913 id delegate;
1914#endif
1980 1915
1981 check_ns (); 1916 check_window_system (NULL);
1982 svcs = [[NSMenu alloc] initWithTitle: @"Services"]; 1917 svcs = [[NSMenu alloc] initWithTitle: @"Services"];
1983 [NSApp setServicesMenu: svcs]; 1918 [NSApp setServicesMenu: svcs];
1984 [NSApp registerServicesMenuSendTypes: ns_send_types 1919 [NSApp registerServicesMenuSendTypes: ns_send_types
@@ -2031,7 +1966,7 @@ there was no result. */)
2031 char *utfStr; 1966 char *utfStr;
2032 1967
2033 CHECK_STRING (service); 1968 CHECK_STRING (service);
2034 check_ns (); 1969 check_window_system (NULL);
2035 1970
2036 utfStr = SSDATA (service); 1971 utfStr = SSDATA (service);
2037 svcName = [NSString stringWithUTF8String: utfStr]; 1972 svcName = [NSString stringWithUTF8String: utfStr];
@@ -2059,15 +1994,9 @@ DEFUN ("ns-convert-utf8-nfd-to-nfc", Fns_convert_utf8_nfd_to_nfc,
2059 1994
2060 CHECK_STRING (str); 1995 CHECK_STRING (str);
2061 utfStr = [NSString stringWithUTF8String: SSDATA (str)]; 1996 utfStr = [NSString stringWithUTF8String: SSDATA (str)];
2062 if (![utfStr respondsToSelector: 1997#ifdef NS_IMPL_COCOA
2063 @selector (precomposedStringWithCanonicalMapping)])
2064 {
2065 message1
2066 ("Warning: ns-convert-utf8-nfd-to-nfc unsupported under GNUstep.\n");
2067 return Qnil;
2068 }
2069 else
2070 utfStr = [utfStr precomposedStringWithCanonicalMapping]; 1998 utfStr = [utfStr precomposedStringWithCanonicalMapping];
1999#endif
2071 return build_string ([utfStr UTF8String]); 2000 return build_string ([utfStr UTF8String]);
2072} 2001}
2073 2002
@@ -2155,7 +2084,7 @@ In case the execution fails, an error is signaled. */)
2155 NSEvent *nxev; 2084 NSEvent *nxev;
2156 2085
2157 CHECK_STRING (script); 2086 CHECK_STRING (script);
2158 check_ns (); 2087 check_window_system (NULL);
2159 2088
2160 block_input (); 2089 block_input ();
2161 2090
@@ -2204,15 +2133,6 @@ In case the execution fails, an error is signaled. */)
2204 2133
2205 ========================================================================== */ 2134 ========================================================================== */
2206 2135
2207
2208/* called from image.c */
2209FRAME_PTR
2210check_x_frame (Lisp_Object frame)
2211{
2212 return check_ns_frame (frame);
2213}
2214
2215
2216/* called from frame.c */ 2136/* called from frame.c */
2217struct ns_display_info * 2137struct ns_display_info *
2218check_x_display_info (Lisp_Object frame) 2138check_x_display_info (Lisp_Object frame)
@@ -2231,6 +2151,9 @@ x_set_scroll_bar_default_width (struct frame *f)
2231} 2151}
2232 2152
2233 2153
2154extern const char *x_get_string_resource (XrmDatabase, char *, char *);
2155
2156
2234/* terms impl this instead of x-get-resource directly */ 2157/* terms impl this instead of x-get-resource directly */
2235const char * 2158const char *
2236x_get_string_resource (XrmDatabase rdb, char *name, char *class) 2159x_get_string_resource (XrmDatabase rdb, char *name, char *class)
@@ -2238,7 +2161,7 @@ x_get_string_resource (XrmDatabase rdb, char *name, char *class)
2238 /* remove appname prefix; TODO: allow for !="Emacs" */ 2161 /* remove appname prefix; TODO: allow for !="Emacs" */
2239 char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0); 2162 char *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
2240 const char *res; 2163 const char *res;
2241 check_ns (); 2164 check_window_system (NULL);
2242 2165
2243 if (inhibit_x_resources) 2166 if (inhibit_x_resources)
2244 /* --quick was passed, so this is a no-op. */ 2167 /* --quick was passed, so this is a no-op. */
@@ -2279,13 +2202,6 @@ x_pixel_height (struct frame *f)
2279} 2202}
2280 2203
2281 2204
2282int
2283x_screen_planes (struct frame *f)
2284{
2285 return FRAME_NS_DISPLAY_INFO (f)->n_planes;
2286}
2287
2288
2289void 2205void
2290x_sync (struct frame *f) 2206x_sync (struct frame *f)
2291{ 2207{
@@ -2308,7 +2224,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
2308 (Lisp_Object color, Lisp_Object frame) 2224 (Lisp_Object color, Lisp_Object frame)
2309{ 2225{
2310 NSColor * col; 2226 NSColor * col;
2311 check_ns (); 2227 check_window_system (NULL);
2312 return ns_lisp_to_color (color, &col) ? Qnil : Qt; 2228 return ns_lisp_to_color (color, &col) ? Qnil : Qt;
2313} 2229}
2314 2230
@@ -2318,9 +2234,9 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2318 (Lisp_Object color, Lisp_Object frame) 2234 (Lisp_Object color, Lisp_Object frame)
2319{ 2235{
2320 NSColor * col; 2236 NSColor * col;
2321 CGFloat red, green, blue, alpha; 2237 EmacsCGFloat red, green, blue, alpha;
2322 2238
2323 check_ns (); 2239 check_window_system (NULL);
2324 CHECK_STRING (color); 2240 CHECK_STRING (color);
2325 2241
2326 if (ns_lisp_to_color (color, &col)) 2242 if (ns_lisp_to_color (color, &col))
@@ -2335,12 +2251,13 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
2335 2251
2336DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0, 2252DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2337 doc: /* Internal function called by `display-color-p', which see. */) 2253 doc: /* Internal function called by `display-color-p', which see. */)
2338 (Lisp_Object display) 2254 (Lisp_Object terminal)
2339{ 2255{
2340 NSWindowDepth depth; 2256 NSWindowDepth depth;
2341 NSString *colorSpace; 2257 NSString *colorSpace;
2342 check_ns (); 2258
2343 depth = [ns_get_screen (display) depth]; 2259 check_ns_display_info (terminal);
2260 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2344 colorSpace = NSColorSpaceFromDepth (depth); 2261 colorSpace = NSColorSpaceFromDepth (depth);
2345 2262
2346 return [colorSpace isEqualToString: NSDeviceWhiteColorSpace] 2263 return [colorSpace isEqualToString: NSDeviceWhiteColorSpace]
@@ -2349,18 +2266,19 @@ DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
2349} 2266}
2350 2267
2351 2268
2352DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, 2269DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
2353 Sx_display_grayscale_p, 0, 1, 0, 2270 0, 1, 0,
2354 doc: /* Return t if the Nextstep display supports shades of gray. 2271 doc: /* Return t if the Nextstep display supports shades of gray.
2355Note that color displays do support shades of gray. 2272Note that color displays do support shades of gray.
2356The optional argument DISPLAY specifies which display to ask about. 2273The optional argument TERMINAL specifies which display to ask about.
2357DISPLAY should be either a frame, a display name (a string), or terminal ID. 2274TERMINAL should be a terminal object, a frame or a display name (a string).
2358If omitted or nil, that stands for the selected frame's display. */) 2275If omitted or nil, that stands for the selected frame's display. */)
2359 (Lisp_Object display) 2276 (Lisp_Object terminal)
2360{ 2277{
2361 NSWindowDepth depth; 2278 NSWindowDepth depth;
2362 check_ns (); 2279
2363 depth = [ns_get_screen (display) depth]; 2280 check_ns_display_info (terminal);
2281 depth = [[[NSScreen screens] objectAtIndex:0] depth];
2364 2282
2365 return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil; 2283 return NSBitsPerPixelFromDepth (depth) > 1 ? Qt : Qnil;
2366} 2284}
@@ -2368,87 +2286,230 @@ If omitted or nil, that stands for the selected frame's display. */)
2368 2286
2369DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 2287DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
2370 0, 1, 0, 2288 0, 1, 0,
2371 doc: /* Return the width in pixels of the Nextstep display DISPLAY. 2289 doc: /* Return the width in pixels of the Nextstep display TERMINAL.
2372The optional argument DISPLAY specifies which display to ask about. 2290The optional argument TERMINAL specifies which display to ask about.
2373DISPLAY should be either a frame, a display name (a string), or terminal ID. 2291TERMINAL should be a terminal object, a frame or a display name (a string).
2374If omitted or nil, that stands for the selected frame's display. */) 2292If omitted or nil, that stands for the selected frame's display.
2375 (Lisp_Object display) 2293
2294On \"multi-monitor\" setups this refers to the pixel width for all
2295physical monitors associated with TERMINAL. To get information for
2296each physical monitor, use `display-monitor-attributes-list'. */)
2297 (Lisp_Object terminal)
2376{ 2298{
2377 check_ns (); 2299 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2378 return make_number ((int) [ns_get_screen (display) frame].size.width); 2300
2301 return make_number (x_display_pixel_width (dpyinfo));
2379} 2302}
2380 2303
2381 2304
2382DEFUN ("x-display-pixel-height", Fx_display_pixel_height, 2305DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
2383 Sx_display_pixel_height, 0, 1, 0, 2306 Sx_display_pixel_height, 0, 1, 0,
2384 doc: /* Return the height in pixels of the Nextstep display DISPLAY. 2307 doc: /* Return the height in pixels of the Nextstep display TERMINAL.
2385The optional argument DISPLAY specifies which display to ask about. 2308The optional argument TERMINAL specifies which display to ask about.
2386DISPLAY should be either a frame, a display name (a string), or terminal ID. 2309TERMINAL should be a terminal object, a frame or a display name (a string).
2387If omitted or nil, that stands for the selected frame's display. */) 2310If omitted or nil, that stands for the selected frame's display.
2388 (Lisp_Object display) 2311
2312On \"multi-monitor\" setups this refers to the pixel height for all
2313physical monitors associated with TERMINAL. To get information for
2314each physical monitor, use `display-monitor-attributes-list'. */)
2315 (Lisp_Object terminal)
2389{ 2316{
2390 check_ns (); 2317 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2391 return make_number ((int) [ns_get_screen (display) frame].size.height); 2318
2319 return make_number (x_display_pixel_height (dpyinfo));
2320}
2321
2322#ifdef NS_IMPL_COCOA
2323/* Returns the name for the screen that DICT came from, or NULL.
2324 Caller must free return value.
2325*/
2326
2327static char *
2328ns_screen_name (CGDirectDisplayID did)
2329{
2330 char *name = NULL;
2331 NSDictionary *info = (NSDictionary *)
2332 IODisplayCreateInfoDictionary (CGDisplayIOServicePort (did),
2333 kIODisplayOnlyPreferredName);
2334 NSDictionary *names
2335 = [info objectForKey:
2336 [NSString stringWithUTF8String:kDisplayProductName]];
2337
2338 if ([names count] > 0) {
2339 NSString *n = [names objectForKey: [[names allKeys] objectAtIndex:0]];
2340 if (n != nil)
2341 name = xstrdup ([n UTF8String]);
2342 }
2343
2344 [info release];
2345 return name;
2346}
2347#endif
2348
2349static Lisp_Object
2350ns_make_monitor_attribute_list (struct MonitorInfo *monitors,
2351 int n_monitors,
2352 int primary_monitor,
2353 const char *source)
2354{
2355 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
2356 Lisp_Object frame, rest;
2357 NSArray *screens = [NSScreen screens];
2358 int i;
2359
2360 FOR_EACH_FRAME (rest, frame)
2361 {
2362 struct frame *f = XFRAME (frame);
2363
2364 if (FRAME_NS_P (f))
2365 {
2366 NSView *view = FRAME_NS_VIEW (f);
2367 NSScreen *screen = [[view window] screen];
2368 NSUInteger k;
2369
2370 i = -1;
2371 for (k = 0; i == -1 && k < [screens count]; ++k)
2372 {
2373 if ([screens objectAtIndex: k] == screen)
2374 i = (int)k;
2375 }
2376
2377 if (i > -1)
2378 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
2379 }
2380 }
2381
2382 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
2383 monitor_frames, source);
2392} 2384}
2393 2385
2386DEFUN ("ns-display-monitor-attributes-list",
2387 Fns_display_monitor_attributes_list,
2388 Sns_display_monitor_attributes_list,
2389 0, 1, 0,
2390 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
2391
2392The optional argument TERMINAL specifies which display to ask about.
2393TERMINAL should be a terminal object, a frame or a display name (a string).
2394If omitted or nil, that stands for the selected frame's display.
2395
2396In addition to the standard attribute keys listed in
2397`display-monitor-attributes-list', the following keys are contained in
2398the attributes:
2394 2399
2395DEFUN ("display-usable-bounds", Fns_display_usable_bounds, 2400 source -- String describing the source from which multi-monitor
2396 Sns_display_usable_bounds, 0, 1, 0, 2401 information is obtained, \"NS\" is always the source."
2397 doc: /* Return the bounds of the usable part of the screen.
2398The return value is a list of integers (LEFT TOP WIDTH HEIGHT), which
2399are the boundaries of the usable part of the screen, excluding areas
2400reserved for the Mac menu, dock, and so forth.
2401 2402
2402The screen queried corresponds to DISPLAY, which should be either a 2403Internal use only, use `display-monitor-attributes-list' instead. */)
2403frame, a display name (a string), or terminal ID. If omitted or nil, 2404 (Lisp_Object terminal)
2404that stands for the selected frame's display. */)
2405 (Lisp_Object display)
2406{ 2405{
2407 NSScreen *screen; 2406 struct terminal *term = get_terminal (terminal, 1);
2408 NSRect vScreen; 2407 NSArray *screens;
2408 NSUInteger i, n_monitors;
2409 struct MonitorInfo *monitors;
2410 Lisp_Object attributes_list = Qnil;
2411 CGFloat primary_display_height = 0;
2409 2412
2410 check_ns (); 2413 if (term->type != output_ns)
2411 screen = ns_get_screen (display);
2412 if (!screen)
2413 return Qnil; 2414 return Qnil;
2414 2415
2415 vScreen = [screen visibleFrame]; 2416 screens = [NSScreen screens];
2417 n_monitors = [screens count];
2418 if (n_monitors == 0)
2419 return Qnil;
2420
2421 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
2422
2423 for (i = 0; i < [screens count]; ++i)
2424 {
2425 NSScreen *s = [screens objectAtIndex:i];
2426 struct MonitorInfo *m = &monitors[i];
2427 NSRect fr = [s frame];
2428 NSRect vfr = [s visibleFrame];
2429 short y, vy;
2430
2431#ifdef NS_IMPL_COCOA
2432 NSDictionary *dict = [s deviceDescription];
2433 NSNumber *nid = [dict objectForKey:@"NSScreenNumber"];
2434 CGDirectDisplayID did = [nid unsignedIntValue];
2435#endif
2436 if (i == 0)
2437 {
2438 primary_display_height = fr.size.height;
2439 y = (short) fr.origin.y;
2440 vy = (short) vfr.origin.y;
2441 }
2442 else
2443 {
2444 // Flip y coordinate as NS has y starting from the bottom.
2445 y = (short) (primary_display_height - fr.size.height - fr.origin.y);
2446 vy = (short) (primary_display_height -
2447 vfr.size.height - vfr.origin.y);
2448 }
2449
2450 m->geom.x = (short) fr.origin.x;
2451 m->geom.y = y;
2452 m->geom.width = (unsigned short) fr.size.width;
2453 m->geom.height = (unsigned short) fr.size.height;
2454
2455 m->work.x = (short) vfr.origin.x;
2456 // y is flipped on NS, so vy - y are pixels missing at the bottom,
2457 // and fr.size.height - vfr.size.height are pixels missing in total.
2458 // Pixels missing at top are
2459 // fr.size.height - vfr.size.height - vy + y.
2460 // work.y is then pixels missing at top + y.
2461 m->work.y = (short) (fr.size.height - vfr.size.height) - vy + y + y;
2462 m->work.width = (unsigned short) vfr.size.width;
2463 m->work.height = (unsigned short) vfr.size.height;
2464
2465#ifdef NS_IMPL_COCOA
2466 m->name = ns_screen_name (did);
2416 2467
2417 /* NS coordinate system is upside-down. 2468 {
2418 Transform to screen-specific coordinates. */ 2469 CGSize mms = CGDisplayScreenSize (did);
2419 return list4i (vScreen.origin.x, 2470 m->mm_width = (int) mms.width;
2420 [screen frame].size.height 2471 m->mm_height = (int) mms.height;
2421 - vScreen.size.height - vScreen.origin.y, 2472 }
2422 vScreen.size.width, vScreen.size.height); 2473
2474#else
2475 // Assume 92 dpi as x-display-mm-height/x-display-mm-width does.
2476 m->mm_width = (int) (25.4 * fr.size.width / 92.0);
2477 m->mm_height = (int) (25.4 * fr.size.height / 92.0);
2478#endif
2479 }
2480
2481 // Primary monitor is always first for NS.
2482 attributes_list = ns_make_monitor_attribute_list (monitors, n_monitors,
2483 0, "NS");
2484
2485 free_monitors (monitors, n_monitors);
2486 return attributes_list;
2423} 2487}
2424 2488
2425 2489
2426DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 2490DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
2427 0, 1, 0, 2491 0, 1, 0,
2428 doc: /* Return the number of bitplanes of the Nextstep display DISPLAY. 2492 doc: /* Return the number of bitplanes of the Nextstep display TERMINAL.
2429The optional argument DISPLAY specifies which display to ask about. 2493The optional argument TERMINAL specifies which display to ask about.
2430DISPLAY should be either a frame, a display name (a string), or terminal ID. 2494TERMINAL should be a terminal object, a frame or a display name (a string).
2431If omitted or nil, that stands for the selected frame's display. */) 2495If omitted or nil, that stands for the selected frame's display. */)
2432 (Lisp_Object display) 2496 (Lisp_Object terminal)
2433{ 2497{
2434 check_ns (); 2498 check_ns_display_info (terminal);
2435 return make_number 2499 return make_number
2436 (NSBitsPerPixelFromDepth ([ns_get_screen (display) depth])); 2500 (NSBitsPerPixelFromDepth ([[[NSScreen screens] objectAtIndex:0] depth]));
2437} 2501}
2438 2502
2439 2503
2440DEFUN ("x-display-color-cells", Fx_display_color_cells, 2504DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
2441 Sx_display_color_cells, 0, 1, 0, 2505 0, 1, 0,
2442 doc: /* Returns the number of color cells of the Nextstep display DISPLAY. 2506 doc: /* Returns the number of color cells of the Nextstep display TERMINAL.
2443The optional argument DISPLAY specifies which display to ask about. 2507The optional argument TERMINAL specifies which display to ask about.
2444DISPLAY should be either a frame, a display name (a string), or terminal ID. 2508TERMINAL should be a terminal object, a frame or a display name (a string).
2445If omitted or nil, that stands for the selected frame's display. */) 2509If omitted or nil, that stands for the selected frame's display. */)
2446 (Lisp_Object display) 2510 (Lisp_Object terminal)
2447{ 2511{
2448 struct ns_display_info *dpyinfo; 2512 struct ns_display_info *dpyinfo = check_ns_display_info (terminal);
2449 check_ns ();
2450
2451 dpyinfo = check_ns_display_info (display);
2452 /* We force 24+ bit depths to 24-bit to prevent an overflow. */ 2513 /* We force 24+ bit depths to 24-bit to prevent an overflow. */
2453 return make_number (1 << min (dpyinfo->n_planes, 24)); 2514 return make_number (1 << min (dpyinfo->n_planes, 24));
2454} 2515}
@@ -2561,7 +2622,7 @@ Text larger than the specified size is clipped. */)
2561 2622
2562 CHECK_STRING (string); 2623 CHECK_STRING (string);
2563 str = SSDATA (string); 2624 str = SSDATA (string);
2564 f = check_x_frame (frame); 2625 f = decode_window_system_frame (frame);
2565 if (NILP (timeout)) 2626 if (NILP (timeout))
2566 timeout = make_number (5); 2627 timeout = make_number (5);
2567 else 2628 else
@@ -2617,6 +2678,75 @@ Value is t if tooltip was open, nil otherwise. */)
2617 2678
2618 ========================================================================== */ 2679 ========================================================================== */
2619 2680
2681/*
2682 Handle arrow/function/control keys and copy/paste/cut in file dialogs.
2683 Return YES if handled, NO if not.
2684 */
2685static BOOL
2686handlePanelKeys (NSSavePanel *panel, NSEvent *theEvent)
2687{
2688 NSString *s;
2689 int i;
2690 BOOL ret = NO;
2691
2692 if ([theEvent type] != NSKeyDown) return NO;
2693 s = [theEvent characters];
2694
2695 for (i = 0; i < [s length]; ++i)
2696 {
2697 int ch = (int) [s characterAtIndex: i];
2698 switch (ch)
2699 {
2700 case NSHomeFunctionKey:
2701 case NSDownArrowFunctionKey:
2702 case NSUpArrowFunctionKey:
2703 case NSLeftArrowFunctionKey:
2704 case NSRightArrowFunctionKey:
2705 case NSPageUpFunctionKey:
2706 case NSPageDownFunctionKey:
2707 case NSEndFunctionKey:
2708 [panel sendEvent: theEvent];
2709 ret = YES;
2710 break;
2711 /* As we don't have the standard key commands for
2712 copy/paste/cut/select-all in our edit menu, we must handle
2713 them here. TODO: handle Emacs key bindings for copy/cut/select-all
2714 here, paste works, because we have that in our Edit menu.
2715 I.e. refactor out code in nsterm.m, keyDown: to figure out the
2716 correct modifier.
2717 */
2718 case 'x': // Cut
2719 case 'c': // Copy
2720 case 'v': // Paste
2721 case 'a': // Select all
2722 if ([theEvent modifierFlags] & NSCommandKeyMask)
2723 {
2724 [NSApp sendAction:
2725 (ch == 'x'
2726 ? @selector(cut:)
2727 : (ch == 'c'
2728 ? @selector(copy:)
2729 : (ch == 'v'
2730 ? @selector(paste:)
2731 : @selector(selectAll:))))
2732 to:nil from:panel];
2733 ret = YES;
2734 }
2735 default:
2736 // Send all control keys, as the text field supports C-a, C-f, C-e
2737 // C-b and more.
2738 if ([theEvent modifierFlags] & NSControlKeyMask)
2739 {
2740 [panel sendEvent: theEvent];
2741 ret = YES;
2742 }
2743 break;
2744 }
2745 }
2746
2747
2748 return ret;
2749}
2620 2750
2621@implementation EmacsSavePanel 2751@implementation EmacsSavePanel
2622#ifdef NS_IMPL_COCOA 2752#ifdef NS_IMPL_COCOA
@@ -2637,13 +2767,13 @@ Value is t if tooltip was open, nil otherwise. */)
2637 [NSApp stop: self]; 2767 [NSApp stop: self];
2638} 2768}
2639#endif 2769#endif
2640- (NSString *) getFilename 2770
2641{ 2771- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
2642 return ns_filename_from_panel (self);
2643}
2644- (NSString *) getDirectory
2645{ 2772{
2646 return ns_directory_from_panel (self); 2773 BOOL ret = handlePanelKeys (self, theEvent);
2774 if (! ret)
2775 ret = [super performKeyEquivalent:theEvent];
2776 return ret;
2647} 2777}
2648@end 2778@end
2649 2779
@@ -2660,8 +2790,8 @@ Value is t if tooltip was open, nil otherwise. */)
2660 [super ok: sender]; 2790 [super ok: sender];
2661 2791
2662 // If not choosing directories, and Open is pressed on a directory, return. 2792 // If not choosing directories, and Open is pressed on a directory, return.
2663 if (! [self canChooseDirectories] && [self getDirectory] && 2793 if (! [self canChooseDirectories] && ns_directory_from_panel (self) &&
2664 ! [self getFilename]) 2794 ! ns_filename_from_panel (self))
2665 return; 2795 return;
2666 2796
2667 panelOK = 1; 2797 panelOK = 1;
@@ -2674,15 +2804,14 @@ Value is t if tooltip was open, nil otherwise. */)
2674} 2804}
2675 2805
2676#endif 2806#endif
2677- (NSString *) getFilename 2807- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
2678{ 2808{
2679 return ns_filename_from_panel (self); 2809 // NSOpenPanel inherits NSSavePanel, so passing self is OK.
2680} 2810 BOOL ret = handlePanelKeys (self, theEvent);
2681- (NSString *) getDirectory 2811 if (! ret)
2682{ 2812 ret = [super performKeyEquivalent:theEvent];
2683 return ns_directory_from_panel (self); 2813 return ret;
2684} 2814}
2685
2686@end 2815@end
2687 2816
2688 2817
@@ -2763,7 +2892,7 @@ be used as the image of the icon representing the frame. */);
2763 defsubr (&Sx_server_version); 2892 defsubr (&Sx_server_version);
2764 defsubr (&Sx_display_pixel_width); 2893 defsubr (&Sx_display_pixel_width);
2765 defsubr (&Sx_display_pixel_height); 2894 defsubr (&Sx_display_pixel_height);
2766 defsubr (&Sns_display_usable_bounds); 2895 defsubr (&Sns_display_monitor_attributes_list);
2767 defsubr (&Sx_display_mm_width); 2896 defsubr (&Sx_display_mm_width);
2768 defsubr (&Sx_display_mm_height); 2897 defsubr (&Sx_display_mm_height);
2769 defsubr (&Sx_display_screens); 2898 defsubr (&Sx_display_screens);
@@ -2790,9 +2919,6 @@ be used as the image of the icon representing the frame. */);
2790 defsubr (&Sx_show_tip); 2919 defsubr (&Sx_show_tip);
2791 defsubr (&Sx_hide_tip); 2920 defsubr (&Sx_hide_tip);
2792 2921
2793 /* used only in fontset.c */
2794 check_window_system_func = check_ns;
2795
2796 as_status = 0; 2922 as_status = 0;
2797 as_script = Qnil; 2923 as_script = Qnil;
2798 as_result = 0; 2924 as_result = 0;
diff --git a/src/nsfont.m b/src/nsfont.m
index ebee363651f..709f2cb0d86 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -119,7 +119,7 @@ ns_attribute_fvalue (NSFontDescriptor *fdesc, NSString *trait)
119{ 119{
120 NSDictionary *tdict = [fdesc objectForKey: NSFontTraitsAttribute]; 120 NSDictionary *tdict = [fdesc objectForKey: NSFontTraitsAttribute];
121 NSNumber *val = [tdict objectForKey: trait]; 121 NSNumber *val = [tdict objectForKey: trait];
122 return val == nil ? 0.0 : [val floatValue]; 122 return val == nil ? 0.0F : [val floatValue];
123} 123}
124 124
125 125
@@ -138,23 +138,26 @@ ns_spec_to_descriptor (Lisp_Object font_spec)
138 /* add each attr in font_spec to fdAttrs.. */ 138 /* add each attr in font_spec to fdAttrs.. */
139 n = min (FONT_WEIGHT_NUMERIC (font_spec), 200); 139 n = min (FONT_WEIGHT_NUMERIC (font_spec), 200);
140 if (n != -1 && n != STYLE_REF) 140 if (n != -1 && n != STYLE_REF)
141 [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0] 141 [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
142 forKey: NSFontWeightTrait]; 142 forKey: NSFontWeightTrait];
143 n = min (FONT_SLANT_NUMERIC (font_spec), 200); 143 n = min (FONT_SLANT_NUMERIC (font_spec), 200);
144 if (n != -1 && n != STYLE_REF) 144 if (n != -1 && n != STYLE_REF)
145 [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0] 145 [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
146 forKey: NSFontSlantTrait]; 146 forKey: NSFontSlantTrait];
147 n = min (FONT_WIDTH_NUMERIC (font_spec), 200); 147 n = min (FONT_WIDTH_NUMERIC (font_spec), 200);
148 if (n > -1 && (n > STYLE_REF + 10 || n < STYLE_REF - 10)) 148 if (n > -1 && (n > STYLE_REF + 10 || n < STYLE_REF - 10))
149 [tdict setObject: [NSNumber numberWithFloat: (n - 100.0) / 100.0] 149 [tdict setObject: [NSNumber numberWithFloat: (n - 100.0F) / 100.0F]
150 forKey: NSFontWidthTrait]; 150 forKey: NSFontWidthTrait];
151 if ([tdict count] > 0) 151 if ([tdict count] > 0)
152 [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute]; 152 [fdAttrs setObject: tdict forKey: NSFontTraitsAttribute];
153 153
154 fdesc = [NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]; 154 fdesc = [[[NSFontDescriptor fontDescriptorWithFontAttributes: fdAttrs]
155 retain] autorelease];
156
155 if (family != nil) 157 if (family != nil)
156 { 158 {
157 fdesc = [fdesc fontDescriptorWithFamily: family]; 159 NSFontDescriptor *fdesc2 = [fdesc fontDescriptorWithFamily: family];
160 fdesc = [[fdesc2 retain] autorelease];
158 } 161 }
159 162
160 [fdAttrs release]; 163 [fdAttrs release];
@@ -237,10 +240,10 @@ ns_fallback_entity (void)
237 240
238 241
239/* Utility: get width of a char c in screen font SFONT */ 242/* Utility: get width of a char c in screen font SFONT */
240static float 243static CGFloat
241ns_char_width (NSFont *sfont, int c) 244ns_char_width (NSFont *sfont, int c)
242{ 245{
243 float w = -1.0; 246 CGFloat w = -1.0;
244 NSString *cstr = [NSString stringWithFormat: @"%c", c]; 247 NSString *cstr = [NSString stringWithFormat: @"%c", c];
245 248
246#ifdef NS_IMPL_COCOA 249#ifdef NS_IMPL_COCOA
@@ -266,7 +269,7 @@ static NSString *ascii_printable;
266static int 269static int
267ns_ascii_average_width (NSFont *sfont) 270ns_ascii_average_width (NSFont *sfont)
268{ 271{
269 float w = -1.0; 272 CGFloat w = -1.0;
270 273
271 if (!ascii_printable) 274 if (!ascii_printable)
272 { 275 {
@@ -285,14 +288,14 @@ ns_ascii_average_width (NSFont *sfont)
285 w = [sfont advancementForGlyph: glyph].width; 288 w = [sfont advancementForGlyph: glyph].width;
286#endif 289#endif
287 290
288 if (w < 0.0) 291 if (w < (CGFloat) 0.0)
289 { 292 {
290 NSDictionary *attrsDictionary = 293 NSDictionary *attrsDictionary =
291 [NSDictionary dictionaryWithObject: sfont forKey: NSFontAttributeName]; 294 [NSDictionary dictionaryWithObject: sfont forKey: NSFontAttributeName];
292 w = [ascii_printable sizeWithAttributes: attrsDictionary].width; 295 w = [ascii_printable sizeWithAttributes: attrsDictionary].width;
293 } 296 }
294 297
295 return lrint (w / 95.0); 298 return lrint (w / (CGFloat) 95.0);
296} 299}
297 300
298 301
@@ -320,7 +323,7 @@ ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct)
320 off++; 323 off++;
321 } 324 }
322//fprintf(stderr, "off = %d\ttot = %d\n", off,tot); 325//fprintf(stderr, "off = %d\ttot = %d\n", off,tot);
323 return (float)off / tot < 1.0 - pct; 326 return (float)off / tot < 1.0F - pct;
324} 327}
325 328
326 329
@@ -511,8 +514,8 @@ static NSSet
511 if (ns_charset_covers(fset, charset, pct)) 514 if (ns_charset_covers(fset, charset, pct))
512 [families addObject: family]; 515 [families addObject: family];
513 } 516 }
514 pct -= 0.2; 517 pct -= 0.2F;
515 if ([families count] > 0 || pct < 0.05) 518 if ([families count] > 0 || pct < 0.05F)
516 break; 519 break;
517 } 520 }
518 [charset release]; 521 [charset release];
@@ -760,9 +763,9 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
760 family = [[NSFont userFixedPitchFontOfSize: 0] familyName]; 763 family = [[NSFont userFixedPitchFontOfSize: 0] familyName];
761 /* Should be > 0.23 as some font descriptors (e.g. Terminus) set to that 764 /* Should be > 0.23 as some font descriptors (e.g. Terminus) set to that
762 when setting family in ns_spec_to_descriptor(). */ 765 when setting family in ns_spec_to_descriptor(). */
763 if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50) 766 if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F)
764 traits |= NSBoldFontMask; 767 traits |= NSBoldFontMask;
765 if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05)) 768 if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F))
766 traits |= NSItalicFontMask; 769 traits |= NSItalicFontMask;
767 770
768 /* see http://cocoadev.com/forums/comments.php?DiscussionID=74 */ 771 /* see http://cocoadev.com/forums/comments.php?DiscussionID=74 */
@@ -877,7 +880,7 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
877 font_info->max_bounds.width = lrint (font_info->width); 880 font_info->max_bounds.width = lrint (font_info->width);
878 font_info->max_bounds.lbearing = lrint (brect.origin.x); 881 font_info->max_bounds.lbearing = lrint (brect.origin.x);
879 font_info->max_bounds.rbearing = 882 font_info->max_bounds.rbearing =
880 lrint (brect.size.width - font_info->width); 883 lrint (brect.size.width - (CGFloat) font_info->width);
881 884
882#ifdef NS_IMPL_COCOA 885#ifdef NS_IMPL_COCOA
883 /* set up synthItal and the CG font */ 886 /* set up synthItal and the CG font */
@@ -1038,8 +1041,8 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1038/* NOTE: focus and clip must be set 1041/* NOTE: focus and clip must be set
1039 also, currently assumed (true in nsterm.m call) from ==0, to ==nchars */ 1042 also, currently assumed (true in nsterm.m call) from ==0, to ==nchars */
1040{ 1043{
1041 static char cbuf[1024]; 1044 static unsigned char cbuf[1024];
1042 char *c = cbuf; 1045 unsigned char *c = cbuf;
1043#ifdef NS_IMPL_GNUSTEP 1046#ifdef NS_IMPL_GNUSTEP
1044 static float advances[1024]; 1047 static float advances[1024];
1045 float *adv = advances; 1048 float *adv = advances;
@@ -1206,7 +1209,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1206 [bgCol set]; 1209 [bgCol set];
1207 DPSmoveto (context, r.origin.x, r.origin.y); 1210 DPSmoveto (context, r.origin.x, r.origin.y);
1208/*[context GSSetTextDrawingMode: GSTextFillStroke]; /// not implemented yet */ 1211/*[context GSSetTextDrawingMode: GSTextFillStroke]; /// not implemented yet */
1209 DPSxshow (context, cbuf, advances, len); 1212 DPSxshow (context, (const char *) cbuf, advances, len);
1210 DPSstroke (context); 1213 DPSstroke (context);
1211 [col set]; 1214 [col set];
1212/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */ 1215/*[context GSSetTextDrawingMode: GSTextFill]; /// not implemented yet */
@@ -1216,7 +1219,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1216 1219
1217 /* draw with DPSxshow () */ 1220 /* draw with DPSxshow () */
1218 DPSmoveto (context, r.origin.x, r.origin.y); 1221 DPSmoveto (context, r.origin.x, r.origin.y);
1219 DPSxshow (context, cbuf, advances, len); 1222 DPSxshow (context, (const char *) cbuf, advances, len);
1220 DPSstroke (context); 1223 DPSstroke (context);
1221 1224
1222 DPSgrestore (context); 1225 DPSgrestore (context);
@@ -1404,7 +1407,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
1404 metrics = font_info->metrics[block]; 1407 metrics = font_info->metrics[block];
1405 for (g = block<<8, i =0; i<0x100 && g < numGlyphs; g++, i++, metrics++) 1408 for (g = block<<8, i =0; i<0x100 && g < numGlyphs; g++, i++, metrics++)
1406 { 1409 {
1407 float w, lb, rb; 1410 CGFloat w, lb, rb;
1408 NSRect r = [sfont boundingRectForGlyph: g]; 1411 NSRect r = [sfont boundingRectForGlyph: g];
1409 1412
1410 w = max ([sfont advancementForGlyph: g].width, 2.0); 1413 w = max ([sfont advancementForGlyph: g].width, 2.0);
@@ -1416,7 +1419,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block)
1416 if (lb < 0) 1419 if (lb < 0)
1417 metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN); 1420 metrics->lbearing = round (lb - LCD_SMOOTHING_MARGIN);
1418 if (font_info->ital) 1421 if (font_info->ital)
1419 rb += 0.22 * font_info->height; 1422 rb += (CGFloat) (0.22F * font_info->height);
1420 metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN); 1423 metrics->rbearing = lrint (w + rb + LCD_SMOOTHING_MARGIN);
1421 1424
1422 metrics->descent = r.origin.y < 0 ? -r.origin.y : 0; 1425 metrics->descent = r.origin.y < 0 ? -r.origin.y : 0;
diff --git a/src/nsimage.m b/src/nsimage.m
index 9d21ba8afca..a1703272ad2 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -334,7 +334,7 @@ static EmacsImage *ImageList = nil;
334{ 334{
335 NSSize s = [self size]; 335 NSSize s = [self size];
336 unsigned char *planes[5]; 336 unsigned char *planes[5];
337 CGFloat r, g, b, a; 337 EmacsCGFloat r, g, b, a;
338 NSColor *rgbColor; 338 NSColor *rgbColor;
339 339
340 if (bmRep == nil || color == nil) 340 if (bmRep == nil || color == nil)
@@ -437,7 +437,7 @@ static EmacsImage *ImageList = nil;
437 else 437 else
438 { 438 {
439 NSColor *color = [bmRep colorAtX: x y: y]; 439 NSColor *color = [bmRep colorAtX: x y: y];
440 CGFloat r, g, b, a; 440 EmacsCGFloat r, g, b, a;
441 [color getRed: &r green: &g blue: &b alpha: &a]; 441 [color getRed: &r green: &g blue: &b alpha: &a];
442 return ((int)(a * 255.0) << 24) 442 return ((int)(a * 255.0) << 24)
443 | ((int)(r * 255.0) << 16) | ((int)(g * 255.0) << 8) 443 | ((int)(r * 255.0) << 16) | ((int)(g * 255.0) << 8)
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 22ff4dd0b53..1d3d111e9a1 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -45,8 +45,6 @@ Carbon version by Yamamoto Mitsuharu. */
45#include <sys/types.h> 45#include <sys/types.h>
46#endif 46#endif
47 47
48#define MenuStagger 10.0
49
50#if 0 48#if 0
51int menu_trace_num = 0; 49int menu_trace_num = 0;
52#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \ 50#define NSTRACE(x) fprintf (stderr, "%s:%d: [%d] " #x "\n", \
@@ -88,14 +86,6 @@ static int trackingMenu;
88 ========================================================================== */ 86 ========================================================================== */
89 87
90 88
91/* FIXME: not currently used, but should normalize with other terms. */
92void
93x_activate_menubar (struct frame *f)
94{
95 fprintf (stderr, "XXX: Received x_activate_menubar event.\n");
96}
97
98
99/* Supposed to discard menubar and free storage. Since we share the 89/* Supposed to discard menubar and free storage. Since we share the
100 menubar among frames and update its context for the focused window, 90 menubar among frames and update its context for the focused window,
101 there is nothing to do here. */ 91 there is nothing to do here. */
@@ -120,14 +110,13 @@ popup_activated (void)
120 2) deep_p, submenu = nil: Recompute all submenus. 110 2) deep_p, submenu = nil: Recompute all submenus.
121 3) deep_p, submenu = non-nil: Update contents of a single submenu. 111 3) deep_p, submenu = non-nil: Update contents of a single submenu.
122 -------------------------------------------------------------------------- */ 112 -------------------------------------------------------------------------- */
123void 113static void
124ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu) 114ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
125{ 115{
126 NSAutoreleasePool *pool; 116 NSAutoreleasePool *pool;
127 id menu = [NSApp mainMenu]; 117 id menu = [NSApp mainMenu];
128 static EmacsMenu *last_submenu = nil; 118 static EmacsMenu *last_submenu = nil;
129 BOOL needsSet = NO; 119 BOOL needsSet = NO;
130 const char *submenuTitle = [[submenu title] UTF8String];
131 bool owfi; 120 bool owfi;
132 Lisp_Object items; 121 Lisp_Object items;
133 widget_value *wv, *first_wv, *prev_wv = 0; 122 widget_value *wv, *first_wv, *prev_wv = 0;
@@ -138,7 +127,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
138 long t; 127 long t;
139#endif 128#endif
140 129
141 NSTRACE (set_frame_menubar); 130 NSTRACE (ns_update_menubar);
142 131
143 if (f != SELECTED_FRAME ()) 132 if (f != SELECTED_FRAME ())
144 return; 133 return;
@@ -191,7 +180,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
191 = alloca (previous_menu_items_used * sizeof *previous_items); 180 = alloca (previous_menu_items_used * sizeof *previous_items);
192 181
193 /* lisp preliminaries */ 182 /* lisp preliminaries */
194 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer; 183 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
195 specbind (Qinhibit_quit, Qt); 184 specbind (Qinhibit_quit, Qt);
196 specbind (Qdebug_on_next_call, Qnil); 185 specbind (Qdebug_on_next_call, Qnil);
197 record_unwind_save_match_data (); 186 record_unwind_save_match_data ();
@@ -247,7 +236,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
247 /* FIXME: we'd like to only parse the needed submenu, but this 236 /* FIXME: we'd like to only parse the needed submenu, but this
248 was causing crashes in the _common parsing code.. need to make 237 was causing crashes in the _common parsing code.. need to make
249 sure proper initialization done.. */ 238 sure proper initialization done.. */
250/* if (submenu && strcmp (submenuTitle, SSDATA (string))) 239/* if (submenu && strcmp ([[submenu title] UTF8String], SSDATA (string)))
251 continue; */ 240 continue; */
252 241
253 submenu_start[i] = menu_items_used; 242 submenu_start[i] = menu_items_used;
@@ -267,7 +256,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
267 { 256 {
268 /* should have found a menu for this one but didn't */ 257 /* should have found a menu for this one but didn't */
269 fprintf (stderr, "ERROR: did not find lisp menu for submenu '%s'.\n", 258 fprintf (stderr, "ERROR: did not find lisp menu for submenu '%s'.\n",
270 submenuTitle); 259 [[submenu title] UTF8String]);
271 discard_menu_items (); 260 discard_menu_items ();
272 unbind_to (specpdl_count, Qnil); 261 unbind_to (specpdl_count, Qnil);
273 [pool release]; 262 [pool release];
@@ -354,8 +343,6 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
354 string = AREF (items, i + 1); 343 string = AREF (items, i + 1);
355 if (NILP (string)) 344 if (NILP (string))
356 break; 345 break;
357/* if (submenu && strcmp (submenuTitle, SSDATA (string)))
358 continue; */
359 346
360 wv->name = SSDATA (string); 347 wv->name = SSDATA (string);
361 update_submenu_strings (wv->contents); 348 update_submenu_strings (wv->contents);
@@ -366,6 +353,7 @@ ns_update_menubar (struct frame *f, bool deep_p, EmacsMenu *submenu)
366 create a new menu for each sub and fill it. */ 353 create a new menu for each sub and fill it. */
367 if (submenu) 354 if (submenu)
368 { 355 {
356 const char *submenuTitle = [[submenu title] UTF8String];
369 for (wv = first_wv->contents; wv; wv = wv->next) 357 for (wv = first_wv->contents; wv; wv = wv->next)
370 { 358 {
371 if (!strcmp (submenuTitle, wv->name)) 359 if (!strcmp (submenuTitle, wv->name))
@@ -512,6 +500,31 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
512 ns_update_menubar (f, deep_p, nil); 500 ns_update_menubar (f, deep_p, nil);
513} 501}
514 502
503void
504x_activate_menubar (struct frame *f)
505{
506#ifdef NS_IMPL_COCOA
507 NSArray *a = [[NSApp mainMenu] itemArray];
508 /* Update each submenu separately so ns_update_menubar doesn't reset
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 ();
523#endif
524}
525
526
527
515 528
516/* ========================================================================== 529/* ==========================================================================
517 530
@@ -564,6 +577,14 @@ extern NSString *NSMenuDidBeginTrackingNotification;
564 trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification 577 trackingMenu = ([notification name] == NSMenuDidBeginTrackingNotification
565 ? 1 : 0); 578 ? 1 : 0);
566} 579}
580
581#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
582- (void)menuWillOpen:(NSMenu *)menu
583{
584 ns_check_menu_open (menu);
585}
586#endif
587
567#endif 588#endif
568 589
569/* delegate method called when a submenu is being opened: run a 'deep' call 590/* delegate method called when a submenu is being opened: run a 'deep' call
@@ -591,7 +612,12 @@ extern NSString *NSMenuDidBeginTrackingNotification;
591 if (trackingMenu == 0) 612 if (trackingMenu == 0)
592 return; 613 return;
593/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ 614/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
594 ns_update_menubar (frame, 1, self); 615#if ! defined(NS_IMPL_COCOA) || \
616 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
617 /* Don't know how to do this for anything other than OSX >= 10.5
618 This is wrong, as it might run Lisp code in the event loop. */
619 ns_update_menubar (frame, true, self);
620#endif
595} 621}
596 622
597 623
@@ -714,7 +740,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
714 [self setSubmenu: submenu forItem: item]; 740 [self setSubmenu: submenu forItem: item];
715 [submenu fillWithWidgetValue: wv->contents]; 741 [submenu fillWithWidgetValue: wv->contents];
716 [submenu release]; 742 [submenu release];
717 [item setAction: nil]; 743 [item setAction: (SEL)nil];
718 } 744 }
719 } 745 }
720 746
@@ -731,7 +757,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
731{ 757{
732 NSString *titleStr = [NSString stringWithUTF8String: title]; 758 NSString *titleStr = [NSString stringWithUTF8String: title];
733 NSMenuItem *item = [self addItemWithTitle: titleStr 759 NSMenuItem *item = [self addItemWithTitle: titleStr
734 action: nil /*@selector (menuDown:) */ 760 action: (SEL)nil /*@selector (menuDown:) */
735 keyEquivalent: @""]; 761 keyEquivalent: @""];
736 EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr frame: f]; 762 EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr frame: f];
737 [self setSubmenu: submenu forItem: item]; 763 [self setSubmenu: submenu forItem: item];
@@ -1019,13 +1045,18 @@ update_frame_tool_bar (FRAME_PTR f)
1019 Update toolbar contents 1045 Update toolbar contents
1020 -------------------------------------------------------------------------- */ 1046 -------------------------------------------------------------------------- */
1021{ 1047{
1022 int i; 1048 int i, k = 0;
1023 EmacsView *view = FRAME_NS_VIEW (f); 1049 EmacsView *view = FRAME_NS_VIEW (f);
1024 NSWindow *window = [view window]; 1050 NSWindow *window = [view window];
1025 EmacsToolbar *toolbar = [view toolbar]; 1051 EmacsToolbar *toolbar = [view toolbar];
1026 1052
1027 block_input (); 1053 block_input ();
1054
1055#ifdef NS_IMPL_COCOA
1028 [toolbar clearActive]; 1056 [toolbar clearActive];
1057#else
1058 [toolbar clearAll];
1059#endif
1029 1060
1030 /* update EmacsToolbar as in GtkUtils, build items list */ 1061 /* update EmacsToolbar as in GtkUtils, build items list */
1031 for (i = 0; i < f->n_tool_bar_items; ++i) 1062 for (i = 0; i < f->n_tool_bar_items; ++i)
@@ -1041,6 +1072,15 @@ update_frame_tool_bar (FRAME_PTR f)
1041 Lisp_Object helpObj; 1072 Lisp_Object helpObj;
1042 const char *helpText; 1073 const char *helpText;
1043 1074
1075 /* Check if this is a separator. */
1076 if (EQ (TOOLPROP (TOOL_BAR_ITEM_TYPE), Qt))
1077 {
1078 /* Skip separators. Newer OSX don't show them, and on GNUStep they
1079 are wide as a button, thus overflowing the toolbar most of
1080 the time. */
1081 continue;
1082 }
1083
1044 /* If image is a vector, choose the image according to the 1084 /* If image is a vector, choose the image according to the
1045 button state. */ 1085 button state. */
1046 image = TOOLPROP (TOOL_BAR_ITEM_IMAGES); 1086 image = TOOLPROP (TOOL_BAR_ITEM_IMAGES);
@@ -1077,7 +1117,10 @@ update_frame_tool_bar (FRAME_PTR f)
1077 continue; 1117 continue;
1078 } 1118 }
1079 1119
1080 [toolbar addDisplayItemWithImage: img->pixmap idx: i helpText: helpText 1120 [toolbar addDisplayItemWithImage: img->pixmap
1121 idx: k++
1122 tag: i
1123 helpText: helpText
1081 enabled: enabled_p]; 1124 enabled: enabled_p];
1082#undef TOOLPROP 1125#undef TOOLPROP
1083 } 1126 }
@@ -1085,6 +1128,7 @@ update_frame_tool_bar (FRAME_PTR f)
1085 if (![toolbar isVisible]) 1128 if (![toolbar isVisible])
1086 [toolbar setVisible: YES]; 1129 [toolbar setVisible: YES];
1087 1130
1131#ifdef NS_IMPL_COCOA
1088 if ([toolbar changed]) 1132 if ([toolbar changed])
1089 { 1133 {
1090 /* inform app that toolbar has changed */ 1134 /* inform app that toolbar has changed */
@@ -1106,6 +1150,7 @@ update_frame_tool_bar (FRAME_PTR f)
1106 [toolbar setConfigurationFromDictionary: newDict]; 1150 [toolbar setConfigurationFromDictionary: newDict];
1107 [newDict release]; 1151 [newDict release];
1108 } 1152 }
1153#endif
1109 1154
1110 FRAME_TOOLBAR_HEIGHT (f) = 1155 FRAME_TOOLBAR_HEIGHT (f) =
1111 NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) 1156 NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
@@ -1133,6 +1178,7 @@ update_frame_tool_bar (FRAME_PTR f)
1133 [self setDelegate: self]; 1178 [self setDelegate: self];
1134 identifierToItem = [[NSMutableDictionary alloc] initWithCapacity: 10]; 1179 identifierToItem = [[NSMutableDictionary alloc] initWithCapacity: 10];
1135 activeIdentifiers = [[NSMutableArray alloc] initWithCapacity: 8]; 1180 activeIdentifiers = [[NSMutableArray alloc] initWithCapacity: 8];
1181 prevIdentifiers = nil;
1136 prevEnablement = enablement = 0L; 1182 prevEnablement = enablement = 0L;
1137 return self; 1183 return self;
1138} 1184}
@@ -1154,18 +1200,29 @@ update_frame_tool_bar (FRAME_PTR f)
1154 enablement = 0L; 1200 enablement = 0L;
1155} 1201}
1156 1202
1203- (void) clearAll
1204{
1205 [self clearActive];
1206 while ([[self items] count] > 0)
1207 [self removeItemAtIndex: 0];
1208}
1209
1157- (BOOL) changed 1210- (BOOL) changed
1158{ 1211{
1159 return [activeIdentifiers isEqualToArray: prevIdentifiers] && 1212 return [activeIdentifiers isEqualToArray: prevIdentifiers] &&
1160 enablement == prevEnablement ? NO : YES; 1213 enablement == prevEnablement ? NO : YES;
1161} 1214}
1162 1215
1163- (void) addDisplayItemWithImage: (EmacsImage *)img idx: (int)idx 1216- (void) addDisplayItemWithImage: (EmacsImage *)img
1164 helpText: (const char *)help enabled: (BOOL)enabled 1217 idx: (int)idx
1218 tag: (int)tag
1219 helpText: (const char *)help
1220 enabled: (BOOL)enabled
1165{ 1221{
1166 /* 1) come up w/identifier */ 1222 /* 1) come up w/identifier */
1167 NSString *identifier 1223 NSString *identifier
1168 = [NSString stringWithFormat: @"%u", [img hash]]; 1224 = [NSString stringWithFormat: @"%u", [img hash]];
1225 [activeIdentifiers addObject: identifier];
1169 1226
1170 /* 2) create / reuse item */ 1227 /* 2) create / reuse item */
1171 NSToolbarItem *item = [identifierToItem objectForKey: identifier]; 1228 NSToolbarItem *item = [identifierToItem objectForKey: identifier];
@@ -1177,20 +1234,25 @@ update_frame_tool_bar (FRAME_PTR f)
1177 [item setToolTip: [NSString stringWithUTF8String: help]]; 1234 [item setToolTip: [NSString stringWithUTF8String: help]];
1178 [item setTarget: emacsView]; 1235 [item setTarget: emacsView];
1179 [item setAction: @selector (toolbarClicked:)]; 1236 [item setAction: @selector (toolbarClicked:)];
1237 [identifierToItem setObject: item forKey: identifier];
1180 } 1238 }
1181 1239
1182 [item setTag: idx]; 1240#ifdef NS_IMPL_GNUSTEP
1241 [self insertItemWithItemIdentifier: identifier atIndex: idx];
1242#endif
1243
1244 [item setTag: tag];
1183 [item setEnabled: enabled]; 1245 [item setEnabled: enabled];
1184 1246
1185 /* 3) update state */ 1247 /* 3) update state */
1186 [identifierToItem setObject: item forKey: identifier];
1187 [activeIdentifiers addObject: identifier];
1188 enablement = (enablement << 1) | (enabled == YES); 1248 enablement = (enablement << 1) | (enabled == YES);
1189} 1249}
1190 1250
1191/* This overrides super's implementation, which automatically sets 1251/* This overrides super's implementation, which automatically sets
1192 all items to enabled state (for some reason). */ 1252 all items to enabled state (for some reason). */
1193- (void)validateVisibleItems { } 1253- (void)validateVisibleItems
1254{
1255}
1194 1256
1195 1257
1196/* delegate methods */ 1258/* delegate methods */
@@ -1213,7 +1275,8 @@ update_frame_tool_bar (FRAME_PTR f)
1213- (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar 1275- (NSArray *)toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar
1214{ 1276{
1215 /* return entire set... */ 1277 /* return entire set... */
1216 return [identifierToItem allKeys]; 1278 return activeIdentifiers;
1279 //return [identifierToItem allKeys];
1217} 1280}
1218 1281
1219/* optional and unneeded */ 1282/* optional and unneeded */
@@ -1300,6 +1363,7 @@ update_frame_tool_bar (FRAME_PTR f)
1300 wr.size = [textField frame].size; 1363 wr.size = [textField frame].size;
1301 1364
1302 [win setFrame: wr display: YES]; 1365 [win setFrame: wr display: YES];
1366 [win setLevel: NSPopUpMenuWindowLevel];
1303 [win orderFront: self]; 1367 [win orderFront: self];
1304 [win display]; 1368 [win display];
1305 timer = [NSTimer scheduledTimerWithTimeInterval: (float)seconds target: self 1369 timer = [NSTimer scheduledTimerWithTimeInterval: (float)seconds target: self
@@ -1380,8 +1444,6 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1380 1444
1381 NSTRACE (x-popup-dialog); 1445 NSTRACE (x-popup-dialog);
1382 1446
1383 check_ns ();
1384
1385 isQ = NILP (header); 1447 isQ = NILP (header);
1386 1448
1387 if (EQ (position, Qt) 1449 if (EQ (position, Qt)
@@ -1419,6 +1481,8 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1419 else 1481 else
1420 CHECK_WINDOW (window); 1482 CHECK_WINDOW (window);
1421 1483
1484 check_window_system (f);
1485
1422 p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2; 1486 p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2;
1423 p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2; 1487 p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
1424 1488
@@ -1504,7 +1568,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1504 [img autorelease]; 1568 [img autorelease];
1505 [imgView autorelease]; 1569 [imgView autorelease];
1506 1570
1507 aStyle = NSTitledWindowMask; 1571 aStyle = NSTitledWindowMask|NSClosableWindowMask|NSUtilityWindowMask;
1508 flag = YES; 1572 flag = YES;
1509 rows = 0; 1573 rows = 0;
1510 cols = 1; 1574 cols = 1;
@@ -1572,9 +1636,6 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
1572 [self setOneShot: YES]; 1636 [self setOneShot: YES];
1573 [self setReleasedWhenClosed: YES]; 1637 [self setReleasedWhenClosed: YES];
1574 [self setHidesOnDeactivate: YES]; 1638 [self setHidesOnDeactivate: YES];
1575 [self setStyleMask:
1576 NSTitledWindowMask|NSClosableWindowMask|NSUtilityWindowMask];
1577
1578 return self; 1639 return self;
1579} 1640}
1580 1641
diff --git a/src/nsselect.m b/src/nsselect.m
index 49380f87945..6053ee9ceb2 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -182,7 +182,7 @@ ns_get_local_selection (Lisp_Object selection_name,
182 Lisp_Object target_type) 182 Lisp_Object target_type)
183{ 183{
184 Lisp_Object local_value; 184 Lisp_Object local_value;
185 Lisp_Object handler_fn, value, type, check; 185 Lisp_Object handler_fn, value, check;
186 ptrdiff_t count; 186 ptrdiff_t count;
187 187
188 local_value = assq_no_quit (selection_name, Vselection_alist); 188 local_value = assq_no_quit (selection_name, Vselection_alist);
@@ -203,7 +203,6 @@ ns_get_local_selection (Lisp_Object selection_name,
203 check = value; 203 check = value;
204 if (CONSP (value) && SYMBOLP (XCAR (value))) 204 if (CONSP (value) && SYMBOLP (XCAR (value)))
205 { 205 {
206 type = XCAR (value);
207 check = XCDR (value); 206 check = XCDR (value);
208 } 207 }
209 208
@@ -354,8 +353,7 @@ On Nextstep, FRAME is unused. */)
354 Lisp_Object successful_p = Qnil, rest; 353 Lisp_Object successful_p = Qnil, rest;
355 Lisp_Object target_symbol, data; 354 Lisp_Object target_symbol, data;
356 355
357 356 check_window_system (NULL);
358 check_ns ();
359 CHECK_SYMBOL (selection); 357 CHECK_SYMBOL (selection);
360 if (NILP (value)) 358 if (NILP (value))
361 error ("selection value may not be nil."); 359 error ("selection value may not be nil.");
@@ -409,7 +407,7 @@ On MS-DOS, all this does is return non-nil if we own the selection. */)
409 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal) 407 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
410{ 408{
411 id pb; 409 id pb;
412 check_ns (); 410 check_window_system (NULL);
413 CHECK_SYMBOL (selection); 411 CHECK_SYMBOL (selection);
414 if (NILP (assq_no_quit (selection, Vselection_alist))) return Qnil; 412 if (NILP (assq_no_quit (selection, Vselection_alist))) return Qnil;
415 413
@@ -436,7 +434,7 @@ On Nextstep, TERMINAL is unused. */)
436 id pb; 434 id pb;
437 NSArray *types; 435 NSArray *types;
438 436
439 check_ns (); 437 check_window_system (NULL);
440 CHECK_SYMBOL (selection); 438 CHECK_SYMBOL (selection);
441 if (EQ (selection, Qnil)) selection = QPRIMARY; 439 if (EQ (selection, Qnil)) selection = QPRIMARY;
442 if (EQ (selection, Qt)) selection = QSECONDARY; 440 if (EQ (selection, Qt)) selection = QSECONDARY;
@@ -464,7 +462,7 @@ frame's display, or the first available X display.
464On Nextstep, TERMINAL is unused. */) 462On Nextstep, TERMINAL is unused. */)
465 (Lisp_Object selection, Lisp_Object terminal) 463 (Lisp_Object selection, Lisp_Object terminal)
466{ 464{
467 check_ns (); 465 check_window_system (NULL);
468 CHECK_SYMBOL (selection); 466 CHECK_SYMBOL (selection);
469 if (EQ (selection, Qnil)) selection = QPRIMARY; 467 if (EQ (selection, Qnil)) selection = QPRIMARY;
470 if (EQ (selection, Qt)) selection = QSECONDARY; 468 if (EQ (selection, Qt)) selection = QSECONDARY;
@@ -492,7 +490,7 @@ On Nextstep, TIME-STAMP and TERMINAL are unused. */)
492{ 490{
493 Lisp_Object val; 491 Lisp_Object val;
494 492
495 check_ns (); 493 check_window_system (NULL);
496 CHECK_SYMBOL (selection_name); 494 CHECK_SYMBOL (selection_name);
497 CHECK_SYMBOL (target_type); 495 CHECK_SYMBOL (target_type);
498 val = ns_get_local_selection (selection_name, target_type); 496 val = ns_get_local_selection (selection_name, target_type);
@@ -516,7 +514,7 @@ SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
516 (Lisp_Object selection) 514 (Lisp_Object selection)
517{ 515{
518 id pb; 516 id pb;
519 check_ns (); 517 check_window_system (NULL);
520 pb = ns_symbol_to_pb (selection); 518 pb = ns_symbol_to_pb (selection);
521 return pb != nil ? ns_string_from_pasteboard (pb) : Qnil; 519 return pb != nil ? ns_string_from_pasteboard (pb) : Qnil;
522} 520}
@@ -529,7 +527,7 @@ SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
529 (Lisp_Object selection, Lisp_Object string) 527 (Lisp_Object selection, Lisp_Object string)
530{ 528{
531 id pb; 529 id pb;
532 check_ns (); 530 check_window_system (NULL);
533 pb = ns_symbol_to_pb (selection); 531 pb = ns_symbol_to_pb (selection);
534 if (pb != nil) ns_string_to_pasteboard (pb, string); 532 if (pb != nil) ns_string_to_pasteboard (pb, string);
535 return Qnil; 533 return Qnil;
diff --git a/src/nsterm.h b/src/nsterm.h
index 6bd04b96684..fd8c9baa3e4 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -51,6 +51,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
51 51
52#ifdef __OBJC__ 52#ifdef __OBJC__
53 53
54/* CGFloat on GNUStep may be 4 or 8 byte, but functions expect float* for some
55 versions.
56 On Cocoa, functions expect CGFloat*. Make compatible type. */
57#if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \
58 GNUSTEP_GUI_MINOR_VERSION >= 22
59typedef CGFloat EmacsCGFloat;
60#else
61typedef float EmacsCGFloat;
62#endif
63
54/* ========================================================================== 64/* ==========================================================================
55 65
56 The Emacs application 66 The Emacs application
@@ -60,6 +70,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
60/* We override sendEvent: as a means to stop/start the event loop */ 70/* We override sendEvent: as a means to stop/start the event loop */
61@interface EmacsApp : NSApplication 71@interface EmacsApp : NSApplication
62{ 72{
73#ifdef NS_IMPL_GNUSTEP
74@public
75 int nextappdefined;
76#endif
63} 77}
64- (void)logNotification: (NSNotification *)notification; 78- (void)logNotification: (NSNotification *)notification;
65- (void)sendEvent: (NSEvent *)theEvent; 79- (void)sendEvent: (NSEvent *)theEvent;
@@ -68,8 +82,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
68- (void)fd_handler: (id)unused; 82- (void)fd_handler: (id)unused;
69- (void)timeout_handler: (NSTimer *)timedEntry; 83- (void)timeout_handler: (NSTimer *)timedEntry;
70- (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg; 84- (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg;
85#ifdef NS_IMPL_GNUSTEP
86- (void)sendFromMainThread:(id)unused;
87#endif
71@end 88@end
72 89
90#ifdef NS_IMPL_GNUSTEP
91/* Dummy class to get rid of startup warnings. */
92@interface EmacsDocument : NSDocument
93{
94}
95@end
96#endif
73 97
74/* ========================================================================== 98/* ==========================================================================
75 99
@@ -128,8 +152,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
128#endif 152#endif
129 153
130#ifdef NS_IMPL_GNUSTEP 154#ifdef NS_IMPL_GNUSTEP
131/* Not declared, but useful. */ 155- (void)windowDidMove: (id)sender;
132- (void) unlockFocusNeedsFlush: (BOOL)needs;
133#endif 156#endif
134@end 157@end
135 158
@@ -199,10 +222,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
199 } 222 }
200- initForView: (EmacsView *)view withIdentifier: (NSString *)identifier; 223- initForView: (EmacsView *)view withIdentifier: (NSString *)identifier;
201- (void) clearActive; 224- (void) clearActive;
225- (void) clearAll;
202- (BOOL) changed; 226- (BOOL) changed;
203- (void) addDisplayItemWithImage: (EmacsImage *)img idx: (int)idx 227- (void) addDisplayItemWithImage: (EmacsImage *)img
228 idx: (int)idx
229 tag: (int)tag
204 helpText: (const char *)help 230 helpText: (const char *)help
205 enabled: (BOOL)enabled; 231 enabled: (BOOL)enabled;
232
206/* delegate methods */ 233/* delegate methods */
207- (NSToolbarItem *)toolbar: (NSToolbar *)toolbar 234- (NSToolbarItem *)toolbar: (NSToolbar *)toolbar
208 itemForItemIdentifier: (NSString *)itemIdentifier 235 itemForItemIdentifier: (NSString *)itemIdentifier
@@ -267,14 +294,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
267@interface EmacsSavePanel : NSSavePanel 294@interface EmacsSavePanel : NSSavePanel
268{ 295{
269} 296}
270- (NSString *) getFilename;
271- (NSString *) getDirectory;
272@end 297@end
273@interface EmacsOpenPanel : NSOpenPanel 298@interface EmacsOpenPanel : NSOpenPanel
274{ 299{
275} 300}
276- (NSString *) getFilename;
277- (NSString *) getDirectory;
278@end 301@end
279 302
280@interface EmacsFileDelegate : NSObject 303@interface EmacsFileDelegate : NSObject
@@ -335,7 +358,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
335 NSResponder *prevResponder; 358 NSResponder *prevResponder;
336 359
337 /* offset to the bottom of knob of last mouse down */ 360 /* offset to the bottom of knob of last mouse down */
338 float last_mouse_offset; 361 CGFloat last_mouse_offset;
339 float min_portion; 362 float min_portion;
340 int pixel_height; 363 int pixel_height;
341 int last_hit_part; 364 int last_hit_part;
@@ -577,8 +600,6 @@ extern Lisp_Object ns_display_name_list;
577extern struct ns_display_info *ns_display_info_for_name (Lisp_Object name); 600extern struct ns_display_info *ns_display_info_for_name (Lisp_Object name);
578 601
579struct ns_display_info *check_x_display_info (Lisp_Object frame); 602struct ns_display_info *check_x_display_info (Lisp_Object frame);
580FRAME_PTR check_x_frame (Lisp_Object frame);
581
582 603
583struct ns_output 604struct ns_output
584{ 605{
@@ -764,7 +785,6 @@ extern void ns_clear_frame (struct frame *f);
764 785
765extern const char *ns_xlfd_to_fontname (const char *xlfd); 786extern const char *ns_xlfd_to_fontname (const char *xlfd);
766 787
767extern void check_ns (void);
768extern Lisp_Object ns_map_event_to_object (void); 788extern Lisp_Object ns_map_event_to_object (void);
769#ifdef __OBJC__ 789#ifdef __OBJC__
770extern Lisp_Object ns_string_from_pasteboard (id pb); 790extern Lisp_Object ns_string_from_pasteboard (id pb);
@@ -792,6 +812,9 @@ extern int ns_lisp_to_color (Lisp_Object color, NSColor **col);
792extern NSColor *ns_lookup_indexed_color (unsigned long idx, struct frame *f); 812extern NSColor *ns_lookup_indexed_color (unsigned long idx, struct frame *f);
793extern unsigned long ns_index_color (NSColor *color, struct frame *f); 813extern unsigned long ns_index_color (NSColor *color, struct frame *f);
794extern void ns_free_indexed_color (unsigned long idx, struct frame *f); 814extern void ns_free_indexed_color (unsigned long idx, struct frame *f);
815extern const char *ns_get_pending_menu_title (void);
816extern void ns_check_menu_open (NSMenu *menu);
817extern void ns_check_pending_open_menu (void);
795#endif 818#endif
796 819
797/* C access to ObjC functionality */ 820/* C access to ObjC functionality */
@@ -840,6 +863,7 @@ extern int x_display_pixel_height (struct ns_display_info *);
840extern int x_display_pixel_width (struct ns_display_info *); 863extern int x_display_pixel_width (struct ns_display_info *);
841 864
842/* This in nsterm.m */ 865/* This in nsterm.m */
866extern void x_destroy_window (struct frame *f);
843extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, 867extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
844 fd_set *exceptfds, EMACS_TIME *timeout, 868 fd_set *exceptfds, EMACS_TIME *timeout,
845 sigset_t *sigmask); 869 sigset_t *sigmask);
diff --git a/src/nsterm.m b/src/nsterm.m
index 40e506eab27..9cf138837f6 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -60,6 +60,10 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
60#include "buffer.h" 60#include "buffer.h"
61#include "font.h" 61#include "font.h"
62 62
63#ifdef NS_IMPL_GNUSTEP
64#include "process.h"
65#endif
66
63/* call tracing */ 67/* call tracing */
64#if 0 68#if 0
65int term_trace_num = 0; 69int term_trace_num = 0;
@@ -196,7 +200,9 @@ static BOOL gsaved = NO;
196static BOOL ns_fake_keydown = NO; 200static BOOL ns_fake_keydown = NO;
197int ns_tmp_flags; /* FIXME */ 201int ns_tmp_flags; /* FIXME */
198struct nsfont_info *ns_tmp_font; /* FIXME */ 202struct nsfont_info *ns_tmp_font; /* FIXME */
203#ifdef NS_IMPL_COCOA
199static BOOL ns_menu_bar_is_hidden = NO; 204static BOOL ns_menu_bar_is_hidden = NO;
205#endif
200/*static int debug_lock = 0; */ 206/*static int debug_lock = 0; */
201 207
202/* event loop */ 208/* event loop */
@@ -228,6 +234,27 @@ static struct {
228 NULL, 0, 0 234 NULL, 0, 0
229}; 235};
230 236
237#ifdef NS_IMPL_COCOA
238/*
239 * State for pending menu activation:
240 * MENU_NONE Normal state
241 * MENU_PENDING A menu has been clicked on, but has been canceled so we can
242 * run lisp to update the menu.
243 * MENU_OPENING Menu is up to date, and the click event is redone so the menu
244 * will open.
245 */
246#define MENU_NONE 0
247#define MENU_PENDING 1
248#define MENU_OPENING 2
249static int menu_will_open_state = MENU_NONE;
250
251/* Saved position for menu click. */
252static CGPoint menu_mouse_point;
253
254/* Title for the menu to open. */
255static char *menu_pending_title = 0;
256#endif
257
231/* Convert modifiers in a NeXTstep event to emacs style modifiers. */ 258/* Convert modifiers in a NeXTstep event to emacs style modifiers. */
232#define NS_FUNCTION_KEY_MASK 0x800000 259#define NS_FUNCTION_KEY_MASK 0x800000
233#define NSLeftControlKeyMask (0x000001 | NSControlKeyMask) 260#define NSLeftControlKeyMask (0x000001 | NSControlKeyMask)
@@ -298,8 +325,6 @@ static struct {
298 ns_send_appdefined (-1); \ 325 ns_send_appdefined (-1); \
299 } 326 }
300 327
301void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
302
303/* TODO: get rid of need for these forward declarations */ 328/* TODO: get rid of need for these forward declarations */
304static void ns_condemn_scroll_bars (struct frame *f); 329static void ns_condemn_scroll_bars (struct frame *f);
305static void ns_judge_scroll_bars (struct frame *f); 330static void ns_judge_scroll_bars (struct frame *f);
@@ -651,8 +676,6 @@ ns_update_begin (struct frame *f)
651 -------------------------------------------------------------------------- */ 676 -------------------------------------------------------------------------- */
652{ 677{
653 NSView *view = FRAME_NS_VIEW (f); 678 NSView *view = FRAME_NS_VIEW (f);
654 NSRect r = [view frame];
655 NSBezierPath *bp;
656 NSTRACE (ns_update_begin); 679 NSTRACE (ns_update_begin);
657 680
658 ns_update_auto_hide_menu_bar (); 681 ns_update_auto_hide_menu_bar ();
@@ -664,9 +687,15 @@ ns_update_begin (struct frame *f)
664 is for the minibuffer. But the display engine may draw more because 687 is for the minibuffer. But the display engine may draw more because
665 we have set the frame as garbaged. So reset clip path to the whole 688 we have set the frame as garbaged. So reset clip path to the whole
666 view. */ 689 view. */
690#ifdef NS_IMPL_COCOA
691 {
692 NSBezierPath *bp;
693 NSRect r = [view frame];
667 bp = [[NSBezierPath bezierPathWithRect: r] retain]; 694 bp = [[NSBezierPath bezierPathWithRect: r] retain];
668 [bp setClip]; 695 [bp setClip];
669 [bp release]; 696 [bp release];
697 }
698#endif
670 699
671#ifdef NS_IMPL_GNUSTEP 700#ifdef NS_IMPL_GNUSTEP
672 uRect = NSMakeRect (0, 0, 0, 0); 701 uRect = NSMakeRect (0, 0, 0, 0);
@@ -753,20 +782,13 @@ ns_update_end (struct frame *f)
753 external (RIF) call; for whole frame, called after update_window_end 782 external (RIF) call; for whole frame, called after update_window_end
754 -------------------------------------------------------------------------- */ 783 -------------------------------------------------------------------------- */
755{ 784{
756 NSView *view = FRAME_NS_VIEW (f); 785 EmacsView *view = FRAME_NS_VIEW (f);
757 786
758/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ 787/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
759 MOUSE_HL_INFO (f)->mouse_face_defer = 0; 788 MOUSE_HL_INFO (f)->mouse_face_defer = 0;
760 789
761 block_input (); 790 block_input ();
762 791
763#ifdef NS_IMPL_GNUSTEP
764 /* trigger flush only in the rectangle we tracked as being drawn */
765 [view unlockFocusNeedsFlush: NO];
766/*fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", uRect.origin.x, uRect.origin.y, uRect.size.width, uRect.size.height); */
767 [view lockFocusInRect: uRect];
768#endif
769
770 [view unlockFocus]; 792 [view unlockFocus];
771 [[view window] flushWindow]; 793 [[view window] flushWindow];
772 794
@@ -799,13 +821,6 @@ ns_focus (struct frame *f, NSRect *r, int n)
799 -------------------------------------------------------------------------- */ 821 -------------------------------------------------------------------------- */
800{ 822{
801// NSTRACE (ns_focus); 823// NSTRACE (ns_focus);
802#ifdef NS_IMPL_GNUSTEP
803 NSRect u;
804 if (n == 2)
805 u = NSUnionRect (r[0], r[1]);
806 else if (r)
807 u = *r;
808#endif
809/* static int c =0; 824/* static int c =0;
810 fprintf (stderr, "focus: %d", c++); 825 fprintf (stderr, "focus: %d", c++);
811 if (r) fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", r->origin.x, r->origin.y, r->size.width, r->size.height); 826 if (r) fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", r->origin.x, r->origin.y, r->size.width, r->size.height);
@@ -824,33 +839,11 @@ ns_focus (struct frame *f, NSRect *r, int n)
824 } 839 }
825 840
826 if (view) 841 if (view)
827#ifdef NS_IMPL_GNUSTEP
828 r ? [view lockFocusInRect: u] : [view lockFocus];
829#else
830 [view lockFocus]; 842 [view lockFocus];
831#endif
832 focus_view = view; 843 focus_view = view;
833/*if (view) debug_lock++; */ 844/*if (view) debug_lock++; */
834 } 845 }
835#ifdef NS_IMPL_GNUSTEP
836 else
837 {
838 /* more than one rect being drawn into */
839 if (view && r)
840 {
841 [view unlockFocus]; /* add prev rect to redraw list */
842 [view lockFocusInRect: u]; /* focus for draw in new rect */
843 }
844 }
845#endif
846 } 846 }
847#ifdef NS_IMPL_GNUSTEP
848 else
849 {
850 /* in batch mode, but in GNUstep must still track rectangles explicitly */
851 uRect = (r ? NSUnionRect (uRect, u) : [FRAME_NS_VIEW (f) visibleRect]);
852 }
853#endif
854 847
855 /* clipping */ 848 /* clipping */
856 if (r) 849 if (r)
@@ -993,8 +986,9 @@ ns_raise_frame (struct frame *f)
993 Bring window to foreground and make it active 986 Bring window to foreground and make it active
994 -------------------------------------------------------------------------- */ 987 -------------------------------------------------------------------------- */
995{ 988{
996 NSView *view = FRAME_NS_VIEW (f); 989 NSView *view;
997 check_ns (); 990 check_window_system (f);
991 view = FRAME_NS_VIEW (f);
998 block_input (); 992 block_input ();
999 if (FRAME_VISIBLE_P (f)) 993 if (FRAME_VISIBLE_P (f))
1000 [[view window] makeKeyAndOrderFront: NSApp]; 994 [[view window] makeKeyAndOrderFront: NSApp];
@@ -1008,8 +1002,9 @@ ns_lower_frame (struct frame *f)
1008 Send window to back 1002 Send window to back
1009 -------------------------------------------------------------------------- */ 1003 -------------------------------------------------------------------------- */
1010{ 1004{
1011 NSView *view = FRAME_NS_VIEW (f); 1005 NSView *view;
1012 check_ns (); 1006 check_window_system (f);
1007 view = FRAME_NS_VIEW (f);
1013 block_input (); 1008 block_input ();
1014 [[view window] orderBack: NSApp]; 1009 [[view window] orderBack: NSApp];
1015 unblock_input (); 1010 unblock_input ();
@@ -1112,9 +1107,10 @@ x_make_frame_invisible (struct frame *f)
1112 External: Hide the window (X11 semantics) 1107 External: Hide the window (X11 semantics)
1113 -------------------------------------------------------------------------- */ 1108 -------------------------------------------------------------------------- */
1114{ 1109{
1115 NSView * view = FRAME_NS_VIEW (f); 1110 NSView *view;
1116 NSTRACE (x_make_frame_invisible); 1111 NSTRACE (x_make_frame_invisible);
1117 check_ns (); 1112 check_window_system (f);
1113 view = FRAME_NS_VIEW (f);
1118 [[view window] orderOut: NSApp]; 1114 [[view window] orderOut: NSApp];
1119 SET_FRAME_VISIBLE (f, 0); 1115 SET_FRAME_VISIBLE (f, 0);
1120 SET_FRAME_ICONIFIED (f, 0); 1116 SET_FRAME_ICONIFIED (f, 0);
@@ -1127,10 +1123,13 @@ x_iconify_frame (struct frame *f)
1127 External: Iconify window 1123 External: Iconify window
1128 -------------------------------------------------------------------------- */ 1124 -------------------------------------------------------------------------- */
1129{ 1125{
1130 NSView * view = FRAME_NS_VIEW (f); 1126 NSView *view;
1131 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); 1127 struct ns_display_info *dpyinfo;
1128
1132 NSTRACE (x_iconify_frame); 1129 NSTRACE (x_iconify_frame);
1133 check_ns (); 1130 check_window_system (f);
1131 view = FRAME_NS_VIEW (f);
1132 dpyinfo = FRAME_NS_DISPLAY_INFO (f);
1134 1133
1135 if (dpyinfo->x_highlight_frame == f) 1134 if (dpyinfo->x_highlight_frame == f)
1136 dpyinfo->x_highlight_frame = 0; 1135 dpyinfo->x_highlight_frame = 0;
@@ -1155,11 +1154,15 @@ x_iconify_frame (struct frame *f)
1155void 1154void
1156x_free_frame_resources (struct frame *f) 1155x_free_frame_resources (struct frame *f)
1157{ 1156{
1158 NSView *view = FRAME_NS_VIEW (f); 1157 NSView *view;
1159 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); 1158 struct ns_display_info *dpyinfo;
1160 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); 1159 Mouse_HLInfo *hlinfo;
1160
1161 NSTRACE (x_free_frame_resources); 1161 NSTRACE (x_free_frame_resources);
1162 check_ns (); 1162 check_window_system (f);
1163 view = FRAME_NS_VIEW (f);
1164 dpyinfo = FRAME_NS_DISPLAY_INFO (f);
1165 hlinfo = MOUSE_HL_INFO (f);
1163 1166
1164 [(EmacsView *)view setWindowClosing: YES]; /* may not have been informed */ 1167 [(EmacsView *)view setWindowClosing: YES]; /* may not have been informed */
1165 1168
@@ -1200,7 +1203,7 @@ x_destroy_window (struct frame *f)
1200 -------------------------------------------------------------------------- */ 1203 -------------------------------------------------------------------------- */
1201{ 1204{
1202 NSTRACE (x_destroy_window); 1205 NSTRACE (x_destroy_window);
1203 check_ns (); 1206 check_window_system (f);
1204 x_free_frame_resources (f); 1207 x_free_frame_resources (f);
1205 ns_window_num--; 1208 ns_window_num--;
1206} 1209}
@@ -1288,12 +1291,17 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
1288 1291
1289 /* If we have a toolbar, take its height into account. */ 1292 /* If we have a toolbar, take its height into account. */
1290 if (tb && ! [view isFullscreen]) 1293 if (tb && ! [view isFullscreen])
1294 {
1291 /* NOTE: previously this would generate wrong result if toolbar not 1295 /* NOTE: previously this would generate wrong result if toolbar not
1292 yet displayed and fixing toolbar_height=32 helped, but 1296 yet displayed and fixing toolbar_height=32 helped, but
1293 now (200903) seems no longer needed */ 1297 now (200903) seems no longer needed */
1294 FRAME_TOOLBAR_HEIGHT (f) = 1298 FRAME_TOOLBAR_HEIGHT (f) =
1295 NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) 1299 NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
1296 - FRAME_NS_TITLEBAR_HEIGHT (f); 1300 - FRAME_NS_TITLEBAR_HEIGHT (f);
1301#ifdef NS_IMPL_GNUSTEP
1302 FRAME_TOOLBAR_HEIGHT (f) -= 3;
1303#endif
1304 }
1297 else 1305 else
1298 FRAME_TOOLBAR_HEIGHT (f) = 0; 1306 FRAME_TOOLBAR_HEIGHT (f) = 0;
1299 1307
@@ -1519,7 +1527,7 @@ ns_get_color (const char *name, NSColor **col)
1519 } 1527 }
1520 } 1528 }
1521 1529
1522 if (r >= 0.0) 1530 if (r >= 0.0F)
1523 { 1531 {
1524 *col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0]; 1532 *col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0];
1525 unblock_input (); 1533 unblock_input ();
@@ -1580,7 +1588,7 @@ ns_color_to_lisp (NSColor *col)
1580 Convert a color to a lisp string with the RGB equivalent 1588 Convert a color to a lisp string with the RGB equivalent
1581 -------------------------------------------------------------------------- */ 1589 -------------------------------------------------------------------------- */
1582{ 1590{
1583 CGFloat red, green, blue, alpha, gray; 1591 EmacsCGFloat red, green, blue, alpha, gray;
1584 char buf[1024]; 1592 char buf[1024];
1585 const char *str; 1593 const char *str;
1586 NSTRACE (ns_color_to_lisp); 1594 NSTRACE (ns_color_to_lisp);
@@ -1622,7 +1630,7 @@ ns_query_color(void *col, XColor *color_def, int setPixel)
1622 and set color_def pixel to the resulting index. 1630 and set color_def pixel to the resulting index.
1623 -------------------------------------------------------------------------- */ 1631 -------------------------------------------------------------------------- */
1624{ 1632{
1625 CGFloat r, g, b, a; 1633 EmacsCGFloat r, g, b, a;
1626 1634
1627 [((NSColor *)col) getRed: &r green: &g blue: &b alpha: &a]; 1635 [((NSColor *)col) getRed: &r green: &g blue: &b alpha: &a];
1628 color_def->red = r * 65535; 1636 color_def->red = r * 65535;
@@ -1667,26 +1675,6 @@ ns_defined_color (struct frame *f,
1667} 1675}
1668 1676
1669 1677
1670unsigned long
1671ns_get_rgb_color (struct frame *f, float r, float g, float b, float a)
1672/* --------------------------------------------------------------------------
1673 return an autoreleased RGB color
1674 -------------------------------------------------------------------------- */
1675{
1676/*static int c = 1; fprintf (stderr, "color request %d\n", c++); */
1677 if (r < 0.0) r = 0.0;
1678 else if (r > 1.0) r = 1.0;
1679 if (g < 0.0) g = 0.0;
1680 else if (g > 1.0) g = 1.0;
1681 if (b < 0.0) b = 0.0;
1682 else if (b > 1.0) b = 1.0;
1683 if (a < 0.0) a = 0.0;
1684 else if (a > 1.0) a = 1.0;
1685 return (unsigned long) ns_index_color(
1686 [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a], f);
1687}
1688
1689
1690void 1678void
1691x_set_frame_alpha (struct frame *f) 1679x_set_frame_alpha (struct frame *f)
1692/* -------------------------------------------------------------------------- 1680/* --------------------------------------------------------------------------
@@ -1694,7 +1682,6 @@ x_set_frame_alpha (struct frame *f)
1694 -------------------------------------------------------------------------- */ 1682 -------------------------------------------------------------------------- */
1695{ 1683{
1696 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); 1684 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
1697 EmacsView *view = FRAME_NS_VIEW (f);
1698 double alpha = 1.0; 1685 double alpha = 1.0;
1699 double alpha_min = 1.0; 1686 double alpha_min = 1.0;
1700 1687
@@ -1716,7 +1703,10 @@ x_set_frame_alpha (struct frame *f)
1716 alpha = alpha_min; 1703 alpha = alpha_min;
1717 1704
1718#ifdef NS_IMPL_COCOA 1705#ifdef NS_IMPL_COCOA
1706 {
1707 EmacsView *view = FRAME_NS_VIEW (f);
1719 [[view window] setAlphaValue: alpha]; 1708 [[view window] setAlphaValue: alpha];
1709 }
1720#endif 1710#endif
1721} 1711}
1722 1712
@@ -1769,7 +1759,7 @@ x_set_mouse_position (struct frame *f, int h, int v)
1769 1759
1770 1760
1771static int 1761static int
1772note_mouse_movement (struct frame *frame, float x, float y) 1762note_mouse_movement (struct frame *frame, CGFloat x, CGFloat y)
1773/* ------------------------------------------------------------------------ 1763/* ------------------------------------------------------------------------
1774 Called by EmacsView on mouseMovement events. Passes on 1764 Called by EmacsView on mouseMovement events. Passes on
1775 to emacs mainstream code if we moved off of a rect of interest 1765 to emacs mainstream code if we moved off of a rect of interest
@@ -1854,7 +1844,7 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
1854 f = dpyinfo->x_focus_frame ? dpyinfo->x_focus_frame 1844 f = dpyinfo->x_focus_frame ? dpyinfo->x_focus_frame
1855 : SELECTED_FRAME (); 1845 : SELECTED_FRAME ();
1856 1846
1857 if (f && f->output_data.ns) /* TODO: 2nd check no longer needed? */ 1847 if (f && FRAME_NS_P (f))
1858 { 1848 {
1859 view = FRAME_NS_VIEW (*fp); 1849 view = FRAME_NS_VIEW (*fp);
1860 1850
@@ -2228,7 +2218,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2228{ 2218{
2229 struct frame *f = XFRAME (WINDOW_FRAME (w)); 2219 struct frame *f = XFRAME (WINDOW_FRAME (w));
2230 struct face *face = p->face; 2220 struct face *face = p->face;
2231 int rowY;
2232 static EmacsImage **bimgs = NULL; 2221 static EmacsImage **bimgs = NULL;
2233 static int nBimgs = 0; 2222 static int nBimgs = 0;
2234 2223
@@ -2242,7 +2231,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2242 } 2231 }
2243 2232
2244 /* Must clip because of partially visible lines. */ 2233 /* Must clip because of partially visible lines. */
2245 rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
2246 ns_clip_to_row (w, row, -1, YES); 2234 ns_clip_to_row (w, row, -1, YES);
2247 2235
2248 if (!p->overlay_p) 2236 if (!p->overlay_p)
@@ -2330,7 +2318,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2330 [ns_lookup_indexed_color(face->background, f) set]; 2318 [ns_lookup_indexed_color(face->background, f) set];
2331 NSRectFill (r); 2319 NSRectFill (r);
2332 [img setXBMColor: ns_lookup_indexed_color(face->foreground, f)]; 2320 [img setXBMColor: ns_lookup_indexed_color(face->foreground, f)];
2333#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 2321#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
2334 [img drawInRect: r 2322 [img drawInRect: r
2335 fromRect: NSZeroRect 2323 fromRect: NSZeroRect
2336 operation: NSCompositeSourceOver 2324 operation: NSCompositeSourceOver
@@ -2362,7 +2350,6 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2362 int fx, fy, h, cursor_height; 2350 int fx, fy, h, cursor_height;
2363 struct frame *f = WINDOW_XFRAME (w); 2351 struct frame *f = WINDOW_XFRAME (w);
2364 struct glyph *phys_cursor_glyph; 2352 struct glyph *phys_cursor_glyph;
2365 int overspill;
2366 struct glyph *cursor_glyph; 2353 struct glyph *cursor_glyph;
2367 struct face *face; 2354 struct face *face;
2368 NSColor *hollow_color = FRAME_BACKGROUND_COLOR (f); 2355 NSColor *hollow_color = FRAME_BACKGROUND_COLOR (f);
@@ -2569,7 +2556,7 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2569 --------------------------------------------------------------------- */ 2556 --------------------------------------------------------------------- */
2570 2557
2571static void 2558static void
2572ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x) 2559ns_draw_underwave (struct glyph_string *s, EmacsCGFloat width, EmacsCGFloat x)
2573{ 2560{
2574 int wave_height = 3, wave_length = 2; 2561 int wave_height = 3, wave_length = 2;
2575 int y, dx, dy, odd, xmax; 2562 int y, dx, dy, odd, xmax;
@@ -2587,7 +2574,7 @@ ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x)
2587 NSRectClip (waveClip); 2574 NSRectClip (waveClip);
2588 2575
2589 /* Draw the waves */ 2576 /* Draw the waves */
2590 a.x = x - ((int)(x) % dx) + 0.5; 2577 a.x = x - ((int)(x) % dx) + (EmacsCGFloat) 0.5;
2591 b.x = a.x + dx; 2578 b.x = a.x + dx;
2592 odd = (int)(a.x/dx) % 2; 2579 odd = (int)(a.x/dx) % 2;
2593 a.y = b.y = y + 0.5; 2580 a.y = b.y = y + 0.5;
@@ -2727,7 +2714,8 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
2727} 2714}
2728 2715
2729static void 2716static void
2730ns_draw_box (NSRect r, float thickness, NSColor *col, char left_p, char right_p) 2717ns_draw_box (NSRect r, CGFloat thickness, NSColor *col,
2718 char left_p, char right_p)
2731/* -------------------------------------------------------------------------- 2719/* --------------------------------------------------------------------------
2732 Draw an unfilled rect inside r, optionally leaving left and/or right open. 2720 Draw an unfilled rect inside r, optionally leaving left and/or right open.
2733 Note we can't just use an NSDrawRect command, because of the possibility 2721 Note we can't just use an NSDrawRect command, because of the possibility
@@ -3004,7 +2992,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
3004 /* Draw the image.. do we need to draw placeholder if img ==nil? */ 2992 /* Draw the image.. do we need to draw placeholder if img ==nil? */
3005 if (img != nil) 2993 if (img != nil)
3006 { 2994 {
3007#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 2995#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
3008 NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height); 2996 NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height);
3009 NSRect ir = NSMakeRect (s->slice.x, s->slice.y, 2997 NSRect ir = NSMakeRect (s->slice.x, s->slice.y,
3010 s->slice.width, s->slice.height); 2998 s->slice.width, s->slice.height);
@@ -3329,6 +3317,19 @@ ns_send_appdefined (int value)
3329{ 3317{
3330 /*NSTRACE (ns_send_appdefined); */ 3318 /*NSTRACE (ns_send_appdefined); */
3331 3319
3320#ifdef NS_IMPL_GNUSTEP
3321 // GNUStep needs postEvent to happen on the main thread.
3322 if (! [[NSThread currentThread] isMainThread])
3323 {
3324 EmacsApp *app = (EmacsApp *)NSApp;
3325 app->nextappdefined = value;
3326 [app performSelectorOnMainThread:@selector (sendFromMainThread:)
3327 withObject:nil
3328 waitUntilDone:YES];
3329 return;
3330 }
3331#endif
3332
3332 /* Only post this event if we haven't already posted one. This will end 3333 /* Only post this event if we haven't already posted one. This will end
3333 the [NXApp run] main loop after having processed all events queued at 3334 the [NXApp run] main loop after having processed all events queued at
3334 this moment. */ 3335 this moment. */
@@ -3388,6 +3389,73 @@ check_native_fs ()
3388} 3389}
3389#endif 3390#endif
3390 3391
3392/* GNUStep and OSX <= 10.4 does not have cancelTracking. */
3393#if defined (NS_IMPL_COCOA) && \
3394 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
3395const char *
3396ns_get_pending_menu_title ()
3397{
3398 return menu_pending_title;
3399}
3400
3401/* Check if menu open should be cancelled or continued as normal. */
3402void
3403ns_check_menu_open (NSMenu *menu)
3404{
3405 /* Click in menu bar? */
3406 NSArray *a = [[NSApp mainMenu] itemArray];
3407 int i;
3408 BOOL found = NO;
3409 for (i = 0; ! found && i < [a count]; i++)
3410 found = menu == [[a objectAtIndex:i] submenu];
3411 if (found)
3412 {
3413 if (menu_will_open_state == MENU_NONE && emacs_event)
3414 {
3415 NSEvent *theEvent = [NSApp currentEvent];
3416 struct frame *emacsframe = SELECTED_FRAME ();
3417
3418 [menu cancelTracking];
3419 menu_will_open_state = MENU_PENDING;
3420 emacs_event->kind = MENU_BAR_ACTIVATE_EVENT;
3421 EV_TRAILER (theEvent);
3422
3423 CGEventRef ourEvent = CGEventCreate (NULL);
3424 menu_mouse_point = CGEventGetLocation (ourEvent);
3425 CFRelease (ourEvent);
3426 xfree (menu_pending_title);
3427 menu_pending_title = xstrdup ([[menu title] UTF8String]);
3428 }
3429 else if (menu_will_open_state == MENU_OPENING)
3430 {
3431 menu_will_open_state = MENU_NONE;
3432 }
3433 }
3434}
3435
3436/* Redo saved menu click if state is MENU_PENDING. */
3437void
3438ns_check_pending_open_menu ()
3439{
3440 if (menu_will_open_state == MENU_PENDING)
3441 {
3442 CGEventSourceRef source
3443 = CGEventSourceCreate (kCGEventSourceStateHIDSystemState);
3444
3445 CGEventRef event = CGEventCreateMouseEvent (source,
3446 kCGEventLeftMouseDown,
3447 menu_mouse_point,
3448 kCGMouseButtonLeft);
3449 CGEventSetType (event, kCGEventLeftMouseDown);
3450 CGEventPost (kCGHIDEventTap, event);
3451 CFRelease (event);
3452 CFRelease (source);
3453
3454 menu_will_open_state = MENU_OPENING;
3455 }
3456}
3457#endif /* NS_IMPL_COCOA) && >= MAC_OS_X_VERSION_10_5 */
3458
3391static int 3459static int
3392ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) 3460ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3393/* -------------------------------------------------------------------------- 3461/* --------------------------------------------------------------------------
@@ -3813,15 +3881,31 @@ x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
3813int 3881int
3814x_display_pixel_height (struct ns_display_info *dpyinfo) 3882x_display_pixel_height (struct ns_display_info *dpyinfo)
3815{ 3883{
3816 NSScreen *screen = [NSScreen mainScreen]; 3884 NSArray *screens = [NSScreen screens];
3817 return [screen frame].size.height; 3885 NSEnumerator *enumerator = [screens objectEnumerator];
3886 NSScreen *screen;
3887 NSRect frame;
3888
3889 frame = NSZeroRect;
3890 while ((screen = [enumerator nextObject]) != nil)
3891 frame = NSUnionRect (frame, [screen frame]);
3892
3893 return NSHeight (frame);
3818} 3894}
3819 3895
3820int 3896int
3821x_display_pixel_width (struct ns_display_info *dpyinfo) 3897x_display_pixel_width (struct ns_display_info *dpyinfo)
3822{ 3898{
3823 NSScreen *screen = [NSScreen mainScreen]; 3899 NSArray *screens = [NSScreen screens];
3824 return [screen frame].size.width; 3900 NSEnumerator *enumerator = [screens objectEnumerator];
3901 NSScreen *screen;
3902 NSRect frame;
3903
3904 frame = NSZeroRect;
3905 while ((screen = [enumerator nextObject]) != nil)
3906 frame = NSUnionRect (frame, [screen frame]);
3907
3908 return NSWidth (frame);
3825} 3909}
3826 3910
3827 3911
@@ -4276,6 +4360,12 @@ ns_term_init (Lisp_Object display_name)
4276 4360
4277 [NSApp run]; 4361 [NSApp run];
4278 ns_do_open_file = YES; 4362 ns_do_open_file = YES;
4363
4364#if defined (NS_IMPL_GNUSTEP) && defined (SIGCHLD)
4365 /* GNUstep steals SIGCHLD for use in NSTask, but we don't use NSTask.
4366 We must re-catch it so subprocess works. */
4367 catch_child_signal ();
4368#endif
4279 return dpyinfo; 4369 return dpyinfo;
4280} 4370}
4281 4371
@@ -4583,6 +4673,13 @@ not_in_argv (NSString *arg)
4583 ns_send_appdefined (-2); 4673 ns_send_appdefined (-2);
4584} 4674}
4585 4675
4676#ifdef NS_IMPL_GNUSTEP
4677- (void)sendFromMainThread:(id)unused
4678{
4679 ns_send_appdefined (nextappdefined);
4680}
4681#endif
4682
4586- (void)fd_handler:(id)unused 4683- (void)fd_handler:(id)unused
4587/* -------------------------------------------------------------------------- 4684/* --------------------------------------------------------------------------
4588 Check data waiting on file descriptors and terminate if so 4685 Check data waiting on file descriptors and terminate if so
@@ -4747,7 +4844,7 @@ not_in_argv (NSString *arg)
4747 NSEvent *e =[[self window] currentEvent]; 4844 NSEvent *e =[[self window] currentEvent];
4748 struct face *face =FRAME_DEFAULT_FACE (emacsframe); 4845 struct face *face =FRAME_DEFAULT_FACE (emacsframe);
4749 id newFont; 4846 id newFont;
4750 float size; 4847 CGFloat size;
4751 4848
4752 NSTRACE (changeFont); 4849 NSTRACE (changeFont);
4753 if (!emacs_event) 4850 if (!emacs_event)
@@ -4866,7 +4963,16 @@ not_in_argv (NSString *arg)
4866 { 4963 {
4867 /* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace', 4964 /* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace',
4868 because Emacs treats Delete and KP-Delete same (in simple.el). */ 4965 because Emacs treats Delete and KP-Delete same (in simple.el). */
4869 if (fnKeysym == 0xFFFF && [theEvent keyCode] == 0x33) 4966 if ((fnKeysym == 0xFFFF && [theEvent keyCode] == 0x33)
4967#ifdef NS_IMPL_GNUSTEP
4968 /* GNUstep uses incompatible keycodes, even for those that are
4969 supposed to be hardware independent. Just check for delete.
4970 Keypad delete does not have keysym 0xFFFF.
4971 See http://savannah.gnu.org/bugs/?25395
4972 */
4973 || (fnKeysym == 0xFFFF && code == 127)
4974#endif
4975 )
4870 code = 0xFF08; /* backspace */ 4976 code = 0xFF08; /* backspace */
4871 else 4977 else
4872 code = fnKeysym; 4978 code = fnKeysym;
@@ -5019,10 +5125,14 @@ not_in_argv (NSString *arg)
5019 5125
5020#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 5126#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
5021 /* if we get here we should send the key for input manager processing */ 5127 /* if we get here we should send the key for input manager processing */
5128 /* Disable warning, there is nothing a user can do about it anyway, and
5129 it does not seem to matter. */
5130#if 0
5022 if (firstTime && [[NSInputManager currentInputManager] 5131 if (firstTime && [[NSInputManager currentInputManager]
5023 wantsToDelayTextChangeNotifications] == NO) 5132 wantsToDelayTextChangeNotifications] == NO)
5024 fprintf (stderr, 5133 fprintf (stderr,
5025 "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n"); 5134 "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n");
5135#endif
5026 firstTime = NO; 5136 firstTime = NO;
5027#endif 5137#endif
5028 if (NS_KEYLOG && !processingCompose) 5138 if (NS_KEYLOG && !processingCompose)
@@ -5230,7 +5340,12 @@ not_in_argv (NSString *arg)
5230 return NSMakeRange (NSNotFound, 0); 5340 return NSMakeRange (NSNotFound, 0);
5231} 5341}
5232 5342
5343#if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \
5344 GNUSTEP_GUI_MINOR_VERSION > 22
5233- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint 5345- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
5346#else
5347- (unsigned int)characterIndexForPoint: (NSPoint)thePoint
5348#endif
5234{ 5349{
5235 if (NS_KEYLOG) 5350 if (NS_KEYLOG)
5236 NSLog (@"characterIndexForPoint request"); 5351 NSLog (@"characterIndexForPoint request");
@@ -5269,7 +5384,7 @@ not_in_argv (NSString *arg)
5269 5384
5270 if ([theEvent type] == NSScrollWheel) 5385 if ([theEvent type] == NSScrollWheel)
5271 { 5386 {
5272 float delta = [theEvent deltaY]; 5387 CGFloat delta = [theEvent deltaY];
5273 /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */ 5388 /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
5274 if (delta == 0) 5389 if (delta == 0)
5275 return; 5390 return;
@@ -5453,7 +5568,6 @@ not_in_argv (NSString *arg)
5453 5568
5454 if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) 5569 if (oldr != rows || oldc != cols || neww != oldw || newh != oldh)
5455 { 5570 {
5456 struct frame *f = emacsframe;
5457 NSView *view = FRAME_NS_VIEW (emacsframe); 5571 NSView *view = FRAME_NS_VIEW (emacsframe);
5458 NSWindow *win = [view window]; 5572 NSWindow *win = [view window];
5459 NSSize sz = [win resizeIncrements]; 5573 NSSize sz = [win resizeIncrements];
@@ -5662,7 +5776,6 @@ not_in_argv (NSString *arg)
5662 NSRect r, wr; 5776 NSRect r, wr;
5663 Lisp_Object tem; 5777 Lisp_Object tem;
5664 NSWindow *win; 5778 NSWindow *win;
5665 NSButton *toggleButton;
5666 NSSize sz; 5779 NSSize sz;
5667 NSColor *col; 5780 NSColor *col;
5668 NSString *name; 5781 NSString *name;
@@ -5738,9 +5851,12 @@ not_in_argv (NSString *arg)
5738 [win setToolbar: toolbar]; 5851 [win setToolbar: toolbar];
5739 [toolbar setVisible: NO]; 5852 [toolbar setVisible: NO];
5740#ifdef NS_IMPL_COCOA 5853#ifdef NS_IMPL_COCOA
5854 {
5855 NSButton *toggleButton;
5741 toggleButton = [win standardWindowButton: NSWindowToolbarButton]; 5856 toggleButton = [win standardWindowButton: NSWindowToolbarButton];
5742 [toggleButton setTarget: self]; 5857 [toggleButton setTarget: self];
5743 [toggleButton setAction: @selector (toggleToolbar: )]; 5858 [toggleButton setAction: @selector (toggleToolbar: )];
5859 }
5744#endif 5860#endif
5745 FRAME_TOOLBAR_HEIGHT (f) = 0; 5861 FRAME_TOOLBAR_HEIGHT (f) = 0;
5746 5862
@@ -5764,7 +5880,7 @@ not_in_argv (NSString *arg)
5764 col = ns_lookup_indexed_color (NS_FACE_BACKGROUND 5880 col = ns_lookup_indexed_color (NS_FACE_BACKGROUND
5765 (FRAME_DEFAULT_FACE (emacsframe)), emacsframe); 5881 (FRAME_DEFAULT_FACE (emacsframe)), emacsframe);
5766 [win setBackgroundColor: col]; 5882 [win setBackgroundColor: col];
5767 if ([col alphaComponent] != 1.0) 5883 if ([col alphaComponent] != (EmacsCGFloat) 1.0)
5768 [win setOpaque: NO]; 5884 [win setOpaque: NO];
5769 5885
5770 [self allocateGState]; 5886 [self allocateGState];
@@ -5857,7 +5973,7 @@ not_in_argv (NSString *arg)
5857 result = ns_userRect.size.height ? ns_userRect : result; 5973 result = ns_userRect.size.height ? ns_userRect : result;
5858 ns_userRect = NSMakeRect (0, 0, 0, 0); 5974 ns_userRect = NSMakeRect (0, 0, 0, 0);
5859 [self setFSValue: FULLSCREEN_NONE]; 5975 [self setFSValue: FULLSCREEN_NONE];
5860 maximized_width = maximized_width = -1; 5976 maximized_width = maximized_height = -1;
5861 } 5977 }
5862 5978
5863 if (fs_before_fs == -1) next_maximized = -1; 5979 if (fs_before_fs == -1) next_maximized = -1;
@@ -5950,7 +6066,9 @@ not_in_argv (NSString *arg)
5950{ 6066{
5951 [self setFSValue: fs_before_fs]; 6067 [self setFSValue: fs_before_fs];
5952 fs_before_fs = -1; 6068 fs_before_fs = -1;
6069#ifdef NS_IMPL_COCOA
5953 [self updateCollectionBehaviour]; 6070 [self updateCollectionBehaviour];
6071#endif
5954 if (FRAME_EXTERNAL_TOOL_BAR (emacsframe)) 6072 if (FRAME_EXTERNAL_TOOL_BAR (emacsframe))
5955 { 6073 {
5956 [toolbar setVisible:YES]; 6074 [toolbar setVisible:YES];
@@ -6009,7 +6127,9 @@ not_in_argv (NSString *arg)
6009 6127
6010 if (fs_is_native) 6128 if (fs_is_native)
6011 { 6129 {
6130#ifdef NS_IMPL_COCOA
6012 [[self window] toggleFullScreen:sender]; 6131 [[self window] toggleFullScreen:sender];
6132#endif
6013 return; 6133 return;
6014 } 6134 }
6015 6135
@@ -6055,7 +6175,7 @@ not_in_argv (NSString *arg)
6055 [fw useOptimizedDrawing: YES]; 6175 [fw useOptimizedDrawing: YES];
6056 [fw setResizeIncrements: sz]; 6176 [fw setResizeIncrements: sz];
6057 [fw setBackgroundColor: col]; 6177 [fw setBackgroundColor: col];
6058 if ([col alphaComponent] != 1.0) 6178 if ([col alphaComponent] != (EmacsCGFloat) 1.0)
6059 [fw setOpaque: NO]; 6179 [fw setOpaque: NO];
6060 6180
6061 f->border_width = 0; 6181 f->border_width = 0;
@@ -6093,7 +6213,7 @@ not_in_argv (NSString *arg)
6093 [w setContentView:[fw contentView]]; 6213 [w setContentView:[fw contentView]];
6094 [w setResizeIncrements: sz]; 6214 [w setResizeIncrements: sz];
6095 [w setBackgroundColor: col]; 6215 [w setBackgroundColor: col];
6096 if ([col alphaComponent] != 1.0) 6216 if ([col alphaComponent] != (EmacsCGFloat) 1.0)
6097 [w setOpaque: NO]; 6217 [w setOpaque: NO];
6098 6218
6099 f->border_width = bwidth; 6219 f->border_width = bwidth;
@@ -6532,7 +6652,7 @@ not_in_argv (NSString *arg)
6532{ 6652{
6533 Lisp_Object str = Qnil; 6653 Lisp_Object str = Qnil;
6534 struct frame *f = SELECTED_FRAME (); 6654 struct frame *f = SELECTED_FRAME ();
6535 struct buffer *curbuf = XBUFFER (XWINDOW (f->selected_window)->buffer); 6655 struct buffer *curbuf = XBUFFER (XWINDOW (f->selected_window)->contents);
6536 6656
6537 if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) 6657 if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
6538 return NSAccessibilityTextFieldRole; 6658 return NSAccessibilityTextFieldRole;
@@ -6787,10 +6907,11 @@ not_in_argv (NSString *arg)
6787 } 6907 }
6788 else 6908 else
6789 { 6909 {
6790 float pos, por; 6910 float pos;
6911 CGFloat por;
6791 portion = max ((float)whole*min_portion/pixel_height, portion); 6912 portion = max ((float)whole*min_portion/pixel_height, portion);
6792 pos = (float)position / (whole - portion); 6913 pos = (float)position / (whole - portion);
6793 por = (float)portion/whole; 6914 por = (CGFloat)portion/whole;
6794#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 6915#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
6795 [self setKnobProportion: por]; 6916 [self setKnobProportion: por];
6796 [self setDoubleValue: pos]; 6917 [self setDoubleValue: pos];
@@ -6815,7 +6936,7 @@ not_in_argv (NSString *arg)
6815 *part = last_hit_part; 6936 *part = last_hit_part;
6816 *window = win; 6937 *window = win;
6817 XSETINT (*y, pixel_height); 6938 XSETINT (*y, pixel_height);
6818 if ([self floatValue] > 0.999) 6939 if ([self floatValue] > 0.999F)
6819 XSETINT (*x, pixel_height); 6940 XSETINT (*x, pixel_height);
6820 else 6941 else
6821 XSETINT (*x, pixel_height * [self floatValue]); 6942 XSETINT (*x, pixel_height * [self floatValue]);
@@ -6889,7 +7010,7 @@ not_in_argv (NSString *arg)
6889 NSRect sr, kr; 7010 NSRect sr, kr;
6890 /* hitPart is only updated AFTER event is passed on */ 7011 /* hitPart is only updated AFTER event is passed on */
6891 NSScrollerPart part = [self testPart: [e locationInWindow]]; 7012 NSScrollerPart part = [self testPart: [e locationInWindow]];
6892 double inc = 0.0, loc, kloc, pos; 7013 CGFloat inc = 0.0, loc, kloc, pos;
6893 int edge = 0; 7014 int edge = 0;
6894 7015
6895 NSTRACE (EmacsScroller_mouseDown); 7016 NSTRACE (EmacsScroller_mouseDown);
@@ -6988,7 +7109,6 @@ not_in_argv (NSString *arg)
6988{ 7109{
6989 NSRect sr; 7110 NSRect sr;
6990 double loc, pos; 7111 double loc, pos;
6991 int edge = 0;
6992 7112
6993 NSTRACE (EmacsScroller_mouseDragged); 7113 NSTRACE (EmacsScroller_mouseDragged);
6994 7114
@@ -6999,15 +7119,13 @@ not_in_argv (NSString *arg)
6999 if (loc <= 0.0) 7119 if (loc <= 0.0)
7000 { 7120 {
7001 loc = 0.0; 7121 loc = 0.0;
7002 edge = -1;
7003 } 7122 }
7004 else if (loc >= NSHeight (sr) + last_mouse_offset) 7123 else if (loc >= NSHeight (sr) + last_mouse_offset)
7005 { 7124 {
7006 loc = NSHeight (sr) + last_mouse_offset; 7125 loc = NSHeight (sr) + last_mouse_offset;
7007 edge = 1;
7008 } 7126 }
7009 7127
7010 pos = /*(edge ? loc :*/ (loc - last_mouse_offset) / NSHeight (sr); 7128 pos = (loc - last_mouse_offset) / NSHeight (sr);
7011 [self sendScrollEventAtLoc: pos fromEvent: e]; 7129 [self sendScrollEventAtLoc: pos fromEvent: e];
7012} 7130}
7013 7131
@@ -7034,6 +7152,12 @@ not_in_argv (NSString *arg)
7034@end /* EmacsScroller */ 7152@end /* EmacsScroller */
7035 7153
7036 7154
7155#ifdef NS_IMPL_GNUSTEP
7156/* Dummy class to get rid of startup warnings. */
7157@implementation EmacsDocument
7158
7159@end
7160#endif
7037 7161
7038 7162
7039/* ========================================================================== 7163/* ==========================================================================
diff --git a/src/print.c b/src/print.c
index 74fab475ac0..979b732a057 100644
--- a/src/print.c
+++ b/src/print.c
@@ -227,9 +227,9 @@ printchar (unsigned int ch, Lisp_Object fun)
227 if (NILP (fun)) 227 if (NILP (fun))
228 { 228 {
229 ptrdiff_t incr = len - (print_buffer_size - print_buffer_pos_byte); 229 ptrdiff_t incr = len - (print_buffer_size - print_buffer_pos_byte);
230 if (0 < incr) 230 if (incr > 0)
231 print_buffer = 231 print_buffer = xpalloc (print_buffer, &print_buffer_size,
232 xpalloc (print_buffer, &print_buffer_size, incr, -1, 1); 232 incr, -1, 1);
233 memcpy (print_buffer + print_buffer_pos_byte, str, len); 233 memcpy (print_buffer + print_buffer_pos_byte, str, len);
234 print_buffer_pos += 1; 234 print_buffer_pos += 1;
235 print_buffer_pos_byte += len; 235 print_buffer_pos_byte += len;
@@ -273,7 +273,7 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
273 if (NILP (printcharfun)) 273 if (NILP (printcharfun))
274 { 274 {
275 ptrdiff_t incr = size_byte - (print_buffer_size - print_buffer_pos_byte); 275 ptrdiff_t incr = size_byte - (print_buffer_size - print_buffer_pos_byte);
276 if (0 < incr) 276 if (incr > 0)
277 print_buffer = xpalloc (print_buffer, &print_buffer_size, incr, -1, 1); 277 print_buffer = xpalloc (print_buffer, &print_buffer_size, incr, -1, 1);
278 memcpy (print_buffer + print_buffer_pos_byte, ptr, size_byte); 278 memcpy (print_buffer + print_buffer_pos_byte, ptr, size_byte);
279 print_buffer_pos += size; 279 print_buffer_pos += size;
@@ -1769,10 +1769,10 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1769 strout ("#<window ", -1, -1, printcharfun); 1769 strout ("#<window ", -1, -1, printcharfun);
1770 len = sprintf (buf, "%p", XWINDOW (obj)); 1770 len = sprintf (buf, "%p", XWINDOW (obj));
1771 strout (buf, len, len, printcharfun); 1771 strout (buf, len, len, printcharfun);
1772 if (!NILP (XWINDOW (obj)->buffer)) 1772 if (BUFFERP (XWINDOW (obj)->contents))
1773 { 1773 {
1774 strout (" on ", -1, -1, printcharfun); 1774 strout (" on ", -1, -1, printcharfun);
1775 print_string (BVAR (XBUFFER (XWINDOW (obj)->buffer), name), 1775 print_string (BVAR (XBUFFER (XWINDOW (obj)->contents), name),
1776 printcharfun); 1776 printcharfun);
1777 } 1777 }
1778 PRINTCHAR ('>'); 1778 PRINTCHAR ('>');
@@ -2078,17 +2078,15 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2078 2078
2079 strout ("#<save-value ", -1, -1, printcharfun); 2079 strout ("#<save-value ", -1, -1, printcharfun);
2080 2080
2081 if (v->area) 2081 if (v->save_type == SAVE_TYPE_MEMORY)
2082 { 2082 {
2083 ptrdiff_t amount = v->data[1].integer; 2083 ptrdiff_t amount = v->data[1].integer;
2084 2084
2085#if GC_MARK_STACK 2085#if GC_MARK_STACK
2086 2086
2087 /* If GC_MARK_STACK, valid_lisp_object_p is quite reliable, 2087 /* valid_lisp_object_p is reliable, so try to print up
2088 and so we try to print up to 8 objects we have saved. 2088 to 8 saved objects. This code is rarely used, so
2089 Although valid_lisp_object_p is slow, this shouldn't be 2089 it's OK that valid_lisp_object_p is slow. */
2090 a real bottleneck because we do not use this code under
2091 normal circumstances. */
2092 2090
2093 int limit = min (amount, 8); 2091 int limit = min (amount, 8);
2094 Lisp_Object *area = v->data[0].pointer; 2092 Lisp_Object *area = v->data[0].pointer;
@@ -2113,9 +2111,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2113 2111
2114#else /* not GC_MARK_STACK */ 2112#else /* not GC_MARK_STACK */
2115 2113
2116 /* If !GC_MARK_STACK, we have no reliable way to find 2114 /* There is no reliable way to determine whether the objects
2117 whether Lisp_Object pointers points to an initialized 2115 are initialized, so do not try to print them. */
2118 objects, and so we do not ever trying to print them. */
2119 2116
2120 i = sprintf (buf, "with %"pD"d objects", amount); 2117 i = sprintf (buf, "with %"pD"d objects", amount);
2121 strout (buf, i, i, printcharfun); 2118 strout (buf, i, i, printcharfun);
@@ -2124,33 +2121,37 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2124 } 2121 }
2125 else 2122 else
2126 { 2123 {
2127 /* Print each `data[N]' slot according to its type. */ 2124 /* Print each slot according to its type. */
2128 2125 int index;
2129#define PRINTX(index) \ 2126 for (index = 0; index < SAVE_VALUE_SLOTS; index++)
2130 do { \ 2127 {
2131 i = 0; \ 2128 if (index)
2132 if (v->type ## index == SAVE_UNUSED) \ 2129 PRINTCHAR (' ');
2133 i = sprintf (buf, "<unused>"); \
2134 else if (v->type ## index == SAVE_INTEGER) \
2135 i = sprintf (buf, "<integer %"pD"d>", v->data[index].integer); \
2136 else if (v->type ## index == SAVE_POINTER) \
2137 i = sprintf (buf, "<pointer %p>", v->data[index].pointer); \
2138 else /* SAVE_OBJECT */ \
2139 print_object (v->data[index].object, printcharfun, escapeflag); \
2140 if (i) \
2141 strout (buf, i, i, printcharfun); \
2142 } while (0)
2143
2144 PRINTX (0);
2145 PRINTCHAR (' ');
2146 PRINTX (1);
2147 PRINTCHAR (' ');
2148 PRINTX (2);
2149 PRINTCHAR (' ');
2150 PRINTX (3);
2151 2130
2152#undef PRINTX 2131 switch (save_type (v, index))
2132 {
2133 case SAVE_UNUSED:
2134 i = sprintf (buf, "<unused>");
2135 break;
2136
2137 case SAVE_POINTER:
2138 i = sprintf (buf, "<pointer %p>",
2139 v->data[index].pointer);
2140 break;
2141
2142 case SAVE_INTEGER:
2143 i = sprintf (buf, "<integer %"pD"d>",
2144 v->data[index].integer);
2145 break;
2146
2147 case SAVE_OBJECT:
2148 print_object (v->data[index].object, printcharfun,
2149 escapeflag);
2150 continue;
2151 }
2153 2152
2153 strout (buf, i, i, printcharfun);
2154 }
2154 } 2155 }
2155 PRINTCHAR ('>'); 2156 PRINTCHAR ('>');
2156 } 2157 }
@@ -2201,7 +2202,16 @@ print_interval (INTERVAL interval, Lisp_Object printcharfun)
2201 print_object (interval->plist, printcharfun, 1); 2202 print_object (interval->plist, printcharfun, 1);
2202} 2203}
2203 2204
2204 2205/* Initialize debug_print stuff early to have it working from the very
2206 beginning. */
2207
2208void
2209init_print_once (void)
2210{
2211 DEFSYM (Qexternal_debugging_output, "external-debugging-output");
2212 defsubr (&Sexternal_debugging_output);
2213}
2214
2205void 2215void
2206syms_of_print (void) 2216syms_of_print (void)
2207{ 2217{
@@ -2333,12 +2343,10 @@ priorities. */);
2333 defsubr (&Sprint); 2343 defsubr (&Sprint);
2334 defsubr (&Sterpri); 2344 defsubr (&Sterpri);
2335 defsubr (&Swrite_char); 2345 defsubr (&Swrite_char);
2336 defsubr (&Sexternal_debugging_output);
2337#ifdef WITH_REDIRECT_DEBUGGING_OUTPUT 2346#ifdef WITH_REDIRECT_DEBUGGING_OUTPUT
2338 defsubr (&Sredirect_debugging_output); 2347 defsubr (&Sredirect_debugging_output);
2339#endif 2348#endif
2340 2349
2341 DEFSYM (Qexternal_debugging_output, "external-debugging-output");
2342 DEFSYM (Qprint_escape_newlines, "print-escape-newlines"); 2350 DEFSYM (Qprint_escape_newlines, "print-escape-newlines");
2343 DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte"); 2351 DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte");
2344 DEFSYM (Qprint_escape_nonascii, "print-escape-nonascii"); 2352 DEFSYM (Qprint_escape_nonascii, "print-escape-nonascii");
diff --git a/src/process.c b/src/process.c
index e8e7a2be7be..c1726e7ad60 100644
--- a/src/process.c
+++ b/src/process.c
@@ -136,7 +136,7 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
136/* Work around GCC 4.7.0 bug with strict overflow checking; see 136/* Work around GCC 4.7.0 bug with strict overflow checking; see
137 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. 137 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
138 These lines can be removed once the GCC bug is fixed. */ 138 These lines can be removed once the GCC bug is fixed. */
139#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__ 139#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
140# pragma GCC diagnostic ignored "-Wstrict-overflow" 140# pragma GCC diagnostic ignored "-Wstrict-overflow"
141#endif 141#endif
142 142
@@ -174,6 +174,8 @@ static Lisp_Object QClocal, QCremote, QCcoding;
174static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; 174static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
175static Lisp_Object QCsentinel, QClog, QCoptions, QCplist; 175static Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
176static Lisp_Object Qlast_nonmenu_event; 176static Lisp_Object Qlast_nonmenu_event;
177static Lisp_Object Qinternal_default_process_sentinel;
178static Lisp_Object Qinternal_default_process_filter;
177 179
178#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork)) 180#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
179#define NETCONN1_P(p) (EQ (p->type, Qnetwork)) 181#define NETCONN1_P(p) (EQ (p->type, Qnetwork))
@@ -334,7 +336,7 @@ pset_encoding_buf (struct Lisp_Process *p, Lisp_Object val)
334static void 336static void
335pset_filter (struct Lisp_Process *p, Lisp_Object val) 337pset_filter (struct Lisp_Process *p, Lisp_Object val)
336{ 338{
337 p->filter = val; 339 p->filter = NILP (val) ? Qinternal_default_process_filter : val;
338} 340}
339static void 341static void
340pset_log (struct Lisp_Process *p, Lisp_Object val) 342pset_log (struct Lisp_Process *p, Lisp_Object val)
@@ -364,7 +366,7 @@ pset_plist (struct Lisp_Process *p, Lisp_Object val)
364static void 366static void
365pset_sentinel (struct Lisp_Process *p, Lisp_Object val) 367pset_sentinel (struct Lisp_Process *p, Lisp_Object val)
366{ 368{
367 p->sentinel = val; 369 p->sentinel = NILP (val) ? Qinternal_default_process_sentinel : val;
368} 370}
369static void 371static void
370pset_status (struct Lisp_Process *p, Lisp_Object val) 372pset_status (struct Lisp_Process *p, Lisp_Object val)
@@ -846,6 +848,8 @@ make_process (Lisp_Object name)
846 } 848 }
847 name = name1; 849 name = name1;
848 pset_name (p, name); 850 pset_name (p, name);
851 pset_sentinel (p, Qinternal_default_process_sentinel);
852 pset_filter (p, Qinternal_default_process_filter);
849 XSETPROCESS (val, p); 853 XSETPROCESS (val, p);
850 Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist); 854 Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist);
851 return val; 855 return val;
@@ -1146,10 +1150,10 @@ DEFUN ("process-mark", Fprocess_mark, Sprocess_mark,
1146 1150
1147DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, 1151DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
1148 2, 2, 0, 1152 2, 2, 0,
1149 doc: /* Give PROCESS the filter function FILTER; nil means no filter. 1153 doc: /* Give PROCESS the filter function FILTER; nil means default.
1150A value of t means stop accepting output from the process. 1154A value of t means stop accepting output from the process.
1151 1155
1152When a process has a filter, its buffer is not used for output. 1156When a process has a non-default filter, its buffer is not used for output.
1153Instead, each time it does output, the entire string of output is 1157Instead, each time it does output, the entire string of output is
1154passed to the filter. 1158passed to the filter.
1155 1159
@@ -1175,6 +1179,9 @@ The string argument is normally a multibyte string, except:
1175 (debug) 1179 (debug)
1176 (set-process-filter process ...) */ 1180 (set-process-filter process ...) */
1177 1181
1182 if (NILP (filter))
1183 filter = Qinternal_default_process_filter;
1184
1178 if (p->infd >= 0) 1185 if (p->infd >= 0)
1179 { 1186 {
1180 if (EQ (filter, Qt) && !EQ (p->status, Qlisten)) 1187 if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
@@ -1194,7 +1201,7 @@ The string argument is normally a multibyte string, except:
1194 1201
1195DEFUN ("process-filter", Fprocess_filter, Sprocess_filter, 1202DEFUN ("process-filter", Fprocess_filter, Sprocess_filter,
1196 1, 1, 0, 1203 1, 1, 0,
1197 doc: /* Returns the filter function of PROCESS; nil if none. 1204 doc: /* Return the filter function of PROCESS.
1198See `set-process-filter' for more info on filter functions. */) 1205See `set-process-filter' for more info on filter functions. */)
1199 (register Lisp_Object process) 1206 (register Lisp_Object process)
1200{ 1207{
@@ -1204,7 +1211,7 @@ See `set-process-filter' for more info on filter functions. */)
1204 1211
1205DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel, 1212DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel,
1206 2, 2, 0, 1213 2, 2, 0,
1207 doc: /* Give PROCESS the sentinel SENTINEL; nil for none. 1214 doc: /* Give PROCESS the sentinel SENTINEL; nil for default.
1208The sentinel is called as a function when the process changes state. 1215The sentinel is called as a function when the process changes state.
1209It gets two arguments: the process, and a string describing the change. */) 1216It gets two arguments: the process, and a string describing the change. */)
1210 (register Lisp_Object process, Lisp_Object sentinel) 1217 (register Lisp_Object process, Lisp_Object sentinel)
@@ -1214,6 +1221,9 @@ It gets two arguments: the process, and a string describing the change. */)
1214 CHECK_PROCESS (process); 1221 CHECK_PROCESS (process);
1215 p = XPROCESS (process); 1222 p = XPROCESS (process);
1216 1223
1224 if (NILP (sentinel))
1225 sentinel = Qinternal_default_process_sentinel;
1226
1217 pset_sentinel (p, sentinel); 1227 pset_sentinel (p, sentinel);
1218 if (NETCONN1_P (p) || SERIALCONN1_P (p)) 1228 if (NETCONN1_P (p) || SERIALCONN1_P (p))
1219 pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel)); 1229 pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel));
@@ -1222,7 +1232,7 @@ It gets two arguments: the process, and a string describing the change. */)
1222 1232
1223DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel, 1233DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel,
1224 1, 1, 0, 1234 1, 1, 0,
1225 doc: /* Return the sentinel of PROCESS; nil if none. 1235 doc: /* Return the sentinel of PROCESS.
1226See `set-process-sentinel' for more info on sentinels. */) 1236See `set-process-sentinel' for more info on sentinels. */)
1227 (register Lisp_Object process) 1237 (register Lisp_Object process)
1228{ 1238{
@@ -1575,8 +1585,8 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1575 pset_plist (XPROCESS (proc), Qnil); 1585 pset_plist (XPROCESS (proc), Qnil);
1576 pset_type (XPROCESS (proc), Qreal); 1586 pset_type (XPROCESS (proc), Qreal);
1577 pset_buffer (XPROCESS (proc), buffer); 1587 pset_buffer (XPROCESS (proc), buffer);
1578 pset_sentinel (XPROCESS (proc), Qnil); 1588 pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel);
1579 pset_filter (XPROCESS (proc), Qnil); 1589 pset_filter (XPROCESS (proc), Qinternal_default_process_filter);
1580 pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2)); 1590 pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2));
1581 1591
1582#ifdef HAVE_GNUTLS 1592#ifdef HAVE_GNUTLS
@@ -1998,7 +2008,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1998 /* Back in the parent process. */ 2008 /* Back in the parent process. */
1999 2009
2000 XPROCESS (process)->pid = pid; 2010 XPROCESS (process)->pid = pid;
2001 if (0 <= pid) 2011 if (pid >= 0)
2002 XPROCESS (process)->alive = 1; 2012 XPROCESS (process)->alive = 1;
2003 2013
2004 /* Stop blocking signals in the parent. */ 2014 /* Stop blocking signals in the parent. */
@@ -2346,7 +2356,7 @@ Returns nil upon error setting address, ADDRESS otherwise. */)
2346 channel = XPROCESS (process)->infd; 2356 channel = XPROCESS (process)->infd;
2347 2357
2348 len = get_lisp_to_sockaddr_size (address, &family); 2358 len = get_lisp_to_sockaddr_size (address, &family);
2349 if (datagram_address[channel].len != len) 2359 if (len == 0 || datagram_address[channel].len != len)
2350 return Qnil; 2360 return Qnil;
2351 conv_lisp_to_sockaddr (family, address, datagram_address[channel].sa, len); 2361 conv_lisp_to_sockaddr (family, address, datagram_address[channel].sa, len);
2352 return address; 2362 return address;
@@ -3457,7 +3467,8 @@ usage: (make-network-process &rest ARGS) */)
3457 { 3467 {
3458 int rfamily, rlen; 3468 int rfamily, rlen;
3459 rlen = get_lisp_to_sockaddr_size (remote, &rfamily); 3469 rlen = get_lisp_to_sockaddr_size (remote, &rfamily);
3460 if (rfamily == lres->ai_family && rlen == lres->ai_addrlen) 3470 if (rlen != 0 && rfamily == lres->ai_family
3471 && rlen == lres->ai_addrlen)
3461 conv_lisp_to_sockaddr (rfamily, remote, 3472 conv_lisp_to_sockaddr (rfamily, remote,
3462 datagram_address[s].sa, rlen); 3473 datagram_address[s].sa, rlen);
3463 } 3474 }
@@ -4077,7 +4088,7 @@ Return non-nil if we received any output before the timeout expired. */)
4077 { 4088 {
4078 if (INTEGERP (seconds)) 4089 if (INTEGERP (seconds))
4079 { 4090 {
4080 if (0 < XINT (seconds)) 4091 if (XINT (seconds) > 0)
4081 { 4092 {
4082 secs = XINT (seconds); 4093 secs = XINT (seconds);
4083 nsecs = 0; 4094 nsecs = 0;
@@ -4085,7 +4096,7 @@ Return non-nil if we received any output before the timeout expired. */)
4085 } 4096 }
4086 else if (FLOATP (seconds)) 4097 else if (FLOATP (seconds))
4087 { 4098 {
4088 if (0 < XFLOAT_DATA (seconds)) 4099 if (XFLOAT_DATA (seconds) > 0)
4089 { 4100 {
4090 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds)); 4101 EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds));
4091 secs = min (EMACS_SECS (t), WAIT_READING_MAX); 4102 secs = min (EMACS_SECS (t), WAIT_READING_MAX);
@@ -4215,7 +4226,8 @@ server_accept_connection (Lisp_Object server, int channel)
4215 process name of the server process concatenated with the caller 4226 process name of the server process concatenated with the caller
4216 identification. */ 4227 identification. */
4217 4228
4218 if (!NILP (ps->filter) && !EQ (ps->filter, Qt)) 4229 if (!(EQ (ps->filter, Qinternal_default_process_filter)
4230 || EQ (ps->filter, Qt)))
4219 buffer = Qnil; 4231 buffer = Qnil;
4220 else 4232 else
4221 { 4233 {
@@ -4278,7 +4290,7 @@ server_accept_connection (Lisp_Object server, int channel)
4278 /* Setup coding system for new process based on server process. 4290 /* Setup coding system for new process based on server process.
4279 This seems to be the proper thing to do, as the coding system 4291 This seems to be the proper thing to do, as the coding system
4280 of the new process should reflect the settings at the time the 4292 of the new process should reflect the settings at the time the
4281 server socket was opened; not the current settings. */ 4293 server socket was opened; not the current settings. */
4282 4294
4283 pset_decode_coding_system (p, ps->decode_coding_system); 4295 pset_decode_coding_system (p, ps->decode_coding_system);
4284 pset_encode_coding_system (p, ps->encode_coding_system); 4296 pset_encode_coding_system (p, ps->encode_coding_system);
@@ -4297,11 +4309,10 @@ server_accept_connection (Lisp_Object server, int channel)
4297 (STRINGP (host) ? host : build_string ("-")), 4309 (STRINGP (host) ? host : build_string ("-")),
4298 build_string ("\n"))); 4310 build_string ("\n")));
4299 4311
4300 if (!NILP (p->sentinel)) 4312 exec_sentinel (proc,
4301 exec_sentinel (proc, 4313 concat3 (build_string ("open from "),
4302 concat3 (build_string ("open from "), 4314 (STRINGP (host) ? host : build_string ("-")),
4303 (STRINGP (host) ? host : build_string ("-")), 4315 build_string ("\n")));
4304 build_string ("\n")));
4305} 4316}
4306 4317
4307static Lisp_Object 4318static Lisp_Object
@@ -4405,7 +4416,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4405 4416
4406 /* Since we may need to wait several times, 4417 /* Since we may need to wait several times,
4407 compute the absolute time to return at. */ 4418 compute the absolute time to return at. */
4408 if (time_limit || 0 < nsecs) 4419 if (time_limit || nsecs > 0)
4409 { 4420 {
4410 timeout = make_emacs_time (time_limit, nsecs); 4421 timeout = make_emacs_time (time_limit, nsecs);
4411 end_time = add_emacs_time (current_emacs_time (), timeout); 4422 end_time = add_emacs_time (current_emacs_time (), timeout);
@@ -4427,8 +4438,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4427 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) 4438 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
4428 break; 4439 break;
4429 4440
4430 /* Compute time from now till when time limit is up */ 4441 /* Compute time from now till when time limit is up. */
4431 /* Exit if already run out */ 4442 /* Exit if already run out. */
4432 if (nsecs < 0) 4443 if (nsecs < 0)
4433 { 4444 {
4434 /* A negative timeout means 4445 /* A negative timeout means
@@ -4437,7 +4448,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4437 4448
4438 timeout = make_emacs_time (0, 0); 4449 timeout = make_emacs_time (0, 0);
4439 } 4450 }
4440 else if (time_limit || 0 < nsecs) 4451 else if (time_limit || nsecs > 0)
4441 { 4452 {
4442 EMACS_TIME now = current_emacs_time (); 4453 EMACS_TIME now = current_emacs_time ();
4443 if (EMACS_TIME_LE (end_time, now)) 4454 if (EMACS_TIME_LE (end_time, now))
@@ -4489,7 +4500,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4489 break; 4500 break;
4490 4501
4491 /* A negative timeout means do not wait at all. */ 4502 /* A negative timeout means do not wait at all. */
4492 if (0 <= nsecs) 4503 if (nsecs >= 0)
4493 { 4504 {
4494 if (EMACS_TIME_VALID_P (timer_delay)) 4505 if (EMACS_TIME_VALID_P (timer_delay))
4495 { 4506 {
@@ -4571,7 +4582,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4571 if (nread == 0) 4582 if (nread == 0)
4572 break; 4583 break;
4573 4584
4574 if (0 < nread) 4585 if (nread > 0)
4575 { 4586 {
4576 total_nread += nread; 4587 total_nread += nread;
4577 got_some_input = 1; 4588 got_some_input = 1;
@@ -5029,8 +5040,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5029 } 5040 }
5030 } 5041 }
5031#endif /* NON_BLOCKING_CONNECT */ 5042#endif /* NON_BLOCKING_CONNECT */
5032 } /* end for each file descriptor */ 5043 } /* End for each file descriptor. */
5033 } /* end while exit conditions not met */ 5044 } /* End while exit conditions not met. */
5034 5045
5035 unbind_to (count, Qnil); 5046 unbind_to (count, Qnil);
5036 5047
@@ -5065,6 +5076,11 @@ read_process_output_error_handler (Lisp_Object error_val)
5065 return Qt; 5076 return Qt;
5066} 5077}
5067 5078
5079static void
5080read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
5081 ssize_t nbytes,
5082 struct coding_system *coding);
5083
5068/* Read pending output from the process channel, 5084/* Read pending output from the process channel,
5069 starting with our buffered-ahead character if we have one. 5085 starting with our buffered-ahead character if we have one.
5070 Yield number of decoded characters read. 5086 Yield number of decoded characters read.
@@ -5081,9 +5097,7 @@ read_process_output (Lisp_Object proc, register int channel)
5081{ 5097{
5082 register ssize_t nbytes; 5098 register ssize_t nbytes;
5083 char *chars; 5099 char *chars;
5084 register Lisp_Object outstream;
5085 register struct Lisp_Process *p = XPROCESS (proc); 5100 register struct Lisp_Process *p = XPROCESS (proc);
5086 register ptrdiff_t opoint;
5087 struct coding_system *coding = proc_decode_coding_system[channel]; 5101 struct coding_system *coding = proc_decode_coding_system[channel];
5088 int carryover = p->decoding_carryover; 5102 int carryover = p->decoding_carryover;
5089 int readmax = 4096; 5103 int readmax = 4096;
@@ -5106,7 +5120,7 @@ read_process_output (Lisp_Object proc, register int channel)
5106 else 5120 else
5107#endif 5121#endif
5108 { 5122 {
5109 bool buffered = 0 <= proc_buffered_char[channel]; 5123 bool buffered = proc_buffered_char[channel] >= 0;
5110 if (buffered) 5124 if (buffered)
5111 { 5125 {
5112 chars[carryover] = proc_buffered_char[channel]; 5126 chars[carryover] = proc_buffered_char[channel];
@@ -5171,122 +5185,144 @@ read_process_output (Lisp_Object proc, register int channel)
5171 friends don't expect current-buffer to be changed from under them. */ 5185 friends don't expect current-buffer to be changed from under them. */
5172 record_unwind_current_buffer (); 5186 record_unwind_current_buffer ();
5173 5187
5174 /* Read and dispose of the process output. */ 5188 read_and_dispose_of_process_output (p, chars, nbytes, coding);
5175 outstream = p->filter; 5189
5176 if (!NILP (outstream)) 5190 /* Handling the process output should not deactivate the mark. */
5177 { 5191 Vdeactivate_mark = odeactivate;
5178 Lisp_Object text; 5192
5179 bool outer_running_asynch_code = running_asynch_code; 5193 unbind_to (count, Qnil);
5180 int waiting = waiting_for_user_input_p; 5194 return nbytes;
5195}
5181 5196
5182 /* No need to gcpro these, because all we do with them later 5197static void
5183 is test them for EQness, and none of them should be a string. */ 5198read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
5199 ssize_t nbytes,
5200 struct coding_system *coding)
5201{
5202 Lisp_Object outstream = p->filter;
5203 Lisp_Object text;
5204 bool outer_running_asynch_code = running_asynch_code;
5205 int waiting = waiting_for_user_input_p;
5206
5207 /* No need to gcpro these, because all we do with them later
5208 is test them for EQness, and none of them should be a string. */
5184#if 0 5209#if 0
5185 Lisp_Object obuffer, okeymap; 5210 Lisp_Object obuffer, okeymap;
5186 XSETBUFFER (obuffer, current_buffer); 5211 XSETBUFFER (obuffer, current_buffer);
5187 okeymap = BVAR (current_buffer, keymap); 5212 okeymap = BVAR (current_buffer, keymap);
5188#endif 5213#endif
5189 5214
5190 /* We inhibit quit here instead of just catching it so that 5215 /* We inhibit quit here instead of just catching it so that
5191 hitting ^G when a filter happens to be running won't screw 5216 hitting ^G when a filter happens to be running won't screw
5192 it up. */ 5217 it up. */
5193 specbind (Qinhibit_quit, Qt); 5218 specbind (Qinhibit_quit, Qt);
5194 specbind (Qlast_nonmenu_event, Qt); 5219 specbind (Qlast_nonmenu_event, Qt);
5195
5196 /* In case we get recursively called,
5197 and we already saved the match data nonrecursively,
5198 save the same match data in safely recursive fashion. */
5199 if (outer_running_asynch_code)
5200 {
5201 Lisp_Object tem;
5202 /* Don't clobber the CURRENT match data, either! */
5203 tem = Fmatch_data (Qnil, Qnil, Qnil);
5204 restore_search_regs ();
5205 record_unwind_save_match_data ();
5206 Fset_match_data (tem, Qt);
5207 }
5208 5220
5209 /* For speed, if a search happens within this code, 5221 /* In case we get recursively called,
5210 save the match data in a special nonrecursive fashion. */ 5222 and we already saved the match data nonrecursively,
5211 running_asynch_code = 1; 5223 save the same match data in safely recursive fashion. */
5224 if (outer_running_asynch_code)
5225 {
5226 Lisp_Object tem;
5227 /* Don't clobber the CURRENT match data, either! */
5228 tem = Fmatch_data (Qnil, Qnil, Qnil);
5229 restore_search_regs ();
5230 record_unwind_save_match_data ();
5231 Fset_match_data (tem, Qt);
5232 }
5212 5233
5213 decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt); 5234 /* For speed, if a search happens within this code,
5214 text = coding->dst_object; 5235 save the match data in a special nonrecursive fashion. */
5215 Vlast_coding_system_used = CODING_ID_NAME (coding->id); 5236 running_asynch_code = 1;
5216 /* A new coding system might be found. */
5217 if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
5218 {
5219 pset_decode_coding_system (p, Vlast_coding_system_used);
5220 5237
5221 /* Don't call setup_coding_system for 5238 decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
5222 proc_decode_coding_system[channel] here. It is done in 5239 text = coding->dst_object;
5223 detect_coding called via decode_coding above. */ 5240 Vlast_coding_system_used = CODING_ID_NAME (coding->id);
5241 /* A new coding system might be found. */
5242 if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
5243 {
5244 pset_decode_coding_system (p, Vlast_coding_system_used);
5224 5245
5225 /* If a coding system for encoding is not yet decided, we set 5246 /* Don't call setup_coding_system for
5226 it as the same as coding-system for decoding. 5247 proc_decode_coding_system[channel] here. It is done in
5248 detect_coding called via decode_coding above. */
5227 5249
5228 But, before doing that we must check if 5250 /* If a coding system for encoding is not yet decided, we set
5229 proc_encode_coding_system[p->outfd] surely points to a 5251 it as the same as coding-system for decoding.
5230 valid memory because p->outfd will be changed once EOF is
5231 sent to the process. */
5232 if (NILP (p->encode_coding_system)
5233 && proc_encode_coding_system[p->outfd])
5234 {
5235 pset_encode_coding_system
5236 (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
5237 setup_coding_system (p->encode_coding_system,
5238 proc_encode_coding_system[p->outfd]);
5239 }
5240 }
5241 5252
5242 if (coding->carryover_bytes > 0) 5253 But, before doing that we must check if
5254 proc_encode_coding_system[p->outfd] surely points to a
5255 valid memory because p->outfd will be changed once EOF is
5256 sent to the process. */
5257 if (NILP (p->encode_coding_system)
5258 && proc_encode_coding_system[p->outfd])
5243 { 5259 {
5244 if (SCHARS (p->decoding_buf) < coding->carryover_bytes) 5260 pset_encode_coding_system
5245 pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes)); 5261 (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
5246 memcpy (SDATA (p->decoding_buf), coding->carryover, 5262 setup_coding_system (p->encode_coding_system,
5247 coding->carryover_bytes); 5263 proc_encode_coding_system[p->outfd]);
5248 p->decoding_carryover = coding->carryover_bytes;
5249 } 5264 }
5250 if (SBYTES (text) > 0) 5265 }
5251 /* FIXME: It's wrong to wrap or not based on debug-on-error, and
5252 sometimes it's simply wrong to wrap (e.g. when called from
5253 accept-process-output). */
5254 internal_condition_case_1 (read_process_output_call,
5255 Fcons (outstream,
5256 Fcons (proc, Fcons (text, Qnil))),
5257 !NILP (Vdebug_on_error) ? Qnil : Qerror,
5258 read_process_output_error_handler);
5259
5260 /* If we saved the match data nonrecursively, restore it now. */
5261 restore_search_regs ();
5262 running_asynch_code = outer_running_asynch_code;
5263 5266
5264 /* Restore waiting_for_user_input_p as it was 5267 if (coding->carryover_bytes > 0)
5265 when we were called, in case the filter clobbered it. */ 5268 {
5266 waiting_for_user_input_p = waiting; 5269 if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
5270 pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
5271 memcpy (SDATA (p->decoding_buf), coding->carryover,
5272 coding->carryover_bytes);
5273 p->decoding_carryover = coding->carryover_bytes;
5274 }
5275 if (SBYTES (text) > 0)
5276 /* FIXME: It's wrong to wrap or not based on debug-on-error, and
5277 sometimes it's simply wrong to wrap (e.g. when called from
5278 accept-process-output). */
5279 internal_condition_case_1 (read_process_output_call,
5280 Fcons (outstream,
5281 Fcons (make_lisp_proc (p),
5282 Fcons (text, Qnil))),
5283 !NILP (Vdebug_on_error) ? Qnil : Qerror,
5284 read_process_output_error_handler);
5285
5286 /* If we saved the match data nonrecursively, restore it now. */
5287 restore_search_regs ();
5288 running_asynch_code = outer_running_asynch_code;
5289
5290 /* Restore waiting_for_user_input_p as it was
5291 when we were called, in case the filter clobbered it. */
5292 waiting_for_user_input_p = waiting;
5267 5293
5268#if 0 /* Call record_asynch_buffer_change unconditionally, 5294#if 0 /* Call record_asynch_buffer_change unconditionally,
5269 because we might have changed minor modes or other things 5295 because we might have changed minor modes or other things
5270 that affect key bindings. */ 5296 that affect key bindings. */
5271 if (! EQ (Fcurrent_buffer (), obuffer) 5297 if (! EQ (Fcurrent_buffer (), obuffer)
5272 || ! EQ (current_buffer->keymap, okeymap)) 5298 || ! EQ (current_buffer->keymap, okeymap))
5273#endif 5299#endif
5274 /* But do it only if the caller is actually going to read events. 5300 /* But do it only if the caller is actually going to read events.
5275 Otherwise there's no need to make him wake up, and it could 5301 Otherwise there's no need to make him wake up, and it could
5276 cause trouble (for example it would make sit_for return). */ 5302 cause trouble (for example it would make sit_for return). */
5277 if (waiting_for_user_input_p == -1) 5303 if (waiting_for_user_input_p == -1)
5278 record_asynch_buffer_change (); 5304 record_asynch_buffer_change ();
5279 } 5305}
5280 5306
5281 /* If no filter, write into buffer if it isn't dead. */ 5307DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
5282 else if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) 5308 Sinternal_default_process_filter, 2, 2, 0,
5309 doc: /* Function used as default process filter. */)
5310 (Lisp_Object proc, Lisp_Object text)
5311{
5312 struct Lisp_Process *p;
5313 ptrdiff_t opoint;
5314
5315 CHECK_PROCESS (proc);
5316 p = XPROCESS (proc);
5317 CHECK_STRING (text);
5318
5319 if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5283 { 5320 {
5284 Lisp_Object old_read_only; 5321 Lisp_Object old_read_only;
5285 ptrdiff_t old_begv, old_zv; 5322 ptrdiff_t old_begv, old_zv;
5286 ptrdiff_t old_begv_byte, old_zv_byte; 5323 ptrdiff_t old_begv_byte, old_zv_byte;
5287 ptrdiff_t before, before_byte; 5324 ptrdiff_t before, before_byte;
5288 ptrdiff_t opoint_byte; 5325 ptrdiff_t opoint_byte;
5289 Lisp_Object text;
5290 struct buffer *b; 5326 struct buffer *b;
5291 5327
5292 Fset_buffer (p->buffer); 5328 Fset_buffer (p->buffer);
@@ -5319,31 +5355,6 @@ read_process_output (Lisp_Object proc, register int channel)
5319 if (! (BEGV <= PT && PT <= ZV)) 5355 if (! (BEGV <= PT && PT <= ZV))
5320 Fwiden (); 5356 Fwiden ();
5321 5357
5322 decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
5323 text = coding->dst_object;
5324 Vlast_coding_system_used = CODING_ID_NAME (coding->id);
5325 /* A new coding system might be found. See the comment in the
5326 similar code in the previous `if' block. */
5327 if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
5328 {
5329 pset_decode_coding_system (p, Vlast_coding_system_used);
5330 if (NILP (p->encode_coding_system)
5331 && proc_encode_coding_system[p->outfd])
5332 {
5333 pset_encode_coding_system
5334 (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
5335 setup_coding_system (p->encode_coding_system,
5336 proc_encode_coding_system[p->outfd]);
5337 }
5338 }
5339 if (coding->carryover_bytes > 0)
5340 {
5341 if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
5342 pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
5343 memcpy (SDATA (p->decoding_buf), coding->carryover,
5344 coding->carryover_bytes);
5345 p->decoding_carryover = coding->carryover_bytes;
5346 }
5347 /* Adjust the multibyteness of TEXT to that of the buffer. */ 5358 /* Adjust the multibyteness of TEXT to that of the buffer. */
5348 if (NILP (BVAR (current_buffer, enable_multibyte_characters)) 5359 if (NILP (BVAR (current_buffer, enable_multibyte_characters))
5349 != ! STRING_MULTIBYTE (text)) 5360 != ! STRING_MULTIBYTE (text))
@@ -5388,18 +5399,13 @@ read_process_output (Lisp_Object proc, register int channel)
5388 if (old_begv != BEGV || old_zv != ZV) 5399 if (old_begv != BEGV || old_zv != ZV)
5389 Fnarrow_to_region (make_number (old_begv), make_number (old_zv)); 5400 Fnarrow_to_region (make_number (old_begv), make_number (old_zv));
5390 5401
5391
5392 bset_read_only (current_buffer, old_read_only); 5402 bset_read_only (current_buffer, old_read_only);
5393 SET_PT_BOTH (opoint, opoint_byte); 5403 SET_PT_BOTH (opoint, opoint_byte);
5394 } 5404 }
5395 /* Handling the process output should not deactivate the mark. */ 5405 return Qnil;
5396 Vdeactivate_mark = odeactivate;
5397
5398 unbind_to (count, Qnil);
5399 return nbytes;
5400} 5406}
5401 5407
5402/* Sending data to subprocess */ 5408/* Sending data to subprocess. */
5403 5409
5404/* In send_process, when a write fails temporarily, 5410/* In send_process, when a write fails temporarily,
5405 wait_reading_process_output is called. It may execute user code, 5411 wait_reading_process_output is called. It may execute user code,
@@ -5613,7 +5619,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
5613 rv = sendto (outfd, cur_buf, cur_len, 5619 rv = sendto (outfd, cur_buf, cur_len,
5614 0, datagram_address[outfd].sa, 5620 0, datagram_address[outfd].sa,
5615 datagram_address[outfd].len); 5621 datagram_address[outfd].len);
5616 if (0 <= rv) 5622 if (rv >= 0)
5617 written = rv; 5623 written = rv;
5618 else if (errno == EMSGSIZE) 5624 else if (errno == EMSGSIZE)
5619 report_file_error ("sending datagram", Fcons (proc, Qnil)); 5625 report_file_error ("sending datagram", Fcons (proc, Qnil));
@@ -6308,7 +6314,8 @@ handle_child_signal (int sig)
6308 struct Lisp_Process *p = XPROCESS (proc); 6314 struct Lisp_Process *p = XPROCESS (proc);
6309 int status; 6315 int status;
6310 6316
6311 if (p->alive && child_status_changed (p->pid, &status, WUNTRACED)) 6317 if (p->alive
6318 && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED))
6312 { 6319 {
6313 /* Change the status of the process that was found. */ 6320 /* Change the status of the process that was found. */
6314 p->tick = ++process_tick; 6321 p->tick = ++process_tick;
@@ -6339,13 +6346,6 @@ deliver_child_signal (int sig)
6339 6346
6340 6347
6341static Lisp_Object 6348static Lisp_Object
6342exec_sentinel_unwind (Lisp_Object data)
6343{
6344 pset_sentinel (XPROCESS (XCAR (data)), XCDR (data));
6345 return Qnil;
6346}
6347
6348static Lisp_Object
6349exec_sentinel_error_handler (Lisp_Object error_val) 6349exec_sentinel_error_handler (Lisp_Object error_val)
6350{ 6350{
6351 cmd_error_internal (error_val, "error in process sentinel: "); 6351 cmd_error_internal (error_val, "error in process sentinel: ");
@@ -6382,13 +6382,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
6382 record_unwind_current_buffer (); 6382 record_unwind_current_buffer ();
6383 6383
6384 sentinel = p->sentinel; 6384 sentinel = p->sentinel;
6385 if (NILP (sentinel))
6386 return;
6387 6385
6388 /* Zilch the sentinel while it's running, to avoid recursive invocations;
6389 assure that it gets restored no matter how the sentinel exits. */
6390 pset_sentinel (p, Qnil);
6391 record_unwind_protect (exec_sentinel_unwind, Fcons (proc, sentinel));
6392 /* Inhibit quit so that random quits don't screw up a running filter. */ 6386 /* Inhibit quit so that random quits don't screw up a running filter. */
6393 specbind (Qinhibit_quit, Qt); 6387 specbind (Qinhibit_quit, Qt);
6394 specbind (Qlast_nonmenu_event, Qt); /* Why? --Stef */ 6388 specbind (Qlast_nonmenu_event, Qt); /* Why? --Stef */
@@ -6446,7 +6440,7 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
6446static void 6440static void
6447status_notify (struct Lisp_Process *deleting_process) 6441status_notify (struct Lisp_Process *deleting_process)
6448{ 6442{
6449 register Lisp_Object proc, buffer; 6443 register Lisp_Object proc;
6450 Lisp_Object tail, msg; 6444 Lisp_Object tail, msg;
6451 struct gcpro gcpro1, gcpro2; 6445 struct gcpro gcpro1, gcpro2;
6452 6446
@@ -6484,8 +6478,6 @@ status_notify (struct Lisp_Process *deleting_process)
6484 && p != deleting_process 6478 && p != deleting_process
6485 && read_process_output (proc, p->infd) > 0); 6479 && read_process_output (proc, p->infd) > 0);
6486 6480
6487 buffer = p->buffer;
6488
6489 /* Get the text to use for the message. */ 6481 /* Get the text to use for the message. */
6490 if (p->raw_status_new) 6482 if (p->raw_status_new)
6491 update_status (p); 6483 update_status (p);
@@ -6506,66 +6498,83 @@ status_notify (struct Lisp_Process *deleting_process)
6506 } 6498 }
6507 6499
6508 /* The actions above may have further incremented p->tick. 6500 /* The actions above may have further incremented p->tick.
6509 So set p->update_tick again 6501 So set p->update_tick again so that an error in the sentinel will
6510 so that an error in the sentinel will not cause 6502 not cause this code to be run again. */
6511 this code to be run again. */
6512 p->update_tick = p->tick; 6503 p->update_tick = p->tick;
6513 /* Now output the message suitably. */ 6504 /* Now output the message suitably. */
6514 if (!NILP (p->sentinel)) 6505 exec_sentinel (proc, msg);
6515 exec_sentinel (proc, msg);
6516 /* Don't bother with a message in the buffer
6517 when a process becomes runnable. */
6518 else if (!EQ (symbol, Qrun) && !NILP (buffer))
6519 {
6520 Lisp_Object tem;
6521 struct buffer *old = current_buffer;
6522 ptrdiff_t opoint, opoint_byte;
6523 ptrdiff_t before, before_byte;
6524
6525 /* Avoid error if buffer is deleted
6526 (probably that's why the process is dead, too) */
6527 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
6528 continue;
6529 Fset_buffer (buffer);
6530
6531 opoint = PT;
6532 opoint_byte = PT_BYTE;
6533 /* Insert new output into buffer
6534 at the current end-of-output marker,
6535 thus preserving logical ordering of input and output. */
6536 if (XMARKER (p->mark)->buffer)
6537 Fgoto_char (p->mark);
6538 else
6539 SET_PT_BOTH (ZV, ZV_BYTE);
6540
6541 before = PT;
6542 before_byte = PT_BYTE;
6543
6544 tem = BVAR (current_buffer, read_only);
6545 bset_read_only (current_buffer, Qnil);
6546 insert_string ("\nProcess ");
6547 { /* FIXME: temporary kludge */
6548 Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
6549 insert_string (" ");
6550 Finsert (1, &msg);
6551 bset_read_only (current_buffer, tem);
6552 set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
6553
6554 if (opoint >= before)
6555 SET_PT_BOTH (opoint + (PT - before),
6556 opoint_byte + (PT_BYTE - before_byte));
6557 else
6558 SET_PT_BOTH (opoint, opoint_byte);
6559
6560 set_buffer_internal (old);
6561 }
6562 } 6506 }
6563 } /* end for */ 6507 } /* end for */
6564 6508
6565 update_mode_lines++; /* in case buffers use %s in mode-line-format */ 6509 update_mode_lines++; /* In case buffers use %s in mode-line-format. */
6566 UNGCPRO; 6510 UNGCPRO;
6567} 6511}
6568 6512
6513DEFUN ("internal-default-process-sentinel", Finternal_default_process_sentinel,
6514 Sinternal_default_process_sentinel, 2, 2, 0,
6515 doc: /* Function used as default sentinel for processes. */)
6516 (Lisp_Object proc, Lisp_Object msg)
6517{
6518 Lisp_Object buffer, symbol;
6519 struct Lisp_Process *p;
6520 CHECK_PROCESS (proc);
6521 p = XPROCESS (proc);
6522 buffer = p->buffer;
6523 symbol = p->status;
6524 if (CONSP (symbol))
6525 symbol = XCAR (symbol);
6526
6527 if (!EQ (symbol, Qrun) && !NILP (buffer))
6528 {
6529 Lisp_Object tem;
6530 struct buffer *old = current_buffer;
6531 ptrdiff_t opoint, opoint_byte;
6532 ptrdiff_t before, before_byte;
6533
6534 /* Avoid error if buffer is deleted
6535 (probably that's why the process is dead, too). */
6536 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
6537 return Qnil;
6538 Fset_buffer (buffer);
6539
6540 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
6541 msg = (code_convert_string_norecord
6542 (msg, Vlocale_coding_system, 1));
6543
6544 opoint = PT;
6545 opoint_byte = PT_BYTE;
6546 /* Insert new output into buffer
6547 at the current end-of-output marker,
6548 thus preserving logical ordering of input and output. */
6549 if (XMARKER (p->mark)->buffer)
6550 Fgoto_char (p->mark);
6551 else
6552 SET_PT_BOTH (ZV, ZV_BYTE);
6553
6554 before = PT;
6555 before_byte = PT_BYTE;
6556
6557 tem = BVAR (current_buffer, read_only);
6558 bset_read_only (current_buffer, Qnil);
6559 insert_string ("\nProcess ");
6560 { /* FIXME: temporary kludge. */
6561 Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
6562 insert_string (" ");
6563 Finsert (1, &msg);
6564 bset_read_only (current_buffer, tem);
6565 set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
6566
6567 if (opoint >= before)
6568 SET_PT_BOTH (opoint + (PT - before),
6569 opoint_byte + (PT_BYTE - before_byte));
6570 else
6571 SET_PT_BOTH (opoint, opoint_byte);
6572
6573 set_buffer_internal (old);
6574 }
6575 return Qnil;
6576}
6577
6569 6578
6570DEFUN ("set-process-coding-system", Fset_process_coding_system, 6579DEFUN ("set-process-coding-system", Fset_process_coding_system,
6571 Sset_process_coding_system, 1, 3, 0, 6580 Sset_process_coding_system, 1, 3, 0,
@@ -6729,7 +6738,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6729 time_limit = TYPE_MAXIMUM (time_t); 6738 time_limit = TYPE_MAXIMUM (time_t);
6730 6739
6731 /* What does time_limit really mean? */ 6740 /* What does time_limit really mean? */
6732 if (time_limit || 0 < nsecs) 6741 if (time_limit || nsecs > 0)
6733 { 6742 {
6734 timeout = make_emacs_time (time_limit, nsecs); 6743 timeout = make_emacs_time (time_limit, nsecs);
6735 end_time = add_emacs_time (current_emacs_time (), timeout); 6744 end_time = add_emacs_time (current_emacs_time (), timeout);
@@ -6757,17 +6766,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6757 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) 6766 if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
6758 break; 6767 break;
6759 6768
6760 /* Compute time from now till when time limit is up */ 6769 /* Compute time from now till when time limit is up. */
6761 /* Exit if already run out */ 6770 /* Exit if already run out. */
6762 if (nsecs < 0) 6771 if (nsecs < 0)
6763 { 6772 {
6764 /* A negative timeout means 6773 /* A negative timeout means
6765 gobble output available now 6774 gobble output available now
6766 but don't wait at all. */ 6775 but don't wait at all. */
6767 6776
6768 timeout = make_emacs_time (0, 0); 6777 timeout = make_emacs_time (0, 0);
6769 } 6778 }
6770 else if (time_limit || 0 < nsecs) 6779 else if (time_limit || nsecs > 0)
6771 { 6780 {
6772 EMACS_TIME now = current_emacs_time (); 6781 EMACS_TIME now = current_emacs_time ();
6773 if (EMACS_TIME_LE (end_time, now)) 6782 if (EMACS_TIME_LE (end_time, now))
@@ -6805,7 +6814,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
6805 && requeued_events_pending_p ()) 6814 && requeued_events_pending_p ())
6806 break; 6815 break;
6807 6816
6808 if (EMACS_TIME_VALID_P (timer_delay) && 0 <= nsecs) 6817 if (EMACS_TIME_VALID_P (timer_delay) && nsecs >= 0)
6809 { 6818 {
6810 if (EMACS_TIME_LT (timer_delay, timeout)) 6819 if (EMACS_TIME_LT (timer_delay, timeout))
6811 { 6820 {
@@ -6956,9 +6965,8 @@ setup_process_coding_systems (Lisp_Object process)
6956 if (!proc_decode_coding_system[inch]) 6965 if (!proc_decode_coding_system[inch])
6957 proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system)); 6966 proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system));
6958 coding_system = p->decode_coding_system; 6967 coding_system = p->decode_coding_system;
6959 if (! NILP (p->filter)) 6968 if (EQ (p->filter, Qinternal_default_process_filter)
6960 ; 6969 && BUFFERP (p->buffer))
6961 else if (BUFFERP (p->buffer))
6962 { 6970 {
6963 if (NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters))) 6971 if (NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters)))
6964 coding_system = raw_text_coding_system (coding_system); 6972 coding_system = raw_text_coding_system (coding_system);
@@ -7067,7 +7075,7 @@ kill_buffer_processes (Lisp_Object buffer)
7067 7075
7068DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, 7076DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p,
7069 Swaiting_for_user_input_p, 0, 0, 0, 7077 Swaiting_for_user_input_p, 0, 0, 0,
7070 doc: /* Returns non-nil if Emacs is waiting for input from the user. 7078 doc: /* Return non-nil if Emacs is waiting for input from the user.
7071This is intended for use by asynchronous process output filters and sentinels. */) 7079This is intended for use by asynchronous process output filters and sentinels. */)
7072 (void) 7080 (void)
7073{ 7081{
@@ -7173,6 +7181,16 @@ integer or floating point values.
7173 return system_process_attributes (pid); 7181 return system_process_attributes (pid);
7174} 7182}
7175 7183
7184void
7185catch_child_signal (void)
7186{
7187#ifdef SIGCHLD
7188 struct sigaction action;
7189 emacs_sigaction_init (&action, deliver_child_signal);
7190 sigaction (SIGCHLD, &action, 0);
7191#endif
7192}
7193
7176 7194
7177/* This is not called "init_process" because that is the name of a 7195/* This is not called "init_process" because that is the name of a
7178 Mach system call, so it would cause problems on Darwin systems. */ 7196 Mach system call, so it would cause problems on Darwin systems. */
@@ -7188,9 +7206,7 @@ init_process_emacs (void)
7188 if (! noninteractive || initialized) 7206 if (! noninteractive || initialized)
7189#endif 7207#endif
7190 { 7208 {
7191 struct sigaction action; 7209 catch_child_signal ();
7192 emacs_sigaction_init (&action, deliver_child_signal);
7193 sigaction (SIGCHLD, &action, 0);
7194 } 7210 }
7195 7211
7196 max_desc = 0; 7212 max_desc = 0;
@@ -7368,6 +7384,10 @@ syms_of_process (void)
7368 DEFSYM (Qcutime, "cutime"); 7384 DEFSYM (Qcutime, "cutime");
7369 DEFSYM (Qcstime, "cstime"); 7385 DEFSYM (Qcstime, "cstime");
7370 DEFSYM (Qctime, "ctime"); 7386 DEFSYM (Qctime, "ctime");
7387 DEFSYM (Qinternal_default_process_sentinel,
7388 "internal-default-process-sentinel");
7389 DEFSYM (Qinternal_default_process_filter,
7390 "internal-default-process-filter");
7371 DEFSYM (Qpri, "pri"); 7391 DEFSYM (Qpri, "pri");
7372 DEFSYM (Qnice, "nice"); 7392 DEFSYM (Qnice, "nice");
7373 DEFSYM (Qthcount, "thcount"); 7393 DEFSYM (Qthcount, "thcount");
@@ -7465,6 +7485,8 @@ The variable takes effect when `start-process' is called. */);
7465 defsubr (&Ssignal_process); 7485 defsubr (&Ssignal_process);
7466 defsubr (&Swaiting_for_user_input_p); 7486 defsubr (&Swaiting_for_user_input_p);
7467 defsubr (&Sprocess_type); 7487 defsubr (&Sprocess_type);
7488 defsubr (&Sinternal_default_process_sentinel);
7489 defsubr (&Sinternal_default_process_filter);
7468 defsubr (&Sset_process_coding_system); 7490 defsubr (&Sset_process_coding_system);
7469 defsubr (&Sprocess_coding_system); 7491 defsubr (&Sprocess_coding_system);
7470 defsubr (&Sset_process_filter_multibyte); 7492 defsubr (&Sset_process_filter_multibyte);
diff --git a/src/process.h b/src/process.h
index 7d13a8e5042..cf1e0ea1d44 100644
--- a/src/process.h
+++ b/src/process.h
@@ -220,6 +220,7 @@ extern void add_read_fd (int fd, fd_callback func, void *data);
220extern void delete_read_fd (int fd); 220extern void delete_read_fd (int fd);
221extern void add_write_fd (int fd, fd_callback func, void *data); 221extern void add_write_fd (int fd, fd_callback func, void *data);
222extern void delete_write_fd (int fd); 222extern void delete_write_fd (int fd);
223extern void catch_child_signal (void);
223 224
224extern void update_processes_for_thread_death (Lisp_Object); 225extern void update_processes_for_thread_death (Lisp_Object);
225 226
diff --git a/src/profiler.c b/src/profiler.c
index 85d9c1ca88a..aba81344c68 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -55,7 +55,7 @@ make_log (int heap_size, int max_stack_depth)
55 /* What is special about our hash-tables is that the keys are pre-filled 55 /* What is special about our hash-tables is that the keys are pre-filled
56 with the vectors we'll put in them. */ 56 with the vectors we'll put in them. */
57 int i = ASIZE (h->key_and_value) / 2; 57 int i = ASIZE (h->key_and_value) / 2;
58 while (0 < i) 58 while (i > 0)
59 set_hash_key_slot (h, --i, 59 set_hash_key_slot (h, --i,
60 Fmake_vector (make_number (max_stack_depth), Qnil)); 60 Fmake_vector (make_number (max_stack_depth), Qnil));
61 return log; 61 return log;
@@ -138,10 +138,8 @@ static void evict_lower_half (log_t *log)
138static void 138static void
139record_backtrace (log_t *log, EMACS_INT count) 139record_backtrace (log_t *log, EMACS_INT count)
140{ 140{
141 struct backtrace *backlist = backtrace_list;
142 Lisp_Object backtrace; 141 Lisp_Object backtrace;
143 ptrdiff_t index, i = 0; 142 ptrdiff_t index;
144 ptrdiff_t asize;
145 143
146 if (!INTEGERP (log->next_free)) 144 if (!INTEGERP (log->next_free))
147 /* FIXME: transfer the evicted counts to a special entry rather 145 /* FIXME: transfer the evicted counts to a special entry rather
@@ -151,16 +149,7 @@ record_backtrace (log_t *log, EMACS_INT count)
151 149
152 /* Get a "working memory" vector. */ 150 /* Get a "working memory" vector. */
153 backtrace = HASH_KEY (log, index); 151 backtrace = HASH_KEY (log, index);
154 asize = ASIZE (backtrace); 152 get_backtrace (backtrace);
155
156 /* Copy the backtrace contents into working memory. */
157 for (; i < asize && backlist; i++, backlist = backlist->next)
158 /* FIXME: For closures we should ignore the environment. */
159 ASET (backtrace, i, backlist->function);
160
161 /* Make sure that unused space of working memory is filled with nil. */
162 for (; i < asize; i++)
163 ASET (backtrace, i, Qnil);
164 153
165 { /* We basically do a `gethash+puthash' here, except that we have to be 154 { /* We basically do a `gethash+puthash' here, except that we have to be
166 careful to avoid memory allocation since we're in a signal 155 careful to avoid memory allocation since we're in a signal
@@ -232,7 +221,7 @@ static EMACS_INT current_sampling_interval;
232static void 221static void
233handle_profiler_signal (int signal) 222handle_profiler_signal (int signal)
234{ 223{
235 if (backtrace_list && EQ (backtrace_list->function, Qautomatic_gc)) 224 if (EQ (backtrace_top_function (), Qautomatic_gc))
236 /* Special case the time-count inside GC because the hash-table 225 /* Special case the time-count inside GC because the hash-table
237 code is not prepared to be used while the GC is running. 226 code is not prepared to be used while the GC is running.
238 More specifically it uses ASIZE at many places where it does 227 More specifically it uses ASIZE at many places where it does
@@ -247,7 +236,7 @@ handle_profiler_signal (int signal)
247 if (profiler_timer_ok) 236 if (profiler_timer_ok)
248 { 237 {
249 int overruns = timer_getoverrun (profiler_timer); 238 int overruns = timer_getoverrun (profiler_timer);
250 eassert (0 <= overruns); 239 eassert (overruns >= 0);
251 count += overruns; 240 count += overruns;
252 } 241 }
253#endif 242#endif
diff --git a/src/puresize.h b/src/puresize.h
index 2f717571c7c..25a11aafbcc 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -73,9 +73,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
73/* Signal an error if OBJ is pure. */ 73/* Signal an error if OBJ is pure. */
74#define CHECK_IMPURE(obj) \ 74#define CHECK_IMPURE(obj) \
75 { if (PURE_P (obj)) \ 75 { if (PURE_P (obj)) \
76 pure_write_error (); } 76 pure_write_error (obj); }
77 77
78extern _Noreturn void pure_write_error (void); 78extern _Noreturn void pure_write_error (Lisp_Object);
79 79
80/* Define PURE_P. */ 80/* Define PURE_P. */
81 81
diff --git a/src/regex.c b/src/regex.c
index b5522f19079..73a735cea65 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -33,10 +33,9 @@
33 33
34/* Ignore some GCC warnings for now. This section should go away 34/* Ignore some GCC warnings for now. This section should go away
35 once the Emacs and Gnulib regex code is merged. */ 35 once the Emacs and Gnulib regex code is merged. */
36#if (__GNUC__ == 4 && 5 <= __GNUC_MINOR__) || 4 < __GNUC__ 36#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) || defined __clang__
37# pragma GCC diagnostic ignored "-Wstrict-overflow" 37# pragma GCC diagnostic ignored "-Wstrict-overflow"
38# ifndef emacs 38# ifndef emacs
39# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
40# pragma GCC diagnostic ignored "-Wunused-function" 39# pragma GCC diagnostic ignored "-Wunused-function"
41# pragma GCC diagnostic ignored "-Wunused-macros" 40# pragma GCC diagnostic ignored "-Wunused-macros"
42# pragma GCC diagnostic ignored "-Wunused-result" 41# pragma GCC diagnostic ignored "-Wunused-result"
@@ -44,6 +43,10 @@
44# endif 43# endif
45#endif 44#endif
46 45
46#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && ! defined __clang__
47# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
48#endif
49
47#include <config.h> 50#include <config.h>
48 51
49#include <stddef.h> 52#include <stddef.h>
@@ -710,51 +713,27 @@ typedef enum
710 at SOURCE. */ 713 at SOURCE. */
711 714
712#define EXTRACT_NUMBER(destination, source) \ 715#define EXTRACT_NUMBER(destination, source) \
713 do { \ 716 ((destination) = extract_number (source))
714 (destination) = *(source) & 0377; \
715 (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
716 } while (0)
717 717
718#ifdef DEBUG 718static int
719static void 719extract_number (re_char *source)
720extract_number (int *dest, re_char *source)
721{ 720{
722 int temp = SIGN_EXTEND_CHAR (*(source + 1)); 721 return (SIGN_EXTEND_CHAR (source[1]) << 8) + source[0];
723 *dest = *source & 0377;
724 *dest += temp << 8;
725} 722}
726 723
727# ifndef EXTRACT_MACROS /* To debug the macros. */
728# undef EXTRACT_NUMBER
729# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
730# endif /* not EXTRACT_MACROS */
731
732#endif /* DEBUG */
733
734/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. 724/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
735 SOURCE must be an lvalue. */ 725 SOURCE must be an lvalue. */
736 726
737#define EXTRACT_NUMBER_AND_INCR(destination, source) \ 727#define EXTRACT_NUMBER_AND_INCR(destination, source) \
738 do { \ 728 ((destination) = extract_number_and_incr (&source))
739 EXTRACT_NUMBER (destination, source); \
740 (source) += 2; \
741 } while (0)
742 729
743#ifdef DEBUG 730static int
744static void 731extract_number_and_incr (re_char **source)
745extract_number_and_incr (int *destination, re_char **source)
746{ 732{
747 extract_number (destination, *source); 733 int num = extract_number (*source);
748 *source += 2; 734 *source += 2;
735 return num;
749} 736}
750
751# ifndef EXTRACT_MACROS
752# undef EXTRACT_NUMBER_AND_INCR
753# define EXTRACT_NUMBER_AND_INCR(dest, src) \
754 extract_number_and_incr (&dest, &src)
755# endif /* not EXTRACT_MACROS */
756
757#endif /* DEBUG */
758 737
759/* Store a multibyte character in three contiguous bytes starting 738/* Store a multibyte character in three contiguous bytes starting
760 DESTINATION, and increment DESTINATION to the byte after where the 739 DESTINATION, and increment DESTINATION to the byte after where the
@@ -861,10 +840,8 @@ extract_number_and_incr (int *destination, re_char **source)
861static int debug = -100000; 840static int debug = -100000;
862 841
863# define DEBUG_STATEMENT(e) e 842# define DEBUG_STATEMENT(e) e
864# define DEBUG_PRINT1(x) if (debug > 0) printf (x) 843# define DEBUG_PRINT(...) if (debug > 0) printf (__VA_ARGS__)
865# define DEBUG_PRINT2(x1, x2) if (debug > 0) printf (x1, x2) 844# define DEBUG_COMPILES_ARGUMENTS
866# define DEBUG_PRINT3(x1, x2, x3) if (debug > 0) printf (x1, x2, x3)
867# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug > 0) printf (x1, x2, x3, x4)
868# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ 845# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
869 if (debug > 0) print_partial_compiled_pattern (s, e) 846 if (debug > 0) print_partial_compiled_pattern (s, e)
870# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ 847# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
@@ -873,9 +850,8 @@ static int debug = -100000;
873 850
874/* Print the fastmap in human-readable form. */ 851/* Print the fastmap in human-readable form. */
875 852
876void 853static void
877print_fastmap (fastmap) 854print_fastmap (char *fastmap)
878 char *fastmap;
879{ 855{
880 unsigned was_a_range = 0; 856 unsigned was_a_range = 0;
881 unsigned i = 0; 857 unsigned i = 0;
@@ -905,10 +881,8 @@ print_fastmap (fastmap)
905/* Print a compiled pattern string in human-readable form, starting at 881/* Print a compiled pattern string in human-readable form, starting at
906 the START pointer into it and ending just before the pointer END. */ 882 the START pointer into it and ending just before the pointer END. */
907 883
908void 884static void
909print_partial_compiled_pattern (start, end) 885print_partial_compiled_pattern (re_char *start, re_char *end)
910 re_char *start;
911 re_char *end;
912{ 886{
913 int mcnt, mcnt2; 887 int mcnt, mcnt2;
914 re_char *p = start; 888 re_char *p = start;
@@ -923,7 +897,7 @@ print_partial_compiled_pattern (start, end)
923 /* Loop over pattern commands. */ 897 /* Loop over pattern commands. */
924 while (p < pend) 898 while (p < pend)
925 { 899 {
926 fprintf (stderr, "%d:\t", p - start); 900 fprintf (stderr, "%td:\t", p - start);
927 901
928 switch ((re_opcode_t) *p++) 902 switch ((re_opcode_t) *p++)
929 { 903 {
@@ -1027,51 +1001,58 @@ print_partial_compiled_pattern (start, end)
1027 break; 1001 break;
1028 1002
1029 case on_failure_jump: 1003 case on_failure_jump:
1030 extract_number_and_incr (&mcnt, &p); 1004 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1031 fprintf (stderr, "/on_failure_jump to %d", p + mcnt - start); 1005 fprintf (stderr, "/on_failure_jump to %td", p + mcnt - start);
1032 break; 1006 break;
1033 1007
1034 case on_failure_keep_string_jump: 1008 case on_failure_keep_string_jump:
1035 extract_number_and_incr (&mcnt, &p); 1009 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1036 fprintf (stderr, "/on_failure_keep_string_jump to %d", p + mcnt - start); 1010 fprintf (stderr, "/on_failure_keep_string_jump to %td",
1011 p + mcnt - start);
1037 break; 1012 break;
1038 1013
1039 case on_failure_jump_nastyloop: 1014 case on_failure_jump_nastyloop:
1040 extract_number_and_incr (&mcnt, &p); 1015 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1041 fprintf (stderr, "/on_failure_jump_nastyloop to %d", p + mcnt - start); 1016 fprintf (stderr, "/on_failure_jump_nastyloop to %td",
1017 p + mcnt - start);
1042 break; 1018 break;
1043 1019
1044 case on_failure_jump_loop: 1020 case on_failure_jump_loop:
1045 extract_number_and_incr (&mcnt, &p); 1021 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1046 fprintf (stderr, "/on_failure_jump_loop to %d", p + mcnt - start); 1022 fprintf (stderr, "/on_failure_jump_loop to %td",
1023 p + mcnt - start);
1047 break; 1024 break;
1048 1025
1049 case on_failure_jump_smart: 1026 case on_failure_jump_smart:
1050 extract_number_and_incr (&mcnt, &p); 1027 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1051 fprintf (stderr, "/on_failure_jump_smart to %d", p + mcnt - start); 1028 fprintf (stderr, "/on_failure_jump_smart to %td",
1029 p + mcnt - start);
1052 break; 1030 break;
1053 1031
1054 case jump: 1032 case jump:
1055 extract_number_and_incr (&mcnt, &p); 1033 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1056 fprintf (stderr, "/jump to %d", p + mcnt - start); 1034 fprintf (stderr, "/jump to %td", p + mcnt - start);
1057 break; 1035 break;
1058 1036
1059 case succeed_n: 1037 case succeed_n:
1060 extract_number_and_incr (&mcnt, &p); 1038 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1061 extract_number_and_incr (&mcnt2, &p); 1039 EXTRACT_NUMBER_AND_INCR (mcnt2, p);
1062 fprintf (stderr, "/succeed_n to %d, %d times", p - 2 + mcnt - start, mcnt2); 1040 fprintf (stderr, "/succeed_n to %td, %d times",
1041 p - 2 + mcnt - start, mcnt2);
1063 break; 1042 break;
1064 1043
1065 case jump_n: 1044 case jump_n:
1066 extract_number_and_incr (&mcnt, &p); 1045 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1067 extract_number_and_incr (&mcnt2, &p); 1046 EXTRACT_NUMBER_AND_INCR (mcnt2, p);
1068 fprintf (stderr, "/jump_n to %d, %d times", p - 2 + mcnt - start, mcnt2); 1047 fprintf (stderr, "/jump_n to %td, %d times",
1048 p - 2 + mcnt - start, mcnt2);
1069 break; 1049 break;
1070 1050
1071 case set_number_at: 1051 case set_number_at:
1072 extract_number_and_incr (&mcnt, &p); 1052 EXTRACT_NUMBER_AND_INCR (mcnt, p);
1073 extract_number_and_incr (&mcnt2, &p); 1053 EXTRACT_NUMBER_AND_INCR (mcnt2, p);
1074 fprintf (stderr, "/set_number_at location %d to %d", p - 2 + mcnt - start, mcnt2); 1054 fprintf (stderr, "/set_number_at location %td to %d",
1055 p - 2 + mcnt - start, mcnt2);
1075 break; 1056 break;
1076 1057
1077 case wordbound: 1058 case wordbound:
@@ -1151,13 +1132,12 @@ print_partial_compiled_pattern (start, end)
1151 fprintf (stderr, "\n"); 1132 fprintf (stderr, "\n");
1152 } 1133 }
1153 1134
1154 fprintf (stderr, "%d:\tend of pattern.\n", p - start); 1135 fprintf (stderr, "%td:\tend of pattern.\n", p - start);
1155} 1136}
1156 1137
1157 1138
1158void 1139static void
1159print_compiled_pattern (bufp) 1140print_compiled_pattern (struct re_pattern_buffer *bufp)
1160 struct re_pattern_buffer *bufp;
1161{ 1141{
1162 re_char *buffer = bufp->buffer; 1142 re_char *buffer = bufp->buffer;
1163 1143
@@ -1171,7 +1151,7 @@ print_compiled_pattern (bufp)
1171 print_fastmap (bufp->fastmap); 1151 print_fastmap (bufp->fastmap);
1172 } 1152 }
1173 1153
1174 printf ("re_nsub: %d\t", bufp->re_nsub); 1154 printf ("re_nsub: %zu\t", bufp->re_nsub);
1175 printf ("regs_alloc: %d\t", bufp->regs_allocated); 1155 printf ("regs_alloc: %d\t", bufp->regs_allocated);
1176 printf ("can_be_null: %d\t", bufp->can_be_null); 1156 printf ("can_be_null: %d\t", bufp->can_be_null);
1177 printf ("no_sub: %d\t", bufp->no_sub); 1157 printf ("no_sub: %d\t", bufp->no_sub);
@@ -1183,13 +1163,9 @@ print_compiled_pattern (bufp)
1183} 1163}
1184 1164
1185 1165
1186void 1166static void
1187print_double_string (where, string1, size1, string2, size2) 1167print_double_string (re_char *where, re_char *string1, ssize_t size1,
1188 re_char *where; 1168 re_char *string2, ssize_t size2)
1189 re_char *string1;
1190 re_char *string2;
1191 ssize_t size1;
1192 ssize_t size2;
1193{ 1169{
1194 ssize_t this_char; 1170 ssize_t this_char;
1195 1171
@@ -1216,10 +1192,12 @@ print_double_string (where, string1, size1, string2, size2)
1216# define assert(e) 1192# define assert(e)
1217 1193
1218# define DEBUG_STATEMENT(e) 1194# define DEBUG_STATEMENT(e)
1219# define DEBUG_PRINT1(x) 1195# if __STDC_VERSION__ < 199901L
1220# define DEBUG_PRINT2(x1, x2) 1196# define DEBUG_COMPILES_ARGUMENTS
1221# define DEBUG_PRINT3(x1, x2, x3) 1197# define DEBUG_PRINT /* 'DEBUG_PRINT (x, y)' discards X and Y. */ (void)
1222# define DEBUG_PRINT4(x1, x2, x3, x4) 1198# else
1199# define DEBUG_PRINT(...)
1200# endif
1223# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) 1201# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
1224# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) 1202# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
1225 1203
@@ -1473,20 +1451,21 @@ typedef struct
1473while (REMAINING_AVAIL_SLOTS <= space) { \ 1451while (REMAINING_AVAIL_SLOTS <= space) { \
1474 if (!GROW_FAIL_STACK (fail_stack)) \ 1452 if (!GROW_FAIL_STACK (fail_stack)) \
1475 return -2; \ 1453 return -2; \
1476 DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", (fail_stack).size);\ 1454 DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\
1477 DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ 1455 DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\
1478} 1456}
1479 1457
1480/* Push register NUM onto the stack. */ 1458/* Push register NUM onto the stack. */
1481#define PUSH_FAILURE_REG(num) \ 1459#define PUSH_FAILURE_REG(num) \
1482do { \ 1460do { \
1483 char *destination; \ 1461 char *destination; \
1462 long n = num; \
1484 ENSURE_FAIL_STACK(3); \ 1463 ENSURE_FAIL_STACK(3); \
1485 DEBUG_PRINT4 (" Push reg %d (spanning %p -> %p)\n", \ 1464 DEBUG_PRINT (" Push reg %ld (spanning %p -> %p)\n", \
1486 num, regstart[num], regend[num]); \ 1465 n, regstart[n], regend[n]); \
1487 PUSH_FAILURE_POINTER (regstart[num]); \ 1466 PUSH_FAILURE_POINTER (regstart[n]); \
1488 PUSH_FAILURE_POINTER (regend[num]); \ 1467 PUSH_FAILURE_POINTER (regend[n]); \
1489 PUSH_FAILURE_INT (num); \ 1468 PUSH_FAILURE_INT (n); \
1490} while (0) 1469} while (0)
1491 1470
1492/* Change the counter's value to VAL, but make sure that it will 1471/* Change the counter's value to VAL, but make sure that it will
@@ -1497,7 +1476,7 @@ do { \
1497 int c; \ 1476 int c; \
1498 ENSURE_FAIL_STACK(3); \ 1477 ENSURE_FAIL_STACK(3); \
1499 EXTRACT_NUMBER (c, ptr); \ 1478 EXTRACT_NUMBER (c, ptr); \
1500 DEBUG_PRINT4 (" Push number %p = %d -> %d\n", ptr, c, val); \ 1479 DEBUG_PRINT (" Push number %p = %d -> %d\n", ptr, c, val); \
1501 PUSH_FAILURE_INT (c); \ 1480 PUSH_FAILURE_INT (c); \
1502 PUSH_FAILURE_POINTER (ptr); \ 1481 PUSH_FAILURE_POINTER (ptr); \
1503 PUSH_FAILURE_INT (-1); \ 1482 PUSH_FAILURE_INT (-1); \
@@ -1515,14 +1494,14 @@ do { \
1515 unsigned char *ptr = (unsigned char*) POP_FAILURE_POINTER (); \ 1494 unsigned char *ptr = (unsigned char*) POP_FAILURE_POINTER (); \
1516 pfreg = POP_FAILURE_INT (); \ 1495 pfreg = POP_FAILURE_INT (); \
1517 STORE_NUMBER (ptr, pfreg); \ 1496 STORE_NUMBER (ptr, pfreg); \
1518 DEBUG_PRINT3 (" Pop counter %p = %d\n", ptr, pfreg); \ 1497 DEBUG_PRINT (" Pop counter %p = %ld\n", ptr, pfreg); \
1519 } \ 1498 } \
1520 else \ 1499 else \
1521 { \ 1500 { \
1522 regend[pfreg] = POP_FAILURE_POINTER (); \ 1501 regend[pfreg] = POP_FAILURE_POINTER (); \
1523 regstart[pfreg] = POP_FAILURE_POINTER (); \ 1502 regstart[pfreg] = POP_FAILURE_POINTER (); \
1524 DEBUG_PRINT4 (" Pop reg %d (spanning %p -> %p)\n", \ 1503 DEBUG_PRINT (" Pop reg %ld (spanning %p -> %p)\n", \
1525 pfreg, regstart[pfreg], regend[pfreg]); \ 1504 pfreg, regstart[pfreg], regend[pfreg]); \
1526 } \ 1505 } \
1527} while (0) 1506} while (0)
1528 1507
@@ -1542,10 +1521,10 @@ do { \
1542 cycle = 1; \ 1521 cycle = 1; \
1543 break; \ 1522 break; \
1544 } \ 1523 } \
1545 DEBUG_PRINT2 (" Other pattern: %p\n", FAILURE_PAT (failure)); \ 1524 DEBUG_PRINT (" Other pattern: %p\n", FAILURE_PAT (failure)); \
1546 failure = NEXT_FAILURE_HANDLE(failure); \ 1525 failure = NEXT_FAILURE_HANDLE(failure); \
1547 } \ 1526 } \
1548 DEBUG_PRINT2 (" Other string: %p\n", FAILURE_STR (failure)); \ 1527 DEBUG_PRINT (" Other string: %p\n", FAILURE_STR (failure)); \
1549} while (0) 1528} while (0)
1550 1529
1551/* Push the information about the state we will need 1530/* Push the information about the state we will need
@@ -1564,23 +1543,23 @@ do { \
1564 of 0 + -1 isn't done as unsigned. */ \ 1543 of 0 + -1 isn't done as unsigned. */ \
1565 \ 1544 \
1566 DEBUG_STATEMENT (nfailure_points_pushed++); \ 1545 DEBUG_STATEMENT (nfailure_points_pushed++); \
1567 DEBUG_PRINT1 ("\nPUSH_FAILURE_POINT:\n"); \ 1546 DEBUG_PRINT ("\nPUSH_FAILURE_POINT:\n"); \
1568 DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail); \ 1547 DEBUG_PRINT (" Before push, next avail: %zd\n", (fail_stack).avail); \
1569 DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ 1548 DEBUG_PRINT (" size: %zd\n", (fail_stack).size);\
1570 \ 1549 \
1571 ENSURE_FAIL_STACK (NUM_NONREG_ITEMS); \ 1550 ENSURE_FAIL_STACK (NUM_NONREG_ITEMS); \
1572 \ 1551 \
1573 DEBUG_PRINT1 ("\n"); \ 1552 DEBUG_PRINT ("\n"); \
1574 \ 1553 \
1575 DEBUG_PRINT2 (" Push frame index: %d\n", fail_stack.frame); \ 1554 DEBUG_PRINT (" Push frame index: %zd\n", fail_stack.frame); \
1576 PUSH_FAILURE_INT (fail_stack.frame); \ 1555 PUSH_FAILURE_INT (fail_stack.frame); \
1577 \ 1556 \
1578 DEBUG_PRINT2 (" Push string %p: `", string_place); \ 1557 DEBUG_PRINT (" Push string %p: `", string_place); \
1579 DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, size2);\ 1558 DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, size2);\
1580 DEBUG_PRINT1 ("'\n"); \ 1559 DEBUG_PRINT ("'\n"); \
1581 PUSH_FAILURE_POINTER (string_place); \ 1560 PUSH_FAILURE_POINTER (string_place); \
1582 \ 1561 \
1583 DEBUG_PRINT2 (" Push pattern %p: ", pattern); \ 1562 DEBUG_PRINT (" Push pattern %p: ", pattern); \
1584 DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern, pend); \ 1563 DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern, pend); \
1585 PUSH_FAILURE_POINTER (pattern); \ 1564 PUSH_FAILURE_POINTER (pattern); \
1586 \ 1565 \
@@ -1613,28 +1592,28 @@ do { \
1613 assert (!FAIL_STACK_EMPTY ()); \ 1592 assert (!FAIL_STACK_EMPTY ()); \
1614 \ 1593 \
1615 /* Remove failure points and point to how many regs pushed. */ \ 1594 /* Remove failure points and point to how many regs pushed. */ \
1616 DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ 1595 DEBUG_PRINT ("POP_FAILURE_POINT:\n"); \
1617 DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ 1596 DEBUG_PRINT (" Before pop, next avail: %zd\n", fail_stack.avail); \
1618 DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ 1597 DEBUG_PRINT (" size: %zd\n", fail_stack.size); \
1619 \ 1598 \
1620 /* Pop the saved registers. */ \ 1599 /* Pop the saved registers. */ \
1621 while (fail_stack.frame < fail_stack.avail) \ 1600 while (fail_stack.frame < fail_stack.avail) \
1622 POP_FAILURE_REG_OR_COUNT (); \ 1601 POP_FAILURE_REG_OR_COUNT (); \
1623 \ 1602 \
1624 pat = POP_FAILURE_POINTER (); \ 1603 pat = POP_FAILURE_POINTER (); \
1625 DEBUG_PRINT2 (" Popping pattern %p: ", pat); \ 1604 DEBUG_PRINT (" Popping pattern %p: ", pat); \
1626 DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ 1605 DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
1627 \ 1606 \
1628 /* If the saved string location is NULL, it came from an \ 1607 /* If the saved string location is NULL, it came from an \
1629 on_failure_keep_string_jump opcode, and we want to throw away the \ 1608 on_failure_keep_string_jump opcode, and we want to throw away the \
1630 saved NULL, thus retaining our current position in the string. */ \ 1609 saved NULL, thus retaining our current position in the string. */ \
1631 str = POP_FAILURE_POINTER (); \ 1610 str = POP_FAILURE_POINTER (); \
1632 DEBUG_PRINT2 (" Popping string %p: `", str); \ 1611 DEBUG_PRINT (" Popping string %p: `", str); \
1633 DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ 1612 DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
1634 DEBUG_PRINT1 ("'\n"); \ 1613 DEBUG_PRINT ("'\n"); \
1635 \ 1614 \
1636 fail_stack.frame = POP_FAILURE_INT (); \ 1615 fail_stack.frame = POP_FAILURE_INT (); \
1637 DEBUG_PRINT2 (" Popping frame index: %d\n", fail_stack.frame); \ 1616 DEBUG_PRINT (" Popping frame index: %zd\n", fail_stack.frame); \
1638 \ 1617 \
1639 assert (fail_stack.avail >= 0); \ 1618 assert (fail_stack.avail >= 0); \
1640 assert (fail_stack.frame <= fail_stack.avail); \ 1619 assert (fail_stack.frame <= fail_stack.avail); \
@@ -2497,7 +2476,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
2497 2476
2498#ifdef DEBUG 2477#ifdef DEBUG
2499 debug++; 2478 debug++;
2500 DEBUG_PRINT1 ("\nCompiling pattern: "); 2479 DEBUG_PRINT ("\nCompiling pattern: ");
2501 if (debug > 0) 2480 if (debug > 0)
2502 { 2481 {
2503 unsigned debug_count; 2482 unsigned debug_count;
@@ -2650,7 +2629,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
2650 goto normal_char; 2629 goto normal_char;
2651 handle_plus: 2630 handle_plus:
2652 case '*': 2631 case '*':
2653 /* If there is no previous pattern... */ 2632 /* If there is no previous pattern... */
2654 if (!laststart) 2633 if (!laststart)
2655 { 2634 {
2656 if (syntax & RE_CONTEXT_INVALID_OPS) 2635 if (syntax & RE_CONTEXT_INVALID_OPS)
@@ -2758,7 +2737,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
2758 } 2737 }
2759 } 2738 }
2760 else /* not greedy */ 2739 else /* not greedy */
2761 { /* I wish the greedy and non-greedy cases could be merged. */ 2740 { /* I wish the greedy and non-greedy cases could be merged. */
2762 2741
2763 GET_BUFFER_SPACE (7); /* We might use less. */ 2742 GET_BUFFER_SPACE (7); /* We might use less. */
2764 if (many_times_ok) 2743 if (many_times_ok)
@@ -3062,7 +3041,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
3062 3041
3063 /* Allocate space for COUNT + RANGE_TABLE. Needs two 3042 /* Allocate space for COUNT + RANGE_TABLE. Needs two
3064 bytes for flags, two for COUNT, and three bytes for 3043 bytes for flags, two for COUNT, and three bytes for
3065 each character. */ 3044 each character. */
3066 GET_BUFFER_SPACE (4 + used * 3); 3045 GET_BUFFER_SPACE (4 + used * 3);
3067 3046
3068 /* Indicate the existence of range table. */ 3047 /* Indicate the existence of range table. */
@@ -3489,6 +3468,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
3489 /* There is no way to specify the before_dot and after_dot 3468 /* There is no way to specify the before_dot and after_dot
3490 operators. rms says this is ok. --karl */ 3469 operators. rms says this is ok. --karl */
3491 case '=': 3470 case '=':
3471 laststart = b;
3492 BUF_PUSH (at_dot); 3472 BUF_PUSH (at_dot);
3493 break; 3473 break;
3494 3474
@@ -3537,12 +3517,14 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
3537 case '<': 3517 case '<':
3538 if (syntax & RE_NO_GNU_OPS) 3518 if (syntax & RE_NO_GNU_OPS)
3539 goto normal_char; 3519 goto normal_char;
3520 laststart = b;
3540 BUF_PUSH (wordbeg); 3521 BUF_PUSH (wordbeg);
3541 break; 3522 break;
3542 3523
3543 case '>': 3524 case '>':
3544 if (syntax & RE_NO_GNU_OPS) 3525 if (syntax & RE_NO_GNU_OPS)
3545 goto normal_char; 3526 goto normal_char;
3527 laststart = b;
3546 BUF_PUSH (wordend); 3528 BUF_PUSH (wordend);
3547 break; 3529 break;
3548 3530
@@ -3701,7 +3683,7 @@ regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct
3701 if (debug > 0) 3683 if (debug > 0)
3702 { 3684 {
3703 re_compile_fastmap (bufp); 3685 re_compile_fastmap (bufp);
3704 DEBUG_PRINT1 ("\nCompiled pattern: \n"); 3686 DEBUG_PRINT ("\nCompiled pattern: \n");
3705 print_compiled_pattern (bufp); 3687 print_compiled_pattern (bufp);
3706 } 3688 }
3707 debug--; 3689 debug--;
@@ -4527,8 +4509,8 @@ static int bcmp_translate (re_char *s1, re_char *s2,
4527 and `string2' into an offset from the beginning of that string. */ 4509 and `string2' into an offset from the beginning of that string. */
4528#define POINTER_TO_OFFSET(ptr) \ 4510#define POINTER_TO_OFFSET(ptr) \
4529 (FIRST_STRING_P (ptr) \ 4511 (FIRST_STRING_P (ptr) \
4530 ? ((regoff_t) ((ptr) - string1)) \ 4512 ? (ptr) - string1 \
4531 : ((regoff_t) ((ptr) - string2 + size1))) 4513 : (ptr) - string2 + (ptrdiff_t) size1)
4532 4514
4533/* Call before fetching a character with *d. This switches over to 4515/* Call before fetching a character with *d. This switches over to
4534 string2 if necessary. 4516 string2 if necessary.
@@ -4715,7 +4697,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
4715 /* If we're at the end of the pattern, we can change. */ 4697 /* If we're at the end of the pattern, we can change. */
4716 if (skip_one_char (p1)) 4698 if (skip_one_char (p1))
4717 { 4699 {
4718 DEBUG_PRINT1 (" End of pattern: fast loop.\n"); 4700 DEBUG_PRINT (" End of pattern: fast loop.\n");
4719 return 1; 4701 return 1;
4720 } 4702 }
4721 break; 4703 break;
@@ -4731,7 +4713,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
4731 { 4713 {
4732 if (c != RE_STRING_CHAR (p1 + 2, multibyte)) 4714 if (c != RE_STRING_CHAR (p1 + 2, multibyte))
4733 { 4715 {
4734 DEBUG_PRINT3 (" '%c' != '%c' => fast loop.\n", c, p1[2]); 4716 DEBUG_PRINT (" '%c' != '%c' => fast loop.\n", c, p1[2]);
4735 return 1; 4717 return 1;
4736 } 4718 }
4737 } 4719 }
@@ -4756,14 +4738,14 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
4756 that we can't change to pop_failure_jump. */ 4738 that we can't change to pop_failure_jump. */
4757 if (!not) 4739 if (!not)
4758 { 4740 {
4759 DEBUG_PRINT1 (" No match => fast loop.\n"); 4741 DEBUG_PRINT (" No match => fast loop.\n");
4760 return 1; 4742 return 1;
4761 } 4743 }
4762 } 4744 }
4763 else if ((re_opcode_t) *p1 == anychar 4745 else if ((re_opcode_t) *p1 == anychar
4764 && c == '\n') 4746 && c == '\n')
4765 { 4747 {
4766 DEBUG_PRINT1 (" . != \\n => fast loop.\n"); 4748 DEBUG_PRINT (" . != \\n => fast loop.\n");
4767 return 1; 4749 return 1;
4768 } 4750 }
4769 } 4751 }
@@ -4806,7 +4788,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
4806 if (idx == p2[1] 4788 if (idx == p2[1]
4807 || idx == CHARSET_BITMAP_SIZE (p1)) 4789 || idx == CHARSET_BITMAP_SIZE (p1))
4808 { 4790 {
4809 DEBUG_PRINT1 (" No match => fast loop.\n"); 4791 DEBUG_PRINT (" No match => fast loop.\n");
4810 return 1; 4792 return 1;
4811 } 4793 }
4812 } 4794 }
@@ -4823,7 +4805,7 @@ mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const r
4823 4805
4824 if (idx == p2[1]) 4806 if (idx == p2[1])
4825 { 4807 {
4826 DEBUG_PRINT1 (" No match => fast loop.\n"); 4808 DEBUG_PRINT (" No match => fast loop.\n");
4827 return 1; 4809 return 1;
4828 } 4810 }
4829 } 4811 }
@@ -4943,7 +4925,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
4943 ssize_t pos, struct re_registers *regs, ssize_t stop) 4925 ssize_t pos, struct re_registers *regs, ssize_t stop)
4944{ 4926{
4945 /* General temporaries. */ 4927 /* General temporaries. */
4946 ssize_t mcnt; 4928 int mcnt;
4947 size_t reg; 4929 size_t reg;
4948 4930
4949 /* Just past the end of the corresponding string. */ 4931 /* Just past the end of the corresponding string. */
@@ -4985,7 +4967,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
4985#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ 4967#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
4986 fail_stack_type fail_stack; 4968 fail_stack_type fail_stack;
4987#endif 4969#endif
4988#ifdef DEBUG 4970#ifdef DEBUG_COMPILES_ARGUMENTS
4989 unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; 4971 unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
4990#endif 4972#endif
4991 4973
@@ -5030,12 +5012,12 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5030 and need to test it, it's not garbage. */ 5012 and need to test it, it's not garbage. */
5031 re_char *match_end = NULL; 5013 re_char *match_end = NULL;
5032 5014
5033#ifdef DEBUG 5015#ifdef DEBUG_COMPILES_ARGUMENTS
5034 /* Counts the total number of registers pushed. */ 5016 /* Counts the total number of registers pushed. */
5035 unsigned num_regs_pushed = 0; 5017 unsigned num_regs_pushed = 0;
5036#endif 5018#endif
5037 5019
5038 DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); 5020 DEBUG_PRINT ("\n\nEntering re_match_2.\n");
5039 5021
5040 INIT_FAIL_STACK (); 5022 INIT_FAIL_STACK ();
5041 5023
@@ -5131,22 +5113,25 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5131 dend = end_match_1; 5113 dend = end_match_1;
5132 } 5114 }
5133 5115
5134 DEBUG_PRINT1 ("The compiled pattern is: "); 5116 DEBUG_PRINT ("The compiled pattern is: ");
5135 DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); 5117 DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
5136 DEBUG_PRINT1 ("The string to match is: `"); 5118 DEBUG_PRINT ("The string to match is: `");
5137 DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); 5119 DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
5138 DEBUG_PRINT1 ("'\n"); 5120 DEBUG_PRINT ("'\n");
5139 5121
5140 /* This loops over pattern commands. It exits by returning from the 5122 /* This loops over pattern commands. It exits by returning from the
5141 function if the match is complete, or it drops through if the match 5123 function if the match is complete, or it drops through if the match
5142 fails at this starting point in the input data. */ 5124 fails at this starting point in the input data. */
5143 for (;;) 5125 for (;;)
5144 { 5126 {
5145 DEBUG_PRINT2 ("\n%p: ", p); 5127 DEBUG_PRINT ("\n%p: ", p);
5146 5128
5147 if (p == pend) 5129 if (p == pend)
5148 { /* End of pattern means we might have succeeded. */ 5130 {
5149 DEBUG_PRINT1 ("end of pattern ... "); 5131 ptrdiff_t dcnt;
5132
5133 /* End of pattern means we might have succeeded. */
5134 DEBUG_PRINT ("end of pattern ... ");
5150 5135
5151 /* If we haven't matched the entire string, and we want the 5136 /* If we haven't matched the entire string, and we want the
5152 longest match, try backtracking. */ 5137 longest match, try backtracking. */
@@ -5166,7 +5151,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5166 else 5151 else
5167 best_match_p = !FIRST_STRING_P (d); 5152 best_match_p = !FIRST_STRING_P (d);
5168 5153
5169 DEBUG_PRINT1 ("backtracking.\n"); 5154 DEBUG_PRINT ("backtracking.\n");
5170 5155
5171 if (!FAIL_STACK_EMPTY ()) 5156 if (!FAIL_STACK_EMPTY ())
5172 { /* More failure points to try. */ 5157 { /* More failure points to try. */
@@ -5177,7 +5162,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5177 best_regs_set = true; 5162 best_regs_set = true;
5178 match_end = d; 5163 match_end = d;
5179 5164
5180 DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); 5165 DEBUG_PRINT ("\nSAVING match as best so far.\n");
5181 5166
5182 for (reg = 1; reg < num_regs; reg++) 5167 for (reg = 1; reg < num_regs; reg++)
5183 { 5168 {
@@ -5199,7 +5184,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5199 For example, the pattern `x.*y.*z' against the 5184 For example, the pattern `x.*y.*z' against the
5200 strings `x-' and `y-z-', if the two strings are 5185 strings `x-' and `y-z-', if the two strings are
5201 not consecutive in memory. */ 5186 not consecutive in memory. */
5202 DEBUG_PRINT1 ("Restoring best registers.\n"); 5187 DEBUG_PRINT ("Restoring best registers.\n");
5203 5188
5204 d = match_end; 5189 d = match_end;
5205 dend = ((d >= string1 && d <= end1) 5190 dend = ((d >= string1 && d <= end1)
@@ -5214,7 +5199,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5214 } /* d != end_match_2 */ 5199 } /* d != end_match_2 */
5215 5200
5216 succeed_label: 5201 succeed_label:
5217 DEBUG_PRINT1 ("Accepting match.\n"); 5202 DEBUG_PRINT ("Accepting match.\n");
5218 5203
5219 /* If caller wants register contents data back, do it. */ 5204 /* If caller wants register contents data back, do it. */
5220 if (regs && !bufp->no_sub) 5205 if (regs && !bufp->no_sub)
@@ -5274,10 +5259,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5274 regs->start[reg] = regs->end[reg] = -1; 5259 regs->start[reg] = regs->end[reg] = -1;
5275 else 5260 else
5276 { 5261 {
5277 regs->start[reg] 5262 regs->start[reg] = POINTER_TO_OFFSET (regstart[reg]);
5278 = (regoff_t) POINTER_TO_OFFSET (regstart[reg]); 5263 regs->end[reg] = POINTER_TO_OFFSET (regend[reg]);
5279 regs->end[reg]
5280 = (regoff_t) POINTER_TO_OFFSET (regend[reg]);
5281 } 5264 }
5282 } 5265 }
5283 5266
@@ -5290,17 +5273,17 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5290 regs->start[reg] = regs->end[reg] = -1; 5273 regs->start[reg] = regs->end[reg] = -1;
5291 } /* regs && !bufp->no_sub */ 5274 } /* regs && !bufp->no_sub */
5292 5275
5293 DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", 5276 DEBUG_PRINT ("%u failure points pushed, %u popped (%u remain).\n",
5294 nfailure_points_pushed, nfailure_points_popped, 5277 nfailure_points_pushed, nfailure_points_popped,
5295 nfailure_points_pushed - nfailure_points_popped); 5278 nfailure_points_pushed - nfailure_points_popped);
5296 DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); 5279 DEBUG_PRINT ("%u registers pushed.\n", num_regs_pushed);
5297 5280
5298 mcnt = POINTER_TO_OFFSET (d) - pos; 5281 dcnt = POINTER_TO_OFFSET (d) - pos;
5299 5282
5300 DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); 5283 DEBUG_PRINT ("Returning %td from re_match_2.\n", dcnt);
5301 5284
5302 FREE_VARIABLES (); 5285 FREE_VARIABLES ();
5303 return mcnt; 5286 return dcnt;
5304 } 5287 }
5305 5288
5306 /* Otherwise match next pattern command. */ 5289 /* Otherwise match next pattern command. */
@@ -5309,11 +5292,11 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5309 /* Ignore these. Used to ignore the n of succeed_n's which 5292 /* Ignore these. Used to ignore the n of succeed_n's which
5310 currently have n == 0. */ 5293 currently have n == 0. */
5311 case no_op: 5294 case no_op:
5312 DEBUG_PRINT1 ("EXECUTING no_op.\n"); 5295 DEBUG_PRINT ("EXECUTING no_op.\n");
5313 break; 5296 break;
5314 5297
5315 case succeed: 5298 case succeed:
5316 DEBUG_PRINT1 ("EXECUTING succeed.\n"); 5299 DEBUG_PRINT ("EXECUTING succeed.\n");
5317 goto succeed_label; 5300 goto succeed_label;
5318 5301
5319 /* Match the next n pattern characters exactly. The following 5302 /* Match the next n pattern characters exactly. The following
@@ -5321,7 +5304,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5321 are the characters to match. */ 5304 are the characters to match. */
5322 case exactn: 5305 case exactn:
5323 mcnt = *p++; 5306 mcnt = *p++;
5324 DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); 5307 DEBUG_PRINT ("EXECUTING exactn %d.\n", mcnt);
5325 5308
5326 /* Remember the start point to rollback upon failure. */ 5309 /* Remember the start point to rollback upon failure. */
5327 dfail = d; 5310 dfail = d;
@@ -5427,7 +5410,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5427 int buf_charlen; 5410 int buf_charlen;
5428 re_wchar_t buf_ch; 5411 re_wchar_t buf_ch;
5429 5412
5430 DEBUG_PRINT1 ("EXECUTING anychar.\n"); 5413 DEBUG_PRINT ("EXECUTING anychar.\n");
5431 5414
5432 PREFETCH (); 5415 PREFETCH ();
5433 buf_ch = RE_STRING_CHAR_AND_LENGTH (d, buf_charlen, 5416 buf_ch = RE_STRING_CHAR_AND_LENGTH (d, buf_charlen,
@@ -5440,7 +5423,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5440 && buf_ch == '\000')) 5423 && buf_ch == '\000'))
5441 goto fail; 5424 goto fail;
5442 5425
5443 DEBUG_PRINT2 (" Matched `%d'.\n", *d); 5426 DEBUG_PRINT (" Matched `%d'.\n", *d);
5444 d += buf_charlen; 5427 d += buf_charlen;
5445 } 5428 }
5446 break; 5429 break;
@@ -5467,7 +5450,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5467 /* Whether matching against a unibyte character. */ 5450 /* Whether matching against a unibyte character. */
5468 boolean unibyte_char = false; 5451 boolean unibyte_char = false;
5469 5452
5470 DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); 5453 DEBUG_PRINT ("EXECUTING charset%s.\n", not ? "_not" : "");
5471 5454
5472 range_table_exists = CHARSET_RANGE_TABLE_EXISTS_P (&p[-1]); 5455 range_table_exists = CHARSET_RANGE_TABLE_EXISTS_P (&p[-1]);
5473 5456
@@ -5551,14 +5534,14 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5551 matched within the group is recorded (in the internal 5534 matched within the group is recorded (in the internal
5552 registers data structure) under the register number. */ 5535 registers data structure) under the register number. */
5553 case start_memory: 5536 case start_memory:
5554 DEBUG_PRINT2 ("EXECUTING start_memory %d:\n", *p); 5537 DEBUG_PRINT ("EXECUTING start_memory %d:\n", *p);
5555 5538
5556 /* In case we need to undo this operation (via backtracking). */ 5539 /* In case we need to undo this operation (via backtracking). */
5557 PUSH_FAILURE_REG ((unsigned int)*p); 5540 PUSH_FAILURE_REG (*p);
5558 5541
5559 regstart[*p] = d; 5542 regstart[*p] = d;
5560 regend[*p] = NULL; /* probably unnecessary. -sm */ 5543 regend[*p] = NULL; /* probably unnecessary. -sm */
5561 DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); 5544 DEBUG_PRINT (" regstart: %td\n", POINTER_TO_OFFSET (regstart[*p]));
5562 5545
5563 /* Move past the register number and inner group count. */ 5546 /* Move past the register number and inner group count. */
5564 p += 1; 5547 p += 1;
@@ -5568,7 +5551,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5568 /* The stop_memory opcode represents the end of a group. Its 5551 /* The stop_memory opcode represents the end of a group. Its
5569 argument is the same as start_memory's: the register number. */ 5552 argument is the same as start_memory's: the register number. */
5570 case stop_memory: 5553 case stop_memory:
5571 DEBUG_PRINT2 ("EXECUTING stop_memory %d:\n", *p); 5554 DEBUG_PRINT ("EXECUTING stop_memory %d:\n", *p);
5572 5555
5573 assert (!REG_UNSET (regstart[*p])); 5556 assert (!REG_UNSET (regstart[*p]));
5574 /* Strictly speaking, there should be code such as: 5557 /* Strictly speaking, there should be code such as:
@@ -5586,7 +5569,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5586 is *not* undone. */ 5569 is *not* undone. */
5587 5570
5588 regend[*p] = d; 5571 regend[*p] = d;
5589 DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); 5572 DEBUG_PRINT (" regend: %td\n", POINTER_TO_OFFSET (regend[*p]));
5590 5573
5591 /* Move past the register number and the inner group count. */ 5574 /* Move past the register number and the inner group count. */
5592 p += 1; 5575 p += 1;
@@ -5599,7 +5582,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5599 { 5582 {
5600 register re_char *d2, *dend2; 5583 register re_char *d2, *dend2;
5601 int regno = *p++; /* Get which register to match against. */ 5584 int regno = *p++; /* Get which register to match against. */
5602 DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); 5585 DEBUG_PRINT ("EXECUTING duplicate %d.\n", regno);
5603 5586
5604 /* Can't back reference a group which we've never matched. */ 5587 /* Can't back reference a group which we've never matched. */
5605 if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) 5588 if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
@@ -5621,6 +5604,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5621 ? regend[regno] : end_match_1); 5604 ? regend[regno] : end_match_1);
5622 for (;;) 5605 for (;;)
5623 { 5606 {
5607 ptrdiff_t dcnt;
5608
5624 /* If necessary, advance to next segment in register 5609 /* If necessary, advance to next segment in register
5625 contents. */ 5610 contents. */
5626 while (d2 == dend2) 5611 while (d2 == dend2)
@@ -5639,23 +5624,23 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5639 PREFETCH (); 5624 PREFETCH ();
5640 5625
5641 /* How many characters left in this segment to match. */ 5626 /* How many characters left in this segment to match. */
5642 mcnt = dend - d; 5627 dcnt = dend - d;
5643 5628
5644 /* Want how many consecutive characters we can match in 5629 /* Want how many consecutive characters we can match in
5645 one shot, so, if necessary, adjust the count. */ 5630 one shot, so, if necessary, adjust the count. */
5646 if (mcnt > dend2 - d2) 5631 if (dcnt > dend2 - d2)
5647 mcnt = dend2 - d2; 5632 dcnt = dend2 - d2;
5648 5633
5649 /* Compare that many; failure if mismatch, else move 5634 /* Compare that many; failure if mismatch, else move
5650 past them. */ 5635 past them. */
5651 if (RE_TRANSLATE_P (translate) 5636 if (RE_TRANSLATE_P (translate)
5652 ? bcmp_translate (d, d2, mcnt, translate, target_multibyte) 5637 ? bcmp_translate (d, d2, dcnt, translate, target_multibyte)
5653 : memcmp (d, d2, mcnt)) 5638 : memcmp (d, d2, dcnt))
5654 { 5639 {
5655 d = dfail; 5640 d = dfail;
5656 goto fail; 5641 goto fail;
5657 } 5642 }
5658 d += mcnt, d2 += mcnt; 5643 d += dcnt, d2 += dcnt;
5659 } 5644 }
5660 } 5645 }
5661 break; 5646 break;
@@ -5664,7 +5649,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5664 /* begline matches the empty string at the beginning of the string 5649 /* begline matches the empty string at the beginning of the string
5665 (unless `not_bol' is set in `bufp'), and after newlines. */ 5650 (unless `not_bol' is set in `bufp'), and after newlines. */
5666 case begline: 5651 case begline:
5667 DEBUG_PRINT1 ("EXECUTING begline.\n"); 5652 DEBUG_PRINT ("EXECUTING begline.\n");
5668 5653
5669 if (AT_STRINGS_BEG (d)) 5654 if (AT_STRINGS_BEG (d))
5670 { 5655 {
@@ -5683,7 +5668,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5683 5668
5684 /* endline is the dual of begline. */ 5669 /* endline is the dual of begline. */
5685 case endline: 5670 case endline:
5686 DEBUG_PRINT1 ("EXECUTING endline.\n"); 5671 DEBUG_PRINT ("EXECUTING endline.\n");
5687 5672
5688 if (AT_STRINGS_END (d)) 5673 if (AT_STRINGS_END (d))
5689 { 5674 {
@@ -5700,7 +5685,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5700 5685
5701 /* Match at the very beginning of the data. */ 5686 /* Match at the very beginning of the data. */
5702 case begbuf: 5687 case begbuf:
5703 DEBUG_PRINT1 ("EXECUTING begbuf.\n"); 5688 DEBUG_PRINT ("EXECUTING begbuf.\n");
5704 if (AT_STRINGS_BEG (d)) 5689 if (AT_STRINGS_BEG (d))
5705 break; 5690 break;
5706 goto fail; 5691 goto fail;
@@ -5708,7 +5693,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5708 5693
5709 /* Match at the very end of the data. */ 5694 /* Match at the very end of the data. */
5710 case endbuf: 5695 case endbuf:
5711 DEBUG_PRINT1 ("EXECUTING endbuf.\n"); 5696 DEBUG_PRINT ("EXECUTING endbuf.\n");
5712 if (AT_STRINGS_END (d)) 5697 if (AT_STRINGS_END (d))
5713 break; 5698 break;
5714 goto fail; 5699 goto fail;
@@ -5732,8 +5717,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5732 case; that seems worse than this. */ 5717 case; that seems worse than this. */
5733 case on_failure_keep_string_jump: 5718 case on_failure_keep_string_jump:
5734 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5719 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5735 DEBUG_PRINT3 ("EXECUTING on_failure_keep_string_jump %d (to %p):\n", 5720 DEBUG_PRINT ("EXECUTING on_failure_keep_string_jump %d (to %p):\n",
5736 mcnt, p + mcnt); 5721 mcnt, p + mcnt);
5737 5722
5738 PUSH_FAILURE_POINT (p - 3, NULL); 5723 PUSH_FAILURE_POINT (p - 3, NULL);
5739 break; 5724 break;
@@ -5754,8 +5739,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5754 the loop. */ 5739 the loop. */
5755 case on_failure_jump_nastyloop: 5740 case on_failure_jump_nastyloop:
5756 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5741 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5757 DEBUG_PRINT3 ("EXECUTING on_failure_jump_nastyloop %d (to %p):\n", 5742 DEBUG_PRINT ("EXECUTING on_failure_jump_nastyloop %d (to %p):\n",
5758 mcnt, p + mcnt); 5743 mcnt, p + mcnt);
5759 5744
5760 assert ((re_opcode_t)p[-4] == no_op); 5745 assert ((re_opcode_t)p[-4] == no_op);
5761 { 5746 {
@@ -5775,8 +5760,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5775 case on_failure_jump_loop: 5760 case on_failure_jump_loop:
5776 on_failure: 5761 on_failure:
5777 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5762 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5778 DEBUG_PRINT3 ("EXECUTING on_failure_jump_loop %d (to %p):\n", 5763 DEBUG_PRINT ("EXECUTING on_failure_jump_loop %d (to %p):\n",
5779 mcnt, p + mcnt); 5764 mcnt, p + mcnt);
5780 { 5765 {
5781 int cycle = 0; 5766 int cycle = 0;
5782 CHECK_INFINITE_LOOP (p - 3, d); 5767 CHECK_INFINITE_LOOP (p - 3, d);
@@ -5807,8 +5792,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5807 pop_failure_jump back to this on_failure_jump. */ 5792 pop_failure_jump back to this on_failure_jump. */
5808 case on_failure_jump: 5793 case on_failure_jump:
5809 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5794 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5810 DEBUG_PRINT3 ("EXECUTING on_failure_jump %d (to %p):\n", 5795 DEBUG_PRINT ("EXECUTING on_failure_jump %d (to %p):\n",
5811 mcnt, p + mcnt); 5796 mcnt, p + mcnt);
5812 5797
5813 PUSH_FAILURE_POINT (p -3, d); 5798 PUSH_FAILURE_POINT (p -3, d);
5814 break; 5799 break;
@@ -5822,8 +5807,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5822 on_failure_keep_string_jump instead of on_failure_jump. */ 5807 on_failure_keep_string_jump instead of on_failure_jump. */
5823 case on_failure_jump_smart: 5808 case on_failure_jump_smart:
5824 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5809 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5825 DEBUG_PRINT3 ("EXECUTING on_failure_jump_smart %d (to %p).\n", 5810 DEBUG_PRINT ("EXECUTING on_failure_jump_smart %d (to %p).\n",
5826 mcnt, p + mcnt); 5811 mcnt, p + mcnt);
5827 { 5812 {
5828 re_char *p1 = p; /* Next operation. */ 5813 re_char *p1 = p; /* Next operation. */
5829 /* Here, we discard `const', making re_match non-reentrant. */ 5814 /* Here, we discard `const', making re_match non-reentrant. */
@@ -5843,14 +5828,14 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5843 if (mutually_exclusive_p (bufp, p1, p2)) 5828 if (mutually_exclusive_p (bufp, p1, p2))
5844 { 5829 {
5845 /* Use a fast `on_failure_keep_string_jump' loop. */ 5830 /* Use a fast `on_failure_keep_string_jump' loop. */
5846 DEBUG_PRINT1 (" smart exclusive => fast loop.\n"); 5831 DEBUG_PRINT (" smart exclusive => fast loop.\n");
5847 *p3 = (unsigned char) on_failure_keep_string_jump; 5832 *p3 = (unsigned char) on_failure_keep_string_jump;
5848 STORE_NUMBER (p2 - 2, mcnt + 3); 5833 STORE_NUMBER (p2 - 2, mcnt + 3);
5849 } 5834 }
5850 else 5835 else
5851 { 5836 {
5852 /* Default to a safe `on_failure_jump' loop. */ 5837 /* Default to a safe `on_failure_jump' loop. */
5853 DEBUG_PRINT1 (" smart default => slow loop.\n"); 5838 DEBUG_PRINT (" smart default => slow loop.\n");
5854 *p3 = (unsigned char) on_failure_jump; 5839 *p3 = (unsigned char) on_failure_jump;
5855 } 5840 }
5856 DEBUG_STATEMENT (debug -= 2); 5841 DEBUG_STATEMENT (debug -= 2);
@@ -5862,9 +5847,9 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5862 unconditional_jump: 5847 unconditional_jump:
5863 IMMEDIATE_QUIT_CHECK; 5848 IMMEDIATE_QUIT_CHECK;
5864 EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ 5849 EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
5865 DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); 5850 DEBUG_PRINT ("EXECUTING jump %d ", mcnt);
5866 p += mcnt; /* Do the jump. */ 5851 p += mcnt; /* Do the jump. */
5867 DEBUG_PRINT2 ("(to %p).\n", p); 5852 DEBUG_PRINT ("(to %p).\n", p);
5868 break; 5853 break;
5869 5854
5870 5855
@@ -5873,7 +5858,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5873 case succeed_n: 5858 case succeed_n:
5874 /* Signedness doesn't matter since we only compare MCNT to 0. */ 5859 /* Signedness doesn't matter since we only compare MCNT to 0. */
5875 EXTRACT_NUMBER (mcnt, p + 2); 5860 EXTRACT_NUMBER (mcnt, p + 2);
5876 DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); 5861 DEBUG_PRINT ("EXECUTING succeed_n %d.\n", mcnt);
5877 5862
5878 /* Originally, mcnt is how many times we HAVE to succeed. */ 5863 /* Originally, mcnt is how many times we HAVE to succeed. */
5879 if (mcnt != 0) 5864 if (mcnt != 0)
@@ -5892,7 +5877,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5892 case jump_n: 5877 case jump_n:
5893 /* Signedness doesn't matter since we only compare MCNT to 0. */ 5878 /* Signedness doesn't matter since we only compare MCNT to 0. */
5894 EXTRACT_NUMBER (mcnt, p + 2); 5879 EXTRACT_NUMBER (mcnt, p + 2);
5895 DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); 5880 DEBUG_PRINT ("EXECUTING jump_n %d.\n", mcnt);
5896 5881
5897 /* Originally, this is how many times we CAN jump. */ 5882 /* Originally, this is how many times we CAN jump. */
5898 if (mcnt != 0) 5883 if (mcnt != 0)
@@ -5911,14 +5896,14 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5911 case set_number_at: 5896 case set_number_at:
5912 { 5897 {
5913 unsigned char *p2; /* Location of the counter. */ 5898 unsigned char *p2; /* Location of the counter. */
5914 DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); 5899 DEBUG_PRINT ("EXECUTING set_number_at.\n");
5915 5900
5916 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5901 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5917 /* Here, we discard `const', making re_match non-reentrant. */ 5902 /* Here, we discard `const', making re_match non-reentrant. */
5918 p2 = (unsigned char*) p + mcnt; 5903 p2 = (unsigned char*) p + mcnt;
5919 /* Signedness doesn't matter since we only copy MCNT's bits . */ 5904 /* Signedness doesn't matter since we only copy MCNT's bits . */
5920 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5905 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5921 DEBUG_PRINT3 (" Setting %p to %d.\n", p2, mcnt); 5906 DEBUG_PRINT (" Setting %p to %d.\n", p2, mcnt);
5922 PUSH_NUMBER (p2, mcnt); 5907 PUSH_NUMBER (p2, mcnt);
5923 break; 5908 break;
5924 } 5909 }
@@ -5927,7 +5912,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5927 case notwordbound: 5912 case notwordbound:
5928 { 5913 {
5929 boolean not = (re_opcode_t) *(p - 1) == notwordbound; 5914 boolean not = (re_opcode_t) *(p - 1) == notwordbound;
5930 DEBUG_PRINT2 ("EXECUTING %swordbound.\n", not?"not":""); 5915 DEBUG_PRINT ("EXECUTING %swordbound.\n", not ? "not" : "");
5931 5916
5932 /* We SUCCEED (or FAIL) in one of the following cases: */ 5917 /* We SUCCEED (or FAIL) in one of the following cases: */
5933 5918
@@ -5969,7 +5954,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
5969 } 5954 }
5970 5955
5971 case wordbeg: 5956 case wordbeg:
5972 DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); 5957 DEBUG_PRINT ("EXECUTING wordbeg.\n");
5973 5958
5974 /* We FAIL in one of the following cases: */ 5959 /* We FAIL in one of the following cases: */
5975 5960
@@ -6014,7 +5999,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6014 break; 5999 break;
6015 6000
6016 case wordend: 6001 case wordend:
6017 DEBUG_PRINT1 ("EXECUTING wordend.\n"); 6002 DEBUG_PRINT ("EXECUTING wordend.\n");
6018 6003
6019 /* We FAIL in one of the following cases: */ 6004 /* We FAIL in one of the following cases: */
6020 6005
@@ -6059,7 +6044,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6059 break; 6044 break;
6060 6045
6061 case symbeg: 6046 case symbeg:
6062 DEBUG_PRINT1 ("EXECUTING symbeg.\n"); 6047 DEBUG_PRINT ("EXECUTING symbeg.\n");
6063 6048
6064 /* We FAIL in one of the following cases: */ 6049 /* We FAIL in one of the following cases: */
6065 6050
@@ -6102,7 +6087,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6102 break; 6087 break;
6103 6088
6104 case symend: 6089 case symend:
6105 DEBUG_PRINT1 ("EXECUTING symend.\n"); 6090 DEBUG_PRINT ("EXECUTING symend.\n");
6106 6091
6107 /* We FAIL in one of the following cases: */ 6092 /* We FAIL in one of the following cases: */
6108 6093
@@ -6149,7 +6134,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6149 { 6134 {
6150 boolean not = (re_opcode_t) *(p - 1) == notsyntaxspec; 6135 boolean not = (re_opcode_t) *(p - 1) == notsyntaxspec;
6151 mcnt = *p++; 6136 mcnt = *p++;
6152 DEBUG_PRINT3 ("EXECUTING %ssyntaxspec %d.\n", not?"not":"", mcnt); 6137 DEBUG_PRINT ("EXECUTING %ssyntaxspec %d.\n", not ? "not" : "",
6138 mcnt);
6153 PREFETCH (); 6139 PREFETCH ();
6154#ifdef emacs 6140#ifdef emacs
6155 { 6141 {
@@ -6172,19 +6158,19 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6172 6158
6173#ifdef emacs 6159#ifdef emacs
6174 case before_dot: 6160 case before_dot:
6175 DEBUG_PRINT1 ("EXECUTING before_dot.\n"); 6161 DEBUG_PRINT ("EXECUTING before_dot.\n");
6176 if (PTR_BYTE_POS (d) >= PT_BYTE) 6162 if (PTR_BYTE_POS (d) >= PT_BYTE)
6177 goto fail; 6163 goto fail;
6178 break; 6164 break;
6179 6165
6180 case at_dot: 6166 case at_dot:
6181 DEBUG_PRINT1 ("EXECUTING at_dot.\n"); 6167 DEBUG_PRINT ("EXECUTING at_dot.\n");
6182 if (PTR_BYTE_POS (d) != PT_BYTE) 6168 if (PTR_BYTE_POS (d) != PT_BYTE)
6183 goto fail; 6169 goto fail;
6184 break; 6170 break;
6185 6171
6186 case after_dot: 6172 case after_dot:
6187 DEBUG_PRINT1 ("EXECUTING after_dot.\n"); 6173 DEBUG_PRINT ("EXECUTING after_dot.\n");
6188 if (PTR_BYTE_POS (d) <= PT_BYTE) 6174 if (PTR_BYTE_POS (d) <= PT_BYTE)
6189 goto fail; 6175 goto fail;
6190 break; 6176 break;
@@ -6194,8 +6180,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6194 { 6180 {
6195 boolean not = (re_opcode_t) *(p - 1) == notcategoryspec; 6181 boolean not = (re_opcode_t) *(p - 1) == notcategoryspec;
6196 mcnt = *p++; 6182 mcnt = *p++;
6197 DEBUG_PRINT3 ("EXECUTING %scategoryspec %d.\n", 6183 DEBUG_PRINT ("EXECUTING %scategoryspec %d.\n",
6198 not?"not":"", mcnt); 6184 not ? "not" : "", mcnt);
6199 PREFETCH (); 6185 PREFETCH ();
6200 6186
6201 { 6187 {
@@ -6224,7 +6210,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6224 { 6210 {
6225 re_char *str, *pat; 6211 re_char *str, *pat;
6226 /* A restart point is known. Restore to that state. */ 6212 /* A restart point is known. Restore to that state. */
6227 DEBUG_PRINT1 ("\nFAIL:\n"); 6213 DEBUG_PRINT ("\nFAIL:\n");
6228 POP_FAILURE_POINT (str, pat); 6214 POP_FAILURE_POINT (str, pat);
6229 switch (*pat++) 6215 switch (*pat++)
6230 { 6216 {
@@ -6269,7 +6255,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6269 FREE_VARIABLES (); 6255 FREE_VARIABLES ();
6270 6256
6271 return -1; /* Failure to match. */ 6257 return -1; /* Failure to match. */
6272} /* re_match_2 */ 6258}
6273 6259
6274/* Subroutine definitions for re_match_2. */ 6260/* Subroutine definitions for re_match_2. */
6275 6261
@@ -6402,8 +6388,8 @@ weak_function
6402re_exec (const char *s) 6388re_exec (const char *s)
6403{ 6389{
6404 const size_t len = strlen (s); 6390 const size_t len = strlen (s);
6405 return 6391 return (re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0)
6406 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); 6392 >= 0);
6407} 6393}
6408#endif /* _REGEX_RE_COMP */ 6394#endif /* _REGEX_RE_COMP */
6409 6395
diff --git a/src/regex.h b/src/regex.h
index 36fb4321027..175eed10177 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -530,7 +530,7 @@ extern int re_exec (const char *);
530/* GCC 2.95 and later have "__restrict"; C99 compilers have 530/* GCC 2.95 and later have "__restrict"; C99 compilers have
531 "restrict", and "configure" may have defined "restrict". */ 531 "restrict", and "configure" may have defined "restrict". */
532#ifndef __restrict 532#ifndef __restrict
533# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) 533# if ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
534# if defined restrict || 199901L <= __STDC_VERSION__ 534# if defined restrict || 199901L <= __STDC_VERSION__
535# define __restrict restrict 535# define __restrict restrict
536# else 536# else
diff --git a/src/search.c b/src/search.c
index 4dd3260b735..b4e3cca8269 100644
--- a/src/search.c
+++ b/src/search.c
@@ -326,20 +326,20 @@ looking_at_1 (Lisp_Object string, bool posix)
326 if (i == -2) 326 if (i == -2)
327 matcher_overflow (); 327 matcher_overflow ();
328 328
329 val = (0 <= i ? Qt : Qnil); 329 val = (i >= 0 ? Qt : Qnil);
330 if (NILP (Vinhibit_changing_match_data) && i >= 0) 330 if (NILP (Vinhibit_changing_match_data) && i >= 0)
331 {
331 for (i = 0; i < search_regs.num_regs; i++) 332 for (i = 0; i < search_regs.num_regs; i++)
332 if (search_regs.start[i] >= 0) 333 if (search_regs.start[i] >= 0)
333 { 334 {
334 search_regs.start[i] 335 search_regs.start[i]
335 = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE); 336 = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
336 search_regs.end[i] 337 search_regs.end[i]
337 = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE); 338 = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
338 } 339 }
339 340 /* Set last_thing_searched only when match data is changed. */
340 /* Set last_thing_searched only when match data is changed. */
341 if (NILP (Vinhibit_changing_match_data))
342 XSETBUFFER (last_thing_searched, current_buffer); 341 XSETBUFFER (last_thing_searched, current_buffer);
342 }
343 343
344 return val; 344 return val;
345} 345}
@@ -2450,7 +2450,7 @@ since only regular expressions have distinguished subexpressions. */)
2450 else if (c >= '1' && c <= '9') 2450 else if (c >= '1' && c <= '9')
2451 { 2451 {
2452 if (c - '0' < search_regs.num_regs 2452 if (c - '0' < search_regs.num_regs
2453 && 0 <= search_regs.start[c - '0']) 2453 && search_regs.start[c - '0'] >= 0)
2454 { 2454 {
2455 substart = search_regs.start[c - '0']; 2455 substart = search_regs.start[c - '0'];
2456 subend = search_regs.end[c - '0']; 2456 subend = search_regs.end[c - '0'];
@@ -2533,9 +2533,9 @@ since only regular expressions have distinguished subexpressions. */)
2533 bool str_multibyte = STRING_MULTIBYTE (newtext); 2533 bool str_multibyte = STRING_MULTIBYTE (newtext);
2534 bool really_changed = 0; 2534 bool really_changed = 0;
2535 2535
2536 substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length 2536 substed_alloc_size = (length <= (STRING_BYTES_BOUND - 100) / 2
2537 ? STRING_BYTES_BOUND 2537 ? length * 2 + 100
2538 : length * 2 + 100); 2538 : STRING_BYTES_BOUND);
2539 substed = xmalloc (substed_alloc_size); 2539 substed = xmalloc (substed_alloc_size);
2540 substed_len = 0; 2540 substed_len = 0;
2541 2541
diff --git a/src/sysdep.c b/src/sysdep.c
index bff11fc9f75..1d3e646d359 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -282,7 +282,7 @@ get_child_status (pid_t child, int *status, int options, bool interruptible)
282 reap an unwanted process by mistake. For example, invoking 282 reap an unwanted process by mistake. For example, invoking
283 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses, 283 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
284 so that another thread running glib won't find them. */ 284 so that another thread running glib won't find them. */
285 eassert (0 < child); 285 eassert (child > 0);
286 286
287 while ((pid = waitpid (child, status, options)) < 0) 287 while ((pid = waitpid (child, status, options)) < 0)
288 { 288 {
@@ -2691,7 +2691,7 @@ procfs_ttyname (int rdev)
2691 2691
2692 while (!feof (fdev) && !ferror (fdev)) 2692 while (!feof (fdev) && !ferror (fdev))
2693 { 2693 {
2694 if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) 2694 if (fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor) >= 3
2695 && major == MAJOR (rdev)) 2695 && major == MAJOR (rdev))
2696 { 2696 {
2697 minor_beg = strtoul (minor, &endp, 0); 2697 minor_beg = strtoul (minor, &endp, 0);
@@ -2731,7 +2731,7 @@ procfs_get_total_memory (void)
2731 2731
2732 while (!feof (fmem) && !ferror (fmem)) 2732 while (!feof (fmem) && !ferror (fmem))
2733 { 2733 {
2734 if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) 2734 if (fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value) >= 2
2735 && strcmp (entry_name, "MemTotal:") == 0) 2735 && strcmp (entry_name, "MemTotal:") == 0)
2736 { 2736 {
2737 retval = entry_value; 2737 retval = entry_value;
diff --git a/src/systime.h b/src/systime.h
index fa5e7270cb5..c3bc00c1479 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -121,7 +121,7 @@ EMACS_TIME_SIGN (EMACS_TIME t)
121SYSTIME_INLINE int 121SYSTIME_INLINE int
122EMACS_TIME_VALID_P (EMACS_TIME t) 122EMACS_TIME_VALID_P (EMACS_TIME t)
123{ 123{
124 return 0 <= t.tv_nsec; 124 return t.tv_nsec >= 0;
125} 125}
126 126
127/* Convert the double D to the greatest EMACS_TIME not greater than D. 127/* Convert the double D to the greatest EMACS_TIME not greater than D.
@@ -143,7 +143,7 @@ EMACS_TIME_TO_DOUBLE (EMACS_TIME t)
143 143
144/* defined in sysdep.c */ 144/* defined in sysdep.c */
145extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME); 145extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME);
146extern struct timeval make_timeval (EMACS_TIME); 146extern struct timeval make_timeval (EMACS_TIME) ATTRIBUTE_CONST;
147 147
148/* defined in keyboard.c */ 148/* defined in keyboard.c */
149extern void set_waiting_for_input (EMACS_TIME *); 149extern void set_waiting_for_input (EMACS_TIME *);
diff --git a/src/term.c b/src/term.c
index 38706602a02..28b944c6436 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2909,7 +2909,7 @@ dissociate_if_controlling_tty (int fd)
2909{ 2909{
2910 /* If tcgetpgrp succeeds, fd is the controlling terminal, 2910 /* If tcgetpgrp succeeds, fd is the controlling terminal,
2911 so dissociate it by invoking setsid. */ 2911 so dissociate it by invoking setsid. */
2912 if (0 <= tcgetpgrp (fd) && setsid () < 0) 2912 if (tcgetpgrp (fd) >= 0 && setsid () < 0)
2913 { 2913 {
2914#ifdef TIOCNOTTY 2914#ifdef TIOCNOTTY
2915 /* setsid failed, presumably because Emacs is already a process 2915 /* setsid failed, presumably because Emacs is already a process
diff --git a/src/termhooks.h b/src/termhooks.h
index 252dbabb6f9..4f3fa9cb47f 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -212,7 +212,7 @@ enum event_kind
212 , NS_NONKEY_EVENT 212 , NS_NONKEY_EVENT
213#endif 213#endif
214 214
215#if defined (HAVE_INOTIFY) || defined (HAVE_NTGUI) 215#ifdef USE_FILE_NOTIFY
216 /* File or directory was changed. */ 216 /* File or directory was changed. */
217 , FILE_NOTIFY_EVENT 217 , FILE_NOTIFY_EVENT
218#endif 218#endif
diff --git a/src/textprop.c b/src/textprop.c
index 2b454485370..cc364d5a38c 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -597,8 +597,9 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop,
597 597
598 if (WINDOWP (object)) 598 if (WINDOWP (object))
599 { 599 {
600 CHECK_LIVE_WINDOW (object);
600 w = XWINDOW (object); 601 w = XWINDOW (object);
601 object = w->buffer; 602 object = w->contents;
602 } 603 }
603 if (BUFFERP (object)) 604 if (BUFFERP (object))
604 { 605 {
diff --git a/src/thread.c b/src/thread.c
index 7de260ee3c0..1d282c3557a 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -1,5 +1,5 @@
1/* Threading code. 1/* Threading code.
2 Copyright (C) 2012 Free Software Foundation, Inc. 2 Copyright (C) 2012, 2013 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -507,16 +507,10 @@ thread_select (select_func *func, int max_fds, SELECT_TYPE *rfds,
507static void 507static void
508mark_one_thread (struct thread_state *thread) 508mark_one_thread (struct thread_state *thread)
509{ 509{
510 struct specbinding *bind;
511 struct handler *handler; 510 struct handler *handler;
512 Lisp_Object tem; 511 Lisp_Object tem;
513 512
514 for (bind = thread->m_specpdl; bind != thread->m_specpdl_ptr; bind++) 513 mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr);
515 {
516 mark_object (bind->symbol);
517 mark_object (bind->old_value);
518 mark_object (bind->saved_value);
519 }
520 514
521#if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ 515#if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \
522 || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS) 516 || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS)
@@ -541,8 +535,6 @@ mark_one_thread (struct thread_state *thread)
541 mark_object (handler->handler); 535 mark_object (handler->handler);
542 mark_object (handler->var); 536 mark_object (handler->var);
543 } 537 }
544
545 mark_backtrace (thread->m_backtrace_list);
546#endif 538#endif
547 539
548 if (thread->m_current_buffer) 540 if (thread->m_current_buffer)
diff --git a/src/thread.h b/src/thread.h
index 47fa87c77fa..9f0eead4637 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -72,9 +72,6 @@ struct thread_state
72 /* An address near the top of the stack. */ 72 /* An address near the top of the stack. */
73 char *stack_top; 73 char *stack_top;
74 74
75 struct backtrace *m_backtrace_list;
76#define backtrace_list (current_thread->m_backtrace_list)
77
78 struct catchtag *m_catchlist; 75 struct catchtag *m_catchlist;
79#define catchlist (current_thread->m_catchlist) 76#define catchlist (current_thread->m_catchlist)
80 77
diff --git a/src/undo.c b/src/undo.c
index 63edc8e9b8d..d8711882fbf 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -445,12 +445,6 @@ truncate_undo_list (struct buffer *b)
445 unbind_to (count, Qnil); 445 unbind_to (count, Qnil);
446} 446}
447 447
448static _Noreturn void
449user_error (const char *msg)
450{
451 xsignal1 (Quser_error, build_string (msg));
452}
453
454 448
455void 449void
456syms_of_undo (void) 450syms_of_undo (void)
diff --git a/src/unexcw.c b/src/unexcw.c
index af93e158e14..1290c28d245 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22#include "unexec.h" 22#include "unexec.h"
23#include "w32common.h"
24 23
25#include <lisp.h> 24#include <lisp.h>
26#include <stdio.h> 25#include <stdio.h>
@@ -31,6 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31 30
32#define DOTEXE ".exe" 31#define DOTEXE ".exe"
33 32
33extern void report_sheap_usage (int);
34
34extern int bss_sbrk_did_unexec; 35extern int bss_sbrk_did_unexec;
35 36
36extern int __malloc_initialized; 37extern int __malloc_initialized;
@@ -73,7 +74,11 @@ read_exe_header (int fd, exe_header_t * exe_header_buffer)
73 74
74 assert (exe_header_buffer->file_header.e_magic == 0x5a4d); 75 assert (exe_header_buffer->file_header.e_magic == 0x5a4d);
75 assert (exe_header_buffer->file_header.nt_signature == 0x4550); 76 assert (exe_header_buffer->file_header.nt_signature == 0x4550);
77#ifdef __x86_64__
78 assert (exe_header_buffer->file_header.f_magic == 0x8664);
79#else
76 assert (exe_header_buffer->file_header.f_magic == 0x014c); 80 assert (exe_header_buffer->file_header.f_magic == 0x014c);
81#endif
77 assert (exe_header_buffer->file_header.f_nscns > 0); 82 assert (exe_header_buffer->file_header.f_nscns > 0);
78 assert (exe_header_buffer->file_header.f_nscns <= 83 assert (exe_header_buffer->file_header.f_nscns <=
79 sizeof (exe_header_buffer->section_header) / 84 sizeof (exe_header_buffer->section_header) /
@@ -85,7 +90,11 @@ read_exe_header (int fd, exe_header_t * exe_header_buffer)
85 sizeof (exe_header_buffer->file_optional_header)); 90 sizeof (exe_header_buffer->file_optional_header));
86 assert (ret == sizeof (exe_header_buffer->file_optional_header)); 91 assert (ret == sizeof (exe_header_buffer->file_optional_header));
87 92
93#ifdef __x86_64__
94 assert (exe_header_buffer->file_optional_header.magic == 0x020b);
95#else
88 assert (exe_header_buffer->file_optional_header.magic == 0x010b); 96 assert (exe_header_buffer->file_optional_header.magic == 0x010b);
97#endif
89 98
90 for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i) 99 for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i)
91 { 100 {
@@ -132,7 +141,7 @@ fixup_executable (int fd)
132 exe_header->file_optional_header.ImageBase + 141 exe_header->file_optional_header.ImageBase +
133 exe_header->section_header[i].s_paddr; 142 exe_header->section_header[i].s_paddr;
134 if (debug_unexcw) 143 if (debug_unexcw)
135 printf ("%8s start 0x%08x end 0x%08x\n", 144 printf ("%8s start %#lx end %#lx\n",
136 exe_header->section_header[i].s_name, 145 exe_header->section_header[i].s_name,
137 start_address, end_address); 146 start_address, end_address);
138 if (my_edata >= (char *) start_address 147 if (my_edata >= (char *) start_address
@@ -149,7 +158,7 @@ fixup_executable (int fd)
149 assert (ret == my_edata - (char *) start_address); 158 assert (ret == my_edata - (char *) start_address);
150 ++found_data; 159 ++found_data;
151 if (debug_unexcw) 160 if (debug_unexcw)
152 printf (" .data, mem start 0x%08x mem length %d\n", 161 printf (" .data, mem start %#lx mem length %d\n",
153 start_address, my_edata - (char *) start_address); 162 start_address, my_edata - (char *) start_address);
154 if (debug_unexcw) 163 if (debug_unexcw)
155 printf (" .data, file start %d file length %d\n", 164 printf (" .data, file start %d file length %d\n",
@@ -233,7 +242,7 @@ fixup_executable (int fd)
233 __malloc_initialized = 1; 242 __malloc_initialized = 1;
234 assert (ret == (my_endbss - (char *) start_address)); 243 assert (ret == (my_endbss - (char *) start_address));
235 if (debug_unexcw) 244 if (debug_unexcw)
236 printf (" .bss, mem start 0x%08x mem length %d\n", 245 printf (" .bss, mem start %#lx mem length %d\n",
237 start_address, my_endbss - (char *) start_address); 246 start_address, my_endbss - (char *) start_address);
238 if (debug_unexcw) 247 if (debug_unexcw)
239 printf (" .bss, file start %d file length %d\n", 248 printf (" .bss, file start %d file length %d\n",
diff --git a/src/unexelf.c b/src/unexelf.c
index d3659404f9c..4e50bb86367 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -388,16 +388,19 @@ temacs:
388#include <config.h> 388#include <config.h>
389#include <unexec.h> 389#include <unexec.h>
390 390
391extern void fatal (const char *msgid, ...); 391extern _Noreturn void fatal (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
392 392
393#include <sys/types.h> 393#include <errno.h>
394#include <fcntl.h>
395#include <limits.h>
396#include <memory.h>
397#include <stdbool.h>
394#include <stdint.h> 398#include <stdint.h>
395#include <stdio.h> 399#include <stdio.h>
396#include <sys/stat.h> 400#include <sys/stat.h>
397#include <memory.h> 401#include <sys/types.h>
398#include <errno.h>
399#include <unistd.h> 402#include <unistd.h>
400#include <fcntl.h> 403
401#if !defined (__NetBSD__) && !defined (__OpenBSD__) 404#if !defined (__NetBSD__) && !defined (__OpenBSD__)
402#include <elf.h> 405#include <elf.h>
403#endif /* not __NetBSD__ and not __OpenBSD__ */ 406#endif /* not __NetBSD__ and not __OpenBSD__ */
@@ -519,6 +522,18 @@ typedef struct {
519# define ElfW(type) ElfExpandBitsW (ELFSIZE, type) 522# define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
520#endif 523#endif
521 524
525/* The code often converts ElfW (Half) values like e_shentsize to ptrdiff_t;
526 check that this doesn't lose information. */
527#include <intprops.h>
528#include <verify.h>
529verify ((! TYPE_SIGNED (ElfW (Half))
530 || PTRDIFF_MIN <= TYPE_MINIMUM (ElfW (Half)))
531 && TYPE_MAXIMUM (ElfW (Half)) <= PTRDIFF_MAX);
532
533#ifdef UNEXELF_DEBUG
534# define DEBUG_LOG(expr) fprintf (stderr, #expr " 0x%jx\n", (uintmax_t) (expr))
535#endif
536
522/* Get the address of a particular section or program header entry, 537/* Get the address of a particular section or program header entry,
523 * accounting for the size of the entries. 538 * accounting for the size of the entries.
524 */ 539 */
@@ -546,17 +561,21 @@ typedef struct {
546 Apr 23, 1996 561 Apr 23, 1996
547 */ 562 */
548 563
564static void *
565entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize)
566{
567 char *h = section_h;
568 return h + idx * entsize;
569}
570
549#define OLD_SECTION_H(n) \ 571#define OLD_SECTION_H(n) \
550 (*(ElfW (Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) 572 (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shentsize))
551#define NEW_SECTION_H(n) \ 573#define NEW_SECTION_H(n) \
552 (*(ElfW (Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) 574 (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shentsize))
553#define NEW_PROGRAM_H(n) \ 575#define NEW_PROGRAM_H(n) \
554 (*(ElfW (Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) 576 (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phentsize))
555 577
556#define PATCH_INDEX(n) \ 578#define PATCH_INDEX(n) ((n) += old_bss_index <= (n))
557 do { \
558 if ((int) (n) >= old_bss_index) \
559 (n)++; } while (0)
560typedef unsigned char byte; 579typedef unsigned char byte;
561 580
562/* Round X up to a multiple of Y. */ 581/* Round X up to a multiple of Y. */
@@ -564,7 +583,7 @@ typedef unsigned char byte;
564static ElfW (Addr) 583static ElfW (Addr)
565round_up (ElfW (Addr) x, ElfW (Addr) y) 584round_up (ElfW (Addr) x, ElfW (Addr) y)
566{ 585{
567 int rem = x % y; 586 ElfW (Addr) rem = x % y;
568 if (rem == 0) 587 if (rem == 0)
569 return x; 588 return x;
570 return x - rem + y; 589 return x - rem + y;
@@ -575,33 +594,28 @@ round_up (ElfW (Addr) x, ElfW (Addr) y)
575 about the file we are looking in. 594 about the file we are looking in.
576 595
577 If we don't find the section NAME, that is a fatal error 596 If we don't find the section NAME, that is a fatal error
578 if NOERROR is 0; we return -1 if NOERROR is nonzero. */ 597 if NOERROR is false; return -1 if NOERROR is true. */
579 598
580static int 599static ptrdiff_t
581find_section (const char *name, const char *section_names, const char *file_name, 600find_section (const char *name, const char *section_names, const char *file_name,
582 ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, int noerror) 601 ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h,
602 bool noerror)
583{ 603{
584 int idx; 604 ptrdiff_t idx;
585 605
586 for (idx = 1; idx < old_file_h->e_shnum; idx++) 606 for (idx = 1; idx < old_file_h->e_shnum; idx++)
587 { 607 {
588#ifdef DEBUG 608 char const *found_name = section_names + OLD_SECTION_H (idx).sh_name;
589 fprintf (stderr, "Looking for %s - found %s\n", name, 609#ifdef UNEXELF_DEBUG
590 section_names + OLD_SECTION_H (idx).sh_name); 610 fprintf (stderr, "Looking for %s - found %s\n", name, found_name);
591#endif 611#endif
592 if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name, 612 if (strcmp (name, found_name) == 0)
593 name)) 613 return idx;
594 break;
595 }
596 if (idx == old_file_h->e_shnum)
597 {
598 if (noerror)
599 return -1;
600 else
601 fatal ("Can't find %s in %s.\n", name, file_name);
602 } 614 }
603 615
604 return idx; 616 if (! noerror)
617 fatal ("Can't find %s in %s", name, file_name);
618 return -1;
605} 619}
606 620
607/* **************************************************************** 621/* ****************************************************************
@@ -616,11 +630,9 @@ find_section (const char *name, const char *section_names, const char *file_name
616void 630void
617unexec (const char *new_name, const char *old_name) 631unexec (const char *new_name, const char *old_name)
618{ 632{
619 int new_file, old_file, new_file_size; 633 int new_file, old_file;
620 634 off_t new_file_size;
621#if defined (emacs) || !defined (DEBUG)
622 void *new_break; 635 void *new_break;
623#endif
624 636
625 /* Pointers to the base of the image of the two files. */ 637 /* Pointers to the base of the image of the two files. */
626 caddr_t old_base, new_base; 638 caddr_t old_base, new_base;
@@ -647,14 +659,15 @@ unexec (const char *new_name, const char *old_name)
647 ElfW (Off) old_bss_offset; 659 ElfW (Off) old_bss_offset;
648 ElfW (Word) new_data2_incr; 660 ElfW (Word) new_data2_incr;
649 661
650 int n, nn; 662 ptrdiff_t n, nn;
651 int old_bss_index, old_sbss_index, old_plt_index; 663 ptrdiff_t old_bss_index, old_sbss_index, old_plt_index;
652 int old_data_index, new_data2_index; 664 ptrdiff_t old_data_index, new_data2_index;
653#if defined _SYSTYPE_SYSV || defined __sgi 665#if defined _SYSTYPE_SYSV || defined __sgi
654 int old_mdebug_index; 666 ptrdiff_t old_mdebug_index;
655#endif 667#endif
656 struct stat stat_buf; 668 struct stat stat_buf;
657 int old_file_size; 669 off_t old_file_size;
670 int mask;
658 671
659 /* Open the old file, allocate a buffer of the right size, and read 672 /* Open the old file, allocate a buffer of the right size, and read
660 in the file contents. */ 673 in the file contents. */
@@ -662,15 +675,15 @@ unexec (const char *new_name, const char *old_name)
662 old_file = open (old_name, O_RDONLY); 675 old_file = open (old_name, O_RDONLY);
663 676
664 if (old_file < 0) 677 if (old_file < 0)
665 fatal ("Can't open %s for reading: errno %d\n", old_name, errno); 678 fatal ("Can't open %s for reading: %s", old_name, strerror (errno));
666 679
667 if (fstat (old_file, &stat_buf) == -1) 680 if (fstat (old_file, &stat_buf) != 0)
668 fatal ("Can't fstat (%s): errno %d\n", old_name, errno); 681 fatal ("Can't fstat (%s): %s", old_name, strerror (errno));
669 682
670#if MAP_ANON == 0 683#if MAP_ANON == 0
671 mmap_fd = open ("/dev/zero", O_RDONLY); 684 mmap_fd = open ("/dev/zero", O_RDONLY);
672 if (mmap_fd < 0) 685 if (mmap_fd < 0)
673 fatal ("Can't open /dev/zero for reading: errno %d\n", errno, 0); 686 fatal ("Can't open /dev/zero for reading: %s", strerror (errno));
674#endif 687#endif
675 688
676 /* We cannot use malloc here because that may use sbrk. If it does, 689 /* We cannot use malloc here because that may use sbrk. If it does,
@@ -678,13 +691,15 @@ unexec (const char *new_name, const char *old_name)
678 extra careful to use the correct value of sbrk(0) after 691 extra careful to use the correct value of sbrk(0) after
679 allocating all buffers in the code below, which we aren't. */ 692 allocating all buffers in the code below, which we aren't. */
680 old_file_size = stat_buf.st_size; 693 old_file_size = stat_buf.st_size;
694 if (! (0 <= old_file_size && old_file_size <= SIZE_MAX))
695 fatal ("File size out of range");
681 old_base = mmap (NULL, old_file_size, PROT_READ | PROT_WRITE, 696 old_base = mmap (NULL, old_file_size, PROT_READ | PROT_WRITE,
682 MAP_ANON | MAP_PRIVATE, mmap_fd, 0); 697 MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
683 if (old_base == MAP_FAILED) 698 if (old_base == MAP_FAILED)
684 fatal ("Can't allocate buffer for %s\n", old_name, 0); 699 fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
685 700
686 if (read (old_file, old_base, stat_buf.st_size) != stat_buf.st_size) 701 if (read (old_file, old_base, old_file_size) != old_file_size)
687 fatal ("Didn't read all of %s: errno %d\n", old_name, errno); 702 fatal ("Didn't read all of %s: %s", old_name, strerror (errno));
688 703
689 /* Get pointers to headers & section names */ 704 /* Get pointers to headers & section names */
690 705
@@ -755,12 +770,8 @@ unexec (const char *new_name, const char *old_name)
755 old_data_index = find_section (".data", old_section_names, 770 old_data_index = find_section (".data", old_section_names,
756 old_name, old_file_h, old_section_h, 0); 771 old_name, old_file_h, old_section_h, 0);
757 772
758#if defined (emacs) || !defined (DEBUG)
759 new_break = sbrk (0); 773 new_break = sbrk (0);
760 new_bss_addr = (ElfW (Addr)) new_break; 774 new_bss_addr = (ElfW (Addr)) new_break;
761#else
762 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
763#endif
764 new_data2_addr = old_bss_addr; 775 new_data2_addr = old_bss_addr;
765 new_data2_size = new_bss_addr - old_bss_addr; 776 new_data2_size = new_bss_addr - old_bss_addr;
766 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset 777 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset
@@ -771,38 +782,38 @@ unexec (const char *new_name, const char *old_name)
771 section) was unaligned. */ 782 section) was unaligned. */
772 new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset); 783 new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset);
773 784
774#ifdef DEBUG 785#ifdef UNEXELF_DEBUG
775 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 786 fprintf (stderr, "old_bss_index %td\n", old_bss_index);
776 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 787 DEBUG_LOG (old_bss_addr);
777 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 788 DEBUG_LOG (old_bss_size);
778 fprintf (stderr, "old_bss_offset %x\n", old_bss_offset); 789 DEBUG_LOG (old_bss_offset);
779 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr); 790 DEBUG_LOG (new_bss_addr);
780 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr); 791 DEBUG_LOG (new_data2_addr);
781 fprintf (stderr, "new_data2_size %x\n", new_data2_size); 792 DEBUG_LOG (new_data2_size);
782 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset); 793 DEBUG_LOG (new_data2_offset);
783 fprintf (stderr, "new_data2_incr %x\n", new_data2_incr); 794 DEBUG_LOG (new_data2_incr);
784#endif 795#endif
785 796
786 if ((uintptr_t) new_bss_addr < (uintptr_t) old_bss_addr + old_bss_size) 797 if (new_bss_addr < old_bss_addr + old_bss_size)
787 fatal (".bss shrank when undumping???\n", 0, 0); 798 fatal (".bss shrank when undumping");
788 799
789 /* Set the output file to the right size. Allocate a buffer to hold 800 /* Set the output file to the right size. Allocate a buffer to hold
790 the image of the new file. Set pointers to various interesting 801 the image of the new file. Set pointers to various interesting
791 objects. stat_buf still has old_file data. */ 802 objects. */
792 803
793 new_file = open (new_name, O_RDWR | O_CREAT, 0666); 804 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
794 if (new_file < 0) 805 if (new_file < 0)
795 fatal ("Can't creat (%s): errno %d\n", new_name, errno); 806 fatal ("Can't creat (%s): %s", new_name, strerror (errno));
796 807
797 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_incr; 808 new_file_size = old_file_size + old_file_h->e_shentsize + new_data2_incr;
798 809
799 if (ftruncate (new_file, new_file_size)) 810 if (ftruncate (new_file, new_file_size))
800 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno); 811 fatal ("Can't ftruncate (%s): %s", new_name, strerror (errno));
801 812
802 new_base = mmap (NULL, new_file_size, PROT_READ | PROT_WRITE, 813 new_base = mmap (NULL, new_file_size, PROT_READ | PROT_WRITE,
803 MAP_ANON | MAP_PRIVATE, mmap_fd, 0); 814 MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
804 if (new_base == MAP_FAILED) 815 if (new_base == MAP_FAILED)
805 fatal ("Can't allocate buffer for %s\n", old_name, 0); 816 fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
806 817
807 new_file_h = (ElfW (Ehdr) *) new_base; 818 new_file_h = (ElfW (Ehdr) *) new_base;
808 new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff); 819 new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
@@ -825,11 +836,11 @@ unexec (const char *new_name, const char *old_name)
825 new_file_h->e_shoff += new_data2_incr; 836 new_file_h->e_shoff += new_data2_incr;
826 new_file_h->e_shnum += 1; 837 new_file_h->e_shnum += 1;
827 838
828#ifdef DEBUG 839#ifdef UNEXELF_DEBUG
829 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff); 840 DEBUG_LOG (old_file_h->e_shoff);
830 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum); 841 fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum);
831 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff); 842 DEBUG_LOG (new_file_h->e_shoff);
832 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); 843 fprintf (stderr, "New section count %td\n", (ptrdiff_t) new_file_h->e_shnum);
833#endif 844#endif
834 845
835 /* Fix up a new program header. Extend the writable data segment so 846 /* Fix up a new program header. Extend the writable data segment so
@@ -839,7 +850,7 @@ unexec (const char *new_name, const char *old_name)
839 to adjust the offset and address of any segment that is above 850 to adjust the offset and address of any segment that is above
840 data2, just in case we decide to allow this later. */ 851 data2, just in case we decide to allow this later. */
841 852
842 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 853 for (n = new_file_h->e_phnum; --n >= 0; )
843 { 854 {
844 /* Compute maximum of all requirements for alignment of section. */ 855 /* Compute maximum of all requirements for alignment of section. */
845 ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align; 856 ElfW (Word) alignment = (NEW_PROGRAM_H (n)).p_align;
@@ -857,7 +868,7 @@ unexec (const char *new_name, const char *old_name)
857 > (old_sbss_index == -1 868 > (old_sbss_index == -1
858 ? old_bss_addr 869 ? old_bss_addr
859 : round_up (old_bss_addr, alignment))) 870 : round_up (old_bss_addr, alignment)))
860 fatal ("Program segment above .bss in %s\n", old_name, 0); 871 fatal ("Program segment above .bss in %s", old_name);
861 872
862 if (NEW_PROGRAM_H (n).p_type == PT_LOAD 873 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
863 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr 874 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
@@ -867,7 +878,7 @@ unexec (const char *new_name, const char *old_name)
867 break; 878 break;
868 } 879 }
869 if (n < 0) 880 if (n < 0)
870 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0); 881 fatal ("Couldn't find segment next to .bss in %s", old_name);
871 882
872 /* Make sure that the size includes any padding before the old .bss 883 /* Make sure that the size includes any padding before the old .bss
873 section. */ 884 section. */
@@ -875,7 +886,7 @@ unexec (const char *new_name, const char *old_name)
875 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz; 886 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
876 887
877#if 0 /* Maybe allow section after data2 - does this ever happen? */ 888#if 0 /* Maybe allow section after data2 - does this ever happen? */
878 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 889 for (n = new_file_h->e_phnum; --n >= 0; )
879 { 890 {
880 if (NEW_PROGRAM_H (n).p_vaddr 891 if (NEW_PROGRAM_H (n).p_vaddr
881 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr) 892 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
@@ -894,7 +905,7 @@ unexec (const char *new_name, const char *old_name)
894 905
895 /* Walk through all section headers, insert the new data2 section right 906 /* Walk through all section headers, insert the new data2 section right
896 before the new bss section. */ 907 before the new bss section. */
897 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++) 908 for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++)
898 { 909 {
899 caddr_t src; 910 caddr_t src;
900 /* If it is (s)bss section, insert the new data2 section before it. */ 911 /* If it is (s)bss section, insert the new data2 section before it. */
@@ -1076,8 +1087,9 @@ temacs:
1076 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG 1087 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
1077 && old_mdebug_index != -1) 1088 && old_mdebug_index != -1)
1078 { 1089 {
1079 int diff = NEW_SECTION_H (nn).sh_offset 1090 ptrdiff_t new_offset = NEW_SECTION_H (nn).sh_offset;
1080 - OLD_SECTION_H (old_mdebug_index).sh_offset; 1091 ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset;
1092 ptrdiff_t diff = new_offset - old_offset;
1081 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); 1093 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
1082 1094
1083 if (diff) 1095 if (diff)
@@ -1157,7 +1169,7 @@ temacs:
1157 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 1169 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
1158 { 1170 {
1159 ElfW (Shdr) *spt = &NEW_SECTION_H (nn); 1171 ElfW (Shdr) *spt = &NEW_SECTION_H (nn);
1160 unsigned int num = spt->sh_size / spt->sh_entsize; 1172 ptrdiff_t num = spt->sh_size / spt->sh_entsize;
1161 ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset + 1173 ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset +
1162 new_base); 1174 new_base);
1163 for (; num--; sym++) 1175 for (; num--; sym++)
@@ -1173,7 +1185,7 @@ temacs:
1173 } 1185 }
1174 1186
1175 /* Update the symbol values of _edata and _end. */ 1187 /* Update the symbol values of _edata and _end. */
1176 for (n = new_file_h->e_shnum - 1; n; n--) 1188 for (n = new_file_h->e_shnum; 0 < --n; )
1177 { 1189 {
1178 byte *symnames; 1190 byte *symnames;
1179 ElfW (Sym) *symp, *symendp; 1191 ElfW (Sym) *symp, *symendp;
@@ -1233,7 +1245,7 @@ temacs:
1233 1245
1234 /* This loop seeks out relocation sections for the data section, so 1246 /* This loop seeks out relocation sections for the data section, so
1235 that it can undo relocations performed by the runtime linker. */ 1247 that it can undo relocations performed by the runtime linker. */
1236 for (n = new_file_h->e_shnum - 1; n; n--) 1248 for (n = new_file_h->e_shnum; 0 < --n; )
1237 { 1249 {
1238 ElfW (Shdr) section = NEW_SECTION_H (n); 1250 ElfW (Shdr) section = NEW_SECTION_H (n);
1239 1251
@@ -1293,8 +1305,8 @@ temacs:
1293 /* Write out new_file, and free the buffers. */ 1305 /* Write out new_file, and free the buffers. */
1294 1306
1295 if (write (new_file, new_base, new_file_size) != new_file_size) 1307 if (write (new_file, new_base, new_file_size) != new_file_size)
1296 fatal ("Didn't write %d bytes to %s: errno %d\n", 1308 fatal ("Didn't write %lu bytes to %s: %s",
1297 new_file_size, new_name, errno); 1309 (unsigned long) new_file_size, new_name, strerror (errno));
1298 munmap (old_base, old_file_size); 1310 munmap (old_base, old_file_size);
1299 munmap (new_base, new_file_size); 1311 munmap (new_base, new_file_size);
1300 1312
@@ -1304,18 +1316,18 @@ temacs:
1304 close (mmap_fd); 1316 close (mmap_fd);
1305#endif 1317#endif
1306 1318
1307 if (close (old_file)) 1319 if (close (old_file) != 0)
1308 fatal ("Can't close (%s): errno %d\n", old_name, errno); 1320 fatal ("Can't close (%s): %s", old_name, strerror (errno));
1309 1321
1310 if (close (new_file)) 1322 if (close (new_file) != 0)
1311 fatal ("Can't close (%s): errno %d\n", new_name, errno); 1323 fatal ("Can't close (%s): %s", new_name, strerror (errno));
1312 1324
1313 if (stat (new_name, &stat_buf) == -1) 1325 if (stat (new_name, &stat_buf) != 0)
1314 fatal ("Can't stat (%s): errno %d\n", new_name, errno); 1326 fatal ("Can't stat (%s): %s", new_name, strerror (errno));
1315 1327
1316 n = umask (777); 1328 mask = umask (777);
1317 umask (n); 1329 umask (mask);
1318 stat_buf.st_mode |= 0111 & ~n; 1330 stat_buf.st_mode |= 0111 & ~mask;
1319 if (chmod (new_name, stat_buf.st_mode) == -1) 1331 if (chmod (new_name, stat_buf.st_mode) != 0)
1320 fatal ("Can't chmod (%s): errno %d\n", new_name, errno); 1332 fatal ("Can't chmod (%s): %s", new_name, strerror (errno));
1321} 1333}
diff --git a/src/unexw32.c b/src/unexw32.c
index e8b553a87d3..a01ac799592 100644
--- a/src/unexw32.c
+++ b/src/unexw32.c
@@ -159,6 +159,14 @@ open_output_file (file_data *p_file, char *filename, unsigned long size)
159 HANDLE file_mapping; 159 HANDLE file_mapping;
160 void *file_base; 160 void *file_base;
161 161
162 /* We delete any existing FILENAME because loadup.el will create a
163 hard link to it under the name emacs-XX.YY.ZZ.nn.exe. Evidently,
164 overwriting a file on Unix breaks any hard links to it, but that
165 doesn't happen on Windows. If we don't delete the file before
166 creating it, all the emacs-XX.YY.ZZ.nn.exe end up being hard
167 links to the same file, which defeats the purpose of these hard
168 links: being able to run previous builds. */
169 DeleteFile (filename);
162 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 170 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
163 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 171 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
164 if (file == INVALID_HANDLE_VALUE) 172 if (file == INVALID_HANDLE_VALUE)
diff --git a/src/w32.c b/src/w32.c
index 647faf94ef1..7a39a617ee3 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -29,10 +29,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29#include <ctype.h> 29#include <ctype.h>
30#include <signal.h> 30#include <signal.h>
31#include <sys/file.h> 31#include <sys/file.h>
32#include <time.h> /* must be before nt/inc/sys/time.h, for MinGW64 */
32#include <sys/time.h> 33#include <sys/time.h>
33#include <sys/utime.h> 34#include <sys/utime.h>
34#include <math.h> 35#include <math.h>
35#include <time.h>
36 36
37/* must include CRT headers *before* config.h */ 37/* must include CRT headers *before* config.h */
38 38
@@ -65,11 +65,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
65#undef localtime 65#undef localtime
66 66
67#include "lisp.h" 67#include "lisp.h"
68#include "epaths.h" /* for SHELL */
68 69
69#include <pwd.h> 70#include <pwd.h>
70#include <grp.h> 71#include <grp.h>
71 72
72#ifdef __GNUC__ 73/* MinGW64 (_W64) defines these in its _mingw.h. */
74#if defined(__GNUC__) && !defined(_W64)
73#define _ANONYMOUS_UNION 75#define _ANONYMOUS_UNION
74#define _ANONYMOUS_STRUCT 76#define _ANONYMOUS_STRUCT
75#endif 77#endif
@@ -96,6 +98,7 @@ typedef struct _MEMORY_STATUS_EX {
96#ifndef _MSC_VER 98#ifndef _MSC_VER
97#include <w32api.h> 99#include <w32api.h>
98#endif 100#endif
101#if _WIN32_WINNT < 0x0500
99#if !defined (__MINGW32__) || __W32API_MAJOR_VERSION < 3 || (__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION < 15) 102#if !defined (__MINGW32__) || __W32API_MAJOR_VERSION < 3 || (__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION < 15)
100/* This either is not in psapi.h or guarded by higher value of 103/* This either is not in psapi.h or guarded by higher value of
101 _WIN32_WINNT than what we use. w32api supplied with MinGW 3.15 104 _WIN32_WINNT than what we use. w32api supplied with MinGW 3.15
@@ -114,6 +117,7 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
114 SIZE_T PrivateUsage; 117 SIZE_T PrivateUsage;
115} PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX; 118} PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX;
116#endif 119#endif
120#endif
117 121
118#include <winioctl.h> 122#include <winioctl.h>
119#include <aclapi.h> 123#include <aclapi.h>
@@ -127,11 +131,11 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX {
127#define SDDL_REVISION_1 1 131#define SDDL_REVISION_1 1
128#endif /* SDDL_REVISION_1 */ 132#endif /* SDDL_REVISION_1 */
129 133
130#ifdef _MSC_VER 134#if defined(_MSC_VER) || defined(_W64)
131/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the 135/* MSVC and MinGW64 don't provide the definition of
132 associated macros, except on ntifs.h, which cannot be included 136 REPARSE_DATA_BUFFER and the associated macros, except on ntifs.h,
133 because it triggers conflicts with other Windows API headers. So 137 which cannot be included because it triggers conflicts with other
134 we define it here by hand. */ 138 Windows API headers. So we define it here by hand. */
135 139
136typedef struct _REPARSE_DATA_BUFFER { 140typedef struct _REPARSE_DATA_BUFFER {
137 ULONG ReparseTag; 141 ULONG ReparseTag;
@@ -171,9 +175,12 @@ typedef struct _REPARSE_DATA_BUFFER {
171#ifndef CTL_CODE 175#ifndef CTL_CODE
172#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m)) 176#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m))
173#endif 177#endif
178/* MinGW64 defines FSCTL_GET_REPARSE_POINT on winioctl.h. */
179#ifndef FSCTL_GET_REPARSE_POINT
174#define FSCTL_GET_REPARSE_POINT \ 180#define FSCTL_GET_REPARSE_POINT \
175 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) 181 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
176#endif 182#endif
183#endif
177 184
178/* TCP connection support. */ 185/* TCP connection support. */
179#include <sys/socket.h> 186#include <sys/socket.h>
@@ -2012,7 +2019,7 @@ init_environment (char ** argv)
2012 {"PRELOAD_WINSOCK", NULL}, 2019 {"PRELOAD_WINSOCK", NULL},
2013 {"emacs_dir", "C:/emacs"}, 2020 {"emacs_dir", "C:/emacs"},
2014 {"EMACSLOADPATH", NULL}, 2021 {"EMACSLOADPATH", NULL},
2015 {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"}, 2022 {"SHELL", "cmdproxy.exe"}, /* perhaps it is somewhere on PATH */
2016 {"EMACSDATA", NULL}, 2023 {"EMACSDATA", NULL},
2017 {"EMACSPATH", NULL}, 2024 {"EMACSPATH", NULL},
2018 {"INFOPATH", NULL}, 2025 {"INFOPATH", NULL},
@@ -2088,9 +2095,12 @@ init_environment (char ** argv)
2088 emacs_abort (); 2095 emacs_abort ();
2089 *p = 0; 2096 *p = 0;
2090 2097
2091 if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) 2098 if ((p = _mbsrchr (modname, '\\'))
2099 /* From bin means installed Emacs, from src means uninstalled. */
2100 && (xstrcasecmp (p, "\\bin") == 0 || xstrcasecmp (p, "\\src") == 0))
2092 { 2101 {
2093 char buf[SET_ENV_BUF_SIZE]; 2102 char buf[SET_ENV_BUF_SIZE];
2103 int within_build_tree = xstrcasecmp (p, "\\src") == 0;
2094 2104
2095 *p = 0; 2105 *p = 0;
2096 for (p = modname; *p; p = CharNext (p)) 2106 for (p = modname; *p; p = CharNext (p))
@@ -2098,6 +2108,15 @@ init_environment (char ** argv)
2098 2108
2099 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); 2109 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
2100 _putenv (strdup (buf)); 2110 _putenv (strdup (buf));
2111 /* If we are running from the Posix-like build tree, define
2112 SHELL to point to our own cmdproxy. The loop below will
2113 then disregard PATH_EXEC and the default value. */
2114 if (within_build_tree)
2115 {
2116 _snprintf (buf, sizeof (buf) - 1,
2117 "SHELL=%s/nt/cmdproxy.exe", modname);
2118 _putenv (strdup (buf));
2119 }
2101 } 2120 }
2102 /* Handle running emacs from the build directory: src/oo-spd/i386/ */ 2121 /* Handle running emacs from the build directory: src/oo-spd/i386/ */
2103 2122
@@ -2133,16 +2152,60 @@ init_environment (char ** argv)
2133 if (!getenv (env_vars[i].name)) 2152 if (!getenv (env_vars[i].name))
2134 { 2153 {
2135 int dont_free = 0; 2154 int dont_free = 0;
2155 char bufc[SET_ENV_BUF_SIZE];
2136 2156
2137 if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL 2157 if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL
2138 /* Also ignore empty environment variables. */ 2158 /* Also ignore empty environment variables. */
2139 || *lpval == 0) 2159 || *lpval == 0)
2140 { 2160 {
2141 xfree (lpval); 2161 xfree (lpval);
2142 lpval = env_vars[i].def_value;
2143 dwType = REG_EXPAND_SZ;
2144 dont_free = 1; 2162 dont_free = 1;
2145 if (!strcmp (env_vars[i].name, "HOME") && !appdata) 2163 if (strcmp (env_vars[i].name, "SHELL") == 0)
2164 {
2165 /* Look for cmdproxy.exe in every directory in
2166 PATH_EXEC. FIXME: This does not find cmdproxy
2167 in nt/ when we run uninstalled. */
2168 char fname[MAX_PATH];
2169 const char *pstart = PATH_EXEC, *pend;
2170
2171 do {
2172 pend = _mbschr (pstart, ';');
2173 if (!pend)
2174 pend = pstart + strlen (pstart);
2175 /* Be defensive against series of ;;; characters. */
2176 if (pend > pstart)
2177 {
2178 strncpy (fname, pstart, pend - pstart);
2179 fname[pend - pstart] = '/';
2180 strcpy (&fname[pend - pstart + 1], "cmdproxy.exe");
2181 ExpandEnvironmentStrings ((LPSTR) fname, bufc,
2182 sizeof (bufc));
2183 if (check_existing (bufc))
2184 {
2185 lpval = bufc;
2186 dwType = REG_SZ;
2187 break;
2188 }
2189 }
2190 if (*pend)
2191 pstart = pend + 1;
2192 else
2193 pstart = pend;
2194 if (!*pstart)
2195 {
2196 /* If not found in any directory, use the
2197 default as the last resort. */
2198 lpval = env_vars[i].def_value;
2199 dwType = REG_EXPAND_SZ;
2200 }
2201 } while (*pstart);
2202 }
2203 else
2204 {
2205 lpval = env_vars[i].def_value;
2206 dwType = REG_EXPAND_SZ;
2207 }
2208 if (strcmp (env_vars[i].name, "HOME") == 0 && !appdata)
2146 Vdelayed_warnings_list 2209 Vdelayed_warnings_list
2147 = Fcons (listn (CONSTYPE_HEAP, 2, 2210 = Fcons (listn (CONSTYPE_HEAP, 2,
2148 intern ("initialization"), 2211 intern ("initialization"),
@@ -2388,8 +2451,8 @@ get_emacs_configuration_options (void)
2388#include <sys/timeb.h> 2451#include <sys/timeb.h>
2389 2452
2390/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */ 2453/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
2391void 2454int
2392gettimeofday (struct timeval *tv, struct timezone *tz) 2455gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz)
2393{ 2456{
2394 struct _timeb tb; 2457 struct _timeb tb;
2395 _ftime (&tb); 2458 _ftime (&tb);
@@ -2407,6 +2470,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz)
2407 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */ 2470 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
2408 tz->tz_dsttime = tb.dstflag; /* type of dst correction */ 2471 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
2409 } 2472 }
2473 return 0;
2410} 2474}
2411 2475
2412/* Emulate fdutimens. */ 2476/* Emulate fdutimens. */
diff --git a/src/w32fns.c b/src/w32fns.c
index cef2009d7a1..d7ac0dd1a6c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -95,10 +95,6 @@ static HWND hourglass_hwnd = NULL;
95#define IDC_HAND MAKEINTRESOURCE(32649) 95#define IDC_HAND MAKEINTRESOURCE(32649)
96#endif 96#endif
97 97
98/* Nonzero if using Windows. */
99
100static int w32_in_use;
101
102Lisp_Object Qsuppress_icon; 98Lisp_Object Qsuppress_icon;
103Lisp_Object Qundefined_color; 99Lisp_Object Qundefined_color;
104Lisp_Object Qcancel_timer; 100Lisp_Object Qcancel_timer;
@@ -161,6 +157,8 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
161typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); 157typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
162typedef BOOL (WINAPI * GetMonitorInfo_Proc) 158typedef BOOL (WINAPI * GetMonitorInfo_Proc)
163 (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); 159 (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
160typedef HMONITOR (WINAPI * MonitorFromWindow_Proc)
161 (IN HWND hwnd, IN DWORD dwFlags);
164 162
165TrackMouseEvent_Proc track_mouse_event_fn = NULL; 163TrackMouseEvent_Proc track_mouse_event_fn = NULL;
166ImmGetCompositionString_Proc get_composition_string_fn = NULL; 164ImmGetCompositionString_Proc get_composition_string_fn = NULL;
@@ -169,6 +167,7 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL;
169ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; 167ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
170MonitorFromPoint_Proc monitor_from_point_fn = NULL; 168MonitorFromPoint_Proc monitor_from_point_fn = NULL;
171GetMonitorInfo_Proc get_monitor_info_fn = NULL; 169GetMonitorInfo_Proc get_monitor_info_fn = NULL;
170MonitorFromWindow_Proc monitor_from_window_fn = NULL;
172 171
173#ifdef NTGUI_UNICODE 172#ifdef NTGUI_UNICODE
174#define unicode_append_menu AppendMenuW 173#define unicode_append_menu AppendMenuW
@@ -239,37 +238,6 @@ HINSTANCE hinst = NULL;
239static unsigned int sound_type = 0xFFFFFFFF; 238static unsigned int sound_type = 0xFFFFFFFF;
240#define MB_EMACS_SILENT (0xFFFFFFFF - 1) 239#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
241 240
242
243/* Error if we are not connected to MS-Windows. */
244void
245check_w32 (void)
246{
247 if (! w32_in_use)
248 error ("MS-Windows not in use or not initialized");
249}
250
251/* Nonzero if we can use mouse menus.
252 You should not call this unless HAVE_MENUS is defined. */
253
254int
255have_menus_p (void)
256{
257 return w32_in_use;
258}
259
260/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
261 and checking validity for W32. */
262
263FRAME_PTR
264check_x_frame (Lisp_Object frame)
265{
266 struct frame *f = decode_live_frame (frame);
267
268 if (! FRAME_W32_P (f))
269 error ("Non-W32 frame used");
270 return f;
271}
272
273/* Let the user specify a display with a frame. 241/* Let the user specify a display with a frame.
274 nil stands for the selected frame--or, if that is not a w32 frame, 242 nil stands for the selected frame--or, if that is not a w32 frame,
275 the first display on the list. */ 243 the first display on the list. */
@@ -371,6 +339,66 @@ x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
371 *yptr = rect.top; 339 *yptr = rect.top;
372} 340}
373 341
342/* Returns the window rectangle appropriate for the given fullscreen mode.
343 The normal rect parameter was the window's rectangle prior to entering
344 fullscreen mode. If multiple monitor support is available, the nearest
345 monitor to the window is chosen. */
346
347void
348w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect)
349{
350 struct MONITOR_INFO mi = { sizeof(mi) };
351 if (monitor_from_window_fn && get_monitor_info_fn)
352 {
353 HMONITOR monitor =
354 monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
355 get_monitor_info_fn (monitor, &mi);
356 }
357 else
358 {
359 mi.rcMonitor.left = 0;
360 mi.rcMonitor.top = 0;
361 mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN);
362 mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN);
363 mi.rcWork.left = 0;
364 mi.rcWork.top = 0;
365 mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED);
366 mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED);
367 }
368
369 switch (fsmode)
370 {
371 case FULLSCREEN_BOTH:
372 rect->left = mi.rcMonitor.left;
373 rect->top = mi.rcMonitor.top;
374 rect->right = mi.rcMonitor.right;
375 rect->bottom = mi.rcMonitor.bottom;
376 break;
377 case FULLSCREEN_MAXIMIZED:
378 rect->left = mi.rcWork.left;
379 rect->top = mi.rcWork.top;
380 rect->right = mi.rcWork.right;
381 rect->bottom = mi.rcWork.bottom;
382 break;
383 case FULLSCREEN_WIDTH:
384 rect->left = mi.rcWork.left;
385 rect->top = normal.top;
386 rect->right = mi.rcWork.right;
387 rect->bottom = normal.bottom;
388 break;
389 case FULLSCREEN_HEIGHT:
390 rect->left = normal.left;
391 rect->top = mi.rcWork.top;
392 rect->right = normal.right;
393 rect->bottom = mi.rcWork.bottom;
394 break;
395 case FULLSCREEN_NONE:
396 default:
397 *rect = normal;
398 break;
399 }
400}
401
374 402
375 403
376DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, 404DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
@@ -3155,8 +3183,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3155 form.ptCurrentPos.y = w32_system_caret_y; 3183 form.ptCurrentPos.y = w32_system_caret_y;
3156 3184
3157 form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0); 3185 form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
3158 form.rcArea.top = (WINDOW_TOP_EDGE_Y (w) 3186 form.rcArea.top = WINDOW_TOP_EDGE_Y (w);
3159 + WINDOW_HEADER_LINE_HEIGHT (w)); 3187 if (BUFFERP (w->contents))
3188 form.rcArea.top += WINDOW_HEADER_LINE_HEIGHT (w);
3160 form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w) 3189 form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
3161 - WINDOW_RIGHT_MARGIN_WIDTH (w) 3190 - WINDOW_RIGHT_MARGIN_WIDTH (w)
3162 - WINDOW_RIGHT_FRINGE_WIDTH (w)); 3191 - WINDOW_RIGHT_FRINGE_WIDTH (w));
@@ -3708,6 +3737,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3708 /* Don't restrict the sizing of tip frames. */ 3737 /* Don't restrict the sizing of tip frames. */
3709 if (hwnd == tip_window) 3738 if (hwnd == tip_window)
3710 return 0; 3739 return 0;
3740
3741 /* Don't restrict the sizing of fullscreened frames, allowing them to be
3742 flush with the sides of the screen. */
3743 f = x_window_to_frame (dpyinfo, hwnd);
3744 if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
3745 return 0;
3746
3711 { 3747 {
3712 WINDOWPLACEMENT wp; 3748 WINDOWPLACEMENT wp;
3713 LPWINDOWPOS lppos = (WINDOWPOS *) lParam; 3749 LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
@@ -4353,9 +4389,6 @@ This function is an internal primitive--use `make-frame' instead. */)
4353 specbind (Qx_resource_name, name); 4389 specbind (Qx_resource_name, name);
4354 } 4390 }
4355 4391
4356 f->resx = dpyinfo->resx;
4357 f->resy = dpyinfo->resy;
4358
4359 if (uniscribe_available) 4392 if (uniscribe_available)
4360 register_font_driver (&uniscribe_font_driver, f); 4393 register_font_driver (&uniscribe_font_driver, f);
4361 register_font_driver (&w32font_driver, f); 4394 register_font_driver (&w32font_driver, f);
@@ -4552,7 +4585,7 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
4552 doc: /* Give FRAME input focus, raising to foreground if necessary. */) 4585 doc: /* Give FRAME input focus, raising to foreground if necessary. */)
4553 (Lisp_Object frame) 4586 (Lisp_Object frame)
4554{ 4587{
4555 x_focus_on_frame (check_x_frame (frame)); 4588 x_focus_on_frame (decode_window_system_frame (frame));
4556 return Qnil; 4589 return Qnil;
4557} 4590}
4558 4591
@@ -4563,7 +4596,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
4563 (Lisp_Object color, Lisp_Object frame) 4596 (Lisp_Object color, Lisp_Object frame)
4564{ 4597{
4565 XColor foo; 4598 XColor foo;
4566 FRAME_PTR f = check_x_frame (frame); 4599 FRAME_PTR f = decode_window_system_frame (frame);
4567 4600
4568 CHECK_STRING (color); 4601 CHECK_STRING (color);
4569 4602
@@ -4578,7 +4611,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
4578 (Lisp_Object color, Lisp_Object frame) 4611 (Lisp_Object color, Lisp_Object frame)
4579{ 4612{
4580 XColor foo; 4613 XColor foo;
4581 FRAME_PTR f = check_x_frame (frame); 4614 FRAME_PTR f = decode_window_system_frame (frame);
4582 4615
4583 CHECK_STRING (color); 4616 CHECK_STRING (color);
4584 4617
@@ -4896,7 +4929,6 @@ x_display_info_for_name (Lisp_Object name)
4896 if (dpyinfo == 0) 4929 if (dpyinfo == 0)
4897 error ("Cannot connect to server %s", SDATA (name)); 4930 error ("Cannot connect to server %s", SDATA (name));
4898 4931
4899 w32_in_use = 1;
4900 XSETFASTINT (Vwindow_system_version, w32_major_version); 4932 XSETFASTINT (Vwindow_system_version, w32_major_version);
4901 4933
4902 return dpyinfo; 4934 return dpyinfo;
@@ -4926,7 +4958,7 @@ terminate Emacs if we can't open the connection.
4926 4958
4927 /* If initialization has already been done, return now to avoid 4959 /* If initialization has already been done, return now to avoid
4928 overwriting critical parts of one_w32_display_info. */ 4960 overwriting critical parts of one_w32_display_info. */
4929 if (w32_in_use) 4961 if (window_system_available (NULL))
4930 return Qnil; 4962 return Qnil;
4931 4963
4932 if (! NILP (xrm_string)) 4964 if (! NILP (xrm_string))
@@ -4995,8 +5027,6 @@ terminate Emacs if we can't open the connection.
4995 error ("Cannot connect to server %s", SDATA (display)); 5027 error ("Cannot connect to server %s", SDATA (display));
4996 } 5028 }
4997 5029
4998 w32_in_use = 1;
4999
5000 XSETFASTINT (Vwindow_system_version, w32_major_version); 5030 XSETFASTINT (Vwindow_system_version, w32_major_version);
5001 return Qnil; 5031 return Qnil;
5002} 5032}
@@ -5080,7 +5110,7 @@ FRAME. Default is to change on the edit X window. */)
5080 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame, 5110 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
5081 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p) 5111 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
5082{ 5112{
5083 struct frame *f = check_x_frame (frame); 5113 struct frame *f = decode_window_system_frame (frame);
5084 Atom prop_atom; 5114 Atom prop_atom;
5085 5115
5086 CHECK_STRING (prop); 5116 CHECK_STRING (prop);
@@ -5106,7 +5136,7 @@ DEFUN ("x-delete-window-property", Fx_delete_window_property,
5106FRAME nil or omitted means use the selected frame. Value is PROP. */) 5136FRAME nil or omitted means use the selected frame. Value is PROP. */)
5107 (Lisp_Object prop, Lisp_Object frame) 5137 (Lisp_Object prop, Lisp_Object frame)
5108{ 5138{
5109 struct frame *f = check_x_frame (frame); 5139 struct frame *f = decode_window_system_frame (frame);
5110 Atom prop_atom; 5140 Atom prop_atom;
5111 5141
5112 CHECK_STRING (prop); 5142 CHECK_STRING (prop);
@@ -5142,7 +5172,7 @@ no value of TYPE (always string in the MS Windows case). */)
5142 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type, 5172 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
5143 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p) 5173 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
5144{ 5174{
5145 struct frame *f = check_x_frame (frame); 5175 struct frame *f = decode_window_system_frame (frame);
5146 Atom prop_atom; 5176 Atom prop_atom;
5147 int rc; 5177 int rc;
5148 Lisp_Object prop_value = Qnil; 5178 Lisp_Object prop_value = Qnil;
@@ -5343,8 +5373,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5343 Lisp_Object buffer; 5373 Lisp_Object buffer;
5344 struct buffer *old_buffer; 5374 struct buffer *old_buffer;
5345 5375
5346 check_w32 ();
5347
5348 /* Use this general default value to start with until we know if 5376 /* Use this general default value to start with until we know if
5349 this frame has a specified name. */ 5377 this frame has a specified name. */
5350 Vx_resource_name = Vinvocation_name; 5378 Vx_resource_name = Vinvocation_name;
@@ -5420,9 +5448,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5420 specbind (Qx_resource_name, name); 5448 specbind (Qx_resource_name, name);
5421 } 5449 }
5422 5450
5423 f->resx = dpyinfo->resx;
5424 f->resy = dpyinfo->resy;
5425
5426 if (uniscribe_available) 5451 if (uniscribe_available)
5427 register_font_driver (&uniscribe_font_driver, f); 5452 register_font_driver (&uniscribe_font_driver, f);
5428 register_font_driver (&w32font_driver, f); 5453 register_font_driver (&w32font_driver, f);
@@ -5691,7 +5716,7 @@ Text larger than the specified size is clipped. */)
5691 GCPRO4 (string, parms, frame, timeout); 5716 GCPRO4 (string, parms, frame, timeout);
5692 5717
5693 CHECK_STRING (string); 5718 CHECK_STRING (string);
5694 f = check_x_frame (frame); 5719 f = decode_window_system_frame (frame);
5695 if (NILP (timeout)) 5720 if (NILP (timeout))
5696 timeout = make_number (5); 5721 timeout = make_number (5);
5697 else 5722 else
@@ -5780,8 +5805,8 @@ Text larger than the specified size is clipped. */)
5780 5805
5781 /* Set up the frame's root window. */ 5806 /* Set up the frame's root window. */
5782 w = XWINDOW (FRAME_ROOT_WINDOW (f)); 5807 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5783 wset_left_col (w, make_number (0)); 5808 w->left_col = 0;
5784 wset_top_line (w, make_number (0)); 5809 w->top_line = 0;
5785 5810
5786 if (CONSP (Vx_max_tooltip_size) 5811 if (CONSP (Vx_max_tooltip_size)
5787 && INTEGERP (XCAR (Vx_max_tooltip_size)) 5812 && INTEGERP (XCAR (Vx_max_tooltip_size))
@@ -5789,22 +5814,22 @@ Text larger than the specified size is clipped. */)
5789 && INTEGERP (XCDR (Vx_max_tooltip_size)) 5814 && INTEGERP (XCDR (Vx_max_tooltip_size))
5790 && XINT (XCDR (Vx_max_tooltip_size)) > 0) 5815 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5791 { 5816 {
5792 wset_total_cols (w, XCAR (Vx_max_tooltip_size)); 5817 w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
5793 wset_total_lines (w, XCDR (Vx_max_tooltip_size)); 5818 w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
5794 } 5819 }
5795 else 5820 else
5796 { 5821 {
5797 wset_total_cols (w, make_number (80)); 5822 w->total_cols = 80;
5798 wset_total_lines (w, make_number (40)); 5823 w->total_lines = 40;
5799 } 5824 }
5800 5825
5801 FRAME_TOTAL_COLS (f) = XINT (w->total_cols); 5826 FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w);
5802 adjust_glyphs (f); 5827 adjust_glyphs (f);
5803 w->pseudo_window_p = 1; 5828 w->pseudo_window_p = 1;
5804 5829
5805 /* Display the tooltip text in a temporary buffer. */ 5830 /* Display the tooltip text in a temporary buffer. */
5806 old_buffer = current_buffer; 5831 old_buffer = current_buffer;
5807 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer)); 5832 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
5808 bset_truncate_lines (current_buffer, Qnil); 5833 bset_truncate_lines (current_buffer, Qnil);
5809 clear_glyph_matrix (w->desired_matrix); 5834 clear_glyph_matrix (w->desired_matrix);
5810 clear_glyph_matrix (w->current_matrix); 5835 clear_glyph_matrix (w->current_matrix);
@@ -5866,7 +5891,7 @@ Text larger than the specified size is clipped. */)
5866 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, 5891 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5867 not in pixels. */ 5892 not in pixels. */
5868 width /= WINDOW_FRAME_COLUMN_WIDTH (w); 5893 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5869 wset_total_cols (w, make_number (width)); 5894 w->total_cols = width;
5870 FRAME_TOTAL_COLS (f) = width; 5895 FRAME_TOTAL_COLS (f) = width;
5871 adjust_glyphs (f); 5896 adjust_glyphs (f);
5872 w->pseudo_window_p = 1; 5897 w->pseudo_window_p = 1;
@@ -6342,7 +6367,7 @@ screen saver if defined.
6342If optional parameter FRAME is not specified, use selected frame. */) 6367If optional parameter FRAME is not specified, use selected frame. */)
6343 (Lisp_Object command, Lisp_Object frame) 6368 (Lisp_Object command, Lisp_Object frame)
6344{ 6369{
6345 FRAME_PTR f = check_x_frame (frame); 6370 FRAME_PTR f = decode_window_system_frame (frame);
6346 6371
6347 CHECK_NUMBER (command); 6372 CHECK_NUMBER (command);
6348 6373
@@ -7300,8 +7325,6 @@ void
7300syms_of_w32fns (void) 7325syms_of_w32fns (void)
7301{ 7326{
7302 globals_of_w32fns (); 7327 globals_of_w32fns ();
7303 /* This is zero if not using MS-Windows. */
7304 w32_in_use = 0;
7305 track_mouse_window = NULL; 7328 track_mouse_window = NULL;
7306 7329
7307 w32_visible_system_caret_hwnd = NULL; 7330 w32_visible_system_caret_hwnd = NULL;
@@ -7623,8 +7646,6 @@ only be necessary if the default setting causes problems. */);
7623 defsubr (&Sdefault_printer_name); 7646 defsubr (&Sdefault_printer_name);
7624 defsubr (&Sset_message_beep); 7647 defsubr (&Sset_message_beep);
7625 7648
7626 check_window_system_func = check_w32;
7627
7628 hourglass_hwnd = NULL; 7649 hourglass_hwnd = NULL;
7629 7650
7630 defsubr (&Sx_show_tip); 7651 defsubr (&Sx_show_tip);
@@ -7667,6 +7688,8 @@ globals_of_w32fns (void)
7667 GetProcAddress (user32_lib, "MonitorFromPoint"); 7688 GetProcAddress (user32_lib, "MonitorFromPoint");
7668 get_monitor_info_fn = (GetMonitorInfo_Proc) 7689 get_monitor_info_fn = (GetMonitorInfo_Proc)
7669 GetProcAddress (user32_lib, "GetMonitorInfoA"); 7690 GetProcAddress (user32_lib, "GetMonitorInfoA");
7691 monitor_from_window_fn = (MonitorFromWindow_Proc)
7692 GetProcAddress (user32_lib, "MonitorFromWindow");
7670 7693
7671 { 7694 {
7672 HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); 7695 HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
@@ -7765,6 +7788,9 @@ emacs_abort (void)
7765#endif 7788#endif
7766 if (stderr_fd >= 0) 7789 if (stderr_fd >= 0)
7767 write (stderr_fd, "\r\nBacktrace:\r\n", 14); 7790 write (stderr_fd, "\r\nBacktrace:\r\n", 14);
7791#ifdef CYGWIN
7792#define _open open
7793#endif
7768 errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE); 7794 errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
7769 if (errfile_fd >= 0) 7795 if (errfile_fd >= 0)
7770 { 7796 {
diff --git a/src/w32font.c b/src/w32font.c
index 5c5a15cc340..105daa06365 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -1967,7 +1967,7 @@ static void
1967fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec) 1967fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec)
1968{ 1968{
1969 Lisp_Object tmp, extra; 1969 Lisp_Object tmp, extra;
1970 int dpi = FRAME_W32_DISPLAY_INFO (f)->resy; 1970 int dpi = FRAME_RES_Y (f);
1971 1971
1972 tmp = AREF (font_spec, FONT_DPI_INDEX); 1972 tmp = AREF (font_spec, FONT_DPI_INDEX);
1973 if (INTEGERP (tmp)) 1973 if (INTEGERP (tmp))
@@ -2467,7 +2467,7 @@ If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts
2467in the font selection dialog. */) 2467in the font selection dialog. */)
2468 (Lisp_Object frame, Lisp_Object exclude_proportional) 2468 (Lisp_Object frame, Lisp_Object exclude_proportional)
2469{ 2469{
2470 FRAME_PTR f = check_x_frame (frame); 2470 FRAME_PTR f = decode_window_system_frame (frame);
2471 CHOOSEFONT cf; 2471 CHOOSEFONT cf;
2472 LOGFONT lf; 2472 LOGFONT lf;
2473 TEXTMETRIC tm; 2473 TEXTMETRIC tm;
diff --git a/src/w32menu.c b/src/w32menu.c
index 03904cf20b8..346402b7c6b 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -140,8 +140,6 @@ otherwise it is "Question". */)
140 FRAME_PTR f = NULL; 140 FRAME_PTR f = NULL;
141 Lisp_Object window; 141 Lisp_Object window;
142 142
143 check_w32 ();
144
145 /* Decode the first argument: find the window or frame to use. */ 143 /* Decode the first argument: find the window or frame to use. */
146 if (EQ (position, Qt) 144 if (EQ (position, Qt)
147 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 145 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
@@ -194,6 +192,8 @@ otherwise it is "Question". */)
194 but I don't want to make one now. */ 192 but I don't want to make one now. */
195 CHECK_WINDOW (window); 193 CHECK_WINDOW (window);
196 194
195 check_window_system (f);
196
197#ifndef HAVE_DIALOGS 197#ifndef HAVE_DIALOGS
198 198
199 { 199 {
@@ -396,7 +396,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
396 if (! menubar_widget) 396 if (! menubar_widget)
397 previous_menu_items_used = 0; 397 previous_menu_items_used = 0;
398 398
399 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer; 399 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
400 specbind (Qinhibit_quit, Qt); 400 specbind (Qinhibit_quit, Qt);
401 /* Don't let the debugger step into this code 401 /* Don't let the debugger step into this code
402 because it is not reentrant. */ 402 because it is not reentrant. */
diff --git a/src/w32term.c b/src/w32term.c
index 989ceb0f847..58b1d3ca308 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -109,9 +109,10 @@ struct w32_display_info *x_display_list;
109Lisp_Object w32_display_name_list; 109Lisp_Object w32_display_name_list;
110 110
111 111
112#if _WIN32_WINNT < 0x0500 112#if _WIN32_WINNT < 0x0500 && !defined(_W64)
113/* Pre Windows 2000, this was not available, but define it here so 113/* Pre Windows 2000, this was not available, but define it here so
114 that Emacs compiled on such a platform will run on newer versions. */ 114 that Emacs compiled on such a platform will run on newer versions.
115 MinGW64 (_W64) defines these unconditionally, so avoid redefining. */
115 116
116typedef struct tagWCRANGE 117typedef struct tagWCRANGE
117{ 118{
@@ -5660,79 +5661,42 @@ x_check_fullscreen (struct frame *f)
5660static void 5661static void
5661w32fullscreen_hook (FRAME_PTR f) 5662w32fullscreen_hook (FRAME_PTR f)
5662{ 5663{
5663 static int normal_width, normal_height;
5664
5665 if (FRAME_VISIBLE_P (f)) 5664 if (FRAME_VISIBLE_P (f))
5666 { 5665 {
5667 int width, height, top_pos, left_pos, pixel_height, pixel_width; 5666 HWND hwnd = FRAME_W32_WINDOW(f);
5668 int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f); 5667 DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
5669 RECT workarea_rect; 5668 RECT rect;
5670 5669
5671 block_input (); 5670 block_input();
5672 if (normal_height <= 0) 5671 f->want_fullscreen &= ~FULLSCREEN_WAIT;
5673 normal_height = cur_h;
5674 if (normal_width <= 0)
5675 normal_width = cur_w;
5676 x_real_positions (f, &f->left_pos, &f->top_pos);
5677 x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos);
5678 5672
5679 SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); 5673 if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE)
5680 pixel_height = workarea_rect.bottom - workarea_rect.top; 5674 GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
5681 pixel_width = workarea_rect.right - workarea_rect.left;
5682 5675
5683 switch (f->want_fullscreen) 5676 if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH)
5684 { 5677 {
5685 case FULLSCREEN_BOTH: 5678 SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW);
5686 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0); 5679 SetWindowPos (hwnd, NULL, 0, 0, 0, 0,
5687 break; 5680 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
5688 case FULLSCREEN_MAXIMIZED: 5681 SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
5689 height = 5682 }
5690 FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) 5683
5691 - XINT (Ftool_bar_lines_needed (selected_frame)) 5684 w32_fullscreen_rect (hwnd, f->want_fullscreen,
5692 + (NILP (Vmenu_bar_mode) ? 1 : 0); 5685 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
5693 width = 5686 FRAME_PREV_FSMODE (f) = f->want_fullscreen;
5694 FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) 5687 if (f->want_fullscreen == FULLSCREEN_BOTH)
5695 - FRAME_SCROLL_BAR_COLS (f); 5688 {
5696 left_pos = workarea_rect.left; 5689 SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
5697 top_pos = workarea_rect.top; 5690 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
5698 break; 5691 rect.right - rect.left, rect.bottom - rect.top,
5699 case FULLSCREEN_WIDTH: 5692 SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
5700 width = 5693 }
5701 FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) 5694 else
5702 - FRAME_SCROLL_BAR_COLS (f); 5695 {
5703 if (normal_height > 0) 5696 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
5704 height = normal_height; 5697 rect.right - rect.left, rect.bottom - rect.top, 0);
5705 left_pos = workarea_rect.left; 5698 }
5706 break;
5707 case FULLSCREEN_HEIGHT:
5708 height =
5709 FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
5710 - XINT (Ftool_bar_lines_needed (selected_frame))
5711 + (NILP (Vmenu_bar_mode) ? 1 : 0);
5712 if (normal_width > 0)
5713 width = normal_width;
5714 top_pos = workarea_rect.top;
5715 break;
5716 case FULLSCREEN_NONE:
5717 if (normal_height > 0)
5718 height = normal_height;
5719 else
5720 normal_height = height;
5721 if (normal_width > 0)
5722 width = normal_width;
5723 else
5724 normal_width = width;
5725 /* FIXME: Should restore the original position of the frame. */
5726 top_pos = left_pos = 0;
5727 break;
5728 }
5729 5699
5730 if (cur_w != width || cur_h != height)
5731 {
5732 x_set_offset (f, left_pos, top_pos, 1);
5733 x_set_window_size (f, 1, width, height);
5734 do_pending_window_change (0);
5735 }
5736 f->want_fullscreen = FULLSCREEN_NONE; 5700 f->want_fullscreen = FULLSCREEN_NONE;
5737 unblock_input (); 5701 unblock_input ();
5738 } 5702 }
@@ -6651,7 +6615,7 @@ w32_initialize (void)
6651 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil); 6615 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
6652 6616
6653 { 6617 {
6654 DWORD input_locale_id = (DWORD) GetKeyboardLayout (0); 6618 DWORD input_locale_id = ((DWORD_PTR) GetKeyboardLayout (0) & 0xffffffff);
6655 w32_keyboard_codepage = 6619 w32_keyboard_codepage =
6656 codepage_for_locale ((LCID) (input_locale_id & 0xffff)); 6620 codepage_for_locale ((LCID) (input_locale_id & 0xffff));
6657 } 6621 }
diff --git a/src/w32term.h b/src/w32term.h
index a31c5de193d..9c27c09d03d 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -71,6 +71,8 @@ struct w32_palette_entry {
71}; 71};
72 72
73extern void w32_regenerate_palette (struct frame *f); 73extern void w32_regenerate_palette (struct frame *f);
74extern void w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal,
75 RECT *rect);
74 76
75 77
76/* For each display (currently only one on w32), we have a structure that 78/* For each display (currently only one on w32), we have a structure that
@@ -203,7 +205,6 @@ extern void x_focus_on_frame (struct frame *f);
203 205
204extern struct w32_display_info *w32_term_init (Lisp_Object, 206extern struct w32_display_info *w32_term_init (Lisp_Object,
205 char *, char *); 207 char *, char *);
206extern void check_w32 (void);
207extern int w32_defined_color (FRAME_PTR f, const char *color, 208extern int w32_defined_color (FRAME_PTR f, const char *color,
208 XColor *color_def, int alloc); 209 XColor *color_def, int alloc);
209extern void x_set_window_size (struct frame *f, int change_grav, 210extern void x_set_window_size (struct frame *f, int change_grav,
@@ -359,6 +360,12 @@ struct w32_output
359 /* The background for which the above relief GCs were set up. 360 /* The background for which the above relief GCs were set up.
360 They are changed only when a different background is involved. */ 361 They are changed only when a different background is involved. */
361 unsigned long relief_background; 362 unsigned long relief_background;
363
364 /* Frame geometry and full-screen mode before it was resized by
365 specifying the 'fullscreen' frame parameter. Used to restore the
366 geometry when 'fullscreen' is reset to nil. */
367 WINDOWPLACEMENT normal_placement;
368 int prev_fsmode;
362}; 369};
363 370
364extern struct w32_output w32term_display; 371extern struct w32_output w32term_display;
@@ -390,6 +397,10 @@ extern struct w32_output w32term_display;
390 397
391#define FRAME_SMALLEST_FONT_HEIGHT(F) \ 398#define FRAME_SMALLEST_FONT_HEIGHT(F) \
392 FRAME_W32_DISPLAY_INFO(F)->smallest_font_height 399 FRAME_W32_DISPLAY_INFO(F)->smallest_font_height
400
401#define FRAME_NORMAL_PLACEMENT(F) ((F)->output_data.w32->normal_placement)
402#define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode)
403
393 404
394/* W32-specific scroll bar stuff. */ 405/* W32-specific scroll bar stuff. */
395 406
@@ -727,7 +738,6 @@ struct image;
727struct face; 738struct face;
728 739
729XGCValues *XCreateGC (void *, Window, unsigned long, XGCValues *); 740XGCValues *XCreateGC (void *, Window, unsigned long, XGCValues *);
730struct frame * check_x_frame (Lisp_Object);
731 741
732typedef DWORD (WINAPI * ClipboardSequence_Proc) (void); 742typedef DWORD (WINAPI * ClipboardSequence_Proc) (void);
733typedef BOOL (WINAPI * AppendMenuW_Proc) ( 743typedef BOOL (WINAPI * AppendMenuW_Proc) (
diff --git a/src/window.c b/src/window.c
index 4109b752d8e..33bf70b75c8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -84,8 +84,8 @@ static int foreach_window_1 (struct window *,
84 int (* fn) (struct window *, void *), 84 int (* fn) (struct window *, void *),
85 void *); 85 void *);
86static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 86static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
87static int window_resize_check (struct window *, int); 87static int window_resize_check (struct window *, bool);
88static void window_resize_apply (struct window *, int); 88static void window_resize_apply (struct window *, bool);
89static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 89static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
90static void select_window_1 (Lisp_Object, bool); 90static void select_window_1 (Lisp_Object, bool);
91 91
@@ -147,11 +147,6 @@ wset_display_table (struct window *w, Lisp_Object val)
147 w->display_table = val; 147 w->display_table = val;
148} 148}
149static void 149static void
150wset_hchild (struct window *w, Lisp_Object val)
151{
152 w->hchild = val;
153}
154static void
155wset_left_fringe_width (struct window *w, Lisp_Object val) 150wset_left_fringe_width (struct window *w, Lisp_Object val)
156{ 151{
157 w->left_fringe_width = val; 152 w->left_fringe_width = val;
@@ -217,11 +212,6 @@ wset_temslot (struct window *w, Lisp_Object val)
217 w->temslot = val; 212 w->temslot = val;
218} 213}
219static void 214static void
220wset_vchild (struct window *w, Lisp_Object val)
221{
222 w->vchild = val;
223}
224static void
225wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val) 215wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
226{ 216{
227 w->vertical_scroll_bar_type = val; 217 w->vertical_scroll_bar_type = val;
@@ -231,6 +221,18 @@ wset_window_parameters (struct window *w, Lisp_Object val)
231{ 221{
232 w->window_parameters = val; 222 w->window_parameters = val;
233} 223}
224static void
225wset_combination (struct window *w, bool horflag, Lisp_Object val)
226{
227 /* Since leaf windows never becomes non-leaf, there should
228 be no buffer and markers in start and pointm fields of W. */
229 eassert (!BUFFERP (w->contents) && NILP (w->start) && NILP (w->pointm));
230 w->contents = val;
231 /* When an internal window is deleted and VAL is nil, HORFLAG
232 is meaningless. */
233 if (!NILP (val))
234 w->horizontal = horflag;
235}
234 236
235struct window * 237struct window *
236decode_live_window (register Lisp_Object window) 238decode_live_window (register Lisp_Object window)
@@ -275,9 +277,9 @@ static void
275adjust_window_count (struct window *w, int arg) 277adjust_window_count (struct window *w, int arg)
276{ 278{
277 eassert (eabs (arg) == 1); 279 eassert (eabs (arg) == 1);
278 if (BUFFERP (w->buffer)) 280 if (BUFFERP (w->contents))
279 { 281 {
280 struct buffer *b = XBUFFER (w->buffer); 282 struct buffer *b = XBUFFER (w->contents);
281 283
282 if (b->base_buffer) 284 if (b->base_buffer)
283 b = b->base_buffer; 285 b = b->base_buffer;
@@ -296,7 +298,11 @@ void
296wset_buffer (struct window *w, Lisp_Object val) 298wset_buffer (struct window *w, Lisp_Object val)
297{ 299{
298 adjust_window_count (w, -1); 300 adjust_window_count (w, -1);
299 w->buffer = val; 301 if (BUFFERP (val))
302 /* Make sure that we do not assign the buffer
303 to an internal window. */
304 eassert (MARKERP (w->start) && MARKERP (w->pointm));
305 w->contents = val;
300 adjust_window_count (w, 1); 306 adjust_window_count (w, 1);
301} 307}
302 308
@@ -394,15 +400,8 @@ the first window of that frame. */)
394 window = XFRAME (frame_or_window)->root_window; 400 window = XFRAME (frame_or_window)->root_window;
395 } 401 }
396 402
397 while (NILP (XWINDOW (window)->buffer)) 403 while (WINDOWP (XWINDOW (window)->contents))
398 { 404 window = XWINDOW (window)->contents;
399 if (! NILP (XWINDOW (window)->hchild))
400 window = XWINDOW (window)->hchild;
401 else if (! NILP (XWINDOW (window)->vchild))
402 window = XWINDOW (window)->vchild;
403 else
404 emacs_abort ();
405 }
406 405
407 return window; 406 return window;
408} 407}
@@ -486,17 +485,14 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
486 w = XWINDOW (window); 485 w = XWINDOW (window);
487 w->frozen_window_start_p = 0; 486 w->frozen_window_start_p = 0;
488 487
489 if (NILP (norecord))
490 {
491 w->use_time = ++window_select_count;
492 record_buffer (w->buffer);
493 }
494
495 /* Make the selected window's buffer current. */ 488 /* Make the selected window's buffer current. */
496 Fset_buffer (w->buffer); 489 Fset_buffer (w->contents);
497 490
498 if (EQ (window, selected_window) && !inhibit_point_swap) 491 if (EQ (window, selected_window) && !inhibit_point_swap)
499 return window; 492 /* `switch-to-buffer' uses (select-window (selected-window)) as a "clever"
493 way to call record_buffer from Elisp, so it's important that we call
494 record_buffer before returning here. */
495 goto record_and_return;
500 496
501 sf = SELECTED_FRAME (); 497 sf = SELECTED_FRAME ();
502 if (XFRAME (WINDOW_FRAME (w)) != sf) 498 if (XFRAME (WINDOW_FRAME (w)) != sf)
@@ -515,9 +511,19 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
515 fset_selected_window (sf, window); 511 fset_selected_window (sf, window);
516 512
517 select_window_1 (window, inhibit_point_swap); 513 select_window_1 (window, inhibit_point_swap);
518 514 bset_last_selected_window (XBUFFER (w->contents), window);
519 bset_last_selected_window (XBUFFER (w->buffer), window);
520 windows_or_buffers_changed++; 515 windows_or_buffers_changed++;
516
517 record_and_return:
518 /* record_buffer can run QUIT, so make sure it is run only after we have
519 re-established the invariant between selected_window and selected_frame,
520 otherwise the temporary broken invariant might "escape" (bug#14161). */
521 if (NILP (norecord))
522 {
523 w->use_time = ++window_select_count;
524 record_buffer (w->contents);
525 }
526
521 return window; 527 return window;
522} 528}
523 529
@@ -533,10 +539,10 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
533 if (!inhibit_point_swap) 539 if (!inhibit_point_swap)
534 { 540 {
535 struct window *ow = XWINDOW (selected_window); 541 struct window *ow = XWINDOW (selected_window);
536 if (! NILP (ow->buffer)) 542 if (BUFFERP (ow->contents))
537 set_marker_both (ow->pointm, ow->buffer, 543 set_marker_both (ow->pointm, ow->contents,
538 BUF_PT (XBUFFER (ow->buffer)), 544 BUF_PT (XBUFFER (ow->contents)),
539 BUF_PT_BYTE (XBUFFER (ow->buffer))); 545 BUF_PT_BYTE (XBUFFER (ow->contents)));
540 } 546 }
541 547
542 selected_window = window; 548 selected_window = window;
@@ -581,7 +587,8 @@ If WINDOW is omitted or nil, it defaults to the selected window.
581Return nil for an internal window or a deleted window. */) 587Return nil for an internal window or a deleted window. */)
582 (Lisp_Object window) 588 (Lisp_Object window)
583{ 589{
584 return decode_any_window (window)->buffer; 590 struct window *w = decode_any_window (window);
591 return WINDOW_LEAF_P (w) ? w->contents : Qnil;
585} 592}
586 593
587DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0, 594DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
@@ -601,7 +608,8 @@ Return nil if WINDOW is an internal window whose children form a
601horizontal combination. */) 608horizontal combination. */)
602 (Lisp_Object window) 609 (Lisp_Object window)
603{ 610{
604 return decode_valid_window (window)->vchild; 611 struct window *w = decode_valid_window (window);
612 return WINDOW_VERTICAL_COMBINATION_P (w) ? w->contents : Qnil;
605} 613}
606 614
607DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0, 615DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
@@ -612,7 +620,8 @@ Return nil if WINDOW is an internal window whose children form a
612vertical combination. */) 620vertical combination. */)
613 (Lisp_Object window) 621 (Lisp_Object window)
614{ 622{
615 return decode_valid_window (window)->hchild; 623 struct window *w = decode_valid_window (window);
624 return WINDOW_HORIZONTAL_COMBINATION_P (w) ? w->contents : Qnil;
616} 625}
617 626
618DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0, 627DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0,
@@ -635,30 +644,37 @@ Return nil if WINDOW has no previous sibling. */)
635 644
636DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0, 645DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
637 doc: /* Return combination limit of window WINDOW. 646 doc: /* Return combination limit of window WINDOW.
647WINDOW must be a valid window used in horizontal or vertical combination.
638If the return value is nil, child windows of WINDOW can be recombined with 648If the return value is nil, child windows of WINDOW can be recombined with
639WINDOW's siblings. A return value of t means that child windows of 649WINDOW's siblings. A return value of t means that child windows of
640WINDOW are never \(re-)combined with WINDOW's siblings. 650WINDOW are never \(re-)combined with WINDOW's siblings. */)
641
642WINDOW must be a valid window. The return value is meaningful for
643internal windows only. */)
644 (Lisp_Object window) 651 (Lisp_Object window)
645{ 652{
653 struct window *w;
654
646 CHECK_VALID_WINDOW (window); 655 CHECK_VALID_WINDOW (window);
647 return XWINDOW (window)->combination_limit; 656 w = XWINDOW (window);
657 if (WINDOW_LEAF_P (w))
658 error ("Combination limit is meaningful for internal windows only");
659 return w->combination_limit;
648} 660}
649 661
650DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0, 662DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
651 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT. 663 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
664WINDOW must be a valid window used in horizontal or vertical combination.
652If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's 665If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
653siblings. LIMIT t means that child windows of WINDOW are never 666siblings. LIMIT t means that child windows of WINDOW are never
654\(re-)combined with WINDOW's siblings. Other values are reserved for 667\(re-)combined with WINDOW's siblings. Other values are reserved for
655future use. 668future use. */)
656
657WINDOW must be a valid window. Setting the combination limit is
658meaningful for internal windows only. */)
659 (Lisp_Object window, Lisp_Object limit) 669 (Lisp_Object window, Lisp_Object limit)
660{ 670{
661 wset_combination_limit (decode_valid_window (window), limit); 671 struct window *w;
672
673 CHECK_VALID_WINDOW (window);
674 w = XWINDOW (window);
675 if (WINDOW_LEAF_P (w))
676 error ("Combination limit is meaningful for internal windows only");
677 wset_combination_limit (w, limit);
662 return limit; 678 return limit;
663} 679}
664 680
@@ -685,7 +701,7 @@ On a graphical display, this total height is reported as an
685integer multiple of the default character height. */) 701integer multiple of the default character height. */)
686 (Lisp_Object window) 702 (Lisp_Object window)
687{ 703{
688 return decode_valid_window (window)->total_lines; 704 return make_number (decode_valid_window (window)->total_lines);
689} 705}
690 706
691DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0, 707DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0,
@@ -700,7 +716,7 @@ On a graphical display, this total width is reported as an
700integer multiple of the default character width. */) 716integer multiple of the default character width. */)
701 (Lisp_Object window) 717 (Lisp_Object window)
702{ 718{
703 return decode_valid_window (window)->total_cols; 719 return make_number (decode_valid_window (window)->total_cols);
704} 720}
705 721
706DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0, 722DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
@@ -739,7 +755,7 @@ value is 0 if there is no window to the left of WINDOW.
739WINDOW must be a valid window and defaults to the selected one. */) 755WINDOW must be a valid window and defaults to the selected one. */)
740 (Lisp_Object window) 756 (Lisp_Object window)
741{ 757{
742 return decode_valid_window (window)->left_col; 758 return make_number (decode_valid_window (window)->left_col);
743} 759}
744 760
745DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0, 761DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
@@ -751,7 +767,7 @@ there is no window above WINDOW.
751WINDOW must be a valid window and defaults to the selected one. */) 767WINDOW must be a valid window and defaults to the selected one. */)
752 (Lisp_Object window) 768 (Lisp_Object window)
753{ 769{
754 return decode_valid_window (window)->top_line; 770 return make_number (decode_valid_window (window)->top_line);
755} 771}
756 772
757/* Return the number of lines of W's body. Don't count any mode or 773/* Return the number of lines of W's body. Don't count any mode or
@@ -760,7 +776,7 @@ WINDOW must be a valid window and defaults to the selected one. */)
760static int 776static int
761window_body_lines (struct window *w) 777window_body_lines (struct window *w)
762{ 778{
763 int height = XFASTINT (w->total_lines); 779 int height = w->total_lines;
764 780
765 if (!MINI_WINDOW_P (w)) 781 if (!MINI_WINDOW_P (w))
766 { 782 {
@@ -782,7 +798,7 @@ int
782window_body_cols (struct window *w) 798window_body_cols (struct window *w)
783{ 799{
784 struct frame *f = XFRAME (WINDOW_FRAME (w)); 800 struct frame *f = XFRAME (WINDOW_FRAME (w));
785 int width = XINT (w->total_cols); 801 int width = w->total_cols;
786 802
787 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) 803 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
788 /* Scroll bars occupy a few columns. */ 804 /* Scroll bars occupy a few columns. */
@@ -853,7 +869,7 @@ set_window_hscroll (struct window *w, EMACS_INT hscroll)
853 869
854 /* Prevent redisplay shortcuts when changing the hscroll. */ 870 /* Prevent redisplay shortcuts when changing the hscroll. */
855 if (w->hscroll != new_hscroll) 871 if (w->hscroll != new_hscroll)
856 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 872 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
857 873
858 w->hscroll = new_hscroll; 874 w->hscroll = new_hscroll;
859 return make_number (new_hscroll); 875 return make_number (new_hscroll);
@@ -1368,7 +1384,7 @@ check_window_containing (struct window *w, void *user_data)
1368 1384
1369Lisp_Object 1385Lisp_Object
1370window_from_coordinates (struct frame *f, int x, int y, 1386window_from_coordinates (struct frame *f, int x, int y,
1371 enum window_part *part, int tool_bar_p) 1387 enum window_part *part, bool tool_bar_p)
1372{ 1388{
1373 Lisp_Object window; 1389 Lisp_Object window;
1374 struct check_window_data cw; 1390 struct check_window_data cw;
@@ -1434,7 +1450,7 @@ correct to return the top-level value of `point', outside of any
1434 register struct window *w = decode_live_window (window); 1450 register struct window *w = decode_live_window (window);
1435 1451
1436 if (w == XWINDOW (selected_window)) 1452 if (w == XWINDOW (selected_window))
1437 return make_number (BUF_PT (XBUFFER (w->buffer))); 1453 return make_number (BUF_PT (XBUFFER (w->contents)));
1438 else 1454 else
1439 return Fmarker_position (w->pointm); 1455 return Fmarker_position (w->pointm);
1440} 1456}
@@ -1476,12 +1492,17 @@ if it isn't already recorded. */)
1476 Lisp_Object buf; 1492 Lisp_Object buf;
1477 struct buffer *b; 1493 struct buffer *b;
1478 1494
1479 buf = w->buffer; 1495 buf = w->contents;
1480 CHECK_BUFFER (buf); 1496 CHECK_BUFFER (buf);
1481 b = XBUFFER (buf); 1497 b = XBUFFER (buf);
1482 1498
1483 if (! NILP (update) 1499 if (! NILP (update)
1484 && (windows_or_buffers_changed || !w->window_end_valid) 1500 && (windows_or_buffers_changed
1501 || !w->window_end_valid
1502 || b->clip_changed
1503 || b->prevent_redisplay_optimizations_p
1504 || w->last_modified < BUF_MODIFF (b)
1505 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
1485 && !noninteractive) 1506 && !noninteractive)
1486 { 1507 {
1487 struct text_pos startp; 1508 struct text_pos startp;
@@ -1539,7 +1560,7 @@ Return POS. */)
1539 1560
1540 if (w == XWINDOW (selected_window)) 1561 if (w == XWINDOW (selected_window))
1541 { 1562 {
1542 if (XBUFFER (w->buffer) == current_buffer) 1563 if (XBUFFER (w->contents) == current_buffer)
1543 Fgoto_char (pos); 1564 Fgoto_char (pos);
1544 else 1565 else
1545 { 1566 {
@@ -1547,14 +1568,14 @@ Return POS. */)
1547 1568
1548 /* ... but here we want to catch type error before buffer change. */ 1569 /* ... but here we want to catch type error before buffer change. */
1549 CHECK_NUMBER_COERCE_MARKER (pos); 1570 CHECK_NUMBER_COERCE_MARKER (pos);
1550 set_buffer_internal (XBUFFER (w->buffer)); 1571 set_buffer_internal (XBUFFER (w->contents));
1551 Fgoto_char (pos); 1572 Fgoto_char (pos);
1552 set_buffer_internal (old_buffer); 1573 set_buffer_internal (old_buffer);
1553 } 1574 }
1554 } 1575 }
1555 else 1576 else
1556 { 1577 {
1557 set_marker_restricted (w->pointm, pos, w->buffer); 1578 set_marker_restricted (w->pointm, pos, w->contents);
1558 /* We have to make sure that redisplay updates the window to show 1579 /* We have to make sure that redisplay updates the window to show
1559 the new value of point. */ 1580 the new value of point. */
1560 ++windows_or_buffers_changed; 1581 ++windows_or_buffers_changed;
@@ -1572,7 +1593,7 @@ overriding motion of point in order to display at this exact start. */)
1572{ 1593{
1573 register struct window *w = decode_live_window (window); 1594 register struct window *w = decode_live_window (window);
1574 1595
1575 set_marker_restricted (w->start, pos, w->buffer); 1596 set_marker_restricted (w->start, pos, w->contents);
1576 /* This is not right, but much easier than doing what is right. */ 1597 /* This is not right, but much easier than doing what is right. */
1577 w->start_at_line_beg = 0; 1598 w->start_at_line_beg = 0;
1578 if (NILP (noforce)) 1599 if (NILP (noforce))
@@ -1616,7 +1637,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
1616 int x, y; 1637 int x, y;
1617 1638
1618 w = decode_live_window (window); 1639 w = decode_live_window (window);
1619 buf = XBUFFER (w->buffer); 1640 buf = XBUFFER (w->contents);
1620 SET_TEXT_POS_FROM_MARKER (top, w->start); 1641 SET_TEXT_POS_FROM_MARKER (top, w->start);
1621 1642
1622 if (EQ (pos, Qt)) 1643 if (EQ (pos, Qt))
@@ -1685,13 +1706,14 @@ Return nil if window display is not up-to-date. In that case, use
1685 if (noninteractive || w->pseudo_window_p) 1706 if (noninteractive || w->pseudo_window_p)
1686 return Qnil; 1707 return Qnil;
1687 1708
1688 CHECK_BUFFER (w->buffer); 1709 CHECK_BUFFER (w->contents);
1689 b = XBUFFER (w->buffer); 1710 b = XBUFFER (w->contents);
1690 1711
1691 /* Fail if current matrix is not up-to-date. */ 1712 /* Fail if current matrix is not up-to-date. */
1692 if (!w->window_end_valid 1713 if (!w->window_end_valid
1693 || current_buffer->clip_changed 1714 || windows_or_buffers_changed
1694 || current_buffer->prevent_redisplay_optimizations_p 1715 || b->clip_changed
1716 || b->prevent_redisplay_optimizations_p
1695 || w->last_modified < BUF_MODIFF (b) 1717 || w->last_modified < BUF_MODIFF (b)
1696 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) 1718 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
1697 return Qnil; 1719 return Qnil;
@@ -1912,9 +1934,9 @@ window_display_table (struct window *w)
1912 1934
1913 if (DISP_TABLE_P (w->display_table)) 1935 if (DISP_TABLE_P (w->display_table))
1914 dp = XCHAR_TABLE (w->display_table); 1936 dp = XCHAR_TABLE (w->display_table);
1915 else if (BUFFERP (w->buffer)) 1937 else if (BUFFERP (w->contents))
1916 { 1938 {
1917 struct buffer *b = XBUFFER (w->buffer); 1939 struct buffer *b = XBUFFER (w->contents);
1918 1940
1919 if (DISP_TABLE_P (BVAR (b, display_table))) 1941 if (DISP_TABLE_P (BVAR (b, display_table)))
1920 dp = XCHAR_TABLE (BVAR (b, display_table)); 1942 dp = XCHAR_TABLE (BVAR (b, display_table));
@@ -1939,17 +1961,14 @@ WINDOW must be a live window and defaults to the selected one. */)
1939static void 1961static void
1940unshow_buffer (register struct window *w) 1962unshow_buffer (register struct window *w)
1941{ 1963{
1942 Lisp_Object buf; 1964 Lisp_Object buf = w->contents;
1943 struct buffer *b; 1965 struct buffer *b = XBUFFER (buf);
1944 1966
1945 buf = w->buffer; 1967 eassert (b == XMARKER (w->pointm)->buffer);
1946 b = XBUFFER (buf);
1947 if (b != XMARKER (w->pointm)->buffer)
1948 emacs_abort ();
1949 1968
1950#if 0 1969#if 0
1951 if (w == XWINDOW (selected_window) 1970 if (w == XWINDOW (selected_window)
1952 || ! EQ (buf, XWINDOW (selected_window)->buffer)) 1971 || ! EQ (buf, XWINDOW (selected_window)->contents))
1953 /* Do this except when the selected window's buffer 1972 /* Do this except when the selected window's buffer
1954 is being removed from some other window. */ 1973 is being removed from some other window. */
1955#endif 1974#endif
@@ -1965,14 +1984,14 @@ unshow_buffer (register struct window *w)
1965 /* Point in the selected window's buffer 1984 /* Point in the selected window's buffer
1966 is actually stored in that buffer, and the window's pointm isn't used. 1985 is actually stored in that buffer, and the window's pointm isn't used.
1967 So don't clobber point in that buffer. */ 1986 So don't clobber point in that buffer. */
1968 if (! EQ (buf, XWINDOW (selected_window)->buffer) 1987 if (! EQ (buf, XWINDOW (selected_window)->contents)
1969 /* Don't clobber point in current buffer either (this could be 1988 /* Don't clobber point in current buffer either (this could be
1970 useful in connection with bug#12208). 1989 useful in connection with bug#12208).
1971 && XBUFFER (buf) != current_buffer */ 1990 && XBUFFER (buf) != current_buffer */
1972 /* This line helps to fix Horsley's testbug.el bug. */ 1991 /* This line helps to fix Horsley's testbug.el bug. */
1973 && !(WINDOWP (BVAR (b, last_selected_window)) 1992 && !(WINDOWP (BVAR (b, last_selected_window))
1974 && w != XWINDOW (BVAR (b, last_selected_window)) 1993 && w != XWINDOW (BVAR (b, last_selected_window))
1975 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer))) 1994 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->contents)))
1976 temp_set_point_both (b, 1995 temp_set_point_both (b,
1977 clip_to_bounds (BUF_BEGV (b), 1996 clip_to_bounds (BUF_BEGV (b),
1978 marker_position (w->pointm), 1997 marker_position (w->pointm),
@@ -2000,12 +2019,12 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
2000 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) 2019 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
2001 fset_root_window (XFRAME (o->frame), new); 2020 fset_root_window (XFRAME (o->frame), new);
2002 2021
2003 if (setflag) 2022 if (setflag)
2004 { 2023 {
2005 wset_left_col (n, o->left_col); 2024 n->left_col = o->left_col;
2006 wset_top_line (n, o->top_line); 2025 n->top_line = o->top_line;
2007 wset_total_cols (n, o->total_cols); 2026 n->total_cols = o->total_cols;
2008 wset_total_lines (n, o->total_lines); 2027 n->total_lines = o->total_lines;
2009 wset_normal_cols (n, o->normal_cols); 2028 wset_normal_cols (n, o->normal_cols);
2010 wset_normal_cols (o, make_float (1.0)); 2029 wset_normal_cols (o, make_float (1.0));
2011 wset_normal_lines (n, o->normal_lines); 2030 wset_normal_lines (n, o->normal_lines);
@@ -2037,13 +2056,8 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
2037 2056
2038 tem = o->parent; 2057 tem = o->parent;
2039 wset_parent (n, tem); 2058 wset_parent (n, tem);
2040 if (!NILP (tem)) 2059 if (!NILP (tem) && EQ (XWINDOW (tem)->contents, old))
2041 { 2060 wset_combination (XWINDOW (tem), XWINDOW (tem)->horizontal, new);
2042 if (EQ (XWINDOW (tem)->vchild, old))
2043 wset_vchild (XWINDOW (tem), new);
2044 if (EQ (XWINDOW (tem)->hchild, old))
2045 wset_hchild (XWINDOW (tem), new);
2046 }
2047} 2061}
2048 2062
2049/* If window WINDOW and its parent window are iso-combined, merge 2063/* If window WINDOW and its parent window are iso-combined, merge
@@ -2055,29 +2069,26 @@ recombine_windows (Lisp_Object window)
2055{ 2069{
2056 struct window *w, *p, *c; 2070 struct window *w, *p, *c;
2057 Lisp_Object parent, child; 2071 Lisp_Object parent, child;
2058 int horflag; 2072 bool horflag;
2059 2073
2060 w = XWINDOW (window); 2074 w = XWINDOW (window);
2061 parent = w->parent; 2075 parent = w->parent;
2062 if (!NILP (parent) && NILP (w->combination_limit)) 2076 if (!NILP (parent) && NILP (w->combination_limit))
2063 { 2077 {
2064 p = XWINDOW (parent); 2078 p = XWINDOW (parent);
2065 if (((!NILP (p->vchild) && !NILP (w->vchild)) 2079 if (WINDOWP (p->contents) && WINDOWP (w->contents)
2066 || (!NILP (p->hchild) && !NILP (w->hchild)))) 2080 && p->horizontal == w->horizontal)
2067 /* WINDOW and PARENT are both either a vertical or a horizontal 2081 /* WINDOW and PARENT are both either a vertical or a horizontal
2068 combination. */ 2082 combination. */
2069 { 2083 {
2070 horflag = NILP (w->vchild); 2084 horflag = WINDOW_HORIZONTAL_COMBINATION_P (w);
2071 child = horflag ? w->hchild : w->vchild; 2085 child = w->contents;
2072 c = XWINDOW (child); 2086 c = XWINDOW (child);
2073 2087
2074 /* Splice WINDOW's children into its parent's children and 2088 /* Splice WINDOW's children into its parent's children and
2075 assign new normal sizes. */ 2089 assign new normal sizes. */
2076 if (NILP (w->prev)) 2090 if (NILP (w->prev))
2077 if (horflag) 2091 wset_combination (p, horflag, child);
2078 wset_hchild (p, child);
2079 else
2080 wset_vchild (p, child);
2081 else 2092 else
2082 { 2093 {
2083 wset_prev (c, w->prev); 2094 wset_prev (c, w->prev);
@@ -2090,12 +2101,12 @@ recombine_windows (Lisp_Object window)
2090 2101
2091 if (horflag) 2102 if (horflag)
2092 wset_normal_cols (c, 2103 wset_normal_cols (c,
2093 make_float (XFLOATINT (c->total_cols) 2104 make_float ((double) c->total_cols
2094 / XFLOATINT (p->total_cols))); 2105 / (double) p->total_cols));
2095 else 2106 else
2096 wset_normal_lines (c, 2107 wset_normal_lines (c,
2097 make_float (XFLOATINT (c->total_lines) 2108 make_float ((double) c->total_lines
2098 / XFLOATINT (p->total_lines))); 2109 / (double) p->total_lines));
2099 2110
2100 if (NILP (c->next)) 2111 if (NILP (c->next))
2101 { 2112 {
@@ -2115,8 +2126,7 @@ recombine_windows (Lisp_Object window)
2115 } 2126 }
2116 2127
2117 /* WINDOW can be deleted now. */ 2128 /* WINDOW can be deleted now. */
2118 wset_vchild (w, Qnil); 2129 wset_combination (w, 0, Qnil);
2119 wset_hchild (w, Qnil);
2120 } 2130 }
2121 } 2131 }
2122} 2132}
@@ -2202,7 +2212,7 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
2202 struct frame *f = XFRAME (w->frame); 2212 struct frame *f = XFRAME (w->frame);
2203 int candidate_p = 1; 2213 int candidate_p = 1;
2204 2214
2205 if (!BUFFERP (w->buffer)) 2215 if (!BUFFERP (w->contents))
2206 candidate_p = 0; 2216 candidate_p = 0;
2207 else if (MINI_WINDOW_P (w) 2217 else if (MINI_WINDOW_P (w)
2208 && (EQ (minibuf, Qlambda) 2218 && (EQ (minibuf, Qlambda)
@@ -2542,7 +2552,7 @@ enum window_loop
2542 GET_BUFFER_WINDOW, /* Arg is buffer */ 2552 GET_BUFFER_WINDOW, /* Arg is buffer */
2543 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */ 2553 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
2544 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */ 2554 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
2545 CHECK_ALL_WINDOWS 2555 CHECK_ALL_WINDOWS /* Arg is ignored */
2546}; 2556};
2547 2557
2548static Lisp_Object 2558static Lisp_Object
@@ -2606,7 +2616,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2606 switch (type) 2616 switch (type)
2607 { 2617 {
2608 case GET_BUFFER_WINDOW: 2618 case GET_BUFFER_WINDOW:
2609 if (EQ (w->buffer, obj) 2619 if (EQ (w->contents, obj)
2610 /* Don't find any minibuffer window except the one that 2620 /* Don't find any minibuffer window except the one that
2611 is currently in use. */ 2621 is currently in use. */
2612 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1)) 2622 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
@@ -2630,25 +2640,25 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2630 case REPLACE_BUFFER_IN_WINDOWS_SAFELY: 2640 case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
2631 /* We could simply check whether the buffer shown by window 2641 /* We could simply check whether the buffer shown by window
2632 is live, and show another buffer in case it isn't. */ 2642 is live, and show another buffer in case it isn't. */
2633 if (EQ (w->buffer, obj)) 2643 if (EQ (w->contents, obj))
2634 { 2644 {
2635 /* Undedicate WINDOW. */ 2645 /* Undedicate WINDOW. */
2636 wset_dedicated (w, Qnil); 2646 wset_dedicated (w, Qnil);
2637 /* Make WINDOW show the buffer returned by 2647 /* Make WINDOW show the buffer returned by
2638 other_buffer_safely, don't run any hooks. */ 2648 other_buffer_safely, don't run any hooks. */
2639 set_window_buffer 2649 set_window_buffer
2640 (window, other_buffer_safely (w->buffer), 0, 0); 2650 (window, other_buffer_safely (w->contents), 0, 0);
2641 /* If WINDOW is the selected window, make its buffer 2651 /* If WINDOW is the selected window, make its buffer
2642 current. But do so only if the window shows the 2652 current. But do so only if the window shows the
2643 current buffer (Bug#6454). */ 2653 current buffer (Bug#6454). */
2644 if (EQ (window, selected_window) 2654 if (EQ (window, selected_window)
2645 && XBUFFER (w->buffer) == current_buffer) 2655 && XBUFFER (w->contents) == current_buffer)
2646 Fset_buffer (w->buffer); 2656 Fset_buffer (w->contents);
2647 } 2657 }
2648 break; 2658 break;
2649 2659
2650 case REDISPLAY_BUFFER_WINDOWS: 2660 case REDISPLAY_BUFFER_WINDOWS:
2651 if (EQ (w->buffer, obj)) 2661 if (EQ (w->contents, obj))
2652 { 2662 {
2653 mark_window_display_accurate (window, 0); 2663 mark_window_display_accurate (window, 0);
2654 w->update_mode_line = 1; 2664 w->update_mode_line = 1;
@@ -2658,11 +2668,20 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2658 } 2668 }
2659 break; 2669 break;
2660 2670
2661 /* Check for a window that has a killed buffer. */ 2671 /* Check for a leaf window that has a killed buffer
2672 or broken markers. */
2662 case CHECK_ALL_WINDOWS: 2673 case CHECK_ALL_WINDOWS:
2663 if (! NILP (w->buffer) 2674 if (BUFFERP (w->contents))
2664 && !BUFFER_LIVE_P (XBUFFER (w->buffer))) 2675 {
2665 emacs_abort (); 2676 struct buffer *b = XBUFFER (w->contents);
2677
2678 if (!BUFFER_LIVE_P (b))
2679 emacs_abort ();
2680 if (!MARKERP (w->start) || XMARKER (w->start)->buffer != b)
2681 emacs_abort ();
2682 if (!MARKERP (w->pointm) || XMARKER (w->pointm)->buffer != b)
2683 emacs_abort ();
2684 }
2666 break; 2685 break;
2667 2686
2668 case WINDOW_LOOP_UNUSED: 2687 case WINDOW_LOOP_UNUSED:
@@ -2779,7 +2798,7 @@ window-start value is reasonable when this function is called. */)
2779 else if (MINI_WINDOW_P (w)) /* && top > 0) */ 2798 else if (MINI_WINDOW_P (w)) /* && top > 0) */
2780 error ("Can't expand minibuffer to full frame"); 2799 error ("Can't expand minibuffer to full frame");
2781 2800
2782 if (!NILP (w->buffer)) 2801 if (BUFFERP (w->contents))
2783 { 2802 {
2784 startpos = marker_position (w->start); 2803 startpos = marker_position (w->start);
2785 startbyte = marker_byte_position (w->start); 2804 startbyte = marker_byte_position (w->start);
@@ -2851,12 +2870,11 @@ window-start value is reasonable when this function is called. */)
2851 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 2870 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2852 resize_failed = 0; 2871 resize_failed = 0;
2853 2872
2854 if (NILP (w->buffer)) 2873 if (!WINDOW_LEAF_P (w))
2855 { 2874 {
2856 /* Resize child windows vertically. */ 2875 /* Resize child windows vertically. */
2857 XSETINT (delta, XINT (r->total_lines) 2876 XSETINT (delta, r->total_lines - w->total_lines);
2858 - XINT (w->total_lines)); 2877 w->top_line = r->top_line;
2859 wset_top_line (w, r->top_line);
2860 resize_root_window (window, delta, Qnil, Qnil); 2878 resize_root_window (window, delta, Qnil, Qnil);
2861 if (window_resize_check (w, 0)) 2879 if (window_resize_check (w, 0))
2862 window_resize_apply (w, 0); 2880 window_resize_apply (w, 0);
@@ -2872,10 +2890,8 @@ window-start value is reasonable when this function is called. */)
2872 /* Resize child windows horizontally. */ 2890 /* Resize child windows horizontally. */
2873 if (!resize_failed) 2891 if (!resize_failed)
2874 { 2892 {
2875 wset_left_col (w, r->left_col); 2893 w->left_col = r->left_col;
2876 XSETINT (delta, 2894 XSETINT (delta, r->total_cols - w->total_cols);
2877 XINT (r->total_cols) - XINT (w->total_cols));
2878 wset_left_col (w, r->left_col);
2879 resize_root_window (window, delta, Qt, Qnil); 2895 resize_root_window (window, delta, Qt, Qnil);
2880 if (window_resize_check (w, 1)) 2896 if (window_resize_check (w, 1))
2881 window_resize_apply (w, 1); 2897 window_resize_apply (w, 1);
@@ -2913,28 +2929,21 @@ window-start value is reasonable when this function is called. */)
2913 sibling = w->next; 2929 sibling = w->next;
2914 s = XWINDOW (sibling); 2930 s = XWINDOW (sibling);
2915 wset_prev (s, Qnil); 2931 wset_prev (s, Qnil);
2916 if (!NILP (XWINDOW (w->parent)->vchild)) 2932 wset_combination (XWINDOW (w->parent),
2917 wset_vchild (XWINDOW (w->parent), sibling); 2933 XWINDOW (w->parent)->horizontal, sibling);
2918 else
2919 wset_hchild (XWINDOW (w->parent), sibling);
2920 } 2934 }
2921 2935
2922 /* Delete ROOT and all child windows of ROOT. */ 2936 /* Delete ROOT and all child windows of ROOT. */
2923 if (!NILP (r->vchild)) 2937 if (WINDOWP (r->contents))
2924 {
2925 delete_all_child_windows (r->vchild);
2926 wset_vchild (r, Qnil);
2927 }
2928 else if (!NILP (r->hchild))
2929 { 2938 {
2930 delete_all_child_windows (r->hchild); 2939 delete_all_child_windows (r->contents);
2931 wset_hchild (r, Qnil); 2940 wset_combination (r, 0, Qnil);
2932 } 2941 }
2933 2942
2934 replace_window (root, window, 1); 2943 replace_window (root, window, 1);
2935 2944
2936 /* This must become SWINDOW anyway ....... */ 2945 /* This must become SWINDOW anyway ....... */
2937 if (!NILP (w->buffer) && !resize_failed) 2946 if (BUFFERP (w->contents) && !resize_failed)
2938 { 2947 {
2939 /* Try to minimize scrolling, by setting the window start to the 2948 /* Try to minimize scrolling, by setting the window start to the
2940 point will cause the text at the old window start to be at the 2949 point will cause the text at the old window start to be at the
@@ -2943,18 +2952,18 @@ window-start value is reasonable when this function is called. */)
2943 when the display is not current, due to typeahead). */ 2952 when the display is not current, due to typeahead). */
2944 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2953 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2945 if (new_top != top 2954 if (new_top != top
2946 && startpos >= BUF_BEGV (XBUFFER (w->buffer)) 2955 && startpos >= BUF_BEGV (XBUFFER (w->contents))
2947 && startpos <= BUF_ZV (XBUFFER (w->buffer))) 2956 && startpos <= BUF_ZV (XBUFFER (w->contents)))
2948 { 2957 {
2949 struct position pos; 2958 struct position pos;
2950 struct buffer *obuf = current_buffer; 2959 struct buffer *obuf = current_buffer;
2951 2960
2952 Fset_buffer (w->buffer); 2961 Fset_buffer (w->contents);
2953 /* This computation used to temporarily move point, but that 2962 /* This computation used to temporarily move point, but that
2954 can have unwanted side effects due to text properties. */ 2963 can have unwanted side effects due to text properties. */
2955 pos = *vmotion (startpos, startbyte, -top, w); 2964 pos = *vmotion (startpos, startbyte, -top, w);
2956 2965
2957 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); 2966 set_marker_both (w->start, w->contents, pos.bufpos, pos.bytepos);
2958 w->window_end_valid = 0; 2967 w->window_end_valid = 0;
2959 w->start_at_line_beg = (pos.bytepos == BEGV_BYTE 2968 w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
2960 || FETCH_BYTE (pos.bytepos - 1) == '\n'); 2969 || FETCH_BYTE (pos.bytepos - 1) == '\n');
@@ -3148,12 +3157,13 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
3148 reset from the buffer's local settings. */ 3157 reset from the buffer's local settings. */
3149 3158
3150void 3159void
3151set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int keep_margins_p) 3160set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3161 bool run_hooks_p, bool keep_margins_p)
3152{ 3162{
3153 struct window *w = XWINDOW (window); 3163 struct window *w = XWINDOW (window);
3154 struct buffer *b = XBUFFER (buffer); 3164 struct buffer *b = XBUFFER (buffer);
3155 ptrdiff_t count = SPECPDL_INDEX (); 3165 ptrdiff_t count = SPECPDL_INDEX ();
3156 int samebuf = EQ (buffer, w->buffer); 3166 int samebuf = EQ (buffer, w->contents);
3157 3167
3158 wset_buffer (w, buffer); 3168 wset_buffer (w, buffer);
3159 3169
@@ -3272,7 +3282,7 @@ This function runs `window-scroll-functions' before running
3272 if (!BUFFER_LIVE_P (XBUFFER (buffer))) 3282 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
3273 error ("Attempt to display deleted buffer"); 3283 error ("Attempt to display deleted buffer");
3274 3284
3275 tem = w->buffer; 3285 tem = w->contents;
3276 if (NILP (tem)) 3286 if (NILP (tem))
3277 error ("Window is deleted"); 3287 error ("Window is deleted");
3278 else 3288 else
@@ -3325,8 +3335,8 @@ displaying that buffer. */)
3325 struct window *w = XWINDOW (object); 3335 struct window *w = XWINDOW (object);
3326 mark_window_display_accurate (object, 0); 3336 mark_window_display_accurate (object, 0);
3327 w->update_mode_line = 1; 3337 w->update_mode_line = 1;
3328 if (BUFFERP (w->buffer)) 3338 if (BUFFERP (w->contents))
3329 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 3339 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
3330 ++update_mode_lines; 3340 ++update_mode_lines;
3331 return Qt; 3341 return Qt;
3332 } 3342 }
@@ -3395,7 +3405,7 @@ temp_output_buffer_show (register Lisp_Object buf)
3395 record_unwind_protect (Fset_buffer, prev_buffer); 3405 record_unwind_protect (Fset_buffer, prev_buffer);
3396 record_unwind_protect (select_window_norecord, prev_window); 3406 record_unwind_protect (select_window_norecord, prev_window);
3397 Fselect_window (window, Qt); 3407 Fselect_window (window, Qt);
3398 Fset_buffer (w->buffer); 3408 Fset_buffer (w->contents);
3399 Frun_hooks (1, &Qtemp_buffer_show_hook); 3409 Frun_hooks (1, &Qtemp_buffer_show_hook);
3400 unbind_to (count, Qnil); 3410 unbind_to (count, Qnil);
3401 } 3411 }
@@ -3406,7 +3416,7 @@ temp_output_buffer_show (register Lisp_Object buf)
3406 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only 3416 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3407 horizontal child). */ 3417 horizontal child). */
3408static void 3418static void
3409make_parent_window (Lisp_Object window, int horflag) 3419make_parent_window (Lisp_Object window, bool horflag)
3410{ 3420{
3411 Lisp_Object parent; 3421 Lisp_Object parent;
3412 register struct window *o, *p; 3422 register struct window *o, *p;
@@ -3416,7 +3426,7 @@ make_parent_window (Lisp_Object window, int horflag)
3416 memcpy ((char *) p + sizeof (struct vectorlike_header), 3426 memcpy ((char *) p + sizeof (struct vectorlike_header),
3417 (char *) o + sizeof (struct vectorlike_header), 3427 (char *) o + sizeof (struct vectorlike_header),
3418 word_size * VECSIZE (struct window)); 3428 word_size * VECSIZE (struct window));
3419 /* P's buffer slot may change from nil to a buffer. */ 3429 /* P's buffer slot may change from nil to a buffer... */
3420 adjust_window_count (p, 1); 3430 adjust_window_count (p, 1);
3421 XSETWINDOW (parent, p); 3431 XSETWINDOW (parent, p);
3422 3432
@@ -3425,12 +3435,11 @@ make_parent_window (Lisp_Object window, int horflag)
3425 wset_next (o, Qnil); 3435 wset_next (o, Qnil);
3426 wset_prev (o, Qnil); 3436 wset_prev (o, Qnil);
3427 wset_parent (o, parent); 3437 wset_parent (o, parent);
3428 3438 /* ...but now P becomes an internal window. */
3429 wset_hchild (p, horflag ? window : Qnil);
3430 wset_vchild (p, horflag ? Qnil : window);
3431 wset_start (p, Qnil); 3439 wset_start (p, Qnil);
3432 wset_pointm (p, Qnil); 3440 wset_pointm (p, Qnil);
3433 wset_buffer (p, Qnil); 3441 wset_buffer (p, Qnil);
3442 wset_combination (p, horflag, window);
3434 wset_combination_limit (p, Qnil); 3443 wset_combination_limit (p, Qnil);
3435 wset_window_parameters (p, Qnil); 3444 wset_window_parameters (p, Qnil);
3436} 3445}
@@ -3445,10 +3454,6 @@ make_window (void)
3445 w = allocate_window (); 3454 w = allocate_window ();
3446 /* Initialize Lisp data. Note that allocate_window initializes all 3455 /* Initialize Lisp data. Note that allocate_window initializes all
3447 Lisp data to nil, so do it only for slots which should not be nil. */ 3456 Lisp data to nil, so do it only for slots which should not be nil. */
3448 wset_left_col (w, make_number (0));
3449 wset_top_line (w, make_number (0));
3450 wset_total_lines (w, make_number (0));
3451 wset_total_cols (w, make_number (0));
3452 wset_normal_lines (w, make_float (1.0)); 3457 wset_normal_lines (w, make_float (1.0));
3453 wset_normal_cols (w, make_float (1.0)); 3458 wset_normal_cols (w, make_float (1.0));
3454 wset_new_total (w, make_number (0)); 3459 wset_new_total (w, make_number (0));
@@ -3519,14 +3524,14 @@ Note: This function does not operate on any child windows of WINDOW. */)
3519 `window-min-height' or `window-min-width'. It does check that window 3524 `window-min-height' or `window-min-width'. It does check that window
3520 sizes do not drop below one line (two columns). */ 3525 sizes do not drop below one line (two columns). */
3521static int 3526static int
3522window_resize_check (struct window *w, int horflag) 3527window_resize_check (struct window *w, bool horflag)
3523{ 3528{
3524 struct window *c; 3529 struct window *c;
3525 3530
3526 if (!NILP (w->vchild)) 3531 if (WINDOW_VERTICAL_COMBINATION_P (w))
3527 /* W is a vertical combination. */ 3532 /* W is a vertical combination. */
3528 { 3533 {
3529 c = XWINDOW (w->vchild); 3534 c = XWINDOW (w->contents);
3530 if (horflag) 3535 if (horflag)
3531 /* All child windows of W must have the same width as W. */ 3536 /* All child windows of W must have the same width as W. */
3532 { 3537 {
@@ -3554,10 +3559,10 @@ window_resize_check (struct window *w, int horflag)
3554 return (sum_of_sizes == XINT (w->new_total)); 3559 return (sum_of_sizes == XINT (w->new_total));
3555 } 3560 }
3556 } 3561 }
3557 else if (!NILP (w->hchild)) 3562 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3558 /* W is a horizontal combination. */ 3563 /* W is a horizontal combination. */
3559 { 3564 {
3560 c = XWINDOW (w->hchild); 3565 c = XWINDOW (w->contents);
3561 if (horflag) 3566 if (horflag)
3562 /* The sum of the widths of the child windows of W must equal W's 3567 /* The sum of the widths of the child windows of W must equal W's
3563 width. */ 3568 width. */
@@ -3600,7 +3605,7 @@ window_resize_check (struct window *w, int horflag)
3600 This function does not perform any error checks. Make sure you have 3605 This function does not perform any error checks. Make sure you have
3601 run window_resize_check on W before applying this function. */ 3606 run window_resize_check on W before applying this function. */
3602static void 3607static void
3603window_resize_apply (struct window *w, int horflag) 3608window_resize_apply (struct window *w, bool horflag)
3604{ 3609{
3605 struct window *c; 3610 struct window *c;
3606 int pos; 3611 int pos;
@@ -3609,50 +3614,50 @@ window_resize_apply (struct window *w, int horflag)
3609 parent window has been set *before*. */ 3614 parent window has been set *before*. */
3610 if (horflag) 3615 if (horflag)
3611 { 3616 {
3612 wset_total_cols (w, w->new_total); 3617 w->total_cols = XFASTINT (w->new_total);
3613 if (NUMBERP (w->new_normal)) 3618 if (NUMBERP (w->new_normal))
3614 wset_normal_cols (w, w->new_normal); 3619 wset_normal_cols (w, w->new_normal);
3615 3620
3616 pos = XINT (w->left_col); 3621 pos = w->left_col;
3617 } 3622 }
3618 else 3623 else
3619 { 3624 {
3620 wset_total_lines (w, w->new_total); 3625 w->total_lines = XFASTINT (w->new_total);
3621 if (NUMBERP (w->new_normal)) 3626 if (NUMBERP (w->new_normal))
3622 wset_normal_lines (w, w->new_normal); 3627 wset_normal_lines (w, w->new_normal);
3623 3628
3624 pos = XINT (w->top_line); 3629 pos = w->top_line;
3625 } 3630 }
3626 3631
3627 if (!NILP (w->vchild)) 3632 if (WINDOW_VERTICAL_COMBINATION_P (w))
3628 /* W is a vertical combination. */ 3633 /* W is a vertical combination. */
3629 { 3634 {
3630 c = XWINDOW (w->vchild); 3635 c = XWINDOW (w->contents);
3631 while (c) 3636 while (c)
3632 { 3637 {
3633 if (horflag) 3638 if (horflag)
3634 wset_left_col (c, make_number (pos)); 3639 c->left_col = pos;
3635 else 3640 else
3636 wset_top_line (c, make_number (pos)); 3641 c->top_line = pos;
3637 window_resize_apply (c, horflag); 3642 window_resize_apply (c, horflag);
3638 if (!horflag) 3643 if (!horflag)
3639 pos = pos + XINT (c->total_lines); 3644 pos = pos + c->total_lines;
3640 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3645 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3641 } 3646 }
3642 } 3647 }
3643 else if (!NILP (w->hchild)) 3648 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3644 /* W is a horizontal combination. */ 3649 /* W is a horizontal combination. */
3645 { 3650 {
3646 c = XWINDOW (w->hchild); 3651 c = XWINDOW (w->contents);
3647 while (c) 3652 while (c)
3648 { 3653 {
3649 if (horflag) 3654 if (horflag)
3650 wset_left_col (c, make_number (pos)); 3655 c->left_col = pos;
3651 else 3656 else
3652 wset_top_line (c, make_number (pos)); 3657 c->top_line = pos;
3653 window_resize_apply (c, horflag); 3658 window_resize_apply (c, horflag);
3654 if (horflag) 3659 if (horflag)
3655 pos = pos + XINT (c->total_cols); 3660 pos = pos + c->total_cols;
3656 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3661 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3657 } 3662 }
3658 } 3663 }
@@ -3681,11 +3686,11 @@ be applied on the Elisp level. */)
3681{ 3686{
3682 struct frame *f = decode_live_frame (frame); 3687 struct frame *f = decode_live_frame (frame);
3683 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f)); 3688 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
3684 int horflag = !NILP (horizontal); 3689 bool horflag = !NILP (horizontal);
3685 3690
3686 if (!window_resize_check (r, horflag) 3691 if (!window_resize_check (r, horflag)
3687 || ! EQ (r->new_total, 3692 || (XINT (r->new_total)
3688 (horflag ? r->total_cols : r->total_lines))) 3693 != (horflag ? r->total_cols : r->total_lines)))
3689 return Qnil; 3694 return Qnil;
3690 3695
3691 block_input (); 3696 block_input ();
@@ -3711,7 +3716,7 @@ be applied on the Elisp level. */)
3711 satisfy the request. The result will be meaningful if and only if 3716 satisfy the request. The result will be meaningful if and only if
3712 F's windows have meaningful sizes when you call this. */ 3717 F's windows have meaningful sizes when you call this. */
3713void 3718void
3714resize_frame_windows (struct frame *f, int size, int horflag) 3719resize_frame_windows (struct frame *f, int size, bool horflag)
3715{ 3720{
3716 Lisp_Object root = f->root_window; 3721 Lisp_Object root = f->root_window;
3717 struct window *r = XWINDOW (root); 3722 struct window *r = XWINDOW (root);
@@ -3725,18 +3730,17 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3725 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 3730 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
3726 ? 1 : 0))); 3731 ? 1 : 0)));
3727 3732
3728 wset_top_line (r, make_number (FRAME_TOP_MARGIN (f))); 3733 r->top_line = FRAME_TOP_MARGIN (f);
3729 if (NILP (r->vchild) && NILP (r->hchild)) 3734 if (WINDOW_LEAF_P (r))
3730 /* For a leaf root window just set the size. */ 3735 /* For a leaf root window just set the size. */
3731 if (horflag) 3736 if (horflag)
3732 wset_total_cols (r, make_number (new_size)); 3737 r->total_cols = new_size;
3733 else 3738 else
3734 wset_total_lines (r, make_number (new_size)); 3739 r->total_lines = new_size;
3735 else 3740 else
3736 { 3741 {
3737 /* old_size is the old size of the frame's root window. */ 3742 /* old_size is the old size of the frame's root window. */
3738 int old_size = XFASTINT (horflag ? r->total_cols 3743 int old_size = horflag ? r->total_cols : r->total_lines;
3739 : r->total_lines);
3740 Lisp_Object delta; 3744 Lisp_Object delta;
3741 3745
3742 XSETINT (delta, new_size - old_size); 3746 XSETINT (delta, new_size - old_size);
@@ -3766,9 +3770,9 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3766 root = f->selected_window; 3770 root = f->selected_window;
3767 Fdelete_other_windows_internal (root, Qnil); 3771 Fdelete_other_windows_internal (root, Qnil);
3768 if (horflag) 3772 if (horflag)
3769 wset_total_cols (XWINDOW (root), make_number (new_size)); 3773 XWINDOW (root)->total_cols = new_size;
3770 else 3774 else
3771 wset_total_lines (XWINDOW (root), make_number (new_size)); 3775 XWINDOW (root)->total_lines = new_size;
3772 } 3776 }
3773 } 3777 }
3774 } 3778 }
@@ -3778,13 +3782,12 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3778 { 3782 {
3779 m = XWINDOW (mini); 3783 m = XWINDOW (mini);
3780 if (horflag) 3784 if (horflag)
3781 wset_total_cols (m, make_number (size)); 3785 m->total_cols = size;
3782 else 3786 else
3783 { 3787 {
3784 /* Are we sure we always want 1 line here? */ 3788 /* Are we sure we always want 1 line here? */
3785 wset_total_lines (m, make_number (1)); 3789 m->total_lines = 1;
3786 wset_top_line 3790 m->top_line = r->top_line + r->total_lines;
3787 (m, make_number (XINT (r->top_line) + XINT (r->total_lines)));
3788 } 3791 }
3789 } 3792 }
3790 3793
@@ -3825,7 +3828,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3825 register Lisp_Object new, frame, reference; 3828 register Lisp_Object new, frame, reference;
3826 register struct window *o, *p, *n, *r; 3829 register struct window *o, *p, *n, *r;
3827 struct frame *f; 3830 struct frame *f;
3828 int horflag 3831 bool horflag
3829 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */ 3832 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3830 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright); 3833 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3831 int combination_limit = 0; 3834 int combination_limit = 0;
@@ -3843,9 +3846,9 @@ set correctly. See the code of `split-window' for how this is done. */)
3843 combination_limit = 3846 combination_limit =
3844 EQ (Vwindow_combination_limit, Qt) 3847 EQ (Vwindow_combination_limit, Qt)
3845 || NILP (o->parent) 3848 || NILP (o->parent)
3846 || NILP (horflag 3849 || (horflag
3847 ? (XWINDOW (o->parent)->hchild) 3850 ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
3848 : (XWINDOW (o->parent)->vchild)); 3851 : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent)));
3849 3852
3850 /* We need a live reference window to initialize some parameters. */ 3853 /* We need a live reference window to initialize some parameters. */
3851 if (WINDOW_LIVE_P (old)) 3854 if (WINDOW_LIVE_P (old))
@@ -3868,20 +3871,21 @@ set correctly. See the code of `split-window' for how this is done. */)
3868 p = XWINDOW (o->parent); 3871 p = XWINDOW (o->parent);
3869 /* Temporarily pretend we split the parent window. */ 3872 /* Temporarily pretend we split the parent window. */
3870 wset_new_total 3873 wset_new_total
3871 (p, make_number (XINT (horflag ? p->total_cols : p->total_lines) 3874 (p, make_number ((horflag ? p->total_cols : p->total_lines)
3872 - XINT (total_size))); 3875 - XINT (total_size)));
3873 if (!window_resize_check (p, horflag)) 3876 if (!window_resize_check (p, horflag))
3874 error ("Window sizes don't fit"); 3877 error ("Window sizes don't fit");
3875 else 3878 else
3876 /* Undo the temporary pretension. */ 3879 /* Undo the temporary pretension. */
3877 wset_new_total (p, horflag ? p->total_cols : p->total_lines); 3880 wset_new_total (p, make_number
3881 (horflag ? p->total_cols : p->total_lines));
3878 } 3882 }
3879 else 3883 else
3880 { 3884 {
3881 if (!window_resize_check (o, horflag)) 3885 if (!window_resize_check (o, horflag))
3882 error ("Resizing old window failed"); 3886 error ("Resizing old window failed");
3883 else if (XINT (total_size) + XINT (o->new_total) 3887 else if (XINT (total_size) + XINT (o->new_total)
3884 != XINT (horflag ? o->total_cols : o->total_lines)) 3888 != (horflag ? o->total_cols : o->total_lines))
3885 error ("Sum of sizes of old and new window don't fit"); 3889 error ("Sum of sizes of old and new window don't fit");
3886 } 3890 }
3887 3891
@@ -3901,7 +3905,8 @@ set correctly. See the code of `split-window' for how this is done. */)
3901 that its children get merged into another window. */ 3905 that its children get merged into another window. */
3902 wset_combination_limit (p, Qt); 3906 wset_combination_limit (p, Qt);
3903 /* These get applied below. */ 3907 /* These get applied below. */
3904 wset_new_total (p, horflag ? o->total_cols : o->total_lines); 3908 wset_new_total (p, make_number
3909 (horflag ? o->total_cols : o->total_lines));
3905 wset_new_normal (p, new_normal); 3910 wset_new_normal (p, new_normal);
3906 } 3911 }
3907 else 3912 else
@@ -3913,17 +3918,12 @@ set correctly. See the code of `split-window' for how this is done. */)
3913 n = XWINDOW (new); 3918 n = XWINDOW (new);
3914 wset_frame (n, frame); 3919 wset_frame (n, frame);
3915 wset_parent (n, o->parent); 3920 wset_parent (n, o->parent);
3916 wset_vchild (n, Qnil);
3917 wset_hchild (n, Qnil);
3918 3921
3919 if (EQ (side, Qabove) || EQ (side, Qleft)) 3922 if (EQ (side, Qabove) || EQ (side, Qleft))
3920 { 3923 {
3921 wset_prev (n, o->prev); 3924 wset_prev (n, o->prev);
3922 if (NILP (n->prev)) 3925 if (NILP (n->prev))
3923 if (horflag) 3926 wset_combination (p, horflag, new);
3924 wset_hchild (p, new);
3925 else
3926 wset_vchild (p, new);
3927 else 3927 else
3928 wset_next (XWINDOW (n->prev), new); 3928 wset_next (XWINDOW (n->prev), new);
3929 wset_next (n, old); 3929 wset_next (n, old);
@@ -3953,13 +3953,13 @@ set correctly. See the code of `split-window' for how this is done. */)
3953 /* Directly assign orthogonal coordinates and sizes. */ 3953 /* Directly assign orthogonal coordinates and sizes. */
3954 if (horflag) 3954 if (horflag)
3955 { 3955 {
3956 wset_top_line (n, o->top_line); 3956 n->top_line = o->top_line;
3957 wset_total_lines (n, o->total_lines); 3957 n->total_lines = o->total_lines;
3958 } 3958 }
3959 else 3959 else
3960 { 3960 {
3961 wset_left_col (n, o->left_col); 3961 n->left_col = o->left_col;
3962 wset_total_cols (n, o->total_cols); 3962 n->total_cols = o->total_cols;
3963 } 3963 }
3964 3964
3965 /* Iso-coordinates and sizes are assigned by window_resize_apply, 3965 /* Iso-coordinates and sizes are assigned by window_resize_apply,
@@ -3972,7 +3972,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3972 adjust_glyphs (f); 3972 adjust_glyphs (f);
3973 /* Set buffer of NEW to buffer of reference window. Don't run 3973 /* Set buffer of NEW to buffer of reference window. Don't run
3974 any hooks. */ 3974 any hooks. */
3975 set_window_buffer (new, r->buffer, 0, 1); 3975 set_window_buffer (new, r->contents, 0, 1);
3976 unblock_input (); 3976 unblock_input ();
3977 3977
3978 /* Maybe we should run the scroll functions in Elisp (which already 3978 /* Maybe we should run the scroll functions in Elisp (which already
@@ -3994,13 +3994,11 @@ Signal an error when WINDOW is the only window on its frame. */)
3994 register Lisp_Object parent, sibling, frame, root; 3994 register Lisp_Object parent, sibling, frame, root;
3995 struct window *w, *p, *s, *r; 3995 struct window *w, *p, *s, *r;
3996 struct frame *f; 3996 struct frame *f;
3997 int horflag; 3997 bool horflag, before_sibling = 0;
3998 int before_sibling = 0;
3999 3998
4000 w = decode_any_window (window); 3999 w = decode_any_window (window);
4001 XSETWINDOW (window, w); 4000 XSETWINDOW (window, w);
4002 if (NILP (w->buffer) 4001 if (NILP (w->contents))
4003 && NILP (w->hchild) && NILP (w->vchild))
4004 /* It's a no-op to delete an already deleted window. */ 4002 /* It's a no-op to delete an already deleted window. */
4005 return Qnil; 4003 return Qnil;
4006 4004
@@ -4014,7 +4012,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4014 error ("Attempt to delete sole window of parent"); 4012 error ("Attempt to delete sole window of parent");
4015 4013
4016 p = XWINDOW (parent); 4014 p = XWINDOW (parent);
4017 horflag = NILP (p->vchild); 4015 horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
4018 4016
4019 frame = WINDOW_FRAME (w); 4017 frame = WINDOW_FRAME (w);
4020 f = XFRAME (frame); 4018 f = XFRAME (frame);
@@ -4032,10 +4030,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4032 sibling = w->next; 4030 sibling = w->next;
4033 s = XWINDOW (sibling); 4031 s = XWINDOW (sibling);
4034 wset_prev (s, Qnil); 4032 wset_prev (s, Qnil);
4035 if (horflag) 4033 wset_combination (p, horflag, sibling);
4036 wset_hchild (p, sibling);
4037 else
4038 wset_vchild (p, sibling);
4039 } 4034 }
4040 else 4035 else
4041 /* Get SIBLING above (on the left of) WINDOW. */ 4036 /* Get SIBLING above (on the left of) WINDOW. */
@@ -4048,8 +4043,8 @@ Signal an error when WINDOW is the only window on its frame. */)
4048 } 4043 }
4049 4044
4050 if (window_resize_check (r, horflag) 4045 if (window_resize_check (r, horflag)
4051 && EQ (r->new_total, 4046 && (XINT (r->new_total)
4052 (horflag ? r->total_cols : r->total_lines))) 4047 == (horflag ? r->total_cols : r->total_lines)))
4053 /* We can delete WINDOW now. */ 4048 /* We can delete WINDOW now. */
4054 { 4049 {
4055 4050
@@ -4074,17 +4069,12 @@ Signal an error when WINDOW is the only window on its frame. */)
4074 wset_next (w, Qnil); /* Don't delete w->next too. */ 4069 wset_next (w, Qnil); /* Don't delete w->next too. */
4075 free_window_matrices (w); 4070 free_window_matrices (w);
4076 4071
4077 if (!NILP (w->vchild)) 4072 if (WINDOWP (w->contents))
4078 { 4073 {
4079 delete_all_child_windows (w->vchild); 4074 delete_all_child_windows (w->contents);
4080 wset_vchild (w, Qnil); 4075 wset_combination (w, 0, Qnil);
4081 } 4076 }
4082 else if (!NILP (w->hchild)) 4077 else
4083 {
4084 delete_all_child_windows (w->hchild);
4085 wset_hchild (w, Qnil);
4086 }
4087 else if (!NILP (w->buffer))
4088 { 4078 {
4089 unshow_buffer (w); 4079 unshow_buffer (w);
4090 unchain_marker (XMARKER (w->pointm)); 4080 unchain_marker (XMARKER (w->pointm));
@@ -4103,8 +4093,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4103 wset_normal_cols (s, p->normal_cols); 4093 wset_normal_cols (s, p->normal_cols);
4104 wset_normal_lines (s, p->normal_lines); 4094 wset_normal_lines (s, p->normal_lines);
4105 /* Mark PARENT as deleted. */ 4095 /* Mark PARENT as deleted. */
4106 wset_vchild (p, Qnil); 4096 wset_combination (p, 0, Qnil);
4107 wset_hchild (p, Qnil);
4108 /* Try to merge SIBLING into its new parent. */ 4097 /* Try to merge SIBLING into its new parent. */
4109 recombine_windows (sibling); 4098 recombine_windows (sibling);
4110 } 4099 }
@@ -4152,10 +4141,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4152 if (before_sibling) 4141 if (before_sibling)
4153 { 4142 {
4154 wset_prev (s, window); 4143 wset_prev (s, window);
4155 if (horflag) 4144 wset_combination (p, horflag, window);
4156 wset_hchild (p, window);
4157 else
4158 wset_vchild (p, window);
4159 } 4145 }
4160 else 4146 else
4161 { 4147 {
@@ -4195,10 +4181,8 @@ grow_mini_window (struct window *w, int delta)
4195 window_resize_apply (r, 0); 4181 window_resize_apply (r, 0);
4196 4182
4197 /* Grow the mini-window. */ 4183 /* Grow the mini-window. */
4198 wset_top_line 4184 w->top_line = r->top_line + r->total_lines;
4199 (w, make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines))); 4185 w->total_lines -= XINT (value);
4200 wset_total_lines
4201 (w, make_number (XFASTINT (w->total_lines) - XINT (value)));
4202 w->last_modified = 0; 4186 w->last_modified = 0;
4203 w->last_overlay_modified = 0; 4187 w->last_overlay_modified = 0;
4204 4188
@@ -4220,7 +4204,7 @@ shrink_mini_window (struct window *w)
4220 4204
4221 eassert (MINI_WINDOW_P (w)); 4205 eassert (MINI_WINDOW_P (w));
4222 4206
4223 size = XINT (w->total_lines); 4207 size = w->total_lines;
4224 if (size > 1) 4208 if (size > 1)
4225 { 4209 {
4226 root = FRAME_ROOT_WINDOW (f); 4210 root = FRAME_ROOT_WINDOW (f);
@@ -4233,9 +4217,8 @@ shrink_mini_window (struct window *w)
4233 window_resize_apply (r, 0); 4217 window_resize_apply (r, 0);
4234 4218
4235 /* Shrink the mini-window. */ 4219 /* Shrink the mini-window. */
4236 wset_top_line (w, make_number (XFASTINT (r->top_line) 4220 w->top_line = r->top_line + r->total_lines;
4237 + XFASTINT (r->total_lines))); 4221 w->total_lines = 1;
4238 wset_total_lines (w, make_number (1));
4239 4222
4240 w->last_modified = 0; 4223 w->last_modified = 0;
4241 w->last_overlay_modified = 0; 4224 w->last_overlay_modified = 0;
@@ -4269,7 +4252,7 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4269 error ("Cannot resize a minibuffer-only frame"); 4252 error ("Cannot resize a minibuffer-only frame");
4270 4253
4271 r = XWINDOW (FRAME_ROOT_WINDOW (f)); 4254 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4272 height = XINT (r->total_lines) + XINT (w->total_lines); 4255 height = r->total_lines + w->total_lines;
4273 if (window_resize_check (r, 0) 4256 if (window_resize_check (r, 0)
4274 && XINT (w->new_total) > 0 4257 && XINT (w->new_total) > 0
4275 && height == XINT (r->new_total) + XINT (w->new_total)) 4258 && height == XINT (r->new_total) + XINT (w->new_total))
@@ -4277,9 +4260,8 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4277 block_input (); 4260 block_input ();
4278 window_resize_apply (r, 0); 4261 window_resize_apply (r, 0);
4279 4262
4280 wset_total_lines (w, w->new_total); 4263 w->total_lines = XFASTINT (w->new_total);
4281 wset_top_line (w, make_number (XINT (r->top_line) 4264 w->top_line = r->top_line + r->total_lines;
4282 + XINT (r->total_lines)));
4283 4265
4284 windows_or_buffers_changed++; 4266 windows_or_buffers_changed++;
4285 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4267 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
@@ -4302,10 +4284,8 @@ mark_window_cursors_off (struct window *w)
4302{ 4284{
4303 while (w) 4285 while (w)
4304 { 4286 {
4305 if (!NILP (w->hchild)) 4287 if (WINDOWP (w->contents))
4306 mark_window_cursors_off (XWINDOW (w->hchild)); 4288 mark_window_cursors_off (XWINDOW (w->contents));
4307 else if (!NILP (w->vchild))
4308 mark_window_cursors_off (XWINDOW (w->vchild));
4309 else 4289 else
4310 w->phys_cursor_on_p = 0; 4290 w->phys_cursor_on_p = 0;
4311 4291
@@ -4319,13 +4299,12 @@ mark_window_cursors_off (struct window *w)
4319int 4299int
4320window_internal_height (struct window *w) 4300window_internal_height (struct window *w)
4321{ 4301{
4322 int ht = XFASTINT (w->total_lines); 4302 int ht = w->total_lines;
4323 4303
4324 if (!MINI_WINDOW_P (w)) 4304 if (!MINI_WINDOW_P (w))
4325 { 4305 {
4326 if (!NILP (w->parent) 4306 if (!NILP (w->parent)
4327 || !NILP (w->vchild) 4307 || WINDOWP (w->contents)
4328 || !NILP (w->hchild)
4329 || !NILP (w->next) 4308 || !NILP (w->next)
4330 || !NILP (w->prev) 4309 || !NILP (w->prev)
4331 || WINDOW_WANTS_MODELINE_P (w)) 4310 || WINDOW_WANTS_MODELINE_P (w))
@@ -4464,7 +4443,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4464 else 4443 else
4465 spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV); 4444 spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
4466 set_marker_restricted (w->start, make_number (spos), 4445 set_marker_restricted (w->start, make_number (spos),
4467 w->buffer); 4446 w->contents);
4468 w->start_at_line_beg = 1; 4447 w->start_at_line_beg = 1;
4469 w->update_mode_line = 1; 4448 w->update_mode_line = 1;
4470 w->last_modified = 0; 4449 w->last_modified = 0;
@@ -4588,7 +4567,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4588 4567
4589 /* If control gets here, then we vscrolled. */ 4568 /* If control gets here, then we vscrolled. */
4590 4569
4591 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 4570 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
4592 4571
4593 /* Don't try to change the window start below. */ 4572 /* Don't try to change the window start below. */
4594 vscrolled = 1; 4573 vscrolled = 1;
@@ -4608,7 +4587,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4608 } 4587 }
4609 4588
4610 /* Set the window start, and set up the window for redisplay. */ 4589 /* Set the window start, and set up the window for redisplay. */
4611 set_marker_restricted_both (w->start, w->buffer, IT_CHARPOS (it), 4590 set_marker_restricted_both (w->start, w->contents, IT_CHARPOS (it),
4612 IT_BYTEPOS (it)); 4591 IT_BYTEPOS (it));
4613 bytepos = marker_byte_position (w->start); 4592 bytepos = marker_byte_position (w->start);
4614 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); 4593 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
@@ -4629,7 +4608,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4629 even if there is a header line. */ 4608 even if there is a header line. */
4630 this_scroll_margin = max (0, scroll_margin); 4609 this_scroll_margin = max (0, scroll_margin);
4631 this_scroll_margin 4610 this_scroll_margin
4632 = min (this_scroll_margin, XFASTINT (w->total_lines) / 4); 4611 = min (this_scroll_margin, w->total_lines / 4);
4633 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); 4612 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
4634 4613
4635 if (n > 0) 4614 if (n > 0)
@@ -4806,9 +4785,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4806 { 4785 {
4807 /* Don't use a scroll margin that is negative or too large. */ 4786 /* Don't use a scroll margin that is negative or too large. */
4808 int this_scroll_margin = 4787 int this_scroll_margin =
4809 max (0, min (scroll_margin, XINT (w->total_lines) / 4)); 4788 max (0, min (scroll_margin, w->total_lines / 4));
4810 4789
4811 set_marker_restricted_both (w->start, w->buffer, pos, pos_byte); 4790 set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
4812 w->start_at_line_beg = !NILP (bolp); 4791 w->start_at_line_beg = !NILP (bolp);
4813 w->update_mode_line = 1; 4792 w->update_mode_line = 1;
4814 w->last_modified = 0; 4793 w->last_modified = 0;
@@ -4902,10 +4881,10 @@ scroll_command (Lisp_Object n, int direction)
4902 4881
4903 /* If selected window's buffer isn't current, make it current for 4882 /* If selected window's buffer isn't current, make it current for
4904 the moment. But don't screw up if window_scroll gets an error. */ 4883 the moment. But don't screw up if window_scroll gets an error. */
4905 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) 4884 if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer)
4906 { 4885 {
4907 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 4886 record_unwind_protect (save_excursion_restore, save_excursion_save ());
4908 Fset_buffer (XWINDOW (selected_window)->buffer); 4887 Fset_buffer (XWINDOW (selected_window)->contents);
4909 4888
4910 /* Make redisplay consider other windows than just selected_window. */ 4889 /* Make redisplay consider other windows than just selected_window. */
4911 ++windows_or_buffers_changed; 4890 ++windows_or_buffers_changed;
@@ -5020,7 +4999,7 @@ specifies the window to scroll. This takes precedence over
5020 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 4999 record_unwind_protect (save_excursion_restore, save_excursion_save ());
5021 ++windows_or_buffers_changed; 5000 ++windows_or_buffers_changed;
5022 5001
5023 Fset_buffer (w->buffer); 5002 Fset_buffer (w->contents);
5024 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm)); 5003 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
5025 5004
5026 if (NILP (arg)) 5005 if (NILP (arg))
@@ -5114,10 +5093,10 @@ displayed_window_lines (struct window *w)
5114 int bottom_y; 5093 int bottom_y;
5115 void *itdata = NULL; 5094 void *itdata = NULL;
5116 5095
5117 if (XBUFFER (w->buffer) != current_buffer) 5096 if (XBUFFER (w->contents) != current_buffer)
5118 { 5097 {
5119 old_buffer = current_buffer; 5098 old_buffer = current_buffer;
5120 set_buffer_internal (XBUFFER (w->buffer)); 5099 set_buffer_internal (XBUFFER (w->contents));
5121 } 5100 }
5122 else 5101 else
5123 old_buffer = NULL; 5102 old_buffer = NULL;
@@ -5179,7 +5158,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5179 (register Lisp_Object arg) 5158 (register Lisp_Object arg)
5180{ 5159{
5181 struct window *w = XWINDOW (selected_window); 5160 struct window *w = XWINDOW (selected_window);
5182 struct buffer *buf = XBUFFER (w->buffer); 5161 struct buffer *buf = XBUFFER (w->contents);
5183 struct buffer *obuf = current_buffer; 5162 struct buffer *obuf = current_buffer;
5184 int center_p = 0; 5163 int center_p = 0;
5185 ptrdiff_t charpos, bytepos; 5164 ptrdiff_t charpos, bytepos;
@@ -5223,7 +5202,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5223 /* Do this after making BUF current 5202 /* Do this after making BUF current
5224 in case scroll_margin is buffer-local. */ 5203 in case scroll_margin is buffer-local. */
5225 this_scroll_margin = 5204 this_scroll_margin =
5226 max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4)); 5205 max (0, min (scroll_margin, w->total_lines / 4));
5227 5206
5228 /* Handle centering on a graphical frame specially. Such frames can 5207 /* Handle centering on a graphical frame specially. Such frames can
5229 have variable-height lines and centering point on the basis of 5208 have variable-height lines and centering point on the basis of
@@ -5345,7 +5324,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5345 } 5324 }
5346 5325
5347 /* Set the new window start. */ 5326 /* Set the new window start. */
5348 set_marker_both (w->start, w->buffer, charpos, bytepos); 5327 set_marker_both (w->start, w->contents, charpos, bytepos);
5349 w->window_end_valid = 0; 5328 w->window_end_valid = 0;
5350 5329
5351 w->optional_new_start = 1; 5330 w->optional_new_start = 1;
@@ -5389,9 +5368,8 @@ zero means top of window, negative means relative to bottom of window. */)
5389 int this_scroll_margin; 5368 int this_scroll_margin;
5390#endif 5369#endif
5391 5370
5392 if (!(BUFFERP (w->buffer) 5371 if (!(BUFFERP (w->contents) && XBUFFER (w->contents) == current_buffer))
5393 && XBUFFER (w->buffer) == current_buffer)) 5372 /* This test is needed to make sure PT/PT_BYTE make sense in w->contents
5394 /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
5395 when passed below to set_marker_both. */ 5373 when passed below to set_marker_both. */
5396 error ("move-to-window-line called from unrelated buffer"); 5374 error ("move-to-window-line called from unrelated buffer");
5397 5375
@@ -5401,7 +5379,7 @@ zero means top of window, negative means relative to bottom of window. */)
5401 { 5379 {
5402 int height = window_internal_height (w); 5380 int height = window_internal_height (w);
5403 Fvertical_motion (make_number (- (height / 2)), window); 5381 Fvertical_motion (make_number (- (height / 2)), window);
5404 set_marker_both (w->start, w->buffer, PT, PT_BYTE); 5382 set_marker_both (w->start, w->contents, PT, PT_BYTE);
5405 w->start_at_line_beg = !NILP (Fbolp ()); 5383 w->start_at_line_beg = !NILP (Fbolp ());
5406 w->force_start = 1; 5384 w->force_start = 1;
5407 } 5385 }
@@ -5551,9 +5529,9 @@ the return value is nil. Otherwise the value is t. */)
5551 window-point of the final-selected-window to the window-point of 5529 window-point of the final-selected-window to the window-point of
5552 the current-selected-window. So we have to be careful which 5530 the current-selected-window. So we have to be careful which
5553 point of the current-buffer we copy into old_point. */ 5531 point of the current-buffer we copy into old_point. */
5554 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) 5532 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
5555 && WINDOWP (selected_window) 5533 && WINDOWP (selected_window)
5556 && EQ (XWINDOW (selected_window)->buffer, new_current_buffer) 5534 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
5557 && !EQ (selected_window, data->current_window)) 5535 && !EQ (selected_window, data->current_window))
5558 old_point = marker_position (XWINDOW (data->current_window)->pointm); 5536 old_point = marker_position (XWINDOW (data->current_window)->pointm);
5559 else 5537 else
@@ -5567,7 +5545,7 @@ the return value is nil. Otherwise the value is t. */)
5567 So if possible we want this arbitrary choice of "which point" to 5545 So if possible we want this arbitrary choice of "which point" to
5568 be the one from the to-be-selected-window so as to prevent this 5546 be the one from the to-be-selected-window so as to prevent this
5569 window's cursor from being copied from another window. */ 5547 window's cursor from being copied from another window. */
5570 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) 5548 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
5571 /* If current_window = selected_window, its point is in BUF_PT. */ 5549 /* If current_window = selected_window, its point is in BUF_PT. */
5572 && !EQ (selected_window, data->current_window)) 5550 && !EQ (selected_window, data->current_window))
5573 old_point = marker_position (XWINDOW (data->current_window)->pointm); 5551 old_point = marker_position (XWINDOW (data->current_window)->pointm);
@@ -5609,8 +5587,8 @@ the return value is nil. Otherwise the value is t. */)
5609 p = SAVED_WINDOW_N (saved_windows, k); 5587 p = SAVED_WINDOW_N (saved_windows, k);
5610 window = p->window; 5588 window = p->window;
5611 w = XWINDOW (window); 5589 w = XWINDOW (window);
5612 if (!NILP (w->buffer) 5590 if (BUFFERP (w->contents)
5613 && !EQ (w->buffer, p->buffer) 5591 && !EQ (w->contents, p->buffer)
5614 && BUFFER_LIVE_P (XBUFFER (p->buffer))) 5592 && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5615 /* If a window we restore gets another buffer, record the 5593 /* If a window we restore gets another buffer, record the
5616 window's old buffer. */ 5594 window's old buffer. */
@@ -5643,13 +5621,13 @@ the return value is nil. Otherwise the value is t. */)
5643 window holds garbage.) We do this now, before 5621 window holds garbage.) We do this now, before
5644 restoring the window contents, and prevent it from 5622 restoring the window contents, and prevent it from
5645 being done later on when we select a new window. */ 5623 being done later on when we select a new window. */
5646 if (! NILP (XWINDOW (selected_window)->buffer)) 5624 if (! NILP (XWINDOW (selected_window)->contents))
5647 { 5625 {
5648 w = XWINDOW (selected_window); 5626 w = XWINDOW (selected_window);
5649 set_marker_both (w->pointm, 5627 set_marker_both (w->pointm,
5650 w->buffer, 5628 w->contents,
5651 BUF_PT (XBUFFER (w->buffer)), 5629 BUF_PT (XBUFFER (w->contents)),
5652 BUF_PT_BYTE (XBUFFER (w->buffer))); 5630 BUF_PT_BYTE (XBUFFER (w->contents)));
5653 } 5631 }
5654 5632
5655 windows_or_buffers_changed++; 5633 windows_or_buffers_changed++;
@@ -5696,28 +5674,19 @@ the return value is nil. Otherwise the value is t. */)
5696 { 5674 {
5697 wset_prev (w, Qnil); 5675 wset_prev (w, Qnil);
5698 if (!NILP (w->parent)) 5676 if (!NILP (w->parent))
5699 { 5677 wset_combination (XWINDOW (w->parent),
5700 if (EQ (p->total_cols, XWINDOW (w->parent)->total_cols)) 5678 (XINT (p->total_cols)
5701 { 5679 != XWINDOW (w->parent)->total_cols),
5702 wset_vchild (XWINDOW (w->parent), p->window); 5680 p->window);
5703 wset_hchild (XWINDOW (w->parent), Qnil);
5704 }
5705 else
5706 {
5707 wset_hchild (XWINDOW (w->parent), p->window);
5708 wset_vchild (XWINDOW (w->parent), Qnil);
5709 }
5710 }
5711 } 5681 }
5712 5682
5713 /* If we squirreled away the buffer in the window's height, 5683 /* If we squirreled away the buffer, restore it now. */
5714 restore it now. */ 5684 if (BUFFERP (w->combination_limit))
5715 if (BUFFERP (w->total_lines)) 5685 wset_buffer (w, w->combination_limit);
5716 wset_buffer (w, w->total_lines); 5686 w->left_col = XFASTINT (p->left_col);
5717 wset_left_col (w, p->left_col); 5687 w->top_line = XFASTINT (p->top_line);
5718 wset_top_line (w, p->top_line); 5688 w->total_cols = XFASTINT (p->total_cols);
5719 wset_total_cols (w, p->total_cols); 5689 w->total_lines = XFASTINT (p->total_lines);
5720 wset_total_lines (w, p->total_lines);
5721 wset_normal_cols (w, p->normal_cols); 5690 wset_normal_cols (w, p->normal_cols);
5722 wset_normal_lines (w, p->normal_lines); 5691 wset_normal_lines (w, p->normal_lines);
5723 w->hscroll = XFASTINT (p->hscroll); 5692 w->hscroll = XFASTINT (p->hscroll);
@@ -5757,20 +5726,16 @@ the return value is nil. Otherwise the value is t. */)
5757 w->last_modified = 0; 5726 w->last_modified = 0;
5758 w->last_overlay_modified = 0; 5727 w->last_overlay_modified = 0;
5759 5728
5760 /* Reinstall the saved buffer and pointers into it. */ 5729 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5761 if (NILP (p->buffer))
5762 /* An internal window. */
5763 wset_buffer (w, p->buffer);
5764 else if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
5765 /* If saved buffer is alive, install it. */ 5730 /* If saved buffer is alive, install it. */
5766 { 5731 {
5767 wset_buffer (w, p->buffer); 5732 wset_buffer (w, p->buffer);
5768 w->start_at_line_beg = !NILP (p->start_at_line_beg); 5733 w->start_at_line_beg = !NILP (p->start_at_line_beg);
5769 set_marker_restricted (w->start, p->start, w->buffer); 5734 set_marker_restricted (w->start, p->start, w->contents);
5770 set_marker_restricted (w->pointm, p->pointm, 5735 set_marker_restricted (w->pointm, p->pointm,
5771 w->buffer); 5736 w->contents);
5772 Fset_marker (BVAR (XBUFFER (w->buffer), mark), 5737 Fset_marker (BVAR (XBUFFER (w->contents), mark),
5773 p->mark, w->buffer); 5738 p->mark, w->contents);
5774 5739
5775 /* As documented in Fcurrent_window_configuration, don't 5740 /* As documented in Fcurrent_window_configuration, don't
5776 restore the location of point in the buffer which was 5741 restore the location of point in the buffer which was
@@ -5779,23 +5744,21 @@ the return value is nil. Otherwise the value is t. */)
5779 && XBUFFER (p->buffer) == current_buffer) 5744 && XBUFFER (p->buffer) == current_buffer)
5780 Fgoto_char (w->pointm); 5745 Fgoto_char (w->pointm);
5781 } 5746 }
5782 else if (!NILP (w->buffer) 5747 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
5783 && BUFFER_LIVE_P (XBUFFER (w->buffer))) 5748 /* Keep window's old buffer; make sure the markers are real. */
5784 /* Keep window's old buffer; make sure the markers are 5749 {
5785 real. */ 5750 /* Set window markers at start of visible range. */
5786 { 5751 if (XMARKER (w->start)->buffer == 0)
5787 /* Set window markers at start of visible range. */ 5752 set_marker_restricted_both (w->start, w->contents, 0, 0);
5788 if (XMARKER (w->start)->buffer == 0) 5753 if (XMARKER (w->pointm)->buffer == 0)
5789 set_marker_restricted_both (w->start, w->buffer, 0, 0); 5754 set_marker_restricted_both
5790 if (XMARKER (w->pointm)->buffer == 0) 5755 (w->pointm, w->contents,
5791 set_marker_restricted_both 5756 BUF_PT (XBUFFER (w->contents)),
5792 (w->pointm, w->buffer, 5757 BUF_PT_BYTE (XBUFFER (w->contents)));
5793 BUF_PT (XBUFFER (w->buffer)), 5758 w->start_at_line_beg = 1;
5794 BUF_PT_BYTE (XBUFFER (w->buffer))); 5759 }
5795 w->start_at_line_beg = 1; 5760 else if (!NILP (w->start))
5796 } 5761 /* Leaf window has no live buffer, get one. */
5797 else
5798 /* Window has no live buffer, get one. */
5799 { 5762 {
5800 /* Get the buffer via other_buffer_safely in order to 5763 /* Get the buffer via other_buffer_safely in order to
5801 avoid showing an unimportant buffer and, if necessary, to 5764 avoid showing an unimportant buffer and, if necessary, to
@@ -5804,8 +5767,8 @@ the return value is nil. Otherwise the value is t. */)
5804 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); 5767 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
5805 /* This will set the markers to beginning of visible 5768 /* This will set the markers to beginning of visible
5806 range. */ 5769 range. */
5807 set_marker_restricted_both (w->start, w->buffer, 0, 0); 5770 set_marker_restricted_both (w->start, w->contents, 0, 0);
5808 set_marker_restricted_both (w->pointm, w->buffer, 0, 0); 5771 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
5809 w->start_at_line_beg = 1; 5772 w->start_at_line_beg = 1;
5810 if (!NILP (w->dedicated)) 5773 if (!NILP (w->dedicated))
5811 /* Record this window as dead. */ 5774 /* Record this window as dead. */
@@ -5818,17 +5781,17 @@ the return value is nil. Otherwise the value is t. */)
5818 fset_root_window (f, data->root_window); 5781 fset_root_window (f, data->root_window);
5819 /* Arrange *not* to restore point in the buffer that was 5782 /* Arrange *not* to restore point in the buffer that was
5820 current when the window configuration was saved. */ 5783 current when the window configuration was saved. */
5821 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 5784 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
5822 set_marker_restricted (XWINDOW (data->current_window)->pointm, 5785 set_marker_restricted (XWINDOW (data->current_window)->pointm,
5823 make_number (old_point), 5786 make_number (old_point),
5824 XWINDOW (data->current_window)->buffer); 5787 XWINDOW (data->current_window)->contents);
5825 5788
5826 /* In the following call to `select-window', prevent "swapping out 5789 /* In the following call to `select-window', prevent "swapping out
5827 point" in the old selected window using the buffer that has 5790 point" in the old selected window using the buffer that has
5828 been restored into it. We already swapped out that point from 5791 been restored into it. We already swapped out that point from
5829 that window's old buffer. */ 5792 that window's old buffer. */
5830 select_window (data->current_window, Qnil, 1); 5793 select_window (data->current_window, Qnil, 1);
5831 BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window) 5794 BVAR (XBUFFER (XWINDOW (selected_window)->contents), last_selected_window)
5832 = selected_window; 5795 = selected_window;
5833 5796
5834 if (NILP (data->focus_frame) 5797 if (NILP (data->focus_frame)
@@ -5855,14 +5818,9 @@ the return value is nil. Otherwise the value is t. */)
5855 /* Now, free glyph matrices in windows that were not reused. */ 5818 /* Now, free glyph matrices in windows that were not reused. */
5856 for (i = n = 0; i < n_leaf_windows; ++i) 5819 for (i = n = 0; i < n_leaf_windows; ++i)
5857 { 5820 {
5858 if (NILP (leaf_windows[i]->buffer)) 5821 if (NILP (leaf_windows[i]->contents))
5859 { 5822 free_window_matrices (leaf_windows[i]);
5860 /* Assert it's not reused as a combination. */ 5823 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
5861 eassert (NILP (leaf_windows[i]->hchild)
5862 && NILP (leaf_windows[i]->vchild));
5863 free_window_matrices (leaf_windows[i]);
5864 }
5865 else if (EQ (leaf_windows[i]->buffer, new_current_buffer))
5866 ++n; 5824 ++n;
5867 } 5825 }
5868 5826
@@ -5893,7 +5851,7 @@ the return value is nil. Otherwise the value is t. */)
5893 Fset_buffer (new_current_buffer); 5851 Fset_buffer (new_current_buffer);
5894 /* If the new current buffer doesn't appear in the selected 5852 /* If the new current buffer doesn't appear in the selected
5895 window, go to its old point (see bug#12208). */ 5853 window, go to its old point (see bug#12208). */
5896 if (!EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 5854 if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
5897 Fgoto_char (make_number (old_point)); 5855 Fgoto_char (make_number (old_point));
5898 } 5856 }
5899 5857
@@ -5904,8 +5862,10 @@ the return value is nil. Otherwise the value is t. */)
5904} 5862}
5905 5863
5906 5864
5907/* Recursively delete all child windows reachable via the next, vchild, 5865/* If WINDOW is an internal window, recursively delete all child windows
5908 and hchild slots of WINDOW. */ 5866 reachable via the next and contents slots of WINDOW. Otherwise setup
5867 WINDOW to not show any buffer. */
5868
5909void 5869void
5910delete_all_child_windows (Lisp_Object window) 5870delete_all_child_windows (Lisp_Object window)
5911{ 5871{
@@ -5917,24 +5877,20 @@ delete_all_child_windows (Lisp_Object window)
5917 /* Delete WINDOW's siblings (we traverse postorderly). */ 5877 /* Delete WINDOW's siblings (we traverse postorderly). */
5918 delete_all_child_windows (w->next); 5878 delete_all_child_windows (w->next);
5919 5879
5920 /* See Fset_window_configuration for excuse. */ 5880 if (WINDOWP (w->contents))
5921 wset_total_lines (w, w->buffer);
5922
5923 if (!NILP (w->vchild))
5924 {
5925 delete_all_child_windows (w->vchild);
5926 wset_vchild (w, Qnil);
5927 }
5928 else if (!NILP (w->hchild))
5929 { 5881 {
5930 delete_all_child_windows (w->hchild); 5882 delete_all_child_windows (w->contents);
5931 wset_hchild (w, Qnil); 5883 wset_combination (w, 0, Qnil);
5932 } 5884 }
5933 else if (!NILP (w->buffer)) 5885 else if (BUFFERP (w->contents))
5934 { 5886 {
5935 unshow_buffer (w); 5887 unshow_buffer (w);
5936 unchain_marker (XMARKER (w->pointm)); 5888 unchain_marker (XMARKER (w->pointm));
5937 unchain_marker (XMARKER (w->start)); 5889 unchain_marker (XMARKER (w->start));
5890 /* Since combination limit makes sense for an internal windows
5891 only, we use this slot to save the buffer for the sake of
5892 possible resurrection in Fset_window_configuration. */
5893 wset_combination_limit (w, w->contents);
5938 wset_buffer (w, Qnil); 5894 wset_buffer (w, Qnil);
5939 } 5895 }
5940 5896
@@ -5947,10 +5903,8 @@ count_windows (register struct window *window)
5947 register int count = 1; 5903 register int count = 1;
5948 if (!NILP (window->next)) 5904 if (!NILP (window->next))
5949 count += count_windows (XWINDOW (window->next)); 5905 count += count_windows (XWINDOW (window->next));
5950 if (!NILP (window->vchild)) 5906 if (WINDOWP (window->contents))
5951 count += count_windows (XWINDOW (window->vchild)); 5907 count += count_windows (XWINDOW (window->contents));
5952 if (!NILP (window->hchild))
5953 count += count_windows (XWINDOW (window->hchild));
5954 return count; 5908 return count;
5955} 5909}
5956 5910
@@ -5962,10 +5916,8 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
5962{ 5916{
5963 while (w) 5917 while (w)
5964 { 5918 {
5965 if (!NILP (w->hchild)) 5919 if (WINDOWP (w->contents))
5966 i = get_leaf_windows (XWINDOW (w->hchild), flat, i); 5920 i = get_leaf_windows (XWINDOW (w->contents), flat, i);
5967 else if (!NILP (w->vchild))
5968 i = get_leaf_windows (XWINDOW (w->vchild), flat, i);
5969 else 5921 else
5970 flat[i++] = w; 5922 flat[i++] = w;
5971 5923
@@ -6005,8 +5957,7 @@ get_phys_cursor_glyph (struct window *w)
6005 hpos = row->used[TEXT_AREA] - 1; 5957 hpos = row->used[TEXT_AREA] - 1;
6006 } 5958 }
6007 5959
6008 if (row->used[TEXT_AREA] > hpos 5960 if (0 <= hpos && hpos < row->used[TEXT_AREA])
6009 && 0 <= hpos)
6010 glyph = row->glyphs[TEXT_AREA] + hpos; 5961 glyph = row->glyphs[TEXT_AREA] + hpos;
6011 else 5962 else
6012 glyph = NULL; 5963 glyph = NULL;
@@ -6022,18 +5973,18 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6022 register struct window *w; 5973 register struct window *w;
6023 register Lisp_Object tem, pers, par; 5974 register Lisp_Object tem, pers, par;
6024 5975
6025 for (;!NILP (window); window = w->next) 5976 for (; !NILP (window); window = w->next)
6026 { 5977 {
6027 p = SAVED_WINDOW_N (vector, i); 5978 p = SAVED_WINDOW_N (vector, i);
6028 w = XWINDOW (window); 5979 w = XWINDOW (window);
6029 5980
6030 wset_temslot (w, make_number (i)); i++; 5981 wset_temslot (w, make_number (i)); i++;
6031 p->window = window; 5982 p->window = window;
6032 p->buffer = w->buffer; 5983 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
6033 p->left_col = w->left_col; 5984 p->left_col = make_number (w->left_col);
6034 p->top_line = w->top_line; 5985 p->top_line = make_number (w->top_line);
6035 p->total_cols = w->total_cols; 5986 p->total_cols = make_number (w->total_cols);
6036 p->total_lines = w->total_lines; 5987 p->total_lines = make_number (w->total_lines);
6037 p->normal_cols = w->normal_cols; 5988 p->normal_cols = w->normal_cols;
6038 p->normal_lines = w->normal_lines; 5989 p->normal_lines = w->normal_lines;
6039 XSETFASTINT (p->hscroll, w->hscroll); 5990 XSETFASTINT (p->hscroll, w->hscroll);
@@ -6096,15 +6047,15 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6096 } 6047 }
6097 } 6048 }
6098 6049
6099 if (!NILP (w->buffer)) 6050 if (BUFFERP (w->contents))
6100 { 6051 {
6101 /* Save w's value of point in the window configuration. If w 6052 /* Save w's value of point in the window configuration. If w
6102 is the selected window, then get the value of point from 6053 is the selected window, then get the value of point from
6103 the buffer; pointm is garbage in the selected window. */ 6054 the buffer; pointm is garbage in the selected window. */
6104 if (EQ (window, selected_window)) 6055 if (EQ (window, selected_window))
6105 p->pointm = build_marker (XBUFFER (w->buffer), 6056 p->pointm = build_marker (XBUFFER (w->contents),
6106 BUF_PT (XBUFFER (w->buffer)), 6057 BUF_PT (XBUFFER (w->contents)),
6107 BUF_PT_BYTE (XBUFFER (w->buffer))); 6058 BUF_PT_BYTE (XBUFFER (w->contents)));
6108 else 6059 else
6109 p->pointm = Fcopy_marker (w->pointm, Qnil); 6060 p->pointm = Fcopy_marker (w->pointm, Qnil);
6110 XMARKER (p->pointm)->insertion_type 6061 XMARKER (p->pointm)->insertion_type
@@ -6113,7 +6064,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6113 p->start = Fcopy_marker (w->start, Qnil); 6064 p->start = Fcopy_marker (w->start, Qnil);
6114 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil; 6065 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
6115 6066
6116 tem = BVAR (XBUFFER (w->buffer), mark); 6067 tem = BVAR (XBUFFER (w->contents), mark);
6117 p->mark = Fcopy_marker (tem, Qnil); 6068 p->mark = Fcopy_marker (tem, Qnil);
6118 } 6069 }
6119 else 6070 else
@@ -6134,10 +6085,8 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6134 else 6085 else
6135 p->prev = XWINDOW (w->prev)->temslot; 6086 p->prev = XWINDOW (w->prev)->temslot;
6136 6087
6137 if (!NILP (w->vchild)) 6088 if (WINDOWP (w->contents))
6138 i = save_window_save (w->vchild, vector, i); 6089 i = save_window_save (w->contents, vector, i);
6139 if (!NILP (w->hchild))
6140 i = save_window_save (w->hchild, vector, i);
6141 } 6090 }
6142 6091
6143 return i; 6092 return i;
@@ -6454,7 +6403,7 @@ If PIXELS-P is non-nil, the return value is VSCROLL. */)
6454 adjust_glyphs (f); 6403 adjust_glyphs (f);
6455 6404
6456 /* Prevent redisplay shortcuts. */ 6405 /* Prevent redisplay shortcuts. */
6457 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 6406 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
6458 } 6407 }
6459 } 6408 }
6460 6409
@@ -6488,10 +6437,8 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u
6488 6437
6489 for (cont = 1; w && cont;) 6438 for (cont = 1; w && cont;)
6490 { 6439 {
6491 if (!NILP (w->hchild)) 6440 if (WINDOWP (w->contents))
6492 cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data); 6441 cont = foreach_window_1 (XWINDOW (w->contents), fn, user_data);
6493 else if (!NILP (w->vchild))
6494 cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data);
6495 else 6442 else
6496 cont = fn (w, user_data); 6443 cont = fn (w, user_data);
6497 6444
@@ -6527,7 +6474,7 @@ freeze_window_start (struct window *w, void *freeze_p)
6527 means freeze the window start. */ 6474 means freeze the window start. */
6528 6475
6529void 6476void
6530freeze_window_starts (struct frame *f, int freeze_p) 6477freeze_window_starts (struct frame *f, bool freeze_p)
6531{ 6478{
6532 foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0)); 6479 foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
6533} 6480}
diff --git a/src/window.h b/src/window.h
index dcef37abb4c..411756f045e 100644
--- a/src/window.h
+++ b/src/window.h
@@ -41,14 +41,13 @@ They are deleted only by calling delete-window on them (but
41this can be done implicitly). Combination windows can be created 41this can be done implicitly). Combination windows can be created
42and deleted at any time. 42and deleted at any time.
43 43
44A leaf window has a non-nil buffer field, and also 44A leaf window has a buffer stored in contents field and markers in its start
45 has markers in its start and pointm fields. Non-leaf windows 45and pointm fields. Non-leaf windows have nil in the latter two fields.
46 have nil in these fields.
47 46
48Non-leaf windows are either vertical or horizontal combinations. 47Non-leaf windows are either vertical or horizontal combinations.
49 48
50A vertical combination window has children that are arranged on the frame 49A vertical combination window has children that are arranged on the frame
51one above the next. Its vchild field points to the uppermost child. 50one above the next. Its contents field points to the uppermost child.
52The parent field of each of the children points to the vertical 51The parent field of each of the children points to the vertical
53combination window. The next field of each child points to the 52combination window. The next field of each child points to the
54child below it, or is nil for the lowest child. The prev field 53child below it, or is nil for the lowest child. The prev field
@@ -56,7 +55,7 @@ of each child points to the child above it, or is nil for the
56highest child. 55highest child.
57 56
58A horizontal combination window has children that are side by side. 57A horizontal combination window has children that are side by side.
59Its hchild field points to the leftmost child. In each child 58Its contents field points to the leftmost child. In each child
60the next field points to the child to the right and the prev field 59the next field points to the child to the right and the prev field
61points to the child to the left. 60points to the child to the left.
62 61
@@ -78,7 +77,7 @@ the root window is the minibuf window. On minibufferless screens or
78minibuffer-only screens, the root window and the minibuffer window are 77minibuffer-only screens, the root window and the minibuffer window are
79one and the same, so its prev and next members are nil. 78one and the same, so its prev and next members are nil.
80 79
81A dead window has its buffer, hchild, and vchild windows all nil. */ 80A dead window has its contents field set to nil. */
82 81
83struct cursor_pos 82struct cursor_pos
84{ 83{
@@ -102,37 +101,22 @@ struct window
102 Lisp_Object next; 101 Lisp_Object next;
103 Lisp_Object prev; 102 Lisp_Object prev;
104 103
105 /* First child of this window: vchild is used if this is a vertical
106 combination, hchild if this is a horizontal combination. Of the
107 fields vchild, hchild and buffer, one and only one is non-nil
108 unless the window is dead. */
109 Lisp_Object hchild;
110 Lisp_Object vchild;
111
112 /* The window this one is a child of. */ 104 /* The window this one is a child of. */
113 Lisp_Object parent; 105 Lisp_Object parent;
114 106
115 /* The upper left corner coordinates of this window, as integers 107 /* The normal size of the window. These are fractions, but we do
116 relative to upper left corner of frame = 0, 0. */ 108 not use C doubles to avoid creating new Lisp_Float objects while
117 Lisp_Object left_col; 109 interfacing Lisp in Fwindow_normal_size. */
118 Lisp_Object top_line;
119
120 /* The size of the window. */
121 Lisp_Object total_lines;
122 Lisp_Object total_cols;
123
124 /* The normal size of the window. */
125 Lisp_Object normal_lines; 110 Lisp_Object normal_lines;
126 Lisp_Object normal_cols; 111 Lisp_Object normal_cols;
127 112
128 /* New sizes of the window. */ 113 /* New sizes of the window. Note that Lisp code may set new_normal
114 to something beyond an integer, so C int can't be used here. */
129 Lisp_Object new_total; 115 Lisp_Object new_total;
130 Lisp_Object new_normal; 116 Lisp_Object new_normal;
131 117
132 /* The buffer displayed in this window. Of the fields vchild, 118 /* May be buffer, window, or nil. */
133 hchild and buffer, one and only one is non-nil unless the window 119 Lisp_Object contents;
134 is dead. */
135 Lisp_Object buffer;
136 120
137 /* A marker pointing to where in the text to start displaying. 121 /* A marker pointing to where in the text to start displaying.
138 BIDI Note: This is the _logical-order_ start, i.e. the smallest 122 BIDI Note: This is the _logical-order_ start, i.e. the smallest
@@ -221,6 +205,15 @@ struct window
221 /* Number saying how recently window was selected. */ 205 /* Number saying how recently window was selected. */
222 int use_time; 206 int use_time;
223 207
208 /* The upper left corner coordinates of this window,
209 relative to upper left corner of frame = 0, 0. */
210 int left_col;
211 int top_line;
212
213 /* The size of the window. */
214 int total_lines;
215 int total_cols;
216
224 /* Number of columns display within the window is scrolled to the left. */ 217 /* Number of columns display within the window is scrolled to the left. */
225 ptrdiff_t hscroll; 218 ptrdiff_t hscroll;
226 219
@@ -279,6 +272,10 @@ struct window
279 /* Non-zero if this window is a minibuffer window. */ 272 /* Non-zero if this window is a minibuffer window. */
280 unsigned mini : 1; 273 unsigned mini : 1;
281 274
275 /* Meaningful only if contents is a window, non-zero if this
276 internal window is used in horizontal combination. */
277 unsigned horizontal : 1;
278
282 /* Non-zero means must regenerate mode line of this window. */ 279 /* Non-zero means must regenerate mode line of this window. */
283 unsigned update_mode_line : 1; 280 unsigned update_mode_line : 1;
284 281
@@ -354,11 +351,6 @@ wset_frame (struct window *w, Lisp_Object val)
354 w->frame = val; 351 w->frame = val;
355} 352}
356WINDOW_INLINE void 353WINDOW_INLINE void
357wset_left_col (struct window *w, Lisp_Object val)
358{
359 w->left_col = val;
360}
361WINDOW_INLINE void
362wset_next (struct window *w, Lisp_Object val) 354wset_next (struct window *w, Lisp_Object val)
363{ 355{
364 w->next = val; 356 w->next = val;
@@ -374,21 +366,6 @@ wset_redisplay_end_trigger (struct window *w, Lisp_Object val)
374 w->redisplay_end_trigger = val; 366 w->redisplay_end_trigger = val;
375} 367}
376WINDOW_INLINE void 368WINDOW_INLINE void
377wset_top_line (struct window *w, Lisp_Object val)
378{
379 w->top_line = val;
380}
381WINDOW_INLINE void
382wset_total_cols (struct window *w, Lisp_Object val)
383{
384 w->total_cols = val;
385}
386WINDOW_INLINE void
387wset_total_lines (struct window *w, Lisp_Object val)
388{
389 w->total_lines = val;
390}
391WINDOW_INLINE void
392wset_vertical_scroll_bar (struct window *w, Lisp_Object val) 369wset_vertical_scroll_bar (struct window *w, Lisp_Object val)
393{ 370{
394 w->vertical_scroll_bar = val; 371 w->vertical_scroll_bar = val;
@@ -445,6 +422,21 @@ wset_next_buffers (struct window *w, Lisp_Object val)
445 422
446/* A handy macro. */ 423/* A handy macro. */
447 424
425/* Non-zero if W is leaf (carry the buffer). */
426
427#define WINDOW_LEAF_P(W) \
428 (BUFFERP ((W)->contents))
429
430/* Non-zero if W is a member of horizontal combination. */
431
432#define WINDOW_HORIZONTAL_COMBINATION_P(W) \
433 (WINDOWP ((W)->contents) && (W)->horizontal)
434
435/* Non-zero if W is a member of vertical combination. */
436
437#define WINDOW_VERTICAL_COMBINATION_P(W) \
438 (WINDOWP ((W)->contents) && !(W)->horizontal)
439
448#define WINDOW_XFRAME(W) \ 440#define WINDOW_XFRAME(W) \
449 (XFRAME (WINDOW_FRAME ((W)))) 441 (XFRAME (WINDOW_FRAME ((W))))
450 442
@@ -461,14 +453,12 @@ wset_next_buffers (struct window *w, Lisp_Object val)
461/* Return the width of window W in canonical column units. 453/* Return the width of window W in canonical column units.
462 This includes scroll bars and fringes. */ 454 This includes scroll bars and fringes. */
463 455
464#define WINDOW_TOTAL_COLS(W) \ 456#define WINDOW_TOTAL_COLS(W) (W)->total_cols
465 (XFASTINT (W->total_cols))
466 457
467/* Return the height of window W in canonical line units. 458/* Return the height of window W in canonical line units.
468 This includes header and mode lines, if any. */ 459 This includes header and mode lines, if any. */
469 460
470#define WINDOW_TOTAL_LINES(W) \ 461#define WINDOW_TOTAL_LINES(W) (W)->total_lines
471 (XFASTINT (W->total_lines))
472 462
473/* Return the total pixel width of window W. */ 463/* Return the total pixel width of window W. */
474 464
@@ -495,8 +485,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
495/* Return the canonical frame column at which window W starts. 485/* Return the canonical frame column at which window W starts.
496 This includes a left-hand scroll bar, if any. */ 486 This includes a left-hand scroll bar, if any. */
497 487
498#define WINDOW_LEFT_EDGE_COL(W) \ 488#define WINDOW_LEFT_EDGE_COL(W) (W)->left_col
499 (XFASTINT (W->left_col))
500 489
501/* Return the canonical frame column before which window W ends. 490/* Return the canonical frame column before which window W ends.
502 This includes a right-hand scroll bar, if any. */ 491 This includes a right-hand scroll bar, if any. */
@@ -507,8 +496,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
507/* Return the canonical frame line at which window W starts. 496/* Return the canonical frame line at which window W starts.
508 This includes a header line, if any. */ 497 This includes a header line, if any. */
509 498
510#define WINDOW_TOP_EDGE_LINE(W) \ 499#define WINDOW_TOP_EDGE_LINE(W) (W)->top_line
511 (XFASTINT (W->top_line))
512 500
513/* Return the canonical frame line before which window W ends. 501/* Return the canonical frame line before which window W ends.
514 This includes a mode line, if any. */ 502 This includes a mode line, if any. */
@@ -533,9 +521,14 @@ wset_next_buffers (struct window *w, Lisp_Object val)
533 521
534/* 1 if W is a menu bar window. */ 522/* 1 if W is a menu bar window. */
535 523
524#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
536#define WINDOW_MENU_BAR_P(W) \ 525#define WINDOW_MENU_BAR_P(W) \
537 (WINDOWP (WINDOW_XFRAME (W)->menu_bar_window) \ 526 (WINDOWP (WINDOW_XFRAME (W)->menu_bar_window) \
538 && (W) == XWINDOW (WINDOW_XFRAME (W)->menu_bar_window)) 527 && (W) == XWINDOW (WINDOW_XFRAME (W)->menu_bar_window))
528#else
529/* No menu bar windows if X toolkit is in use. */
530#define WINDOW_MENU_BAR_P(W) (0)
531#endif
539 532
540/* 1 if W is a tool bar window. */ 533/* 1 if W is a tool bar window. */
541 534
@@ -891,10 +884,10 @@ extern Lisp_Object Vmouse_event;
891 884
892extern Lisp_Object make_window (void); 885extern Lisp_Object make_window (void);
893extern Lisp_Object window_from_coordinates (struct frame *, int, int, 886extern Lisp_Object window_from_coordinates (struct frame *, int, int,
894 enum window_part *, int); 887 enum window_part *, bool);
895extern void resize_frame_windows (struct frame *, int, int); 888extern void resize_frame_windows (struct frame *, int, bool);
896extern void delete_all_child_windows (Lisp_Object); 889extern void delete_all_child_windows (Lisp_Object);
897extern void freeze_window_starts (struct frame *, int); 890extern void freeze_window_starts (struct frame *, bool);
898extern void grow_mini_window (struct window *, int); 891extern void grow_mini_window (struct window *, int);
899extern void shrink_mini_window (struct window *); 892extern void shrink_mini_window (struct window *);
900extern int window_relative_x_coord (struct window *, enum window_part, int); 893extern int window_relative_x_coord (struct window *, enum window_part, int);
@@ -906,7 +899,7 @@ void run_window_configuration_change_hook (struct frame *f);
906 it's not allowed. */ 899 it's not allowed. */
907 900
908void set_window_buffer (Lisp_Object window, Lisp_Object buffer, 901void set_window_buffer (Lisp_Object window, Lisp_Object buffer,
909 int run_hooks_p, int keep_margins_p); 902 bool run_hooks_p, bool keep_margins_p);
910 903
911/* This is the window where the echo area message was displayed. It 904/* This is the window where the echo area message was displayed. It
912 is always a minibuffer window, but it may not be the same window 905 is always a minibuffer window, but it may not be the same window
@@ -947,20 +940,17 @@ extern void check_frame_size (struct frame *frame, int *rows, int *cols);
947struct glyph *get_phys_cursor_glyph (struct window *w); 940struct glyph *get_phys_cursor_glyph (struct window *w);
948 941
949/* Value is non-zero if WINDOW is a valid window. */ 942/* Value is non-zero if WINDOW is a valid window. */
950#define WINDOW_VALID_P(WINDOW) \ 943#define WINDOW_VALID_P(WINDOW) \
951 (WINDOWP (WINDOW) \ 944 (WINDOWP (WINDOW) && !NILP (XWINDOW (WINDOW)->contents)) \
952 && (!NILP (XWINDOW (WINDOW)->buffer) \ 945
953 || !NILP (XWINDOW (WINDOW)->vchild) \ 946/* A window of any sort, leaf or interior, is "valid" if its
954 || !NILP (XWINDOW (WINDOW)->hchild))) 947 contents slot is non-nil. */
955
956/* A window of any sort, leaf or interior, is "valid" if one
957 of its buffer, vchild, or hchild members is non-nil. */
958#define CHECK_VALID_WINDOW(WINDOW) \ 948#define CHECK_VALID_WINDOW(WINDOW) \
959 CHECK_TYPE (WINDOW_VALID_P (WINDOW), Qwindow_valid_p, WINDOW) 949 CHECK_TYPE (WINDOW_VALID_P (WINDOW), Qwindow_valid_p, WINDOW)
960 950
961/* Value is non-zero if WINDOW is a live window. */ 951/* Value is non-zero if WINDOW is a live window. */
962#define WINDOW_LIVE_P(WINDOW) \ 952#define WINDOW_LIVE_P(WINDOW) \
963 (WINDOWP (WINDOW) && !NILP (XWINDOW (WINDOW)->buffer)) 953 (WINDOWP (WINDOW) && BUFFERP (XWINDOW (WINDOW)->contents))
964 954
965/* A window is "live" if and only if it shows a buffer. */ 955/* A window is "live" if and only if it shows a buffer. */
966#define CHECK_LIVE_WINDOW(WINDOW) \ 956#define CHECK_LIVE_WINDOW(WINDOW) \
diff --git a/src/xdisp.c b/src/xdisp.c
index a5bba1a81cd..5ae15cbd0b3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -580,7 +580,7 @@ static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
580 580
581/* Ascent and height of the last line processed by move_it_to. */ 581/* Ascent and height of the last line processed by move_it_to. */
582 582
583static int last_max_ascent, last_height; 583static int last_height;
584 584
585/* Non-zero if there's a help-echo in the echo area. */ 585/* Non-zero if there's a help-echo in the echo area. */
586 586
@@ -794,6 +794,7 @@ static void set_iterator_to_next (struct it *, int);
794static void mark_window_display_accurate_1 (struct window *, int); 794static void mark_window_display_accurate_1 (struct window *, int);
795static int single_display_spec_string_p (Lisp_Object, Lisp_Object); 795static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
796static int display_prop_string_p (Lisp_Object, Lisp_Object); 796static int display_prop_string_p (Lisp_Object, Lisp_Object);
797static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
797static int cursor_row_p (struct glyph_row *); 798static int cursor_row_p (struct glyph_row *);
798static int redisplay_mode_lines (Lisp_Object, int); 799static int redisplay_mode_lines (Lisp_Object, int);
799static char *decode_mode_spec_coding (Lisp_Object, char *, int); 800static char *decode_mode_spec_coding (Lisp_Object, char *, int);
@@ -880,7 +881,6 @@ static void next_overlay_string (struct it *);
880static void reseat (struct it *, struct text_pos, int); 881static void reseat (struct it *, struct text_pos, int);
881static void reseat_1 (struct it *, struct text_pos, int); 882static void reseat_1 (struct it *, struct text_pos, int);
882static void back_to_previous_visible_line_start (struct it *); 883static void back_to_previous_visible_line_start (struct it *);
883void reseat_at_previous_visible_line_start (struct it *);
884static void reseat_at_next_visible_line_start (struct it *, int); 884static void reseat_at_next_visible_line_start (struct it *, int);
885static int next_element_from_ellipsis (struct it *); 885static int next_element_from_ellipsis (struct it *);
886static int next_element_from_display_vector (struct it *); 886static int next_element_from_display_vector (struct it *);
@@ -899,7 +899,6 @@ static int get_next_display_element (struct it *);
899static enum move_it_result 899static enum move_it_result
900 move_it_in_display_line_to (struct it *, ptrdiff_t, int, 900 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
901 enum move_operation_enum); 901 enum move_operation_enum);
902void move_it_vertically_backward (struct it *, int);
903static void get_visually_first_element (struct it *); 902static void get_visually_first_element (struct it *);
904static void init_to_row_start (struct it *, struct window *, 903static void init_to_row_start (struct it *, struct window *,
905 struct glyph_row *); 904 struct glyph_row *);
@@ -979,7 +978,7 @@ window_text_bottom_y (struct window *w)
979int 978int
980window_box_width (struct window *w, int area) 979window_box_width (struct window *w, int area)
981{ 980{
982 int cols = XFASTINT (w->total_cols); 981 int cols = w->total_cols;
983 int pixels = 0; 982 int pixels = 0;
984 983
985 if (!w->pseudo_window_p) 984 if (!w->pseudo_window_p)
@@ -1283,10 +1282,10 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1283 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w)))) 1282 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1284 return visible_p; 1283 return visible_p;
1285 1284
1286 if (XBUFFER (w->buffer) != current_buffer) 1285 if (XBUFFER (w->contents) != current_buffer)
1287 { 1286 {
1288 old_buffer = current_buffer; 1287 old_buffer = current_buffer;
1289 set_buffer_internal_1 (XBUFFER (w->buffer)); 1288 set_buffer_internal_1 (XBUFFER (w->contents));
1290 } 1289 }
1291 1290
1292 SET_TEXT_POS_FROM_MARKER (top, w->start); 1291 SET_TEXT_POS_FROM_MARKER (top, w->start);
@@ -1372,18 +1371,41 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1372 top_x = it.glyph_row->x; 1371 top_x = it.glyph_row->x;
1373 else 1372 else
1374 { 1373 {
1375 struct it it2; 1374 struct it it2, it2_prev;
1375 /* The idea is to get to the previous buffer
1376 position, consume the character there, and use
1377 the pixel coordinates we get after that. But if
1378 the previous buffer position is also displayed
1379 from a display vector, we need to consume all of
1380 the glyphs from that display vector. */
1376 start_display (&it2, w, top); 1381 start_display (&it2, w, top);
1377 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS); 1382 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1378 get_next_display_element (&it2); 1383 /* If we didn't get to CHARPOS - 1, there's some
1379 PRODUCE_GLYPHS (&it2); 1384 replacing display property at that position, and
1380 if (ITERATOR_AT_END_OF_LINE_P (&it2) 1385 we stopped after it. That is exactly the place
1381 || it2.current_x > it2.last_visible_x) 1386 whose coordinates we want. */
1387 if (IT_CHARPOS (it2) != charpos - 1)
1388 it2_prev = it2;
1389 else
1390 {
1391 /* Iterate until we get out of the display
1392 vector that displays the character at
1393 CHARPOS - 1. */
1394 do {
1395 get_next_display_element (&it2);
1396 PRODUCE_GLYPHS (&it2);
1397 it2_prev = it2;
1398 set_iterator_to_next (&it2, 1);
1399 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1400 && IT_CHARPOS (it2) < charpos);
1401 }
1402 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1403 || it2_prev.current_x > it2_prev.last_visible_x)
1382 top_x = it.glyph_row->x; 1404 top_x = it.glyph_row->x;
1383 else 1405 else
1384 { 1406 {
1385 top_x = it2.current_x; 1407 top_x = it2_prev.current_x;
1386 top_y = it2.current_y; 1408 top_y = it2_prev.current_y;
1387 } 1409 }
1388 } 1410 }
1389 } 1411 }
@@ -1392,23 +1414,34 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1392 Lisp_Object cpos = make_number (charpos); 1414 Lisp_Object cpos = make_number (charpos);
1393 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil); 1415 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1394 Lisp_Object string = string_from_display_spec (spec); 1416 Lisp_Object string = string_from_display_spec (spec);
1417 struct text_pos tpos;
1418 int replacing_spec_p;
1395 bool newline_in_string 1419 bool newline_in_string
1396 = (STRINGP (string) 1420 = (STRINGP (string)
1397 && memchr (SDATA (string), '\n', SBYTES (string))); 1421 && memchr (SDATA (string), '\n', SBYTES (string)));
1422
1423 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1424 replacing_spec_p
1425 = (!NILP (spec)
1426 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1427 charpos, FRAME_WINDOW_P (it.f)));
1398 /* The tricky code below is needed because there's a 1428 /* The tricky code below is needed because there's a
1399 discrepancy between move_it_to and how we set cursor 1429 discrepancy between move_it_to and how we set cursor
1400 when the display line ends in a newline from a 1430 when PT is at the beginning of a portion of text
1401 display string. move_it_to will stop _after_ such 1431 covered by a display property or an overlay with a
1402 display strings, whereas set_cursor_from_row 1432 display property, or the display line ends in a
1403 conspires with cursor_row_p to place the cursor on 1433 newline from a display string. move_it_to will stop
1404 the first glyph produced from the display string. */ 1434 _after_ such display strings, whereas
1435 set_cursor_from_row conspires with cursor_row_p to
1436 place the cursor on the first glyph produced from the
1437 display string. */
1405 1438
1406 /* We have overshoot PT because it is covered by a 1439 /* We have overshoot PT because it is covered by a
1407 display property whose value is a string. If the 1440 display property that replaces the text it covers.
1408 string includes embedded newlines, we are also in the 1441 If the string includes embedded newlines, we are also
1409 wrong display line. Backtrack to the correct line, 1442 in the wrong display line. Backtrack to the correct
1410 where the display string begins. */ 1443 line, where the display property begins. */
1411 if (newline_in_string) 1444 if (replacing_spec_p)
1412 { 1445 {
1413 Lisp_Object startpos, endpos; 1446 Lisp_Object startpos, endpos;
1414 EMACS_INT start, end; 1447 EMACS_INT start, end;
@@ -1434,7 +1467,8 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1434 rightmost character on a line that is 1467 rightmost character on a line that is
1435 continued or word-wrapped. */ 1468 continued or word-wrapped. */
1436 if (it3.method == GET_FROM_BUFFER 1469 if (it3.method == GET_FROM_BUFFER
1437 && it3.c == '\n') 1470 && (it3.c == '\n'
1471 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1438 move_it_by_lines (&it3, 1); 1472 move_it_by_lines (&it3, 1);
1439 else if (move_it_in_display_line_to (&it3, -1, 1473 else if (move_it_in_display_line_to (&it3, -1,
1440 it3.current_x 1474 it3.current_x
@@ -1502,6 +1536,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1502 produced from the string, until we find the 1536 produced from the string, until we find the
1503 rightmost glyph not from the string. */ 1537 rightmost glyph not from the string. */
1504 if (it3_moved 1538 if (it3_moved
1539 && newline_in_string
1505 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string)) 1540 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1506 { 1541 {
1507 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA] 1542 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
@@ -2677,7 +2712,7 @@ init_iterator (struct it *it, struct window *w,
2677 and IT->region_end_charpos to the start and end of a visible region 2712 and IT->region_end_charpos to the start and end of a visible region
2678 in window IT->w. Set both to -1 to indicate no region. */ 2713 in window IT->w. Set both to -1 to indicate no region. */
2679 markpos = markpos_of_region (); 2714 markpos = markpos_of_region ();
2680 if (0 <= markpos 2715 if (markpos >= 0
2681 /* Maybe highlight only in selected window. */ 2716 /* Maybe highlight only in selected window. */
2682 && (/* Either show region everywhere. */ 2717 && (/* Either show region everywhere. */
2683 highlight_nonselected_windows 2718 highlight_nonselected_windows
@@ -4458,7 +4493,7 @@ handle_display_prop (struct it *it)
4458 if it was a text property. */ 4493 if it was a text property. */
4459 4494
4460 if (!STRINGP (it->string)) 4495 if (!STRINGP (it->string))
4461 object = it->w->buffer; 4496 object = it->w->contents;
4462 4497
4463 display_replaced_p = handle_display_spec (it, propval, object, overlay, 4498 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4464 position, bufpos, 4499 position, bufpos,
@@ -4866,7 +4901,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4866 it->what = IT_IMAGE; 4901 it->what = IT_IMAGE;
4867 it->image_id = -1; /* no image */ 4902 it->image_id = -1; /* no image */
4868 it->position = start_pos; 4903 it->position = start_pos;
4869 it->object = NILP (object) ? it->w->buffer : object; 4904 it->object = NILP (object) ? it->w->contents : object;
4870 it->method = GET_FROM_IMAGE; 4905 it->method = GET_FROM_IMAGE;
4871 it->from_overlay = Qnil; 4906 it->from_overlay = Qnil;
4872 it->face_id = face_id; 4907 it->face_id = face_id;
@@ -5012,7 +5047,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
5012 it->what = IT_IMAGE; 5047 it->what = IT_IMAGE;
5013 it->image_id = lookup_image (it->f, value); 5048 it->image_id = lookup_image (it->f, value);
5014 it->position = start_pos; 5049 it->position = start_pos;
5015 it->object = NILP (object) ? it->w->buffer : object; 5050 it->object = NILP (object) ? it->w->contents : object;
5016 it->method = GET_FROM_IMAGE; 5051 it->method = GET_FROM_IMAGE;
5017 5052
5018 /* Say that we haven't consumed the characters with 5053 /* Say that we haven't consumed the characters with
@@ -5836,7 +5871,7 @@ pop_it (struct it *it)
5836 it->object = p->u.stretch.object; 5871 it->object = p->u.stretch.object;
5837 break; 5872 break;
5838 case GET_FROM_BUFFER: 5873 case GET_FROM_BUFFER:
5839 it->object = it->w->buffer; 5874 it->object = it->w->contents;
5840 break; 5875 break;
5841 case GET_FROM_STRING: 5876 case GET_FROM_STRING:
5842 it->object = it->string; 5877 it->object = it->string;
@@ -5849,7 +5884,7 @@ pop_it (struct it *it)
5849 else 5884 else
5850 { 5885 {
5851 it->method = GET_FROM_BUFFER; 5886 it->method = GET_FROM_BUFFER;
5852 it->object = it->w->buffer; 5887 it->object = it->w->contents;
5853 } 5888 }
5854 } 5889 }
5855 it->end_charpos = p->end_charpos; 5890 it->end_charpos = p->end_charpos;
@@ -6290,7 +6325,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6290 IT_STRING_BYTEPOS (*it) = -1; 6325 IT_STRING_BYTEPOS (*it) = -1;
6291 it->string = Qnil; 6326 it->string = Qnil;
6292 it->method = GET_FROM_BUFFER; 6327 it->method = GET_FROM_BUFFER;
6293 it->object = it->w->buffer; 6328 it->object = it->w->contents;
6294 it->area = TEXT_AREA; 6329 it->area = TEXT_AREA;
6295 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); 6330 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6296 it->sp = 0; 6331 it->sp = 0;
@@ -7141,7 +7176,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
7141 else 7176 else
7142 { 7177 {
7143 it->method = GET_FROM_BUFFER; 7178 it->method = GET_FROM_BUFFER;
7144 it->object = it->w->buffer; 7179 it->object = it->w->contents;
7145 } 7180 }
7146 7181
7147 it->dpvec = NULL; 7182 it->dpvec = NULL;
@@ -7153,6 +7188,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
7153 else if (it->dpvec_char_len > 0) 7188 else if (it->dpvec_char_len > 0)
7154 { 7189 {
7155 if (it->method == GET_FROM_STRING 7190 if (it->method == GET_FROM_STRING
7191 && it->current.overlay_string_index >= 0
7156 && it->n_overlay_strings > 0) 7192 && it->n_overlay_strings > 0)
7157 it->ignore_overlay_strings_at_pos_p = 1; 7193 it->ignore_overlay_strings_at_pos_p = 1;
7158 it->len = it->dpvec_char_len; 7194 it->len = it->dpvec_char_len;
@@ -7714,7 +7750,7 @@ next_element_from_ellipsis (struct it *it)
7714 setting face_before_selective_p. */ 7750 setting face_before_selective_p. */
7715 it->saved_face_id = it->face_id; 7751 it->saved_face_id = it->face_id;
7716 it->method = GET_FROM_BUFFER; 7752 it->method = GET_FROM_BUFFER;
7717 it->object = it->w->buffer; 7753 it->object = it->w->contents;
7718 reseat_at_next_visible_line_start (it, 1); 7754 reseat_at_next_visible_line_start (it, 1);
7719 it->face_before_selective_p = 1; 7755 it->face_before_selective_p = 1;
7720 } 7756 }
@@ -7978,7 +8014,7 @@ next_element_from_buffer (struct it *it)
7978 8014
7979 /* Record what we have and where it came from. */ 8015 /* Record what we have and where it came from. */
7980 it->what = IT_CHARACTER; 8016 it->what = IT_CHARACTER;
7981 it->object = it->w->buffer; 8017 it->object = it->w->contents;
7982 it->position = it->current.pos; 8018 it->position = it->current.pos;
7983 8019
7984 /* Normally we return the character found above, except when we 8020 /* Normally we return the character found above, except when we
@@ -8084,7 +8120,7 @@ next_element_from_composition (struct it *it)
8084 return 0; 8120 return 0;
8085 } 8121 }
8086 it->position = it->current.pos; 8122 it->position = it->current.pos;
8087 it->object = it->w->buffer; 8123 it->object = it->w->contents;
8088 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it), 8124 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8089 IT_BYTEPOS (*it), Qnil); 8125 IT_BYTEPOS (*it), Qnil);
8090 } 8126 }
@@ -8925,7 +8961,6 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
8925 it->current_y += it->max_ascent + it->max_descent; 8961 it->current_y += it->max_ascent + it->max_descent;
8926 ++it->vpos; 8962 ++it->vpos;
8927 last_height = it->max_ascent + it->max_descent; 8963 last_height = it->max_ascent + it->max_descent;
8928 last_max_ascent = it->max_ascent;
8929 it->max_ascent = it->max_descent = 0; 8964 it->max_ascent = it->max_descent = 0;
8930 } 8965 }
8931 8966
@@ -8952,7 +8987,6 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
8952 it->current_y += it->max_ascent + it->max_descent; 8987 it->current_y += it->max_ascent + it->max_descent;
8953 ++it->vpos; 8988 ++it->vpos;
8954 last_height = it->max_ascent + it->max_descent; 8989 last_height = it->max_ascent + it->max_descent;
8955 last_max_ascent = it->max_ascent;
8956 } 8990 }
8957 8991
8958 if (backup_data) 8992 if (backup_data)
@@ -9524,7 +9558,15 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9524 9558
9525 shown = buffer_window_count (current_buffer) > 0; 9559 shown = buffer_window_count (current_buffer) > 0;
9526 set_buffer_internal (oldbuf); 9560 set_buffer_internal (oldbuf);
9527 if (!shown) 9561 /* We called insert_1_both above with its 5th argument (PREPARE)
9562 zero, which prevents insert_1_both from calling
9563 prepare_to_modify_buffer, which in turns prevents us from
9564 incrementing windows_or_buffers_changed even if *Messages* is
9565 shown in some window. So we must manually incrementing
9566 windows_or_buffers_changed here to make up for that. */
9567 if (shown)
9568 windows_or_buffers_changed++;
9569 else
9528 windows_or_buffers_changed = old_windows_or_buffers_changed; 9570 windows_or_buffers_changed = old_windows_or_buffers_changed;
9529 message_log_need_newline = !nlflag; 9571 message_log_need_newline = !nlflag;
9530 Vdeactivate_mark = old_deactivate_mark; 9572 Vdeactivate_mark = old_deactivate_mark;
@@ -9994,7 +10036,7 @@ with_echo_area_buffer_unwind_data (struct window *w)
9994 Vwith_echo_area_save_vector = Qnil; 10036 Vwith_echo_area_save_vector = Qnil;
9995 10037
9996 if (NILP (vector)) 10038 if (NILP (vector))
9997 vector = Fmake_vector (make_number (7), Qnil); 10039 vector = Fmake_vector (make_number (9), Qnil);
9998 10040
9999 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i; 10041 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10000 ASET (vector, i, Vdeactivate_mark); ++i; 10042 ASET (vector, i, Vdeactivate_mark); ++i;
@@ -10003,13 +10045,15 @@ with_echo_area_buffer_unwind_data (struct window *w)
10003 if (w) 10045 if (w)
10004 { 10046 {
10005 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i; 10047 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10006 ASET (vector, i, w->buffer); ++i; 10048 ASET (vector, i, w->contents); ++i;
10007 ASET (vector, i, make_number (marker_position (w->pointm))); ++i; 10049 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10008 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i; 10050 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10051 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10052 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10009 } 10053 }
10010 else 10054 else
10011 { 10055 {
10012 int end = i + 4; 10056 int end = i + 6;
10013 for (; i < end; ++i) 10057 for (; i < end; ++i)
10014 ASET (vector, i, Qnil); 10058 ASET (vector, i, Qnil);
10015 } 10059 }
@@ -10032,16 +10076,18 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
10032 if (WINDOWP (AREF (vector, 3))) 10076 if (WINDOWP (AREF (vector, 3)))
10033 { 10077 {
10034 struct window *w; 10078 struct window *w;
10035 Lisp_Object buffer, charpos, bytepos; 10079 Lisp_Object buffer;
10036 10080
10037 w = XWINDOW (AREF (vector, 3)); 10081 w = XWINDOW (AREF (vector, 3));
10038 buffer = AREF (vector, 4); 10082 buffer = AREF (vector, 4);
10039 charpos = AREF (vector, 5);
10040 bytepos = AREF (vector, 6);
10041 10083
10042 wset_buffer (w, buffer); 10084 wset_buffer (w, buffer);
10043 set_marker_both (w->pointm, buffer, 10085 set_marker_both (w->pointm, buffer,
10044 XFASTINT (charpos), XFASTINT (bytepos)); 10086 XFASTINT (AREF (vector, 5)),
10087 XFASTINT (AREF (vector, 6)));
10088 set_marker_both (w->start, buffer,
10089 XFASTINT (AREF (vector, 7)),
10090 XFASTINT (AREF (vector, 8)));
10045 } 10091 }
10046 10092
10047 Vwith_echo_area_save_vector = vector; 10093 Vwith_echo_area_save_vector = vector;
@@ -10255,9 +10301,9 @@ resize_mini_window (struct window *w, int exact_p)
10255 eassert (MINI_WINDOW_P (w)); 10301 eassert (MINI_WINDOW_P (w));
10256 10302
10257 /* By default, start display at the beginning. */ 10303 /* By default, start display at the beginning. */
10258 set_marker_both (w->start, w->buffer, 10304 set_marker_both (w->start, w->contents,
10259 BUF_BEGV (XBUFFER (w->buffer)), 10305 BUF_BEGV (XBUFFER (w->contents)),
10260 BUF_BEGV_BYTE (XBUFFER (w->buffer))); 10306 BUF_BEGV_BYTE (XBUFFER (w->contents)));
10261 10307
10262 /* Don't resize windows while redisplaying a window; it would 10308 /* Don't resize windows while redisplaying a window; it would
10263 confuse redisplay functions when the size of the window they are 10309 confuse redisplay functions when the size of the window they are
@@ -10284,10 +10330,10 @@ resize_mini_window (struct window *w, int exact_p)
10284 struct text_pos start; 10330 struct text_pos start;
10285 struct buffer *old_current_buffer = NULL; 10331 struct buffer *old_current_buffer = NULL;
10286 10332
10287 if (current_buffer != XBUFFER (w->buffer)) 10333 if (current_buffer != XBUFFER (w->contents))
10288 { 10334 {
10289 old_current_buffer = current_buffer; 10335 old_current_buffer = current_buffer;
10290 set_buffer_internal (XBUFFER (w->buffer)); 10336 set_buffer_internal (XBUFFER (w->contents));
10291 } 10337 }
10292 10338
10293 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID); 10339 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
@@ -10736,7 +10782,7 @@ buffer_shared_and_changed (void)
10736 10782
10737/* Nonzero if W doesn't reflect the actual state of current buffer due 10783/* Nonzero if W doesn't reflect the actual state of current buffer due
10738 to its text or overlays change. FIXME: this may be called when 10784 to its text or overlays change. FIXME: this may be called when
10739 XBUFFER (w->buffer) != current_buffer, which looks suspicious. */ 10785 XBUFFER (w->contents) != current_buffer, which looks suspicious. */
10740 10786
10741static int 10787static int
10742window_outdated (struct window *w) 10788window_outdated (struct window *w)
@@ -10751,7 +10797,7 @@ window_outdated (struct window *w)
10751static int 10797static int
10752window_buffer_changed (struct window *w) 10798window_buffer_changed (struct window *w)
10753{ 10799{
10754 struct buffer *b = XBUFFER (w->buffer); 10800 struct buffer *b = XBUFFER (w->contents);
10755 10801
10756 eassert (BUFFER_LIVE_P (b)); 10802 eassert (BUFFER_LIVE_P (b));
10757 10803
@@ -11005,7 +11051,7 @@ x_consider_frame_title (Lisp_Object frame)
11005 11051
11006 Fselect_window (f->selected_window, Qt); 11052 Fselect_window (f->selected_window, Qt);
11007 set_buffer_internal_1 11053 set_buffer_internal_1
11008 (XBUFFER (XWINDOW (f->selected_window)->buffer)); 11054 (XBUFFER (XWINDOW (f->selected_window)->contents));
11009 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format; 11055 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11010 11056
11011 mode_line_target = MODE_LINE_TITLE; 11057 mode_line_target = MODE_LINE_TITLE;
@@ -11124,7 +11170,7 @@ prepare_menu_bars (void)
11124 if (windows_or_buffers_changed 11170 if (windows_or_buffers_changed
11125 && FRAME_NS_P (f)) 11171 && FRAME_NS_P (f))
11126 ns_set_doc_edited 11172 ns_set_doc_edited
11127 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer)); 11173 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->contents));
11128#endif 11174#endif
11129 UNGCPRO; 11175 UNGCPRO;
11130 } 11176 }
@@ -11196,7 +11242,7 @@ update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11196 11242
11197 specbind (Qinhibit_menubar_update, Qt); 11243 specbind (Qinhibit_menubar_update, Qt);
11198 11244
11199 set_buffer_internal_1 (XBUFFER (w->buffer)); 11245 set_buffer_internal_1 (XBUFFER (w->contents));
11200 if (save_match_data) 11246 if (save_match_data)
11201 record_unwind_save_match_data (); 11247 record_unwind_save_match_data ();
11202 if (NILP (Voverriding_local_map_menu_flag)) 11248 if (NILP (Voverriding_local_map_menu_flag))
@@ -11400,7 +11446,7 @@ update_tool_bar (struct frame *f, int save_match_data)
11400 /* Set current_buffer to the buffer of the selected 11446 /* Set current_buffer to the buffer of the selected
11401 window of the frame, so that we get the right local 11447 window of the frame, so that we get the right local
11402 keymaps. */ 11448 keymaps. */
11403 set_buffer_internal_1 (XBUFFER (w->buffer)); 11449 set_buffer_internal_1 (XBUFFER (w->contents));
11404 11450
11405 /* Save match data, if we must. */ 11451 /* Save match data, if we must. */
11406 if (save_match_data) 11452 if (save_match_data)
@@ -12267,10 +12313,8 @@ hscroll_window_tree (Lisp_Object window)
12267 { 12313 {
12268 struct window *w = XWINDOW (window); 12314 struct window *w = XWINDOW (window);
12269 12315
12270 if (WINDOWP (w->hchild)) 12316 if (WINDOWP (w->contents))
12271 hscrolled_p |= hscroll_window_tree (w->hchild); 12317 hscrolled_p |= hscroll_window_tree (w->contents);
12272 else if (WINDOWP (w->vchild))
12273 hscrolled_p |= hscroll_window_tree (w->vchild);
12274 else if (w->cursor.vpos >= 0) 12318 else if (w->cursor.vpos >= 0)
12275 { 12319 {
12276 int h_margin; 12320 int h_margin;
@@ -12290,7 +12334,7 @@ hscroll_window_tree (Lisp_Object window)
12290 /* Scroll when cursor is inside this scroll margin. */ 12334 /* Scroll when cursor is inside this scroll margin. */
12291 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w); 12335 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12292 12336
12293 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer)) 12337 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12294 /* For left-to-right rows, hscroll when cursor is either 12338 /* For left-to-right rows, hscroll when cursor is either
12295 (i) inside the right hscroll margin, or (ii) if it is 12339 (i) inside the right hscroll margin, or (ii) if it is
12296 inside the left margin and the window is already 12340 inside the left margin and the window is already
@@ -12325,7 +12369,7 @@ hscroll_window_tree (Lisp_Object window)
12325 12369
12326 /* Find point in a display of infinite width. */ 12370 /* Find point in a display of infinite width. */
12327 saved_current_buffer = current_buffer; 12371 saved_current_buffer = current_buffer;
12328 current_buffer = XBUFFER (w->buffer); 12372 current_buffer = XBUFFER (w->contents);
12329 12373
12330 if (w == XWINDOW (selected_window)) 12374 if (w == XWINDOW (selected_window))
12331 pt = PT; 12375 pt = PT;
@@ -12378,7 +12422,7 @@ hscroll_window_tree (Lisp_Object window)
12378 redisplay. */ 12422 redisplay. */
12379 if (w->hscroll != hscroll) 12423 if (w->hscroll != hscroll)
12380 { 12424 {
12381 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 12425 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
12382 w->hscroll = hscroll; 12426 w->hscroll = hscroll;
12383 hscrolled_p = 1; 12427 hscrolled_p = 1;
12384 } 12428 }
@@ -12467,9 +12511,9 @@ debug_method_add (struct window *w, char const *fmt, ...)
12467 if (trace_redisplay_p) 12511 if (trace_redisplay_p)
12468 fprintf (stderr, "%p (%s): %s\n", 12512 fprintf (stderr, "%p (%s): %s\n",
12469 w, 12513 w,
12470 ((BUFFERP (w->buffer) 12514 ((BUFFERP (w->contents)
12471 && STRINGP (BVAR (XBUFFER (w->buffer), name))) 12515 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12472 ? SSDATA (BVAR (XBUFFER (w->buffer), name)) 12516 ? SSDATA (BVAR (XBUFFER (w->contents), name))
12473 : "no buffer"), 12517 : "no buffer"),
12474 method + len); 12518 method + len);
12475} 12519}
@@ -12533,8 +12577,8 @@ text_outside_line_unchanged_p (struct window *w,
12533 require to redisplay the whole paragraph. It might be worthwhile 12577 require to redisplay the whole paragraph. It might be worthwhile
12534 to find the paragraph limits and widen the range of redisplayed 12578 to find the paragraph limits and widen the range of redisplayed
12535 lines to that, but for now just give up this optimization. */ 12579 lines to that, but for now just give up this optimization. */
12536 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)) 12580 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
12537 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction))) 12581 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
12538 unchanged_p = 0; 12582 unchanged_p = 0;
12539 } 12583 }
12540 12584
@@ -12757,7 +12801,7 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
12757 we set b->clip_changed to 1 to force updating the screen. If 12801 we set b->clip_changed to 1 to force updating the screen. If
12758 b->clip_changed has already been set to 1, we can skip this 12802 b->clip_changed has already been set to 1, we can skip this
12759 check. */ 12803 check. */
12760 if (!b->clip_changed && BUFFERP (w->buffer) && w->window_end_valid) 12804 if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid)
12761 { 12805 {
12762 ptrdiff_t pt; 12806 ptrdiff_t pt;
12763 12807
@@ -12766,11 +12810,11 @@ reconsider_clip_changes (struct window *w, struct buffer *b)
12766 else 12810 else
12767 pt = marker_position (w->pointm); 12811 pt = marker_position (w->pointm);
12768 12812
12769 if ((w->current_matrix->buffer != XBUFFER (w->buffer) 12813 if ((w->current_matrix->buffer != XBUFFER (w->contents)
12770 || pt != w->last_point) 12814 || pt != w->last_point)
12771 && check_point_in_composition (w->current_matrix->buffer, 12815 && check_point_in_composition (w->current_matrix->buffer,
12772 w->last_point, 12816 w->last_point,
12773 XBUFFER (w->buffer), pt)) 12817 XBUFFER (w->contents), pt))
12774 b->clip_changed = 1; 12818 b->clip_changed = 1;
12775 } 12819 }
12776} 12820}
@@ -12802,7 +12846,6 @@ redisplay_internal (void)
12802 struct frame *sf; 12846 struct frame *sf;
12803 int polling_stopped_here = 0; 12847 int polling_stopped_here = 0;
12804 Lisp_Object tail, frame; 12848 Lisp_Object tail, frame;
12805 struct backtrace backtrace;
12806 12849
12807 /* Non-zero means redisplay has to consider all windows on all 12850 /* Non-zero means redisplay has to consider all windows on all
12808 frames. Zero means, only selected_window is considered. */ 12851 frames. Zero means, only selected_window is considered. */
@@ -12846,12 +12889,7 @@ redisplay_internal (void)
12846 specbind (Qinhibit_free_realized_faces, Qnil); 12889 specbind (Qinhibit_free_realized_faces, Qnil);
12847 12890
12848 /* Record this function, so it appears on the profiler's backtraces. */ 12891 /* Record this function, so it appears on the profiler's backtraces. */
12849 backtrace.next = backtrace_list; 12892 record_in_backtrace (Qredisplay_internal, &Qnil, 0);
12850 backtrace.function = Qredisplay_internal;
12851 backtrace.args = &Qnil;
12852 backtrace.nargs = 0;
12853 backtrace.debug_on_exit = 0;
12854 backtrace_list = &backtrace;
12855 12893
12856 FOR_EACH_FRAME (tail, frame) 12894 FOR_EACH_FRAME (tail, frame)
12857 XFRAME (frame)->already_hscrolled_p = 0; 12895 XFRAME (frame)->already_hscrolled_p = 0;
@@ -12948,8 +12986,6 @@ redisplay_internal (void)
12948 12986
12949 unbind_to (count1, Qnil); 12987 unbind_to (count1, Qnil);
12950 12988
12951 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
12952
12953 consider_all_windows_p = (update_mode_lines 12989 consider_all_windows_p = (update_mode_lines
12954 || buffer_shared_and_changed () 12990 || buffer_shared_and_changed ()
12955 || cursor_type_changed); 12991 || cursor_type_changed);
@@ -13025,11 +13061,11 @@ redisplay_internal (void)
13025 the whole window. The assignment to this_line_start_pos prevents 13061 the whole window. The assignment to this_line_start_pos prevents
13026 the optimization directly below this if-statement. */ 13062 the optimization directly below this if-statement. */
13027 if (((!NILP (Vtransient_mark_mode) 13063 if (((!NILP (Vtransient_mark_mode)
13028 && !NILP (BVAR (XBUFFER (w->buffer), mark_active))) 13064 && !NILP (BVAR (XBUFFER (w->contents), mark_active)))
13029 != (w->region_showing > 0)) 13065 != (w->region_showing > 0))
13030 || (w->region_showing 13066 || (w->region_showing
13031 && w->region_showing 13067 && w->region_showing
13032 != XINT (Fmarker_position (BVAR (XBUFFER (w->buffer), mark))))) 13068 != XINT (Fmarker_position (BVAR (XBUFFER (w->contents), mark)))))
13033 CHARPOS (this_line_start_pos) = 0; 13069 CHARPOS (this_line_start_pos) = 0;
13034 13070
13035 /* Optimize the case that only the line containing the cursor in the 13071 /* Optimize the case that only the line containing the cursor in the
@@ -13047,7 +13083,7 @@ redisplay_internal (void)
13047 && !FRAME_OBSCURED_P (XFRAME (w->frame)) 13083 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13048 /* Make sure recorded data applies to current buffer, etc. */ 13084 /* Make sure recorded data applies to current buffer, etc. */
13049 && this_line_buffer == current_buffer 13085 && this_line_buffer == current_buffer
13050 && current_buffer == XBUFFER (w->buffer) 13086 && current_buffer == XBUFFER (w->contents)
13051 && !w->force_start 13087 && !w->force_start
13052 && !w->optional_new_start 13088 && !w->optional_new_start
13053 /* Point must be on the line that we have info recorded about. */ 13089 /* Point must be on the line that we have info recorded about. */
@@ -13171,7 +13207,7 @@ redisplay_internal (void)
13171 /* Make sure the cursor was last displayed 13207 /* Make sure the cursor was last displayed
13172 in this window. Otherwise we have to reposition it. */ 13208 in this window. Otherwise we have to reposition it. */
13173 && 0 <= w->cursor.vpos 13209 && 0 <= w->cursor.vpos
13174 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos) 13210 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13175 { 13211 {
13176 if (!must_finish) 13212 if (!must_finish)
13177 { 13213 {
@@ -13338,7 +13374,7 @@ redisplay_internal (void)
13338 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf); 13374 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13339 struct frame *mini_frame; 13375 struct frame *mini_frame;
13340 13376
13341 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer); 13377 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
13342 /* Use list_of_error, not Qerror, so that 13378 /* Use list_of_error, not Qerror, so that
13343 we catch only errors and don't run the debugger. */ 13379 we catch only errors and don't run the debugger. */
13344 internal_condition_case_1 (redisplay_window_1, selected_window, 13380 internal_condition_case_1 (redisplay_window_1, selected_window,
@@ -13490,7 +13526,6 @@ redisplay_internal (void)
13490#endif /* HAVE_WINDOW_SYSTEM */ 13526#endif /* HAVE_WINDOW_SYSTEM */
13491 13527
13492 end_of_redisplay: 13528 end_of_redisplay:
13493 backtrace_list = backtrace.next;
13494 unbind_to (count, Qnil); 13529 unbind_to (count, Qnil);
13495 RESUME_POLLING; 13530 RESUME_POLLING;
13496} 13531}
@@ -13548,7 +13583,7 @@ unwind_redisplay (Lisp_Object old_frame)
13548static void 13583static void
13549mark_window_display_accurate_1 (struct window *w, int accurate_p) 13584mark_window_display_accurate_1 (struct window *w, int accurate_p)
13550{ 13585{
13551 struct buffer *b = XBUFFER (w->buffer); 13586 struct buffer *b = XBUFFER (w->contents);
13552 13587
13553 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0; 13588 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
13554 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0; 13589 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
@@ -13595,11 +13630,9 @@ mark_window_display_accurate (Lisp_Object window, int accurate_p)
13595 for (; !NILP (window); window = w->next) 13630 for (; !NILP (window); window = w->next)
13596 { 13631 {
13597 w = XWINDOW (window); 13632 w = XWINDOW (window);
13598 if (!NILP (w->vchild)) 13633 if (WINDOWP (w->contents))
13599 mark_window_display_accurate (w->vchild, accurate_p); 13634 mark_window_display_accurate (w->contents, accurate_p);
13600 else if (!NILP (w->hchild)) 13635 else
13601 mark_window_display_accurate (w->hchild, accurate_p);
13602 else if (BUFFERP (w->buffer))
13603 mark_window_display_accurate_1 (w, accurate_p); 13636 mark_window_display_accurate_1 (w, accurate_p);
13604 } 13637 }
13605 13638
@@ -13656,13 +13689,11 @@ redisplay_windows (Lisp_Object window)
13656 { 13689 {
13657 struct window *w = XWINDOW (window); 13690 struct window *w = XWINDOW (window);
13658 13691
13659 if (!NILP (w->hchild)) 13692 if (WINDOWP (w->contents))
13660 redisplay_windows (w->hchild); 13693 redisplay_windows (w->contents);
13661 else if (!NILP (w->vchild)) 13694 else if (BUFFERP (w->contents))
13662 redisplay_windows (w->vchild);
13663 else if (!NILP (w->buffer))
13664 { 13695 {
13665 displayed_buffer = XBUFFER (w->buffer); 13696 displayed_buffer = XBUFFER (w->contents);
13666 /* Use list_of_error, not Qerror, so that 13697 /* Use list_of_error, not Qerror, so that
13667 we catch only errors and don't run the debugger. */ 13698 we catch only errors and don't run the debugger. */
13668 internal_condition_case_1 (redisplay_window_0, window, 13699 internal_condition_case_1 (redisplay_window_0, window,
@@ -14309,7 +14340,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
14309 && !MATRIX_ROW_CONTINUATION_LINE_P (row) 14340 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14310 && row->x == 0) 14341 && row->x == 0)
14311 { 14342 {
14312 this_line_buffer = XBUFFER (w->buffer); 14343 this_line_buffer = XBUFFER (w->contents);
14313 14344
14314 CHARPOS (this_line_start_pos) 14345 CHARPOS (this_line_start_pos)
14315 = MATRIX_ROW_START_CHARPOS (row) + delta; 14346 = MATRIX_ROW_START_CHARPOS (row) + delta;
@@ -14345,7 +14376,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14345 struct window *w = XWINDOW (window); 14376 struct window *w = XWINDOW (window);
14346 SET_MARKER_FROM_TEXT_POS (w->start, startp); 14377 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14347 14378
14348 if (current_buffer != XBUFFER (w->buffer)) 14379 if (current_buffer != XBUFFER (w->contents))
14349 emacs_abort (); 14380 emacs_abort ();
14350 14381
14351 if (!NILP (Vwindow_scroll_functions)) 14382 if (!NILP (Vwindow_scroll_functions))
@@ -14354,7 +14385,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14354 make_number (CHARPOS (startp))); 14385 make_number (CHARPOS (startp)));
14355 SET_TEXT_POS_FROM_MARKER (startp, w->start); 14386 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14356 /* In case the hook functions switch buffers. */ 14387 /* In case the hook functions switch buffers. */
14357 set_buffer_internal (XBUFFER (w->buffer)); 14388 set_buffer_internal (XBUFFER (w->contents));
14358 } 14389 }
14359 14390
14360 return startp; 14391 return startp;
@@ -15005,7 +15036,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
15005 must_scroll = 1; 15036 must_scroll = 1;
15006 } 15037 }
15007 else if (rc != CURSOR_MOVEMENT_SUCCESS 15038 else if (rc != CURSOR_MOVEMENT_SUCCESS
15008 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))) 15039 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15009 { 15040 {
15010 struct glyph_row *row1; 15041 struct glyph_row *row1;
15011 15042
@@ -15068,7 +15099,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
15068 else if (scroll_p) 15099 else if (scroll_p)
15069 rc = CURSOR_MOVEMENT_MUST_SCROLL; 15100 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15070 else if (rc != CURSOR_MOVEMENT_SUCCESS 15101 else if (rc != CURSOR_MOVEMENT_SUCCESS
15071 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))) 15102 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
15072 { 15103 {
15073 /* With bidi-reordered rows, there could be more than 15104 /* With bidi-reordered rows, there could be more than
15074 one candidate row whose start and end positions 15105 one candidate row whose start and end positions
@@ -15175,7 +15206,7 @@ set_vertical_scroll_bar (struct window *w)
15175 || (w == XWINDOW (minibuf_window) 15206 || (w == XWINDOW (minibuf_window)
15176 && NILP (echo_area_buffer[0]))) 15207 && NILP (echo_area_buffer[0])))
15177 { 15208 {
15178 struct buffer *buf = XBUFFER (w->buffer); 15209 struct buffer *buf = XBUFFER (w->contents);
15179 whole = BUF_ZV (buf) - BUF_BEGV (buf); 15210 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15180 start = marker_position (w->start) - BUF_BEGV (buf); 15211 start = marker_position (w->start) - BUF_BEGV (buf);
15181 /* I don't think this is guaranteed to be right. For the 15212 /* I don't think this is guaranteed to be right. For the
@@ -15209,7 +15240,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15209{ 15240{
15210 struct window *w = XWINDOW (window); 15241 struct window *w = XWINDOW (window);
15211 struct frame *f = XFRAME (w->frame); 15242 struct frame *f = XFRAME (w->frame);
15212 struct buffer *buffer = XBUFFER (w->buffer); 15243 struct buffer *buffer = XBUFFER (w->contents);
15213 struct buffer *old = current_buffer; 15244 struct buffer *old = current_buffer;
15214 struct text_pos lpoint, opoint, startp; 15245 struct text_pos lpoint, opoint, startp;
15215 int update_mode_line; 15246 int update_mode_line;
@@ -15231,12 +15262,14 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15231 SET_TEXT_POS (lpoint, PT, PT_BYTE); 15262 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15232 opoint = lpoint; 15263 opoint = lpoint;
15233 15264
15234 /* W must be a leaf window here. */
15235 eassert (!NILP (w->buffer));
15236#ifdef GLYPH_DEBUG 15265#ifdef GLYPH_DEBUG
15237 *w->desired_matrix->method = 0; 15266 *w->desired_matrix->method = 0;
15238#endif 15267#endif
15239 15268
15269 /* Make sure that both W's markers are valid. */
15270 eassert (XMARKER (w->start)->buffer == buffer);
15271 eassert (XMARKER (w->pointm)->buffer == buffer);
15272
15240 restart: 15273 restart:
15241 reconsider_clip_changes (w, buffer); 15274 reconsider_clip_changes (w, buffer);
15242 15275
@@ -15262,10 +15295,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15262 else if ((w != XWINDOW (minibuf_window) 15295 else if ((w != XWINDOW (minibuf_window)
15263 || minibuf_level == 0) 15296 || minibuf_level == 0)
15264 /* When buffer is nonempty, redisplay window normally. */ 15297 /* When buffer is nonempty, redisplay window normally. */
15265 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer)) 15298 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
15266 /* Quail displays non-mini buffers in minibuffer window. 15299 /* Quail displays non-mini buffers in minibuffer window.
15267 In that case, redisplay the window normally. */ 15300 In that case, redisplay the window normally. */
15268 && !NILP (Fmemq (w->buffer, Vminibuffer_list))) 15301 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
15269 { 15302 {
15270 /* W is a mini-buffer window, but it's not active, so clear 15303 /* W is a mini-buffer window, but it's not active, so clear
15271 it. */ 15304 it. */
@@ -15287,7 +15320,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15287 value. */ 15320 value. */
15288 /* Really select the buffer, for the sake of buffer-local 15321 /* Really select the buffer, for the sake of buffer-local
15289 variables. */ 15322 variables. */
15290 set_buffer_internal_1 (XBUFFER (w->buffer)); 15323 set_buffer_internal_1 (XBUFFER (w->contents));
15291 15324
15292 current_matrix_up_to_date_p 15325 current_matrix_up_to_date_p
15293 = (w->window_end_valid 15326 = (w->window_end_valid
@@ -15520,7 +15553,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15520 15553
15521 /* If we are highlighting the region, then we just changed 15554 /* If we are highlighting the region, then we just changed
15522 the region, so redisplay to show it. */ 15555 the region, so redisplay to show it. */
15523 if (0 <= markpos_of_region ()) 15556 if (markpos_of_region () >= 0)
15524 { 15557 {
15525 clear_glyph_matrix (w->desired_matrix); 15558 clear_glyph_matrix (w->desired_matrix);
15526 if (!try_window (window, startp, 0)) 15559 if (!try_window (window, startp, 0))
@@ -16221,7 +16254,7 @@ try_window_reusing_current_matrix (struct window *w)
16221 return 0; 16254 return 0;
16222 16255
16223 /* Can't do this if region may have changed. */ 16256 /* Can't do this if region may have changed. */
16224 if (0 <= markpos_of_region () 16257 if (markpos_of_region () >= 0
16225 || w->region_showing 16258 || w->region_showing
16226 || !NILP (Vshow_trailing_whitespace)) 16259 || !NILP (Vshow_trailing_whitespace))
16227 return 0; 16260 return 0;
@@ -16578,7 +16611,7 @@ try_window_reusing_current_matrix (struct window *w)
16578 bidi-reordered glyph rows. Let set_cursor_from_row 16611 bidi-reordered glyph rows. Let set_cursor_from_row
16579 figure out where to put the cursor, and if it fails, 16612 figure out where to put the cursor, and if it fails,
16580 give up. */ 16613 give up. */
16581 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))) 16614 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16582 { 16615 {
16583 if (!set_cursor_from_row (w, row, w->current_matrix, 16616 if (!set_cursor_from_row (w, row, w->current_matrix,
16584 0, 0, 0, 0)) 16617 0, 0, 0, 0))
@@ -16829,7 +16862,7 @@ sync_frame_with_window_matrix_rows (struct window *w)
16829 16862
16830 /* Preconditions: W must be a leaf window and full-width. Its frame 16863 /* Preconditions: W must be a leaf window and full-width. Its frame
16831 must have a frame matrix. */ 16864 must have a frame matrix. */
16832 eassert (NILP (w->hchild) && NILP (w->vchild)); 16865 eassert (BUFFERP (w->contents));
16833 eassert (WINDOW_FULL_WIDTH_P (w)); 16866 eassert (WINDOW_FULL_WIDTH_P (w));
16834 eassert (!FRAME_WINDOW_P (f)); 16867 eassert (!FRAME_WINDOW_P (f));
16835 16868
@@ -16871,7 +16904,7 @@ row_containing_pos (struct window *w, ptrdiff_t charpos,
16871{ 16904{
16872 struct glyph_row *row = start; 16905 struct glyph_row *row = start;
16873 struct glyph_row *best_row = NULL; 16906 struct glyph_row *best_row = NULL;
16874 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->buffer)) + 1; 16907 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
16875 int last_y; 16908 int last_y;
16876 16909
16877 /* If we happen to start on a header-line, skip that. */ 16910 /* If we happen to start on a header-line, skip that. */
@@ -16899,21 +16932,20 @@ row_containing_pos (struct window *w, ptrdiff_t charpos,
16899 || (MATRIX_ROW_END_CHARPOS (row) == charpos 16932 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16900 /* The end position of a row equals the start 16933 /* The end position of a row equals the start
16901 position of the next row. If CHARPOS is there, we 16934 position of the next row. If CHARPOS is there, we
16902 would rather display it in the next line, except 16935 would rather consider it displayed in the next
16903 when this line ends in ZV. */ 16936 line, except when this line ends in ZV. */
16904 && !row->ends_at_zv_p 16937 && !row_for_charpos_p (row, charpos)))
16905 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16906 && charpos >= MATRIX_ROW_START_CHARPOS (row)) 16938 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16907 { 16939 {
16908 struct glyph *g; 16940 struct glyph *g;
16909 16941
16910 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)) 16942 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
16911 || (!best_row && !row->continued_p)) 16943 || (!best_row && !row->continued_p))
16912 return row; 16944 return row;
16913 /* In bidi-reordered rows, there could be several rows 16945 /* In bidi-reordered rows, there could be several rows whose
16914 occluding point, all of them belonging to the same 16946 edges surround CHARPOS, all of these rows belonging to
16915 continued line. We need to find the row which fits 16947 the same continued line. We need to find the row which
16916 CHARPOS the best. */ 16948 fits CHARPOS the best. */
16917 for (g = row->glyphs[TEXT_AREA]; 16949 for (g = row->glyphs[TEXT_AREA];
16918 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; 16950 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16919 g++) 16951 g++)
@@ -17053,7 +17085,7 @@ try_window_id (struct window *w)
17053 17085
17054 /* Can't use this if highlighting a region because a cursor movement 17086 /* Can't use this if highlighting a region because a cursor movement
17055 will do more than just set the cursor. */ 17087 will do more than just set the cursor. */
17056 if (0 <= markpos_of_region ()) 17088 if (markpos_of_region () >= 0)
17057 GIVE_UP (9); 17089 GIVE_UP (9);
17058 17090
17059 /* Likewise if highlighting trailing whitespace. */ 17091 /* Likewise if highlighting trailing whitespace. */
@@ -17073,7 +17105,7 @@ try_window_id (struct window *w)
17073 wrapped line can change the wrap position, altering the line 17105 wrapped line can change the wrap position, altering the line
17074 above it. It might be worthwhile to handle this more 17106 above it. It might be worthwhile to handle this more
17075 intelligently, but for now just redisplay from scratch. */ 17107 intelligently, but for now just redisplay from scratch. */
17076 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap))) 17108 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
17077 GIVE_UP (21); 17109 GIVE_UP (21);
17078 17110
17079 /* Under bidi reordering, adding or deleting a character in the 17111 /* Under bidi reordering, adding or deleting a character in the
@@ -17084,8 +17116,8 @@ try_window_id (struct window *w)
17084 to find the paragraph limits and widen the range of redisplayed 17116 to find the paragraph limits and widen the range of redisplayed
17085 lines to that, but for now just give up this optimization and 17117 lines to that, but for now just give up this optimization and
17086 redisplay from scratch. */ 17118 redisplay from scratch. */
17087 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)) 17119 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
17088 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction))) 17120 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
17089 GIVE_UP (22); 17121 GIVE_UP (22);
17090 17122
17091 /* Make sure beg_unchanged and end_unchanged are up to date. Do it 17123 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
@@ -17950,7 +17982,7 @@ glyphs in short form, otherwise show glyphs in long form. */)
17950 (Lisp_Object glyphs) 17982 (Lisp_Object glyphs)
17951{ 17983{
17952 struct window *w = XWINDOW (selected_window); 17984 struct window *w = XWINDOW (selected_window);
17953 struct buffer *buffer = XBUFFER (w->buffer); 17985 struct buffer *buffer = XBUFFER (w->contents);
17954 17986
17955 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n", 17987 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
17956 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer)); 17988 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
@@ -18056,7 +18088,7 @@ static struct glyph_row *
18056get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string) 18088get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18057{ 18089{
18058 struct frame *f = XFRAME (WINDOW_FRAME (w)); 18090 struct frame *f = XFRAME (WINDOW_FRAME (w));
18059 struct buffer *buffer = XBUFFER (w->buffer); 18091 struct buffer *buffer = XBUFFER (w->contents);
18060 struct buffer *old = current_buffer; 18092 struct buffer *old = current_buffer;
18061 const unsigned char *arrow_string = SDATA (overlay_arrow_string); 18093 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18062 int arrow_len = SCHARS (overlay_arrow_string); 18094 int arrow_len = SCHARS (overlay_arrow_string);
@@ -18717,15 +18749,15 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18717 18749
18718 18750
18719/* Value is non-zero if glyph row ROW should be 18751/* Value is non-zero if glyph row ROW should be
18720 used to hold the cursor. */ 18752 considered to hold the buffer position CHARPOS. */
18721 18753
18722static int 18754static int
18723cursor_row_p (struct glyph_row *row) 18755row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
18724{ 18756{
18725 int result = 1; 18757 int result = 1;
18726 18758
18727 if (PT == CHARPOS (row->end.pos) 18759 if (charpos == CHARPOS (row->end.pos)
18728 || PT == MATRIX_ROW_END_CHARPOS (row)) 18760 || charpos == MATRIX_ROW_END_CHARPOS (row))
18729 { 18761 {
18730 /* Suppose the row ends on a string. 18762 /* Suppose the row ends on a string.
18731 Unless the row is continued, that means it ends on a newline 18763 Unless the row is continued, that means it ends on a newline
@@ -18751,7 +18783,7 @@ cursor_row_p (struct glyph_row *row)
18751 if (STRINGP (glyph->object)) 18783 if (STRINGP (glyph->object))
18752 { 18784 {
18753 Lisp_Object prop 18785 Lisp_Object prop
18754 = Fget_char_property (make_number (PT), 18786 = Fget_char_property (make_number (charpos),
18755 Qdisplay, Qnil); 18787 Qdisplay, Qnil);
18756 result = 18788 result =
18757 (!NILP (prop) 18789 (!NILP (prop)
@@ -18805,6 +18837,15 @@ cursor_row_p (struct glyph_row *row)
18805 return result; 18837 return result;
18806} 18838}
18807 18839
18840/* Value is non-zero if glyph row ROW should be
18841 used to hold the cursor. */
18842
18843static int
18844cursor_row_p (struct glyph_row *row)
18845{
18846 return row_for_charpos_p (row, PT);
18847}
18848
18808 18849
18809 18850
18810/* Push the property PROP so that it will be rendered at the current 18851/* Push the property PROP so that it will be rendered at the current
@@ -19263,7 +19304,7 @@ display_line (struct it *it)
19263 row->glyphs[TEXT_AREA]->charpos = -1; 19304 row->glyphs[TEXT_AREA]->charpos = -1;
19264 row->displays_text_p = 0; 19305 row->displays_text_p = 0;
19265 19306
19266 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines)) 19307 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
19267 && (!MINI_WINDOW_P (it->w) 19308 && (!MINI_WINDOW_P (it->w)
19268 || (minibuf_level && EQ (it->window, minibuf_window)))) 19309 || (minibuf_level && EQ (it->window, minibuf_window))))
19269 row->indicate_empty_line_p = 1; 19310 row->indicate_empty_line_p = 1;
@@ -19988,18 +20029,17 @@ display_menu_bar (struct window *w)
19988 return; 20029 return;
19989#endif /* HAVE_NS */ 20030#endif /* HAVE_NS */
19990 20031
19991#ifdef USE_X_TOOLKIT 20032#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
19992 eassert (!FRAME_WINDOW_P (f)); 20033 eassert (!FRAME_WINDOW_P (f));
19993 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID); 20034 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
19994 it.first_visible_x = 0; 20035 it.first_visible_x = 0;
19995 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 20036 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19996#else /* not USE_X_TOOLKIT */ 20037#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
19997 if (FRAME_WINDOW_P (f)) 20038 if (FRAME_WINDOW_P (f))
19998 { 20039 {
19999 /* Menu bar lines are displayed in the desired matrix of the 20040 /* Menu bar lines are displayed in the desired matrix of the
20000 dummy window menu_bar_window. */ 20041 dummy window menu_bar_window. */
20001 struct window *menu_w; 20042 struct window *menu_w;
20002 eassert (WINDOWP (f->menu_bar_window));
20003 menu_w = XWINDOW (f->menu_bar_window); 20043 menu_w = XWINDOW (f->menu_bar_window);
20004 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows, 20044 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20005 MENU_FACE_ID); 20045 MENU_FACE_ID);
@@ -20007,6 +20047,7 @@ display_menu_bar (struct window *w)
20007 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 20047 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20008 } 20048 }
20009 else 20049 else
20050#endif /* not USE_X_TOOLKIT and not USE_GTK */
20010 { 20051 {
20011 /* This is a TTY frame, i.e. character hpos/vpos are used as 20052 /* This is a TTY frame, i.e. character hpos/vpos are used as
20012 pixel x/y. */ 20053 pixel x/y. */
@@ -20015,7 +20056,6 @@ display_menu_bar (struct window *w)
20015 it.first_visible_x = 0; 20056 it.first_visible_x = 0;
20016 it.last_visible_x = FRAME_COLS (f); 20057 it.last_visible_x = FRAME_COLS (f);
20017 } 20058 }
20018#endif /* not USE_X_TOOLKIT */
20019 20059
20020 /* FIXME: This should be controlled by a user option. See the 20060 /* FIXME: This should be controlled by a user option. See the
20021 comments in redisplay_tool_bar and display_mode_line about 20061 comments in redisplay_tool_bar and display_mode_line about
@@ -20079,10 +20119,8 @@ redisplay_mode_lines (Lisp_Object window, int force)
20079 { 20119 {
20080 struct window *w = XWINDOW (window); 20120 struct window *w = XWINDOW (window);
20081 20121
20082 if (WINDOWP (w->hchild)) 20122 if (WINDOWP (w->contents))
20083 nwindows += redisplay_mode_lines (w->hchild, force); 20123 nwindows += redisplay_mode_lines (w->contents, force);
20084 else if (WINDOWP (w->vchild))
20085 nwindows += redisplay_mode_lines (w->vchild, force);
20086 else if (force 20124 else if (force
20087 || FRAME_GARBAGED_P (XFRAME (w->frame)) 20125 || FRAME_GARBAGED_P (XFRAME (w->frame))
20088 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p) 20126 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
@@ -20092,7 +20130,7 @@ redisplay_mode_lines (Lisp_Object window, int force)
20092 20130
20093 /* Set the window's buffer for the mode line display. */ 20131 /* Set the window's buffer for the mode line display. */
20094 SET_TEXT_POS (lpoint, PT, PT_BYTE); 20132 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20095 set_buffer_internal_1 (XBUFFER (w->buffer)); 20133 set_buffer_internal_1 (XBUFFER (w->contents));
20096 20134
20097 /* Point refers normally to the selected window. For any 20135 /* Point refers normally to the selected window. For any
20098 other window, set up appropriate value. */ 20136 other window, set up appropriate value. */
@@ -20874,7 +20912,7 @@ are the selected window and the WINDOW's buffer). */)
20874 XSETWINDOW (window, w); 20912 XSETWINDOW (window, w);
20875 20913
20876 if (NILP (buffer)) 20914 if (NILP (buffer))
20877 buffer = w->buffer; 20915 buffer = w->contents;
20878 CHECK_BUFFER (buffer); 20916 CHECK_BUFFER (buffer);
20879 20917
20880 /* Make formatting the modeline a non-op when noninteractive, otherwise 20918 /* Make formatting the modeline a non-op when noninteractive, otherwise
@@ -21009,7 +21047,7 @@ pint2hrstr (char *buf, int width, ptrdiff_t d)
21009 char * psuffix; 21047 char * psuffix;
21010 char * p; 21048 char * p;
21011 21049
21012 if (1000 <= quotient) 21050 if (quotient >= 1000)
21013 { 21051 {
21014 /* Scale to the appropriate EXPONENT. */ 21052 /* Scale to the appropriate EXPONENT. */
21015 do 21053 do
@@ -21018,13 +21056,13 @@ pint2hrstr (char *buf, int width, ptrdiff_t d)
21018 quotient /= 1000; 21056 quotient /= 1000;
21019 exponent++; 21057 exponent++;
21020 } 21058 }
21021 while (1000 <= quotient); 21059 while (quotient >= 1000);
21022 21060
21023 /* Round to nearest and decide whether to use TENTHS or not. */ 21061 /* Round to nearest and decide whether to use TENTHS or not. */
21024 if (quotient <= 9) 21062 if (quotient <= 9)
21025 { 21063 {
21026 tenths = remainder / 100; 21064 tenths = remainder / 100;
21027 if (50 <= remainder % 100) 21065 if (remainder % 100 >= 50)
21028 { 21066 {
21029 if (tenths < 9) 21067 if (tenths < 9)
21030 tenths++; 21068 tenths++;
@@ -21039,7 +21077,7 @@ pint2hrstr (char *buf, int width, ptrdiff_t d)
21039 } 21077 }
21040 } 21078 }
21041 else 21079 else
21042 if (500 <= remainder) 21080 if (remainder >= 500)
21043 { 21081 {
21044 if (quotient < 999) 21082 if (quotient < 999)
21045 quotient++; 21083 quotient++;
@@ -22082,11 +22120,6 @@ else if the text is replaced by an ellipsis. */)
22082 22120
22083*/ 22121*/
22084 22122
22085#define NUMVAL(X) \
22086 ((INTEGERP (X) || FLOATP (X)) \
22087 ? XFLOATINT (X) \
22088 : - 1)
22089
22090static int 22123static int
22091calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop, 22124calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22092 struct font *font, int width_p, int *align_to) 22125 struct font *font, int width_p, int *align_to)
@@ -22117,24 +22150,11 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22117 pixels = 0; 22150 pixels = 0;
22118 if (pixels > 0) 22151 if (pixels > 0)
22119 { 22152 {
22120 double ppi; 22153 double ppi = (width_p ? FRAME_RES_X (it->f)
22121#ifdef HAVE_WINDOW_SYSTEM 22154 : FRAME_RES_Y (it->f));
22122 if (FRAME_WINDOW_P (it->f)
22123 && (ppi = (width_p
22124 ? FRAME_X_DISPLAY_INFO (it->f)->resx
22125 : FRAME_X_DISPLAY_INFO (it->f)->resy),
22126 ppi > 0))
22127 return OK_PIXELS (ppi / pixels);
22128#endif
22129 22155
22130 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0) 22156 if (ppi > 0)
22131 || (CONSP (Vdisplay_pixels_per_inch)
22132 && (ppi = (width_p
22133 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
22134 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
22135 ppi > 0)))
22136 return OK_PIXELS (ppi / pixels); 22157 return OK_PIXELS (ppi / pixels);
22137
22138 return 0; 22158 return 0;
22139 } 22159 }
22140 } 22160 }
@@ -22198,7 +22218,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22198 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)); 22218 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22199 } 22219 }
22200 22220
22201 prop = buffer_local_value_1 (prop, it->w->buffer); 22221 prop = buffer_local_value_1 (prop, it->w->contents);
22202 if (EQ (prop, Qunbound)) 22222 if (EQ (prop, Qunbound))
22203 prop = Qnil; 22223 prop = Qnil;
22204 } 22224 }
@@ -22250,7 +22270,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22250 return OK_PIXELS (pixels); 22270 return OK_PIXELS (pixels);
22251 } 22271 }
22252 22272
22253 car = buffer_local_value_1 (car, it->w->buffer); 22273 car = buffer_local_value_1 (car, it->w->contents);
22254 if (EQ (car, Qunbound)) 22274 if (EQ (car, Qunbound))
22255 car = Qnil; 22275 car = Qnil;
22256 } 22276 }
@@ -22410,16 +22430,16 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id,
22410 XChar2b *char2b, int display_p) 22430 XChar2b *char2b, int display_p)
22411{ 22431{
22412 struct face *face = FACE_FROM_ID (f, face_id); 22432 struct face *face = FACE_FROM_ID (f, face_id);
22433 unsigned code = 0;
22413 22434
22414 if (face->font) 22435 if (face->font)
22415 { 22436 {
22416 unsigned code = face->font->driver->encode_char (face->font, c); 22437 code = face->font->driver->encode_char (face->font, c);
22417 22438
22418 if (code != FONT_INVALID_CODE) 22439 if (code == FONT_INVALID_CODE)
22419 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); 22440 code = 0;
22420 else
22421 STORE_XCHAR2B (char2b, 0, 0);
22422 } 22441 }
22442 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22423 22443
22424 /* Make sure X resources of the face are allocated. */ 22444 /* Make sure X resources of the face are allocated. */
22425#ifdef HAVE_X_WINDOWS 22445#ifdef HAVE_X_WINDOWS
@@ -22443,31 +22463,30 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22443 XChar2b *char2b, int *two_byte_p) 22463 XChar2b *char2b, int *two_byte_p)
22444{ 22464{
22445 struct face *face; 22465 struct face *face;
22466 unsigned code = 0;
22446 22467
22447 eassert (glyph->type == CHAR_GLYPH); 22468 eassert (glyph->type == CHAR_GLYPH);
22448 face = FACE_FROM_ID (f, glyph->face_id); 22469 face = FACE_FROM_ID (f, glyph->face_id);
22449 22470
22471 /* Make sure X resources of the face are allocated. */
22472 eassert (face != NULL);
22473 PREPARE_FACE_FOR_DISPLAY (f, face);
22474
22450 if (two_byte_p) 22475 if (two_byte_p)
22451 *two_byte_p = 0; 22476 *two_byte_p = 0;
22452 22477
22453 if (face->font) 22478 if (face->font)
22454 { 22479 {
22455 unsigned code;
22456
22457 if (CHAR_BYTE8_P (glyph->u.ch)) 22480 if (CHAR_BYTE8_P (glyph->u.ch))
22458 code = CHAR_TO_BYTE8 (glyph->u.ch); 22481 code = CHAR_TO_BYTE8 (glyph->u.ch);
22459 else 22482 else
22460 code = face->font->driver->encode_char (face->font, glyph->u.ch); 22483 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22461 22484
22462 if (code != FONT_INVALID_CODE) 22485 if (code == FONT_INVALID_CODE)
22463 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); 22486 code = 0;
22464 else
22465 STORE_XCHAR2B (char2b, 0, 0);
22466 } 22487 }
22467 22488
22468 /* Make sure X resources of the face are allocated. */ 22489 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22469 eassert (face != NULL);
22470 PREPARE_FACE_FOR_DISPLAY (f, face);
22471 return face; 22490 return face;
22472} 22491}
22473 22492
@@ -22777,9 +22796,12 @@ static struct font_metrics *
22777get_per_char_metric (struct font *font, XChar2b *char2b) 22796get_per_char_metric (struct font *font, XChar2b *char2b)
22778{ 22797{
22779 static struct font_metrics metrics; 22798 static struct font_metrics metrics;
22780 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b); 22799 unsigned code;
22781 22800
22782 if (! font || code == FONT_INVALID_CODE) 22801 if (! font)
22802 return NULL;
22803 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22804 if (code == FONT_INVALID_CODE)
22783 return NULL; 22805 return NULL;
22784 font->driver->text_extents (font, &code, 1, &metrics); 22806 font->driver->text_extents (font, &code, 1, &metrics);
22785 return &metrics; 22807 return &metrics;
@@ -24100,7 +24122,7 @@ produce_stretch_glyph (struct it *it)
24100 int n = width; 24122 int n = width;
24101 24123
24102 if (!STRINGP (object)) 24124 if (!STRINGP (object))
24103 object = it->w->buffer; 24125 object = it->w->contents;
24104#ifdef HAVE_WINDOW_SYSTEM 24126#ifdef HAVE_WINDOW_SYSTEM
24105 if (FRAME_WINDOW_P (it->f)) 24127 if (FRAME_WINDOW_P (it->f))
24106 append_stretch_glyph (it, object, width, height, ascent); 24128 append_stretch_glyph (it, object, width, height, ascent);
@@ -25496,7 +25518,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25496 int *active_cursor) 25518 int *active_cursor)
25497{ 25519{
25498 struct frame *f = XFRAME (w->frame); 25520 struct frame *f = XFRAME (w->frame);
25499 struct buffer *b = XBUFFER (w->buffer); 25521 struct buffer *b = XBUFFER (w->contents);
25500 int cursor_type = DEFAULT_CURSOR; 25522 int cursor_type = DEFAULT_CURSOR;
25501 Lisp_Object alt_cursor; 25523 Lisp_Object alt_cursor;
25502 int non_selected = 0; 25524 int non_selected = 0;
@@ -26047,10 +26069,8 @@ update_cursor_in_window_tree (struct window *w, int on_p)
26047{ 26069{
26048 while (w) 26070 while (w)
26049 { 26071 {
26050 if (!NILP (w->hchild)) 26072 if (WINDOWP (w->contents))
26051 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p); 26073 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
26052 else if (!NILP (w->vchild))
26053 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
26054 else 26074 else
26055 update_window_cursor (w, on_p); 26075 update_window_cursor (w, on_p);
26056 26076
@@ -27296,7 +27316,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27296 { 27316 {
27297 help_echo_string = help; 27317 help_echo_string = help;
27298 XSETWINDOW (help_echo_window, w); 27318 XSETWINDOW (help_echo_window, w);
27299 help_echo_object = w->buffer; 27319 help_echo_object = w->contents;
27300 help_echo_pos = charpos; 27320 help_echo_pos = charpos;
27301 } 27321 }
27302 } 27322 }
@@ -27332,7 +27352,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27332 { 27352 {
27333 Lisp_Object default_help 27353 Lisp_Object default_help
27334 = buffer_local_value_1 (Qmode_line_default_help_echo, 27354 = buffer_local_value_1 (Qmode_line_default_help_echo,
27335 w->buffer); 27355 w->contents);
27336 27356
27337 if (STRINGP (default_help)) 27357 if (STRINGP (default_help))
27338 { 27358 {
@@ -27607,7 +27627,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
27607 27627
27608 /* Are we in a window whose display is up to date? 27628 /* Are we in a window whose display is up to date?
27609 And verify the buffer's text has not changed. */ 27629 And verify the buffer's text has not changed. */
27610 b = XBUFFER (w->buffer); 27630 b = XBUFFER (w->contents);
27611 if (part == ON_TEXT 27631 if (part == ON_TEXT
27612 && w->window_end_valid 27632 && w->window_end_valid
27613 && w->last_modified == BUF_MODIFF (b) 27633 && w->last_modified == BUF_MODIFF (b)
@@ -27816,8 +27836,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
27816 if (pos > 0) 27836 if (pos > 0)
27817 { 27837 {
27818 mouse_face = get_char_property_and_overlay 27838 mouse_face = get_char_property_and_overlay
27819 (make_number (pos), Qmouse_face, w->buffer, &overlay); 27839 (make_number (pos), Qmouse_face, w->contents, &overlay);
27820 buffer = w->buffer; 27840 buffer = w->contents;
27821 disp_string = object; 27841 disp_string = object;
27822 } 27842 }
27823 } 27843 }
@@ -27930,11 +27950,11 @@ note_mouse_highlight (struct frame *f, int x, int y)
27930 if (p > 0) 27950 if (p > 0)
27931 { 27951 {
27932 help = Fget_char_property (make_number (p), 27952 help = Fget_char_property (make_number (p),
27933 Qhelp_echo, w->buffer); 27953 Qhelp_echo, w->contents);
27934 if (!NILP (help)) 27954 if (!NILP (help))
27935 { 27955 {
27936 charpos = p; 27956 charpos = p;
27937 obj = w->buffer; 27957 obj = w->contents;
27938 } 27958 }
27939 } 27959 }
27940 } 27960 }
@@ -27985,7 +28005,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
27985 ptrdiff_t p = string_buffer_position (obj, start); 28005 ptrdiff_t p = string_buffer_position (obj, start);
27986 if (p > 0) 28006 if (p > 0)
27987 pointer = Fget_char_property (make_number (p), 28007 pointer = Fget_char_property (make_number (p),
27988 Qpointer, w->buffer); 28008 Qpointer, w->contents);
27989 } 28009 }
27990 } 28010 }
27991 else if (BUFFERP (obj) 28011 else if (BUFFERP (obj)
@@ -28428,12 +28448,9 @@ expose_window_tree (struct window *w, XRectangle *r)
28428 28448
28429 while (w && !FRAME_GARBAGED_P (f)) 28449 while (w && !FRAME_GARBAGED_P (f))
28430 { 28450 {
28431 if (!NILP (w->hchild)) 28451 if (WINDOWP (w->contents))
28432 mouse_face_overwritten_p 28452 mouse_face_overwritten_p
28433 |= expose_window_tree (XWINDOW (w->hchild), r); 28453 |= expose_window_tree (XWINDOW (w->contents), r);
28434 else if (!NILP (w->vchild))
28435 mouse_face_overwritten_p
28436 |= expose_window_tree (XWINDOW (w->vchild), r);
28437 else 28454 else
28438 mouse_face_overwritten_p |= expose_window (w, r); 28455 mouse_face_overwritten_p |= expose_window (w, r);
28439 28456
@@ -28498,11 +28515,11 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
28498 28515
28499#ifdef HAVE_X_WINDOWS 28516#ifdef HAVE_X_WINDOWS
28500#ifndef MSDOS 28517#ifndef MSDOS
28501#ifndef USE_X_TOOLKIT 28518#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
28502 if (WINDOWP (f->menu_bar_window)) 28519 if (WINDOWP (f->menu_bar_window))
28503 mouse_face_overwritten_p 28520 mouse_face_overwritten_p
28504 |= expose_window (XWINDOW (f->menu_bar_window), &r); 28521 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28505#endif /* not USE_X_TOOLKIT */ 28522#endif /* not USE_X_TOOLKIT and not USE_GTK */
28506#endif 28523#endif
28507#endif 28524#endif
28508 28525
@@ -29236,13 +29253,13 @@ init_xdisp (void)
29236 29253
29237 echo_area_window = minibuf_window; 29254 echo_area_window = minibuf_window;
29238 29255
29239 wset_top_line (r, make_number (FRAME_TOP_MARGIN (f))); 29256 r->top_line = FRAME_TOP_MARGIN (f);
29240 wset_total_lines 29257 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
29241 (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f))); 29258 r->total_cols = FRAME_COLS (f);
29242 wset_total_cols (r, make_number (FRAME_COLS (f))); 29259
29243 wset_top_line (m, make_number (FRAME_LINES (f) - 1)); 29260 m->top_line = FRAME_LINES (f) - 1;
29244 wset_total_lines (m, make_number (1)); 29261 m->total_lines = 1;
29245 wset_total_cols (m, make_number (FRAME_COLS (f))); 29262 m->total_cols = FRAME_COLS (f);
29246 29263
29247 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs; 29264 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29248 scratch_glyph_row.glyphs[TEXT_AREA + 1] 29265 scratch_glyph_row.glyphs[TEXT_AREA + 1]
diff --git a/src/xfaces.c b/src/xfaces.c
index 71709446c1d..b2ace1be14e 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -112,7 +112,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
112 merging faces of that character, that face is `realized'. The 112 merging faces of that character, that face is `realized'. The
113 realization process maps face attributes to what is physically 113 realization process maps face attributes to what is physically
114 available on the system where Emacs runs. The result is a 114 available on the system where Emacs runs. The result is a
115 `realized face' in form of a struct face which is stored in the 115 `realized face' in the form of a struct face which is stored in the
116 face cache of the frame on which it was realized. 116 face cache of the frame on which it was realized.
117 117
118 Face realization is done in the context of the character to display 118 Face realization is done in the context of the character to display
@@ -231,7 +231,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
231#undef FRAME_X_DISPLAY_INFO 231#undef FRAME_X_DISPLAY_INFO
232#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO 232#define FRAME_X_DISPLAY_INFO FRAME_W32_DISPLAY_INFO
233#define x_display_info w32_display_info 233#define x_display_info w32_display_info
234#define check_x check_w32
235#define GCGraphicsExposures 0 234#define GCGraphicsExposures 0
236#endif /* HAVE_NTGUI */ 235#endif /* HAVE_NTGUI */
237 236
@@ -239,7 +238,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
239#undef FRAME_X_DISPLAY_INFO 238#undef FRAME_X_DISPLAY_INFO
240#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO 239#define FRAME_X_DISPLAY_INFO FRAME_NS_DISPLAY_INFO
241#define x_display_info ns_display_info 240#define x_display_info ns_display_info
242#define check_x check_ns
243#define GCGraphicsExposures 0 241#define GCGraphicsExposures 0
244#endif /* HAVE_NS */ 242#endif /* HAVE_NS */
245#endif /* HAVE_WINDOW_SYSTEM */ 243#endif /* HAVE_WINDOW_SYSTEM */
@@ -1592,7 +1590,7 @@ the face font sort order. */)
1592 ASET (v, 0, AREF (font, FONT_FAMILY_INDEX)); 1590 ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
1593 ASET (v, 1, FONT_WIDTH_SYMBOLIC (font)); 1591 ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
1594 point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10, 1592 point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
1595 XFRAME (frame)->resy); 1593 FRAME_RES_Y (XFRAME (frame)));
1596 ASET (v, 2, make_number (point)); 1594 ASET (v, 2, make_number (point));
1597 ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font)); 1595 ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
1598 ASET (v, 4, FONT_SLANT_SYMBOLIC (font)); 1596 ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
@@ -1636,7 +1634,7 @@ the WIDTH times as wide as FACE on FRAME. */)
1636 struct frame *f; 1634 struct frame *f;
1637 int size, avgwidth IF_LINT (= 0); 1635 int size, avgwidth IF_LINT (= 0);
1638 1636
1639 check_x (); 1637 check_window_system (NULL);
1640 CHECK_STRING (pattern); 1638 CHECK_STRING (pattern);
1641 1639
1642 if (! NILP (maximum)) 1640 if (! NILP (maximum))
@@ -1645,8 +1643,8 @@ the WIDTH times as wide as FACE on FRAME. */)
1645 if (!NILP (width)) 1643 if (!NILP (width))
1646 CHECK_NUMBER (width); 1644 CHECK_NUMBER (width);
1647 1645
1648 /* We can't simply call check_x_frame because this function may be 1646 /* We can't simply call decode_window_system_frame because
1649 called before any frame is created. */ 1647 this function may be called before any frame is created. */
1650 f = decode_live_frame (frame); 1648 f = decode_live_frame (frame);
1651 if (! FRAME_WINDOW_P (f)) 1649 if (! FRAME_WINDOW_P (f))
1652 { 1650 {
@@ -2118,7 +2116,7 @@ set_lface_from_font (struct frame *f, Lisp_Object lface,
2118 2116
2119 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface))) 2117 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
2120 { 2118 {
2121 int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy); 2119 int pt = PIXEL_TO_POINT (font->pixel_size * 10, FRAME_RES_Y (f));
2122 2120
2123 eassert (pt > 0); 2121 eassert (pt > 0);
2124 ASET (lface, LFACE_HEIGHT_INDEX, make_number (pt)); 2122 ASET (lface, LFACE_HEIGHT_INDEX, make_number (pt));
@@ -3395,21 +3393,22 @@ set_font_frame_param (Lisp_Object frame, Lisp_Object lface)
3395 } 3393 }
3396} 3394}
3397 3395
3398
3399/* Get the value of X resource RESOURCE, class CLASS for the display
3400 of frame FRAME. This is here because ordinary `x-get-resource'
3401 doesn't take a frame argument. */
3402
3403DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource, 3396DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
3404 Sinternal_face_x_get_resource, 3, 3, 0, doc: /* */) 3397 Sinternal_face_x_get_resource, 2, 3, 0,
3398 doc: /* Get the value of X resource RESOURCE, class CLASS.
3399Returned value is for the display of frame FRAME. If FRAME is not
3400specified or nil, use selected frame. This function exists because
3401ordinary `x-get-resource' doesn't take a frame argument. */)
3405 (Lisp_Object resource, Lisp_Object class, Lisp_Object frame) 3402 (Lisp_Object resource, Lisp_Object class, Lisp_Object frame)
3406{ 3403{
3407 Lisp_Object value = Qnil; 3404 Lisp_Object value = Qnil;
3405 struct frame *f;
3406
3408 CHECK_STRING (resource); 3407 CHECK_STRING (resource);
3409 CHECK_STRING (class); 3408 CHECK_STRING (class);
3410 CHECK_LIVE_FRAME (frame); 3409 f = decode_live_frame (frame);
3411 block_input (); 3410 block_input ();
3412 value = display_x_get_resource (FRAME_X_DISPLAY_INFO (XFRAME (frame)), 3411 value = display_x_get_resource (FRAME_X_DISPLAY_INFO (f),
3413 resource, class, Qnil, Qnil); 3412 resource, class, Qnil, Qnil);
3414 unblock_input (); 3413 unblock_input ();
3415 return value; 3414 return value;
@@ -3924,8 +3923,8 @@ If FRAME is omitted or nil, use the selected frame. */)
3924 struct frame *f; 3923 struct frame *f;
3925 Lisp_Object lface1, lface2; 3924 Lisp_Object lface1, lface2;
3926 3925
3927 /* Don't use check_x_frame here because this function is called 3926 /* Don't use decode_window_system_frame here because this function
3928 before X frames exist. At that time, if FRAME is nil, 3927 is called before X frames exist. At that time, if FRAME is nil,
3929 selected_frame will be used which is the frame dumped with 3928 selected_frame will be used which is the frame dumped with
3930 Emacs. That frame is not an X frame. */ 3929 Emacs. That frame is not an X frame. */
3931 f = EQ (frame, Qt) ? NULL : decode_live_frame (frame); 3930 f = EQ (frame, Qt) ? NULL : decode_live_frame (frame);
@@ -5963,7 +5962,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
5963 5962
5964 /* W must display the current buffer. We could write this function 5963 /* W must display the current buffer. We could write this function
5965 to use the frame and buffer of W, but right now it doesn't. */ 5964 to use the frame and buffer of W, but right now it doesn't. */
5966 /* eassert (XBUFFER (w->buffer) == current_buffer); */ 5965 /* eassert (XBUFFER (w->contents) == current_buffer); */
5967 5966
5968 XSETFASTINT (position, pos); 5967 XSETFASTINT (position, pos);
5969 5968
@@ -5973,9 +5972,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
5973 5972
5974 /* Get the `face' or `mouse_face' text property at POS, and 5973 /* Get the `face' or `mouse_face' text property at POS, and
5975 determine the next position at which the property changes. */ 5974 determine the next position at which the property changes. */
5976 prop = Fget_text_property (position, propname, w->buffer); 5975 prop = Fget_text_property (position, propname, w->contents);
5977 XSETFASTINT (limit1, (limit < endpos ? limit : endpos)); 5976 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
5978 end = Fnext_single_property_change (position, propname, w->buffer, limit1); 5977 end = Fnext_single_property_change (position, propname, w->contents, limit1);
5979 if (INTEGERP (end)) 5978 if (INTEGERP (end))
5980 endpos = XINT (end); 5979 endpos = XINT (end);
5981 5980
@@ -6071,7 +6070,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
6071 6070
6072 /* W must display the current buffer. We could write this function 6071 /* W must display the current buffer. We could write this function
6073 to use the frame and buffer of W, but right now it doesn't. */ 6072 to use the frame and buffer of W, but right now it doesn't. */
6074 /* eassert (XBUFFER (w->buffer) == current_buffer); */ 6073 /* eassert (XBUFFER (w->contents) == current_buffer); */
6075 6074
6076 XSETFASTINT (position, pos); 6075 XSETFASTINT (position, pos);
6077 6076
@@ -6081,9 +6080,9 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos,
6081 6080
6082 /* Get the `face' or `mouse_face' text property at POS, and 6081 /* Get the `face' or `mouse_face' text property at POS, and
6083 determine the next position at which the property changes. */ 6082 determine the next position at which the property changes. */
6084 prop = Fget_text_property (position, propname, w->buffer); 6083 prop = Fget_text_property (position, propname, w->contents);
6085 XSETFASTINT (limit1, (limit < endpos ? limit : endpos)); 6084 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
6086 end = Fnext_single_property_change (position, propname, w->buffer, limit1); 6085 end = Fnext_single_property_change (position, propname, w->contents, limit1);
6087 if (INTEGERP (end)) 6086 if (INTEGERP (end))
6088 endpos = XINT (end); 6087 endpos = XINT (end);
6089 6088
diff --git a/src/xfns.c b/src/xfns.c
index 100fd81a155..a1c709a6c26 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -59,6 +59,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
59 59
60#include "xsettings.h" 60#include "xsettings.h"
61 61
62#ifdef HAVE_XRANDR
63#include <X11/extensions/Xrandr.h>
64#endif
65#ifdef HAVE_XINERAMA
66#include <X11/extensions/Xinerama.h>
67#endif
68
62#ifdef USE_GTK 69#ifdef USE_GTK
63#include "gtkutil.h" 70#include "gtkutil.h"
64#endif 71#endif
@@ -123,10 +130,6 @@ extern LWLIB_ID widget_id_tick;
123 130
124#define MAXREQUEST(dpy) (XMaxRequestSize (dpy)) 131#define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
125 132
126/* Nonzero if using X. */
127
128int x_in_use;
129
130static Lisp_Object Qsuppress_icon; 133static Lisp_Object Qsuppress_icon;
131static Lisp_Object Qundefined_color; 134static Lisp_Object Qundefined_color;
132static Lisp_Object Qcompound_text, Qcancel_timer; 135static Lisp_Object Qcompound_text, Qcancel_timer;
@@ -139,38 +142,6 @@ static int dpyinfo_refcount;
139 142
140static struct x_display_info *x_display_info_for_name (Lisp_Object); 143static struct x_display_info *x_display_info_for_name (Lisp_Object);
141 144
142
143/* Error if we are not connected to X. */
144
145void
146check_x (void)
147{
148 if (! x_in_use)
149 error ("X windows are not in use or not initialized");
150}
151
152/* Nonzero if we can use mouse menus.
153 You should not call this unless HAVE_MENUS is defined. */
154
155int
156have_menus_p (void)
157{
158 return x_in_use;
159}
160
161/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
162 and checking validity for X. */
163
164FRAME_PTR
165check_x_frame (Lisp_Object frame)
166{
167 struct frame *f = decode_live_frame (frame);
168
169 if (! FRAME_X_P (f))
170 error ("Non-X frame used");
171 return f;
172}
173
174/* Let the user specify an X display with a Lisp object. 145/* Let the user specify an X display with a Lisp object.
175 OBJECT may be nil, a frame or a terminal object. 146 OBJECT may be nil, a frame or a terminal object.
176 nil stands for the selected frame--or, if that is not an X frame, 147 nil stands for the selected frame--or, if that is not an X frame,
@@ -197,7 +168,7 @@ check_x_display_info (Lisp_Object object)
197 struct terminal *t = get_terminal (object, 1); 168 struct terminal *t = get_terminal (object, 1);
198 169
199 if (t->type != output_x_window) 170 if (t->type != output_x_window)
200 error ("Terminal %"pI"d is not an X display", XINT (object)); 171 error ("Terminal %d is not an X display", t->id);
201 172
202 dpyinfo = t->display_info.x; 173 dpyinfo = t->display_info.x;
203 } 174 }
@@ -205,7 +176,7 @@ check_x_display_info (Lisp_Object object)
205 dpyinfo = x_display_info_for_name (object); 176 dpyinfo = x_display_info_for_name (object);
206 else 177 else
207 { 178 {
208 FRAME_PTR f = check_x_frame (object); 179 FRAME_PTR f = decode_window_system_frame (object);
209 dpyinfo = FRAME_X_DISPLAY_INFO (f); 180 dpyinfo = FRAME_X_DISPLAY_INFO (f);
210 } 181 }
211 182
@@ -2992,7 +2963,7 @@ If FRAME is omitted or nil, use the selected frame.
2992Signal error if FRAME is not an X frame. */) 2963Signal error if FRAME is not an X frame. */)
2993 (Lisp_Object frame) 2964 (Lisp_Object frame)
2994{ 2965{
2995 struct frame *f = check_x_frame (frame); 2966 struct frame *f = decode_window_system_frame (frame);
2996 2967
2997 block_input (); 2968 block_input ();
2998 x_wm_set_size_hint (f, 0, 0); 2969 x_wm_set_size_hint (f, 0, 0);
@@ -3182,9 +3153,6 @@ This function is an internal primitive--use `make-frame' instead. */)
3182 specbind (Qx_resource_name, name); 3153 specbind (Qx_resource_name, name);
3183 } 3154 }
3184 3155
3185 f->resx = dpyinfo->resx;
3186 f->resy = dpyinfo->resy;
3187
3188#ifdef HAVE_FREETYPE 3156#ifdef HAVE_FREETYPE
3189#ifdef HAVE_XFT 3157#ifdef HAVE_XFT
3190 register_font_driver (&xftfont_driver, f); 3158 register_font_driver (&xftfont_driver, f);
@@ -3486,7 +3454,7 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
3486FRAME nil means use the selected frame. */) 3454FRAME nil means use the selected frame. */)
3487 (Lisp_Object frame) 3455 (Lisp_Object frame)
3488{ 3456{
3489 struct frame *f = check_x_frame (frame); 3457 struct frame *f = decode_window_system_frame (frame);
3490 Display *dpy = FRAME_X_DISPLAY (f); 3458 Display *dpy = FRAME_X_DISPLAY (f);
3491 3459
3492 block_input (); 3460 block_input ();
@@ -3519,7 +3487,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
3519 (Lisp_Object color, Lisp_Object frame) 3487 (Lisp_Object color, Lisp_Object frame)
3520{ 3488{
3521 XColor foo; 3489 XColor foo;
3522 FRAME_PTR f = check_x_frame (frame); 3490 FRAME_PTR f = decode_window_system_frame (frame);
3523 3491
3524 CHECK_STRING (color); 3492 CHECK_STRING (color);
3525 3493
@@ -3534,7 +3502,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
3534 (Lisp_Object color, Lisp_Object frame) 3502 (Lisp_Object color, Lisp_Object frame)
3535{ 3503{
3536 XColor foo; 3504 XColor foo;
3537 FRAME_PTR f = check_x_frame (frame); 3505 FRAME_PTR f = decode_window_system_frame (frame);
3538 3506
3539 CHECK_STRING (color); 3507 CHECK_STRING (color);
3540 3508
@@ -3600,7 +3568,11 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
3600 doc: /* Return the width in pixels of the X display TERMINAL. 3568 doc: /* Return the width in pixels of the X display TERMINAL.
3601The optional argument TERMINAL specifies which display to ask about. 3569The optional argument TERMINAL specifies which display to ask about.
3602TERMINAL should be a terminal object, a frame or a display name (a string). 3570TERMINAL should be a terminal object, a frame or a display name (a string).
3603If omitted or nil, that stands for the selected frame's display. */) 3571If omitted or nil, that stands for the selected frame's display.
3572
3573On \"multi-monitor\" setups this refers to the pixel width for all
3574physical monitors associated with TERMINAL. To get information for
3575each physical monitor, use `display-monitor-attributes-list'. */)
3604 (Lisp_Object terminal) 3576 (Lisp_Object terminal)
3605{ 3577{
3606 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3578 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3613,7 +3585,11 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
3613 doc: /* Return the height in pixels of the X display TERMINAL. 3585 doc: /* Return the height in pixels of the X display TERMINAL.
3614The optional argument TERMINAL specifies which display to ask about. 3586The optional argument TERMINAL specifies which display to ask about.
3615TERMINAL should be a terminal object, a frame or a display name (a string). 3587TERMINAL should be a terminal object, a frame or a display name (a string).
3616If omitted or nil, that stands for the selected frame's display. */) 3588If omitted or nil, that stands for the selected frame's display.
3589
3590On \"multi-monitor\" setups this refers to the pixel height for all
3591physical monitors associated with TERMINAL. To get information for
3592each physical monitor, use `display-monitor-attributes-list'. */)
3617 (Lisp_Object terminal) 3593 (Lisp_Object terminal)
3618{ 3594{
3619 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3595 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3721,7 +3697,11 @@ DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1,
3721 doc: /* Return the height in millimeters of the X display TERMINAL. 3697 doc: /* Return the height in millimeters of the X display TERMINAL.
3722The optional argument TERMINAL specifies which display to ask about. 3698The optional argument TERMINAL specifies which display to ask about.
3723TERMINAL should be a terminal object, a frame or a display name (a string). 3699TERMINAL should be a terminal object, a frame or a display name (a string).
3724If omitted or nil, that stands for the selected frame's display. */) 3700If omitted or nil, that stands for the selected frame's display.
3701
3702On \"multi-monitor\" setups this refers to the height in millimeters for
3703all physical monitors associated with TERMINAL. To get information
3704for each physical monitor, use `display-monitor-attributes-list'. */)
3725 (Lisp_Object terminal) 3705 (Lisp_Object terminal)
3726{ 3706{
3727 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3707 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3733,7 +3713,11 @@ DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
3733 doc: /* Return the width in millimeters of the X display TERMINAL. 3713 doc: /* Return the width in millimeters of the X display TERMINAL.
3734The optional argument TERMINAL specifies which display to ask about. 3714The optional argument TERMINAL specifies which display to ask about.
3735TERMINAL should be a terminal object, a frame or a display name (a string). 3715TERMINAL should be a terminal object, a frame or a display name (a string).
3736If omitted or nil, that stands for the selected frame's display. */) 3716If omitted or nil, that stands for the selected frame's display.
3717
3718On \"multi-monitor\" setups this refers to the width in millimeters for
3719all physical monitors associated with TERMINAL. To get information
3720for each physical monitor, use `display-monitor-attributes-list'. */)
3737 (Lisp_Object terminal) 3721 (Lisp_Object terminal)
3738{ 3722{
3739 struct x_display_info *dpyinfo = check_x_display_info (terminal); 3723 struct x_display_info *dpyinfo = check_x_display_info (terminal);
@@ -3830,6 +3814,512 @@ If omitted or nil, that stands for the selected frame's display. */)
3830 else 3814 else
3831 return Qnil; 3815 return Qnil;
3832} 3816}
3817
3818/* Store the geometry of the workarea on display DPYINFO into *RECT.
3819 Return false if and only if the workarea information cannot be
3820 obtained via the _NET_WORKAREA root window property. */
3821
3822#if ! GTK_CHECK_VERSION (3, 4, 0)
3823static bool
3824x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
3825{
3826 Display *dpy = dpyinfo->display;
3827 long offset, max_len;
3828 Atom target_type, actual_type;
3829 unsigned long actual_size, bytes_remaining;
3830 int rc, actual_format;
3831 unsigned char *tmp_data = NULL;
3832 bool result = false;
3833
3834 x_catch_errors (dpy);
3835 offset = 0;
3836 max_len = 1;
3837 target_type = XA_CARDINAL;
3838 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3839 dpyinfo->Xatom_net_current_desktop,
3840 offset, max_len, False, target_type,
3841 &actual_type, &actual_format, &actual_size,
3842 &bytes_remaining, &tmp_data);
3843 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3844 && actual_format == 32 && actual_size == max_len)
3845 {
3846 long current_desktop = ((long *) tmp_data)[0];
3847
3848 XFree (tmp_data);
3849 tmp_data = NULL;
3850
3851 offset = 4 * current_desktop;
3852 max_len = 4;
3853 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3854 dpyinfo->Xatom_net_workarea,
3855 offset, max_len, False, target_type,
3856 &actual_type, &actual_format, &actual_size,
3857 &bytes_remaining, &tmp_data);
3858 if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
3859 && actual_format == 32 && actual_size == max_len)
3860 {
3861 long *values = (long *) tmp_data;
3862
3863 rect->x = values[0];
3864 rect->y = values[1];
3865 rect->width = values[2];
3866 rect->height = values[3];
3867
3868 XFree (tmp_data);
3869 tmp_data = NULL;
3870
3871 result = true;
3872 }
3873 }
3874 if (tmp_data)
3875 XFree (tmp_data);
3876 x_uncatch_errors ();
3877
3878 return result;
3879}
3880#endif
3881
3882#ifndef USE_GTK
3883
3884/* Return monitor number where F is "most" or closest to. */
3885static int
3886x_get_monitor_for_frame (struct frame *f,
3887 struct MonitorInfo *monitors,
3888 int n_monitors)
3889{
3890 XRectangle frect;
3891 int area = 0, dist = -1;
3892 int best_area = -1, best_dist = -1;
3893 int i;
3894
3895 if (n_monitors == 1) return 0;
3896 frect.x = f->left_pos;
3897 frect.y = f->top_pos;
3898 frect.width = FRAME_PIXEL_WIDTH (f);
3899 frect.height = FRAME_PIXEL_HEIGHT (f);
3900
3901 for (i = 0; i < n_monitors; ++i)
3902 {
3903 struct MonitorInfo *mi = &monitors[i];
3904 XRectangle res;
3905 int a = 0;
3906
3907 if (mi->geom.width == 0) continue;
3908
3909 if (x_intersect_rectangles (&mi->geom, &frect, &res))
3910 {
3911 a = res.width * res.height;
3912 if (a > area)
3913 {
3914 area = a;
3915 best_area = i;
3916 }
3917 }
3918
3919 if (a == 0 && area == 0)
3920 {
3921 int dx, dy, d;
3922 if (frect.x + frect.width < mi->geom.x)
3923 dx = mi->geom.x - frect.x + frect.width;
3924 else if (frect.x > mi->geom.x + mi->geom.width)
3925 dx = frect.x - mi->geom.x + mi->geom.width;
3926 else
3927 dx = 0;
3928 if (frect.y + frect.height < mi->geom.y)
3929 dy = mi->geom.y - frect.y + frect.height;
3930 else if (frect.y > mi->geom.y + mi->geom.height)
3931 dy = frect.y - mi->geom.y + mi->geom.height;
3932 else
3933 dy = 0;
3934
3935 d = dx*dx + dy*dy;
3936 if (dist == -1 || dist > d)
3937 {
3938 dist = d;
3939 best_dist = i;
3940 }
3941 }
3942 }
3943
3944 return best_area != -1 ? best_area : (best_dist != -1 ? best_dist : 0);
3945}
3946
3947static Lisp_Object
3948x_make_monitor_attribute_list (struct MonitorInfo *monitors,
3949 int n_monitors,
3950 int primary_monitor,
3951 struct x_display_info *dpyinfo,
3952 const char *source)
3953{
3954 Lisp_Object monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
3955 Lisp_Object frame, rest;
3956
3957 FOR_EACH_FRAME (rest, frame)
3958 {
3959 struct frame *f = XFRAME (frame);
3960
3961 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo
3962 && !EQ (frame, tip_frame))
3963 {
3964 int i = x_get_monitor_for_frame (f, monitors, n_monitors);
3965 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
3966 }
3967 }
3968
3969 return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
3970 monitor_frames, source);
3971}
3972
3973static Lisp_Object
3974x_get_monitor_attributes_fallback (struct x_display_info *dpyinfo)
3975{
3976 struct MonitorInfo monitor;
3977 XRectangle workarea_r;
3978
3979 /* Fallback: treat (possibly) multiple physical monitors as if they
3980 formed a single monitor as a whole. This should provide a
3981 consistent result at least on single monitor environments. */
3982 monitor.geom.x = monitor.geom.y = 0;
3983 monitor.geom.width = x_display_pixel_width (dpyinfo);
3984 monitor.geom.height = x_display_pixel_height (dpyinfo);
3985 monitor.mm_width = WidthMMOfScreen (dpyinfo->screen);
3986 monitor.mm_height = HeightMMOfScreen (dpyinfo->screen);
3987 monitor.name = xstrdup ("combined screen");
3988
3989 if (x_get_net_workarea (dpyinfo, &workarea_r))
3990 monitor.work = workarea_r;
3991 else
3992 monitor.work = monitor.geom;
3993 return x_make_monitor_attribute_list (&monitor, 1, 0, dpyinfo, "fallback");
3994}
3995
3996
3997#ifdef HAVE_XINERAMA
3998static Lisp_Object
3999x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
4000{
4001 int n_monitors, i;
4002 Lisp_Object attributes_list = Qnil;
4003 Display *dpy = dpyinfo->display;
4004 XineramaScreenInfo *info = XineramaQueryScreens (dpy, &n_monitors);
4005 struct MonitorInfo *monitors;
4006 double mm_width_per_pixel, mm_height_per_pixel;
4007
4008 if (! info || n_monitors == 0)
4009 {
4010 if (info)
4011 XFree (info);
4012 return attributes_list;
4013 }
4014
4015 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
4016 / x_display_pixel_width (dpyinfo));
4017 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
4018 / x_display_pixel_height (dpyinfo));
4019 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
4020 for (i = 0; i < n_monitors; ++i)
4021 {
4022 struct MonitorInfo *mi = &monitors[i];
4023 XRectangle workarea_r;
4024
4025 mi->geom.x = info[i].x_org;
4026 mi->geom.y = info[i].y_org;
4027 mi->geom.width = info[i].width;
4028 mi->geom.height = info[i].height;
4029 mi->mm_width = mi->geom.width * mm_width_per_pixel + 0.5;
4030 mi->mm_height = mi->geom.height * mm_height_per_pixel + 0.5;
4031 mi->name = 0;
4032
4033 /* Xinerama usually have primary monitor first, just use that. */
4034 if (i == 0 && x_get_net_workarea (dpyinfo, &workarea_r))
4035 {
4036 mi->work = workarea_r;
4037 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
4038 mi->work = mi->geom;
4039 }
4040 else
4041 mi->work = mi->geom;
4042 }
4043 XFree (info);
4044
4045 attributes_list = x_make_monitor_attribute_list (monitors,
4046 n_monitors,
4047 0,
4048 dpyinfo,
4049 "Xinerama");
4050 free_monitors (monitors, n_monitors);
4051 return attributes_list;
4052}
4053#endif /* HAVE_XINERAMA */
4054
4055
4056#ifdef HAVE_XRANDR
4057static Lisp_Object
4058x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
4059{
4060 Lisp_Object attributes_list = Qnil;
4061 XRRScreenResources *resources;
4062 Display *dpy = dpyinfo->display;
4063 int i, n_monitors, primary = -1;
4064 RROutput pxid = None;
4065 struct MonitorInfo *monitors;
4066
4067#ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
4068 resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
4069#else
4070 resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
4071#endif
4072 if (! resources || resources->noutput == 0)
4073 {
4074 if (resources)
4075 XRRFreeScreenResources (resources);
4076 return Qnil;
4077 }
4078 n_monitors = resources->noutput;
4079 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
4080
4081#ifdef HAVE_XRRGETOUTPUTPRIMARY
4082 pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
4083#endif
4084
4085 for (i = 0; i < n_monitors; ++i)
4086 {
4087 XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
4088 resources->outputs[i]);
4089 Connection conn = info ? info->connection : RR_Disconnected;
4090 RRCrtc id = info ? info->crtc : None;
4091
4092 if (strcmp (info->name, "default") == 0)
4093 {
4094 /* Non XRandr 1.2 driver, does not give useful data. */
4095 XRRFreeOutputInfo (info);
4096 XRRFreeScreenResources (resources);
4097 free_monitors (monitors, n_monitors);
4098 return Qnil;
4099 }
4100
4101 if (conn != RR_Disconnected && id != None)
4102 {
4103 XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, id);
4104 struct MonitorInfo *mi = &monitors[i];
4105 XRectangle workarea_r;
4106
4107 if (! crtc)
4108 {
4109 XRRFreeOutputInfo (info);
4110 continue;
4111 }
4112
4113 mi->geom.x = crtc->x;
4114 mi->geom.y = crtc->y;
4115 mi->geom.width = crtc->width;
4116 mi->geom.height = crtc->height;
4117 mi->mm_width = info->mm_width;
4118 mi->mm_height = info->mm_height;
4119 mi->name = xstrdup (info->name);
4120
4121 if (pxid != None && pxid == resources->outputs[i])
4122 primary = i;
4123 else if (primary == -1 && strcmp (info->name, "LVDS") == 0)
4124 primary = i;
4125
4126 if (i == primary && x_get_net_workarea (dpyinfo, &workarea_r))
4127 {
4128 mi->work= workarea_r;
4129 if (! x_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
4130 mi->work = mi->geom;
4131 }
4132 else
4133 mi->work = mi->geom;
4134
4135 XRRFreeCrtcInfo (crtc);
4136 }
4137 XRRFreeOutputInfo (info);
4138 }
4139 XRRFreeScreenResources (resources);
4140
4141 attributes_list = x_make_monitor_attribute_list (monitors,
4142 n_monitors,
4143 primary,
4144 dpyinfo,
4145 "XRandr");
4146 free_monitors (monitors, n_monitors);
4147 return attributes_list;
4148}
4149#endif /* HAVE_XRANDR */
4150
4151static Lisp_Object
4152x_get_monitor_attributes (struct x_display_info *dpyinfo)
4153{
4154 Lisp_Object attributes_list = Qnil;
4155 Display *dpy = dpyinfo->display;
4156
4157#ifdef HAVE_XRANDR
4158 int xrr_event_base, xrr_error_base;
4159 bool xrr_ok = false;
4160 xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
4161 if (xrr_ok)
4162 {
4163 int xrr_major, xrr_minor;
4164 XRRQueryVersion (dpy, &xrr_major, &xrr_minor);
4165 xrr_ok = (xrr_major == 1 && xrr_minor >= 2) || xrr_major > 1;
4166 }
4167
4168 if (xrr_ok)
4169 attributes_list = x_get_monitor_attributes_xrandr (dpyinfo);
4170#endif /* HAVE_XRANDR */
4171
4172#ifdef HAVE_XINERAMA
4173 if (NILP (attributes_list))
4174 {
4175 int xin_event_base, xin_error_base;
4176 bool xin_ok = false;
4177 xin_ok = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
4178 if (xin_ok && XineramaIsActive (dpy))
4179 attributes_list = x_get_monitor_attributes_xinerama (dpyinfo);
4180 }
4181#endif /* HAVE_XINERAMA */
4182
4183 if (NILP (attributes_list))
4184 attributes_list = x_get_monitor_attributes_fallback (dpyinfo);
4185
4186 return attributes_list;
4187}
4188
4189#endif /* !USE_GTK */
4190
4191DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list,
4192 Sx_display_monitor_attributes_list,
4193 0, 1, 0,
4194 doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
4195
4196The optional argument TERMINAL specifies which display to ask about.
4197TERMINAL should be a terminal object, a frame or a display name (a string).
4198If omitted or nil, that stands for the selected frame's display.
4199
4200In addition to the standard attribute keys listed in
4201`display-monitor-attributes-list', the following keys are contained in
4202the attributes:
4203
4204 source -- String describing the source from which multi-monitor
4205 information is obtained, one of \"Gdk\", \"XRandr\",
4206 \"Xinerama\", or \"fallback\"
4207
4208Internal use only, use `display-monitor-attributes-list' instead. */)
4209 (Lisp_Object terminal)
4210{
4211 struct x_display_info *dpyinfo = check_x_display_info (terminal);
4212 Lisp_Object attributes_list = Qnil;
4213
4214#ifdef USE_GTK
4215 double mm_width_per_pixel, mm_height_per_pixel;
4216 GdkDisplay *gdpy;
4217 GdkScreen *gscreen;
4218 gint primary_monitor = 0, n_monitors, i;
4219 Lisp_Object monitor_frames, rest, frame;
4220 static const char *source = "Gdk";
4221 struct MonitorInfo *monitors;
4222
4223 block_input ();
4224 mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
4225 / x_display_pixel_width (dpyinfo));
4226 mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
4227 / x_display_pixel_height (dpyinfo));
4228 gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
4229 gscreen = gdk_display_get_default_screen (gdpy);
4230#if GTK_CHECK_VERSION (2, 20, 0)
4231 primary_monitor = gdk_screen_get_primary_monitor (gscreen);
4232#endif
4233 n_monitors = gdk_screen_get_n_monitors (gscreen);
4234 monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
4235 monitors = (struct MonitorInfo *) xzalloc (n_monitors * sizeof (*monitors));
4236
4237 FOR_EACH_FRAME (rest, frame)
4238 {
4239 struct frame *f = XFRAME (frame);
4240
4241 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo
4242 && !EQ (frame, tip_frame))
4243 {
4244 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4245
4246 i = gdk_screen_get_monitor_at_window (gscreen, gwin);
4247 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
4248 }
4249 }
4250
4251 for (i = 0; i < n_monitors; ++i)
4252 {
4253 gint width_mm = -1, height_mm = -1;
4254 GdkRectangle rec, work;
4255 struct MonitorInfo *mi = &monitors[i];
4256
4257 gdk_screen_get_monitor_geometry (gscreen, i, &rec);
4258
4259#if GTK_CHECK_VERSION (2, 14, 0)
4260 width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
4261 height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
4262#endif
4263 if (width_mm < 0)
4264 width_mm = rec.width * mm_width_per_pixel + 0.5;
4265 if (height_mm < 0)
4266 height_mm = rec.height * mm_height_per_pixel + 0.5;
4267
4268#if GTK_CHECK_VERSION (3, 4, 0)
4269 gdk_screen_get_monitor_workarea (gscreen, i, &work);
4270#else
4271 /* Emulate the behavior of GTK+ 3.4. */
4272 {
4273 XRectangle workarea_r;
4274
4275 if (i == primary_monitor && x_get_net_workarea (dpyinfo, &workarea_r))
4276 {
4277 work.x = workarea_r.x;
4278 work.y = workarea_r.y;
4279 work.width = workarea_r.width;
4280 work.height = workarea_r.height;
4281 if (! gdk_rectangle_intersect (&rec, &work, &work))
4282 work = rec;
4283 }
4284 else
4285 work = rec;
4286 }
4287#endif
4288
4289
4290 mi->geom.x = rec.x;
4291 mi->geom.y = rec.y;
4292 mi->geom.width = rec.width;
4293 mi->geom.height = rec.height;
4294 mi->work.x = work.x;
4295 mi->work.y = work.y;
4296 mi->work.width = work.width;
4297 mi->work.height = work.height;
4298 mi->mm_width = width_mm;
4299 mi->mm_height = height_mm;
4300
4301#if GTK_CHECK_VERSION (2, 14, 0)
4302 mi->name = gdk_screen_get_monitor_plug_name (gscreen, i);
4303#endif
4304 }
4305
4306 attributes_list = make_monitor_attribute_list (monitors,
4307 n_monitors,
4308 primary_monitor,
4309 monitor_frames,
4310 source);
4311 unblock_input ();
4312#else /* not USE_GTK */
4313
4314 block_input ();
4315 attributes_list = x_get_monitor_attributes (dpyinfo);
4316 unblock_input ();
4317
4318#endif /* not USE_GTK */
4319
4320 return attributes_list;
4321}
4322
3833 4323
3834int 4324int
3835x_pixel_width (register struct frame *f) 4325x_pixel_width (register struct frame *f)
@@ -3999,7 +4489,6 @@ x_display_info_for_name (Lisp_Object name)
3999 if (dpyinfo == 0) 4489 if (dpyinfo == 0)
4000 error ("Cannot connect to X server %s", SDATA (name)); 4490 error ("Cannot connect to X server %s", SDATA (name));
4001 4491
4002 x_in_use = 1;
4003 XSETFASTINT (Vwindow_system_version, 11); 4492 XSETFASTINT (Vwindow_system_version, 11);
4004 4493
4005 return dpyinfo; 4494 return dpyinfo;
@@ -4053,8 +4542,6 @@ An insecure way to solve the problem may be to use `xhost'.\n",
4053 error ("Cannot connect to X server %s", SDATA (display)); 4542 error ("Cannot connect to X server %s", SDATA (display));
4054 } 4543 }
4055 4544
4056 x_in_use = 1;
4057
4058 XSETFASTINT (Vwindow_system_version, 11); 4545 XSETFASTINT (Vwindow_system_version, 11);
4059 return Qnil; 4546 return Qnil;
4060} 4547}
@@ -4146,7 +4633,7 @@ FRAME. Default is to change on the edit X window. */)
4146 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame, 4633 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
4147 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p) 4634 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
4148{ 4635{
4149 struct frame *f = check_x_frame (frame); 4636 struct frame *f = decode_window_system_frame (frame);
4150 Atom prop_atom; 4637 Atom prop_atom;
4151 Atom target_type = XA_STRING; 4638 Atom target_type = XA_STRING;
4152 int element_format = 8; 4639 int element_format = 8;
@@ -4224,7 +4711,7 @@ DEFUN ("x-delete-window-property", Fx_delete_window_property,
4224FRAME nil or omitted means use the selected frame. Value is PROP. */) 4711FRAME nil or omitted means use the selected frame. Value is PROP. */)
4225 (Lisp_Object prop, Lisp_Object frame) 4712 (Lisp_Object prop, Lisp_Object frame)
4226{ 4713{
4227 struct frame *f = check_x_frame (frame); 4714 struct frame *f = decode_window_system_frame (frame);
4228 Atom prop_atom; 4715 Atom prop_atom;
4229 4716
4230 CHECK_STRING (prop); 4717 CHECK_STRING (prop);
@@ -4260,7 +4747,7 @@ no value of TYPE (always string in the MS Windows case). */)
4260 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type, 4747 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
4261 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p) 4748 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
4262{ 4749{
4263 struct frame *f = check_x_frame (frame); 4750 struct frame *f = decode_window_system_frame (frame);
4264 Atom prop_atom; 4751 Atom prop_atom;
4265 int rc; 4752 int rc;
4266 Lisp_Object prop_value = Qnil; 4753 Lisp_Object prop_value = Qnil;
@@ -4325,7 +4812,7 @@ no value of TYPE (always string in the MS Windows case). */)
4325 property and those are indeed in 32 bit quantities if format is 4812 property and those are indeed in 32 bit quantities if format is
4326 32. */ 4813 32. */
4327 4814
4328 if (32 < BITS_PER_LONG && actual_format == 32) 4815 if (BITS_PER_LONG > 32 && actual_format == 32)
4329 { 4816 {
4330 unsigned long i; 4817 unsigned long i;
4331 int *idata = (int *) tmp_data; 4818 int *idata = (int *) tmp_data;
@@ -4528,8 +5015,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
4528 Lisp_Object buffer; 5015 Lisp_Object buffer;
4529 struct buffer *old_buffer; 5016 struct buffer *old_buffer;
4530 5017
4531 check_x ();
4532
4533 if (!dpyinfo->terminal->name) 5018 if (!dpyinfo->terminal->name)
4534 error ("Terminal is not live, can't create new frames on it"); 5019 error ("Terminal is not live, can't create new frames on it");
4535 5020
@@ -4631,9 +5116,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
4631 specbind (Qx_resource_name, name); 5116 specbind (Qx_resource_name, name);
4632 } 5117 }
4633 5118
4634 f->resx = dpyinfo->resx;
4635 f->resy = dpyinfo->resy;
4636
4637 register_font_driver (&xfont_driver, f); 5119 register_font_driver (&xfont_driver, f);
4638#ifdef HAVE_FREETYPE 5120#ifdef HAVE_FREETYPE
4639#ifdef HAVE_XFT 5121#ifdef HAVE_XFT
@@ -4929,7 +5411,7 @@ Text larger than the specified size is clipped. */)
4929 if (SCHARS (string) == 0) 5411 if (SCHARS (string) == 0)
4930 string = make_unibyte_string (" ", 1); 5412 string = make_unibyte_string (" ", 1);
4931 5413
4932 f = check_x_frame (frame); 5414 f = decode_window_system_frame (frame);
4933 if (NILP (timeout)) 5415 if (NILP (timeout))
4934 timeout = make_number (5); 5416 timeout = make_number (5);
4935 else 5417 else
@@ -5027,29 +5509,29 @@ Text larger than the specified size is clipped. */)
5027 5509
5028 /* Set up the frame's root window. */ 5510 /* Set up the frame's root window. */
5029 w = XWINDOW (FRAME_ROOT_WINDOW (f)); 5511 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5030 wset_left_col (w, make_number (0)); 5512 w->left_col = 0;
5031 wset_top_line (w, make_number (0)); 5513 w->top_line = 0;
5032 5514
5033 if (CONSP (Vx_max_tooltip_size) 5515 if (CONSP (Vx_max_tooltip_size)
5034 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX) 5516 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
5035 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX)) 5517 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
5036 { 5518 {
5037 wset_total_cols (w, XCAR (Vx_max_tooltip_size)); 5519 w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
5038 wset_total_lines (w, XCDR (Vx_max_tooltip_size)); 5520 w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
5039 } 5521 }
5040 else 5522 else
5041 { 5523 {
5042 wset_total_cols (w, make_number (80)); 5524 w->total_cols = 80;
5043 wset_total_lines (w, make_number (40)); 5525 w->total_lines = 40;
5044 } 5526 }
5045 5527
5046 FRAME_TOTAL_COLS (f) = XINT (w->total_cols); 5528 FRAME_TOTAL_COLS (f) = w->total_cols;
5047 adjust_glyphs (f); 5529 adjust_glyphs (f);
5048 w->pseudo_window_p = 1; 5530 w->pseudo_window_p = 1;
5049 5531
5050 /* Display the tooltip text in a temporary buffer. */ 5532 /* Display the tooltip text in a temporary buffer. */
5051 old_buffer = current_buffer; 5533 old_buffer = current_buffer;
5052 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer)); 5534 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
5053 bset_truncate_lines (current_buffer, Qnil); 5535 bset_truncate_lines (current_buffer, Qnil);
5054 clear_glyph_matrix (w->desired_matrix); 5536 clear_glyph_matrix (w->desired_matrix);
5055 clear_glyph_matrix (w->current_matrix); 5537 clear_glyph_matrix (w->current_matrix);
@@ -5110,7 +5592,7 @@ Text larger than the specified size is clipped. */)
5110 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, 5592 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5111 not in pixels. */ 5593 not in pixels. */
5112 width /= WINDOW_FRAME_COLUMN_WIDTH (w); 5594 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5113 wset_total_cols (w, make_number (width)); 5595 w->total_cols = width;
5114 FRAME_TOTAL_COLS (f) = width; 5596 FRAME_TOTAL_COLS (f) = width;
5115 adjust_glyphs (f); 5597 adjust_glyphs (f);
5116 clear_glyph_matrix (w->desired_matrix); 5598 clear_glyph_matrix (w->desired_matrix);
@@ -5252,7 +5734,7 @@ DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
5252#ifdef USE_GTK 5734#ifdef USE_GTK
5253 if (use_dialog_box 5735 if (use_dialog_box
5254 && use_file_dialog 5736 && use_file_dialog
5255 && have_menus_p () 5737 && window_system_available (SELECTED_FRAME ())
5256 && xg_uses_old_file_dialog ()) 5738 && xg_uses_old_file_dialog ())
5257 return Qt; 5739 return Qt;
5258#endif 5740#endif
@@ -5322,7 +5804,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5322 ptrdiff_t count = SPECPDL_INDEX (); 5804 ptrdiff_t count = SPECPDL_INDEX ();
5323 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; 5805 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5324 5806
5325 check_x (); 5807 check_window_system (f);
5326 5808
5327 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); 5809 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5328 5810
@@ -5492,7 +5974,7 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
5492 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; 5974 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
5493 char *cdef_file; 5975 char *cdef_file;
5494 5976
5495 check_x (); 5977 check_window_system (f);
5496 5978
5497 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file); 5979 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
5498 5980
@@ -5547,15 +6029,13 @@ FRAME is the frame on which to pop up the font chooser. If omitted or
5547nil, it defaults to the selected frame. */) 6029nil, it defaults to the selected frame. */)
5548 (Lisp_Object frame, Lisp_Object ignored) 6030 (Lisp_Object frame, Lisp_Object ignored)
5549{ 6031{
5550 FRAME_PTR f = check_x_frame (frame); 6032 FRAME_PTR f = decode_window_system_frame (frame);
5551 Lisp_Object font; 6033 Lisp_Object font;
5552 Lisp_Object font_param; 6034 Lisp_Object font_param;
5553 char *default_name = NULL; 6035 char *default_name = NULL;
5554 struct gcpro gcpro1, gcpro2; 6036 struct gcpro gcpro1, gcpro2;
5555 ptrdiff_t count = SPECPDL_INDEX (); 6037 ptrdiff_t count = SPECPDL_INDEX ();
5556 6038
5557 check_x ();
5558
5559 if (popup_activated ()) 6039 if (popup_activated ())
5560 error ("Trying to use a menu from within a menu-entry"); 6040 error ("Trying to use a menu from within a menu-entry");
5561 6041
@@ -5597,7 +6077,7 @@ nil, it defaults to the selected frame. */)
5597 Keyboard 6077 Keyboard
5598 ***********************************************************************/ 6078 ***********************************************************************/
5599 6079
5600#ifdef HAVE_XKBGETKEYBOARD 6080#ifdef HAVE_XKB
5601#include <X11/XKBlib.h> 6081#include <X11/XKBlib.h>
5602#include <X11/keysym.h> 6082#include <X11/keysym.h>
5603#endif 6083#endif
@@ -5611,9 +6091,11 @@ usual X keysyms. Value is `lambda' if we cannot determine if both keys are
5611present and mapped to the usual X keysyms. */) 6091present and mapped to the usual X keysyms. */)
5612 (Lisp_Object frame) 6092 (Lisp_Object frame)
5613{ 6093{
5614#ifdef HAVE_XKBGETKEYBOARD 6094#ifndef HAVE_XKB
6095 return Qlambda;
6096#else
5615 XkbDescPtr kb; 6097 XkbDescPtr kb;
5616 struct frame *f = check_x_frame (frame); 6098 struct frame *f = decode_window_system_frame (frame);
5617 Display *dpy = FRAME_X_DISPLAY (f); 6099 Display *dpy = FRAME_X_DISPLAY (f);
5618 Lisp_Object have_keys; 6100 Lisp_Object have_keys;
5619 int major, minor, op, event, error_code; 6101 int major, minor, op, event, error_code;
@@ -5689,9 +6171,7 @@ present and mapped to the usual X keysyms. */)
5689 } 6171 }
5690 unblock_input (); 6172 unblock_input ();
5691 return have_keys; 6173 return have_keys;
5692#else /* not HAVE_XKBGETKEYBOARD */ 6174#endif
5693 return Qlambda;
5694#endif /* not HAVE_XKBGETKEYBOARD */
5695} 6175}
5696 6176
5697 6177
@@ -5743,9 +6223,6 @@ frame_parm_handler x_frame_parm_handlers[] =
5743void 6223void
5744syms_of_xfns (void) 6224syms_of_xfns (void)
5745{ 6225{
5746 /* This is zero if not using X windows. */
5747 x_in_use = 0;
5748
5749 /* The section below is built by the lisp expression at the top of the file, 6226 /* The section below is built by the lisp expression at the top of the file,
5750 just above where these variables are declared. */ 6227 just above where these variables are declared. */
5751 /*&&& init symbols here &&&*/ 6228 /*&&& init symbols here &&&*/
@@ -5916,6 +6393,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
5916 defsubr (&Sx_display_visual_class); 6393 defsubr (&Sx_display_visual_class);
5917 defsubr (&Sx_display_backing_store); 6394 defsubr (&Sx_display_backing_store);
5918 defsubr (&Sx_display_save_under); 6395 defsubr (&Sx_display_save_under);
6396 defsubr (&Sx_display_monitor_attributes_list);
5919 defsubr (&Sx_wm_set_size_hint); 6397 defsubr (&Sx_wm_set_size_hint);
5920 defsubr (&Sx_create_frame); 6398 defsubr (&Sx_create_frame);
5921 defsubr (&Sx_open_connection); 6399 defsubr (&Sx_open_connection);
@@ -5925,9 +6403,6 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
5925 defsubr (&Sx_focus_frame); 6403 defsubr (&Sx_focus_frame);
5926 defsubr (&Sx_backspace_delete_keys_p); 6404 defsubr (&Sx_backspace_delete_keys_p);
5927 6405
5928 /* Setting callback functions for fontset handler. */
5929 check_window_system_func = check_x;
5930
5931 defsubr (&Sx_show_tip); 6406 defsubr (&Sx_show_tip);
5932 defsubr (&Sx_hide_tip); 6407 defsubr (&Sx_hide_tip);
5933 tip_timer = Qnil; 6408 tip_timer = Qnil;
diff --git a/src/xgselect.c b/src/xgselect.c
index 2c8e9671abb..0b5ad6ae70d 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -26,6 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#include <glib.h> 26#include <glib.h>
27#include <errno.h> 27#include <errno.h>
28#include "xterm.h" 28#include "xterm.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, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
@@ -43,7 +44,7 @@ xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
43 int i, nfds, tmo_in_millisec; 44 int i, nfds, tmo_in_millisec;
44 USE_SAFE_ALLOCA; 45 USE_SAFE_ALLOCA;
45 46
46 if (! (x_in_use 47 if (! (window_system_available (NULL)
47 && g_main_context_pending (context = g_main_context_default ()))) 48 && g_main_context_pending (context = g_main_context_default ())))
48 return pselect (fds_lim, rfds, wfds, efds, timeout, sigmask); 49 return pselect (fds_lim, rfds, wfds, efds, timeout, sigmask);
49 50
diff --git a/src/xmenu.c b/src/xmenu.c
index 958cd220393..9993bd87d5b 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -223,8 +223,6 @@ for instance using the window manager, then this produces a quit and
223 FRAME_PTR f = NULL; 223 FRAME_PTR f = NULL;
224 Lisp_Object window; 224 Lisp_Object window;
225 225
226 check_x ();
227
228 /* Decode the first argument: find the window or frame to use. */ 226 /* Decode the first argument: find the window or frame to use. */
229 if (EQ (position, Qt) 227 if (EQ (position, Qt)
230 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 228 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
@@ -277,8 +275,7 @@ for instance using the window manager, then this produces a quit and
277 but I don't want to make one now. */ 275 but I don't want to make one now. */
278 CHECK_WINDOW (window); 276 CHECK_WINDOW (window);
279 277
280 if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f)) 278 check_window_system (f);
281 error ("Can not put X dialog on this terminal");
282 279
283 /* Force a redisplay before showing the dialog. If a frame is created 280 /* Force a redisplay before showing the dialog. If a frame is created
284 just before showing the dialog, its contents may not have been fully 281 just before showing the dialog, its contents may not have been fully
@@ -485,7 +482,7 @@ If FRAME is nil or not given, use the selected frame. */)
485 (Lisp_Object frame) 482 (Lisp_Object frame)
486{ 483{
487 XEvent ev; 484 XEvent ev;
488 FRAME_PTR f = check_x_frame (frame); 485 FRAME_PTR f = decode_window_system_frame (frame);
489 Widget menubar; 486 Widget menubar;
490 block_input (); 487 block_input ();
491 488
@@ -569,7 +566,7 @@ If FRAME is nil or not given, use the selected frame. */)
569 block_input (). */ 566 block_input (). */
570 567
571 block_input (); 568 block_input ();
572 f = check_x_frame (frame); 569 f = decode_window_system_frame (frame);
573 570
574 if (FRAME_EXTERNAL_MENU_BAR (f)) 571 if (FRAME_EXTERNAL_MENU_BAR (f))
575 set_frame_menubar (f, 0, 1); 572 set_frame_menubar (f, 0, 1);
@@ -976,7 +973,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
976 if (! menubar_widget) 973 if (! menubar_widget)
977 previous_menu_items_used = 0; 974 previous_menu_items_used = 0;
978 975
979 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer; 976 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
980 specbind (Qinhibit_quit, Qt); 977 specbind (Qinhibit_quit, Qt);
981 /* Don't let the debugger step into this code 978 /* Don't let the debugger step into this code
982 because it is not reentrant. */ 979 because it is not reentrant. */
@@ -1055,7 +1052,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
1055 wv->help = Qnil; 1052 wv->help = Qnil;
1056 first_wv = wv; 1053 first_wv = wv;
1057 1054
1058 for (i = 0; 0 <= submenu_start[i]; i++) 1055 for (i = 0; submenu_start[i] >= 0; i++)
1059 { 1056 {
1060 menu_items_n_panes = submenu_n_panes[i]; 1057 menu_items_n_panes = submenu_n_panes[i];
1061 wv = digest_single_submenu (submenu_start[i], submenu_end[i], 1058 wv = digest_single_submenu (submenu_start[i], submenu_end[i],
@@ -2479,7 +2476,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
2479#endif 2476#endif
2480 2477
2481 record_unwind_protect (pop_down_menu, 2478 record_unwind_protect (pop_down_menu,
2482 make_save_value ("pp", f, menu)); 2479 make_save_value (SAVE_TYPE_PTR_PTR, f, menu));
2483 2480
2484 /* Help display under X won't work because XMenuActivate contains 2481 /* Help display under X won't work because XMenuActivate contains
2485 a loop that doesn't give Emacs a chance to process it. */ 2482 a loop that doesn't give Emacs a chance to process it. */
diff --git a/src/xselect.c b/src/xselect.c
index 5b90d7def22..b422a22d68b 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1388,7 +1388,7 @@ x_get_window_property (Display *display, Window window, Atom property,
1388 data = data1; 1388 data = data1;
1389 } 1389 }
1390 1390
1391 if (32 < BITS_PER_LONG && *actual_format_ret == 32) 1391 if (BITS_PER_LONG > 32 && *actual_format_ret == 32)
1392 { 1392 {
1393 unsigned long i; 1393 unsigned long i;
1394 int *idata = (int *) (data + offset); 1394 int *idata = (int *) (data + offset);
@@ -2450,7 +2450,7 @@ Use the display for FRAME or the current frame if FRAME is not given or nil.
2450If the value is 0 or the atom is not known, return the empty string. */) 2450If the value is 0 or the atom is not known, return the empty string. */)
2451 (Lisp_Object value, Lisp_Object frame) 2451 (Lisp_Object value, Lisp_Object frame)
2452{ 2452{
2453 struct frame *f = check_x_frame (frame); 2453 struct frame *f = decode_window_system_frame (frame);
2454 char *name = 0; 2454 char *name = 0;
2455 char empty[] = ""; 2455 char empty[] = "";
2456 Lisp_Object ret = Qnil; 2456 Lisp_Object ret = Qnil;
@@ -2485,7 +2485,7 @@ FRAME is on. If FRAME is nil, the selected frame is used. */)
2485 (Lisp_Object atom, Lisp_Object frame) 2485 (Lisp_Object atom, Lisp_Object frame)
2486{ 2486{
2487 Atom x_atom; 2487 Atom x_atom;
2488 struct frame *f = check_x_frame (frame); 2488 struct frame *f = decode_window_system_frame (frame);
2489 ptrdiff_t i; 2489 ptrdiff_t i;
2490 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 2490 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2491 2491
@@ -2541,7 +2541,7 @@ x_handle_dnd_message (struct frame *f, XClientMessageEvent *event,
2541 function expects them to be of size int (i.e. 32). So to be able to 2541 function expects them to be of size int (i.e. 32). So to be able to
2542 use that function, put the data in the form it expects if format is 32. */ 2542 use that function, put the data in the form it expects if format is 32. */
2543 2543
2544 if (32 < BITS_PER_LONG && event->format == 32) 2544 if (BITS_PER_LONG > 32 && event->format == 32)
2545 { 2545 {
2546 for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */ 2546 for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */
2547 idata[i] = event->data.l[i]; 2547 idata[i] = event->data.l[i];
@@ -2571,7 +2571,7 @@ x_handle_dnd_message (struct frame *f, XClientMessageEvent *event,
2571 return 1; 2571 return 1;
2572} 2572}
2573 2573
2574DEFUN ("x-send-client-message", Fx_send_client_event, 2574DEFUN ("x-send-client-message", Fx_send_client_message,
2575 Sx_send_client_message, 6, 6, 0, 2575 Sx_send_client_message, 6, 6, 0,
2576 doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY. 2576 doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
2577 2577
@@ -2618,7 +2618,7 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
2618 struct x_display_info *dpyinfo = check_x_display_info (display); 2618 struct x_display_info *dpyinfo = check_x_display_info (display);
2619 Window wdest; 2619 Window wdest;
2620 XEvent event; 2620 XEvent event;
2621 struct frame *f = check_x_frame (from); 2621 struct frame *f = decode_window_system_frame (from);
2622 int to_root; 2622 int to_root;
2623 2623
2624 CHECK_NUMBER (format); 2624 CHECK_NUMBER (format);
@@ -2635,7 +2635,7 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
2635 2635
2636 if (FRAMEP (dest) || NILP (dest)) 2636 if (FRAMEP (dest) || NILP (dest))
2637 { 2637 {
2638 struct frame *fdest = check_x_frame (dest); 2638 struct frame *fdest = decode_window_system_frame (dest);
2639 wdest = FRAME_OUTER_WINDOW (fdest); 2639 wdest = FRAME_OUTER_WINDOW (fdest);
2640 } 2640 }
2641 else if (STRINGP (dest)) 2641 else if (STRINGP (dest))
diff --git a/src/xsettings.c b/src/xsettings.c
index 576a5032eac..f48c49dbafe 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -673,19 +673,14 @@ apply_xft_settings (struct x_display_info *dpyinfo,
673 if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi 673 if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi
674 && settings->dpi > 0) 674 && settings->dpi > 0)
675 { 675 {
676 Lisp_Object frame, tail;
677
678 FcPatternDel (pat, FC_DPI); 676 FcPatternDel (pat, FC_DPI);
679 FcPatternAddDouble (pat, FC_DPI, settings->dpi); 677 FcPatternAddDouble (pat, FC_DPI, settings->dpi);
680 ++changed; 678 ++changed;
681 oldsettings.dpi = settings->dpi; 679 oldsettings.dpi = settings->dpi;
682 680
683 /* Change the DPI on this display and all frames on the display. */ 681 /* Changing the DPI on this display affects all frames on it.
682 Check FRAME_RES_X and FRAME_RES_Y in frame.h to see how. */
684 dpyinfo->resy = dpyinfo->resx = settings->dpi; 683 dpyinfo->resy = dpyinfo->resx = settings->dpi;
685 FOR_EACH_FRAME (tail, frame)
686 if (FRAME_X_P (XFRAME (frame))
687 && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
688 XFRAME (frame)->resy = XFRAME (frame)->resx = settings->dpi;
689 } 684 }
690 685
691 if (changed) 686 if (changed)
diff --git a/src/xterm.c b/src/xterm.c
index 88433b6c0b3..7038de7039f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -130,6 +130,10 @@ extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
130 130
131#include "bitmaps/gray.xbm" 131#include "bitmaps/gray.xbm"
132 132
133#ifdef HAVE_XKB
134#include <X11/XKBlib.h>
135#endif
136
133/* Default to using XIM if available. */ 137/* Default to using XIM if available. */
134#ifdef USE_XIM 138#ifdef USE_XIM
135int use_xim = 1; 139int use_xim = 1;
@@ -3218,7 +3222,11 @@ XTring_bell (struct frame *f)
3218 else 3222 else
3219 { 3223 {
3220 block_input (); 3224 block_input ();
3225#ifdef HAVE_XKB
3226 XkbBell (FRAME_X_DISPLAY (f), None, 0, None);
3227#else
3221 XBell (FRAME_X_DISPLAY (f), 0); 3228 XBell (FRAME_X_DISPLAY (f), 0);
3229#endif
3222 XFlush (FRAME_X_DISPLAY (f)); 3230 XFlush (FRAME_X_DISPLAY (f));
3223 unblock_input (); 3231 unblock_input ();
3224 } 3232 }
@@ -5076,7 +5084,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
5076 5084
5077 /* Draw the empty space above the handle. Note that we can't clear 5085 /* Draw the empty space above the handle. Note that we can't clear
5078 zero-height areas; that means "clear to end of window." */ 5086 zero-height areas; that means "clear to end of window." */
5079 if (0 < start) 5087 if (start > 0)
5080 x_clear_area (FRAME_X_DISPLAY (f), w, 5088 x_clear_area (FRAME_X_DISPLAY (f), w,
5081 /* x, y, width, height, and exposures. */ 5089 /* x, y, width, height, and exposures. */
5082 VERTICAL_SCROLL_BAR_LEFT_BORDER, 5090 VERTICAL_SCROLL_BAR_LEFT_BORDER,
@@ -9889,6 +9897,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9889 9897
9890 XSetLocaleModifiers (""); 9898 XSetLocaleModifiers ("");
9891 9899
9900 /* If D-Bus is not already configured, inhibit D-Bus autolaunch,
9901 as autolaunch can mess up Emacs's SIGCHLD handler.
9902 FIXME: Rewrite subprocess handlers to use glib's child watchers.
9903 See Bug#14474. */
9904 if (! egetenv ("DBUS_SESSION_BUS_ADDRESS"))
9905 xputenv ("DBUS_SESSION_BUS_ADDRESS=unix:path=/dev/null");
9906
9892 /* Emacs can only handle core input events, so make sure 9907 /* Emacs can only handle core input events, so make sure
9893 Gtk doesn't use Xinput or Xinput2 extensions. */ 9908 Gtk doesn't use Xinput or Xinput2 extensions. */
9894 xputenv ("GDK_CORE_DEVICE_EVENTS=1"); 9909 xputenv ("GDK_CORE_DEVICE_EVENTS=1");
@@ -9913,7 +9928,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9913 9928
9914 dpy = DEFAULT_GDK_DISPLAY (); 9929 dpy = DEFAULT_GDK_DISPLAY ();
9915 9930
9916#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90 9931#if ! GTK_CHECK_VERSION (2, 90, 0)
9917 /* Load our own gtkrc if it exists. */ 9932 /* Load our own gtkrc if it exists. */
9918 { 9933 {
9919 const char *file = "~/.emacs.d/gtkrc"; 9934 const char *file = "~/.emacs.d/gtkrc";
@@ -10243,6 +10258,8 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10243 { "_NET_WM_WINDOW_OPACITY", &dpyinfo->Xatom_net_wm_window_opacity }, 10258 { "_NET_WM_WINDOW_OPACITY", &dpyinfo->Xatom_net_wm_window_opacity },
10244 { "_NET_ACTIVE_WINDOW", &dpyinfo->Xatom_net_active_window }, 10259 { "_NET_ACTIVE_WINDOW", &dpyinfo->Xatom_net_active_window },
10245 { "_NET_FRAME_EXTENTS", &dpyinfo->Xatom_net_frame_extents }, 10260 { "_NET_FRAME_EXTENTS", &dpyinfo->Xatom_net_frame_extents },
10261 { "_NET_CURRENT_DESKTOP", &dpyinfo->Xatom_net_current_desktop },
10262 { "_NET_WORKAREA", &dpyinfo->Xatom_net_workarea },
10246 /* Session management */ 10263 /* Session management */
10247 { "SM_CLIENT_ID", &dpyinfo->Xatom_SM_CLIENT_ID }, 10264 { "SM_CLIENT_ID", &dpyinfo->Xatom_SM_CLIENT_ID },
10248 { "_XSETTINGS_SETTINGS", &dpyinfo->Xatom_xsettings_prop }, 10265 { "_XSETTINGS_SETTINGS", &dpyinfo->Xatom_xsettings_prop },
diff --git a/src/xterm.h b/src/xterm.h
index b241ff23559..4a5ebc66370 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -53,14 +53,26 @@ typedef GtkWidget *xt_or_gtk_widget;
53#undef XSync 53#undef XSync
54#define XSync(d, b) do { gdk_window_process_all_updates (); \ 54#define XSync(d, b) do { gdk_window_process_all_updates (); \
55 XSync (d, b); } while (0) 55 XSync (d, b); } while (0)
56#endif /* USE_GTK */
57
58/* True iff GTK's version is at least I.J.K. */
59#ifndef GTK_CHECK_VERSION
60# ifdef USE_GTK
61# define GTK_CHECK_VERSION(i, j, k) \
62 ((i) \
63 < GTK_MAJOR_VERSION + ((j) \
64 < GTK_MINOR_VERSION + ((k) \
65 <= GTK_MICRO_VERSION)))
66# else
67# define GTK_CHECK_VERSION(i, j, k) 0
68# endif
69#endif
56 70
57/* The GtkTooltip API came in 2.12, but gtk-enable-tooltips in 2.14. */ 71/* The GtkTooltip API came in 2.12, but gtk-enable-tooltips in 2.14. */
58#if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 13 72#if GTK_CHECK_VERSION (2, 14, 0)
59#define USE_GTK_TOOLTIP 73#define USE_GTK_TOOLTIP
60#endif 74#endif
61 75
62#endif /* USE_GTK */
63
64 76
65/* Bookkeeping to distinguish X versions. */ 77/* Bookkeeping to distinguish X versions. */
66 78
@@ -346,7 +358,8 @@ struct x_display_info
346 Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen, 358 Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen,
347 Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert, 359 Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert,
348 Xatom_net_wm_state_sticky, Xatom_net_wm_state_hidden, 360 Xatom_net_wm_state_sticky, Xatom_net_wm_state_hidden,
349 Xatom_net_frame_extents; 361 Xatom_net_frame_extents,
362 Xatom_net_current_desktop, Xatom_net_workarea;
350 363
351 /* XSettings atoms and windows. */ 364 /* XSettings atoms and windows. */
352 Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; 365 Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
@@ -366,10 +379,6 @@ struct x_display_info
366extern int use_xim; 379extern int use_xim;
367#endif 380#endif
368 381
369/* This checks to make sure we have a display. */
370
371extern void check_x (void);
372
373extern struct frame *x_window_to_frame (struct x_display_info *, int); 382extern struct frame *x_window_to_frame (struct x_display_info *, int);
374extern struct frame *x_any_window_to_frame (struct x_display_info *, int); 383extern struct frame *x_any_window_to_frame (struct x_display_info *, int);
375extern struct frame *x_menubar_window_to_frame (struct x_display_info *, 384extern struct frame *x_menubar_window_to_frame (struct x_display_info *,
@@ -927,7 +936,6 @@ void x_handle_property_notify (XPropertyEvent *);
927 936
928/* From xfns.c. */ 937/* From xfns.c. */
929 938
930struct frame *check_x_frame (Lisp_Object);
931extern void x_free_gcs (struct frame *); 939extern void x_free_gcs (struct frame *);
932 940
933/* From xrdb.c. */ 941/* From xrdb.c. */
@@ -1012,7 +1020,6 @@ extern void x_clipboard_manager_save_all (void);
1012 1020
1013extern struct x_display_info * check_x_display_info (Lisp_Object); 1021extern struct x_display_info * check_x_display_info (Lisp_Object);
1014extern Lisp_Object x_get_focus_frame (struct frame *); 1022extern Lisp_Object x_get_focus_frame (struct frame *);
1015extern int x_in_use;
1016 1023
1017#ifdef USE_GTK 1024#ifdef USE_GTK
1018extern int xg_set_icon (struct frame *, Lisp_Object); 1025extern int xg_set_icon (struct frame *, Lisp_Object);