aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-12-07 19:21:57 +0200
committerEli Zaretskii2013-12-07 19:21:57 +0200
commitce1d7b61f12dcc1b67535b68d9b0655b45fcadb6 (patch)
tree881d03f4f486933482cd2e3851184cd3b172ef1b /src
parent6630df25238c5a1efa2bc6a0fa7889782e8c91b5 (diff)
parentfa6fa1a1773f255b5efbe52a743b017f4908a6cb (diff)
downloademacs-ce1d7b61f12dcc1b67535b68d9b0655b45fcadb6.tar.gz
emacs-ce1d7b61f12dcc1b67535b68d9b0655b45fcadb6.zip
Merge from trunk.
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit2
-rw-r--r--src/ChangeLog762
-rw-r--r--src/ChangeLog.122
-rw-r--r--src/Makefile.in72
-rw-r--r--src/alloc.c34
-rw-r--r--src/bidi.c65
-rw-r--r--src/blockinput.h2
-rw-r--r--src/buffer.c24
-rw-r--r--src/buffer.h7
-rw-r--r--src/callproc.c31
-rw-r--r--src/charset.c10
-rw-r--r--src/charset.h2
-rw-r--r--src/chartab.c2
-rw-r--r--src/composite.c2
-rw-r--r--src/data.c151
-rw-r--r--src/dispextern.h77
-rw-r--r--src/dispnew.c188
-rw-r--r--src/editfns.c40
-rw-r--r--src/emacs.c65
-rw-r--r--src/epaths.in6
-rw-r--r--src/eval.c68
-rw-r--r--src/fileio.c49
-rw-r--r--src/fns.c71
-rw-r--r--src/font.c2
-rw-r--r--src/font.h21
-rw-r--r--src/frame.c409
-rw-r--r--src/frame.h280
-rw-r--r--src/fringe.c4
-rw-r--r--src/ftfont.c1
-rw-r--r--src/gnutls.c6
-rw-r--r--src/gtkutil.c49
-rw-r--r--src/gtkutil.h2
-rw-r--r--src/image.c4
-rw-r--r--src/indent.c4
-rw-r--r--src/insdel.c6
-rw-r--r--src/intervals.c2
-rw-r--r--src/intervals.h2
-rw-r--r--src/keyboard.c45
-rw-r--r--src/keyboard.h1
-rw-r--r--src/lisp.h23
-rw-r--r--src/lisp.mk2
-rw-r--r--src/lread.c270
-rw-r--r--src/menu.c12
-rw-r--r--src/minibuf.c3
-rw-r--r--src/nsfns.m23
-rw-r--r--src/nsfont.m1
-rw-r--r--src/nsterm.h6
-rw-r--r--src/nsterm.m132
-rw-r--r--src/print.c7
-rw-r--r--src/process.c11
-rw-r--r--src/regex.c2
-rw-r--r--src/term.c12
-rw-r--r--src/textprop.c28
-rw-r--r--src/tparam.c2
-rw-r--r--src/undo.c6
-rw-r--r--src/w32fns.c324
-rw-r--r--src/w32font.c33
-rw-r--r--src/w32inevt.c10
-rw-r--r--src/w32menu.c9
-rw-r--r--src/w32notify.c29
-rw-r--r--src/w32proc.c34
-rw-r--r--src/w32term.c141
-rw-r--r--src/w32term.h19
-rw-r--r--src/w32xfns.c1
-rw-r--r--src/widget.c12
-rw-r--r--src/window.c1111
-rw-r--r--src/window.h345
-rw-r--r--src/xdisp.c940
-rw-r--r--src/xfaces.c7
-rw-r--r--src/xfns.c90
-rw-r--r--src/xmenu.c6
-rw-r--r--src/xrdb.c2
-rw-r--r--src/xterm.c329
-rw-r--r--src/xterm.h18
74 files changed, 4497 insertions, 2073 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index 1bfc293c466..275a1d8db88 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -67,7 +67,7 @@ define xgettype
67 else 67 else
68 set $bugfix = $arg0 68 set $bugfix = $arg0
69 end 69 end
70 set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : $bugfix >> VALBITS) 70 set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : (EMACS_UINT) $bugfix >> VALBITS)
71end 71end
72 72
73# Set up something to print out s-expressions. 73# Set up something to print out s-expressions.
diff --git a/src/ChangeLog b/src/ChangeLog
index a2dfa5bf613..e67fdada36f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,10 +1,766 @@
12013-12-07 Jan Djärv <jan.h.d@swipnet.se>
2
3 Pixel resize changes for NS (Bug#16049).
4 * nsterm.m (x_set_window_size): Change parameters rows/cols to
5 height/width. row/cols are locals.
6 Pass pixelwise to check_frame_size. Don't set FRAME_PIXEL_WIDTH/HEIGHT.
7 (updateFrameSize:): Remove gsextra. Adjust for pixelwise resize.
8 (windowWillResize): Remove gsextra. Calculate extra as in
9 updateFrameSize.
10 (x_new_font): Don't change frame size if fullscreen. Change
11 size pixelwise.
12
13 * nsfns.m (Fx_create_frame): Call change_frame_size twice as per
14 comment in xfns.c. Change to pixelwise call.
15
162013-12-06 Eli Zaretskii <eliz@gnu.org>
17
18 * buffer.c (Fset_buffer_multibyte): Invalidate buffer caches.
19 (Bug#16070)
20
212013-12-06 Dmitry Antipov <dmantipov@yandex.ru>
22
23 * xterm.c (input_signal_count): Remove.
24 (x_dispatch_event): Define unconditionally.
25 (x_make_frame_visible): Process X events until the frame
26 is really visible (Bug#16027).
27 * xterm.h (x_dispatch_event): Declare unconditionally.
28
292013-12-05 Jan Djärv <jan.h.d@swipnet.se>
30
31 * nsfns.m (ns_frame_parm_handlers): Add right/bottom_divider_width.
32
33 * nsterm.m (x_set_window_size): Handle pixelwise.
34
352013-12-05 Martin Rudalics <rudalics@gmx.at>
36
37 * w32term.c (x_new_font):
38 * xterm.c (x_new_font): Calculate new frame size from new font
39 size (Bug#16028).
40
412013-12-04 Stefan Monnier <monnier@iro.umontreal.ca>
42
43 * lisp.h (FOR_EACH_TAIL): New macro.
44 * fns.c (Fdelq): Use it to avoid inf-loops; remove QUIT.
45
46 * window.c (select_window): Call second wset_redisplay before we change
47 selected_window (bug#16034).
48
492013-12-04 Paul Eggert <eggert@cs.ucla.edu>
50
51 * bidi.c (LRM_CHAR, RLM_CHAR): Remove; no longer used.
52
532013-12-04 Eli Zaretskii <eliz@gnu.org>
54
55 * w32xfns.c: Include window.h, to avoid a compiler warning.
56
572013-12-04 Stefan Monnier <monnier@iro.umontreal.ca>
58
59 * window.c (window_scroll): Mark window for redisplay (bug#16034).
60 (scroll_command, Fscroll_other_window): Don't cause redisplay now that
61 window_scroll takes care of it.
62 (Fset_window_point, Fdelete_other_windows_internal)
63 (set_window_buffer, Fwindow_resize_apply, resize_frame_windows)
64 (Fsplit_window_internal, Fdelete_window_internal)
65 (Fresize_mini_window_internal, Fset_window_configuration)
66 (apply_window_adjustment): Use fset_redisplay and wset_redisplay to
67 cause redisplay instead of forcing a complete redisplay.
68 * xdisp.c (wset_redisplay): Don't set windows_or_buffers_changed if
69 we're only affecting the selected_window.
70
712013-12-04 Eli Zaretskii <eliz@gnu.org>
72
73 * bidi.c (bidi_get_type, bidi_get_category): Handle the isolate
74 directional control characters. Update type and category
75 determination according to the UBA from Unicode v6.3.
76 (bidi_category_t): New category EXPLICIT_FORMATTING.
77
78 * dispextern.h (bidi_type_t): Update to include new bidirectional
79 properties introduced with Unicode v6.3. (Bug#16043)
80
812013-12-04 Martin Rudalics <rudalics@gmx.at>
82
83 * xterm.c (XTflash): Fix coordinate of bottom area to flash
84 (Bug#16044).
85
862013-12-04 Dmitry Antipov <dmantipov@yandex.ru>
87
88 * font.c (font_list_entities): Remove dummy assignment.
89 * font.h (struct font) [HAVE_WINDOW_SYSTEM]: Group members which are
90 used on graphic displays only. Remove unused 'font_encoder' member.
91 (struct font_bitmap): Remove unused 'extra' member.
92 * nsfont.m (nsfont_open):
93 * w32font.c (w32font_open_internal):
94 * ftfont.c (ftfont_get_bitmap): Adjust users.
95
962013-12-03 Paul Eggert <eggert@cs.ucla.edu>
97
98 Use bool for boolean.
99 * tparam.c (tparam1):
100 * undo.c (record_point, record_property_change):
101 Use bool for boolean, for local vars that are always true or false.
102
103 Minor integer overflow fixes (Bug#16033).
104 * window.c (Fset_window_new_pixel): Don't let new_pixel go negative.
105 This improves on the previous fix to this function.
106 (window_resize_check): When summing up pixel counts, don't rely on
107 undefined behavior if the sum overflows.
108
1092013-12-03 Martin Rudalics <rudalics@gmx.at>
110
111 * window.c (Fset_window_new_pixel): Don't choke at negative
112 argument value (Bug#16033).
113
114 * xfns.c (Fx_create_frame): Add another call to change_frame_size
115 to avoid crash in window_box_height.
116
117 * gtkutil.h: Fix external declaration of xg_frame_set_char_size.
118 * gtkutil.c (xg_frame_set_char_size, style_changed_cb): Fix size
119 calculation.
120 * xterm.c (x_set_window_size): Fix size calculation (Bug#16013).
121
1222013-12-03 Paul Eggert <eggert@cs.ucla.edu>
123
124 Minor integer overflow fixes.
125 * window.c (Fset_window_new_pixel, grow_mini_window):
126 * xdisp.c (Fwindow_text_pixel_size):
127 Avoid undefined behavior on signed integer overflow.
128 * xfns.c (x_set_mouse_color):
129 Check that drag shape fits in 'unsigned', since that's what X wants.
130
1312013-12-02 Eli Zaretskii <eliz@gnu.org>
132
133 Improve reporting of fatal exception on MS-Windows.
134 * w32fns.c (my_exception_handler): New function.
135 (globals_of_w32fns): Set it up as the unhandled exception
136 handler. Initialize exception code and address to zeros.
137 (emacs_abort): If the exception code and address are available,
138 print them at the beginning of the backtrace. Fix the format of
139 printing addresses (was producing 0x0x12345678 on XP).
140 (Bug#15994)
141
1422013-12-02 Helmut Eller <eller.helmut@gmail.com>
143
144 * eval.c (Fbacktrace__locals): New function.
145 (syms_of_eval): Defsubr it.
146
1472013-12-02 Dmitry Antipov <dmantipov@yandex.ru>
148
149 * font.h (FONT_WIDTH, FONT_HEIGHT, FONT_BASE, FONT_DESCENT):
150 Define here to unify between...
151 * nsterm.h, w32term.h, xterm.h: ...port-specific headers.
152 * w32term.h (CHECK_W32_FRAME): Remove unused macro.
153
1542013-12-02 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
155
156 * xterm.h (struct scroll_bar): Remove member `fringe_extended_p'.
157
158 * xterm.c (x_draw_fringe_bitmap, x_scroll_run): Remove code for
159 fringe background extension.
160 (x_scroll_bar_create): Remove variables `sb_left' and `sb_width',
161 because they are now always the same as `left' and `width',
162 respectively. Remove code for the case that `width' and
163 `sb_width' are different.
164
1652013-12-01 Paul Eggert <eggert@cs.ucla.edu>
166
167 Fix minor problems found by static checking.
168 * dispextern.h, xdisp.c (x_draw_bottom_divider): Now static.
169 * frame.c (set_frame_param) [!HAVE_NTGUI]: Remove.
170 * xdisp.c (Ftool_bar_height) [USE_GTK || HAVE_NS]: Now const function.
171
1722013-12-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
173
174 * image.c (imagemagick_compute_animated_image): Don't crash if we
175 have an animation with different-sized images (bug#15313).
176
1772013-11-30 Martin Rudalics <rudalics@gmx.at>
178
179 Remove some unused items introduced during pixelwise change.
180 * window.c (window_resize_total_check): Remove unused function.
181 * xdisp.c (remember_mouse_glyph): Remove unused label.
182 (Ftool_bar_height): Move declaration inside #if.
183 * xterm.c (x_set_window_size): Don't use r and c.
184
1852013-11-30 Juanma Barranquero <lekktu@gmail.com>
186
187 * xdisp.c (Fwindow_text_pixel_size): Remove unused variables
188 `value' and `endp'.
189
190 * window.c (Fset_window_configuration): Comment out unused variables.
191
192 * w32term.c (w32_read_socket): Remove unused variable `buf'.
193
1942013-11-30 Jan Djärv <jan.h.d@swipnet.se>
195
196 * xdisp.c (redisplay_internal): unrequest_sigio => request_sigio.
197
198 * xfaces.c (NEAR_SAME_COLOR_THRESHOLD): Move inside HAVE_WINDOW_SYSTEM.
199
200 * gnutls.c (gnutls_audit_log_function): Only declare and define if
201 HAVE_GNUTLS3 (Bug#16001).
202
203 * xdisp.c (redisplay_internal): Call request_sigio at end_of_redisplay
204 if interrupts are deferred (Bug#15801).
205
2062013-11-30 Martin Rudalics <rudalics@gmx.at>
207
208 Support resizing frames and windows pixelwise.
209 * dispextern.h (enum window_part): Add ON_SCROLL_BAR,
210 ON_RIGHT_DIVIDER and ON_BOTTOM_DIVIDER.
211 (struct glyph_matrix): Replace window_left_col and
212 window_top_line by window_pixel_left and window_pixel_top.
213 (WINDOW_WANTS_MODELINE_P, WINDOW_WANTS_HEADER_LINE_P): Minor
214 rewrite.
215 (enum face_id): Add WINDOW_DIVIDER_FACE_ID.
216 (draw_window_divider, move_it_to, x_draw_right_divider)
217 (x_draw_bottom_divider, change_frame_size): Add or fix
218 declarations.
219 * dispnew.c (change_frame_size_1): Change prototype.
220 (adjust_glyph_matrix, required_matrix_width)
221 (adjust_frame_glyphs_for_window_redisplay): Use pixel
222 values instead of lines and columns.
223 (marginal_area_string): Use WINDOW_FRINGES_WIDTH instead of
224 WINDOW_TOTAL_FRINGE_WIDTH.
225 (handle_window_change_signal, do_pending_window_change)
226 (init_display): Adjusts calls of change_frame_size.
227 (change_frame_size, change_frame_size_1): Handle pixelwise
228 changes.
229 * frame.c (Qright_divider_width, Qbottom_divider_width): New
230 Lisp objects.
231 (set_menu_bar_lines_1, set_menu_bar_lines, make_frame)
232 (make_terminal_frame, Fmake_terminal_frame, Fframe_parameters)
233 (x_set_internal_border_width, x_set_vertical_scroll_bars)
234 (x_set_scroll_bar_width, x_figure_window_size): Handle pixel
235 values.
236 (set_frame_param): New function.
237 (Fframe_text_cols, Fframe_text_lines, Fframe_total_cols)
238 (Fframe_text_width, Fframe_text_height, Fscroll_bar_width)
239 (Ffringe_width, Fborder_width, Fright_divider_width)
240 (Fbottom_divider_width): New functions, defsubr them.
241 (Fset_frame_height, Fset_frame_width, Fset_frame_size): New
242 argument pixelwise.
243 (struct frame_parm_table): New members Qright_divider_width and
244 Qbottom_divider_width.
245 (x_set_frame_parameters): Handle parameters for pixelwise sizes.
246 (x_report_frame_params): Handle Qright_divider_width and
247 Qbottom_divider_width.
248 (x_set_right_divider_width, x_set_bottom_divider_width): New
249 functions.
250 (frame_resize_pixelwise): New option.
251 * frame.h (struct frame): Add tool_bar_height, menu_bar_height,
252 new_pixelwise, right_divider_width and bottom_divider_width;
253 remove total_lines; rename text_lines, text_cols, new_text_lines
254 and new_text_cols to text_height, text_width, new_height and
255 new_width respectively.
256 (FRAME_LINES, FRAME_COLS): Rename to FRAME_TEXT_HEIGHT and
257 FRAME_TEXT_WIDTH respectively.
258 (FRAME_MENU_BAR_HEIGHT, FRAME_TOOL_BAR_HEIGHT)
259 (FRAME_RIGHT_DIVIDER_WIDTH, FRAME_BOTTOM_DIVIDER_WIDTH)
260 (FRAME_TEXT_TO_PIXEL_WIDTH, FRAME_PIXEL_TO_TEXT_WIDTH): New
261 macros.
262 (FRAME_TOP_MARGIN_HEIGHT, FRAME_LEFT_SCROLL_BAR_AREA_WIDTH)
263 (FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH, FRAME_SCROLL_BAR_AREA_WIDTH)
264 (SET_FRAME_COLS, SET_FRAME_WIDTH, SET_FRAME_HEIGHT)
265 (FRAME_TEXT_COLS_TO_PIXEL_WIDTH, FRAME_PIXEL_WIDTH_TO_TEXT_COLS)
266 (FRAME_TEXT_COLS_TO_PIXEL_WIDTH): Rewrite macros.
267 (FRAME_TOTAL_COLS_ARG): Remove macro.
268 * fringe.c (draw_fringe_bitmap_1): Handle right divder.
269 * gtkutil.c (xg_frame_resized, xg_frame_set_char_size)
270 (x_wm_set_size_hint): Handle frame pixel sizes.
271 * indent.c (compute_motion, Fcompute_motion): Call
272 window_body_width instead of window_body_cols.
273 * keyboard.c (Qright_divider, Qbottom_divider): New symbols.
274 (make_lispy_position): Handle right and bottom dividers.
275 (Fsuspend_emacs): Pixelize call of change_frame_size.
276 * keyboard.h: Extern Qright_divider, Qbottom_divider.
277 * lisp.h: Extern set_frame_param.
278 * nsfns.m (x_set_tool_bar_lines): Pixelize call of
279 x_set_window_size.
280 (Fx_create_frame): Add entry for vertical_drag_cursor. Pixelize
281 call of change_frame_size.
282 * nsterm.h (struct ns_output): Add vertical_drag_cursor.
283 * nsterm.m (ns_update_window_end): Optionally draw right
284 divider.
285 (x_set_window_size): Add argument pixelwise. Call
286 check_frame_size and change_frame_size with pixelwise zero.
287 (ns_draw_window_divider): New function.
288 (ns_redisplay_interface): Add ns_draw_window_divider.
289 (updateFrameSize:): Call change_frame_size with pixelwise zero.
290 (x_new_font): Call x_set_window_size with pixelwise zero.
291 * print.c (print_object): For a window print its sequence
292 number again.
293 * term.c (Fresume_tty): Pixelize call of change_frame_size.
294 * w32fns.c (x_set_mouse_color): Handle vertical drag cursor.
295 (x_set_menu_bar_lines, x_set_tool_bar_lines): Calculate pixelwise.
296 (w32_createwindow): Use scroll bar area width.
297 (w32_wnd_proc): Handle bottom divider width. For
298 WM_WINDOWPOSCHANGING return zero if we resize pixelwise.
299 (Fx_create_frame): Default divider width parameters. Caclulate
300 sizes pixelwise. Add vertical drag cursor support.
301 (x_create_tip_frame): Default divider widths to zero. Pixelize
302 call to change_frame_size.
303 (Fx_show_tip): Add handling of divider widths. Pixelize window
304 position and sizes.
305 (Fw32_frame_rect): New function.
306 (frame_parm_handler w32_frame_parm_handlers): Add divider
307 widths.
308 (Vx_window_vertical_drag_shape): Add variable.
309 * w32inevt.c (resize_event, maybe_generate_resize_event):
310 Pixelize change_frame_size calls.
311 * w32menu.c (set_frame_menubar): Pixelize x_set_window_size
312 call.
313 * w32term.c (w32_draw_window_divider): New function.
314 (x_update_window_end): Handle right divider.
315 (w32_draw_fringe_bitmap, x_scroll_run)
316 (w32_set_vertical_scroll_bar): Pixelize scrollbar widths.
317 (w32_read_socket): Handle SIZE_MAXIMIZED separately. Calculate
318 new frame sizes pixelwise.
319 (x_new_font): Pixelize call to x_set_window_size.
320 (x_check_fullscreen): Pixelize call to change_frame_size.
321 (x_set_window_size_1, x_set_window_size): New argument
322 pixelwise. Calculate pixelwise.
323 (x_wm_set_size_hint): Use scroll bar area width.
324 (w32_redisplay_interface): Add w32_draw_window_divider.
325 * w32term.h (struct w32_output): Add vertical drag cursor.
326 * widget.c (set_frame_size, update_wm_hints)
327 (EmacsFrameResize, EmacsFrameSetValues): Pixelize calls of
328 change_frame_size.
329 (EmacsFrameSetCharSize): Pixelize call of x_set_window_size.
330 * window.c (sequence_number): Restore.
331 (Fwindow_pixel_width, Fwindow_pixel_height)
332 (Fwindow_mode_line_height, Fwindow_header_line_height)
333 (window_pixel_to_total, Frun_window_scroll_functions)
334 (Fset_window_new_pixel, window_resize_apply_total)
335 (Fwindow_resize_apply_total): New functions.
336 (window_body_height, window_body_width): Rename from
337 window_body_lines. New argument PIXELWISE. Calculate
338 pixelwise.
339 (Fwindow_body_height, Fwindow_body_width): New argument
340 PIXELWISE.
341 (coordinates_in_window, window_relative_x_coord): Use window's
342 pixel width instead of total width.
343 (replace_window, recombine_windows): Initialize pixel values.
344 (resize_root_window, resize_frame_windows, grow_mini_window)
345 (shrink_mini_window): New argument PIXELWISE. Calculate
346 pixelwise.
347 (Fdelete_other_windows_internal, adjust_window_margins)
348 (window_resize_check, window_resize_apply)
349 (Fdelete_window_internal, Fresize_mini_window_internal)
350 (Fwindow_text_width, Fwindow_text_height): Calculate pixelwise.
351 (check_frame_size): Rename arguments. New argument PIXELWISE.
352 Calculate pixelwise.
353 (set_window_buffer): Make samebuf bool. Run configuration change
354 hook only if buffer changed.
355 (Fset_window_buffer): Rewrite doc-string.
356 (make_window): Initialize new_pixel slot.
357 (Fwindow_resize_apply): Check pixel size of root window.
358 (Fsplit_window_internal): Call 2nd argument pixel_size.
359 Calculate pixelwise.
360 (Fscroll_left, Fscroll_right): Call window_body_width instead of
361 window_body_cols.
362 (save_window_data): New slots frame_text_width,
363 frame_text_height, frame_menu_bar_height, frame_tool_bar_height.
364 (saved_window): New slots pixel_left, pixel_top, pixel_height,
365 pixel_width.
366 (Fcurrent_window_configuration, Fset_window_configuration)
367 (save_window_save, compare_window_configurations): Handle new
368 slots in save_window_data and saved_window.
369 (Fset_window_scroll_bars): Fix doc-string.
370 (window_resize_pixelwise): New variable.
371 (coordinates_in_window, Fcoordinates_in_window_p): Handle
372 dividers.
373 (make_parent_window): Adjust sequence_number.
374 (Fwindow_right_divider_width, Fwindow_bottom_divider_width): New
375 functions.
376 * window.h (struct window): New members new_pixel, pixel_left,
377 pixel_top, pixel_width, pixel_height. Restore sequence_number.
378 (wset_new_pixel): New function.
379 (WINDOW_PIXEL_WIDTH, WINDOW_PIXEL_HEIGHT)
380 (MIN_SAFE_WINDOW_PIXEL_WIDTH, MIN_SAFE_WINDOW_PIXEL_HEIGHT)
381 (WINDOW_LEFT_PIXEL_EDGE, WINDOW_RIGHT_PIXEL_EDGE)
382 (WINDOW_TOP_PIXEL_EDGE, WINDOW_BOTTOM_PIXEL_EDGE)
383 (WINDOW_BOTTOMMOST_P, WINDOW_BOX_LEFT_PIXEL_EDGE)
384 (WINDOW_BOX_RIGHT_PIXEL_EDGE, WINDOW_MARGINS_COLS)
385 (WINDOW_MARGINS_WIDTH, WINDOW_RIGHT_DIVIDER_WIDTH)
386 (WINDOW_BOTTOM_DIVIDER_WIDTH): New macros.
387 (WINDOW_TOTAL_FRINGE_WIDTH): Rename to WINDOW_FRINGES_WIDTH.
388 (WINDOW_TOTAL_WIDTH, WINDOW_TOTAL_HEIGHT): Remove macros.
389 (WINDOW_RIGHT_EDGE_X, WINDOW_LEFT_EDGE_X, WINDOW_TOP_EDGE_Y)
390 (WINDOW_BOTTOM_EDGE_Y, WINDOW_FULL_WIDTH_P, WINDOW_LEFTMOST_P)
391 (WINDOW_RIGHTMOST_P, WINDOW_BOX_LEFT_EDGE_X)
392 (WINDOW_BOX_RIGHT_EDGE_X, WINDOW_FRINGE_COLS)
393 (WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT):
394 Rewrite.
395 (resize_frame_windows, grow_mini_window, shrink_mini_window)
396 (window_body_width, check_frame_size): Adapt external declarations.
397 * xdisp.c (last_max_ascent): New integer.
398 (window_text_bottom_y): Handle bottom divider.
399 (window_box_width, window_box_height): Calculate pixelwise.
400 (get_glyph_string_clip_rects): Handle right divider.
401 (remember_mouse_glyph): When windows are resized pixelwise
402 proceed with width and height set to 1.
403 (init_iterator): Use WINDOW_PIXEL_WIDTH instead of
404 WINDOW_TOTAL_WIDTH.
405 (move_it_to): Calculate and return maximum x position
406 encountered.
407 (Fwindow_text_pixel_size): New function.
408 (resize_mini_window, update_tool_bar): Calculate pixelwise.
409 (tool_bar_lines_needed): Rename to tool_bar_height. Calculate
410 pixelwise.
411 (Ftool_bar_lines_needed): Rename to Ftool_bar_height. Calculate
412 pixelwise.
413 (redisplay_tool_bar): Calculate pixelwise.
414 (redisplay_window): Calculate pixelwise. Handle dividers.
415 (draw_glyphs, x_clear_end_of_line, note_mouse_highlight)
416 (x_draw_vertical_border): Handle dividers.
417 (define_frame_cursor1): Handle vertical drag cursor.
418 (x_draw_right_divider, x_draw_bottom_divider): New functions.
419 (expose_window): Calculate pixelwise. Handle dividers.
420 (init_xdisp): Initialize pixel values.
421 * xfaces.c (Qwindow_divider): New face.
422 (realize_basic_faces): Realize it.
423 * xfns.c (x_set_mouse_color): Handle vertical_drag_cursor.
424 (x_set_menu_bar_lines, x_set_tool_bar_lines): Calculate pixelwise.
425 (x_set_scroll_bar_default_width): Default actual width to 16.
426 (Fx_create_frame): Set sizes pixelwise.
427 (x_create_tip_frame): Default divider widths to zero. Pixelize
428 call of change_frame_size.
429 (Fx_show_tip): Handle divider widths. Initial pixel position
430 and sizes.
431 (frame_parm_handler x_frame_parm_handlers): Add divider widths.
432 (Vx_window_vertical_drag_shape): New option.
433 * xmenu.c (free_frame_menubar): Pixelize call of
434 x_set_window_size.
435 * xterm.c (x_draw_window_divider): New function.
436 (x_update_window_end): Optionally draw right divider.
437 (x_draw_fringe_bitmap, x_scroll_run, x_scroll_bar_create)
438 (XTset_vertical_scroll_bar): Use scroll bar pixel width.
439 (handle_one_xevent, x_new_font): Calculate pixelwise.
440 (x_set_window_size_1, x_set_window_size): New argument
441 pixelwise. Calculate pixelwise.
442 (x_wm_set_size_hint): Pixelize call of check_frame_size.
443 (struct x_redisplay_interface): Add x_draw_window_divider.
444 * xterm.h (struct x_output): Add vertical_drag_cursor.
445
4462013-11-30 Stefan Monnier <monnier@iro.umontreal.ca>
447
448 * xdisp.c (redisplay_internal): Don't call set_window_update_flags.
449 Set invisible frames's `redisplay' when a full redisplay is requested.
450 (redisplay_window): Set must_be_updated_p instead (bug#15999).
451 (redisplay_mode_lines): Don't set must_be_updated_p any more.
452 (display_mode_lines): Set it here instead.
453
454 * dispnew.c (set_window_update_flags): Remove `b' argument; make static.
455
456 * dispextern.h (set_window_update_flags): Remove.
457
4582013-11-29 Stefan Monnier <monnier@iro.umontreal.ca>
459
460 * fns.c (internal_equal): Add a hash_table argument to handle cycles.
461
462 * xdisp.c (REDISPLAY_SOME_P): New macro.
463 (redisplay_internal): Use it (bug#15999).
464 (prepare_menu_bars, redisplay_window): Use it as well.
465
466 * lisp.mk (lisp): Add electric.elc and uniquify.elc.
467
4682013-11-29 Tom Seddon <emacs@tomseddon.plus.com> (tiny change)
469
470 * w32font.c (g_b_init_get_char_width_32_w): New static var.
471 (globals_of_w32font): Zero it out.
472 (GetCharWidth32W_Proc): New function pointer.
473 (get_char_width_32_w): New function.
474 (compute_metrics): If get_glyph_outline_w returns an error, try
475 get_char_width_32_w before declaring a failure. This avoids
476 punishing raster (a.k.a. "bitmap") fonts by slowing down
477 redisplay. (Bug#6364).
478
4792013-11-29 Eli Zaretskii <eliz@gnu.org>
480
481 * xdisp.c (clear_mouse_face): Don't invalidate the entire
482 mouse-highlight info, just signal frame_up_to_date_hook that mouse
483 highlight needs to be redisplayed. (Bug#15913)
484
4852013-11-29 Paul Eggert <eggert@cs.ucla.edu>
486
487 Fix minor problems found by static checking.
488 * buffer.h (struct buffer_text, struct buffer):
489 * frame.h (struct frame):
490 * window.h (struct window):
491 Avoid 'bool foo : 1;', as it's not portable to pre-C99 compilers,
492 as described in ../lib/stdbool.in.h. Use 'unsigned foo : 1;' instead.
493 * menu.c (syms_of_menu): Define x-popup-dialog, removing a
494 no-longer-valid use of HAVE_MENUS.
495 * xdisp.c (propagate_buffer_redisplay): Now static.
496
4972013-11-29 Stefan Monnier <monnier@iro.umontreal.ca>
498
499 * xmenu.c (Fmenu_or_popup_active_p):
500 * window.c (Fset_window_configuration):
501 * menu.c (Fx_popup_menu, Fx_popup_dialog):
502 * keyboard.c (record_menu_key, read_char_x_menu_prompt):
503 * fns.c (Fyes_or_no_p):
504 * editfns.c (Fmessage_box, Fmessage_or_box):
505 * alloc.c (make_save_ptr_ptr):
506 * xdisp.c, w32menu.c, term.c, xterm.h, xterm.c: Remove HAVE_MENUS.
507
508 * window.c (Fset_window_configuration): Move select_window later.
509
5102013-11-28 Stefan Monnier <monnier@iro.umontreal.ca>
511
512 Refine redisplay optimizations to only redisplay *some* frames/windows
513 rather than all of them.
514 * xdisp.c (REDISPLAY_SOME): New constant.
515 (redisplay_other_windows, wset_redisplay, fset_redisplay)
516 (bset_redisplay, bset_update_mode_line): New functions.
517 (message_dolog): Use bset_redisplay.
518 (clear_garbaged_frames): Use fset_redisplay.
519 (echo_area_display): Use wset_redisplay.
520 (buffer_shared_and_changed): Remove.
521 (prepare_menu_bars): Call Vpre_redisplay_function before updating
522 frame titles. Compute the actual set of windows redisplayed.
523 Don't update frame titles and menu bars for frames that don't need to
524 be redisplayed.
525 (propagate_buffer_redisplay): New function.
526 (AINC): New macro.
527 (redisplay_internal): Use it. Be more selective in the set of windows
528 we redisplay. Propagate windows_or_buffers_changed to
529 update_mode_lines a bit later to simplify the code.
530 (mark_window_display_accurate_1): Reset window and buffer's
531 `redisplay' flag.
532 (redisplay_window): Do nothing if neither the window nor the buffer nor
533 the frame needs redisplay.
534 * window.h (struct window): Add `redisplay' field.
535 (wset_redisplay, fset_redisplay, bset_redisplay, bset_update_mode_line)
536 (redisplay_other_windows, window_list): New declarations.
537 * window.c (select_window, Fset_window_start): Use wset_redisplay.
538 (window_list): Not static any more.
539 (grow_mini_window, shrink_mini_window): Use fset_redisplay.
540 * minibuf.c (read_minibuf_unwind): Don't redisplay everything.
541 * insdel.c (prepare_to_modify_buffer_1): Use bset_redisplay.
542 * frame.c (Fmake_frame_visible): Don't redisplay everything.
543 * frame.h (struct frame): Add `redisplay' field.
544 Move `external_menu_bar' bitfield next to other bit-fields.
545 (SET_FRAME_GARBAGED): Use fset_redisplay.
546 (SET_FRAME_VISIBLE): Don't garbage the frame;
547 Use redisplay_other_windows.
548 * buffer.h (struct buffer): Add `redisplay' field.
549 * buffer.c (Fforce_mode_line_update): Pay attention to the `all' flag.
550 (modify_overlay): Use bset_redisplay.
551 * alloc.c (gc_sweep): Don't unmark strings while sweeping symbols.
552
5532013-11-28 Eli Zaretskii <eliz@gnu.org>
554
555 Support w32 file notifications in batch mode.
556 * w32proc.c (sys_select): Don't wait on interrupt_handle if it is
557 invalid (which happens in batch mode). If non-interactive, call
558 handle_file_notifications to store file notification events in the
559 input queue. (Bug#15933)
560
561 * w32notify.c (send_notifications): Handle FRAME_INITIAL frames as well.
562
563 * w32inevt.c (handle_file_notifications): Now external, not static.
564
565 * w32term.h (handle_file_notifications): Provide prototype.
566
567 * emacs.c (main) [HAVE_W32NOTIFY]: When non-interactive, call
568 init_crit, since init_display, which does that otherwise, is not
569 called.
570
5712013-11-27 Glenn Morris <rgm@gnu.org>
572
573 * Makefile.in ($(lispsource)/international/charprop.el): New.
574 (emacs$(EXEEXT)): Depend on charprop.el.
575
5762013-11-27 Eli Zaretskii <eliz@gnu.org>
577
578 * fileio.c (Finsert_file_contents): Invalidate buffer caches when
579 deleting portions of the buffer under non-nil REPLACE argument.
580 (Bug#15973)
581
582 * w32notify.c (Fw32notify_add_watch): If the argument FILE is a
583 directory, watch it and not its parent.
584 (add_watch): Allow empty string in FILE.
585
5862013-11-27 Martin Rudalics <rudalics@gmx.at>
587
588 * window.c (Fset_window_start, window_resize_apply)
589 (window_scroll): Reset window_end_valid (Bug#15957).
590
5912013-11-27 Glenn Morris <rgm@gnu.org>
592
593 * Makefile.in (leimdir): Now in lisp source directory.
594 ($(leimdir)/leim-list.el): Just use ../leim .
595 * epaths.in (PATH_DUMPLOADSEARCH):
596 * lread.c (load_path_default):
597 * nsterm.m (ns_load_path): No more leim directory.
598
5992013-11-26 Andreas Schwab <schwab@suse.de>
600
601 * .gdbinit (xgettype): Add cast.
602
6032013-11-26 Glenn Morris <rgm@gnu.org>
604
605 Preload leim-list.el.
606 * epaths.in (PATH_DUMPLOADSEARCH): Add leim/.
607 * callproc.c (init_callproc): Don't assume PATH_DUMPLOADSEARCH
608 is a single directory.
609
6102013-11-25 Paul Eggert <eggert@cs.ucla.edu>
611
612 bool-vector-subsetp is now the normal direction (Bug#15912).
613 * data.c (Fbool_vector_subsetp): Test whether the first argument
614 is a subset of the second one, not the reverse. Add doc string.
615
616 Fix minor problems found by static checking.
617 * lread.c (load_path_default): Now static.
618 * textprop.c (text_property_stickiness): Be consistent about the
619 test used when deciding whether to consider the previous character.
620 This simplifies the code a bit.
621
6222013-11-25 Stefan Monnier <monnier@iro.umontreal.ca>
623
624 * textprop.c (text_property_stickiness): Fix front-stickiness at BOB.
625
626 * frame.c (Fhandle_focus_in, Fhandle_focus_out): Move to frame.el.
627 (syms_of_frame): Don't defsubr them.
628
6292013-11-25 Glenn Morris <rgm@gnu.org>
630
631 * lread.c (load_path_default): Change the sense of the argument.
632 (init_lread): When EMACSLOADPATH is set, do not ignore changes
633 from dump_path. When it is not, avoid checking dump_path twice.
634
635 * lread.c (init_lread): Fix 2013-11-23 goof that was checking
636 uninstalled dump_path against installed Vload_path. (Bug#15964)
637
6382013-11-24 Stefan Monnier <monnier@iro.umontreal.ca>
639
640 Export get_pos_property to Elisp.
641 * editfns.c (Fget_pos_property): Rename from get_pos_property.
642 (syms_of_editfns): Export it to Elisp.
643
644 * data.c (Fmake_variable_buffer_local): Mention `permanent-local'.
645
6462013-11-23 Romain Francoise <romain@orebokech.com>
647
648 * fileio.c (init_fileio): Move `write_region_inhibit_fsync'
649 initialization here ...
650 (syms_of_fileio): ... from here.
651
6522013-11-23 Stefan Monnier <monnier@iro.umontreal.ca>
653
654 * lread.c (init_lread): Fix int/Lisp_Object mixup.
655 Please use --enable-check-lisp-object-type.
656
6572013-11-23 Glenn Morris <rgm@gnu.org>
658
659 * process.c (get_process): Explicit error for dead buffers.
660
6612013-11-23 Andreas Schwab <schwab@linux-m68k.org>
662
663 * process.c (get_process): Check that OBJ is a live buffer. (Bug#15923)
664
6652013-11-23 Glenn Morris <rgm@gnu.org>
666
667 Empty elements in EMACSLOADPATH stand for the default. (Bug#12100)
668 * lread.c (load_path_check): Take path to check as argument.
669 (load_path_default): New, split from init_lread.
670 (init_lread): Move calc of default load-path to load_path_default.
671 Empty elements in EMACSLOADPATH now stand for the default.
672 (load-path): Doc fix.
673 * emacs.c (decode_env_path): Add option to treat empty elements
674 as nil rather than ".".
675 * callproc.c (init_callproc_1, init_callproc):
676 * image.c (Vx_bitmap_file_path):
677 * lisp.h (decode_env_path):
678 * lread.c (Vsource_directory):
679 Update for new argument spec of decode_env_path.
680
6812013-11-22 Eli Zaretskii <eliz@gnu.org>
682
683 * bidi.c (bidi_find_paragraph_start): Limit the returned positions
684 to BEGV_BYTE..ZV_BYTE range. (Bug#15951)
685
6862013-11-21 Paul Eggert <eggert@cs.ucla.edu>
687
688 Fix some dependency problems that cause unnecessary recompiles.
689 Problem reported by RMS in
690 <http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00421.html>.
691 * Makefile.in (OLDXMENU_TARGET, OLDXMENU, OLDXMENU_DEPS)
692 (really-lwlib, really-oldXMenu, stamp-oldxmenu)
693 (../src/$(OLDXMENU), $(OLDXMENU)): Remove.
694 (temacs$(EXEEXT)): Depend on $(LIBXMENU), not stamp-oldxmenu.
695 ($(lwlibdir)/liblw.a, $(oldXMenudir)/libXMenu11.a, FORCE): New targets.
696 (boostrap-clean): No need to remove stamp-oldxmenu.
697
698 Fix recently introduced bool vector overrun.
699 This was due to an optimization that went awry.
700 Reported by Glenn Morris in
701 <http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00622.html>.
702 * alloc.c (make_uninit_bool_vector): Don't allocate a dummy word
703 for empty vectors, undoing the 2013-11-18 change.
704 * data.c (bool_vector_binop_driver): Rely on this.
705 Fix bug that occasionally overran the destination.
706 * lisp.h (struct Lisp_Bool_vector): Document this.
707
7082013-11-20 Jan Djärv <jan.h.d@swipnet.se>
709
710 * nsterm.m (init, run, stop:): Enable again. stop calls super stop
711 to handle dialogs.
712
713 * nsterm.m (init, run, stop:): Comment out for now, does not work
714 with dialogs.
715
7162013-11-19 Paul Eggert <eggert@cs.ucla.edu>
717
718 * charset.c (syms_of_charset): Don't read past end of string.
719
7202013-11-19 Glenn Morris <rgm@gnu.org>
721
722 * frame.c (Fhandle_focus_in, Fhandle_focus_out): Doc fixes.
723
7242013-11-19 Brian Jenkins <brian@brianjenkins.org> (tiny change)
725
726 Add hooks to run on gaining/losing focus. (Bug#15029)
727 * frame.c (Qfocus_in_hook, Qfocus_out_hook): New static lisp objects.
728 (Fhandle_focus_in, Fhandle_focus_out): Run focus hooks.
729 (syms_of_frame): Add focus-in-hook, focus-out-hook.
730
7312013-11-18 Paul Eggert <eggert@cs.ucla.edu>
732
733 * data.c (bool_vector_binop_driver): Rename locals for sanity's sake.
734 The old names predated the API change that put destination at end.
735
736 Improve API of recently-added bool vector functions (Bug#15912).
737 The old API had (bool-vector-count-matches A B)
738 and (bool-vector-count-matches-at A B I), which gave the
739 misleading impression that the two functions were variants, one
740 with a location I. The new API has (bool-vector-count-population A)
741 and (bool-vector-count-consecutive A B I) to make the distinction
742 clearer. The first function no longer has a B argument, since the
743 caller can easily determine the number of nils if the length and
744 number of ts is known.
745 * data.c (Fbool_vector_count_population): Rename from
746 bool_vector_count_matches, and accept just 1 argument.
747 (Fbool_vector_count_consecutive): Rename from
748 Fbool_vector_count_matches_at.
749
750 Always allocate at least one bits_word per bool vector.
751 See Daniel Colascione in:
752 http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00518.html
753 * alloc.c (make_uninit_bool_vector): Always allocate at least one word.
754 * data.c (bool_vector_binop_driver): Rely on this. Tune.
755 * lisp.h (struct Lisp_Bool_vector): Document this.
756
12013-11-18 Eli Zaretskii <eliz@gnu.org> 7572013-11-18 Eli Zaretskii <eliz@gnu.org>
2 758
3 * insdel.c (invalidate_buffer_caches): New function, consolidated 759 * insdel.c (invalidate_buffer_caches): New function, consolidated
4 from part of prepare_to_modify_buffer. 760 from part of prepare_to_modify_buffer.
5 (insert_from_gap, prepare_to_modify_buffer): 761 (insert_from_gap, prepare_to_modify_buffer):
6 * coding.c (code_convert_region, code_convert_string): Call 762 * coding.c (code_convert_region, code_convert_string):
7 invalidate_buffer_caches. (Bug#15841) 763 Call invalidate_buffer_caches. (Bug#15841)
8 764
9 * lisp.h (invalidate_buffer_caches): Add prototype. 765 * lisp.h (invalidate_buffer_caches): Add prototype.
10 766
@@ -141,7 +897,7 @@
141 "dumb loop", adjust C pointers into buffer text to follow suit. 897 "dumb loop", adjust C pointers into buffer text to follow suit.
142 (Bug#15841) 898 (Bug#15841)
143 899
1442013-11-09 Łukasz Stelmach <stlman@poczta.fm> (tiny change) 9002013-11-09 Łukasz Stelmach <stlman@poczta.fm> (tiny change)
145 901
146 * gtkutil.c (xg_check_special_colors): Use rgb: instead of rgbi: 902 * gtkutil.c (xg_check_special_colors): Use rgb: instead of rgbi:
147 for conversion (Bug#15837). 903 for conversion (Bug#15837).
diff --git a/src/ChangeLog.12 b/src/ChangeLog.12
index b14ce20ede3..02940840eaa 100644
--- a/src/ChangeLog.12
+++ b/src/ChangeLog.12
@@ -2840,7 +2840,7 @@
28402012-11-19 Daniel Colascione <dancol@dancol.org> 28402012-11-19 Daniel Colascione <dancol@dancol.org>
2841 2841
2842 * w32fns.c (Fx_file_dialog): 2842 * w32fns.c (Fx_file_dialog):
2843 (Fx_file_dialog): Accomodate rename of cygwin_convert_path* to 2843 (Fx_file_dialog): Accommodate rename of cygwin_convert_path* to
2844 cygwin_convert_file_name*. 2844 cygwin_convert_file_name*.
2845 2845
2846 * cygw32.c (Fcygwin_convert_path_to_windows, syms_of_cygw32): 2846 * cygw32.c (Fcygwin_convert_path_to_windows, syms_of_cygw32):
diff --git a/src/Makefile.in b/src/Makefile.in
index ca0b25a2f69..7d91928acfe 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -52,7 +52,7 @@ lispsource = $(srcdir)/../lisp
52lib = ../lib 52lib = ../lib
53libsrc = ../lib-src 53libsrc = ../lib-src
54etc = ../etc 54etc = ../etc
55leimdir = ../leim 55leimdir = ${lispsource}/leim
56oldXMenudir = ../oldXMenu 56oldXMenudir = ../oldXMenu
57lwlibdir = ../lwlib 57lwlibdir = ../lwlib
58 58
@@ -179,30 +179,8 @@ LIBXTR6=@LIBXTR6@
179LIBXT_OTHER=@LIBXT_OTHER@ 179LIBXT_OTHER=@LIBXT_OTHER@
180 180
181## If !HAVE_X11 || USE_GTK, empty. 181## If !HAVE_X11 || USE_GTK, empty.
182## Else if USE_X_TOOLKIT really-lwlib, else really-oldxmenu.
183OLDXMENU_TARGET=@OLDXMENU_TARGET@
184
185## If !HAVE_X11 || USE_GTK, empty.
186## Else if USE_X_TOOLKIT, $(lwlibdir)/liblw.a. 182## Else if USE_X_TOOLKIT, $(lwlibdir)/liblw.a.
187## Else $(oldXMenudir)/libXMenu11.a. 183## Else $(oldXMenudir)/libXMenu11.a.
188## (Actually, rather than being empty, it is set to "nothing".
189## It is never actually used for anything in this case.
190## This is done because there is a rule with target $(OLDXMENU) below,
191## and I think it might be a syntax error with some makes to have
192## an empty target, even if the associated rule is never run.
193## http://lists.gnu.org/archive/html/help-make/2010-05/msg00058.html
194## The alternative would be to put that rule in a makefile fragment.)
195OLDXMENU=@OLDXMENU@
196
197## If HAVE_X11 && !USE_GTK, $(OLDXMENU) ../src/$(OLDXMENU); else empty.
198## We use stamp-xmenu with these two deps to both ensure that lwlib
199## gets remade based on its dependencies in its own makefile,
200## and remake temacs if lwlib gets changed by this.
201OLDXMENU_DEPS=@OLDXMENU_DEPS@
202
203## If !HAVE_X11 && HAVE_X_WINDOWS, -lXMenu (this case no longer possible).
204## Else if !HAVE_X11 || USE_GTK, empty.
205## Else $(OLDXMENU).
206LIBXMENU=@LIBXMENU@ 184LIBXMENU=@LIBXMENU@
207 185
208## xmenu.o if HAVE_X_WINDOWS, else empty. 186## xmenu.o if HAVE_X_WINDOWS, else empty.
@@ -222,7 +200,7 @@ LIBXT=$(TOOLKIT_LIBW) $(LIBXT_OTHER)
222## If HAVE_X11, $(LIBXT) $(LIBX_EXTRA), else empty. 200## If HAVE_X11, $(LIBXT) $(LIBX_EXTRA), else empty.
223LIBX_OTHER=@LIBX_OTHER@ 201LIBX_OTHER=@LIBX_OTHER@
224 202
225## LIBXMENU is nil if !HAVE_X_WINDOWS. 203## LIBXMENU is empty if !HAVE_X_WINDOWS.
226## LD_SWITCH_X_SITE should not be used if not using X, but nothing 204## LD_SWITCH_X_SITE should not be used if not using X, but nothing
227## sets it at present, and if something ever does, it should be 205## sets it at present, and if something ever does, it should be
228## configure, which should set it to nil in non-X builds. 206## configure, which should set it to nil in non-X builds.
@@ -437,7 +415,10 @@ all: emacs$(EXEEXT) $(OTHER_FILES)
437.PHONY: all 415.PHONY: all
438 416
439$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT) 417$(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
440 cd $(leimdir) && $(MAKE) $(MFLAGS) leim-list.el EMACS="$(bootstrap_exe)" 418 cd ../leim && $(MAKE) $(MFLAGS) leim-list.el EMACS="$(bootstrap_exe)"
419
420$(lispsource)/international/charprop.el: bootstrap-emacs$(EXEEXT)
421 cd ../admin/unidata && $(MAKE) $(MFLAGS) all EMACS="../$(bootstrap_exe)"
441 422
442## The dumped Emacs is as functional and more efficient than 423## The dumped Emacs is as functional and more efficient than
443## bootstrap-emacs, so we replace the latter with the former. 424## bootstrap-emacs, so we replace the latter with the former.
@@ -445,7 +426,8 @@ $(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT)
445## since not all pieces are used on all platforms. But DOC depends 426## since not all pieces are used on all platforms. But DOC depends
446## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here. 427## on all of $lisp, and emacs depends on DOC, so it is ok to use $lisp here.
447emacs$(EXEEXT): temacs$(EXEEXT) $(ADDSECTION) \ 428emacs$(EXEEXT): temacs$(EXEEXT) $(ADDSECTION) \
448 $(etc)/DOC $(lisp) $(leimdir)/leim-list.el 429 $(etc)/DOC $(lisp) $(leimdir)/leim-list.el \
430 $(lispsource)/international/charprop.el
449 if test "$(CANNOT_DUMP)" = "yes"; then \ 431 if test "$(CANNOT_DUMP)" = "yes"; then \
450 rm -f emacs$(EXEEXT); \ 432 rm -f emacs$(EXEEXT); \
451 ln temacs$(EXEEXT) emacs$(EXEEXT); \ 433 ln temacs$(EXEEXT) emacs$(EXEEXT); \
@@ -504,7 +486,7 @@ $(lib)/libgnu.a: $(config_h)
504## existence when setting Vinstallation_directory (FIXME?). 486## existence when setting Vinstallation_directory (FIXME?).
505## This goes on to affect various things, and the emacs binary fails 487## This goes on to affect various things, and the emacs binary fails
506## to start if Vinstallation_directory has the wrong value. 488## to start if Vinstallation_directory has the wrong value.
507temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \ 489temacs$(EXEEXT): $(LIBXMENU) $(ALLOBJS) \
508 $(lib)/libgnu.a $(EMACSRES) 490 $(lib)/libgnu.a $(EMACSRES)
509 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \ 491 $(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
510 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES) 492 -o temacs $(ALLOBJS) $(lib)/libgnu.a $(W32_RES_LINK) $(LIBES)
@@ -514,29 +496,17 @@ temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \
514 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT) 496 test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT)
515 497
516## The following oldxmenu-related rules are only (possibly) used if 498## The following oldxmenu-related rules are only (possibly) used if
517## HAVE_X11 && !USE_GTK, but there is no harm in always defining them 499## HAVE_X11 && !USE_GTK, but there is no harm in always defining them.
518## (provided we take a little care that OLDXMENU is never empty). 500$(lwlibdir)/liblw.a: $(config_h) globals.h lisp.h FORCE
519really-lwlib: globals.h 501 cd $(lwlibdir) && \
520 cd $(lwlibdir); $(MAKE) $(MFLAGS) \ 502 $(MAKE) $(MFLAGS) CC='$(CC)' CFLAGS='$(CFLAGS)' MAKE='$(MAKE)' \
521 CC='$(CC)' CFLAGS='$(CFLAGS)' MAKE='$(MAKE)' 503 liblw.a
522 @true # make -t should not create really-lwlib. 504$(oldXMenudir)/libXMenu11.a: FORCE
523.PHONY: really-lwlib 505 cd $(oldXMenudir) && \
524 506 $(MAKE) $(MFLAGS) CC='$(CC)' CFLAGS='$(CFLAGS)' MAKE='$(MAKE)' \
525really-oldXMenu: 507 libXMenu11.a
526 cd $(oldXMenudir); $(MAKE) $(MFLAGS) \ 508FORCE:
527 CC='$(CC)' CFLAGS='$(CFLAGS)' MAKE='$(MAKE)' 509.PHONY: FORCE
528 @true # make -t should not create really-oldXMenu.
529.PHONY: really-oldXMenu
530
531## We do not really need this when OLDXMENU_DEPS is empty, but as
532## things stand we need something to satisfy the temacs dependency.
533stamp-oldxmenu: $(OLDXMENU_DEPS)
534 touch stamp-oldxmenu
535
536## Supply an ordering for parallel make.
537../src/$(OLDXMENU): $(OLDXMENU)
538
539$(OLDXMENU): $(OLDXMENU_TARGET)
540 510
541../config.status: config.in epaths.in 511../config.status: config.in epaths.in
542 @echo "The file ${?:.in=.h} needs to be set up from $?." 512 @echo "The file ${?:.in=.h} needs to be set up from $?."
@@ -572,7 +542,7 @@ clean: mostlyclean
572## It should remove all files generated during a compilation/bootstrap, 542## It should remove all files generated during a compilation/bootstrap,
573## but not things like config.status or TAGS. 543## but not things like config.status or TAGS.
574bootstrap-clean: clean 544bootstrap-clean: clean
575 rm -f epaths.h config.h config.stamp stamp-h1 stamp-oldxmenu 545 rm -f epaths.h config.h config.stamp stamp-h1
576 if test -f ./.gdbinit; then \ 546 if test -f ./.gdbinit; then \
577 mv ./.gdbinit ./.gdbinit.save; \ 547 mv ./.gdbinit ./.gdbinit.save; \
578 if test -f "$(srcdir)/.gdbinit"; then rm -f ./.gdbinit.save; \ 548 if test -f "$(srcdir)/.gdbinit"; then rm -f ./.gdbinit.save; \
diff --git a/src/alloc.c b/src/alloc.c
index f12fdc5c861..f076075a94f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2066,20 +2066,20 @@ Lisp_Object
2066make_uninit_bool_vector (EMACS_INT nbits) 2066make_uninit_bool_vector (EMACS_INT nbits)
2067{ 2067{
2068 Lisp_Object val; 2068 Lisp_Object val;
2069 struct Lisp_Bool_Vector *p; 2069 EMACS_INT words = bool_vector_words (nbits);
2070 EMACS_INT word_bytes, needed_elements; 2070 EMACS_INT word_bytes = words * sizeof (bits_word);
2071 word_bytes = bool_vector_words (nbits) * sizeof (bits_word); 2071 EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes
2072 needed_elements = ((bool_header_size - header_size + word_bytes 2072 + word_size - 1)
2073 + word_size - 1) 2073 / word_size);
2074 / word_size); 2074 struct Lisp_Bool_Vector *p
2075 p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements); 2075 = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
2076 XSETVECTOR (val, p); 2076 XSETVECTOR (val, p);
2077 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); 2077 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2078 p->size = nbits; 2078 p->size = nbits;
2079 2079
2080 /* Clear padding at the end. */ 2080 /* Clear padding at the end. */
2081 if (nbits) 2081 if (words)
2082 p->data[bool_vector_words (nbits) - 1] = 0; 2082 p->data[words - 1] = 0;
2083 2083
2084 return val; 2084 return val;
2085} 2085}
@@ -3477,7 +3477,7 @@ make_save_ptr_int (void *a, ptrdiff_t b)
3477 return val; 3477 return val;
3478} 3478}
3479 3479
3480#if defined HAVE_MENUS && ! (defined USE_X_TOOLKIT || defined USE_GTK) 3480#if ! (defined USE_X_TOOLKIT || defined USE_GTK)
3481Lisp_Object 3481Lisp_Object
3482make_save_ptr_ptr (void *a, void *b) 3482make_save_ptr_ptr (void *a, void *b)
3483{ 3483{
@@ -4317,7 +4317,7 @@ live_buffer_p (struct mem_node *m, void *p)
4317void dump_zombies (void) EXTERNALLY_VISIBLE; 4317void dump_zombies (void) EXTERNALLY_VISIBLE;
4318 4318
4319/* Array of objects that are kept alive because the C stack contains 4319/* Array of objects that are kept alive because the C stack contains
4320 a pattern that looks like a reference to them . */ 4320 a pattern that looks like a reference to them. */
4321 4321
4322#define MAX_ZOMBIES 10 4322#define MAX_ZOMBIES 10
4323static Lisp_Object zombies[MAX_ZOMBIES]; 4323static Lisp_Object zombies[MAX_ZOMBIES];
@@ -6291,7 +6291,7 @@ survives_gc_p (Lisp_Object obj)
6291 6291
6292 6292
6293 6293
6294/* Sweep: find all structures not marked, and free them. */ 6294/* Sweep: find all structures not marked, and free them. */
6295 6295
6296static void 6296static void
6297gc_sweep (void) 6297gc_sweep (void)
@@ -6303,7 +6303,7 @@ gc_sweep (void)
6303 sweep_strings (); 6303 sweep_strings ();
6304 check_string_bytes (!noninteractive); 6304 check_string_bytes (!noninteractive);
6305 6305
6306 /* Put all unmarked conses on free list */ 6306 /* Put all unmarked conses on free list. */
6307 { 6307 {
6308 register struct cons_block *cblk; 6308 register struct cons_block *cblk;
6309 struct cons_block **cprev = &cons_block; 6309 struct cons_block **cprev = &cons_block;
@@ -6380,7 +6380,7 @@ gc_sweep (void)
6380 total_free_conses = num_free; 6380 total_free_conses = num_free;
6381 } 6381 }
6382 6382
6383 /* Put all unmarked floats on free list */ 6383 /* Put all unmarked floats on free list. */
6384 { 6384 {
6385 register struct float_block *fblk; 6385 register struct float_block *fblk;
6386 struct float_block **fprev = &float_block; 6386 struct float_block **fprev = &float_block;
@@ -6426,7 +6426,7 @@ gc_sweep (void)
6426 total_free_floats = num_free; 6426 total_free_floats = num_free;
6427 } 6427 }
6428 6428
6429 /* Put all unmarked intervals on free list */ 6429 /* Put all unmarked intervals on free list. */
6430 { 6430 {
6431 register struct interval_block *iblk; 6431 register struct interval_block *iblk;
6432 struct interval_block **iprev = &interval_block; 6432 struct interval_block **iprev = &interval_block;
@@ -6475,7 +6475,7 @@ gc_sweep (void)
6475 total_free_intervals = num_free; 6475 total_free_intervals = num_free;
6476 } 6476 }
6477 6477
6478 /* Put all unmarked symbols on free list */ 6478 /* Put all unmarked symbols on free list. */
6479 { 6479 {
6480 register struct symbol_block *sblk; 6480 register struct symbol_block *sblk;
6481 struct symbol_block **sprev = &symbol_block; 6481 struct symbol_block **sprev = &symbol_block;
@@ -6512,7 +6512,7 @@ gc_sweep (void)
6512 { 6512 {
6513 ++num_used; 6513 ++num_used;
6514 if (!pure_p) 6514 if (!pure_p)
6515 UNMARK_STRING (XSTRING (sym->s.name)); 6515 eassert (!STRING_MARKED_P (XSTRING (sym->s.name)));
6516 sym->s.gcmarkbit = 0; 6516 sym->s.gcmarkbit = 0;
6517 } 6517 }
6518 } 6518 }
diff --git a/src/bidi.c b/src/bidi.c
index dc905cd9e5f..18dce1931db 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -67,16 +67,15 @@ static bool bidi_initialized = 0;
67 67
68static Lisp_Object bidi_type_table, bidi_mirror_table; 68static Lisp_Object bidi_type_table, bidi_mirror_table;
69 69
70#define LRM_CHAR 0x200E 70#define BIDI_EOB (-1)
71#define RLM_CHAR 0x200F
72#define BIDI_EOB -1
73 71
74/* Data type for describing the bidirectional character categories. */ 72/* Data type for describing the bidirectional character categories. */
75typedef enum { 73typedef enum {
76 UNKNOWN_BC, 74 UNKNOWN_BC,
77 NEUTRAL, 75 NEUTRAL,
78 WEAK, 76 WEAK,
79 STRONG 77 STRONG,
78 EXPLICIT_FORMATTING
80} bidi_category_t; 79} bidi_category_t;
81 80
82/* UAX#9 says to search only for L, AL, or R types of characters, and 81/* UAX#9 says to search only for L, AL, or R types of characters, and
@@ -115,13 +114,9 @@ bidi_get_type (int ch, bidi_dir_t override)
115 if (default_type == UNKNOWN_BT) 114 if (default_type == UNKNOWN_BT)
116 emacs_abort (); 115 emacs_abort ();
117 116
118 if (override == NEUTRAL_DIR)
119 return default_type;
120
121 switch (default_type) 117 switch (default_type)
122 { 118 {
123 /* Although UAX#9 does not tell, it doesn't make sense to 119 case WEAK_BN:
124 override NEUTRAL_B and LRM/RLM characters. */
125 case NEUTRAL_B: 120 case NEUTRAL_B:
126 case LRE: 121 case LRE:
127 case LRO: 122 case LRO:
@@ -129,20 +124,20 @@ bidi_get_type (int ch, bidi_dir_t override)
129 case RLO: 124 case RLO:
130 case PDF: 125 case PDF:
131 return default_type; 126 return default_type;
127 /* FIXME: The isolate controls are treated as BN until we add
128 support for UBA v6.3. */
129 case LRI:
130 case RLI:
131 case FSI:
132 case PDI:
133 return WEAK_BN;
132 default: 134 default:
133 switch (ch) 135 if (override == L2R)
134 { 136 return STRONG_L;
135 case LRM_CHAR: 137 else if (override == R2L)
136 case RLM_CHAR: 138 return STRONG_R;
137 return default_type; 139 else
138 default: 140 return default_type;
139 if (override == L2R) /* X6 */
140 return STRONG_L;
141 else if (override == R2L)
142 return STRONG_R;
143 else
144 emacs_abort (); /* can't happen: handled above */
145 }
146 } 141 }
147} 142}
148 143
@@ -163,12 +158,7 @@ bidi_get_category (bidi_type_t type)
163 case STRONG_L: 158 case STRONG_L:
164 case STRONG_R: 159 case STRONG_R:
165 case STRONG_AL: 160 case STRONG_AL:
166 case LRE:
167 case LRO:
168 case RLE:
169 case RLO:
170 return STRONG; 161 return STRONG;
171 case PDF: /* ??? really?? */
172 case WEAK_EN: 162 case WEAK_EN:
173 case WEAK_ES: 163 case WEAK_ES:
174 case WEAK_ET: 164 case WEAK_ET:
@@ -176,12 +166,30 @@ bidi_get_category (bidi_type_t type)
176 case WEAK_CS: 166 case WEAK_CS:
177 case WEAK_NSM: 167 case WEAK_NSM:
178 case WEAK_BN: 168 case WEAK_BN:
169 /* FIXME */
170 case LRI:
171 case RLI:
172 case FSI:
173 case PDI:
179 return WEAK; 174 return WEAK;
180 case NEUTRAL_B: 175 case NEUTRAL_B:
181 case NEUTRAL_S: 176 case NEUTRAL_S:
182 case NEUTRAL_WS: 177 case NEUTRAL_WS:
183 case NEUTRAL_ON: 178 case NEUTRAL_ON:
184 return NEUTRAL; 179 return NEUTRAL;
180 case LRE:
181 case LRO:
182 case RLE:
183 case RLO:
184 case PDF:
185#if 0
186 /* FIXME: This awaits implementation of isolate support. */
187 case LRI:
188 case RLI:
189 case FSI:
190 case PDI:
191#endif
192 return EXPLICIT_FORMATTING;
185 default: 193 default:
186 emacs_abort (); 194 emacs_abort ();
187 } 195 }
@@ -1148,6 +1156,9 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
1148 pos = BEGV, pos_byte = BEGV_BYTE; 1156 pos = BEGV, pos_byte = BEGV_BYTE;
1149 if (bpc) 1157 if (bpc)
1150 know_region_cache (current_buffer, bpc, pos, oldpos); 1158 know_region_cache (current_buffer, bpc, pos, oldpos);
1159 /* Positions returned by the region cache are not limited to
1160 BEGV..ZV range, so we limit them here. */
1161 pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE);
1151 return pos_byte; 1162 return pos_byte;
1152} 1163}
1153 1164
diff --git a/src/blockinput.h b/src/blockinput.h
index 8f1b1e18985..6c69b01d3dd 100644
--- a/src/blockinput.h
+++ b/src/blockinput.h
@@ -59,7 +59,7 @@ extern void unblock_input (void);
59extern void totally_unblock_input (void); 59extern void totally_unblock_input (void);
60extern void unblock_input_to (int); 60extern void unblock_input_to (int);
61 61
62/* In critical section ? */ 62/* In critical section? */
63 63
64INLINE bool 64INLINE bool
65input_blocked_p (void) 65input_blocked_p (void)
diff --git a/src/buffer.c b/src/buffer.c
index 61b685ea5c5..e4a550fed95 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1336,10 +1336,16 @@ header lines. This function also forces recomputation of the
1336menu bar menus and the frame title. */) 1336menu bar menus and the frame title. */)
1337 (Lisp_Object all) 1337 (Lisp_Object all)
1338{ 1338{
1339 if (!NILP (all) || buffer_window_count (current_buffer)) 1339 if (!NILP (all))
1340 { 1340 {
1341 update_mode_lines = 10; 1341 update_mode_lines = 10;
1342 current_buffer->prevent_redisplay_optimizations_p = 1; 1342 /* FIXME: This can't be right. */
1343 current_buffer->prevent_redisplay_optimizations_p = true;
1344 }
1345 else if (buffer_window_count (current_buffer))
1346 {
1347 bset_update_mode_line (current_buffer);
1348 current_buffer->prevent_redisplay_optimizations_p = true;
1343 } 1349 }
1344 return all; 1350 return all;
1345} 1351}
@@ -2476,6 +2482,8 @@ current buffer is cleared. */)
2476 if (narrowed) 2482 if (narrowed)
2477 error ("Changing multibyteness in a narrowed buffer"); 2483 error ("Changing multibyteness in a narrowed buffer");
2478 2484
2485 invalidate_buffer_caches (current_buffer, BEGV, ZV);
2486
2479 if (NILP (flag)) 2487 if (NILP (flag))
2480 { 2488 {
2481 ptrdiff_t pos, stop; 2489 ptrdiff_t pos, stop;
@@ -3895,17 +3903,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
3895 3903
3896 BUF_COMPUTE_UNCHANGED (buf, start, end); 3904 BUF_COMPUTE_UNCHANGED (buf, start, end);
3897 3905
3898 /* If BUF is visible, consider updating the display if ... */ 3906 bset_redisplay (buf);
3899 if (buffer_window_count (buf) > 0)
3900 {
3901 /* ... it's visible in other window than selected, */
3902 if (buf != XBUFFER (XWINDOW (selected_window)->contents))
3903 windows_or_buffers_changed = 11;
3904 /* ... or if we modify an overlay at the end of the buffer
3905 and so we cannot be sure that window end is still valid. */
3906 else if (end >= ZV && start <= ZV)
3907 windows_or_buffers_changed = 12;
3908 }
3909 3907
3910 ++BUF_OVERLAY_MODIFF (buf); 3908 ++BUF_OVERLAY_MODIFF (buf);
3911} 3909}
diff --git a/src/buffer.h b/src/buffer.h
index d1a3e50d7cf..10d5fdc23e0 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -475,7 +475,10 @@ struct buffer_text
475 /* Usually 0. Temporarily set to 1 in decode_coding_gap to 475 /* Usually 0. Temporarily set to 1 in decode_coding_gap to
476 prevent Fgarbage_collect from shrinking the gap and losing 476 prevent Fgarbage_collect from shrinking the gap and losing
477 not-yet-decoded bytes. */ 477 not-yet-decoded bytes. */
478 bool inhibit_shrinking; 478 unsigned inhibit_shrinking : 1;
479
480 /* True if it needs to be redisplayed. */
481 unsigned redisplay : 1;
479 }; 482 };
480 483
481/* Most code should use this macro to access Lisp fields in struct buffer. */ 484/* Most code should use this macro to access Lisp fields in struct buffer. */
@@ -738,7 +741,7 @@ struct buffer
738 Lisp_Object INTERNAL_FIELD (cursor_in_non_selected_windows); 741 Lisp_Object INTERNAL_FIELD (cursor_in_non_selected_windows);
739 742
740 /* No more Lisp_Object beyond this point. Except undo_list, 743 /* No more Lisp_Object beyond this point. Except undo_list,
741 which is handled specially in Fgarbage_collect . */ 744 which is handled specially in Fgarbage_collect. */
742 745
743 /* This structure holds the coordinates of the buffer contents 746 /* This structure holds the coordinates of the buffer contents
744 in ordinary buffers. In indirect buffers, this is not used. */ 747 in ordinary buffers. In indirect buffers, this is not used. */
diff --git a/src/callproc.c b/src/callproc.c
index 2966711978b..b44f680b352 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1,6 +1,6 @@
1/* Synchronous subprocess invocation for GNU Emacs. 1/* Synchronous subprocess invocation for GNU Emacs.
2 Copyright (C) 1985-1988, 1993-1995, 1999-2013 2
3 Free Software Foundation, Inc. 3Copyright (C) 1985-1988, 1993-1995, 1999-2013 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -1520,14 +1520,14 @@ init_callproc_1 (void)
1520#ifdef HAVE_NS 1520#ifdef HAVE_NS
1521 etc_dir ? etc_dir : 1521 etc_dir ? etc_dir :
1522#endif 1522#endif
1523 PATH_DATA); 1523 PATH_DATA, 0);
1524 Vdata_directory = Ffile_name_as_directory (Fcar (Vdata_directory)); 1524 Vdata_directory = Ffile_name_as_directory (Fcar (Vdata_directory));
1525 1525
1526 Vdoc_directory = decode_env_path ("EMACSDOC", 1526 Vdoc_directory = decode_env_path ("EMACSDOC",
1527#ifdef HAVE_NS 1527#ifdef HAVE_NS
1528 etc_dir ? etc_dir : 1528 etc_dir ? etc_dir :
1529#endif 1529#endif
1530 PATH_DOC); 1530 PATH_DOC, 0);
1531 Vdoc_directory = Ffile_name_as_directory (Fcar (Vdoc_directory)); 1531 Vdoc_directory = Ffile_name_as_directory (Fcar (Vdoc_directory));
1532 1532
1533 /* Check the EMACSPATH environment variable, defaulting to the 1533 /* Check the EMACSPATH environment variable, defaulting to the
@@ -1536,10 +1536,10 @@ init_callproc_1 (void)
1536#ifdef HAVE_NS 1536#ifdef HAVE_NS
1537 path_exec ? path_exec : 1537 path_exec ? path_exec :
1538#endif 1538#endif
1539 PATH_EXEC); 1539 PATH_EXEC, 0);
1540 Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); 1540 Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path));
1541 /* FIXME? For ns, path_exec should go at the front? */ 1541 /* FIXME? For ns, path_exec should go at the front? */
1542 Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path); 1542 Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path);
1543} 1543}
1544 1544
1545/* This is run after init_cmdargs, when Vinstallation_directory is valid. */ 1545/* This is run after init_cmdargs, when Vinstallation_directory is valid. */
@@ -1580,9 +1580,9 @@ init_callproc (void)
1580#ifdef HAVE_NS 1580#ifdef HAVE_NS
1581 path_exec ? path_exec : 1581 path_exec ? path_exec :
1582#endif 1582#endif
1583 PATH_EXEC); 1583 PATH_EXEC, 0);
1584 Vexec_path = Fcons (tem, Vexec_path); 1584 Vexec_path = Fcons (tem, Vexec_path);
1585 Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path); 1585 Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path);
1586 } 1586 }
1587 1587
1588 Vexec_directory = Ffile_name_as_directory (tem); 1588 Vexec_directory = Ffile_name_as_directory (tem);
@@ -1606,24 +1606,17 @@ init_callproc (void)
1606 source directory. */ 1606 source directory. */
1607 if (data_dir == 0) 1607 if (data_dir == 0)
1608 { 1608 {
1609 Lisp_Object tem, tem1, tem2, srcdir; 1609 Lisp_Object tem, tem1, srcdir;
1610#ifdef WINDOWSNT 1610 Lisp_Object lispdir = Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH, 0));
1611 /* PATH_DUMPLOADSEARCH is in ANSI codepage; convert to UTF-8. */
1612 char dumpload_dir[MAX_UTF8_PATH];
1613 1611
1614 filename_from_ansi (PATH_DUMPLOADSEARCH, dumpload_dir); 1612 srcdir = Fexpand_file_name (build_string ("../src/"), lispdir);
1615 tem2 = build_unibyte_string (dumpload_dir);
1616#else
1617 tem2 = build_unibyte_string (PATH_DUMPLOADSEARCH);
1618#endif
1619 1613
1620 srcdir = Fexpand_file_name (build_string ("../src/"), tem2);
1621 tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory); 1614 tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory);
1622 tem1 = Ffile_exists_p (tem); 1615 tem1 = Ffile_exists_p (tem);
1623 if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1)) 1616 if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1))
1624 { 1617 {
1625 Lisp_Object newdir; 1618 Lisp_Object newdir;
1626 newdir = Fexpand_file_name (build_string ("../etc/"), tem2); 1619 newdir = Fexpand_file_name (build_string ("../etc/"), lispdir);
1627 tem = Fexpand_file_name (build_string ("GNU"), newdir); 1620 tem = Fexpand_file_name (build_string ("GNU"), newdir);
1628 tem1 = Ffile_exists_p (tem); 1621 tem1 = Ffile_exists_p (tem);
1629 if (!NILP (tem1)) 1622 if (!NILP (tem1))
diff --git a/src/charset.c b/src/charset.c
index 4a36f8059ae..2ef060228ee 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2428,19 +2428,19 @@ the value may be a list of mnemonics. */);
2428 Vcurrent_iso639_language = Qnil; 2428 Vcurrent_iso639_language = Qnil;
2429 2429
2430 charset_ascii 2430 charset_ascii
2431 = define_charset_internal (Qascii, 1, "\x00\x7F\x00\x00\x00\x00", 2431 = define_charset_internal (Qascii, 1, "\x00\x7F\0\0\0\0\0",
2432 0, 127, 'B', -1, 0, 1, 0, 0); 2432 0, 127, 'B', -1, 0, 1, 0, 0);
2433 charset_iso_8859_1 2433 charset_iso_8859_1
2434 = define_charset_internal (Qiso_8859_1, 1, "\x00\xFF\x00\x00\x00\x00", 2434 = define_charset_internal (Qiso_8859_1, 1, "\x00\xFF\0\0\0\0\0",
2435 0, 255, -1, -1, -1, 1, 0, 0); 2435 0, 255, -1, -1, -1, 1, 0, 0);
2436 charset_unicode 2436 charset_unicode
2437 = define_charset_internal (Qunicode, 3, "\x00\xFF\x00\xFF\x00\x10", 2437 = define_charset_internal (Qunicode, 3, "\x00\xFF\x00\xFF\x00\x10\0",
2438 0, MAX_UNICODE_CHAR, -1, 0, -1, 1, 0, 0); 2438 0, MAX_UNICODE_CHAR, -1, 0, -1, 1, 0, 0);
2439 charset_emacs 2439 charset_emacs
2440 = define_charset_internal (Qemacs, 3, "\x00\xFF\x00\xFF\x00\x3F", 2440 = define_charset_internal (Qemacs, 3, "\x00\xFF\x00\xFF\x00\x3F\0",
2441 0, MAX_5_BYTE_CHAR, -1, 0, -1, 1, 1, 0); 2441 0, MAX_5_BYTE_CHAR, -1, 0, -1, 1, 1, 0);
2442 charset_eight_bit 2442 charset_eight_bit
2443 = define_charset_internal (Qeight_bit, 1, "\x80\xFF\x00\x00\x00\x00", 2443 = define_charset_internal (Qeight_bit, 1, "\x80\xFF\0\0\0\0\0",
2444 128, 255, -1, 0, -1, 0, 1, 2444 128, 255, -1, 0, -1, 0, 1,
2445 MAX_5_BYTE_CHAR + 1); 2445 MAX_5_BYTE_CHAR + 1);
2446 charset_unibyte = charset_iso_8859_1; 2446 charset_unibyte = charset_iso_8859_1;
diff --git a/src/charset.h b/src/charset.h
index 6e6a8891b4a..d5c41ec6f49 100644
--- a/src/charset.h
+++ b/src/charset.h
@@ -208,7 +208,7 @@ struct charset
208 unsigned min_code, max_code; 208 unsigned min_code, max_code;
209 209
210 /* Offset value used by macros CODE_POINT_TO_INDEX and 210 /* Offset value used by macros CODE_POINT_TO_INDEX and
211 INDEX_TO_CODE_POINT. . */ 211 INDEX_TO_CODE_POINT. */
212 unsigned char_index_offset; 212 unsigned char_index_offset;
213 213
214 /* Minimum and Maximum character codes of the charset. If the 214 /* Minimum and Maximum character codes of the charset. If the
diff --git a/src/chartab.c b/src/chartab.c
index 16dd85c12c0..2a8bbc6983a 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -1272,7 +1272,7 @@ uniprop_encode_value_run_length (Lisp_Object table, Lisp_Object value)
1272 1272
1273 1273
1274/* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH 1274/* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH
1275 compression and contains numbers as elements . */ 1275 compression and contains numbers as elements. */
1276 1276
1277static Lisp_Object 1277static Lisp_Object
1278uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value) 1278uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value)
diff --git a/src/composite.c b/src/composite.c
index 2ab5dbc9133..cef2ed86e57 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1191,7 +1191,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1191 1191
1192/* Check if the character at CHARPOS (and BYTEPOS) is composed 1192/* Check if the character at CHARPOS (and BYTEPOS) is composed
1193 (possibly with the following characters) on window W. ENDPOS limits 1193 (possibly with the following characters) on window W. ENDPOS limits
1194 characters to be composed. FACE, in non-NULL, is a base face of 1194 characters to be composed. FACE, if non-NULL, is a base face of
1195 the character. If STRING is not nil, it is a string containing the 1195 the character. If STRING is not nil, it is a string containing the
1196 character to check, and CHARPOS and BYTEPOS are indices in the 1196 character to check, and CHARPOS and BYTEPOS are indices in the
1197 string. In that case, FACE must not be NULL. 1197 string. In that case, FACE must not be NULL.
diff --git a/src/data.c b/src/data.c
index d0171b5d758..1fe7a1c9b65 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1551,8 +1551,12 @@ Note that binding the variable with `let', or setting it while
1551a `let'-style binding made in this buffer is in effect, 1551a `let'-style binding made in this buffer is in effect,
1552does not make the variable buffer-local. Return VARIABLE. 1552does not make the variable buffer-local. Return VARIABLE.
1553 1553
1554In most cases it is better to use `make-local-variable', 1554This globally affects all uses of this variable, so it belongs together with
1555which makes a variable local in just one buffer. 1555the variable declaration, rather than with its uses (if you just want to make
1556a variable local to the current buffer for one particular use, use
1557`make-local-variable'). Buffer-local bindings are normally cleared
1558while setting up a new major mode, unless they have a `permanent-local'
1559property.
1556 1560
1557The function `default-value' gets the default value and `set-default' sets it. */) 1561The function `default-value' gets the default value and `set-default' sets it. */)
1558 (register Lisp_Object variable) 1562 (register Lisp_Object variable)
@@ -3018,64 +3022,103 @@ enum bool_vector_op { bool_vector_exclusive_or,
3018 bool_vector_subsetp }; 3022 bool_vector_subsetp };
3019 3023
3020static Lisp_Object 3024static Lisp_Object
3021bool_vector_binop_driver (Lisp_Object op1, 3025bool_vector_binop_driver (Lisp_Object a,
3022 Lisp_Object op2, 3026 Lisp_Object b,
3023 Lisp_Object dest, 3027 Lisp_Object dest,
3024 enum bool_vector_op op) 3028 enum bool_vector_op op)
3025{ 3029{
3026 EMACS_INT nr_bits; 3030 EMACS_INT nr_bits;
3027 bits_word *adata, *bdata, *cdata; 3031 bits_word *adata, *bdata, *destdata;
3028 ptrdiff_t i; 3032 ptrdiff_t i = 0;
3029 bool changed = 0;
3030 bits_word mword;
3031 ptrdiff_t nr_words; 3033 ptrdiff_t nr_words;
3032 3034
3033 CHECK_BOOL_VECTOR (op1); 3035 CHECK_BOOL_VECTOR (a);
3034 CHECK_BOOL_VECTOR (op2); 3036 CHECK_BOOL_VECTOR (b);
3035 3037
3036 nr_bits = bool_vector_size (op1); 3038 nr_bits = bool_vector_size (a);
3037 if (bool_vector_size (op2) != nr_bits) 3039 if (bool_vector_size (b) != nr_bits)
3038 wrong_length_argument (op1, op2, dest); 3040 wrong_length_argument (a, b, dest);
3041
3042 nr_words = bool_vector_words (nr_bits);
3043 adata = bool_vector_data (a);
3044 bdata = bool_vector_data (b);
3039 3045
3040 if (NILP (dest)) 3046 if (NILP (dest))
3041 { 3047 {
3042 dest = make_uninit_bool_vector (nr_bits); 3048 dest = make_uninit_bool_vector (nr_bits);
3043 changed = 1; 3049 destdata = bool_vector_data (dest);
3044 } 3050 }
3045 else 3051 else
3046 { 3052 {
3047 CHECK_BOOL_VECTOR (dest); 3053 CHECK_BOOL_VECTOR (dest);
3054 destdata = bool_vector_data (dest);
3048 if (bool_vector_size (dest) != nr_bits) 3055 if (bool_vector_size (dest) != nr_bits)
3049 wrong_length_argument (op1, op2, dest); 3056 wrong_length_argument (a, b, dest);
3050 }
3051 3057
3052 nr_words = bool_vector_words (nr_bits); 3058 switch (op)
3059 {
3060 case bool_vector_exclusive_or:
3061 for (; i < nr_words; i++)
3062 if (destdata[i] != (adata[i] ^ bdata[i]))
3063 goto set_dest;
3064 break;
3065
3066 case bool_vector_subsetp:
3067 for (; i < nr_words; i++)
3068 if (adata[i] &~ bdata[i])
3069 return Qnil;
3070 return Qt;
3071
3072 case bool_vector_union:
3073 for (; i < nr_words; i++)
3074 if (destdata[i] != (adata[i] | bdata[i]))
3075 goto set_dest;
3076 break;
3077
3078 case bool_vector_intersection:
3079 for (; i < nr_words; i++)
3080 if (destdata[i] != (adata[i] & bdata[i]))
3081 goto set_dest;
3082 break;
3053 3083
3054 adata = bool_vector_data (dest); 3084 case bool_vector_set_difference:
3055 bdata = bool_vector_data (op1); 3085 for (; i < nr_words; i++)
3056 cdata = bool_vector_data (op2); 3086 if (destdata[i] != (adata[i] &~ bdata[i]))
3087 goto set_dest;
3088 break;
3089 }
3090
3091 return Qnil;
3092 }
3057 3093
3058 for (i = 0; i < nr_words; i++) 3094 set_dest:
3095 switch (op)
3059 { 3096 {
3060 if (op == bool_vector_exclusive_or) 3097 case bool_vector_exclusive_or:
3061 mword = bdata[i] ^ cdata[i]; 3098 for (; i < nr_words; i++)
3062 else if (op == bool_vector_union || op == bool_vector_subsetp) 3099 destdata[i] = adata[i] ^ bdata[i];
3063 mword = bdata[i] | cdata[i]; 3100 break;
3064 else if (op == bool_vector_intersection)
3065 mword = bdata[i] & cdata[i];
3066 else if (op == bool_vector_set_difference)
3067 mword = bdata[i] &~ cdata[i];
3068 else
3069 abort ();
3070 3101
3071 if (! changed) 3102 case bool_vector_union:
3072 changed = adata[i] != mword; 3103 for (; i < nr_words; i++)
3104 destdata[i] = adata[i] | bdata[i];
3105 break;
3073 3106
3074 if (op != bool_vector_subsetp) 3107 case bool_vector_intersection:
3075 adata[i] = mword; 3108 for (; i < nr_words; i++)
3109 destdata[i] = adata[i] & bdata[i];
3110 break;
3111
3112 case bool_vector_set_difference:
3113 for (; i < nr_words; i++)
3114 destdata[i] = adata[i] &~ bdata[i];
3115 break;
3116
3117 default:
3118 eassume (0);
3076 } 3119 }
3077 3120
3078 return changed ? dest : Qnil; 3121 return dest;
3079} 3122}
3080 3123
3081/* PRECONDITION must be true. Return VALUE. This odd construction 3124/* PRECONDITION must be true. Return VALUE. This odd construction
@@ -3199,11 +3242,11 @@ Return the destination vector if it changed or nil otherwise. */)
3199 3242
3200DEFUN ("bool-vector-subsetp", Fbool_vector_subsetp, 3243DEFUN ("bool-vector-subsetp", Fbool_vector_subsetp,
3201 Sbool_vector_subsetp, 2, 2, 0, 3244 Sbool_vector_subsetp, 2, 2, 0,
3202 doc: ) 3245 doc: /* Return t if every t value in A is also t in B, nil otherwise.
3246A and B must be bool vectors of the same length. */)
3203 (Lisp_Object a, Lisp_Object b) 3247 (Lisp_Object a, Lisp_Object b)
3204{ 3248{
3205 /* Like bool_vector_union, but doesn't modify b. */ 3249 return bool_vector_binop_driver (a, b, b, bool_vector_subsetp);
3206 return bool_vector_binop_driver (b, a, b, bool_vector_subsetp);
3207} 3250}
3208 3251
3209DEFUN ("bool-vector-not", Fbool_vector_not, 3252DEFUN ("bool-vector-not", Fbool_vector_not,
@@ -3247,11 +3290,12 @@ Return the destination vector. */)
3247 return b; 3290 return b;
3248} 3291}
3249 3292
3250DEFUN ("bool-vector-count-matches", Fbool_vector_count_matches, 3293DEFUN ("bool-vector-count-population", Fbool_vector_count_population,
3251 Sbool_vector_count_matches, 2, 2, 0, 3294 Sbool_vector_count_population, 1, 1, 0,
3252 doc: /* Count how many elements in A equal B. 3295 doc: /* Count how many elements in A are t.
3253A must be a bool vector. B is a generalized bool. */) 3296A is a bool vector. To count A's nil elements, subtract the return
3254 (Lisp_Object a, Lisp_Object b) 3297value from A's length. */)
3298 (Lisp_Object a)
3255{ 3299{
3256 EMACS_INT count; 3300 EMACS_INT count;
3257 EMACS_INT nr_bits; 3301 EMACS_INT nr_bits;
@@ -3268,17 +3312,13 @@ A must be a bool vector. B is a generalized bool. */)
3268 for (i = 0; i < nwords; i++) 3312 for (i = 0; i < nwords; i++)
3269 count += count_one_bits_word (adata[i]); 3313 count += count_one_bits_word (adata[i]);
3270 3314
3271 if (NILP (b))
3272 count = nr_bits - count;
3273 return make_number (count); 3315 return make_number (count);
3274} 3316}
3275 3317
3276DEFUN ("bool-vector-count-matches-at", 3318DEFUN ("bool-vector-count-consecutive", Fbool_vector_count_consecutive,
3277 Fbool_vector_count_matches_at, 3319 Sbool_vector_count_consecutive, 3, 3, 0,
3278 Sbool_vector_count_matches_at, 3, 3, 0, 3320 doc: /* Count how many consecutive elements in A equal B starting at I.
3279 doc: /* Count how many consecutive elements in A equal B at i. 3321A is a bool vector, B is t or nil, and I is an index into A. */)
3280A must be a bool vector. B is a generalized boolean. i is an
3281index into the vector. */)
3282 (Lisp_Object a, Lisp_Object b, Lisp_Object i) 3322 (Lisp_Object a, Lisp_Object b, Lisp_Object i)
3283{ 3323{
3284 EMACS_INT count; 3324 EMACS_INT count;
@@ -3314,7 +3354,10 @@ index into the vector. */)
3314 mword = bits_word_to_host_endian (adata[pos]); 3354 mword = bits_word_to_host_endian (adata[pos]);
3315 mword ^= twiddle; 3355 mword ^= twiddle;
3316 mword >>= offset; 3356 mword >>= offset;
3357
3358 /* Do not count the pad bits. */
3317 mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset); 3359 mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset);
3360
3318 count = count_trailing_zero_bits (mword); 3361 count = count_trailing_zero_bits (mword);
3319 pos++; 3362 pos++;
3320 if (count + offset < BITS_PER_BITS_WORD) 3363 if (count + offset < BITS_PER_BITS_WORD)
@@ -3622,8 +3665,8 @@ syms_of_data (void)
3622 defsubr (&Sbool_vector_set_difference); 3665 defsubr (&Sbool_vector_set_difference);
3623 defsubr (&Sbool_vector_not); 3666 defsubr (&Sbool_vector_not);
3624 defsubr (&Sbool_vector_subsetp); 3667 defsubr (&Sbool_vector_subsetp);
3625 defsubr (&Sbool_vector_count_matches); 3668 defsubr (&Sbool_vector_count_consecutive);
3626 defsubr (&Sbool_vector_count_matches_at); 3669 defsubr (&Sbool_vector_count_population);
3627 3670
3628 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); 3671 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function);
3629 3672
diff --git a/src/dispextern.h b/src/dispextern.h
index d40febd207a..7de4edf2196 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -118,7 +118,9 @@ enum window_part
118 ON_RIGHT_FRINGE, 118 ON_RIGHT_FRINGE,
119 ON_LEFT_MARGIN, 119 ON_LEFT_MARGIN,
120 ON_RIGHT_MARGIN, 120 ON_RIGHT_MARGIN,
121 ON_SCROLL_BAR 121 ON_SCROLL_BAR,
122 ON_RIGHT_DIVIDER,
123 ON_BOTTOM_DIVIDER
122}; 124};
123 125
124/* Number of bits allocated to store fringe bitmap numbers. */ 126/* Number of bits allocated to store fringe bitmap numbers. */
@@ -667,7 +669,7 @@ struct glyph_pool
667 glyph memory, which is allocated in the form of a glyph_pool structure. 669 glyph memory, which is allocated in the form of a glyph_pool structure.
668 Glyph rows in such a window matrix are slices of frame matrix rows. 670 Glyph rows in such a window matrix are slices of frame matrix rows.
669 671
670 2. Free-standing window glyph matrices managing their own glyph 672 3. Free-standing window glyph matrices managing their own glyph
671 storage. This form is used in window-based redisplay which 673 storage. This form is used in window-based redisplay which
672 includes variable width and height fonts etc. 674 includes variable width and height fonts etc.
673 675
@@ -704,12 +706,12 @@ struct glyph_matrix
704 int matrix_w, matrix_h; 706 int matrix_w, matrix_h;
705 707
706 /* If this structure describes a window matrix of window W, 708 /* If this structure describes a window matrix of window W,
707 window_left_col is the value of W->left_col, window_top_line the 709 window_pixel_left is the value of W->pixel_left, window_pixel_top
708 value of W->top_line, window_height and window_width are width and 710 the value of W->pixel_top, window_height and window_width are width
709 height of W, as returned by window_box, and window_vscroll is the 711 and height of W, as returned by window_box, and window_vscroll is
710 value of W->vscroll at the time the matrix was last adjusted. 712 the value of W->vscroll at the time the matrix was last adjusted.
711 Only set for window-based redisplay. */ 713 Only set for window-based redisplay. */
712 int window_left_col, window_top_line; 714 int window_pixel_left, window_pixel_top;
713 int window_height, window_width; 715 int window_height, window_width;
714 int window_vscroll; 716 int window_vscroll;
715 717
@@ -722,7 +724,7 @@ struct glyph_matrix
722 which do their own scrolling. */ 724 which do their own scrolling. */
723 unsigned no_scrolling_p : 1; 725 unsigned no_scrolling_p : 1;
724 726
725 /* Non-zero means window displayed in this matrix has a top mode 727 /* Non-zero means window displayed in this matrix has a header
726 line. */ 728 line. */
727 unsigned header_line_p : 1; 729 unsigned header_line_p : 1;
728 730
@@ -1460,28 +1462,40 @@ struct glyph_string
1460#define DESIRED_HEADER_LINE_HEIGHT(W) \ 1462#define DESIRED_HEADER_LINE_HEIGHT(W) \
1461 MATRIX_HEADER_LINE_HEIGHT ((W)->desired_matrix) 1463 MATRIX_HEADER_LINE_HEIGHT ((W)->desired_matrix)
1462 1464
1463/* Value is non-zero if window W wants a mode line. */ 1465/* PXW: The height checks below serve to show at least one text line
1466 instead of a mode- and/or header line when a window gets very small.
1467 But (1) the check fails when the mode- or header-line is taller than
1468 the associated frame's line height and (2) we don't care much about
1469 text visibility anyway when shrinking a frame containing a toolbar.
1464 1470
1465#define WINDOW_WANTS_MODELINE_P(W) \ 1471 So maybe these checks should be removed and any clipping left to the
1466 (!MINI_WINDOW_P ((W)) \ 1472 window manager. */
1467 && !(W)->pseudo_window_p \
1468 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \
1469 && BUFFERP ((W)->contents) \
1470 && !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
1471 && WINDOW_TOTAL_LINES (W) > 1)
1472 1473
1473/* Value is true if window W wants a header line. */ 1474/* Value is true if window W wants a mode line and is large enough
1474 1475 to accommodate it. */
1475#define WINDOW_WANTS_HEADER_LINE_P(W) \ 1476#define WINDOW_WANTS_MODELINE_P(W) \
1476 (BUFFERP ((W)->contents) \ 1477 (BUFFERP ((W)->contents) \
1477 ? (!MINI_WINDOW_P ((W)) \ 1478 ? (!MINI_WINDOW_P (W) \
1478 && !(W)->pseudo_window_p \ 1479 && !(W)->pseudo_window_p \
1479 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME ((W)))) \ 1480 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
1480 && !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \ 1481 && !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)) \
1481 && WINDOW_TOTAL_LINES (W) > \ 1482 && WINDOW_PIXEL_HEIGHT (W) > WINDOW_FRAME_LINE_HEIGHT (W)) \
1482 (1 + !NILP (BVAR (XBUFFER ((W)->contents), mode_line_format)))) \
1483 : 0) 1483 : 0)
1484 1484
1485/* Value is true if window W wants a header line and is large enough
1486 to accommodate it. */
1487#define WINDOW_WANTS_HEADER_LINE_P(W) \
1488 (BUFFERP ((W)->contents) \
1489 ? (!MINI_WINDOW_P (W) \
1490 && !(W)->pseudo_window_p \
1491 && FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (W))) \
1492 && !NILP (BVAR (XBUFFER ((W)->contents), header_line_format)) \
1493 && (WINDOW_PIXEL_HEIGHT (W) \
1494 > (WINDOW_WANTS_MODELINE_P (W) \
1495 ? (2 * WINDOW_FRAME_LINE_HEIGHT (W)) \
1496 : WINDOW_FRAME_LINE_HEIGHT (W)))) \
1497 : 0)
1498
1485/* Return proper value to be used as baseline offset of font that has 1499/* Return proper value to be used as baseline offset of font that has
1486 ASCENT and DESCENT to draw characters by the font at the vertical 1500 ASCENT and DESCENT to draw characters by the font at the vertical
1487 center of the line of frame F. 1501 center of the line of frame F.
@@ -1751,6 +1765,7 @@ enum face_id
1751 MOUSE_FACE_ID, 1765 MOUSE_FACE_ID,
1752 MENU_FACE_ID, 1766 MENU_FACE_ID,
1753 VERTICAL_BORDER_FACE_ID, 1767 VERTICAL_BORDER_FACE_ID,
1768 WINDOW_DIVIDER_FACE_ID,
1754 BASIC_FACE_ID_SENTINEL 1769 BASIC_FACE_ID_SENTINEL
1755}; 1770};
1756 1771
@@ -1880,6 +1895,10 @@ typedef enum {
1880 RLE, /* right-to-left embedding */ 1895 RLE, /* right-to-left embedding */
1881 RLO, /* right-to-left override */ 1896 RLO, /* right-to-left override */
1882 PDF, /* pop directional format */ 1897 PDF, /* pop directional format */
1898 LRI, /* left-to-right isolate */
1899 RLI, /* right-to-left isolate */
1900 FSI, /* first strong isolate */
1901 PDI, /* pop directional isolate */
1883 WEAK_ES, /* european number separator */ 1902 WEAK_ES, /* european number separator */
1884 WEAK_ET, /* european number terminator */ 1903 WEAK_ET, /* european number terminator */
1885 WEAK_CS, /* common separator */ 1904 WEAK_CS, /* common separator */
@@ -2850,6 +2869,10 @@ struct redisplay_interface
2850 void (*draw_vertical_window_border) (struct window *w, 2869 void (*draw_vertical_window_border) (struct window *w,
2851 int x, int y_0, int y_1); 2870 int x, int y_0, int y_1);
2852 2871
2872/* Draw window divider for window W from (X_0, Y_0) to (X_1, ,Y_1). */
2873 void (*draw_window_divider) (struct window *w,
2874 int x_0, int x_1, int y_0, int y_1);
2875
2853/* Shift display of frame F to make room for inserted glyphs. 2876/* Shift display of frame F to make room for inserted glyphs.
2854 The area at pixel (X,Y) of width WIDTH and height HEIGHT is 2877 The area at pixel (X,Y) of width WIDTH and height HEIGHT is
2855 shifted right by SHIFT_BY pixels. */ 2878 shifted right by SHIFT_BY pixels. */
@@ -3167,6 +3190,7 @@ int window_box_left_offset (struct window *, enum glyph_row_area);
3167int window_box_right (struct window *, enum glyph_row_area); 3190int window_box_right (struct window *, enum glyph_row_area);
3168int window_box_right_offset (struct window *, enum glyph_row_area); 3191int window_box_right_offset (struct window *, enum glyph_row_area);
3169int estimate_mode_line_height (struct frame *, enum face_id); 3192int estimate_mode_line_height (struct frame *, enum face_id);
3193int move_it_to (struct it *, ptrdiff_t, int, int, int, int);
3170void pixel_to_glyph_coords (struct frame *, int, int, int *, int *, 3194void pixel_to_glyph_coords (struct frame *, int, int, int *, int *,
3171 NativeRectangle *, int); 3195 NativeRectangle *, int);
3172void remember_mouse_glyph (struct frame *, int, int, NativeRectangle *); 3196void remember_mouse_glyph (struct frame *, int, int, NativeRectangle *);
@@ -3178,7 +3202,6 @@ void init_iterator (struct it *, struct window *, ptrdiff_t,
3178void init_iterator_to_row_start (struct it *, struct window *, 3202void init_iterator_to_row_start (struct it *, struct window *,
3179 struct glyph_row *); 3203 struct glyph_row *);
3180void start_display (struct it *, struct window *, struct text_pos); 3204void start_display (struct it *, struct window *, struct text_pos);
3181void move_it_to (struct it *, ptrdiff_t, int, int, int, int);
3182void move_it_vertically (struct it *, int); 3205void move_it_vertically (struct it *, int);
3183void move_it_vertically_backward (struct it *, int); 3206void move_it_vertically_backward (struct it *, int);
3184void move_it_by_lines (struct it *, ptrdiff_t); 3207void move_it_by_lines (struct it *, ptrdiff_t);
@@ -3235,6 +3258,7 @@ extern void display_and_set_cursor (struct window *, bool, int, int, int, int);
3235extern void x_update_cursor (struct frame *, bool); 3258extern void x_update_cursor (struct frame *, bool);
3236extern void x_clear_cursor (struct window *); 3259extern void x_clear_cursor (struct window *);
3237extern void x_draw_vertical_border (struct window *w); 3260extern void x_draw_vertical_border (struct window *w);
3261extern void x_draw_right_divider (struct window *w);
3238 3262
3239extern int get_glyph_string_clip_rects (struct glyph_string *, 3263extern int get_glyph_string_clip_rects (struct glyph_string *,
3240 NativeRectangle *, int); 3264 NativeRectangle *, int);
@@ -3462,10 +3486,9 @@ void blank_row (struct window *, struct glyph_row *, int);
3462void clear_glyph_matrix_rows (struct glyph_matrix *, int, int); 3486void clear_glyph_matrix_rows (struct glyph_matrix *, int, int);
3463void clear_glyph_row (struct glyph_row *); 3487void clear_glyph_row (struct glyph_row *);
3464void prepare_desired_row (struct glyph_row *); 3488void prepare_desired_row (struct glyph_row *);
3465void set_window_update_flags (struct window *, struct buffer *, bool);
3466void update_single_window (struct window *, bool); 3489void update_single_window (struct window *, bool);
3467void do_pending_window_change (bool); 3490void do_pending_window_change (bool);
3468void change_frame_size (struct frame *, int, int, bool, bool, bool); 3491void change_frame_size (struct frame *, int, int, bool, bool, bool, bool);
3469void init_display (void); 3492void init_display (void);
3470void syms_of_display (void); 3493void syms_of_display (void);
3471extern Lisp_Object Qredisplay_dont_pause; 3494extern Lisp_Object Qredisplay_dont_pause;
diff --git a/src/dispnew.c b/src/dispnew.c
index 3207f4a0018..94929600286 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -72,7 +72,7 @@ struct dim
72static void update_frame_line (struct frame *, int); 72static void update_frame_line (struct frame *, int);
73static int required_matrix_height (struct window *); 73static int required_matrix_height (struct window *);
74static int required_matrix_width (struct window *); 74static int required_matrix_width (struct window *);
75static void change_frame_size_1 (struct frame *, int, int, bool, bool, bool); 75static void change_frame_size_1 (struct frame *, int, int, bool, bool, bool, bool);
76static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t); 76static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
77static void build_frame_matrix_from_window_tree (struct glyph_matrix *, 77static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
78 struct window *); 78 struct window *);
@@ -97,6 +97,7 @@ static bool scrolling (struct frame *);
97static void set_window_cursor_after_update (struct window *); 97static void set_window_cursor_after_update (struct window *);
98static void adjust_frame_glyphs_for_window_redisplay (struct frame *); 98static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
99static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); 99static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
100static void set_window_update_flags (struct window *w, bool on_p);
100 101
101/* True means last display completed. False means it was preempted. */ 102/* True means last display completed. False means it was preempted. */
102 103
@@ -400,8 +401,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
400 if (!marginal_areas_changed_p 401 if (!marginal_areas_changed_p
401 && !XFRAME (w->frame)->fonts_changed 402 && !XFRAME (w->frame)->fonts_changed
402 && !header_line_changed_p 403 && !header_line_changed_p
403 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w) 404 && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
404 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w) 405 && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
405 && matrix->window_height == window_height 406 && matrix->window_height == window_height
406 && matrix->window_vscroll == w->vscroll 407 && matrix->window_vscroll == w->vscroll
407 && matrix->window_width == window_width) 408 && matrix->window_width == window_width)
@@ -542,8 +543,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
542 && !header_line_changed_p 543 && !header_line_changed_p
543 && new_rows == 0 544 && new_rows == 0
544 && dim.width == matrix->matrix_w 545 && dim.width == matrix->matrix_w
545 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w) 546 && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
546 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w) 547 && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
547 && matrix->window_width == window_width) 548 && matrix->window_width == window_width)
548 { 549 {
549 /* Find the last row in the window. */ 550 /* Find the last row in the window. */
@@ -590,8 +591,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
590 was last adjusted. This is used to optimize redisplay above. */ 591 was last adjusted. This is used to optimize redisplay above. */
591 if (w) 592 if (w)
592 { 593 {
593 matrix->window_left_col = WINDOW_LEFT_EDGE_COL (w); 594 matrix->window_pixel_left = WINDOW_LEFT_PIXEL_EDGE (w);
594 matrix->window_top_line = WINDOW_TOP_EDGE_LINE (w); 595 matrix->window_pixel_top = WINDOW_TOP_PIXEL_EDGE (w);
595 matrix->window_height = window_height; 596 matrix->window_height = window_height;
596 matrix->window_width = window_width; 597 matrix->window_width = window_width;
597 matrix->window_vscroll = w->vscroll; 598 matrix->window_vscroll = w->vscroll;
@@ -1660,6 +1661,7 @@ required_matrix_height (struct window *w)
1660 { 1661 {
1661 int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f); 1662 int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
1662 int window_pixel_height = window_box_height (w) + eabs (w->vscroll); 1663 int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
1664
1663 return (((window_pixel_height + ch_height - 1) 1665 return (((window_pixel_height + ch_height - 1)
1664 / ch_height) * w->nrows_scale_factor 1666 / ch_height) * w->nrows_scale_factor
1665 /* One partially visible line at the top and 1667 /* One partially visible line at the top and
@@ -1684,10 +1686,9 @@ required_matrix_width (struct window *w)
1684 if (FRAME_WINDOW_P (f)) 1686 if (FRAME_WINDOW_P (f))
1685 { 1687 {
1686 int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f); 1688 int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
1687 int window_pixel_width = WINDOW_TOTAL_WIDTH (w);
1688 1689
1689 /* Compute number of glyphs needed in a glyph row. */ 1690 /* Compute number of glyphs needed in a glyph row. */
1690 return (((window_pixel_width + ch_width - 1) 1691 return (((WINDOW_PIXEL_WIDTH (w) + ch_width - 1)
1691 / ch_width) * w->ncols_scale_factor 1692 / ch_width) * w->ncols_scale_factor
1692 /* 2 partially visible columns in the text area. */ 1693 /* 2 partially visible columns in the text area. */
1693 + 2 1694 + 2
@@ -1977,6 +1978,10 @@ adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
1977 /* Size of frame matrices must equal size of frame. Note 1978 /* Size of frame matrices must equal size of frame. Note
1978 that we are called for X frames with window widths NOT equal 1979 that we are called for X frames with window widths NOT equal
1979 to the frame width (from CHANGE_FRAME_SIZE_1). */ 1980 to the frame width (from CHANGE_FRAME_SIZE_1). */
1981 if (matrix_dim.width != FRAME_COLS (f)
1982 || matrix_dim.height != FRAME_LINES (f))
1983 return;
1984
1980 eassert (matrix_dim.width == FRAME_COLS (f) 1985 eassert (matrix_dim.width == FRAME_COLS (f)
1981 && matrix_dim.height == FRAME_LINES (f)); 1986 && matrix_dim.height == FRAME_LINES (f));
1982 1987
@@ -2046,10 +2051,14 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2046 2051
2047 /* Set window dimensions to frame dimensions and allocate or 2052 /* Set window dimensions to frame dimensions and allocate or
2048 adjust glyph matrices of W. */ 2053 adjust glyph matrices of W. */
2049 w->top_line = 0; 2054 w->pixel_left = 0;
2050 w->left_col = 0; 2055 w->left_col = 0;
2051 w->total_lines = FRAME_MENU_BAR_LINES (f); 2056 w->pixel_top = 0;
2057 w->top_line = 0;
2058 w->pixel_width = FRAME_PIXEL_WIDTH (f);
2052 w->total_cols = FRAME_TOTAL_COLS (f); 2059 w->total_cols = FRAME_TOTAL_COLS (f);
2060 w->pixel_height = FRAME_MENU_BAR_HEIGHT (f);
2061 w->total_lines = FRAME_MENU_BAR_LINES (f);
2053 allocate_matrices_for_window_redisplay (w); 2062 allocate_matrices_for_window_redisplay (w);
2054 } 2063 }
2055#endif 2064#endif
@@ -2071,10 +2080,15 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2071 else 2080 else
2072 w = XWINDOW (f->tool_bar_window); 2081 w = XWINDOW (f->tool_bar_window);
2073 2082
2074 w->top_line = FRAME_MENU_BAR_LINES (f); 2083 w->pixel_left = 0;
2075 w->left_col = 0; 2084 w->left_col = 0;
2076 w->total_lines = FRAME_TOOL_BAR_LINES (f); 2085 w->pixel_top = FRAME_MENU_BAR_HEIGHT (f);
2086 w->top_line = FRAME_MENU_BAR_LINES (f);
2087 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2088 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2077 w->total_cols = FRAME_TOTAL_COLS (f); 2089 w->total_cols = FRAME_TOTAL_COLS (f);
2090 w->pixel_height = FRAME_TOOL_BAR_HEIGHT (f);
2091 w->total_lines = FRAME_TOOL_BAR_LINES (f);
2078 allocate_matrices_for_window_redisplay (w); 2092 allocate_matrices_for_window_redisplay (w);
2079 } 2093 }
2080#endif 2094#endif
@@ -2944,8 +2958,8 @@ redraw_frame (struct frame *f)
2944 /* Mark all windows as inaccurate, so that every window will have 2958 /* Mark all windows as inaccurate, so that every window will have
2945 its redisplay done. */ 2959 its redisplay done. */
2946 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); 2960 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
2947 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), NULL, 1); 2961 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), true);
2948 f->garbaged = 0; 2962 f->garbaged = false;
2949} 2963}
2950 2964
2951DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0, 2965DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0,
@@ -3029,7 +3043,7 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
3029 Lisp_Object tem; 3043 Lisp_Object tem;
3030 3044
3031 update_window (w, 1); 3045 update_window (w, 1);
3032 w->must_be_updated_p = 0; 3046 w->must_be_updated_p = false;
3033 3047
3034 /* Swap tool-bar strings. We swap because we want to 3048 /* Swap tool-bar strings. We swap because we want to
3035 reuse strings. */ 3049 reuse strings. */
@@ -3075,7 +3089,7 @@ update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
3075 3089
3076 do_pause: 3090 do_pause:
3077 /* Reset flags indicating that a window should be updated. */ 3091 /* Reset flags indicating that a window should be updated. */
3078 set_window_update_flags (root_window, NULL, 0); 3092 set_window_update_flags (root_window, false);
3079 3093
3080 display_completed = !paused_p; 3094 display_completed = !paused_p;
3081 return paused_p; 3095 return paused_p;
@@ -3098,7 +3112,7 @@ update_frame_with_menu (struct frame *f)
3098 frame matrix we operate. */ 3112 frame matrix we operate. */
3099 set_frame_matrix_frame (f); 3113 set_frame_matrix_frame (f);
3100 3114
3101 /* Update the display */ 3115 /* Update the display. */
3102 update_begin (f); 3116 update_begin (f);
3103 /* Force update_frame_1 not to stop due to pending input, and not 3117 /* Force update_frame_1 not to stop due to pending input, and not
3104 try scrolling. */ 3118 try scrolling. */
@@ -3122,7 +3136,7 @@ update_frame_with_menu (struct frame *f)
3122#endif 3136#endif
3123 3137
3124 /* Reset flags indicating that a window should be updated. */ 3138 /* Reset flags indicating that a window should be updated. */
3125 set_window_update_flags (root_window, NULL, 0); 3139 set_window_update_flags (root_window, false);
3126} 3140}
3127 3141
3128 3142
@@ -3174,7 +3188,7 @@ update_single_window (struct window *w, bool force_p)
3174 update_end (f); 3188 update_end (f);
3175 3189
3176 /* Reset flag in W. */ 3190 /* Reset flag in W. */
3177 w->must_be_updated_p = 0; 3191 w->must_be_updated_p = false;
3178 } 3192 }
3179} 3193}
3180 3194
@@ -3897,18 +3911,17 @@ set_window_cursor_after_update (struct window *w)
3897} 3911}
3898 3912
3899 3913
3900/* If B is NULL, set WINDOW->must_be_updated_p to ON_P for all windows in 3914/* Set WINDOW->must_be_updated_p to ON_P for all windows in
3901 the window tree rooted at W. Otherwise set WINDOW->must_be_updated_p 3915 the window tree rooted at W. */
3902 to ON_P only for windows that displays B. */
3903 3916
3904void 3917static void
3905set_window_update_flags (struct window *w, struct buffer *b, bool on_p) 3918set_window_update_flags (struct window *w, bool on_p)
3906{ 3919{
3907 while (w) 3920 while (w)
3908 { 3921 {
3909 if (WINDOWP (w->contents)) 3922 if (WINDOWP (w->contents))
3910 set_window_update_flags (XWINDOW (w->contents), b, on_p); 3923 set_window_update_flags (XWINDOW (w->contents), on_p);
3911 else if (!(b && b != XBUFFER (w->contents))) 3924 else
3912 w->must_be_updated_p = on_p; 3925 w->must_be_updated_p = on_p;
3913 3926
3914 w = NILP (w->next) ? 0 : XWINDOW (w->next); 3927 w = NILP (w->next) ? 0 : XWINDOW (w->next);
@@ -5275,7 +5288,7 @@ marginal_area_string (struct window *w, enum window_part part,
5275 if (area == RIGHT_MARGIN_AREA) 5288 if (area == RIGHT_MARGIN_AREA)
5276 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 5289 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5277 ? WINDOW_LEFT_FRINGE_WIDTH (w) 5290 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5278 : WINDOW_TOTAL_FRINGE_WIDTH (w)) 5291 : WINDOW_FRINGES_WIDTH (w))
5279 + window_box_width (w, LEFT_MARGIN_AREA) 5292 + window_box_width (w, LEFT_MARGIN_AREA)
5280 + window_box_width (w, TEXT_AREA)); 5293 + window_box_width (w, TEXT_AREA));
5281 else 5294 else
@@ -5367,7 +5380,7 @@ handle_window_change_signal (int sig)
5367 /* Record the new sizes, but don't reallocate the data 5380 /* Record the new sizes, but don't reallocate the data
5368 structures now. Let that be done later outside of the 5381 structures now. Let that be done later outside of the
5369 signal handler. */ 5382 signal handler. */
5370 change_frame_size (XFRAME (frame), height, width, 0, 1, 0); 5383 change_frame_size (XFRAME (frame), width, height, 0, 1, 0, 0);
5371 } 5384 }
5372 } 5385 }
5373} 5386}
@@ -5401,17 +5414,21 @@ do_pending_window_change (bool safe)
5401 { 5414 {
5402 struct frame *f = XFRAME (frame); 5415 struct frame *f = XFRAME (frame);
5403 5416
5404 if (f->new_text_lines != 0 || f->new_text_cols != 0) 5417 if (f->new_height != 0 || f->new_width != 0)
5405 change_frame_size (f, f->new_text_lines, f->new_text_cols, 5418 change_frame_size (f, f->new_width, f->new_height,
5406 0, 0, safe); 5419 0, 0, safe, f->new_pixelwise);
5407 } 5420 }
5408 } 5421 }
5409} 5422}
5410 5423
5411
5412/* Change the frame height and/or width. Values may be given as zero to 5424/* Change the frame height and/or width. Values may be given as zero to
5413 indicate no change is to take place. 5425 indicate no change is to take place.
5414 5426
5427 new_height and new_width refer to the text portion of the frame. It
5428 doesn't matter for new_height, since text and total portion are the
5429 same in that case. But new_width must be enlarged to get the total
5430 width of the frame.
5431
5415 If DELAY, assume we're being called from a signal handler, and 5432 If DELAY, assume we're being called from a signal handler, and
5416 queue the change for later - perhaps the next redisplay. 5433 queue the change for later - perhaps the next redisplay.
5417 Since this tries to resize windows, we can't call it 5434 Since this tries to resize windows, we can't call it
@@ -5421,8 +5438,8 @@ do_pending_window_change (bool safe)
5421 safe to change frame sizes while a redisplay is in progress. */ 5438 safe to change frame sizes while a redisplay is in progress. */
5422 5439
5423void 5440void
5424change_frame_size (struct frame *f, int newheight, int newwidth, 5441change_frame_size (struct frame *f, int new_width, int new_height,
5425 bool pretend, bool delay, bool safe) 5442 bool pretend, bool delay, bool safe, bool pixelwise)
5426{ 5443{
5427 Lisp_Object tail, frame; 5444 Lisp_Object tail, frame;
5428 5445
@@ -5433,55 +5450,72 @@ change_frame_size (struct frame *f, int newheight, int newwidth,
5433 ttys. */ 5450 ttys. */
5434 FOR_EACH_FRAME (tail, frame) 5451 FOR_EACH_FRAME (tail, frame)
5435 if (! FRAME_WINDOW_P (XFRAME (frame))) 5452 if (! FRAME_WINDOW_P (XFRAME (frame)))
5436 change_frame_size_1 (XFRAME (frame), newheight, newwidth, 5453 change_frame_size_1 (XFRAME (frame), new_width, new_height,
5437 pretend, delay, safe); 5454 pretend, delay, safe, pixelwise);
5438 } 5455 }
5439 else 5456 else
5440 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe); 5457 change_frame_size_1 (f, new_width, new_height, pretend, delay, safe,
5458 pixelwise);
5441} 5459}
5442 5460
5443static void 5461static void
5444change_frame_size_1 (struct frame *f, int newheight, int newwidth, 5462change_frame_size_1 (struct frame *f, int new_width, int new_height,
5445 bool pretend, bool delay, bool safe) 5463 bool pretend, bool delay, bool safe, bool pixelwise)
5446{ 5464{
5447 int new_frame_total_cols; 5465 int new_text_width, new_text_height, new_root_width;
5466 int old_root_width = (FRAME_PIXEL_WIDTH (f)
5467 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
5468 int new_cols, new_lines;
5448 ptrdiff_t count = SPECPDL_INDEX (); 5469 ptrdiff_t count = SPECPDL_INDEX ();
5449 5470
5450 /* If we can't deal with the change now, queue it for later. */ 5471 /* If we can't deal with the change now, queue it for later. */
5451 if (delay || (redisplaying_p && !safe)) 5472 if (delay || (redisplaying_p && !safe))
5452 { 5473 {
5453 f->new_text_lines = newheight; 5474 f->new_width = new_width;
5454 f->new_text_cols = newwidth; 5475 f->new_height = new_height;
5476 f->new_pixelwise = pixelwise;
5455 delayed_size_change = 1; 5477 delayed_size_change = 1;
5456 return; 5478 return;
5457 } 5479 }
5458 5480
5459 /* This size-change overrides any pending one for this frame. */ 5481 /* This size-change overrides any pending one for this frame. */
5460 f->new_text_lines = 0; 5482 f->new_height = 0;
5461 f->new_text_cols = 0; 5483 f->new_width = 0;
5484 f->new_pixelwise = 0;
5462 5485
5463 /* If an argument is zero, set it to the current value. */ 5486 /* If an argument is zero, set it to the current value. */
5464 if (newheight == 0) 5487 if (pixelwise)
5465 newheight = FRAME_LINES (f); 5488 {
5466 if (newwidth == 0) 5489 new_text_width = (new_width == 0) ? FRAME_TEXT_WIDTH (f) : new_width;
5467 newwidth = FRAME_COLS (f); 5490 new_text_height = (new_height == 0) ? FRAME_TEXT_HEIGHT (f) : new_height;
5491 new_cols = new_text_width / FRAME_COLUMN_WIDTH (f);
5492 new_lines = new_text_height / FRAME_LINE_HEIGHT (f);
5493 }
5494 else
5495 {
5496 new_cols = (new_width == 0) ? FRAME_COLS (f) : new_width;
5497 new_lines = (new_height == 0) ? FRAME_LINES (f) : new_height;
5498 new_text_width = new_cols * FRAME_COLUMN_WIDTH (f);
5499 new_text_height = new_lines * FRAME_LINE_HEIGHT (f);
5500 }
5468 5501
5469 /* Compute width of windows in F. */ 5502 /* Compute width of windows in F. */
5470 /* Round up to the smallest acceptable size. */ 5503 /* Round up to the smallest acceptable size. */
5471 check_frame_size (f, &newheight, &newwidth); 5504 check_frame_size (f, &new_text_width, &new_text_height, 1);
5472 5505
5473 /* This is the width of the frame with vertical scroll bars and fringe 5506 /* This is the width of the frame without vertical scroll bars and
5474 columns. Do this after rounding - see discussion of bug#9723. */ 5507 fringe columns. Do this after rounding - see discussion of
5475 new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth); 5508 bug#9723. */
5476 5509 new_root_width = (new_text_width
5510 /* PXM: Use the configured scrollbar width !?? */
5511 + FRAME_SCROLL_BAR_AREA_WIDTH (f)
5512 + FRAME_TOTAL_FRINGE_WIDTH (f));
5477 /* If we're not changing the frame size, quit now. */ 5513 /* If we're not changing the frame size, quit now. */
5478 /* Frame width may be unchanged but the text portion may change, for 5514 /* Frame width may be unchanged but the text portion may change, for
5479 example, fullscreen and remove/add scroll bar. */ 5515 example, fullscreen and remove/add scroll bar. */
5480 if (newheight == FRAME_LINES (f) 5516 if (new_text_height == FRAME_TEXT_HEIGHT (f)
5481 /* Text portion unchanged? */ 5517 && new_text_width == FRAME_TEXT_WIDTH (f)
5482 && newwidth == FRAME_COLS (f) 5518 && new_root_width == old_root_width)
5483 /* Frame width unchanged? */
5484 && new_frame_total_cols == FRAME_TOTAL_COLS (f))
5485 return; 5519 return;
5486 5520
5487 block_input (); 5521 block_input ();
@@ -5490,36 +5524,44 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
5490 /* We only can set screen dimensions to certain values supported 5524 /* We only can set screen dimensions to certain values supported
5491 by our video hardware. Try to find the smallest size greater 5525 by our video hardware. Try to find the smallest size greater
5492 or equal to the requested dimensions. */ 5526 or equal to the requested dimensions. */
5493 dos_set_window_size (&newheight, &newwidth); 5527 dos_set_window_size (&new_lines, &new_cols);
5494#endif 5528#endif
5495 5529
5496 if (newheight != FRAME_LINES (f)) 5530 if (new_text_height != FRAME_TEXT_HEIGHT (f))
5497 { 5531 {
5498 resize_frame_windows (f, newheight, 0); 5532 resize_frame_windows (f, new_text_height, 0, 1);
5499 5533
5500 /* MSDOS frames cannot PRETEND, as they change frame size by 5534 /* MSDOS frames cannot PRETEND, as they change frame size by
5501 manipulating video hardware. */ 5535 manipulating video hardware. */
5502 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 5536 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
5503 FrameRows (FRAME_TTY (f)) = newheight; 5537 FrameRows (FRAME_TTY (f)) = new_height;
5504 } 5538 }
5505 5539
5506 if (new_frame_total_cols != FRAME_TOTAL_COLS (f)) 5540 if (new_text_width != FRAME_TEXT_WIDTH (f)
5541 || new_root_width != old_root_width)
5507 { 5542 {
5508 resize_frame_windows (f, new_frame_total_cols, 1); 5543 resize_frame_windows (f, new_root_width, 1, 1);
5509 5544
5510 /* MSDOS frames cannot PRETEND, as they change frame size by 5545 /* MSDOS frames cannot PRETEND, as they change frame size by
5511 manipulating video hardware. */ 5546 manipulating video hardware. */
5512 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 5547 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
5513 FrameCols (FRAME_TTY (f)) = newwidth; 5548 FrameCols (FRAME_TTY (f)) = new_cols;
5514 5549
5515#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS) 5550#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
5516 if (WINDOWP (f->tool_bar_window)) 5551 if (WINDOWP (f->tool_bar_window))
5517 XWINDOW (f->tool_bar_window)->total_cols = newwidth; 5552 {
5553 XWINDOW (f->tool_bar_window)->total_cols = new_cols;
5554 XWINDOW (f->tool_bar_window)->pixel_width = new_root_width;
5555 }
5518#endif 5556#endif
5519 } 5557 }
5520 5558
5521 FRAME_LINES (f) = newheight; 5559 SET_FRAME_COLS (f, new_cols);
5522 SET_FRAME_COLS (f, newwidth); 5560 FRAME_LINES (f) = new_lines;
5561 FRAME_TEXT_WIDTH (f) = new_text_width;
5562 FRAME_TEXT_HEIGHT (f) = new_text_height;
5563 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width);
5564 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height);
5523 5565
5524 { 5566 {
5525 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); 5567 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
@@ -5546,8 +5588,6 @@ change_frame_size_1 (struct frame *f, int newheight, int newwidth,
5546 5588
5547 unbind_to (count, Qnil); 5589 unbind_to (count, Qnil);
5548} 5590}
5549
5550
5551 5591
5552/*********************************************************************** 5592/***********************************************************************
5553 Terminal Related Lisp Functions 5593 Terminal Related Lisp Functions
@@ -6076,8 +6116,8 @@ init_display (void)
6076#endif 6116#endif
6077 t->display_info.tty->top_frame = selected_frame; 6117 t->display_info.tty->top_frame = selected_frame;
6078 change_frame_size (XFRAME (selected_frame), 6118 change_frame_size (XFRAME (selected_frame),
6079 FrameRows (t->display_info.tty), 6119 FrameCols (t->display_info.tty),
6080 FrameCols (t->display_info.tty), 0, 0, 1); 6120 FrameRows (t->display_info.tty), 0, 0, 1, 0);
6081 6121
6082 /* Delete the initial terminal. */ 6122 /* Delete the initial terminal. */
6083 if (--initial_terminal->reference_count == 0 6123 if (--initial_terminal->reference_count == 0
diff --git a/src/editfns.c b/src/editfns.c
index 277e5b60704..8e47d1f82e4 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -343,16 +343,15 @@ overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
343 return idx; 343 return idx;
344} 344}
345 345
346/* Return the value of property PROP, in OBJECT at POSITION. 346DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0,
347 It's the value of PROP that a char inserted at POSITION would get. 347 doc: /* Return the value of POSITION's property PROP, in OBJECT.
348 OBJECT is optional and defaults to the current buffer. 348Almost identical to `get-char-property' except for the following difference:
349 If OBJECT is a buffer, then overlay properties are considered as well as 349Whereas `get-char-property' returns the property of the char at (i.e. right
350 text properties. 350after) POSITION, this pays attention to properties's stickiness and overlays's
351 If OBJECT is a window, then that window's buffer is used, but 351advancement settings, in order to find the property of POSITION itself,
352 window-specific overlays are considered only if they are associated 352i.e. the property that a char would inherit if it were inserted
353 with OBJECT. */ 353at POSITION. */)
354Lisp_Object 354 (Lisp_Object position, register Lisp_Object prop, Lisp_Object object)
355get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object object)
356{ 355{
357 CHECK_NUMBER_COERCE_MARKER (position); 356 CHECK_NUMBER_COERCE_MARKER (position);
358 357
@@ -484,7 +483,7 @@ find_field (Lisp_Object pos, Lisp_Object merge_at_boundary,
484 specially. */ 483 specially. */
485 if (NILP (merge_at_boundary)) 484 if (NILP (merge_at_boundary))
486 { 485 {
487 Lisp_Object field = get_pos_property (pos, Qfield, Qnil); 486 Lisp_Object field = Fget_pos_property (pos, Qfield, Qnil);
488 if (!EQ (field, after_field)) 487 if (!EQ (field, after_field))
489 at_field_end = 1; 488 at_field_end = 1;
490 if (!EQ (field, before_field)) 489 if (!EQ (field, before_field))
@@ -683,7 +682,7 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
683 && (!NILP (Fget_char_property (new_pos, Qfield, Qnil)) 682 && (!NILP (Fget_char_property (new_pos, Qfield, Qnil))
684 || !NILP (Fget_char_property (old_pos, Qfield, Qnil)) 683 || !NILP (Fget_char_property (old_pos, Qfield, Qnil))
685 /* To recognize field boundaries, we must also look at the 684 /* To recognize field boundaries, we must also look at the
686 previous positions; we could use `get_pos_property' 685 previous positions; we could use `Fget_pos_property'
687 instead, but in itself that would fail inside non-sticky 686 instead, but in itself that would fail inside non-sticky
688 fields (like comint prompts). */ 687 fields (like comint prompts). */
689 || (XFASTINT (new_pos) > BEGV 688 || (XFASTINT (new_pos) > BEGV
@@ -694,10 +693,12 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
694 /* Field boundaries are again a problem; but now we must 693 /* Field boundaries are again a problem; but now we must
695 decide the case exactly, so we need to call 694 decide the case exactly, so we need to call
696 `get_pos_property' as well. */ 695 `get_pos_property' as well. */
697 || (NILP (get_pos_property (old_pos, inhibit_capture_property, Qnil)) 696 || (NILP (Fget_pos_property (old_pos, inhibit_capture_property, Qnil))
698 && (XFASTINT (old_pos) <= BEGV 697 && (XFASTINT (old_pos) <= BEGV
699 || NILP (Fget_char_property (old_pos, inhibit_capture_property, Qnil)) 698 || NILP (Fget_char_property
700 || NILP (Fget_char_property (prev_old, inhibit_capture_property, Qnil)))))) 699 (old_pos, inhibit_capture_property, Qnil))
700 || NILP (Fget_char_property
701 (prev_old, inhibit_capture_property, Qnil))))))
701 /* It is possible that NEW_POS is not within the same field as 702 /* It is possible that NEW_POS is not within the same field as
702 OLD_POS; try to move NEW_POS so that it is. */ 703 OLD_POS; try to move NEW_POS so that it is. */
703 { 704 {
@@ -717,7 +718,7 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
717 /* NEW_POS should be constrained, but only if either 718 /* NEW_POS should be constrained, but only if either
718 ONLY_IN_LINE is nil (in which case any constraint is OK), 719 ONLY_IN_LINE is nil (in which case any constraint is OK),
719 or NEW_POS and FIELD_BOUND are on the same line (in which 720 or NEW_POS and FIELD_BOUND are on the same line (in which
720 case the constraint is OK even if ONLY_IN_LINE is non-nil). */ 721 case the constraint is OK even if ONLY_IN_LINE is non-nil). */
721 && (NILP (only_in_line) 722 && (NILP (only_in_line)
722 /* This is the ONLY_IN_LINE case, check that NEW_POS and 723 /* This is the ONLY_IN_LINE case, check that NEW_POS and
723 FIELD_BOUND are on the same line by seeing whether 724 FIELD_BOUND are on the same line by seeing whether
@@ -3472,7 +3473,6 @@ usage: (message-box FORMAT-STRING &rest ARGS) */)
3472 else 3473 else
3473 { 3474 {
3474 Lisp_Object val = Fformat (nargs, args); 3475 Lisp_Object val = Fformat (nargs, args);
3475#ifdef HAVE_MENUS
3476 Lisp_Object pane, menu; 3476 Lisp_Object pane, menu;
3477 struct gcpro gcpro1; 3477 struct gcpro gcpro1;
3478 3478
@@ -3481,9 +3481,6 @@ usage: (message-box FORMAT-STRING &rest ARGS) */)
3481 menu = Fcons (val, pane); 3481 menu = Fcons (val, pane);
3482 Fx_popup_dialog (Qt, menu, Qt); 3482 Fx_popup_dialog (Qt, menu, Qt);
3483 UNGCPRO; 3483 UNGCPRO;
3484#else /* !HAVE_MENUS */
3485 message3 (val);
3486#endif
3487 return val; 3484 return val;
3488 } 3485 }
3489} 3486}
@@ -3502,11 +3499,9 @@ message; let the minibuffer contents show.
3502usage: (message-or-box FORMAT-STRING &rest ARGS) */) 3499usage: (message-or-box FORMAT-STRING &rest ARGS) */)
3503 (ptrdiff_t nargs, Lisp_Object *args) 3500 (ptrdiff_t nargs, Lisp_Object *args)
3504{ 3501{
3505#ifdef HAVE_MENUS
3506 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 3502 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
3507 && use_dialog_box) 3503 && use_dialog_box)
3508 return Fmessage_box (nargs, args); 3504 return Fmessage_box (nargs, args);
3509#endif
3510 return Fmessage (nargs, args); 3505 return Fmessage (nargs, args);
3511} 3506}
3512 3507
@@ -4836,6 +4831,7 @@ functions if all the text being accessed has this property. */);
4836 defsubr (&Sbuffer_substring); 4831 defsubr (&Sbuffer_substring);
4837 defsubr (&Sbuffer_substring_no_properties); 4832 defsubr (&Sbuffer_substring_no_properties);
4838 defsubr (&Sbuffer_string); 4833 defsubr (&Sbuffer_string);
4834 defsubr (&Sget_pos_property);
4839 4835
4840 defsubr (&Spoint_marker); 4836 defsubr (&Spoint_marker);
4841 defsubr (&Smark_marker); 4837 defsubr (&Smark_marker);
diff --git a/src/emacs.c b/src/emacs.c
index 22be1d82949..af69e2c4efe 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1539,6 +1539,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1539 init_keyboard (); /* This too must precede init_sys_modes. */ 1539 init_keyboard (); /* This too must precede init_sys_modes. */
1540 if (!noninteractive) 1540 if (!noninteractive)
1541 init_display (); /* Determine terminal type. Calls init_sys_modes. */ 1541 init_display (); /* Determine terminal type. Calls init_sys_modes. */
1542#if HAVE_W32NOTIFY
1543 else
1544 init_crit (); /* w32notify.c needs this in batch mode. */
1545#endif /* HAVE_W32NOTIFY */
1542 init_xdisp (); 1546 init_xdisp ();
1543#ifdef HAVE_WINDOW_SYSTEM 1547#ifdef HAVE_WINDOW_SYSTEM
1544 init_fringe (); 1548 init_fringe ();
@@ -2198,10 +2202,13 @@ synchronize_system_messages_locale (void)
2198 2202
2199 2203
2200Lisp_Object 2204Lisp_Object
2201decode_env_path (const char *evarname, const char *defalt) 2205decode_env_path (const char *evarname, const char *defalt, bool empty)
2202{ 2206{
2203 const char *path, *p; 2207 const char *path, *p;
2204 Lisp_Object lpath, element, tem; 2208 Lisp_Object lpath, element, tem;
2209 /* Default is to use "." for empty path elements.
2210 But if argument EMPTY is true, use nil instead. */
2211 Lisp_Object empty_element = empty ? Qnil : build_string (".");
2205#ifdef WINDOWSNT 2212#ifdef WINDOWSNT
2206 bool defaulted = 0; 2213 bool defaulted = 0;
2207 static const char *emacs_dir_env = "%emacs_dir%/"; 2214 static const char *emacs_dir_env = "%emacs_dir%/";
@@ -2281,34 +2288,38 @@ decode_env_path (const char *evarname, const char *defalt)
2281 if (!p) 2288 if (!p)
2282 p = path + strlen (path); 2289 p = path + strlen (path);
2283 element = (p - path ? make_unibyte_string (path, p - path) 2290 element = (p - path ? make_unibyte_string (path, p - path)
2284 : build_string (".")); 2291 : empty_element);
2292 if (! NILP (element))
2293 {
2285#ifdef WINDOWSNT 2294#ifdef WINDOWSNT
2286 /* Relative file names in the default path are interpreted as 2295 /* Relative file names in the default path are interpreted as
2287 being relative to $emacs_dir. */ 2296 being relative to $emacs_dir. */
2288 if (emacs_dir && defaulted 2297 if (emacs_dir && defaulted
2289 && strncmp (path, emacs_dir_env, emacs_dir_len) == 0) 2298 && strncmp (path, emacs_dir_env, emacs_dir_len) == 0)
2290 element = Fexpand_file_name (Fsubstring (element, 2299 element = Fexpand_file_name (Fsubstring
2291 make_number (emacs_dir_len), 2300 (element,
2292 Qnil), 2301 make_number (emacs_dir_len),
2293 build_unibyte_string (emacs_dir)); 2302 Qnil),
2294#endif 2303 build_unibyte_string (emacs_dir));
2295 2304#endif
2296 /* Add /: to the front of the name 2305
2297 if it would otherwise be treated as magic. */ 2306 /* Add /: to the front of the name
2298 tem = Ffind_file_name_handler (element, Qt); 2307 if it would otherwise be treated as magic. */
2299 2308 tem = Ffind_file_name_handler (element, Qt);
2300 /* However, if the handler says "I'm safe", 2309
2301 don't bother adding /:. */ 2310 /* However, if the handler says "I'm safe",
2302 if (SYMBOLP (tem)) 2311 don't bother adding /:. */
2303 { 2312 if (SYMBOLP (tem))
2304 Lisp_Object prop; 2313 {
2305 prop = Fget (tem, intern ("safe-magic")); 2314 Lisp_Object prop;
2306 if (! NILP (prop)) 2315 prop = Fget (tem, intern ("safe-magic"));
2307 tem = Qnil; 2316 if (! NILP (prop))
2308 } 2317 tem = Qnil;
2318 }
2309 2319
2310 if (! NILP (tem)) 2320 if (! NILP (tem))
2311 element = concat2 (build_string ("/:"), element); 2321 element = concat2 (build_string ("/:"), element);
2322 } /* !NILP (element) */
2312 2323
2313 lpath = Fcons (element, lpath); 2324 lpath = Fcons (element, lpath);
2314 if (*p) 2325 if (*p)
diff --git a/src/epaths.in b/src/epaths.in
index 1f5701e5337..5bfc7158316 100644
--- a/src/epaths.in
+++ b/src/epaths.in
@@ -1,7 +1,6 @@
1/* Hey Emacs, this is -*- C -*- code! */ 1/* Hey Emacs, this is -*- C -*- code! */
2/* 2/*
3Copyright (C) 1993, 1995, 1997, 1999, 2001-2013 Free Software 3Copyright (C) 1993, 1995, 1997, 1999, 2001-2013 Free Software Foundation, Inc.
4Foundation, Inc.
5 4
6This file is part of GNU Emacs. 5This file is part of GNU Emacs.
7 6
@@ -23,8 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 load-path, which is the search path for the Lisp function "load". 22 load-path, which is the search path for the Lisp function "load".
24 Configure (using "make epaths-force") sets this to 23 Configure (using "make epaths-force") sets this to
25 ${standardlisppath}, which typically has a value like: 24 ${standardlisppath}, which typically has a value like:
26 <datadir>/emacs/VERSION/lisp:<datadir>/emacs/VERSION/leim 25 <datadir>/emacs/VERSION/lisp where datadir is eg /usr/local/share.
27 where datadir is eg /usr/local/share.
28*/ 26*/
29#define PATH_LOADSEARCH "/usr/local/share/emacs/lisp" 27#define PATH_LOADSEARCH "/usr/local/share/emacs/lisp"
30 28
diff --git a/src/eval.c b/src/eval.c
index d3fcec5aef4..81666830f4e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3576,6 +3576,73 @@ NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'.
3576 from the debugger. */ 3576 from the debugger. */
3577 return unbind_to (count, eval_sub (exp)); 3577 return unbind_to (count, eval_sub (exp));
3578} 3578}
3579
3580DEFUN ("backtrace--locals", Fbacktrace__locals, Sbacktrace__locals, 1, 2, NULL,
3581 doc: /* Return names and values of local variables of a stack frame.
3582NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. */)
3583 (Lisp_Object nframes, Lisp_Object base)
3584{
3585 union specbinding *frame = get_backtrace_frame (nframes, base);
3586 union specbinding *prevframe
3587 = get_backtrace_frame (make_number (XFASTINT (nframes) - 1), base);
3588 ptrdiff_t distance = specpdl_ptr - frame;
3589 Lisp_Object result = Qnil;
3590 eassert (distance >= 0);
3591
3592 if (!backtrace_p (prevframe))
3593 error ("Activation frame not found!");
3594 if (!backtrace_p (frame))
3595 error ("Activation frame not found!");
3596
3597 /* The specpdl entries normally contain the symbol being bound along with its
3598 `old_value', so it can be restored. The new value to which it is bound is
3599 available in one of two places: either in the current value of the
3600 variable (if it hasn't been rebount yet) or in the `old_value' slot of the
3601 next specpdl entry for it.
3602 `backtrace_eval_unrewind' happens to swap the role of `old_value'
3603 and "new value", so we abuse it here, to fetch the new value.
3604 It's ugly (we'd rather not modify global data) and a bit inefficient,
3605 but it does the job for now. */
3606 backtrace_eval_unrewind (distance);
3607
3608 /* Grab values. */
3609 {
3610 union specbinding *tmp = prevframe;
3611 for (; tmp > frame; tmp--)
3612 {
3613 switch (tmp->kind)
3614 {
3615 case SPECPDL_LET:
3616 case SPECPDL_LET_DEFAULT:
3617 case SPECPDL_LET_LOCAL:
3618 {
3619 Lisp_Object sym = specpdl_symbol (tmp);
3620 Lisp_Object val = specpdl_old_value (tmp);
3621 if (EQ (sym, Qinternal_interpreter_environment))
3622 {
3623 Lisp_Object env = val;
3624 for (; CONSP (env); env = XCDR (env))
3625 {
3626 Lisp_Object binding = XCAR (env);
3627 if (CONSP (binding))
3628 result = Fcons (Fcons (XCAR (binding),
3629 XCDR (binding)),
3630 result);
3631 }
3632 }
3633 else
3634 result = Fcons (Fcons (sym, val), result);
3635 }
3636 }
3637 }
3638 }
3639
3640 /* Restore values from specpdl to original place. */
3641 backtrace_eval_unrewind (-distance);
3642
3643 return result;
3644}
3645
3579 3646
3580void 3647void
3581mark_specpdl (void) 3648mark_specpdl (void)
@@ -3824,6 +3891,7 @@ alist of active lexical bindings. */);
3824 defsubr (&Sbacktrace); 3891 defsubr (&Sbacktrace);
3825 defsubr (&Sbacktrace_frame); 3892 defsubr (&Sbacktrace_frame);
3826 defsubr (&Sbacktrace_eval); 3893 defsubr (&Sbacktrace_eval);
3894 defsubr (&Sbacktrace__locals);
3827 defsubr (&Sspecial_variable_p); 3895 defsubr (&Sspecial_variable_p);
3828 defsubr (&Sfunctionp); 3896 defsubr (&Sfunctionp);
3829} 3897}
diff --git a/src/fileio.c b/src/fileio.c
index 7b4bd7f196d..2ef3f1fe0f9 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3878,6 +3878,9 @@ by calling `format-decode', which see. */)
3878 beg_offset += same_at_start - BEGV_BYTE; 3878 beg_offset += same_at_start - BEGV_BYTE;
3879 end_offset -= ZV_BYTE - same_at_end; 3879 end_offset -= ZV_BYTE - same_at_end;
3880 3880
3881 invalidate_buffer_caches (current_buffer,
3882 BYTE_TO_CHAR (same_at_start),
3883 BYTE_TO_CHAR (same_at_end));
3881 del_range_byte (same_at_start, same_at_end, 0); 3884 del_range_byte (same_at_start, same_at_end, 0);
3882 /* Insert from the file at the proper position. */ 3885 /* Insert from the file at the proper position. */
3883 temp = BYTE_TO_CHAR (same_at_start); 3886 temp = BYTE_TO_CHAR (same_at_start);
@@ -3988,7 +3991,12 @@ by calling `format-decode', which see. */)
3988 { 3991 {
3989 /* Truncate the buffer to the size of the file. */ 3992 /* Truncate the buffer to the size of the file. */
3990 if (same_at_start != same_at_end) 3993 if (same_at_start != same_at_end)
3991 del_range_byte (same_at_start, same_at_end, 0); 3994 {
3995 invalidate_buffer_caches (current_buffer,
3996 BYTE_TO_CHAR (same_at_start),
3997 BYTE_TO_CHAR (same_at_end));
3998 del_range_byte (same_at_start, same_at_end, 0);
3999 }
3992 inserted = 0; 4000 inserted = 0;
3993 4001
3994 unbind_to (this_count, Qnil); 4002 unbind_to (this_count, Qnil);
@@ -4036,6 +4044,9 @@ by calling `format-decode', which see. */)
4036 4044
4037 if (same_at_end != same_at_start) 4045 if (same_at_end != same_at_start)
4038 { 4046 {
4047 invalidate_buffer_caches (current_buffer,
4048 BYTE_TO_CHAR (same_at_start),
4049 BYTE_TO_CHAR (same_at_end));
4039 del_range_byte (same_at_start, same_at_end, 0); 4050 del_range_byte (same_at_start, same_at_end, 0);
4040 temp = GPT; 4051 temp = GPT;
4041 eassert (same_at_start == GPT_BYTE); 4052 eassert (same_at_start == GPT_BYTE);
@@ -5793,6 +5804,24 @@ void
5793init_fileio (void) 5804init_fileio (void)
5794{ 5805{
5795 valid_timestamp_file_system = 0; 5806 valid_timestamp_file_system = 0;
5807
5808 /* fsync can be a significant performance hit. Often it doesn't
5809 suffice to make the file-save operation survive a crash. For
5810 batch scripts, which are typically part of larger shell commands
5811 that don't fsync other files, its effect on performance can be
5812 significant so its utility is particularly questionable.
5813 Hence, for now by default fsync is used only when interactive.
5814
5815 For more on why fsync often fails to work on today's hardware, see:
5816 Zheng M et al. Understanding the robustness of SSDs under power fault.
5817 11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
5818 http://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
5819
5820 For more on why fsync does not suffice even if it works properly, see:
5821 Roche X. Necessary step(s) to synchronize filename operations on disk.
5822 Austin Group Defect 672, 2013-03-19
5823 http://austingroupbugs.net/view.php?id=672 */
5824 write_region_inhibit_fsync = noninteractive;
5796} 5825}
5797 5826
5798void 5827void
@@ -6013,28 +6042,12 @@ in the buffer; this is the default behavior, because the auto-save
6013file is usually more useful if it contains the deleted text. */); 6042file is usually more useful if it contains the deleted text. */);
6014 Vauto_save_include_big_deletions = Qnil; 6043 Vauto_save_include_big_deletions = Qnil;
6015 6044
6016 /* fsync can be a significant performance hit. Often it doesn't
6017 suffice to make the file-save operation survive a crash. For
6018 batch scripts, which are typically part of larger shell commands
6019 that don't fsync other files, its effect on performance can be
6020 significant so its utility is particularly questionable.
6021 Hence, for now by default fsync is used only when interactive.
6022
6023 For more on why fsync often fails to work on today's hardware, see:
6024 Zheng M et al. Understanding the robustness of SSDs under power fault.
6025 11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
6026 http://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
6027
6028 For more on why fsync does not suffice even if it works properly, see:
6029 Roche X. Necessary step(s) to synchronize filename operations on disk.
6030 Austin Group Defect 672, 2013-03-19
6031 http://austingroupbugs.net/view.php?id=672 */
6032 DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync, 6045 DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync,
6033 doc: /* Non-nil means don't call fsync in `write-region'. 6046 doc: /* Non-nil means don't call fsync in `write-region'.
6034This variable affects calls to `write-region' as well as save commands. 6047This variable affects calls to `write-region' as well as save commands.
6035Setting this to nil may avoid data loss if the system loses power or 6048Setting this to nil may avoid data loss if the system loses power or
6036the operating system crashes. */); 6049the operating system crashes. */);
6037 write_region_inhibit_fsync = noninteractive; 6050 write_region_inhibit_fsync = 0; /* See also `init_fileio' above. */
6038 6051
6039 DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash, 6052 DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
6040 doc: /* Specifies whether to use the system's trash can. 6053 doc: /* Specifies whether to use the system's trash can.
diff --git a/src/fns.c b/src/fns.c
index 93829fb1d62..b13bb8d80dc 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -35,11 +35,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35#include "frame.h" 35#include "frame.h"
36#include "window.h" 36#include "window.h"
37#include "blockinput.h" 37#include "blockinput.h"
38#ifdef HAVE_MENUS
39#if defined (HAVE_X_WINDOWS) 38#if defined (HAVE_X_WINDOWS)
40#include "xterm.h" 39#include "xterm.h"
41#endif 40#endif
42#endif /* HAVE_MENUS */
43 41
44Lisp_Object Qstring_lessp; 42Lisp_Object Qstring_lessp;
45static Lisp_Object Qprovide, Qrequire; 43static Lisp_Object Qprovide, Qrequire;
@@ -50,7 +48,7 @@ static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
50 48
51static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; 49static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512;
52 50
53static bool internal_equal (Lisp_Object, Lisp_Object, int, bool); 51static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object);
54 52
55DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, 53DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
56 doc: /* Return the argument unchanged. */) 54 doc: /* Return the argument unchanged. */)
@@ -1357,7 +1355,7 @@ The value is actually the tail of LIST whose car is ELT. */)
1357 register Lisp_Object tem; 1355 register Lisp_Object tem;
1358 CHECK_LIST_CONS (tail, list); 1356 CHECK_LIST_CONS (tail, list);
1359 tem = XCAR (tail); 1357 tem = XCAR (tail);
1360 if (FLOATP (tem) && internal_equal (elt, tem, 0, 0)) 1358 if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil))
1361 return tail; 1359 return tail;
1362 QUIT; 1360 QUIT;
1363 } 1361 }
@@ -1539,15 +1537,12 @@ Write `(setq foo (delq element foo))' to be sure of correctly changing
1539the value of a list `foo'. */) 1537the value of a list `foo'. */)
1540 (register Lisp_Object elt, Lisp_Object list) 1538 (register Lisp_Object elt, Lisp_Object list)
1541{ 1539{
1542 register Lisp_Object tail, prev; 1540 Lisp_Object tail, tortoise, prev = Qnil;
1543 register Lisp_Object tem; 1541 bool skip;
1544 1542
1545 tail = list; 1543 FOR_EACH_TAIL (tail, list, tortoise, skip)
1546 prev = Qnil;
1547 while (CONSP (tail))
1548 { 1544 {
1549 CHECK_LIST_CONS (tail, list); 1545 Lisp_Object tem = XCAR (tail);
1550 tem = XCAR (tail);
1551 if (EQ (elt, tem)) 1546 if (EQ (elt, tem))
1552 { 1547 {
1553 if (NILP (prev)) 1548 if (NILP (prev))
@@ -1557,8 +1552,6 @@ the value of a list `foo'. */)
1557 } 1552 }
1558 else 1553 else
1559 prev = tail; 1554 prev = tail;
1560 tail = XCDR (tail);
1561 QUIT;
1562 } 1555 }
1563 return list; 1556 return list;
1564} 1557}
@@ -1961,7 +1954,7 @@ Floating-point numbers of equal value are `eql', but they may not be `eq'. */)
1961 (Lisp_Object obj1, Lisp_Object obj2) 1954 (Lisp_Object obj1, Lisp_Object obj2)
1962{ 1955{
1963 if (FLOATP (obj1)) 1956 if (FLOATP (obj1))
1964 return internal_equal (obj1, obj2, 0, 0) ? Qt : Qnil; 1957 return internal_equal (obj1, obj2, 0, 0, Qnil) ? Qt : Qnil;
1965 else 1958 else
1966 return EQ (obj1, obj2) ? Qt : Qnil; 1959 return EQ (obj1, obj2) ? Qt : Qnil;
1967} 1960}
@@ -1976,7 +1969,7 @@ Numbers are compared by value, but integers cannot equal floats.
1976Symbols must match exactly. */) 1969Symbols must match exactly. */)
1977 (register Lisp_Object o1, Lisp_Object o2) 1970 (register Lisp_Object o1, Lisp_Object o2)
1978{ 1971{
1979 return internal_equal (o1, o2, 0, 0) ? Qt : Qnil; 1972 return internal_equal (o1, o2, 0, 0, Qnil) ? Qt : Qnil;
1980} 1973}
1981 1974
1982DEFUN ("equal-including-properties", Fequal_including_properties, Sequal_including_properties, 2, 2, 0, 1975DEFUN ("equal-including-properties", Fequal_including_properties, Sequal_including_properties, 2, 2, 0,
@@ -1985,7 +1978,7 @@ This is like `equal' except that it compares the text properties
1985of strings. (`equal' ignores text properties.) */) 1978of strings. (`equal' ignores text properties.) */)
1986 (register Lisp_Object o1, Lisp_Object o2) 1979 (register Lisp_Object o1, Lisp_Object o2)
1987{ 1980{
1988 return internal_equal (o1, o2, 0, 1) ? Qt : Qnil; 1981 return internal_equal (o1, o2, 0, 1, Qnil) ? Qt : Qnil;
1989} 1982}
1990 1983
1991/* DEPTH is current depth of recursion. Signal an error if it 1984/* DEPTH is current depth of recursion. Signal an error if it
@@ -1993,10 +1986,39 @@ of strings. (`equal' ignores text properties.) */)
1993 PROPS means compare string text properties too. */ 1986 PROPS means compare string text properties too. */
1994 1987
1995static bool 1988static bool
1996internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props) 1989internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props,
1990 Lisp_Object ht)
1997{ 1991{
1998 if (depth > 200) 1992 if (depth > 10)
1999 error ("Stack overflow in equal"); 1993 {
1994 if (depth > 200)
1995 error ("Stack overflow in equal");
1996 if (NILP (ht))
1997 {
1998 Lisp_Object args[2] = { QCtest, Qeq };
1999 ht = Fmake_hash_table (2, args);
2000 }
2001 switch (XTYPE (o1))
2002 {
2003 case Lisp_Cons: case Lisp_Misc: case Lisp_Vectorlike:
2004 {
2005 struct Lisp_Hash_Table *h = XHASH_TABLE (ht);
2006 EMACS_UINT hash;
2007 ptrdiff_t i = hash_lookup (h, o1, &hash);
2008 if (i >= 0)
2009 { /* `o1' was seen already. */
2010 Lisp_Object o2s = HASH_VALUE (h, i);
2011 if (!NILP (Fmemq (o2, o2s)))
2012 return 1;
2013 else
2014 set_hash_value_slot (h, i, Fcons (o2, o2s));
2015 }
2016 else
2017 hash_put (h, o1, Fcons (o2, Qnil), hash);
2018 }
2019 default: ;
2020 }
2021 }
2000 2022
2001 tail_recurse: 2023 tail_recurse:
2002 QUIT; 2024 QUIT;
@@ -2019,10 +2041,11 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
2019 } 2041 }
2020 2042
2021 case Lisp_Cons: 2043 case Lisp_Cons:
2022 if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1, props)) 2044 if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1, props, ht))
2023 return 0; 2045 return 0;
2024 o1 = XCDR (o1); 2046 o1 = XCDR (o1);
2025 o2 = XCDR (o2); 2047 o2 = XCDR (o2);
2048 /* FIXME: This inf-loops in a circular list! */
2026 goto tail_recurse; 2049 goto tail_recurse;
2027 2050
2028 case Lisp_Misc: 2051 case Lisp_Misc:
@@ -2031,9 +2054,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
2031 if (OVERLAYP (o1)) 2054 if (OVERLAYP (o1))
2032 { 2055 {
2033 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), 2056 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
2034 depth + 1, props) 2057 depth + 1, props, ht)
2035 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2), 2058 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
2036 depth + 1, props)) 2059 depth + 1, props, ht))
2037 return 0; 2060 return 0;
2038 o1 = XOVERLAY (o1)->plist; 2061 o1 = XOVERLAY (o1)->plist;
2039 o2 = XOVERLAY (o2)->plist; 2062 o2 = XOVERLAY (o2)->plist;
@@ -2085,7 +2108,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
2085 Lisp_Object v1, v2; 2108 Lisp_Object v1, v2;
2086 v1 = AREF (o1, i); 2109 v1 = AREF (o1, i);
2087 v2 = AREF (o2, i); 2110 v2 = AREF (o2, i);
2088 if (!internal_equal (v1, v2, depth + 1, props)) 2111 if (!internal_equal (v1, v2, depth + 1, props, ht))
2089 return 0; 2112 return 0;
2090 } 2113 }
2091 return 1; 2114 return 1;
@@ -2416,7 +2439,6 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */)
2416 2439
2417 CHECK_STRING (prompt); 2440 CHECK_STRING (prompt);
2418 2441
2419#ifdef HAVE_MENUS
2420 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 2442 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2421 && use_dialog_box) 2443 && use_dialog_box)
2422 { 2444 {
@@ -2430,7 +2452,6 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */)
2430 UNGCPRO; 2452 UNGCPRO;
2431 return obj; 2453 return obj;
2432 } 2454 }
2433#endif /* HAVE_MENUS */
2434 2455
2435 args[0] = prompt; 2456 args[0] = prompt;
2436 args[1] = build_string ("(yes or no) "); 2457 args[1] = build_string ("(yes or no) ");
diff --git a/src/font.c b/src/font.c
index 1e1670b21af..ad604ebe744 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2718,7 +2718,7 @@ font_list_entities (struct frame *f, Lisp_Object spec)
2718 ASET (scratch_font_spec, FONT_SPACING_INDEX, AREF (spec, FONT_SPACING_INDEX)); 2718 ASET (scratch_font_spec, FONT_SPACING_INDEX, AREF (spec, FONT_SPACING_INDEX));
2719 ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX)); 2719 ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX));
2720 2720
2721 for (i = 0; driver_list; driver_list = driver_list->next) 2721 for (; driver_list; driver_list = driver_list->next)
2722 if (driver_list->on 2722 if (driver_list->on
2723 && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) 2723 && (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
2724 { 2724 {
diff --git a/src/font.h b/src/font.h
index 2db8d35af48..539ebeba52a 100644
--- a/src/font.h
+++ b/src/font.h
@@ -234,6 +234,11 @@ enum font_property_index
234#define FONT_SET_STYLE(font, prop, val) \ 234#define FONT_SET_STYLE(font, prop, val) \
235 ASET ((font), prop, make_number (font_style_to_value (prop, val, 1))) 235 ASET ((font), prop, make_number (font_style_to_value (prop, val, 1)))
236 236
237#define FONT_WIDTH(f) ((f)->max_width)
238#define FONT_HEIGHT(f) ((f)->height)
239#define FONT_BASE(f) ((f)->ascent)
240#define FONT_DESCENT(f) ((f)->descent)
241
237extern Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript; 242extern Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript;
238extern Lisp_Object QCavgwidth, QCantialias, QCfont_entity; 243extern Lisp_Object QCavgwidth, QCantialias, QCfont_entity;
239extern Lisp_Object Qp; 244extern Lisp_Object Qp;
@@ -307,6 +312,10 @@ struct font
307 /* Ascent and descent of the font (in pixels). */ 312 /* Ascent and descent of the font (in pixels). */
308 int ascent, descent; 313 int ascent, descent;
309 314
315 /* The following members makes sense on graphic displays only. */
316
317#if defined (HAVE_WINDOW_SYSTEM)
318
310 /* Vertical pixel width of the underline. If is zero if that 319 /* Vertical pixel width of the underline. If is zero if that
311 information is not in the font. */ 320 information is not in the font. */
312 int underline_thickness; 321 int underline_thickness;
@@ -369,12 +378,6 @@ struct font
369 registered in char-table `use-default-ascent'. */ 378 registered in char-table `use-default-ascent'. */
370 int default_ascent; 379 int default_ascent;
371 380
372 /* CCL program to calculate code points of the font. */
373 struct ccl_program *font_encoder;
374
375 /* Font-driver for the font. */
376 struct font_driver *driver;
377
378 /* Charset to encode a character code into a glyph code of the font. 381 /* Charset to encode a character code into a glyph code of the font.
379 -1 means that the font doesn't require this information to encode 382 -1 means that the font doesn't require this information to encode
380 a character. */ 383 a character. */
@@ -385,6 +388,11 @@ struct font
385 determine it. */ 388 determine it. */
386 int repertory_charset; 389 int repertory_charset;
387 390
391#endif /* HAVE_WINDOW_SYSTEM */
392
393 /* Font-driver for the font. */
394 struct font_driver *driver;
395
388 /* There are more members in this structure, but they are private 396 /* There are more members in this structure, but they are private
389 to the font-driver. */ 397 to the font-driver. */
390}; 398};
@@ -412,7 +420,6 @@ struct font_bitmap
412 int left; 420 int left;
413 int top; 421 int top;
414 int advance; 422 int advance;
415 void *extra;
416}; 423};
417 424
418/* Predicates to check various font-related objects. */ 425/* Predicates to check various font-related objects. */
diff --git a/src/frame.c b/src/frame.c
index 4494edda5d7..03bdf696c47 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -78,6 +78,7 @@ Lisp_Object Qleft, Qright;
78Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; 78Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
79Lisp_Object Qtooltip; 79Lisp_Object Qtooltip;
80Lisp_Object Qinternal_border_width; 80Lisp_Object Qinternal_border_width;
81Lisp_Object Qright_divider_width, Qbottom_divider_width;
81Lisp_Object Qmouse_color; 82Lisp_Object Qmouse_color;
82Lisp_Object Qminibuffer; 83Lisp_Object Qminibuffer;
83Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; 84Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
@@ -109,6 +110,8 @@ Lisp_Object Qalpha;
109 110
110Lisp_Object Qface_set_after_frame_default; 111Lisp_Object Qface_set_after_frame_default;
111 112
113static Lisp_Object Qfocus_in_hook;
114static Lisp_Object Qfocus_out_hook;
112static Lisp_Object Qdelete_frame_functions; 115static Lisp_Object Qdelete_frame_functions;
113 116
114static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource; 117static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
@@ -195,9 +198,12 @@ static void
195set_menu_bar_lines_1 (Lisp_Object window, int n) 198set_menu_bar_lines_1 (Lisp_Object window, int n)
196{ 199{
197 struct window *w = XWINDOW (window); 200 struct window *w = XWINDOW (window);
201 struct frame *f = XFRAME (WINDOW_FRAME (w));
198 202
199 w->top_line += n; 203 w->top_line += n;
204 w->pixel_top += n * FRAME_LINE_HEIGHT (f);
200 w->total_lines -= n; 205 w->total_lines -= n;
206 w->pixel_height -= n * FRAME_LINE_HEIGHT (f);
201 207
202 /* Handle just the top child in a vertical split. */ 208 /* Handle just the top child in a vertical split. */
203 if (WINDOW_VERTICAL_COMBINATION_P (w)) 209 if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -234,6 +240,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
234 windows_or_buffers_changed = 14; 240 windows_or_buffers_changed = 14;
235 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 241 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
236 FRAME_MENU_BAR_LINES (f) = nlines; 242 FRAME_MENU_BAR_LINES (f) = nlines;
243 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
237 set_menu_bar_lines_1 (f->root_window, nlines - olines); 244 set_menu_bar_lines_1 (f->root_window, nlines - olines);
238 adjust_frame_glyphs (f); 245 adjust_frame_glyphs (f);
239 } 246 }
@@ -323,6 +330,7 @@ make_frame (bool mini_p)
323{ 330{
324 Lisp_Object frame; 331 Lisp_Object frame;
325 register struct frame *f; 332 register struct frame *f;
333 register struct window *rw, *mw;
326 register Lisp_Object root_window; 334 register Lisp_Object root_window;
327 register Lisp_Object mini_window; 335 register Lisp_Object mini_window;
328 336
@@ -337,33 +345,36 @@ make_frame (bool mini_p)
337 non-Lisp data, so do it only for slots which should not be zero. 345 non-Lisp data, so do it only for slots which should not be zero.
338 To avoid subtle bugs and for the sake of readability, it's better to 346 To avoid subtle bugs and for the sake of readability, it's better to
339 initialize enum members explicitly even if their values are zero. */ 347 initialize enum members explicitly even if their values are zero. */
340 f->wants_modeline = 1; 348 f->wants_modeline = true;
341 f->garbaged = 1; 349 f->redisplay = true;
350 f->garbaged = true;
342 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 351 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
343 f->column_width = 1; /* !FRAME_WINDOW_P value */ 352 f->column_width = 1; /* !FRAME_WINDOW_P value. */
344 f->line_height = 1; /* !FRAME_WINDOW_P value */ 353 f->line_height = 1; /* !FRAME_WINDOW_P value. */
345#ifdef HAVE_WINDOW_SYSTEM 354#ifdef HAVE_WINDOW_SYSTEM
346 f->want_fullscreen = FULLSCREEN_NONE; 355 f->want_fullscreen = FULLSCREEN_NONE;
347#endif 356#endif
348 357
349 root_window = make_window (); 358 root_window = make_window ();
359 rw = XWINDOW (root_window);
350 if (mini_p) 360 if (mini_p)
351 { 361 {
352 mini_window = make_window (); 362 mini_window = make_window ();
353 wset_next (XWINDOW (root_window), mini_window); 363 mw = XWINDOW (mini_window);
354 wset_prev (XWINDOW (mini_window), root_window); 364 wset_next (rw, mini_window);
355 XWINDOW (mini_window)->mini = 1; 365 wset_prev (mw, root_window);
356 wset_frame (XWINDOW (mini_window), frame); 366 mw->mini = 1;
367 wset_frame (mw, frame);
357 fset_minibuffer_window (f, mini_window); 368 fset_minibuffer_window (f, mini_window);
358 } 369 }
359 else 370 else
360 { 371 {
361 mini_window = Qnil; 372 mini_window = Qnil;
362 wset_next (XWINDOW (root_window), Qnil); 373 wset_next (rw, Qnil);
363 fset_minibuffer_window (f, Qnil); 374 fset_minibuffer_window (f, Qnil);
364 } 375 }
365 376
366 wset_frame (XWINDOW (root_window), frame); 377 wset_frame (rw, frame);
367 378
368 /* 10 is arbitrary, 379 /* 10 is arbitrary,
369 just so that there is "something there." 380 just so that there is "something there."
@@ -371,15 +382,22 @@ make_frame (bool mini_p)
371 382
372 SET_FRAME_COLS (f, 10); 383 SET_FRAME_COLS (f, 10);
373 FRAME_LINES (f) = 10; 384 FRAME_LINES (f) = 10;
385 SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
386 SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
374 387
375 XWINDOW (root_window)->total_cols = 10; 388 rw->total_cols = 10;
376 XWINDOW (root_window)->total_lines = mini_p ? 9 : 10; 389 rw->pixel_width = rw->total_cols * FRAME_COLUMN_WIDTH (f);
390 rw->total_lines = mini_p ? 9 : 10;
391 rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f);
377 392
378 if (mini_p) 393 if (mini_p)
379 { 394 {
380 XWINDOW (mini_window)->total_cols = 10; 395 mw->top_line = rw->total_lines;
381 XWINDOW (mini_window)->top_line = 9; 396 mw->pixel_top = rw->pixel_height;
382 XWINDOW (mini_window)->total_lines = 1; 397 mw->total_cols = rw->total_cols;
398 mw->pixel_width = rw->pixel_width;
399 mw->total_lines = 1;
400 mw->pixel_height = FRAME_LINE_HEIGHT (f);
383 } 401 }
384 402
385 /* Choose a buffer for the frame's root window. */ 403 /* Choose a buffer for the frame's root window. */
@@ -600,7 +618,8 @@ make_terminal_frame (struct terminal *terminal)
600#endif /* not MSDOS */ 618#endif /* not MSDOS */
601 619
602 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; 620 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
603 FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1; 621 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
622 FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
604 623
605 /* Set the top frame to the newly created frame. */ 624 /* Set the top frame to the newly created frame. */
606 if (FRAMEP (FRAME_TTY (f)->top_frame) 625 if (FRAMEP (FRAME_TTY (f)->top_frame)
@@ -720,7 +739,7 @@ affects all frames on the same terminal device. */)
720 { 739 {
721 int width, height; 740 int width, height;
722 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height); 741 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
723 change_frame_size (f, height, width, 0, 0, 0); 742 change_frame_size (f, width, height, 0, 0, 0, 0);
724 } 743 }
725 744
726 adjust_frame_glyphs (f); 745 adjust_frame_glyphs (f);
@@ -783,9 +802,6 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
783 if (sf == XFRAME (frame)) 802 if (sf == XFRAME (frame))
784 return frame; 803 return frame;
785 804
786 /* This is too greedy; it causes inappropriate focus redirection
787 that's hard to get rid of. */
788#if 0
789 /* If a frame's focus has been redirected toward the currently 805 /* If a frame's focus has been redirected toward the currently
790 selected frame, we should change the redirection to point to the 806 selected frame, we should change the redirection to point to the
791 newly selected frame. This means that if the focus is redirected 807 newly selected frame. This means that if the focus is redirected
@@ -793,6 +809,9 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
793 can use `other-window' to switch between all the frames using 809 can use `other-window' to switch between all the frames using
794 that minibuffer frame, and the focus redirection will follow us 810 that minibuffer frame, and the focus redirection will follow us
795 around. */ 811 around. */
812#if 0
813 /* This is too greedy; it causes inappropriate focus redirection
814 that's hard to get rid of. */
796 if (track) 815 if (track)
797 { 816 {
798 Lisp_Object tail; 817 Lisp_Object tail;
@@ -885,27 +904,6 @@ This function returns FRAME, or nil if FRAME has been deleted. */)
885 return do_switch_frame (frame, 1, 0, norecord); 904 return do_switch_frame (frame, 1, 0, norecord);
886} 905}
887 906
888DEFUN ("handle-focus-in", Fhandle_focus_in, Shandle_focus_in, 1, 1, "e",
889 doc: /* Handle a focus-in event.
890Focus in events are usually bound to this function.
891Focus in events occur when a frame has focus, but a switch-frame event
892is not generated.
893This function checks if blink-cursor timers should be turned on again. */)
894 (Lisp_Object event)
895{
896 return call0 (intern ("blink-cursor-check"));
897}
898
899DEFUN ("handle-focus-out", Fhandle_focus_out, Shandle_focus_out, 1, 1, "e",
900 doc: /* Handle a focus-out event.
901Focus out events are usually bound to this function.
902Focus out events occur when no frame has focus.
903This function checks if blink-cursor timers should be turned off. */)
904 (Lisp_Object event)
905{
906 return call0 (intern ("blink-cursor-suspend"));
907}
908
909DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e", 907DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
910 doc: /* Handle a switch-frame event EVENT. 908 doc: /* Handle a switch-frame event EVENT.
911Switch-frame events are usually bound to this function. 909Switch-frame events are usually bound to this function.
@@ -920,7 +918,8 @@ to that frame. */)
920 /* Preserve prefix arg that the command loop just cleared. */ 918 /* Preserve prefix arg that the command loop just cleared. */
921 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); 919 kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
922 Frun_hooks (1, &Qmouse_leave_buffer_hook); 920 Frun_hooks (1, &Qmouse_leave_buffer_hook);
923 Fhandle_focus_in (event); // switch-frame implies a focus in. 921 /* `switch-frame' implies a focus in. */
922 call1 (intern ("handle-focus-in"), event);
924 return do_switch_frame (event, 0, 0, Qnil); 923 return do_switch_frame (event, 0, 0, Qnil);
925} 924}
926 925
@@ -1699,7 +1698,7 @@ If omitted, FRAME defaults to the currently selected frame. */)
1699 make_frame_visible_1 (f->root_window); 1698 make_frame_visible_1 (f->root_window);
1700 1699
1701 /* Make menu bar update for the Buffers and Frames menus. */ 1700 /* Make menu bar update for the Buffers and Frames menus. */
1702 windows_or_buffers_changed = 15; 1701 /* windows_or_buffers_changed = 15; FIXME: Why? */
1703 1702
1704 XSETFRAME (frame, f); 1703 XSETFRAME (frame, f);
1705 return frame; 1704 return frame;
@@ -2028,6 +2027,20 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
2028 update_mode_lines = 16; 2027 update_mode_lines = 16;
2029} 2028}
2030 2029
2030#ifdef HAVE_NTGUI
2031void
2032set_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
2033{
2034 register Lisp_Object old_alist_elt;
2035
2036 old_alist_elt = Fassq (prop, f->param_alist);
2037 if (EQ (old_alist_elt, Qnil))
2038 fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
2039 else
2040 Fsetcdr (old_alist_elt, val);
2041}
2042#endif
2043
2031void 2044void
2032store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) 2045store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
2033{ 2046{
@@ -2181,9 +2194,17 @@ If FRAME is omitted or nil, return information on the currently selected frame.
2181 :"tty")); 2194 :"tty"));
2182 } 2195 }
2183 store_in_alist (&alist, Qname, f->name); 2196 store_in_alist (&alist, Qname, f->name);
2184 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f)); 2197 height = (f->new_height
2198 ? (f->new_pixelwise
2199 ? (f->new_height / FRAME_LINE_HEIGHT (f))
2200 : f->new_height)
2201 : FRAME_LINES (f));
2185 store_in_alist (&alist, Qheight, make_number (height)); 2202 store_in_alist (&alist, Qheight, make_number (height));
2186 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f)); 2203 width = (f->new_width
2204 ? (f->new_pixelwise
2205 ? (f->new_width / FRAME_COLUMN_WIDTH (f))
2206 : f->new_width)
2207 : FRAME_COLS (f));
2187 store_in_alist (&alist, Qwidth, make_number (width)); 2208 store_in_alist (&alist, Qwidth, make_number (width));
2188 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil)); 2209 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2189 store_in_alist (&alist, Qminibuffer, 2210 store_in_alist (&alist, Qminibuffer,
@@ -2454,80 +2475,180 @@ is used. */)
2454#endif 2475#endif
2455 return make_number (0); 2476 return make_number (0);
2456} 2477}
2478
2479DEFUN ("frame-text-cols", Fframe_text_cols, Sframe_text_cols, 0, 1, 0,
2480 doc: /* Return width in columns of FRAME's text area. */)
2481 (Lisp_Object frame)
2482{
2483 return make_number (FRAME_COLS (decode_any_frame (frame)));
2484}
2485
2486DEFUN ("frame-text-lines", Fframe_text_lines, Sframe_text_lines, 0, 1, 0,
2487 doc: /* Return height in lines of FRAME's text area. */)
2488 (Lisp_Object frame)
2489{
2490 return make_number (FRAME_LINES (decode_any_frame (frame)));
2491}
2492
2493DEFUN ("frame-total-cols", Fframe_total_cols, Sframe_total_cols, 0, 1, 0,
2494 doc: /* Return total columns of FRAME. */)
2495 (Lisp_Object frame)
2496{
2497 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame)));
2498}
2499
2500DEFUN ("frame-text-width", Fframe_text_width, Sframe_text_width, 0, 1, 0,
2501 doc: /* Return text area width of FRAME in pixels. */)
2502 (Lisp_Object frame)
2503{
2504 return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame)));
2505}
2506
2507DEFUN ("frame-text-height", Fframe_text_height, Sframe_text_height, 0, 1, 0,
2508 doc: /* Return text area height of FRAME in pixels. */)
2509 (Lisp_Object frame)
2510{
2511 return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame)));
2512}
2513
2514DEFUN ("frame-scroll-bar-width", Fscroll_bar_width, Sscroll_bar_width, 0, 1, 0,
2515 doc: /* Return scroll bar width of FRAME in pixels. */)
2516 (Lisp_Object frame)
2517{
2518 return make_number (decode_any_frame (frame)->scroll_bar_actual_width);
2519}
2520
2521DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
2522 doc: /* Return fringe width of FRAME in pixels. */)
2523 (Lisp_Object frame)
2524{
2525 return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
2526}
2527
2528DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0,
2529 doc: /* Return border width of FRAME in pixels. */)
2530 (Lisp_Object frame)
2531{
2532 return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
2533}
2534
2535DEFUN ("frame-right-divider-width", Fright_divider_width, Sright_divider_width, 0, 1, 0,
2536 doc: /* Return width (in pixels) of vertical window dividers on FRAME. */)
2537 (Lisp_Object frame)
2538{
2539 return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame)));
2540}
2541
2542DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_width, 0, 1, 0,
2543 doc: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
2544 (Lisp_Object frame)
2545{
2546 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame)));
2547}
2457 2548
2458DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0, 2549DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, 0,
2459 doc: /* Specify that the frame FRAME has LINES lines. 2550 doc: /* Specify that the frame FRAME has HEIGHT text lines.
2460If FRAME is nil, the selected frame is used. Optional third arg 2551Optional third arg PRETEND non-nil means that redisplay should use
2461non-nil means that redisplay should use LINES lines but that the 2552HEIGHT lines but that the idea of the actual height of the frame should
2462idea of the actual height of the frame should not be changed. */) 2553not be changed. Optional fourth argument PIXELWISE non-nil means that
2463 (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend) 2554FRAME should be HEIGHT pixels high. */)
2555 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
2464{ 2556{
2465 register struct frame *f = decode_live_frame (frame); 2557 register struct frame *f = decode_live_frame (frame);
2466 2558
2467 CHECK_TYPE_RANGED_INTEGER (int, lines); 2559 CHECK_TYPE_RANGED_INTEGER (int, height);
2468 2560
2469 /* I think this should be done with a hook. */ 2561 /* I think this should be done with a hook. */
2470#ifdef HAVE_WINDOW_SYSTEM 2562#ifdef HAVE_WINDOW_SYSTEM
2471 if (FRAME_WINDOW_P (f)) 2563 if (FRAME_WINDOW_P (f))
2472 { 2564 {
2473 if (XINT (lines) != FRAME_LINES (f)) 2565 if (NILP (pixelwise))
2474 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines)); 2566 {
2475 do_pending_window_change (0); 2567 if (XINT (height) != FRAME_LINES (f))
2568 x_set_window_size (f, 1, FRAME_COLS (f), XINT (height), 0);
2569
2570 do_pending_window_change (0);
2571 }
2572 else if (XINT (height) != FRAME_TEXT_HEIGHT (f))
2573 {
2574 x_set_window_size (f, 1, FRAME_TEXT_WIDTH (f), XINT (height), 1);
2575 do_pending_window_change (0);
2576 }
2476 } 2577 }
2477 else 2578 else
2478#endif 2579#endif
2479 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0); 2580 change_frame_size (f, 0, XINT (height), !NILP (pretend), 0, 0,
2581 NILP (pixelwise) ? 0 : 1);
2480 return Qnil; 2582 return Qnil;
2481} 2583}
2482 2584
2483DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0, 2585DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4, 0,
2484 doc: /* Specify that the frame FRAME has COLS columns. 2586 doc: /* Specify that the frame FRAME has WIDTH columns.
2485If FRAME is nil, the selected frame is used. Optional third arg 2587Optional third arg PRETEND non-nil means that redisplay should use WIDTH
2486non-nil means that redisplay should use COLS columns but that the 2588columns but that the idea of the actual width of the frame should not
2487idea of the actual width of the frame should not be changed. */) 2589be changed. Optional fourth argument PIXELWISE non-nil means that FRAME
2488 (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend) 2590should be WIDTH pixels wide. */)
2591 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
2489{ 2592{
2490 register struct frame *f = decode_live_frame (frame); 2593 register struct frame *f = decode_live_frame (frame);
2491 2594
2492 CHECK_TYPE_RANGED_INTEGER (int, cols); 2595 CHECK_TYPE_RANGED_INTEGER (int, width);
2493 2596
2494 /* I think this should be done with a hook. */ 2597 /* I think this should be done with a hook. */
2495#ifdef HAVE_WINDOW_SYSTEM 2598#ifdef HAVE_WINDOW_SYSTEM
2496 if (FRAME_WINDOW_P (f)) 2599 if (FRAME_WINDOW_P (f))
2497 { 2600 {
2498 if (XINT (cols) != FRAME_COLS (f)) 2601 if (NILP (pixelwise))
2499 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f)); 2602 {
2500 do_pending_window_change (0); 2603 if (XINT (width) != FRAME_COLS (f))
2604 x_set_window_size (f, 1, XINT (width), FRAME_LINES (f), 0);
2605
2606 do_pending_window_change (0);
2607 }
2608 else if (XINT (width) != FRAME_TEXT_WIDTH (f))
2609 {
2610 x_set_window_size (f, 1, XINT (width), FRAME_TEXT_HEIGHT (f), 1);
2611 do_pending_window_change (0);
2612 }
2501 } 2613 }
2502 else 2614 else
2503#endif 2615#endif
2504 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0); 2616 change_frame_size (f, XINT (width), 0, !NILP (pretend), 0, 0,
2617 NILP (pixelwise) ? 0 : 1);
2505 return Qnil; 2618 return Qnil;
2506} 2619}
2507 2620
2508DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, 2621DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 4, 0,
2509 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. 2622 doc: /* Sets size of FRAME to WIDTH by HEIGHT, measured in characters.
2510If FRAME is nil, the selected frame is used. */) 2623Optional argument PIXELWISE non-nil means to measure in pixels. */)
2511 (Lisp_Object frame, Lisp_Object cols, Lisp_Object rows) 2624 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
2512{ 2625{
2513 register struct frame *f = decode_live_frame (frame); 2626 register struct frame *f = decode_live_frame (frame);
2514 2627
2515 CHECK_TYPE_RANGED_INTEGER (int, cols); 2628 CHECK_TYPE_RANGED_INTEGER (int, width);
2516 CHECK_TYPE_RANGED_INTEGER (int, rows); 2629 CHECK_TYPE_RANGED_INTEGER (int, height);
2517 2630
2518 /* I think this should be done with a hook. */ 2631 /* I think this should be done with a hook. */
2519#ifdef HAVE_WINDOW_SYSTEM 2632#ifdef HAVE_WINDOW_SYSTEM
2520 if (FRAME_WINDOW_P (f)) 2633 if (FRAME_WINDOW_P (f))
2521 { 2634 {
2522 if (XINT (rows) != FRAME_LINES (f) 2635 if (!NILP (pixelwise)
2523 || XINT (cols) != FRAME_COLS (f) 2636 ? (XINT (width) != FRAME_TEXT_WIDTH (f)
2524 || f->new_text_lines || f->new_text_cols) 2637 || XINT (height) != FRAME_TEXT_HEIGHT (f)
2525 x_set_window_size (f, 1, XINT (cols), XINT (rows)); 2638 || f->new_height || f->new_width)
2526 do_pending_window_change (0); 2639 : (XINT (width) != FRAME_COLS (f)
2640 || XINT (height) != FRAME_LINES (f)
2641 || f->new_height || f->new_width))
2642 {
2643 x_set_window_size (f, 1, XINT (width), XINT (height),
2644 NILP (pixelwise) ? 0 : 1);
2645 do_pending_window_change (0);
2646 }
2527 } 2647 }
2528 else 2648 else
2529#endif 2649#endif
2530 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0); 2650 change_frame_size (f, XINT (width), XINT (height), 0, 0, 0,
2651 NILP (pixelwise) ? 0 : 1);
2531 2652
2532 return Qnil; 2653 return Qnil;
2533} 2654}
@@ -2586,6 +2707,8 @@ static const struct frame_parm_table frame_parms[] =
2586 {"icon-name", &Qicon_name}, 2707 {"icon-name", &Qicon_name},
2587 {"icon-type", &Qicon_type}, 2708 {"icon-type", &Qicon_type},
2588 {"internal-border-width", &Qinternal_border_width}, 2709 {"internal-border-width", &Qinternal_border_width},
2710 {"right-divider-width", &Qright_divider_width},
2711 {"bottom-divider-width", &Qbottom_divider_width},
2589 {"menu-bar-lines", &Qmenu_bar_lines}, 2712 {"menu-bar-lines", &Qmenu_bar_lines},
2590 {"mouse-color", &Qmouse_color}, 2713 {"mouse-color", &Qmouse_color},
2591 {"name", &Qname}, 2714 {"name", &Qname},
@@ -2720,8 +2843,16 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
2720 icon_left = icon_top = Qunbound; 2843 icon_left = icon_top = Qunbound;
2721 2844
2722 /* Provide default values for HEIGHT and WIDTH. */ 2845 /* Provide default values for HEIGHT and WIDTH. */
2723 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f)); 2846 width = (f->new_width
2724 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f)); 2847 ? (f->new_pixelwise
2848 ? (f->new_width / FRAME_COLUMN_WIDTH (f))
2849 : f->new_width)
2850 : FRAME_COLS (f));
2851 height = (f->new_height
2852 ? (f->new_pixelwise
2853 ? (f->new_height / FRAME_LINE_HEIGHT (f))
2854 : f->new_height)
2855 : FRAME_LINES (f));
2725 2856
2726 /* Process foreground_color and background_color before anything else. 2857 /* Process foreground_color and background_color before anything else.
2727 They are independent of other properties, but other properties (e.g., 2858 They are independent of other properties, but other properties (e.g.,
@@ -2847,15 +2978,16 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
2847 { 2978 {
2848 Lisp_Object frame; 2979 Lisp_Object frame;
2849 2980
2850 check_frame_size (f, &height, &width); 2981 /* Make this 1, eventually. */
2982 check_frame_size (f, &width, &height, 0);
2851 2983
2852 XSETFRAME (frame, f); 2984 XSETFRAME (frame, f);
2853 2985
2854 if (size_changed 2986 if (size_changed
2855 && (width != FRAME_COLS (f) 2987 && (width != FRAME_COLS (f)
2856 || height != FRAME_LINES (f) 2988 || height != FRAME_LINES (f)
2857 || f->new_text_lines || f->new_text_cols)) 2989 || f->new_height || f->new_width))
2858 Fset_frame_size (frame, make_number (width), make_number (height)); 2990 Fset_frame_size (frame, make_number (width), make_number (height), Qnil);
2859 2991
2860 if ((!NILP (left) || !NILP (top)) 2992 if ((!NILP (left) || !NILP (top))
2861 && ! (left_no_change && top_no_change) 2993 && ! (left_no_change && top_no_change)
@@ -2963,6 +3095,10 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
2963 make_number (f->border_width)); 3095 make_number (f->border_width));
2964 store_in_alist (alistptr, Qinternal_border_width, 3096 store_in_alist (alistptr, Qinternal_border_width,
2965 make_number (FRAME_INTERNAL_BORDER_WIDTH (f))); 3097 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
3098 store_in_alist (alistptr, Qright_divider_width,
3099 make_number (FRAME_RIGHT_DIVIDER_WIDTH (f)));
3100 store_in_alist (alistptr, Qbottom_divider_width,
3101 make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f)));
2966 store_in_alist (alistptr, Qleft_fringe, 3102 store_in_alist (alistptr, Qleft_fringe,
2967 make_number (FRAME_LEFT_FRINGE_WIDTH (f))); 3103 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
2968 store_in_alist (alistptr, Qright_fringe, 3104 store_in_alist (alistptr, Qright_fringe,
@@ -3295,7 +3431,53 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
3295 3431
3296 if (FRAME_X_WINDOW (f) != 0) 3432 if (FRAME_X_WINDOW (f) != 0)
3297 { 3433 {
3298 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3434 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
3435 SET_FRAME_GARBAGED (f);
3436 do_pending_window_change (0);
3437 }
3438 else
3439 SET_FRAME_GARBAGED (f);
3440}
3441
3442void
3443x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3444{
3445 int old = FRAME_RIGHT_DIVIDER_WIDTH (f);
3446
3447 CHECK_TYPE_RANGED_INTEGER (int, arg);
3448 FRAME_RIGHT_DIVIDER_WIDTH (f) = XINT (arg);
3449 if (FRAME_RIGHT_DIVIDER_WIDTH (f) < 0)
3450 FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
3451
3452 if (FRAME_RIGHT_DIVIDER_WIDTH (f) == old)
3453 return;
3454
3455 if (FRAME_X_WINDOW (f) != 0)
3456 {
3457 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
3458 SET_FRAME_GARBAGED (f);
3459 do_pending_window_change (0);
3460 }
3461 else
3462 SET_FRAME_GARBAGED (f);
3463}
3464
3465void
3466x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3467{
3468 int old = FRAME_BOTTOM_DIVIDER_WIDTH (f);
3469
3470 CHECK_TYPE_RANGED_INTEGER (int, arg);
3471 FRAME_BOTTOM_DIVIDER_WIDTH (f) = XINT (arg);
3472 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) < 0)
3473 FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
3474
3475 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) == old)
3476 return;
3477
3478 if (FRAME_X_WINDOW (f) != 0)
3479 {
3480 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
3299 SET_FRAME_GARBAGED (f); 3481 SET_FRAME_GARBAGED (f);
3300 do_pending_window_change (0); 3482 do_pending_window_change (0);
3301 } 3483 }
@@ -3361,7 +3543,8 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3361 However, if the window hasn't been created yet, we shouldn't 3543 However, if the window hasn't been created yet, we shouldn't
3362 call x_set_window_size. */ 3544 call x_set_window_size. */
3363 if (FRAME_X_WINDOW (f)) 3545 if (FRAME_X_WINDOW (f))
3364 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3546 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
3547 FRAME_TEXT_HEIGHT (f), 1);
3365 do_pending_window_change (0); 3548 do_pending_window_change (0);
3366 } 3549 }
3367} 3550}
@@ -3369,27 +3552,29 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3369void 3552void
3370x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 3553x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3371{ 3554{
3372 int wid = FRAME_COLUMN_WIDTH (f); 3555 int unit = FRAME_COLUMN_WIDTH (f);
3373 3556
3374 if (NILP (arg)) 3557 if (NILP (arg))
3375 { 3558 {
3376 x_set_scroll_bar_default_width (f); 3559 x_set_scroll_bar_default_width (f);
3377 3560
3378 if (FRAME_X_WINDOW (f)) 3561 if (FRAME_X_WINDOW (f))
3379 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3562 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
3563 FRAME_TEXT_HEIGHT (f), 1);
3380 do_pending_window_change (0); 3564 do_pending_window_change (0);
3381 } 3565 }
3382 else if (RANGED_INTEGERP (1, arg, INT_MAX) 3566 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3383 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) 3567 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3384 { 3568 {
3385 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); 3569 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3386 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid; 3570 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
3387 if (FRAME_X_WINDOW (f)) 3571 if (FRAME_X_WINDOW (f))
3388 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 3572 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
3573 FRAME_TEXT_HEIGHT (f), 1);
3389 do_pending_window_change (0); 3574 do_pending_window_change (0);
3390 } 3575 }
3391 3576
3392 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0); 3577 change_frame_size (f, 0, 0, 0, 0, 0, 1);
3393 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0; 3578 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3394 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0; 3579 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3395} 3580}
@@ -4002,17 +4187,20 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4002 /* Default values if we fall through. 4187 /* Default values if we fall through.
4003 Actually, if that happens we should get 4188 Actually, if that happens we should get
4004 window manager prompting. */ 4189 window manager prompting. */
4190 SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
4005 SET_FRAME_COLS (f, DEFAULT_COLS); 4191 SET_FRAME_COLS (f, DEFAULT_COLS);
4192 SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
4006 FRAME_LINES (f) = DEFAULT_ROWS; 4193 FRAME_LINES (f) = DEFAULT_ROWS;
4194
4007 /* Window managers expect that if program-specified 4195 /* Window managers expect that if program-specified
4008 positions are not (0,0), they're intentional, not defaults. */ 4196 positions are not (0,0), they're intentional, not defaults. */
4009 f->top_pos = 0; 4197 f->top_pos = 0;
4010 f->left_pos = 0; 4198 f->left_pos = 0;
4011 4199
4012 /* Ensure that old new_text_cols and new_text_lines will not override the 4200 /* Ensure that old new_width and new_height will not override the
4013 values set here. */ 4201 values set here. */
4014 /* ++KFS: This was specific to W32, but seems ok for all platforms */ 4202 /* ++KFS: This was specific to W32, but seems ok for all platforms */
4015 f->new_text_cols = f->new_text_lines = 0; 4203 f->new_width = f->new_height = f->new_pixelwise = 0;
4016 4204
4017 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER); 4205 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4018 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER); 4206 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
@@ -4053,7 +4241,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4053 change the frame size. This is done so that users can create 4241 change the frame size. This is done so that users can create
4054 tall Emacs frames without having to guess how tall the tool-bar 4242 tall Emacs frames without having to guess how tall the tool-bar
4055 will get. */ 4243 will get. */
4056 if (toolbar_p && FRAME_TOOL_BAR_LINES (f)) 4244 if (toolbar_p && FRAME_TOOL_BAR_HEIGHT (f))
4057 { 4245 {
4058 int margin, relief, bar_height; 4246 int margin, relief, bar_height;
4059 4247
@@ -4069,14 +4257,15 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4069 else 4257 else
4070 margin = 0; 4258 margin = 0;
4071 4259
4260 /* PXW: We should be able to not round here. */
4072 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; 4261 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4073 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f); 4262 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
4074 } 4263 }
4075 4264
4076 compute_fringe_widths (f, 0); 4265 compute_fringe_widths (f, 0);
4077 4266
4078 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f)); 4267 SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
4079 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f)); 4268 SET_FRAME_HEIGHT(f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
4080 4269
4081 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER); 4270 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4082 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER); 4271 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
@@ -4465,6 +4654,16 @@ when the mouse is over clickable text. */);
4465The pointer becomes visible again when the mouse is moved. */); 4654The pointer becomes visible again when the mouse is moved. */);
4466 Vmake_pointer_invisible = Qt; 4655 Vmake_pointer_invisible = Qt;
4467 4656
4657 DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook,
4658 doc: /* Normal hook run when a frame gains input focus. */);
4659 Vfocus_in_hook = Qnil;
4660 DEFSYM (Qfocus_in_hook, "focus-in-hook");
4661
4662 DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook,
4663 doc: /* Normal hook run when a frame loses input focus. */);
4664 Vfocus_out_hook = Qnil;
4665 DEFSYM (Qfocus_out_hook, "focus-out-hook");
4666
4468 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions, 4667 DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
4469 doc: /* Functions run before deleting a frame. 4668 doc: /* Functions run before deleting a frame.
4470The functions are run with one arg, the frame to be deleted. 4669The functions are run with one arg, the frame to be deleted.
@@ -4519,6 +4718,12 @@ handles focus, since there is no way in general for Emacs to find out
4519automatically. See also `mouse-autoselect-window'. */); 4718automatically. See also `mouse-autoselect-window'. */);
4520 focus_follows_mouse = 0; 4719 focus_follows_mouse = 0;
4521 4720
4721 DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise,
4722 doc: /* Non-nil means frames are resized pixelwise.
4723If this is nil, resizing a frame will round sizes to the frame's
4724current values of `frame-char-height' and `frame-char-width'. */);
4725 frame_resize_pixelwise = 0;
4726
4522 staticpro (&Vframe_list); 4727 staticpro (&Vframe_list);
4523 4728
4524 defsubr (&Sframep); 4729 defsubr (&Sframep);
@@ -4526,8 +4731,6 @@ automatically. See also `mouse-autoselect-window'. */);
4526 defsubr (&Swindow_system); 4731 defsubr (&Swindow_system);
4527 defsubr (&Smake_terminal_frame); 4732 defsubr (&Smake_terminal_frame);
4528 defsubr (&Shandle_switch_frame); 4733 defsubr (&Shandle_switch_frame);
4529 defsubr (&Shandle_focus_in);
4530 defsubr (&Shandle_focus_out);
4531 defsubr (&Sselect_frame); 4734 defsubr (&Sselect_frame);
4532 defsubr (&Sselected_frame); 4735 defsubr (&Sselected_frame);
4533 defsubr (&Sframe_list); 4736 defsubr (&Sframe_list);
@@ -4560,6 +4763,16 @@ automatically. See also `mouse-autoselect-window'. */);
4560 defsubr (&Sframe_char_width); 4763 defsubr (&Sframe_char_width);
4561 defsubr (&Sframe_pixel_height); 4764 defsubr (&Sframe_pixel_height);
4562 defsubr (&Sframe_pixel_width); 4765 defsubr (&Sframe_pixel_width);
4766 defsubr (&Sframe_text_cols);
4767 defsubr (&Sframe_text_lines);
4768 defsubr (&Sframe_total_cols);
4769 defsubr (&Sframe_text_width);
4770 defsubr (&Sframe_text_height);
4771 defsubr (&Sscroll_bar_width);
4772 defsubr (&Sfringe_width);
4773 defsubr (&Sborder_width);
4774 defsubr (&Sright_divider_width);
4775 defsubr (&Sbottom_divider_width);
4563 defsubr (&Stool_bar_pixel_width); 4776 defsubr (&Stool_bar_pixel_width);
4564 defsubr (&Sset_frame_height); 4777 defsubr (&Sset_frame_height);
4565 defsubr (&Sset_frame_width); 4778 defsubr (&Sset_frame_width);
diff --git a/src/frame.h b/src/frame.h
index 8dfcaae114b..8369cf6b17e 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -214,45 +214,64 @@ struct frame
214 /* Nonzero means that cursor type has been changed. */ 214 /* Nonzero means that cursor type has been changed. */
215 unsigned cursor_type_changed : 1; 215 unsigned cursor_type_changed : 1;
216 216
217 /* True if it needs to be redisplayed. */
218 unsigned redisplay : 1;
219
217 /* Margin at the top of the frame. Used to display the tool-bar. */ 220 /* Margin at the top of the frame. Used to display the tool-bar. */
218 int tool_bar_lines; 221 int tool_bar_lines;
219 222
223 /* Pixel height of tool bar. */
224 int tool_bar_height;
225
220 int n_tool_bar_rows; 226 int n_tool_bar_rows;
221 int n_tool_bar_items; 227 int n_tool_bar_items;
222 228
223 /* A buffer for decode_mode_line. */ 229 /* A buffer for decode_mode_line. */
224 char *decode_mode_spec_buffer; 230 char *decode_mode_spec_buffer;
225 231
226 /* See do_line_insertion_deletion_costs for info on these arrays. */ 232 /* See do_line_insertion_deletion_costs for info on these arrays. */
227 /* Cost of inserting 1 line on this frame */ 233 /* Cost of inserting 1 line on this frame. */
228 int *insert_line_cost; 234 int *insert_line_cost;
229 /* Cost of deleting 1 line on this frame */ 235 /* Cost of deleting 1 line on this frame. */
230 int *delete_line_cost; 236 int *delete_line_cost;
231 /* Cost of inserting n lines on this frame */ 237 /* Cost of inserting n lines on this frame. */
232 int *insert_n_lines_cost; 238 int *insert_n_lines_cost;
233 /* Cost of deleting n lines on this frame */ 239 /* Cost of deleting n lines on this frame. */
234 int *delete_n_lines_cost; 240 int *delete_n_lines_cost;
235 241
236 /* Size of this frame, excluding fringes, scroll bars etc., 242 /* Text width of this frame (excluding fringes, scroll bars and
237 in units of canonical characters. */ 243 internal border width) and text height (excluding internal border
238 int text_lines, text_cols; 244 width) in units of canonical characters. */
245 int text_cols, text_lines;
246
247 /* Total width of this frame (including fringes and scroll bars) in
248 units of canonical characters. */
249 int total_cols;
250
251 /* Text width of this frame (excluding fringes, scroll bars and
252 internal border width) and text height (excluding internal border
253 width) in pixels. */
254 int text_width, text_height;
239 255
240 /* Total size of this frame (i.e. its native window), in units of 256 /* New text height and width for pending size change. 0 if no change
241 canonical characters. */ 257 pending. These values represent pixels or canonical character units
242 int total_lines, total_cols; 258 according to the value of new_pixelwise and correlate to the the
259 text width/height of the frame. */
260 int new_width, new_height;
243 261
244 /* New text height and width for pending size change. 262 /* Whether new_height and new_width shall be interpreted
245 0 if no change pending. */ 263 in pixels. */
246 int new_text_lines, new_text_cols; 264 bool new_pixelwise;
247 265
248 /* Pixel position of the frame window (x and y offsets in root window). */ 266 /* Pixel position of the frame window (x and y offsets in root window). */
249 int left_pos, top_pos; 267 int left_pos, top_pos;
250 268
251 /* Size of the frame window in pixels. */ 269 /* Size of the frame window (including internal border widths) in
252 int pixel_height, pixel_width; 270 pixels. */
271 int pixel_width, pixel_height;
253 272
254 /* These many pixels are the difference between the outer window (i.e. the 273 /* These many pixels are the difference between the outer window (i.e. the
255 left and top of the window manager decoration) and FRAME_X_WINDOW. */ 274 left and top of the window manager decoration) and FRAME_X_WINDOW. */
256 int x_pixels_diff, y_pixels_diff; 275 int x_pixels_diff, y_pixels_diff;
257 276
258 /* This is the gravity value for the specified window position. */ 277 /* This is the gravity value for the specified window position. */
@@ -269,6 +288,10 @@ struct frame
269 a highlighting is displayed inside the internal border. */ 288 a highlighting is displayed inside the internal border. */
270 int internal_border_width; 289 int internal_border_width;
271 290
291 /* Width of borders between this frame's windows. */
292 int right_divider_width;
293 int bottom_divider_width;
294
272 /* Canonical X unit. Width of default font, in pixels. */ 295 /* Canonical X unit. Width of default font, in pixels. */
273 int column_width; 296 int column_width;
274 297
@@ -281,23 +304,23 @@ struct frame
281 enum output_method output_method; 304 enum output_method output_method;
282 305
283 /* The terminal device that this frame uses. If this is NULL, then 306 /* The terminal device that this frame uses. If this is NULL, then
284 the frame has been deleted. */ 307 the frame has been deleted. */
285 struct terminal *terminal; 308 struct terminal *terminal;
286 309
287 /* Device-dependent, frame-local auxiliary data used for displaying 310 /* Device-dependent, frame-local auxiliary data used for displaying
288 the contents. When the frame is deleted, this data is deleted as 311 the contents. When the frame is deleted, this data is deleted as
289 well. */ 312 well. */
290 union output_data 313 union output_data
291 { 314 {
292 struct tty_output *tty; /* termchar.h */ 315 struct tty_output *tty; /* From termchar.h. */
293 struct x_output *x; /* xterm.h */ 316 struct x_output *x; /* From xterm.h. */
294 struct w32_output *w32; /* w32term.h */ 317 struct w32_output *w32; /* From w32term.h. */
295 struct ns_output *ns; /* nsterm.h */ 318 struct ns_output *ns; /* From nsterm.h. */
296 intptr_t nothing; 319 intptr_t nothing;
297 } 320 }
298 output_data; 321 output_data;
299 322
300 /* List of font-drivers available on the frame. */ 323 /* List of font-drivers available on the frame. */
301 struct font_driver_list *font_driver_list; 324 struct font_driver_list *font_driver_list;
302 /* List of data specific to font-driver and frame, but common to 325 /* List of data specific to font-driver and frame, but common to
303 faces. */ 326 faces. */
@@ -313,39 +336,38 @@ struct frame
313 /* The extra width (in pixels) currently allotted for fringes. */ 336 /* The extra width (in pixels) currently allotted for fringes. */
314 int left_fringe_width, right_fringe_width; 337 int left_fringe_width, right_fringe_width;
315 338
316 /* See FULLSCREEN_ enum below */ 339 /* See FULLSCREEN_ enum below. */
317 enum fullscreen_type want_fullscreen; 340 enum fullscreen_type want_fullscreen;
318 341
319 /* Number of lines of menu bar. */ 342 /* Number of lines of menu bar. */
320 int menu_bar_lines; 343 int menu_bar_lines;
321 344
322#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \ 345 /* Pixel height of menubar. */
323 || defined (HAVE_NS) || defined (USE_GTK) 346 int menu_bar_height;
324 /* Nonzero means using a menu bar that comes from the X toolkit. */
325 unsigned int external_menu_bar : 1;
326#endif
327 347
328#if defined (HAVE_X_WINDOWS) 348#if defined (HAVE_X_WINDOWS)
329 /* Used by x_wait_for_event when watching for an X event on this frame. */ 349 /* Used by x_wait_for_event when watching for an X event on this frame. */
330 int wait_event_type; 350 int wait_event_type;
331#endif 351#endif
332 352
353#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
354 || defined (HAVE_NS) || defined (USE_GTK)
355 /* Nonzero means using a menu bar that comes from the X toolkit. */
356 unsigned external_menu_bar : 1;
357#endif
358
333 /* Next two bitfields are mutually exclusive. They might both be 359 /* Next two bitfields are mutually exclusive. They might both be
334 zero if the frame has been made invisible without an icon. */ 360 zero if the frame has been made invisible without an icon. */
335 361
336 /* Nonzero if the frame is currently displayed; we check 362 /* Nonzero if the frame is currently displayed; we check
337 it to see if we should bother updating the frame's contents. 363 it to see if we should bother updating the frame's contents.
338 364
339 Note that, since invisible frames aren't updated, whenever a
340 frame becomes visible again, it must be marked as garbaged.
341
342 On ttys and on Windows NT/9X, to avoid wasting effort updating 365 On ttys and on Windows NT/9X, to avoid wasting effort updating
343 visible frames that are actually completely obscured by other 366 visible frames that are actually completely obscured by other
344 windows on the display, we bend the meaning of visible slightly: 367 windows on the display, we bend the meaning of visible slightly:
345 if equal to 2, then the frame is obscured - we still consider 368 if equal to 2, then the frame is obscured - we still consider
346 it to be "visible" as seen from lisp, but we don't bother 369 it to be "visible" as seen from lisp, but we don't bother
347 updating it. We must take care to garbage the frame when it 370 updating it. */
348 ceases to be obscured though. See SET_FRAME_VISIBLE below. */
349 unsigned visible : 2; 371 unsigned visible : 2;
350 372
351 /* Nonzero if the frame is currently iconified. Do not 373 /* Nonzero if the frame is currently iconified. Do not
@@ -379,10 +401,10 @@ struct frame
379 401
380 /* Nonzero if the mouse has moved on this display device 402 /* Nonzero if the mouse has moved on this display device
381 since the last time we checked. */ 403 since the last time we checked. */
382 unsigned mouse_moved :1; 404 unsigned mouse_moved : 1;
383 405
384 /* Nonzero means that the pointer is invisible. */ 406 /* Nonzero means that the pointer is invisible. */
385 unsigned pointer_invisible :1; 407 unsigned pointer_invisible : 1;
386 408
387 /* Nonzero means that all windows except mini-window and 409 /* Nonzero means that all windows except mini-window and
388 selected window on this frame have frozen window starts. */ 410 selected window on this frame have frozen window starts. */
@@ -659,20 +681,28 @@ default_pixels_per_inch_y (void)
659 (WINDOWP (f->minibuffer_window) \ 681 (WINDOWP (f->minibuffer_window) \
660 && XFRAME (XWINDOW (f->minibuffer_window)->frame) == f) 682 && XFRAME (XWINDOW (f->minibuffer_window)->frame) == f)
661 683
684/* Pixel width of frame F. */
685#define FRAME_PIXEL_WIDTH(f) ((f)->pixel_width)
686
662/* Pixel height of frame F, including non-toolkit menu bar and 687/* Pixel height of frame F, including non-toolkit menu bar and
663 non-toolkit tool bar lines. */ 688 non-toolkit tool bar lines. */
664#define FRAME_PIXEL_HEIGHT(f) ((f)->pixel_height) 689#define FRAME_PIXEL_HEIGHT(f) ((f)->pixel_height)
665 690
666/* Pixel width of frame F. */ 691/* Width of frame F, measured in canonical character columns,
667#define FRAME_PIXEL_WIDTH(f) ((f)->pixel_width) 692 not including scroll bars if any. */
693#define FRAME_COLS(f) (f)->text_cols
668 694
669/* Height of frame F, measured in canonical lines, including 695/* Height of frame F, measured in canonical lines, including
670 non-toolkit menu bar and non-toolkit tool bar lines. */ 696 non-toolkit menu bar and non-toolkit tool bar lines. */
671#define FRAME_LINES(f) (f)->text_lines 697#define FRAME_LINES(f) (f)->text_lines
672 698
673/* Width of frame F, measured in canonical character columns, 699/* Width of frame F, measured in pixels not including the width for
674 not including scroll bars if any. */ 700 fringes, scroll bar, and internal borders. */
675#define FRAME_COLS(f) (f)->text_cols 701#define FRAME_TEXT_WIDTH(f) (f)->text_width
702
703/* Height of frame F, measured in pixels not including the height
704 for internal borders. */
705#define FRAME_TEXT_HEIGHT(f) (f)->text_height
676 706
677/* Number of lines of frame F used for menu bar. 707/* Number of lines of frame F used for menu bar.
678 This is relevant on terminal frames and on 708 This is relevant on terminal frames and on
@@ -680,6 +710,9 @@ default_pixels_per_inch_y (void)
680 These lines are counted in FRAME_LINES. */ 710 These lines are counted in FRAME_LINES. */
681#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines 711#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
682 712
713/* Pixel height of frame F's menu bar. */
714#define FRAME_MENU_BAR_HEIGHT(f) (f)->menu_bar_height
715
683/* Nonzero if this frame should display a tool bar 716/* Nonzero if this frame should display a tool bar
684 in a way that does not use any text lines. */ 717 in a way that does not use any text lines. */
685#if defined (USE_GTK) || defined (HAVE_NS) 718#if defined (USE_GTK) || defined (HAVE_NS)
@@ -689,19 +722,18 @@ default_pixels_per_inch_y (void)
689#endif 722#endif
690 723
691/* Number of lines of frame F used for the tool-bar. */ 724/* Number of lines of frame F used for the tool-bar. */
692
693#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines 725#define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines
694 726
727/* Pixel height of frame F's tool-bar. */
728#define FRAME_TOOL_BAR_HEIGHT(f) (f)->tool_bar_height
695 729
696/* Lines above the top-most window in frame F. */ 730/* Lines above the top-most window in frame F. */
697
698#define FRAME_TOP_MARGIN(F) \ 731#define FRAME_TOP_MARGIN(F) \
699 (FRAME_MENU_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F)) 732 (FRAME_MENU_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F))
700 733
701/* Pixel height of the top margin above. */ 734/* Pixel height of frame F's top margin. */
702 735#define FRAME_TOP_MARGIN_HEIGHT(F) \
703#define FRAME_TOP_MARGIN_HEIGHT(f) \ 736 (FRAME_MENU_BAR_HEIGHT (F) + FRAME_TOOL_BAR_HEIGHT (F))
704 (FRAME_TOP_MARGIN (f) * FRAME_LINE_HEIGHT (f))
705 737
706/* Nonzero if this frame should display a menu bar 738/* Nonzero if this frame should display a menu bar
707 in a way that does not use any text lines. */ 739 in a way that does not use any text lines. */
@@ -720,7 +752,8 @@ default_pixels_per_inch_y (void)
720#define FRAME_ICONIFIED_P(f) (f)->iconified 752#define FRAME_ICONIFIED_P(f) (f)->iconified
721 753
722/* Mark frame F as currently garbaged. */ 754/* Mark frame F as currently garbaged. */
723#define SET_FRAME_GARBAGED(f) (frame_garbaged = 1, f->garbaged = 1) 755#define SET_FRAME_GARBAGED(f) \
756 (frame_garbaged = true, fset_redisplay (f), f->garbaged = true)
724 757
725/* Nonzero if frame F is currently garbaged. */ 758/* Nonzero if frame F is currently garbaged. */
726#define FRAME_GARBAGED_P(f) (f)->garbaged 759#define FRAME_GARBAGED_P(f) (f)->garbaged
@@ -788,7 +821,7 @@ default_pixels_per_inch_y (void)
788 821
789#define FRAME_LEFT_SCROLL_BAR_AREA_WIDTH(f) \ 822#define FRAME_LEFT_SCROLL_BAR_AREA_WIDTH(f) \
790 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \ 823 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \
791 ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \ 824 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
792 : 0) 825 : 0)
793 826
794/* Width of a scroll bar in frame F, measured in columns (characters), 827/* Width of a scroll bar in frame F, measured in columns (characters),
@@ -804,7 +837,7 @@ default_pixels_per_inch_y (void)
804 837
805#define FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH(f) \ 838#define FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH(f) \
806 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \ 839 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \
807 ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \ 840 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
808 : 0) 841 : 0)
809 842
810/* Actual width of a scroll bar in frame F, measured in columns. */ 843/* Actual width of a scroll bar in frame F, measured in columns. */
@@ -818,29 +851,36 @@ default_pixels_per_inch_y (void)
818 851
819#define FRAME_SCROLL_BAR_AREA_WIDTH(f) \ 852#define FRAME_SCROLL_BAR_AREA_WIDTH(f) \
820 (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \ 853 (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
821 ? (FRAME_CONFIG_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f)) \ 854 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
822 : 0) 855 : 0)
823 856
824/* Total width of frame F, in columns (characters), 857/* Total width of frame F, in columns (characters),
825 including the width used by scroll bars if any. */ 858 including the width used by scroll bars if any. */
826
827#define FRAME_TOTAL_COLS(f) ((f)->total_cols) 859#define FRAME_TOTAL_COLS(f) ((f)->total_cols)
828 860
829/* Set the width of frame F to VAL. 861/* Set the character widths of frame F. WIDTH specifies a nominal
830 VAL is the width of a full-frame window, 862 character text width. */
831 not including scroll bars and fringes. */ 863#define SET_FRAME_COLS(f, width) \
832 864 ((f)->text_cols = (width), \
833#define SET_FRAME_COLS(f, val) \ 865 (f)->total_cols = ((width) \
834 (FRAME_COLS (f) = (val), \ 866 + FRAME_SCROLL_BAR_COLS (f) \
835 (f)->total_cols = FRAME_TOTAL_COLS_ARG (f, FRAME_COLS (f))) 867 + FRAME_FRINGE_COLS (f)))
836 868
837/* Given a value WIDTH for frame F's nominal width, 869/* Set the pixel widths of frame F. WIDTH specifies a nominal pixel
838 return the value that FRAME_TOTAL_COLS should have. */ 870 text width. */
839 871#define SET_FRAME_WIDTH(f, width) \
840#define FRAME_TOTAL_COLS_ARG(f, width) \ 872 ((f)->text_width = (width), \
841 ((width) \ 873 (f)->pixel_width = ((width) \
842 + FRAME_SCROLL_BAR_COLS (f) \ 874 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
843 + FRAME_FRINGE_COLS (f)) 875 + FRAME_TOTAL_FRINGE_WIDTH (f) \
876 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
877
878/* Set the pixel heights of frame F. HEIGHT specifies a nominal pixel
879 text width. */
880#define SET_FRAME_HEIGHT(f, height) \
881 ((f)->text_height = (height), \
882 (f)->pixel_height = ((height) \
883 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
844 884
845/* Maximum + 1 legitimate value for FRAME_CURSOR_X. */ 885/* Maximum + 1 legitimate value for FRAME_CURSOR_X. */
846 886
@@ -911,11 +951,14 @@ default_pixels_per_inch_y (void)
911 } \ 951 } \
912 } while (0) 952 } while (0)
913 953
914/* Set visibility of frame F, marking F as garbaged if needed. */ 954/* Set visibility of frame F.
955 We call redisplay_other_windows to make sure the frame gets redisplayed
956 if some changes were applied to it while it wasn't visible (and hence
957 wasn't redisplayed). */
915 958
916#define SET_FRAME_VISIBLE(f, v) \ 959#define SET_FRAME_VISIBLE(f, v) \
917 (((f)->visible == 0 || ((f)->visible == 2)) \ 960 (((f)->visible == 0 || ((f)->visible == 2)) && ((v) == 1) \
918 && ((v) == 1) ? SET_FRAME_GARBAGED (f) : 0, \ 961 ? redisplay_other_windows () : 0, \
919 (f)->visible = (eassert (0 <= (v) && (v) <= 2), (v))) 962 (f)->visible = (eassert (0 <= (v) && (v) <= 2), (v)))
920 963
921/* Set iconify of frame F. */ 964/* Set iconify of frame F. */
@@ -1001,11 +1044,13 @@ extern Lisp_Object Vframe_list;
1001#define FRAME_TOTAL_FRINGE_WIDTH(F) \ 1044#define FRAME_TOTAL_FRINGE_WIDTH(F) \
1002 (FRAME_LEFT_FRINGE_WIDTH (F) + FRAME_RIGHT_FRINGE_WIDTH (F)) 1045 (FRAME_LEFT_FRINGE_WIDTH (F) + FRAME_RIGHT_FRINGE_WIDTH (F))
1003 1046
1004
1005/* Pixel-width of internal border lines */ 1047/* Pixel-width of internal border lines */
1006
1007#define FRAME_INTERNAL_BORDER_WIDTH(F) ((F)->internal_border_width) 1048#define FRAME_INTERNAL_BORDER_WIDTH(F) ((F)->internal_border_width)
1008 1049
1050/* Pixel-size of window border lines */
1051#define FRAME_RIGHT_DIVIDER_WIDTH(F) ((F)->right_divider_width)
1052#define FRAME_BOTTOM_DIVIDER_WIDTH(F) ((F)->bottom_divider_width)
1053
1009#else /* not HAVE_WINDOW_SYSTEM */ 1054#else /* not HAVE_WINDOW_SYSTEM */
1010 1055
1011#define FRAME_FRINGE_COLS(F) 0 1056#define FRAME_FRINGE_COLS(F) 0
@@ -1013,11 +1058,10 @@ extern Lisp_Object Vframe_list;
1013#define FRAME_LEFT_FRINGE_WIDTH(F) 0 1058#define FRAME_LEFT_FRINGE_WIDTH(F) 0
1014#define FRAME_RIGHT_FRINGE_WIDTH(F) 0 1059#define FRAME_RIGHT_FRINGE_WIDTH(F) 0
1015#define FRAME_INTERNAL_BORDER_WIDTH(F) 0 1060#define FRAME_INTERNAL_BORDER_WIDTH(F) 0
1061#define FRAME_RIGHT_DIVIDER_WIDTH(F) 0
1062#define FRAME_BOTTOM_DIVIDER_WIDTH(F) 0
1016 1063
1017#endif /* not HAVE_WINDOW_SYSTEM */ 1064#endif /* not HAVE_WINDOW_SYSTEM */
1018
1019
1020
1021 1065
1022/*********************************************************************** 1066/***********************************************************************
1023 Conversion between canonical units and pixels 1067 Conversion between canonical units and pixels
@@ -1074,58 +1118,81 @@ extern Lisp_Object Vframe_list;
1074 Return the upper/left pixel position of the character cell on frame F 1118 Return the upper/left pixel position of the character cell on frame F
1075 at ROW/COL. */ 1119 at ROW/COL. */
1076 1120
1077#define FRAME_LINE_TO_PIXEL_Y(f, row) \ 1121#define FRAME_LINE_TO_PIXEL_Y(f, row) \
1078 (((row) < FRAME_TOP_MARGIN (f) ? 0 : FRAME_INTERNAL_BORDER_WIDTH (f)) \ 1122 (((row) < FRAME_TOP_MARGIN (f) ? 0 : FRAME_INTERNAL_BORDER_WIDTH (f)) \
1079 + (row) * FRAME_LINE_HEIGHT (f)) 1123 + (row) * FRAME_LINE_HEIGHT (f))
1080 1124
1081#define FRAME_COL_TO_PIXEL_X(f, col) \ 1125#define FRAME_COL_TO_PIXEL_X(f, col) \
1082 (FRAME_INTERNAL_BORDER_WIDTH (f) \ 1126 (FRAME_INTERNAL_BORDER_WIDTH (f) \
1083 + (col) * FRAME_COLUMN_WIDTH (f)) 1127 + (col) * FRAME_COLUMN_WIDTH (f))
1084 1128
1085/* Return the pixel width/height of frame F if it has 1129/* Return the pixel width/height of frame F if it has
1086 COLS columns/LINES rows. */ 1130 COLS columns/LINES rows. */
1087 1131
1088#define FRAME_TEXT_COLS_TO_PIXEL_WIDTH(f, cols) \ 1132#define FRAME_TEXT_COLS_TO_PIXEL_WIDTH(f, cols) \
1089 (FRAME_COL_TO_PIXEL_X (f, cols) \ 1133 (FRAME_COL_TO_PIXEL_X (f, cols) \
1090 + (f)->scroll_bar_actual_width \ 1134 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
1091 + FRAME_TOTAL_FRINGE_WIDTH (f) \ 1135 + FRAME_TOTAL_FRINGE_WIDTH (f) \
1092 + FRAME_INTERNAL_BORDER_WIDTH (f)) 1136 + FRAME_INTERNAL_BORDER_WIDTH (f))
1093 1137
1094#define FRAME_TEXT_LINES_TO_PIXEL_HEIGHT(f, lines) \ 1138#define FRAME_TEXT_LINES_TO_PIXEL_HEIGHT(f, lines) \
1095 ((lines) * FRAME_LINE_HEIGHT (f) \ 1139 ((lines) * FRAME_LINE_HEIGHT (f) \
1096 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1140 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1097 1141
1098
1099/* Return the row/column (zero-based) of the character cell containing 1142/* Return the row/column (zero-based) of the character cell containing
1100 the pixel on FRAME at Y/X. */ 1143 the pixel on FRAME at Y/X. */
1101 1144
1102#define FRAME_PIXEL_Y_TO_LINE(f, y) \ 1145#define FRAME_PIXEL_Y_TO_LINE(f, y) \
1103 (((y) < FRAME_TOP_MARGIN_HEIGHT (f) \ 1146 (((y) < FRAME_TOP_MARGIN_HEIGHT (f) \
1104 ? (y) \ 1147 ? (y) \
1105 : ((y) < FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \ 1148 : ((y) < FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \
1106 ? (y) - (FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \ 1149 ? (y) - (FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \
1107 /* Arrange for the division to round down. */ \ 1150 /* Arrange for the division to round down. */ \
1108 + FRAME_LINE_HEIGHT (f) - 1) \ 1151 + FRAME_LINE_HEIGHT (f) - 1) \
1109 : (y) - FRAME_INTERNAL_BORDER_WIDTH (f))) \ 1152 : (y) - FRAME_INTERNAL_BORDER_WIDTH (f))) \
1110 / FRAME_LINE_HEIGHT (f)) 1153 / FRAME_LINE_HEIGHT (f))
1111 1154
1112#define FRAME_PIXEL_X_TO_COL(f, x) \ 1155#define FRAME_PIXEL_X_TO_COL(f, x) \
1113 (((x) - FRAME_INTERNAL_BORDER_WIDTH (f)) \ 1156 (((x) - FRAME_INTERNAL_BORDER_WIDTH (f)) \
1114 / FRAME_COLUMN_WIDTH (f)) 1157 / FRAME_COLUMN_WIDTH (f))
1115 1158
1116/* How many columns/rows of text can we fit in WIDTH/HEIGHT pixels on 1159/* How many columns/rows of text can we fit in WIDTH/HEIGHT pixels on
1117 frame F? */ 1160 frame F? */
1118 1161
1119#define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width) \ 1162#define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width) \
1120 (FRAME_PIXEL_X_TO_COL (f, ((width) \ 1163 (FRAME_PIXEL_X_TO_COL (f, ((width) \
1121 - FRAME_INTERNAL_BORDER_WIDTH (f) \ 1164 - FRAME_INTERNAL_BORDER_WIDTH (f) \
1122 - FRAME_TOTAL_FRINGE_WIDTH (f) \ 1165 - FRAME_TOTAL_FRINGE_WIDTH (f) \
1123 - (f)->scroll_bar_actual_width))) 1166 - FRAME_SCROLL_BAR_AREA_WIDTH (f)))) \
1124 1167
1125#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \ 1168#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \
1126 (FRAME_PIXEL_Y_TO_LINE (f, ((height) \ 1169 (FRAME_PIXEL_Y_TO_LINE (f, ((height) \
1127 - FRAME_INTERNAL_BORDER_WIDTH (f)))) 1170 - FRAME_INTERNAL_BORDER_WIDTH (f))))
1128 1171
1172/* Return the pixel width/height of frame F with a text size of
1173 width/height. */
1174
1175#define FRAME_TEXT_TO_PIXEL_WIDTH(f, width) \
1176 ((width) \
1177 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
1178 + FRAME_TOTAL_FRINGE_WIDTH (f) \
1179 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1180
1181#define FRAME_TEXT_TO_PIXEL_HEIGHT(f, height) \
1182 ((height) + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1183
1184/* Return the text width/height of frame F with a pixel size of
1185 width/height. */
1186
1187#define FRAME_PIXEL_TO_TEXT_WIDTH(f, width) \
1188 ((width) \
1189 - FRAME_SCROLL_BAR_AREA_WIDTH (f) \
1190 - FRAME_TOTAL_FRINGE_WIDTH (f) \
1191 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1192
1193#define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height) \
1194 ((height) - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1195
1129/* Value is the smallest width of any character in any font on frame F. */ 1196/* Value is the smallest width of any character in any font on frame F. */
1130 1197
1131#define FRAME_SMALLEST_CHAR_WIDTH(f) \ 1198#define FRAME_SMALLEST_CHAR_WIDTH(f) \
@@ -1148,6 +1215,7 @@ extern Lisp_Object Qfont;
1148extern Lisp_Object Qbackground_color, Qforeground_color; 1215extern Lisp_Object Qbackground_color, Qforeground_color;
1149extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top; 1216extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top;
1150extern Lisp_Object Qinternal_border_width; 1217extern Lisp_Object Qinternal_border_width;
1218extern Lisp_Object Qright_divider_width, Qbottom_divider_width;
1151extern Lisp_Object Qtooltip; 1219extern Lisp_Object Qtooltip;
1152extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position; 1220extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
1153extern Lisp_Object Qmouse_color; 1221extern Lisp_Object Qmouse_color;
@@ -1211,6 +1279,10 @@ extern void x_set_fringe_width (struct frame *, Lisp_Object, Lisp_Object);
1211extern void x_set_border_width (struct frame *, Lisp_Object, Lisp_Object); 1279extern void x_set_border_width (struct frame *, Lisp_Object, Lisp_Object);
1212extern void x_set_internal_border_width (struct frame *, Lisp_Object, 1280extern void x_set_internal_border_width (struct frame *, Lisp_Object,
1213 Lisp_Object); 1281 Lisp_Object);
1282extern void x_set_right_divider_width (struct frame *, Lisp_Object,
1283 Lisp_Object);
1284extern void x_set_bottom_divider_width (struct frame *, Lisp_Object,
1285 Lisp_Object);
1214extern void x_set_visibility (struct frame *, Lisp_Object, Lisp_Object); 1286extern void x_set_visibility (struct frame *, Lisp_Object, Lisp_Object);
1215extern void x_set_autoraise (struct frame *, Lisp_Object, Lisp_Object); 1287extern void x_set_autoraise (struct frame *, Lisp_Object, Lisp_Object);
1216extern void x_set_autolower (struct frame *, Lisp_Object, Lisp_Object); 1288extern void x_set_autolower (struct frame *, Lisp_Object, Lisp_Object);
@@ -1234,7 +1306,7 @@ extern Lisp_Object display_x_get_resource (Display_Info *,
1234 1306
1235extern void set_frame_menubar (struct frame *f, bool first_time, bool deep_p); 1307extern void set_frame_menubar (struct frame *f, bool first_time, bool deep_p);
1236extern void x_set_window_size (struct frame *f, int change_grav, 1308extern void x_set_window_size (struct frame *f, int change_grav,
1237 int cols, int rows); 1309 int width, int height, bool pixelwise);
1238extern Lisp_Object x_get_focus_frame (struct frame *); 1310extern Lisp_Object x_get_focus_frame (struct frame *);
1239extern void x_set_mouse_position (struct frame *f, int h, int v); 1311extern void x_set_mouse_position (struct frame *f, int h, int v);
1240extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); 1312extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
@@ -1243,9 +1315,7 @@ extern void x_make_frame_invisible (struct frame *f);
1243extern void x_iconify_frame (struct frame *f); 1315extern void x_iconify_frame (struct frame *f);
1244extern void x_set_frame_alpha (struct frame *f); 1316extern void x_set_frame_alpha (struct frame *f);
1245extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); 1317extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
1246extern void x_set_tool_bar_lines (struct frame *f, 1318extern void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
1247 Lisp_Object value,
1248 Lisp_Object oldval);
1249extern void x_activate_menubar (struct frame *); 1319extern void x_activate_menubar (struct frame *);
1250extern void x_real_positions (struct frame *, int *, int *); 1320extern void x_real_positions (struct frame *, int *, int *);
1251extern void free_frame_menubar (struct frame *); 1321extern void free_frame_menubar (struct frame *);
diff --git a/src/fringe.c b/src/fringe.c
index 9c77e6557f4..db4f92d6ce4 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -659,6 +659,10 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o
659 { 659 {
660 /* If W has a vertical border to its left, don't draw over it. */ 660 /* If W has a vertical border to its left, don't draw over it. */
661 wd -= ((!WINDOW_LEFTMOST_P (w) 661 wd -= ((!WINDOW_LEFTMOST_P (w)
662 /* This could be wrong when we allow window local
663 right dividers - but the window on the left is hard
664 to get. */
665 && !FRAME_RIGHT_DIVIDER_WIDTH (f)
662 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w) 666 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
663 /* But don't reduce the fringe width if the window 667 /* But don't reduce the fringe width if the window
664 has a left margin, because that means we are not 668 has a left margin, because that means we are not
diff --git a/src/ftfont.c b/src/ftfont.c
index 224b8e82500..6a2303ab4a7 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -1478,7 +1478,6 @@ ftfont_get_bitmap (struct font *font, unsigned int code, struct font_bitmap *bit
1478 bitmap->left = ft_face->glyph->bitmap_left; 1478 bitmap->left = ft_face->glyph->bitmap_left;
1479 bitmap->top = ft_face->glyph->bitmap_top; 1479 bitmap->top = ft_face->glyph->bitmap_top;
1480 bitmap->advance = ft_face->glyph->metrics.horiAdvance >> 6; 1480 bitmap->advance = ft_face->glyph->metrics.horiAdvance >> 6;
1481 bitmap->extra = NULL;
1482 1481
1483 return 0; 1482 return 0;
1484} 1483}
diff --git a/src/gnutls.c b/src/gnutls.c
index 19617cea4b2..9ea3f59100d 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -56,8 +56,10 @@ static Lisp_Object QCgnutls_bootprop_verify_hostname_error;
56static Lisp_Object QCgnutls_bootprop_callbacks_verify; 56static Lisp_Object QCgnutls_bootprop_callbacks_verify;
57 57
58static void gnutls_log_function (int, const char *); 58static void gnutls_log_function (int, const char *);
59static void gnutls_audit_log_function (gnutls_session_t, const char *);
60static void gnutls_log_function2 (int, const char*, const char*); 59static void gnutls_log_function2 (int, const char*, const char*);
60#ifdef HAVE_GNUTLS3
61static void gnutls_audit_log_function (gnutls_session_t, const char *);
62#endif
61 63
62 64
63#ifdef WINDOWSNT 65#ifdef WINDOWSNT
@@ -262,6 +264,7 @@ init_gnutls_functions (void)
262#endif /* !WINDOWSNT */ 264#endif /* !WINDOWSNT */
263 265
264 266
267#ifdef HAVE_GNUTLS3
265/* Function to log a simple audit message. */ 268/* Function to log a simple audit message. */
266static void 269static void
267gnutls_audit_log_function (gnutls_session_t session, const char* string) 270gnutls_audit_log_function (gnutls_session_t session, const char* string)
@@ -271,6 +274,7 @@ gnutls_audit_log_function (gnutls_session_t session, const char* string)
271 message ("gnutls.c: [audit] %s", string); 274 message ("gnutls.c: [audit] %s", string);
272 } 275 }
273} 276}
277#endif
274 278
275/* Function to log a simple message. */ 279/* Function to log a simple message. */
276static void 280static void
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 192b64a7e62..ef422989c61 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -904,7 +904,7 @@ xg_clear_under_internal_border (struct frame *f)
904void 904void
905xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight) 905xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
906{ 906{
907 int rows, columns; 907 int width, height;
908 908
909 if (pixelwidth == -1 && pixelheight == -1) 909 if (pixelwidth == -1 && pixelheight == -1)
910 { 910 {
@@ -916,11 +916,11 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
916 } 916 }
917 917
918 918
919 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight); 919 width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth);
920 columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth); 920 height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight);
921 921
922 if (columns != FRAME_COLS (f) 922 if (width != FRAME_TEXT_WIDTH (f)
923 || rows != FRAME_LINES (f) 923 || height != FRAME_TEXT_HEIGHT (f)
924 || pixelwidth != FRAME_PIXEL_WIDTH (f) 924 || pixelwidth != FRAME_PIXEL_WIDTH (f)
925 || pixelheight != FRAME_PIXEL_HEIGHT (f)) 925 || pixelheight != FRAME_PIXEL_HEIGHT (f))
926 { 926 {
@@ -928,7 +928,7 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
928 FRAME_PIXEL_HEIGHT (f) = pixelheight; 928 FRAME_PIXEL_HEIGHT (f) = pixelheight;
929 929
930 xg_clear_under_internal_border (f); 930 xg_clear_under_internal_border (f);
931 change_frame_size (f, rows, columns, 0, 1, 0); 931 change_frame_size (f, width, height, 0, 1, 0, 1);
932 SET_FRAME_GARBAGED (f); 932 SET_FRAME_GARBAGED (f);
933 cancel_mouse_face (f); 933 cancel_mouse_face (f);
934 } 934 }
@@ -938,38 +938,23 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
938 COLUMNS/ROWS is the size the edit area shall have after the resize. */ 938 COLUMNS/ROWS is the size the edit area shall have after the resize. */
939 939
940void 940void
941xg_frame_set_char_size (struct frame *f, int cols, int rows) 941xg_frame_set_char_size (struct frame *f, int width, int height)
942{ 942{
943 int pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows) 943 int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
944 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); 944 int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
945 int pixelwidth;
946 945
947 if (FRAME_PIXEL_HEIGHT (f) == 0) 946 if (FRAME_PIXEL_HEIGHT (f) == 0)
948 return; 947 return;
949 948
950 /* Take into account the size of the scroll bar. Always use the
951 number of columns occupied by the scroll bar here otherwise we
952 might end up with a frame width that is not a multiple of the
953 frame's character width which is bad for vertically split
954 windows. */
955 f->scroll_bar_actual_width
956 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
957
958 compute_fringe_widths (f, 0);
959
960 /* FRAME_TEXT_COLS_TO_PIXEL_WIDTH uses scroll_bar_actual_width, so call it
961 after calculating that value. */
962 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols)
963 + FRAME_TOOLBAR_WIDTH (f);
964
965
966 /* Do this before resize, as we don't know yet if we will be resized. */ 949 /* Do this before resize, as we don't know yet if we will be resized. */
967 xg_clear_under_internal_border (f); 950 xg_clear_under_internal_border (f);
968 951
969 /* Must resize our top level widget. Font size may have changed, 952 /* Must resize our top level widget. Font size may have changed,
970 but not rows/cols. */ 953 but not rows/cols. */
971 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 954 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
972 pixelwidth, pixelheight); 955 pixelwidth + FRAME_TOOLBAR_WIDTH (f),
956 pixelheight + FRAME_TOOLBAR_HEIGHT (f)
957 + FRAME_MENUBAR_HEIGHT (f));
973 x_wm_set_size_hint (f, 0, 0); 958 x_wm_set_size_hint (f, 0, 0);
974 959
975 SET_FRAME_GARBAGED (f); 960 SET_FRAME_GARBAGED (f);
@@ -990,11 +975,7 @@ xg_frame_set_char_size (struct frame *f, int cols, int rows)
990 x_wait_for_event (f, ConfigureNotify); 975 x_wait_for_event (f, ConfigureNotify);
991 } 976 }
992 else 977 else
993 { 978 change_frame_size (f, width, height, 0, 1, 0, 1);
994 change_frame_size (f, rows, cols, 0, 1, 0);
995 FRAME_PIXEL_WIDTH (f) = pixelwidth;
996 FRAME_PIXEL_HEIGHT (f) = pixelheight;
997 }
998} 979}
999 980
1000/* Handle height/width changes (i.e. add/remove/move menu/toolbar). 981/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
@@ -1098,7 +1079,7 @@ style_changed_cb (GObject *go,
1098 && FRAME_X_DISPLAY (f) == dpy) 1079 && FRAME_X_DISPLAY (f) == dpy)
1099 { 1080 {
1100 x_set_scroll_bar_default_width (f); 1081 x_set_scroll_bar_default_width (f);
1101 xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f)); 1082 xg_frame_set_char_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f));
1102 } 1083 }
1103 } 1084 }
1104 } 1085 }
@@ -1381,7 +1362,7 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
1381 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1) 1362 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1)
1382 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); 1363 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
1383 1364
1384 check_frame_size (f, &min_rows, &min_cols); 1365 check_frame_size (f, &min_cols, &min_rows, 0);
1385 if (min_cols > 0) --min_cols; /* We used one col in base_width = ... 1); */ 1366 if (min_cols > 0) --min_cols; /* We used one col in base_width = ... 1); */
1386 if (min_rows > 0) --min_rows; /* We used one row in base_height = ... 1); */ 1367 if (min_rows > 0) --min_rows; /* We used one row in base_height = ... 1); */
1387 1368
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 1c26d2aa44b..a2c5bb3ee76 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -139,7 +139,7 @@ extern void xg_change_toolbar_position (struct frame *f, Lisp_Object pos);
139extern void xg_frame_resized (struct frame *f, 139extern void xg_frame_resized (struct frame *f,
140 int pixelwidth, 140 int pixelwidth,
141 int pixelheight); 141 int pixelheight);
142extern void xg_frame_set_char_size (struct frame *f, int cols, int rows); 142extern void xg_frame_set_char_size (struct frame *f, int width, int height);
143extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc); 143extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc);
144 144
145extern void xg_display_open (char *display_name, Display **dpy); 145extern void xg_display_open (char *display_name, Display **dpy);
diff --git a/src/image.c b/src/image.c
index 89e4f863d53..38a92277299 100644
--- a/src/image.c
+++ b/src/image.c
@@ -8105,7 +8105,7 @@ imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
8105 { 8105 {
8106 /* Sanity check. This shouldn't happen, but apparently 8106 /* Sanity check. This shouldn't happen, but apparently
8107 also does in some pictures. */ 8107 also does in some pictures. */
8108 if (x + source_left > dest_width) 8108 if (x + source_left > dest_width - 1)
8109 break; 8109 break;
8110 /* Normally we only copy over non-transparent pixels, 8110 /* Normally we only copy over non-transparent pixels,
8111 but if the disposal method is "Background", then we 8111 but if the disposal method is "Background", then we
@@ -9517,7 +9517,7 @@ A cross is always drawn on black & white displays. */);
9517 9517
9518 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path, 9518 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
9519 doc: /* List of directories to search for window system bitmap files. */); 9519 doc: /* List of directories to search for window system bitmap files. */);
9520 Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS); 9520 Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS, 0);
9521 9521
9522 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay, 9522 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
9523 doc: /* Maximum time after which images are removed from the cache. 9523 doc: /* Maximum time after which images are removed from the cache.
diff --git a/src/indent.c b/src/indent.c
index 891b42788ed..502611b534a 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1146,7 +1146,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos,
1146 /* Negative width means use all available text columns. */ 1146 /* Negative width means use all available text columns. */
1147 if (width < 0) 1147 if (width < 0)
1148 { 1148 {
1149 width = window_body_cols (win); 1149 width = window_body_width (win, 0);
1150 /* We must make room for continuation marks if we don't have fringes. */ 1150 /* We must make room for continuation marks if we don't have fringes. */
1151#ifdef HAVE_WINDOW_SYSTEM 1151#ifdef HAVE_WINDOW_SYSTEM
1152 if (!FRAME_WINDOW_P (XFRAME (win->frame))) 1152 if (!FRAME_WINDOW_P (XFRAME (win->frame)))
@@ -1756,7 +1756,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */)
1756 ? window_internal_height (w) 1756 ? window_internal_height (w)
1757 : XINT (XCDR (topos))), 1757 : XINT (XCDR (topos))),
1758 (NILP (topos) 1758 (NILP (topos)
1759 ? (window_body_cols (w) 1759 ? (window_body_width (w, 0)
1760 - ( 1760 - (
1761#ifdef HAVE_WINDOW_SYSTEM 1761#ifdef HAVE_WINDOW_SYSTEM
1762 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 : 1762 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
diff --git a/src/insdel.c b/src/insdel.c
index 8de4f095396..db7ac0e3ad5 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1804,11 +1804,7 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
1804 if (!NILP (BVAR (current_buffer, read_only))) 1804 if (!NILP (BVAR (current_buffer, read_only)))
1805 Fbarf_if_buffer_read_only (); 1805 Fbarf_if_buffer_read_only ();
1806 1806
1807 /* If we're modifying the buffer other than shown in a selected window, 1807 bset_redisplay (current_buffer);
1808 let redisplay consider other windows if this buffer is visible. */
1809 if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer
1810 && buffer_window_count (current_buffer))
1811 windows_or_buffers_changed = 20;
1812 1808
1813 if (buffer_intervals (current_buffer)) 1809 if (buffer_intervals (current_buffer))
1814 { 1810 {
diff --git a/src/intervals.c b/src/intervals.c
index 5aa68a359d6..0e3b684f570 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -2232,7 +2232,7 @@ get_local_map (ptrdiff_t position, struct buffer *buffer, Lisp_Object type)
2232 editing a field with a `local-map' property, we want insertion at the end 2232 editing a field with a `local-map' property, we want insertion at the end
2233 to obey the `local-map' property. */ 2233 to obey the `local-map' property. */
2234 if (NILP (prop)) 2234 if (NILP (prop))
2235 prop = get_pos_property (lispy_position, type, lispy_buffer); 2235 prop = Fget_pos_property (lispy_position, type, lispy_buffer);
2236 2236
2237 SET_BUF_BEGV_BOTH (buffer, old_begv, old_begv_byte); 2237 SET_BUF_BEGV_BOTH (buffer, old_begv, old_begv_byte);
2238 SET_BUF_ZV_BOTH (buffer, old_zv, old_zv_byte); 2238 SET_BUF_ZV_BOTH (buffer, old_zv, old_zv_byte);
diff --git a/src/intervals.h b/src/intervals.h
index 51dfa09c5c4..40f32645ba0 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -296,8 +296,6 @@ Lisp_Object get_char_property_and_overlay (Lisp_Object, Lisp_Object,
296 Lisp_Object, Lisp_Object*); 296 Lisp_Object, Lisp_Object*);
297extern int text_property_stickiness (Lisp_Object prop, Lisp_Object pos, 297extern int text_property_stickiness (Lisp_Object prop, Lisp_Object pos,
298 Lisp_Object buffer); 298 Lisp_Object buffer);
299extern Lisp_Object get_pos_property (Lisp_Object pos, Lisp_Object prop,
300 Lisp_Object object);
301 299
302extern void syms_of_textprop (void); 300extern void syms_of_textprop (void);
303 301
diff --git a/src/keyboard.c b/src/keyboard.c
index 450592a07b6..b50c06b4154 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -347,6 +347,7 @@ static Lisp_Object Qmodifier_cache;
347/* Symbols to use for parts of windows. */ 347/* Symbols to use for parts of windows. */
348Lisp_Object Qmode_line; 348Lisp_Object Qmode_line;
349Lisp_Object Qvertical_line; 349Lisp_Object Qvertical_line;
350Lisp_Object Qright_divider, Qbottom_divider;
350static Lisp_Object Qvertical_scroll_bar; 351static Lisp_Object Qvertical_scroll_bar;
351Lisp_Object Qmenu_bar; 352Lisp_Object Qmenu_bar;
352 353
@@ -1771,8 +1772,8 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified)
1771 than skip both boundaries. However, this code 1772 than skip both boundaries. However, this code
1772 also stops anywhere in a non-sticky text-property, 1773 also stops anywhere in a non-sticky text-property,
1773 which breaks (e.g.) Org mode. */ 1774 which breaks (e.g.) Org mode. */
1774 && (val = get_pos_property (make_number (end), 1775 && (val = Fget_pos_property (make_number (end),
1775 Qinvisible, Qnil), 1776 Qinvisible, Qnil),
1776 TEXT_PROP_MEANS_INVISIBLE (val)) 1777 TEXT_PROP_MEANS_INVISIBLE (val))
1777#endif 1778#endif
1778 && !NILP (val = get_char_property_and_overlay 1779 && !NILP (val = get_char_property_and_overlay
@@ -1789,8 +1790,8 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified)
1789 } 1790 }
1790 while (beg > BEGV 1791 while (beg > BEGV
1791#if 0 1792#if 0
1792 && (val = get_pos_property (make_number (beg), 1793 && (val = Fget_pos_property (make_number (beg),
1793 Qinvisible, Qnil), 1794 Qinvisible, Qnil),
1794 TEXT_PROP_MEANS_INVISIBLE (val)) 1795 TEXT_PROP_MEANS_INVISIBLE (val))
1795#endif 1796#endif
1796 && !NILP (val = get_char_property_and_overlay 1797 && !NILP (val = get_char_property_and_overlay
@@ -1843,12 +1844,12 @@ adjust_point_for_property (ptrdiff_t last_pt, bool modified)
1843 to the other end would mean moving backwards and thus 1844 to the other end would mean moving backwards and thus
1844 could lead to an infinite loop. */ 1845 could lead to an infinite loop. */
1845 ; 1846 ;
1846 else if (val = get_pos_property (make_number (PT), 1847 else if (val = Fget_pos_property (make_number (PT),
1847 Qinvisible, Qnil), 1848 Qinvisible, Qnil),
1848 TEXT_PROP_MEANS_INVISIBLE (val) 1849 TEXT_PROP_MEANS_INVISIBLE (val)
1849 && (val = get_pos_property 1850 && (val = (Fget_pos_property
1850 (make_number (PT == beg ? end : beg), 1851 (make_number (PT == beg ? end : beg),
1851 Qinvisible, Qnil), 1852 Qinvisible, Qnil)),
1852 !TEXT_PROP_MEANS_INVISIBLE (val))) 1853 !TEXT_PROP_MEANS_INVISIBLE (val)))
1853 (check_composition = check_display = 1, 1854 (check_composition = check_display = 1,
1854 SET_PT (PT == beg ? end : beg)); 1855 SET_PT (PT == beg ? end : beg));
@@ -3222,8 +3223,6 @@ read_char (int commandflag, Lisp_Object map,
3222 RETURN_UNGCPRO (c); 3223 RETURN_UNGCPRO (c);
3223} 3224}
3224 3225
3225#ifdef HAVE_MENUS
3226
3227/* Record a key that came from a mouse menu. 3226/* Record a key that came from a mouse menu.
3228 Record it for echoing, for this-command-keys, and so on. */ 3227 Record it for echoing, for this-command-keys, and so on. */
3229 3228
@@ -3254,13 +3253,11 @@ record_menu_key (Lisp_Object c)
3254 /* Record this character as part of the current key. */ 3253 /* Record this character as part of the current key. */
3255 add_command_key (c); 3254 add_command_key (c);
3256 3255
3257 /* Re-reading in the middle of a command */ 3256 /* Re-reading in the middle of a command. */
3258 last_input_event = c; 3257 last_input_event = c;
3259 num_input_events++; 3258 num_input_events++;
3260} 3259}
3261 3260
3262#endif /* HAVE_MENUS */
3263
3264/* Return true if should recognize C as "the help character". */ 3261/* Return true if should recognize C as "the help character". */
3265 3262
3266static bool 3263static bool
@@ -5306,6 +5303,20 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5306 dy = yret = wy; 5303 dy = yret = wy;
5307 } 5304 }
5308 /* Nothing special for part == ON_SCROLL_BAR. */ 5305 /* Nothing special for part == ON_SCROLL_BAR. */
5306 else if (part == ON_RIGHT_DIVIDER)
5307 {
5308 posn = Qright_divider;
5309 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
5310 dx = xret = wx;
5311 dy = yret = wy;
5312 }
5313 else if (part == ON_BOTTOM_DIVIDER)
5314 {
5315 posn = Qbottom_divider;
5316 width = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
5317 dx = xret = wx;
5318 dy = yret = wy;
5319 }
5309 5320
5310 /* For clicks in the text area, fringes, or margins, call 5321 /* For clicks in the text area, fringes, or margins, call
5311 buffer_posn_from_coords to extract TEXTPOS, the buffer 5322 buffer_posn_from_coords to extract TEXTPOS, the buffer
@@ -8359,7 +8370,6 @@ read_char_x_menu_prompt (Lisp_Object map,
8359 if (! menu_prompting) 8370 if (! menu_prompting)
8360 return Qnil; 8371 return Qnil;
8361 8372
8362#ifdef HAVE_MENUS
8363 /* If we got to this point via a mouse click, 8373 /* If we got to this point via a mouse click,
8364 use a real menu for mouse selection. */ 8374 use a real menu for mouse selection. */
8365 if (EVENT_HAS_PARAMETERS (prev_event) 8375 if (EVENT_HAS_PARAMETERS (prev_event)
@@ -8405,7 +8415,6 @@ read_char_x_menu_prompt (Lisp_Object map,
8405 *used_mouse_menu = 1; 8415 *used_mouse_menu = 1;
8406 return value; 8416 return value;
8407 } 8417 }
8408#endif /* HAVE_MENUS */
8409 return Qnil ; 8418 return Qnil ;
8410} 8419}
8411 8420
@@ -10148,7 +10157,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
10148 with a window system; but suspend should be disabled in that case. */ 10157 with a window system; but suspend should be disabled in that case. */
10149 get_tty_size (fileno (CURTTY ()->input), &width, &height); 10158 get_tty_size (fileno (CURTTY ()->input), &width, &height);
10150 if (width != old_width || height != old_height) 10159 if (width != old_width || height != old_height)
10151 change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0); 10160 change_frame_size (SELECTED_FRAME (), width, height, 0, 0, 0, 0);
10152 10161
10153 /* Run suspend-resume-hook. */ 10162 /* Run suspend-resume-hook. */
10154 hook = intern ("suspend-resume-hook"); 10163 hook = intern ("suspend-resume-hook");
@@ -10984,6 +10993,8 @@ syms_of_keyboard (void)
10984 DEFSYM (Qvertical_line, "vertical-line"); 10993 DEFSYM (Qvertical_line, "vertical-line");
10985 DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar"); 10994 DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
10986 DEFSYM (Qmenu_bar, "menu-bar"); 10995 DEFSYM (Qmenu_bar, "menu-bar");
10996 DEFSYM (Qright_divider, "right-divider");
10997 DEFSYM (Qbottom_divider, "bottom-divider");
10987 10998
10988 DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message"); 10999 DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message");
10989 11000
diff --git a/src/keyboard.h b/src/keyboard.h
index b8aad959dd9..a1aa59fe988 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -457,6 +457,7 @@ extern Lisp_Object Qhelp_echo;
457 457
458/* Symbols to use for non-text mouse positions. */ 458/* Symbols to use for non-text mouse positions. */
459extern Lisp_Object Qmode_line, Qvertical_line, Qheader_line; 459extern Lisp_Object Qmode_line, Qvertical_line, Qheader_line;
460extern Lisp_Object Qright_divider, Qbottom_divider;
460 461
461/* True while doing kbd input. */ 462/* True while doing kbd input. */
462extern bool waiting_for_input; 463extern bool waiting_for_input;
diff --git a/src/lisp.h b/src/lisp.h
index a5aec41be38..d8cf6b6960e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1,7 +1,6 @@
1/* Fundamental definitions for GNU Emacs Lisp interpreter. 1/* Fundamental definitions for GNU Emacs Lisp interpreter.
2 2
3Copyright (C) 1985-1987, 1993-1995, 1997-2013 Free Software Foundation, 3Copyright (C) 1985-1987, 1993-1995, 1997-2013 Free Software Foundation, Inc.
4Inc.
5 4
6This file is part of GNU Emacs. 5This file is part of GNU Emacs.
7 6
@@ -1213,6 +1212,7 @@ struct Lisp_Bool_Vector
1213 /* This is the size in bits. */ 1212 /* This is the size in bits. */
1214 EMACS_INT size; 1213 EMACS_INT size;
1215 /* The actual bits, packed into bytes. 1214 /* The actual bits, packed into bytes.
1215 Zeros fill out the last word if needed.
1216 The bits are in little-endian order in the bytes, and 1216 The bits are in little-endian order in the bytes, and
1217 the bytes are in little-endian order in the words. */ 1217 the bytes are in little-endian order in the words. */
1218 bits_word data[FLEXIBLE_ARRAY_MEMBER]; 1218 bits_word data[FLEXIBLE_ARRAY_MEMBER];
@@ -3523,7 +3523,7 @@ extern void pop_message_unwind (void);
3523extern Lisp_Object restore_message_unwind (Lisp_Object); 3523extern Lisp_Object restore_message_unwind (Lisp_Object);
3524extern void restore_message (void); 3524extern void restore_message (void);
3525extern Lisp_Object current_message (void); 3525extern Lisp_Object current_message (void);
3526extern void clear_message (int, int); 3526extern void clear_message (bool, bool);
3527extern void message (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); 3527extern void message (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
3528extern void message1 (const char *); 3528extern void message1 (const char *);
3529extern void message1_nolog (const char *); 3529extern void message1_nolog (const char *);
@@ -4042,6 +4042,7 @@ extern void syms_of_indent (void);
4042/* Defined in frame.c. */ 4042/* Defined in frame.c. */
4043extern Lisp_Object Qonly, Qnone; 4043extern Lisp_Object Qonly, Qnone;
4044extern Lisp_Object Qvisible; 4044extern Lisp_Object Qvisible;
4045extern void set_frame_param (struct frame *, Lisp_Object, Lisp_Object);
4045extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object); 4046extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object);
4046extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object); 4047extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
4047extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object); 4048extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
@@ -4057,7 +4058,7 @@ extern int initial_argc;
4057#if defined (HAVE_X_WINDOWS) || defined (HAVE_NS) 4058#if defined (HAVE_X_WINDOWS) || defined (HAVE_NS)
4058extern bool display_arg; 4059extern bool display_arg;
4059#endif 4060#endif
4060extern Lisp_Object decode_env_path (const char *, const char *); 4061extern Lisp_Object decode_env_path (const char *, const char *, bool);
4061extern Lisp_Object empty_unibyte_string, empty_multibyte_string; 4062extern Lisp_Object empty_unibyte_string, empty_multibyte_string;
4062extern Lisp_Object Qfile_name_handler_alist; 4063extern Lisp_Object Qfile_name_handler_alist;
4063extern _Noreturn void terminate_due_to_signal (int, int); 4064extern _Noreturn void terminate_due_to_signal (int, int);
@@ -4442,6 +4443,20 @@ extern void *record_xmalloc (size_t);
4442 memory_full (SIZE_MAX); \ 4443 memory_full (SIZE_MAX); \
4443 } while (0) 4444 } while (0)
4444 4445
4446/* Loop over all tails of a list, checking for cycles.
4447 FIXME: Make tortoise and n internal declarations.
4448 FIXME: Unroll the loop body so we don't need `n'. */
4449#define FOR_EACH_TAIL(hare, list, tortoise, n) \
4450 for (tortoise = hare = (list), n = true; \
4451 CONSP (hare); \
4452 (hare = XCDR (hare), n = !n, \
4453 (n \
4454 ? ((EQ (hare, tortoise) \
4455 && (xsignal1 (Qcircular_list, (list)), 0))) \
4456 /* Move tortoise before the next iteration, in case */ \
4457 /* the next iteration does an Fsetcdr. */ \
4458 : (tortoise = XCDR (tortoise), 0))))
4459
4445/* Do a `for' loop over alist values. */ 4460/* Do a `for' loop over alist values. */
4446 4461
4447#define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \ 4462#define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \
diff --git a/src/lisp.mk b/src/lisp.mk
index c12deebd893..d61f7f71c2f 100644
--- a/src/lisp.mk
+++ b/src/lisp.mk
@@ -164,6 +164,8 @@ lisp = \
164 $(lispsource)/emacs-lisp/float-sup.elc \ 164 $(lispsource)/emacs-lisp/float-sup.elc \
165 $(lispsource)/vc/vc-hooks.elc \ 165 $(lispsource)/vc/vc-hooks.elc \
166 $(lispsource)/vc/ediff-hook.elc \ 166 $(lispsource)/vc/ediff-hook.elc \
167 $(lispsource)/electric.elc \
168 $(lispsource)/uniquify.elc \
167 $(lispsource)/tooltip.elc 169 $(lispsource)/tooltip.elc
168 170
169 171
diff --git a/src/lread.c b/src/lread.c
index 6c1b17f62b7..a64f083a5ac 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1,7 +1,6 @@
1/* Lisp parsing and input streams. 1/* Lisp parsing and input streams.
2 2
3Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation, 3Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation, Inc.
4Inc.
5 4
6This file is part of GNU Emacs. 5This file is part of GNU Emacs.
7 6
@@ -3538,7 +3537,7 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag)
3538 return vector; 3537 return vector;
3539} 3538}
3540 3539
3541/* FLAG means check for ] to terminate rather than ) and . */ 3540/* FLAG means check for ']' to terminate rather than ')' and '.'. */
3542 3541
3543static Lisp_Object 3542static Lisp_Object
3544read_list (bool flag, Lisp_Object readcharfun) 3543read_list (bool flag, Lisp_Object readcharfun)
@@ -4106,17 +4105,17 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd,
4106 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); 4105 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd);
4107} 4106}
4108 4107
4109/* Check that the elements of Vload_path exist. */ 4108/* Check that the elements of lpath exist. */
4110 4109
4111static void 4110static void
4112load_path_check (void) 4111load_path_check (Lisp_Object lpath)
4113{ 4112{
4114 Lisp_Object path_tail; 4113 Lisp_Object path_tail;
4115 4114
4116 /* The only elements that might not exist are those from 4115 /* The only elements that might not exist are those from
4117 PATH_LOADSEARCH, EMACSLOADPATH. Anything else is only added if 4116 PATH_LOADSEARCH, EMACSLOADPATH. Anything else is only added if
4118 it exists. */ 4117 it exists. */
4119 for (path_tail = Vload_path; !NILP (path_tail); path_tail = XCDR (path_tail)) 4118 for (path_tail = lpath; !NILP (path_tail); path_tail = XCDR (path_tail))
4120 { 4119 {
4121 Lisp_Object dirfile; 4120 Lisp_Object dirfile;
4122 dirfile = Fcar (path_tail); 4121 dirfile = Fcar (path_tail);
@@ -4133,19 +4132,23 @@ load_path_check (void)
4133 so we can see if the site changed it later during dumping. */ 4132 so we can see if the site changed it later during dumping. */
4134static Lisp_Object dump_path; 4133static Lisp_Object dump_path;
4135 4134
4136/* Compute the default Vload_path, with the following logic: 4135/* Return the default load-path, to be used if EMACSLOADPATH is unset.
4137 If CANNOT_DUMP: 4136 This does not include the standard site-lisp directories
4138 use EMACSLOADPATH env-var if set; otherwise use PATH_LOADSEARCH, 4137 under the installation prefix (i.e., PATH_SITELOADSEARCH),
4139 prepending PATH_SITELOADSEARCH unless --no-site-lisp. 4138 but it does (unless no_site_lisp is set) include site-lisp
4139 directories in the source/build directories if those exist and we
4140 are running uninstalled.
4141
4142 Uses the following logic:
4143 If CANNOT_DUMP: Use PATH_LOADSEARCH.
4140 The remainder is what happens when dumping works: 4144 The remainder is what happens when dumping works:
4141 If purify-flag (ie dumping) just use PATH_DUMPLOADSEARCH. 4145 If purify-flag (ie dumping) just use PATH_DUMPLOADSEARCH.
4142 Otherwise use EMACSLOADPATH if set, else PATH_LOADSEARCH. 4146 Otherwise use PATH_LOADSEARCH.
4143 4147
4144 If !initialized, then just set both Vload_path and dump_path. 4148 If !initialized, then just set dump_path and return PATH_DUMPLOADSEARCH.
4145 If initialized, then if Vload_path != dump_path, do nothing. 4149 If initialized, then if Vload_path != dump_path, return just Vload_path.
4146 (Presumably the load-path has already been changed by something. 4150 (Presumably the load-path has already been changed by something.
4147 This can only be from a site-load file during dumping, 4151 This can only be from a site-load file during dumping.)
4148 or because EMACSLOADPATH is set.)
4149 If Vinstallation_directory is not nil (ie, running uninstalled): 4152 If Vinstallation_directory is not nil (ie, running uninstalled):
4150 If installation-dir/lisp exists and not already a member, 4153 If installation-dir/lisp exists and not already a member,
4151 we must be running uninstalled. Reset the load-path 4154 we must be running uninstalled. Reset the load-path
@@ -4154,20 +4157,17 @@ static Lisp_Object dump_path;
4154 are not yet installed, we should not use them, even if they exist.) 4157 are not yet installed, we should not use them, even if they exist.)
4155 If installation-dir/lisp does not exist, just add dump_path at the 4158 If installation-dir/lisp does not exist, just add dump_path at the
4156 end instead. 4159 end instead.
4157 Add installation-dir/leim (if exists and not already a member) at the front.
4158 Add installation-dir/site-lisp (if !no_site_lisp, and exists 4160 Add installation-dir/site-lisp (if !no_site_lisp, and exists
4159 and not already a member) at the front. 4161 and not already a member) at the front.
4160 If installation-dir != source-dir (ie running an uninstalled, 4162 If installation-dir != source-dir (ie running an uninstalled,
4161 out-of-tree build) AND install-dir/src/Makefile exists BUT 4163 out-of-tree build) AND install-dir/src/Makefile exists BUT
4162 install-dir/src/Makefile.in does NOT exist (this is a sanity 4164 install-dir/src/Makefile.in does NOT exist (this is a sanity
4163 check), then repeat the above steps for source-dir/lisp, 4165 check), then repeat the above steps for source-dir/lisp, site-lisp. */
4164 leim and site-lisp.
4165 Finally, add the site-lisp directories at the front (if !no_site_lisp).
4166*/
4167 4166
4168void 4167static Lisp_Object
4169init_lread (void) 4168load_path_default (bool changed)
4170{ 4169{
4170 Lisp_Object lpath = Qnil;
4171 const char *normal; 4171 const char *normal;
4172 4172
4173#ifdef CANNOT_DUMP 4173#ifdef CANNOT_DUMP
@@ -4177,63 +4177,48 @@ init_lread (void)
4177 4177
4178 normal = PATH_LOADSEARCH; 4178 normal = PATH_LOADSEARCH;
4179#ifdef HAVE_NS 4179#ifdef HAVE_NS
4180 Vload_path = decode_env_path ("EMACSLOADPATH", loadpath ? loadpath : normal); 4180 lpath = decode_env_path (0, loadpath ? loadpath : normal, 0);
4181#else 4181#else
4182 Vload_path = decode_env_path ("EMACSLOADPATH", normal); 4182 lpath = decode_env_path (0, normal, 0);
4183#endif 4183#endif
4184 4184
4185 load_path_check ();
4186
4187 /* FIXME CANNOT_DUMP platforms should get source-dir/lisp etc added
4188 to their load-path too, AFAICS. I don't think we can tell the
4189 difference between initialized and !initialized in this case,
4190 so we'll have to do it unconditionally when Vinstallation_directory
4191 is non-nil. */
4192 if (!no_site_lisp && !egetenv ("EMACSLOADPATH"))
4193 {
4194 Lisp_Object sitelisp;
4195 sitelisp = decode_env_path (0, PATH_SITELOADSEARCH);
4196 if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path);
4197 }
4198#else /* !CANNOT_DUMP */ 4185#else /* !CANNOT_DUMP */
4199 if (NILP (Vpurify_flag)) 4186
4200 { 4187 normal = NILP (Vpurify_flag) ? PATH_LOADSEARCH : PATH_DUMPLOADSEARCH;
4201 normal = PATH_LOADSEARCH;
4202 /* If the EMACSLOADPATH environment variable is set, use its value.
4203 This doesn't apply if we're dumping. */
4204 if (egetenv ("EMACSLOADPATH"))
4205 Vload_path = decode_env_path ("EMACSLOADPATH", normal);
4206 }
4207 else
4208 normal = PATH_DUMPLOADSEARCH;
4209 4188
4210 /* In a dumped Emacs, we normally reset the value of Vload_path using 4189 /* In a dumped Emacs, we normally reset the value of Vload_path using
4211 PATH_LOADSEARCH, since the value that was dumped uses lisp/ in 4190 PATH_LOADSEARCH, since the value that was dumped uses lisp/ in
4212 the source directory, instead of the path of the installed elisp 4191 the source directory, instead of the path of the installed elisp
4213 libraries. However, if it appears that Vload_path has already been 4192 libraries. However, if it appears that Vload_path has already been
4214 changed from the default that was saved before dumping, don't 4193 changed from the default that was saved before dumping, don't
4215 change it further. Changes can only be due to EMACSLOADPATH, or 4194 change it further. Changes can only be due to site-lisp
4216 site-lisp files that were processed during dumping. */ 4195 files that were processed during dumping. */
4196 /* FIXME? AFAICS, it does not make sense to change load-path in a
4197 dumped site-lisp file, so maybe we should just drop this check.
4198 E.g., if you add an element to load-path, you are going to be
4199 adding it to PATH_DUMPLOADSEARCH, which refers to the source directory.
4200 This will make no sense (and may not still exist) in an installed Emacs.
4201 And the only change it is sensible to make to load-path is to add
4202 something to the front, which you should do with configure's
4203 --enable-locallisppath option if you really want to have it dumped. */
4217 if (initialized) 4204 if (initialized)
4218 { 4205 {
4219 if (NILP (Fequal (dump_path, Vload_path))) 4206 if (changed || NILP (Fequal (dump_path, Vload_path)))
4220 { 4207 {
4221 /* Do not make any changes, just check the elements exist. */ 4208 /* Do not make any changes. */
4222 /* Note: --no-site-lisp is ignored. 4209 return Vload_path;
4223 I don't know what to do about this. */
4224 load_path_check ();
4225 } 4210 }
4226 else 4211 else
4227 { 4212 {
4228#ifdef HAVE_NS 4213#ifdef HAVE_NS
4229 const char *loadpath = ns_load_path (); 4214 const char *loadpath = ns_load_path ();
4230 Vload_path = decode_env_path (0, loadpath ? loadpath : normal); 4215 lpath = decode_env_path (0, loadpath ? loadpath : normal, 0);
4231#else 4216#else
4232 Vload_path = decode_env_path (0, normal); 4217 lpath = decode_env_path (0, normal, 0);
4233#endif 4218#endif
4234 if (!NILP (Vinstallation_directory)) 4219 if (!NILP (Vinstallation_directory))
4235 { 4220 {
4236 Lisp_Object tem, tem1; 4221 Lisp_Object tem, tem1;
4237 4222
4238 /* Add to the path the lisp subdir of the installation 4223 /* Add to the path the lisp subdir of the installation
4239 dir, if it is accessible. Note: in out-of-tree builds, 4224 dir, if it is accessible. Note: in out-of-tree builds,
@@ -4243,29 +4228,19 @@ init_lread (void)
4243 tem1 = Ffile_accessible_directory_p (tem); 4228 tem1 = Ffile_accessible_directory_p (tem);
4244 if (!NILP (tem1)) 4229 if (!NILP (tem1))
4245 { 4230 {
4246 if (NILP (Fmember (tem, Vload_path))) 4231 if (NILP (Fmember (tem, lpath)))
4247 { 4232 {
4248 /* We are running uninstalled. The default load-path 4233 /* We are running uninstalled. The default load-path
4249 points to the eventual installed lisp, leim 4234 points to the eventual installed lisp directories.
4250 directories. We should not use those now, even 4235 We should not use those now, even if they exist,
4251 if they exist, so start over from a clean slate. */ 4236 so start over from a clean slate. */
4252 Vload_path = list1 (tem); 4237 lpath = list1 (tem);
4253 } 4238 }
4254 } 4239 }
4255 else 4240 else
4256 /* That dir doesn't exist, so add the build-time 4241 /* That dir doesn't exist, so add the build-time
4257 Lisp dirs instead. */ 4242 Lisp dirs instead. */
4258 Vload_path = nconc2 (Vload_path, dump_path); 4243 lpath = nconc2 (lpath, dump_path);
4259
4260 /* Add leim under the installation dir, if it is accessible. */
4261 tem = Fexpand_file_name (build_string ("leim"),
4262 Vinstallation_directory);
4263 tem1 = Ffile_accessible_directory_p (tem);
4264 if (!NILP (tem1))
4265 {
4266 if (NILP (Fmember (tem, Vload_path)))
4267 Vload_path = Fcons (tem, Vload_path);
4268 }
4269 4244
4270 /* Add site-lisp under the installation dir, if it exists. */ 4245 /* Add site-lisp under the installation dir, if it exists. */
4271 if (!no_site_lisp) 4246 if (!no_site_lisp)
@@ -4275,14 +4250,14 @@ init_lread (void)
4275 tem1 = Ffile_accessible_directory_p (tem); 4250 tem1 = Ffile_accessible_directory_p (tem);
4276 if (!NILP (tem1)) 4251 if (!NILP (tem1))
4277 { 4252 {
4278 if (NILP (Fmember (tem, Vload_path))) 4253 if (NILP (Fmember (tem, lpath)))
4279 Vload_path = Fcons (tem, Vload_path); 4254 lpath = Fcons (tem, lpath);
4280 } 4255 }
4281 } 4256 }
4282 4257
4283 /* If Emacs was not built in the source directory, 4258 /* If Emacs was not built in the source directory,
4284 and it is run from where it was built, add to load-path 4259 and it is run from where it was built, add to load-path
4285 the lisp, leim and site-lisp dirs under that directory. */ 4260 the lisp and site-lisp dirs under that directory. */
4286 4261
4287 if (NILP (Fequal (Vinstallation_directory, Vsource_directory))) 4262 if (NILP (Fequal (Vinstallation_directory, Vsource_directory)))
4288 { 4263 {
@@ -4304,14 +4279,8 @@ init_lread (void)
4304 tem = Fexpand_file_name (build_string ("lisp"), 4279 tem = Fexpand_file_name (build_string ("lisp"),
4305 Vsource_directory); 4280 Vsource_directory);
4306 4281
4307 if (NILP (Fmember (tem, Vload_path))) 4282 if (NILP (Fmember (tem, lpath)))
4308 Vload_path = Fcons (tem, Vload_path); 4283 lpath = Fcons (tem, lpath);
4309
4310 tem = Fexpand_file_name (build_string ("leim"),
4311 Vsource_directory);
4312
4313 if (NILP (Fmember (tem, Vload_path)))
4314 Vload_path = Fcons (tem, Vload_path);
4315 4284
4316 if (!no_site_lisp) 4285 if (!no_site_lisp)
4317 { 4286 {
@@ -4320,47 +4289,113 @@ init_lread (void)
4320 tem1 = Ffile_accessible_directory_p (tem); 4289 tem1 = Ffile_accessible_directory_p (tem);
4321 if (!NILP (tem1)) 4290 if (!NILP (tem1))
4322 { 4291 {
4323 if (NILP (Fmember (tem, Vload_path))) 4292 if (NILP (Fmember (tem, lpath)))
4324 Vload_path = Fcons (tem, Vload_path); 4293 lpath = Fcons (tem, lpath);
4325 } 4294 }
4326 } 4295 }
4327 } 4296 }
4328 } /* Vinstallation_directory != Vsource_directory */ 4297 } /* Vinstallation_directory != Vsource_directory */
4329 4298
4330 } /* if Vinstallation_directory */ 4299 } /* if Vinstallation_directory */
4331 4300
4332 /* Check before adding the site-lisp directories. 4301 } /* if dump_path == Vload_path */
4333 The install should have created them, but they are not
4334 required, so no need to warn if they are absent.
4335 Or we might be running before installation. */
4336 load_path_check ();
4337
4338 /* Add the site-lisp directories at the front. */
4339 if (!no_site_lisp)
4340 {
4341 Lisp_Object sitelisp;
4342 sitelisp = decode_env_path (0, PATH_SITELOADSEARCH);
4343 if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path);
4344 }
4345 } /* if dump_path == Vload_path */
4346 } 4302 }
4347 else /* !initialized */ 4303 else /* !initialized */
4348 { 4304 {
4349 /* NORMAL refers to PATH_DUMPLOADSEARCH, ie the lisp dir in the 4305 /* NORMAL refers to PATH_DUMPLOADSEARCH, ie the lisp dir in the
4350 source directory. We used to add ../lisp (ie the lisp dir in 4306 source directory. We used to add ../lisp (ie the lisp dir in
4351 the build directory) at the front here, but that caused trouble 4307 the build directory) at the front here, but that caused trouble
4352 because it was copied from dump_path into Vload_path, above, 4308 because it was copied from dump_path into Vload_path, above,
4353 when Vinstallation_directory was non-nil. It should not be 4309 when Vinstallation_directory was non-nil. It should not be
4354 necessary, since in out of tree builds lisp/ is empty, save 4310 necessary, since in out of tree builds lisp/ is empty, save
4355 for Makefile. */ 4311 for Makefile. */
4356 Vload_path = decode_env_path (0, normal); 4312 lpath = decode_env_path (0, normal, 0);
4357 dump_path = Vload_path; 4313 dump_path = lpath;
4358 /* No point calling load_path_check; load-path only contains essential
4359 elements from the source directory at this point. They cannot
4360 be missing unless something went extremely (and improbably)
4361 wrong, in which case the build will fail in obvious ways. */
4362 } 4314 }
4363#endif /* !CANNOT_DUMP */ 4315#endif /* !CANNOT_DUMP */
4316
4317 return lpath;
4318}
4319
4320void
4321init_lread (void)
4322{
4323 /* First, set Vload_path. */
4324
4325 /* NB: Do not change Vload_path before calling load_path_default,
4326 since it may check it against dump_path.
4327 (This behavior could be changed.) */
4328
4329 /* We explicitly ignore EMACSLOADPATH when dumping. */
4330 if (NILP (Vpurify_flag) && egetenv ("EMACSLOADPATH"))
4331 {
4332 Lisp_Object elpath = decode_env_path ("EMACSLOADPATH", 0, 1);
4333
4334 /* Check (non-nil) user-supplied elements. */
4335 load_path_check (elpath);
4336
4337 /* If no nils in the environment variable, use as-is.
4338 Otherwise, replace any nils with the default. */
4339 if (NILP (Fmemq (Qnil, elpath)))
4340 {
4341 Vload_path = elpath;
4342 }
4343 else
4344 {
4345 Lisp_Object elem, default_lpath = load_path_default (0);
4346
4347 /* Check defaults, before adding site-lisp. */
4348 load_path_check (default_lpath);
4349
4350 /* Add the site-lisp directories to the front of the default. */
4351 if (!no_site_lisp)
4352 {
4353 Lisp_Object sitelisp;
4354 sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
4355 if (! NILP (sitelisp))
4356 default_lpath = nconc2 (sitelisp, default_lpath);
4357 }
4358
4359 Vload_path = Qnil;
4360
4361 /* Replace nils from EMACSLOADPATH by default. */
4362 while (CONSP (elpath))
4363 {
4364 Lisp_Object arg[2];
4365 elem = XCAR (elpath);
4366 elpath = XCDR (elpath);
4367 arg[0] = Vload_path;
4368 arg[1] = NILP (elem) ? default_lpath : Fcons (elem, Qnil);
4369 Vload_path = Fappend (2, arg);
4370 }
4371 } /* Fmemq (Qnil, Vload_path) */
4372 }
4373 else /* Vpurify_flag || !EMACSLOADPATH */
4374 {
4375#ifdef CANNOT_DUMP
4376 bool changed = 0;
4377#else
4378 bool changed = initialized && NILP (Fequal (dump_path, Vload_path));
4379#endif
4380
4381 Vload_path = load_path_default (changed);
4382
4383 /* Check before adding site-lisp directories.
4384 The install should have created them, but they are not
4385 required, so no need to warn if they are absent.
4386 Or we might be running before installation. */
4387 load_path_check (Vload_path);
4388
4389 /* Add the site-lisp directories at the front, unless the
4390 load-path has already been changed.
4391 FIXME? Should we ignore changed here? */
4392 if (initialized && !no_site_lisp && !changed)
4393 {
4394 Lisp_Object sitelisp;
4395 sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
4396 if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path);
4397 }
4398 } /* !Vpurify_flag && EMACSLOADPATH */
4364 4399
4365 Vvalues = Qnil; 4400 Vvalues = Qnil;
4366 4401
@@ -4467,9 +4502,8 @@ were read in. */);
4467 4502
4468 DEFVAR_LISP ("load-path", Vload_path, 4503 DEFVAR_LISP ("load-path", Vload_path,
4469 doc: /* List of directories to search for files to load. 4504 doc: /* List of directories to search for files to load.
4470Each element is a string (directory name) or nil (try default directory). 4505Each element is a string (directory name) or nil (meaning `default-directory').
4471Initialized based on EMACSLOADPATH environment variable, if any, 4506Initialized during startup as described in Info node `(elisp)Library Search'. */);
4472otherwise to default specified by file `epaths.h' when Emacs was built. */);
4473 4507
4474 DEFVAR_LISP ("load-suffixes", Vload_suffixes, 4508 DEFVAR_LISP ("load-suffixes", Vload_suffixes,
4475 doc: /* List of suffixes for (compiled or source) Emacs Lisp files. 4509 doc: /* List of suffixes for (compiled or source) Emacs Lisp files.
@@ -4585,7 +4619,7 @@ and is not meant for users to change. */);
4585You cannot count on them to still be there! */); 4619You cannot count on them to still be there! */);
4586 Vsource_directory 4620 Vsource_directory
4587 = Fexpand_file_name (build_string ("../"), 4621 = Fexpand_file_name (build_string ("../"),
4588 Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH))); 4622 Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH, 0)));
4589 4623
4590 DEFVAR_LISP ("preloaded-file-list", Vpreloaded_file_list, 4624 DEFVAR_LISP ("preloaded-file-list", Vpreloaded_file_list,
4591 doc: /* List of files that were preloaded (when dumping Emacs). */); 4625 doc: /* List of files that were preloaded (when dumping Emacs). */);
diff --git a/src/menu.c b/src/menu.c
index 96b8f73824a..e33c647d020 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1178,7 +1178,6 @@ no quit occurs and `x-popup-menu' returns nil. */)
1178 keybinding equivalents, but we don't do that any more anyway. */ 1178 keybinding equivalents, but we don't do that any more anyway. */
1179 return Qnil; 1179 return Qnil;
1180 1180
1181#ifdef HAVE_MENUS
1182 { 1181 {
1183 bool get_current_pos_p = 0; 1182 bool get_current_pos_p = 0;
1184 1183
@@ -1315,7 +1314,6 @@ no quit occurs and `x-popup-menu' returns nil. */)
1315 1314
1316 XSETFRAME (Vmenu_updating_frame, f); 1315 XSETFRAME (Vmenu_updating_frame, f);
1317 } 1316 }
1318#endif /* HAVE_MENUS */
1319 1317
1320 /* Now parse the lisp menus. */ 1318 /* Now parse the lisp menus. */
1321 record_unwind_protect_void (unuse_menu_items); 1319 record_unwind_protect_void (unuse_menu_items);
@@ -1398,7 +1396,6 @@ no quit occurs and `x-popup-menu' returns nil. */)
1398 1396
1399 unbind_to (specpdl_count, Qnil); 1397 unbind_to (specpdl_count, Qnil);
1400 1398
1401#ifdef HAVE_MENUS
1402#ifdef HAVE_WINDOW_SYSTEM 1399#ifdef HAVE_WINDOW_SYSTEM
1403 /* Hide a previous tip, if any. */ 1400 /* Hide a previous tip, if any. */
1404 if (!FRAME_TERMCAP_P (f)) 1401 if (!FRAME_TERMCAP_P (f))
@@ -1460,16 +1457,12 @@ no quit occurs and `x-popup-menu' returns nil. */)
1460 FRAME_DISPLAY_INFO (f)->grabbed = 0; 1457 FRAME_DISPLAY_INFO (f)->grabbed = 0;
1461#endif 1458#endif
1462 1459
1463#endif /* HAVE_MENUS */
1464
1465 UNGCPRO; 1460 UNGCPRO;
1466 1461
1467 if (error_name) error ("%s", error_name); 1462 if (error_name) error ("%s", error_name);
1468 return selection; 1463 return selection;
1469} 1464}
1470 1465
1471#ifdef HAVE_MENUS
1472
1473DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, 1466DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
1474 doc: /* Pop up a dialog box and return user's selection. 1467 doc: /* Pop up a dialog box and return user's selection.
1475POSITION specifies which frame to use. 1468POSITION specifies which frame to use.
@@ -1605,8 +1598,6 @@ for instance using the window manager, then this produces a quit and
1605 } 1598 }
1606} 1599}
1607 1600
1608#endif /* HAVE_MENUS */
1609
1610void 1601void
1611syms_of_menu (void) 1602syms_of_menu (void)
1612{ 1603{
@@ -1615,9 +1606,6 @@ syms_of_menu (void)
1615 menu_items_inuse = Qnil; 1606 menu_items_inuse = Qnil;
1616 1607
1617 defsubr (&Sx_popup_menu); 1608 defsubr (&Sx_popup_menu);
1618
1619#ifdef HAVE_MENUS
1620 defsubr (&Sx_popup_dialog); 1609 defsubr (&Sx_popup_dialog);
1621#endif
1622 defsubr (&Smenu_bar_menu_at_x_y); 1610 defsubr (&Smenu_bar_menu_at_x_y);
1623} 1611}
diff --git a/src/minibuf.c b/src/minibuf.c
index 8eb1a2890e0..c8ae8eae2a4 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -865,9 +865,6 @@ read_minibuf_unwind (void)
865 if (minibuf_level == 0) 865 if (minibuf_level == 0)
866 resize_mini_window (XWINDOW (window), 0); 866 resize_mini_window (XWINDOW (window), 0);
867 867
868 /* Enforce full redisplay. FIXME: make it more selective. */
869 windows_or_buffers_changed = 22;
870
871 /* In case the previous minibuffer displayed in this miniwindow is 868 /* In case the previous minibuffer displayed in this miniwindow is
872 dead, we may keep displaying this buffer (tho it's inactive), so reset it, 869 dead, we may keep displaying this buffer (tho it's inactive), so reset it,
873 to make sure we don't leave around bindings and stuff which only 870 to make sure we don't leave around bindings and stuff which only
diff --git a/src/nsfns.m b/src/nsfns.m
index ee6020f2b43..8f14915ea65 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -703,7 +703,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
703 } 703 }
704 } 704 }
705 705
706 x_set_window_size (f, 0, f->text_cols, f->text_lines); 706 x_set_window_size (f, 0, f->text_cols, f->text_lines, 0);
707} 707}
708 708
709 709
@@ -946,6 +946,8 @@ frame_parm_handler ns_frame_parm_handlers[] =
946 x_set_icon_name, 946 x_set_icon_name,
947 x_set_icon_type, 947 x_set_icon_type,
948 x_set_internal_border_width, /* generic OK */ 948 x_set_internal_border_width, /* generic OK */
949 0, /* x_set_right_divider_width */
950 0, /* x_set_bottom_divider_width */
949 x_set_menu_bar_lines, 951 x_set_menu_bar_lines,
950 x_set_mouse_color, 952 x_set_mouse_color,
951 x_explicitly_set_name, 953 x_explicitly_set_name,
@@ -1235,6 +1237,13 @@ This function is an internal primitive--use `make-frame' instead. */)
1235 1237
1236 init_frame_faces (f); 1238 init_frame_faces (f);
1237 1239
1240 /* Read comment about this code in corresponding place in xfns.c. */
1241 width = FRAME_TEXT_WIDTH (f);
1242 height = FRAME_TEXT_HEIGHT (f);
1243 FRAME_TEXT_HEIGHT (f) = 0;
1244 SET_FRAME_WIDTH (f, 0);
1245 change_frame_size (f, width, height, 1, 0, 0, 1);
1246
1238 /* The resources controlling the menu-bar and tool-bar are 1247 /* The resources controlling the menu-bar and tool-bar are
1239 processed specially at startup, and reflected in the mode 1248 processed specially at startup, and reflected in the mode
1240 variables; ignore them here. */ 1249 variables; ignore them here. */
@@ -1266,6 +1275,7 @@ This function is an internal primitive--use `make-frame' instead. */)
1266 f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor]; 1275 f->output_data.ns->hand_cursor = [NSCursor pointingHandCursor];
1267 f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor]; 1276 f->output_data.ns->hourglass_cursor = [NSCursor disappearingItemCursor];
1268 f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor]; 1277 f->output_data.ns->horizontal_drag_cursor = [NSCursor resizeLeftRightCursor];
1278 f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor];
1269 FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor 1279 FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
1270 = [NSCursor arrowCursor]; 1280 = [NSCursor arrowCursor];
1271 f->output_data.ns->current_pointer = f->output_data.ns->text_cursor; 1281 f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
@@ -1298,12 +1308,11 @@ This function is an internal primitive--use `make-frame' instead. */)
1298 x_default_parameter (f, parms, Qfullscreen, Qnil, 1308 x_default_parameter (f, parms, Qfullscreen, Qnil,
1299 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); 1309 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
1300 1310
1301 width = FRAME_COLS (f); 1311 width = FRAME_TEXT_WIDTH (f);
1302 height = FRAME_LINES (f); 1312 height = FRAME_TEXT_HEIGHT (f);
1303 1313 FRAME_TEXT_HEIGHT (f) = 0;
1304 SET_FRAME_COLS (f, 0); 1314 SET_FRAME_WIDTH (f, 0);
1305 FRAME_LINES (f) = 0; 1315 change_frame_size (f, width, height, 1, 0, 0, 1);
1306 change_frame_size (f, height, width, 1, 0, 0);
1307 1316
1308 if (! f->output_data.ns->explicit_parent) 1317 if (! f->output_data.ns->explicit_parent)
1309 { 1318 {
diff --git a/src/nsfont.m b/src/nsfont.m
index 58663804a2f..0f546408316 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -829,7 +829,6 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
829 font->vertical_centering = 0; 829 font->vertical_centering = 0;
830 font->baseline_offset = 0; 830 font->baseline_offset = 0;
831 font->relative_compose = 0; 831 font->relative_compose = 0;
832 font->font_encoder = NULL;
833 832
834 font->props[FONT_FORMAT_INDEX] = Qns; 833 font->props[FONT_FORMAT_INDEX] = Qns;
835 font->props[FONT_FILE_INDEX] = Qnil; 834 font->props[FONT_FILE_INDEX] = Qnil;
diff --git a/src/nsterm.h b/src/nsterm.h
index 22a8aec9436..976347ad3b4 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -654,6 +654,7 @@ struct ns_output
654 Cursor hand_cursor; 654 Cursor hand_cursor;
655 Cursor hourglass_cursor; 655 Cursor hourglass_cursor;
656 Cursor horizontal_drag_cursor; 656 Cursor horizontal_drag_cursor;
657 Cursor vertical_drag_cursor;
657 658
658 /* NS-specific */ 659 /* NS-specific */
659 Cursor current_pointer; 660 Cursor current_pointer;
@@ -719,11 +720,6 @@ struct x_output
719#define FRAME_NS_TITLEBAR_HEIGHT(f) ((f)->output_data.ns->titlebar_height) 720#define FRAME_NS_TITLEBAR_HEIGHT(f) ((f)->output_data.ns->titlebar_height)
720#define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.ns->toolbar_height) 721#define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.ns->toolbar_height)
721 722
722#define FONT_WIDTH(f) ((f)->max_width)
723#define FONT_HEIGHT(f) ((f)->height)
724#define FONT_BASE(f) ((f)->ascent)
725#define FONT_DESCENT(f) ((f)->descent)
726
727#define FRAME_DEFAULT_FACE(f) FACE_FROM_ID (f, DEFAULT_FACE_ID) 723#define FRAME_DEFAULT_FACE(f) FACE_FROM_ID (f, DEFAULT_FACE_ID)
728 724
729#define FRAME_NS_VIEW(f) ((f)->output_data.ns->view) 725#define FRAME_NS_VIEW(f) ((f)->output_data.ns->view)
diff --git a/src/nsterm.m b/src/nsterm.m
index 0e7667b6dc6..37edfb238a9 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1,7 +1,7 @@
1/* NeXT/Open/GNUstep / MacOSX communication module. 1/* NeXT/Open/GNUstep / MacOSX communication module.
2 2
3Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013 Free Software 3Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013
4Foundation, Inc. 4 Free Software Foundation, Inc.
5 5
6This file is part of GNU Emacs. 6This file is part of GNU Emacs.
7 7
@@ -445,8 +445,8 @@ ns_exec_path (void)
445const char * 445const char *
446ns_load_path (void) 446ns_load_path (void)
447/* If running as a self-contained app bundle, return as a path string 447/* If running as a self-contained app bundle, return as a path string
448 the filenames of the site-lisp, lisp and leim directories. 448 the filenames of the site-lisp and lisp directories.
449 Ie, site-lisp:lisp:leim. Otherwise, return nil. */ 449 Ie, site-lisp:lisp. Otherwise, return nil. */
450{ 450{
451 NSBundle *bundle = [NSBundle mainBundle]; 451 NSBundle *bundle = [NSBundle mainBundle];
452 NSString *resourceDir = [bundle resourcePath]; 452 NSString *resourceDir = [bundle resourcePath];
@@ -456,7 +456,7 @@ ns_load_path (void)
456 BOOL isDir; 456 BOOL isDir;
457 NSArray *paths = [resourceDir stringsByAppendingPaths: 457 NSArray *paths = [resourceDir stringsByAppendingPaths:
458 [NSArray arrayWithObjects: 458 [NSArray arrayWithObjects:
459 @"site-lisp", @"lisp", @"leim", nil]]; 459 @"site-lisp", @"lisp", nil]];
460 NSEnumerator *pathEnum = [paths objectEnumerator]; 460 NSEnumerator *pathEnum = [paths objectEnumerator];
461 resourcePaths = @""; 461 resourcePaths = @"";
462 462
@@ -771,7 +771,12 @@ ns_update_window_end (struct window *w, bool cursor_on_p,
771 w->output_cursor.x, w->output_cursor.y); 771 w->output_cursor.x, w->output_cursor.y);
772 772
773 if (draw_window_fringes (w, 1)) 773 if (draw_window_fringes (w, 1))
774 x_draw_vertical_border (w); 774 {
775 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
776 x_draw_right_divider (w);
777 else
778 x_draw_vertical_border (w);
779 }
775 780
776 unblock_input (); 781 unblock_input ();
777 } 782 }
@@ -1235,7 +1240,11 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
1235 1240
1236 1241
1237void 1242void
1238x_set_window_size (struct frame *f, int change_grav, int cols, int rows) 1243x_set_window_size (struct frame *f,
1244 int change_grav,
1245 int width,
1246 int height,
1247 bool pixelwise)
1239/* -------------------------------------------------------------------------- 1248/* --------------------------------------------------------------------------
1240 Adjust window pixel size based on given character grid size 1249 Adjust window pixel size based on given character grid size
1241 Impl is a bit more complex than other terms, need to do some 1250 Impl is a bit more complex than other terms, need to do some
@@ -1247,23 +1256,36 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
1247 NSRect wr = [window frame]; 1256 NSRect wr = [window frame];
1248 int tb = FRAME_EXTERNAL_TOOL_BAR (f); 1257 int tb = FRAME_EXTERNAL_TOOL_BAR (f);
1249 int pixelwidth, pixelheight; 1258 int pixelwidth, pixelheight;
1259 int rows, cols;
1250 1260
1251 NSTRACE (x_set_window_size); 1261 NSTRACE (x_set_window_size);
1252 1262
1253 if (view == nil) 1263 if (view == nil)
1254 return; 1264 return;
1255 1265
1256/*fprintf (stderr, "\tsetWindowSize: %d x %d, font size %d x %d\n", cols, rows, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f)); */ 1266/*fprintf (stderr, "\tsetWindowSize: %d x %d, pixelwise %d, font size %d x %d\n", width, height, pixelwise, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f));*/
1257 1267
1258 block_input (); 1268 block_input ();
1259 1269
1260 check_frame_size (f, &rows, &cols); 1270 check_frame_size (f, &width, &height, pixelwise);
1261 1271
1262 f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f); 1272 f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f);
1263 compute_fringe_widths (f, 0); 1273 compute_fringe_widths (f, 0);
1264 1274
1265 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); 1275 if (pixelwise)
1266 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); 1276 {
1277 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
1278 pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
1279 cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
1280 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
1281 }
1282 else
1283 {
1284 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
1285 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
1286 cols = width;
1287 rows = height;
1288 }
1267 1289
1268 /* If we have a toolbar, take its height into account. */ 1290 /* If we have a toolbar, take its height into account. */
1269 if (tb && ! [view isFullscreen]) 1291 if (tb && ! [view isFullscreen])
@@ -1298,7 +1320,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
1298 [view setRows: rows andColumns: cols]; 1320 [view setRows: rows andColumns: cols];
1299 [window setFrame: wr display: YES]; 1321 [window setFrame: wr display: YES];
1300 1322
1301/*fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight); */ 1323 fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight);
1302 1324
1303 /* This is a trick to compensate for Emacs' managing the scrollbar area 1325 /* This is a trick to compensate for Emacs' managing the scrollbar area
1304 as a fixed number of standard character columns. Instead of leaving 1326 as a fixed number of standard character columns. Instead of leaving
@@ -1316,9 +1338,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
1316 [view setBoundsOrigin: origin]; 1338 [view setBoundsOrigin: origin];
1317 } 1339 }
1318 1340
1319 change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */ 1341 change_frame_size (f, width, height, 0, 1, 0, pixelwise);
1320 FRAME_PIXEL_WIDTH (f) = pixelwidth;
1321 FRAME_PIXEL_HEIGHT (f) = pixelheight;
1322/* SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */ 1342/* SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */
1323 1343
1324 mark_window_cursors_off (XWINDOW (f->root_window)); 1344 mark_window_cursors_off (XWINDOW (f->root_window));
@@ -1385,7 +1405,7 @@ ns_index_color (NSColor *color, struct frame *f)
1385 color_table->empty_indices = [[NSMutableSet alloc] init]; 1405 color_table->empty_indices = [[NSMutableSet alloc] init];
1386 } 1406 }
1387 1407
1388 /* do we already have this color ? */ 1408 /* Do we already have this color? */
1389 for (i = 1; i < color_table->avail; i++) 1409 for (i = 1; i < color_table->avail; i++)
1390 if (color_table->colors[i] && [color_table->colors[i] isEqual: color]) 1410 if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
1391 return i; 1411 return i;
@@ -2504,6 +2524,28 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
2504} 2524}
2505 2525
2506 2526
2527static void
2528ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
2529/* --------------------------------------------------------------------------
2530 External (RIF): Draw a window divider.
2531 -------------------------------------------------------------------------- */
2532{
2533 struct frame *f = XFRAME (WINDOW_FRAME (w));
2534 struct face *face;
2535 NSRect r = NSMakeRect (x0, y0, x1-x0, y1-y0);
2536
2537 NSTRACE (ns_draw_window_divider);
2538
2539 face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
2540 if (face)
2541 [ns_lookup_indexed_color(face->foreground, f) set];
2542
2543 ns_focus (f, &r, 1);
2544 NSRectFill(r);
2545 ns_unfocus (f);
2546}
2547
2548
2507void 2549void
2508show_hourglass (struct atimer *timer) 2550show_hourglass (struct atimer *timer)
2509{ 2551{
@@ -4017,6 +4059,7 @@ static struct redisplay_interface ns_redisplay_interface =
4017 ns_clear_frame_area, 4059 ns_clear_frame_area,
4018 ns_draw_window_cursor, 4060 ns_draw_window_cursor,
4019 ns_draw_vertical_window_border, 4061 ns_draw_vertical_window_border,
4062 ns_draw_window_divider,
4020 ns_shift_glyphs_for_insert 4063 ns_shift_glyphs_for_insert
4021}; 4064};
4022 4065
@@ -4385,7 +4428,7 @@ ns_term_shutdown (int sig)
4385 4428
4386 shouldKeepRunning = YES; 4429 shouldKeepRunning = YES;
4387 do 4430 do
4388 { 4431 {
4389 [pool release]; 4432 [pool release];
4390 pool = [[NSAutoreleasePool alloc] init]; 4433 pool = [[NSAutoreleasePool alloc] init];
4391 4434
@@ -4404,6 +4447,9 @@ ns_term_shutdown (int sig)
4404- (void)stop: (id)sender 4447- (void)stop: (id)sender
4405{ 4448{
4406 shouldKeepRunning = NO; 4449 shouldKeepRunning = NO;
4450 // Stop possible dialog also. Noop if no dialog present.
4451 // The file dialog still leaks 7k - 10k on 10.9 though.
4452 [super stop:sender];
4407} 4453}
4408#endif 4454#endif
4409 4455
@@ -5617,44 +5663,39 @@ not_in_argv (NSString *arg)
5617 NSWindow *window = [self window]; 5663 NSWindow *window = [self window];
5618 NSRect wr = [window frame]; 5664 NSRect wr = [window frame];
5619 int extra = 0; 5665 int extra = 0;
5620 int gsextra = 0;
5621#ifdef NS_IMPL_GNUSTEP
5622 gsextra = 3;
5623#endif
5624
5625 int oldc = cols, oldr = rows; 5666 int oldc = cols, oldr = rows;
5626 int oldw = FRAME_PIXEL_WIDTH (emacsframe), 5667 int oldw = FRAME_PIXEL_WIDTH (emacsframe),
5627 oldh = FRAME_PIXEL_HEIGHT (emacsframe); 5668 oldh = FRAME_PIXEL_HEIGHT (emacsframe);
5628 int neww, newh; 5669 int neww, newh;
5629 5670
5630 cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, wr.size.width + gsextra);
5631
5632 if (cols < MINWIDTH)
5633 cols = MINWIDTH;
5634
5635 if (! [self isFullscreen]) 5671 if (! [self isFullscreen])
5636 { 5672 {
5637 extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) 5673 extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
5638 + FRAME_TOOLBAR_HEIGHT (emacsframe) - gsextra; 5674 + FRAME_TOOLBAR_HEIGHT (emacsframe);
5639 } 5675 }
5640 5676
5641 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, wr.size.height - extra); 5677 neww = (int)wr.size.width - emacsframe->border_width;
5678 newh = (int)wr.size.height - extra;
5679
5680 cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww);
5681 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh);
5682
5683 if (cols < MINWIDTH)
5684 cols = MINWIDTH;
5642 5685
5643 if (rows < MINHEIGHT) 5686 if (rows < MINHEIGHT)
5644 rows = MINHEIGHT; 5687 rows = MINHEIGHT;
5645 5688
5646 neww = (int)wr.size.width - emacsframe->border_width;
5647 newh = (int)wr.size.height - extra;
5648
5649 if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) 5689 if (oldr != rows || oldc != cols || neww != oldw || newh != oldh)
5650 { 5690 {
5651 NSView *view = FRAME_NS_VIEW (emacsframe); 5691 NSView *view = FRAME_NS_VIEW (emacsframe);
5652 NSWindow *win = [view window]; 5692 NSWindow *win = [view window];
5653 NSSize sz = [win resizeIncrements]; 5693 NSSize sz = [win resizeIncrements];
5654 5694
5655 FRAME_PIXEL_WIDTH (emacsframe) = neww; 5695 change_frame_size (emacsframe,
5656 FRAME_PIXEL_HEIGHT (emacsframe) = newh; 5696 FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww),
5657 change_frame_size (emacsframe, rows, cols, 0, delay, 0); 5697 FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh),
5698 0, delay, 0, 1);
5658 SET_FRAME_GARBAGED (emacsframe); 5699 SET_FRAME_GARBAGED (emacsframe);
5659 cancel_mouse_face (emacsframe); 5700 cancel_mouse_face (emacsframe);
5660 5701
@@ -5676,10 +5717,6 @@ not_in_argv (NSString *arg)
5676/* normalize frame to gridded text size */ 5717/* normalize frame to gridded text size */
5677{ 5718{
5678 int extra = 0; 5719 int extra = 0;
5679 int gsextra = 0;
5680#ifdef NS_IMPL_GNUSTEP
5681 gsextra = 3;
5682#endif
5683 5720
5684 NSTRACE (windowWillResize); 5721 NSTRACE (windowWillResize);
5685/*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */ 5722/*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */
@@ -5697,8 +5734,13 @@ not_in_argv (NSString *arg)
5697 if (fs_state == FULLSCREEN_NONE) 5734 if (fs_state == FULLSCREEN_NONE)
5698 maximized_width = maximized_height = -1; 5735 maximized_width = maximized_height = -1;
5699 5736
5700 cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, 5737 if (! [self isFullscreen])
5701 frameSize.width + gsextra); 5738 {
5739 extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
5740 + FRAME_TOOLBAR_HEIGHT (emacsframe);
5741 }
5742
5743 cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, frameSize.width);
5702 if (cols < MINWIDTH) 5744 if (cols < MINWIDTH)
5703 cols = MINWIDTH; 5745 cols = MINWIDTH;
5704 5746
@@ -7294,6 +7336,7 @@ Lisp_Object
7294x_new_font (struct frame *f, Lisp_Object font_object, int fontset) 7336x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7295{ 7337{
7296 struct font *font = XFONT_OBJECT (font_object); 7338 struct font *font = XFONT_OBJECT (font_object);
7339 EmacsView *view = FRAME_NS_VIEW (f);
7297 7340
7298 if (fontset < 0) 7341 if (fontset < 0)
7299 fontset = fontset_from_font (font_object); 7342 fontset = fontset_from_font (font_object);
@@ -7326,8 +7369,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7326 } 7369 }
7327 7370
7328 /* Now make the frame display the given font. */ 7371 /* Now make the frame display the given font. */
7329 if (FRAME_NS_WINDOW (f) != 0) 7372 if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen])
7330 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 7373 x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
7374 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
7331 7375
7332 return font_object; 7376 return font_object;
7333} 7377}
@@ -7554,5 +7598,5 @@ baseline level. The default value is nil. */);
7554#else 7598#else
7555 Fprovide (Qgnustep, Qnil); 7599 Fprovide (Qgnustep, Qnil);
7556#endif 7600#endif
7557 7601
7558} 7602}
diff --git a/src/print.c b/src/print.c
index e3c56a6de62..6e8aec37ba5 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1119,7 +1119,7 @@ print (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1119 string (its text properties will be traced), or a symbol that has 1119 string (its text properties will be traced), or a symbol that has
1120 no obarray (this is for the print-gensym feature). 1120 no obarray (this is for the print-gensym feature).
1121 The status fields of Vprint_number_table mean whether each object appears 1121 The status fields of Vprint_number_table mean whether each object appears
1122 more than once in OBJ: Qnil at the first time, and Qt after that . */ 1122 more than once in OBJ: Qnil at the first time, and Qt after that. */
1123static void 1123static void
1124print_preprocess (Lisp_Object obj) 1124print_preprocess (Lisp_Object obj)
1125{ 1125{
@@ -1766,8 +1766,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1766 } 1766 }
1767 else if (WINDOWP (obj)) 1767 else if (WINDOWP (obj))
1768 { 1768 {
1769 void *ptr = XWINDOW (obj); 1769 int len;
1770 int len = sprintf (buf, "#<window %p", ptr); 1770 strout ("#<window ", -1, -1, printcharfun);
1771 len = sprintf (buf, "%d", XWINDOW (obj)->sequence_number);
1771 strout (buf, len, len, printcharfun); 1772 strout (buf, len, len, printcharfun);
1772 if (BUFFERP (XWINDOW (obj)->contents)) 1773 if (BUFFERP (XWINDOW (obj)->contents))
1773 { 1774 {
diff --git a/src/process.c b/src/process.c
index 307eab3ab30..7050bf9822e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1,7 +1,7 @@
1/* Asynchronous subprocess control for GNU Emacs. 1/* Asynchronous subprocess control for GNU Emacs.
2 2
3Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2013 Free Software 3Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2013
4Foundation, Inc. 4 Free Software Foundation, Inc.
5 5
6This file is part of GNU Emacs. 6This file is part of GNU Emacs.
7 7
@@ -812,13 +812,14 @@ get_process (register Lisp_Object name)
812 else 812 else
813 obj = name; 813 obj = name;
814 814
815 /* Now obj should be either a buffer object or a process object. 815 /* Now obj should be either a buffer object or a process object. */
816 */
817 if (BUFFERP (obj)) 816 if (BUFFERP (obj))
818 { 817 {
818 if (NILP (BVAR (XBUFFER (obj), name)))
819 error ("Attempt to get process for a dead buffer");
819 proc = Fget_buffer_process (obj); 820 proc = Fget_buffer_process (obj);
820 if (NILP (proc)) 821 if (NILP (proc))
821 error ("Buffer %s has no process", SDATA (BVAR (XBUFFER (obj), name))); 822 error ("Buffer %s has no process", SDATA (BVAR (XBUFFER (obj), name)));
822 } 823 }
823 else 824 else
824 { 825 {
diff --git a/src/regex.c b/src/regex.c
index 615fb3fdf34..b45dbcaada7 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -5907,7 +5907,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
5907 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5907 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5908 /* Here, we discard `const', making re_match non-reentrant. */ 5908 /* Here, we discard `const', making re_match non-reentrant. */
5909 p2 = (unsigned char*) p + mcnt; 5909 p2 = (unsigned char*) p + mcnt;
5910 /* Signedness doesn't matter since we only copy MCNT's bits . */ 5910 /* Signedness doesn't matter since we only copy MCNT's bits. */
5911 EXTRACT_NUMBER_AND_INCR (mcnt, p); 5911 EXTRACT_NUMBER_AND_INCR (mcnt, p);
5912 DEBUG_PRINT (" Setting %p to %d.\n", p2, mcnt); 5912 DEBUG_PRINT (" Setting %p to %d.\n", p2, mcnt);
5913 PUSH_NUMBER (p2, mcnt); 5913 PUSH_NUMBER (p2, mcnt);
diff --git a/src/term.c b/src/term.c
index f86d71ac2f4..4d900020ce6 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2407,7 +2407,7 @@ frame's terminal). */)
2407 was suspended. */ 2407 was suspended. */
2408 get_tty_size (fileno (t->display_info.tty->input), &width, &height); 2408 get_tty_size (fileno (t->display_info.tty->input), &width, &height);
2409 if (width != old_width || height != old_height) 2409 if (width != old_width || height != old_height)
2410 change_frame_size (f, height, width, 0, 0, 0); 2410 change_frame_size (f, width, height, 0, 0, 0, 0);
2411 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); 2411 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
2412 } 2412 }
2413 2413
@@ -2739,7 +2739,7 @@ DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop,
2739 Menus 2739 Menus
2740 ***********************************************************************/ 2740 ***********************************************************************/
2741 2741
2742#if defined (HAVE_MENUS) && !defined (MSDOS) 2742#if !defined (MSDOS)
2743 2743
2744/* TTY menu implementation and main ideas are borrowed from msdos.c. 2744/* TTY menu implementation and main ideas are borrowed from msdos.c.
2745 2745
@@ -3816,7 +3816,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
3816 return entry; 3816 return entry;
3817} 3817}
3818 3818
3819#endif /* HAVE_MENUS && !MSDOS */ 3819#endif /* !MSDOS */
3820 3820
3821 3821
3822#ifndef MSDOS 3822#ifndef MSDOS
@@ -3825,7 +3825,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
3825 ***********************************************************************/ 3825 ***********************************************************************/
3826 3826
3827/* Initialize the tty-dependent part of frame F. The frame must 3827/* Initialize the tty-dependent part of frame F. The frame must
3828 already have its device initialized. */ 3828 already have its device initialized. */
3829 3829
3830void 3830void
3831create_tty_output (struct frame *f) 3831create_tty_output (struct frame *f)
@@ -3839,7 +3839,7 @@ create_tty_output (struct frame *f)
3839 f->output_data.tty = t; 3839 f->output_data.tty = t;
3840} 3840}
3841 3841
3842/* Delete frame F's face cache, and its tty-dependent part. */ 3842/* Delete frame F's face cache, and its tty-dependent part. */
3843 3843
3844static void 3844static void
3845tty_free_frame_resources (struct frame *f) 3845tty_free_frame_resources (struct frame *f)
@@ -3854,7 +3854,7 @@ tty_free_frame_resources (struct frame *f)
3854 3854
3855#else /* MSDOS */ 3855#else /* MSDOS */
3856 3856
3857/* Delete frame F's face cache. */ 3857/* Delete frame F's face cache. */
3858 3858
3859static void 3859static void
3860tty_free_frame_resources (struct frame *f) 3860tty_free_frame_resources (struct frame *f)
diff --git a/src/textprop.c b/src/textprop.c
index b804f345047..5597a781a61 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -1819,32 +1819,30 @@ markers). If OBJECT is a string, START and END are 0-based indices into it. */
1819int 1819int
1820text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer) 1820text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer)
1821{ 1821{
1822 Lisp_Object prev_pos, front_sticky; 1822 bool ignore_previous_character;
1823 bool is_rear_sticky = 1, is_front_sticky = 0; /* defaults */ 1823 Lisp_Object prev_pos = make_number (XINT (pos) - 1);
1824 Lisp_Object front_sticky;
1825 bool is_rear_sticky = true, is_front_sticky = false; /* defaults */
1824 Lisp_Object defalt = Fassq (prop, Vtext_property_default_nonsticky); 1826 Lisp_Object defalt = Fassq (prop, Vtext_property_default_nonsticky);
1825 1827
1826 if (NILP (buffer)) 1828 if (NILP (buffer))
1827 XSETBUFFER (buffer, current_buffer); 1829 XSETBUFFER (buffer, current_buffer);
1828 1830
1829 if (CONSP (defalt) && !NILP (XCDR (defalt))) 1831 ignore_previous_character = XINT (pos) <= BUF_BEGV (XBUFFER (buffer));
1830 is_rear_sticky = 0;
1831 1832
1832 if (XINT (pos) > BUF_BEGV (XBUFFER (buffer))) 1833 if (ignore_previous_character || (CONSP (defalt) && !NILP (XCDR (defalt))))
1833 /* Consider previous character. */ 1834 is_rear_sticky = false;
1835 else
1834 { 1836 {
1835 Lisp_Object rear_non_sticky; 1837 Lisp_Object rear_non_sticky
1836 1838 = Fget_text_property (prev_pos, Qrear_nonsticky, buffer);
1837 prev_pos = make_number (XINT (pos) - 1);
1838 rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, buffer);
1839 1839
1840 if (!NILP (CONSP (rear_non_sticky) 1840 if (!NILP (CONSP (rear_non_sticky)
1841 ? Fmemq (prop, rear_non_sticky) 1841 ? Fmemq (prop, rear_non_sticky)
1842 : rear_non_sticky)) 1842 : rear_non_sticky))
1843 /* PROP is rear-non-sticky. */ 1843 /* PROP is rear-non-sticky. */
1844 is_rear_sticky = 0; 1844 is_rear_sticky = false;
1845 } 1845 }
1846 else
1847 return 0;
1848 1846
1849 /* Consider following character. */ 1847 /* Consider following character. */
1850 /* This signals an arg-out-of-range error if pos is outside the 1848 /* This signals an arg-out-of-range error if pos is outside the
@@ -1855,7 +1853,7 @@ text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer)
1855 || (CONSP (front_sticky) 1853 || (CONSP (front_sticky)
1856 && !NILP (Fmemq (prop, front_sticky)))) 1854 && !NILP (Fmemq (prop, front_sticky))))
1857 /* PROP is inherited from after. */ 1855 /* PROP is inherited from after. */
1858 is_front_sticky = 1; 1856 is_front_sticky = true;
1859 1857
1860 /* Simple cases, where the properties are consistent. */ 1858 /* Simple cases, where the properties are consistent. */
1861 if (is_rear_sticky && !is_front_sticky) 1859 if (is_rear_sticky && !is_front_sticky)
@@ -1869,7 +1867,7 @@ text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer)
1869 disambiguate. Basically, rear-sticky wins, _except_ if the 1867 disambiguate. Basically, rear-sticky wins, _except_ if the
1870 property that would be inherited has a value of nil, in which case 1868 property that would be inherited has a value of nil, in which case
1871 front-sticky wins. */ 1869 front-sticky wins. */
1872 if (XINT (pos) == BUF_BEGV (XBUFFER (buffer)) 1870 if (ignore_previous_character
1873 || NILP (Fget_text_property (prev_pos, prop, buffer))) 1871 || NILP (Fget_text_property (prev_pos, prop, buffer)))
1874 return 1; 1872 return 1;
1875 else 1873 else
diff --git a/src/tparam.c b/src/tparam.c
index c3ecfb9e3a3..e97544d9234 100644
--- a/src/tparam.c
+++ b/src/tparam.c
@@ -79,7 +79,7 @@ tparam1 (const char *string, char *outstring, int len,
79 register int tem; 79 register int tem;
80 int *old_argp = argp; /* can move */ 80 int *old_argp = argp; /* can move */
81 int *fixed_argp = argp; /* never moves */ 81 int *fixed_argp = argp; /* never moves */
82 int explicit_param_p = 0; /* set by %p */ 82 bool explicit_param_p = 0; /* set by %p */
83 ptrdiff_t doleft = 0; 83 ptrdiff_t doleft = 0;
84 ptrdiff_t doup = 0; 84 ptrdiff_t doup = 0;
85 ptrdiff_t append_len = 0; 85 ptrdiff_t append_len = 0;
diff --git a/src/undo.c b/src/undo.c
index 234b8510f0a..88cca102b6d 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -55,7 +55,7 @@ static Lisp_Object pending_boundary;
55static void 55static void
56record_point (ptrdiff_t pt) 56record_point (ptrdiff_t pt)
57{ 57{
58 int at_boundary; 58 bool at_boundary;
59 59
60 /* Don't record position of pt when undo_inhibit_record_point holds. */ 60 /* Don't record position of pt when undo_inhibit_record_point holds. */
61 if (undo_inhibit_record_point) 61 if (undo_inhibit_record_point)
@@ -77,7 +77,7 @@ record_point (ptrdiff_t pt)
77 77
78 if (CONSP (BVAR (current_buffer, undo_list))) 78 if (CONSP (BVAR (current_buffer, undo_list)))
79 { 79 {
80 /* Set AT_BOUNDARY to 1 only when we have nothing other than 80 /* Set AT_BOUNDARY only when we have nothing other than
81 marker adjustment before undo boundary. */ 81 marker adjustment before undo boundary. */
82 82
83 Lisp_Object tail = BVAR (current_buffer, undo_list), elt; 83 Lisp_Object tail = BVAR (current_buffer, undo_list), elt;
@@ -244,7 +244,7 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length,
244{ 244{
245 Lisp_Object lbeg, lend, entry; 245 Lisp_Object lbeg, lend, entry;
246 struct buffer *obuf = current_buffer, *buf = XBUFFER (buffer); 246 struct buffer *obuf = current_buffer, *buf = XBUFFER (buffer);
247 int boundary = 0; 247 bool boundary = 0;
248 248
249 if (EQ (BVAR (buf, undo_list), Qt)) 249 if (EQ (BVAR (buf, undo_list), Qt))
250 return; 250 return;
diff --git a/src/w32fns.c b/src/w32fns.c
index a4f9e320fc4..b3e6d29b973 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1384,6 +1384,17 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1384 horizontal_drag_cursor 1384 horizontal_drag_cursor
1385 = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow); 1385 = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
1386 1386
1387 if (!NILP (Vx_window_vertical_drag_shape))
1388 {
1389 CHECK_NUMBER (Vx_window_vertical_drag_shape);
1390 vertical_drag_cursor
1391 = XCreateFontCursor (FRAME_X_DISPLAY (f),
1392 XINT (Vx_window_vertical_drag_shape));
1393 }
1394 else
1395 vertical_drag_cursor
1396 = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_v_double_arrow);
1397
1387 /* Check and report errors with the above calls. */ 1398 /* Check and report errors with the above calls. */
1388 x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s"); 1399 x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
1389 x_uncatch_errors (FRAME_W32_DISPLAY (f), count); 1400 x_uncatch_errors (FRAME_W32_DISPLAY (f), count);
@@ -1624,6 +1635,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1624 nlines = 0; 1635 nlines = 0;
1625 1636
1626 FRAME_MENU_BAR_LINES (f) = 0; 1637 FRAME_MENU_BAR_LINES (f) = 0;
1638 FRAME_MENU_BAR_HEIGHT (f) = 0;
1627 if (nlines) 1639 if (nlines)
1628 FRAME_EXTERNAL_MENU_BAR (f) = 1; 1640 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1629 else 1641 else
@@ -1635,7 +1647,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1635 /* Adjust the frame size so that the client (text) dimensions 1647 /* Adjust the frame size so that the client (text) dimensions
1636 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being 1648 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
1637 set correctly. */ 1649 set correctly. */
1638 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 1650 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
1639 do_pending_window_change (0); 1651 do_pending_window_change (0);
1640 } 1652 }
1641 adjust_frame_glyphs (f); 1653 adjust_frame_glyphs (f);
@@ -1643,16 +1655,17 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1643 1655
1644 1656
1645/* Set the number of lines used for the tool bar of frame F to VALUE. 1657/* Set the number of lines used for the tool bar of frame F to VALUE.
1646 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL 1658 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL is
1647 is the old number of tool bar lines. This function changes the 1659 the old number of tool bar lines (and is unused). This function may
1648 height of all windows on frame F to match the new tool bar height. 1660 change the height of all windows on frame F to match the new tool bar
1649 The frame's height doesn't change. */ 1661 height. By design, the frame's height doesn't change (but maybe it
1662 should if we don't get enough space otherwise). */
1650 1663
1651void 1664void
1652x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) 1665x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1653{ 1666{
1654 int delta, nlines, root_height; 1667 int delta, nlines, root_height;
1655 Lisp_Object root_window; 1668 int unit = FRAME_LINE_HEIGHT (f);
1656 1669
1657 /* Treat tool bars like menu bars. */ 1670 /* Treat tool bars like menu bars. */
1658 if (FRAME_MINIBUF_ONLY_P (f)) 1671 if (FRAME_MINIBUF_ONLY_P (f))
@@ -1667,19 +1680,25 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1667 /* Make sure we redisplay all windows in this frame. */ 1680 /* Make sure we redisplay all windows in this frame. */
1668 windows_or_buffers_changed = 23; 1681 windows_or_buffers_changed = 23;
1669 1682
1670 delta = nlines - FRAME_TOOL_BAR_LINES (f); 1683 /* DELTA is in pixels now. */
1684 delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
1671 1685
1672 /* Don't resize the tool-bar to more than we have room for. */ 1686 /* Don't resize the tool-bar to more than we have room for. FIXME:
1673 root_window = FRAME_ROOT_WINDOW (f); 1687 This must use window_sizable eventually !!!!!!!!!!!! */
1674 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window)); 1688 if (delta > 0)
1675 if (root_height - delta < 1)
1676 { 1689 {
1677 delta = root_height - 1; 1690 root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)));
1678 nlines = FRAME_TOOL_BAR_LINES (f) + delta; 1691 if (root_height - delta < unit)
1692 {
1693 delta = root_height - unit;
1694 nlines = (root_height / unit) + min (1, (root_height % unit));
1695 }
1679 } 1696 }
1680 1697
1681 FRAME_TOOL_BAR_LINES (f) = nlines; 1698 FRAME_TOOL_BAR_LINES (f) = nlines;
1682 resize_frame_windows (f, FRAME_LINES (f), 0); 1699 FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1700 ++windows_or_buffers_changed;
1701 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
1683 adjust_frame_glyphs (f); 1702 adjust_frame_glyphs (f);
1684 1703
1685 /* We also have to make sure that the internal border at the top of 1704 /* We also have to make sure that the internal border at the top of
@@ -1688,7 +1707,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1688 below the tool bar if one is displayed, but is below the menu bar 1707 below the tool bar if one is displayed, but is below the menu bar
1689 if there isn't a tool bar. The tool bar draws into the area 1708 if there isn't a tool bar. The tool bar draws into the area
1690 below the menu bar. */ 1709 below the menu bar. */
1691 if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0) 1710 if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1692 { 1711 {
1693 clear_frame (f); 1712 clear_frame (f);
1694 clear_current_matrices (f); 1713 clear_current_matrices (f);
@@ -1701,7 +1720,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1701 { 1720 {
1702 int height = FRAME_INTERNAL_BORDER_WIDTH (f); 1721 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1703 int width = FRAME_PIXEL_WIDTH (f); 1722 int width = FRAME_PIXEL_WIDTH (f);
1704 int y = nlines * FRAME_LINE_HEIGHT (f); 1723 int y = nlines * unit;
1705 1724
1706 block_input (); 1725 block_input ();
1707 { 1726 {
@@ -1949,7 +1968,7 @@ w32_createwindow (struct frame *f)
1949 SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); 1968 SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
1950 SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); 1969 SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
1951 SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); 1970 SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
1952 SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width); 1971 SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
1953 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f)); 1972 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
1954 1973
1955 /* Enable drag-n-drop. */ 1974 /* Enable drag-n-drop. */
@@ -3225,6 +3244,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3225 - WINDOW_RIGHT_MARGIN_WIDTH (w) 3244 - WINDOW_RIGHT_MARGIN_WIDTH (w)
3226 - WINDOW_RIGHT_FRINGE_WIDTH (w)); 3245 - WINDOW_RIGHT_FRINGE_WIDTH (w));
3227 form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w) 3246 form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
3247 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
3228 - w32_system_caret_mode_height); 3248 - w32_system_caret_mode_height);
3229 3249
3230 /* Punt if the window was deleted behind our back. */ 3250 /* Punt if the window was deleted behind our back. */
@@ -3774,7 +3794,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3774 3794
3775 case WM_WINDOWPOSCHANGING: 3795 case WM_WINDOWPOSCHANGING:
3776 /* Don't restrict the sizing of tip frames. */ 3796 /* Don't restrict the sizing of tip frames. */
3777 if (hwnd == tip_window) 3797 if (frame_resize_pixelwise || hwnd == tip_window)
3778 return 0; 3798 return 0;
3779 3799
3780 /* Don't restrict the sizing of fullscreened frames, allowing them to be 3800 /* Don't restrict the sizing of fullscreened frames, allowing them to be
@@ -4453,6 +4473,10 @@ This function is an internal primitive--use `make-frame' instead. */)
4453 /* Default internalBorderWidth to 0 on Windows to match other programs. */ 4473 /* Default internalBorderWidth to 0 on Windows to match other programs. */
4454 x_default_parameter (f, parameters, Qinternal_border_width, make_number (0), 4474 x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
4455 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER); 4475 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
4476 x_default_parameter (f, parameters, Qright_divider_width, make_number (0),
4477 NULL, NULL, RES_TYPE_NUMBER);
4478 x_default_parameter (f, parameters, Qbottom_divider_width, make_number (0),
4479 NULL, NULL, RES_TYPE_NUMBER);
4456 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright, 4480 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
4457 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL); 4481 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
4458 4482
@@ -4482,6 +4506,20 @@ This function is an internal primitive--use `make-frame' instead. */)
4482 happen. */ 4506 happen. */
4483 init_frame_faces (f); 4507 init_frame_faces (f);
4484 4508
4509 /* PXW: This is a duplicate from below. We have to do it here since
4510 otherwise x_set_tool_bar_lines will work with the character sizes
4511 installed by init_frame_faces while the frame's pixel size is still
4512 calculated from a character size of 1 and we subsequently hit the
4513 eassert (height >= 0) assertion in window_box_height. The
4514 non-pixelwise code apparently worked around this because it had one
4515 frame line vs one toolbar line which left us with a zero root
4516 window height which was obviously wrong as well ... */
4517 width = FRAME_TEXT_WIDTH (f);
4518 height = FRAME_TEXT_HEIGHT (f);
4519 FRAME_TEXT_HEIGHT (f) = 0;
4520 SET_FRAME_WIDTH (f, 0);
4521 change_frame_size (f, width, height, 1, 0, 0, 1);
4522
4485 /* The X resources controlling the menu-bar and tool-bar are 4523 /* The X resources controlling the menu-bar and tool-bar are
4486 processed specially at startup, and reflected in the mode 4524 processed specially at startup, and reflected in the mode
4487 variables; ignore them here. */ 4525 variables; ignore them here. */
@@ -4510,6 +4548,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4510 f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND); 4548 f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
4511 f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT); 4549 f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
4512 f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE); 4550 f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
4551 f->output_data.w32->vertical_drag_cursor = w32_load_cursor (IDC_SIZENS);
4513 4552
4514 f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor; 4553 f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
4515 4554
@@ -4547,12 +4586,11 @@ This function is an internal primitive--use `make-frame' instead. */)
4547 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. 4586 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4548 Change will not be effected unless different from the current 4587 Change will not be effected unless different from the current
4549 FRAME_LINES (f). */ 4588 FRAME_LINES (f). */
4550 width = FRAME_COLS (f); 4589 width = FRAME_TEXT_WIDTH (f);
4551 height = FRAME_LINES (f); 4590 height = FRAME_TEXT_HEIGHT (f);
4552 4591 FRAME_TEXT_HEIGHT (f) = 0;
4553 FRAME_LINES (f) = 0; 4592 SET_FRAME_WIDTH (f, 0);
4554 SET_FRAME_COLS (f, 0); 4593 change_frame_size (f, width, height, 1, 0, 0, 1);
4555 change_frame_size (f, height, width, 1, 0, 0);
4556 4594
4557 /* Tell the server what size and position, etc, we want, and how 4595 /* Tell the server what size and position, etc, we want, and how
4558 badly we want them. This should be done after we have the menu 4596 badly we want them. This should be done after we have the menu
@@ -5690,6 +5728,10 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5690 x_default_parameter (f, parms, Qinternal_border_width, make_number (1), 5728 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
5691 "internalBorderWidth", "internalBorderWidth", 5729 "internalBorderWidth", "internalBorderWidth",
5692 RES_TYPE_NUMBER); 5730 RES_TYPE_NUMBER);
5731 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
5732 NULL, NULL, RES_TYPE_NUMBER);
5733 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
5734 NULL, NULL, RES_TYPE_NUMBER);
5693 5735
5694 /* Also do the stuff which must be set before the window exists. */ 5736 /* Also do the stuff which must be set before the window exists. */
5695 x_default_parameter (f, parms, Qforeground_color, build_string ("black"), 5737 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
@@ -5734,14 +5776,14 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5734 x_default_parameter (f, parms, Qcursor_type, Qbox, 5776 x_default_parameter (f, parms, Qcursor_type, Qbox,
5735 "cursorType", "CursorType", RES_TYPE_SYMBOL); 5777 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5736 5778
5737 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. 5779 /* Dimensions, especially FRAME_LINES (f), must be done via
5738 Change will not be effected unless different from the current 5780 change_frame_size. Change will not be effected unless different
5739 FRAME_LINES (f). */ 5781 from the current FRAME_LINES (f). */
5740 width = FRAME_COLS (f); 5782 width = FRAME_COLS (f);
5741 height = FRAME_LINES (f); 5783 height = FRAME_LINES (f);
5742 FRAME_LINES (f) = 0; 5784 FRAME_LINES (f) = 0;
5743 SET_FRAME_COLS (f, 0); 5785 SET_FRAME_COLS (f, 0);
5744 change_frame_size (f, height, width, 1, 0, 0); 5786 change_frame_size (f, width, height, 1, 0, 0, 0);
5745 5787
5746 /* Add `tooltip' frame parameter's default value. */ 5788 /* Add `tooltip' frame parameter's default value. */
5747 if (NILP (Fframe_parameter (frame, Qtooltip))) 5789 if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -5999,6 +6041,10 @@ Text larger than the specified size is clipped. */)
5999 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms); 6041 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
6000 if (NILP (Fassq (Qinternal_border_width, parms))) 6042 if (NILP (Fassq (Qinternal_border_width, parms)))
6001 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms); 6043 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
6044 if (NILP (Fassq (Qright_divider_width, parms)))
6045 parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
6046 if (NILP (Fassq (Qbottom_divider_width, parms)))
6047 parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
6002 if (NILP (Fassq (Qborder_width, parms))) 6048 if (NILP (Fassq (Qborder_width, parms)))
6003 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms); 6049 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
6004 if (NILP (Fassq (Qborder_color, parms))) 6050 if (NILP (Fassq (Qborder_color, parms)))
@@ -6020,6 +6066,8 @@ Text larger than the specified size is clipped. */)
6020 w = XWINDOW (FRAME_ROOT_WINDOW (f)); 6066 w = XWINDOW (FRAME_ROOT_WINDOW (f));
6021 w->left_col = 0; 6067 w->left_col = 0;
6022 w->top_line = 0; 6068 w->top_line = 0;
6069 w->pixel_left = 0;
6070 w->pixel_top = 0;
6023 6071
6024 if (CONSP (Vx_max_tooltip_size) 6072 if (CONSP (Vx_max_tooltip_size)
6025 && INTEGERP (XCAR (Vx_max_tooltip_size)) 6073 && INTEGERP (XCAR (Vx_max_tooltip_size))
@@ -6036,6 +6084,9 @@ Text larger than the specified size is clipped. */)
6036 w->total_lines = 40; 6084 w->total_lines = 40;
6037 } 6085 }
6038 6086
6087 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
6088 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
6089
6039 FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w); 6090 FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w);
6040 adjust_frame_glyphs (f); 6091 adjust_frame_glyphs (f);
6041 w->pseudo_window_p = 1; 6092 w->pseudo_window_p = 1;
@@ -6101,11 +6152,17 @@ Text larger than the specified size is clipped. */)
6101 width of the frame. */ 6152 width of the frame. */
6102 if (seen_reversed_p) 6153 if (seen_reversed_p)
6103 { 6154 {
6104 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, 6155 /* PXW: Why do we do the pixel-to-cols conversion only if
6156 seen_reversed_p holds? Don't we have to set other fields of
6157 the window/frame structure?
6158
6159 w->total_cols and FRAME_TOTAL_COLS want the width in columns,
6105 not in pixels. */ 6160 not in pixels. */
6161 w->pixel_width = width;
6106 width /= WINDOW_FRAME_COLUMN_WIDTH (w); 6162 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
6107 w->total_cols = width; 6163 w->total_cols = width;
6108 FRAME_TOTAL_COLS (f) = width; 6164 FRAME_TOTAL_COLS (f) = width;
6165 SET_FRAME_WIDTH (f, width);
6109 adjust_frame_glyphs (f); 6166 adjust_frame_glyphs (f);
6110 w->pseudo_window_p = 1; 6167 w->pseudo_window_p = 1;
6111 clear_glyph_matrix (w->desired_matrix); 6168 clear_glyph_matrix (w->desired_matrix);
@@ -6135,16 +6192,15 @@ Text larger than the specified size is clipped. */)
6135 } 6192 }
6136 } 6193 }
6137 6194
6138 /* Round up the height to an integral multiple of FRAME_LINE_HEIGHT. */
6139 if (height % FRAME_LINE_HEIGHT (f) != 0)
6140 height += FRAME_LINE_HEIGHT (f) - height % FRAME_LINE_HEIGHT (f);
6141 /* Add the frame's internal border to the width and height the w32 6195 /* Add the frame's internal border to the width and height the w32
6142 window should have. */ 6196 window should have. */
6143 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); 6197 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
6144 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); 6198 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
6145 6199
6146 /* Move the tooltip window where the mouse pointer is. Resize and 6200 /* Move the tooltip window where the mouse pointer is. Resize and
6147 show it. */ 6201 show it.
6202
6203 PXW: This should use the frame's pixel coordinates. */
6148 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); 6204 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
6149 6205
6150 { 6206 {
@@ -7212,6 +7268,29 @@ This is a direct interface to the Windows API FindWindow function. */)
7212 return Qt; 7268 return Qt;
7213} 7269}
7214 7270
7271DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0,
7272 doc: /* Return boundary rectangle of FRAME in screen coordinates.
7273FRAME must be a live frame and defaults to the selected one.
7274
7275The boundary rectangle is a list of four elements, specifying the left,
7276top, right and bottom screen coordinates of FRAME including menu and
7277title bar and decorations. Optional argument CLIENT non-nil means to
7278return the boundaries of the client rectangle which excludes menu and
7279title bar and decorations. */)
7280 (Lisp_Object frame, Lisp_Object client)
7281{
7282 struct frame *f = decode_live_frame (frame);
7283 RECT rect;
7284
7285 if (!NILP (client))
7286 GetClientRect (FRAME_W32_WINDOW (f), &rect);
7287 else
7288 GetWindowRect (FRAME_W32_WINDOW (f), &rect);
7289
7290 return list4 (make_number (rect.left), make_number (rect.top),
7291 make_number (rect.right), make_number (rect.bottom));
7292}
7293
7215DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0, 7294DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
7216 doc: /* Get power status information from Windows system. 7295 doc: /* Get power status information from Windows system.
7217 7296
@@ -7868,6 +7947,8 @@ frame_parm_handler w32_frame_parm_handlers[] =
7868 x_set_icon_name, 7947 x_set_icon_name,
7869 x_set_icon_type, 7948 x_set_icon_type,
7870 x_set_internal_border_width, 7949 x_set_internal_border_width,
7950 x_set_right_divider_width,
7951 x_set_bottom_divider_width,
7871 x_set_menu_bar_lines, 7952 x_set_menu_bar_lines,
7872 x_set_mouse_color, 7953 x_set_mouse_color,
7873 x_explicitly_set_name, 7954 x_explicitly_set_name,
@@ -8119,6 +8200,13 @@ or when you set the mouse color. */);
8119This variable takes effect when you create a new frame 8200This variable takes effect when you create a new frame
8120or when you set the mouse color. */); 8201or when you set the mouse color. */);
8121 Vx_window_horizontal_drag_shape = Qnil; 8202 Vx_window_horizontal_drag_shape = Qnil;
8203
8204 DEFVAR_LISP ("x-window-vertical-drag-cursor",
8205 Vx_window_vertical_drag_shape,
8206 doc: /* Pointer shape to use for indicating a window can be dragged vertically.
8207This variable takes effect when you create a new frame
8208or when you set the mouse color. */);
8209 Vx_window_vertical_drag_shape = Qnil;
8122#endif 8210#endif
8123 8211
8124 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel, 8212 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
@@ -8211,6 +8299,7 @@ only be necessary if the default setting causes problems. */);
8211 defsubr (&Sw32_reconstruct_hot_key); 8299 defsubr (&Sw32_reconstruct_hot_key);
8212 defsubr (&Sw32_toggle_lock_key); 8300 defsubr (&Sw32_toggle_lock_key);
8213 defsubr (&Sw32_window_exists_p); 8301 defsubr (&Sw32_window_exists_p);
8302 defsubr (&Sw32_frame_rect);
8214 defsubr (&Sw32_battery_status); 8303 defsubr (&Sw32_battery_status);
8215 8304
8216#ifdef WINDOWSNT 8305#ifdef WINDOWSNT
@@ -8238,61 +8327,35 @@ only be necessary if the default setting causes problems. */);
8238#endif 8327#endif
8239} 8328}
8240 8329
8330
8241 8331
8242/* 8332/* Crashing and reporting backtrace. */
8243 globals_of_w32fns is used to initialize those global variables that
8244 must always be initialized on startup even when the global variable
8245 initialized is non zero (see the function main in emacs.c).
8246 globals_of_w32fns is called from syms_of_w32fns when the global
8247 variable initialized is 0 and directly from main when initialized
8248 is non zero.
8249 */
8250void
8251globals_of_w32fns (void)
8252{
8253 HMODULE user32_lib = GetModuleHandle ("user32.dll");
8254 /*
8255 TrackMouseEvent not available in all versions of Windows, so must load
8256 it dynamically. Do it once, here, instead of every time it is used.
8257 */
8258 track_mouse_event_fn = (TrackMouseEvent_Proc)
8259 GetProcAddress (user32_lib, "TrackMouseEvent");
8260
8261 monitor_from_point_fn = (MonitorFromPoint_Proc)
8262 GetProcAddress (user32_lib, "MonitorFromPoint");
8263 get_monitor_info_fn = (GetMonitorInfo_Proc)
8264 GetProcAddress (user32_lib, "GetMonitorInfoA");
8265 monitor_from_window_fn = (MonitorFromWindow_Proc)
8266 GetProcAddress (user32_lib, "MonitorFromWindow");
8267 enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
8268 GetProcAddress (user32_lib, "EnumDisplayMonitors");
8269
8270 {
8271 HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
8272 get_composition_string_fn = (ImmGetCompositionString_Proc)
8273 GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
8274 get_ime_context_fn = (ImmGetContext_Proc)
8275 GetProcAddress (imm32_lib, "ImmGetContext");
8276 release_ime_context_fn = (ImmReleaseContext_Proc)
8277 GetProcAddress (imm32_lib, "ImmReleaseContext");
8278 set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
8279 GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
8280 }
8281 DEFVAR_INT ("w32-ansi-code-page",
8282 w32_ansi_code_page,
8283 doc: /* The ANSI code page used by the system. */);
8284 w32_ansi_code_page = GetACP ();
8285 8333
8286 if (os_subtype == OS_NT) 8334#ifndef CYGWIN
8287 w32_unicode_gui = 1; 8335static LONG CALLBACK my_exception_handler (EXCEPTION_POINTERS *);
8288 else 8336static LPTOP_LEVEL_EXCEPTION_FILTER prev_exception_handler;
8289 w32_unicode_gui = 0; 8337#endif
8290 8338static DWORD except_code;
8291 /* MessageBox does not work without this when linked to comctl32.dll 6.0. */ 8339static PVOID except_addr;
8292 InitCommonControls ();
8293 8340
8294 syms_of_w32uniscribe (); 8341#ifndef CYGWIN
8342/* This handler records the exception code and the address where it
8343 was triggered so that this info could be included in the backtrace.
8344 Without that, the backtrace in some cases has no information
8345 whatsoever about the offending code, and looks as if the top-level
8346 exception handler in the MinGW startup code di the one that
8347 crashed. */
8348static LONG CALLBACK
8349my_exception_handler (EXCEPTION_POINTERS * exception_data)
8350{
8351 except_code = exception_data->ExceptionRecord->ExceptionCode;
8352 except_addr = exception_data->ExceptionRecord->ExceptionAddress;
8353
8354 if (prev_exception_handler)
8355 return prev_exception_handler (exception_data);
8356 return EXCEPTION_EXECUTE_HANDLER;
8295} 8357}
8358#endif
8296 8359
8297typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *, 8360typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *,
8298 PULONG); 8361 PULONG);
@@ -8349,21 +8412,32 @@ emacs_abort (void)
8349 8412
8350 if (i) 8413 if (i)
8351 { 8414 {
8415 int errfile_fd = -1;
8416 int j;
8417 char buf[sizeof ("\r\nException at this address:\r\n\r\n")
8418 + 2 * INT_BUFSIZE_BOUND (void *)];
8352#ifdef CYGWIN 8419#ifdef CYGWIN
8353 int stderr_fd = 2; 8420 int stderr_fd = 2;
8354#else 8421#else
8355 HANDLE errout = GetStdHandle (STD_ERROR_HANDLE); 8422 HANDLE errout = GetStdHandle (STD_ERROR_HANDLE);
8356 int stderr_fd = -1; 8423 int stderr_fd = -1;
8357#endif
8358 int errfile_fd = -1;
8359 int j;
8360 8424
8361#ifndef CYGWIN
8362 if (errout && errout != INVALID_HANDLE_VALUE) 8425 if (errout && errout != INVALID_HANDLE_VALUE)
8363 stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND | O_BINARY); 8426 stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND | O_BINARY);
8364#endif 8427#endif
8428
8429 /* We use %p, not 0x%p, as %p produces a leading "0x" on XP,
8430 but not on Windows 7. addr2line doesn't mind a missing
8431 "0x", but will be confused by an extra one. */
8432 if (except_addr)
8433 sprintf (buf, "\r\nException 0x%lx at this address:\r\n%p\r\n",
8434 except_code, except_addr);
8365 if (stderr_fd >= 0) 8435 if (stderr_fd >= 0)
8366 write (stderr_fd, "\r\nBacktrace:\r\n", 14); 8436 {
8437 if (except_addr)
8438 write (stderr_fd, buf, strlen (buf));
8439 write (stderr_fd, "\r\nBacktrace:\r\n", 14);
8440 }
8367#ifdef CYGWIN 8441#ifdef CYGWIN
8368#define _open open 8442#define _open open
8369#endif 8443#endif
@@ -8371,17 +8445,17 @@ emacs_abort (void)
8371 if (errfile_fd >= 0) 8445 if (errfile_fd >= 0)
8372 { 8446 {
8373 lseek (errfile_fd, 0L, SEEK_END); 8447 lseek (errfile_fd, 0L, SEEK_END);
8448 if (except_addr)
8449 write (errfile_fd, buf, strlen (buf));
8374 write (errfile_fd, "\r\nBacktrace:\r\n", 14); 8450 write (errfile_fd, "\r\nBacktrace:\r\n", 14);
8375 } 8451 }
8376 8452
8377 for (j = 0; j < i; j++) 8453 for (j = 0; j < i; j++)
8378 { 8454 {
8379 char buf[INT_BUFSIZE_BOUND (void *)];
8380
8381 /* stack[] gives the return addresses, whereas we want 8455 /* stack[] gives the return addresses, whereas we want
8382 the address of the call, so decrease each address 8456 the address of the call, so decrease each address
8383 by approximate size of 1 CALL instruction. */ 8457 by approximate size of 1 CALL instruction. */
8384 sprintf (buf, "0x%p\r\n", (char *)stack[j] - sizeof(void *)); 8458 sprintf (buf, "%p\r\n", (char *)stack[j] - sizeof(void *));
8385 if (stderr_fd >= 0) 8459 if (stderr_fd >= 0)
8386 write (stderr_fd, buf, strlen (buf)); 8460 write (stderr_fd, buf, strlen (buf));
8387 if (errfile_fd >= 0) 8461 if (errfile_fd >= 0)
@@ -8403,6 +8477,72 @@ emacs_abort (void)
8403 } 8477 }
8404} 8478}
8405 8479
8480
8481
8482/* Initialization. */
8483
8484/*
8485 globals_of_w32fns is used to initialize those global variables that
8486 must always be initialized on startup even when the global variable
8487 initialized is non zero (see the function main in emacs.c).
8488 globals_of_w32fns is called from syms_of_w32fns when the global
8489 variable initialized is 0 and directly from main when initialized
8490 is non zero.
8491 */
8492void
8493globals_of_w32fns (void)
8494{
8495 HMODULE user32_lib = GetModuleHandle ("user32.dll");
8496 /*
8497 TrackMouseEvent not available in all versions of Windows, so must load
8498 it dynamically. Do it once, here, instead of every time it is used.
8499 */
8500 track_mouse_event_fn = (TrackMouseEvent_Proc)
8501 GetProcAddress (user32_lib, "TrackMouseEvent");
8502
8503 monitor_from_point_fn = (MonitorFromPoint_Proc)
8504 GetProcAddress (user32_lib, "MonitorFromPoint");
8505 get_monitor_info_fn = (GetMonitorInfo_Proc)
8506 GetProcAddress (user32_lib, "GetMonitorInfoA");
8507 monitor_from_window_fn = (MonitorFromWindow_Proc)
8508 GetProcAddress (user32_lib, "MonitorFromWindow");
8509 enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
8510 GetProcAddress (user32_lib, "EnumDisplayMonitors");
8511
8512 {
8513 HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
8514 get_composition_string_fn = (ImmGetCompositionString_Proc)
8515 GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
8516 get_ime_context_fn = (ImmGetContext_Proc)
8517 GetProcAddress (imm32_lib, "ImmGetContext");
8518 release_ime_context_fn = (ImmReleaseContext_Proc)
8519 GetProcAddress (imm32_lib, "ImmReleaseContext");
8520 set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
8521 GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
8522 }
8523
8524 except_code = 0;
8525 except_addr = 0;
8526#ifndef CYGWIN
8527 prev_exception_handler = SetUnhandledExceptionFilter (my_exception_handler);
8528#endif
8529
8530 DEFVAR_INT ("w32-ansi-code-page",
8531 w32_ansi_code_page,
8532 doc: /* The ANSI code page used by the system. */);
8533 w32_ansi_code_page = GetACP ();
8534
8535 if (os_subtype == OS_NT)
8536 w32_unicode_gui = 1;
8537 else
8538 w32_unicode_gui = 0;
8539
8540 /* MessageBox does not work without this when linked to comctl32.dll 6.0. */
8541 InitCommonControls ();
8542
8543 syms_of_w32uniscribe ();
8544}
8545
8406#ifdef NTGUI_UNICODE 8546#ifdef NTGUI_UNICODE
8407 8547
8408Lisp_Object 8548Lisp_Object
diff --git a/src/w32font.c b/src/w32font.c
index effedfc04e1..654e0d9cae4 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -149,6 +149,7 @@ static BOOL g_b_init_get_outline_metrics_w;
149static BOOL g_b_init_get_text_metrics_w; 149static BOOL g_b_init_get_text_metrics_w;
150static BOOL g_b_init_get_glyph_outline_w; 150static BOOL g_b_init_get_glyph_outline_w;
151static BOOL g_b_init_get_glyph_outline_w; 151static BOOL g_b_init_get_glyph_outline_w;
152static BOOL g_b_init_get_char_width_32_w;
152 153
153typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) ( 154typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
154 HDC hdc, 155 HDC hdc,
@@ -165,6 +166,11 @@ typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
165 DWORD cbBuffer, 166 DWORD cbBuffer,
166 LPVOID lpvBuffer, 167 LPVOID lpvBuffer,
167 const MAT2 *lpmat2); 168 const MAT2 *lpmat2);
169typedef BOOL (WINAPI * GetCharWidth32W_Proc) (
170 HDC hdc,
171 UINT uFirstChar,
172 UINT uLastChar,
173 LPINT lpBuffer);
168 174
169/* Several "wide" functions we use to support the font backends are 175/* Several "wide" functions we use to support the font backends are
170 unavailable on Windows 9X, unless UNICOWS.DLL is installed (their 176 unavailable on Windows 9X, unless UNICOWS.DLL is installed (their
@@ -274,6 +280,23 @@ get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
274 lpvBuffer, lpmat2); 280 lpvBuffer, lpmat2);
275} 281}
276 282
283static DWORD WINAPI get_char_width_32_w (HDC hdc, UINT uFirstChar,
284 UINT uLastChar, LPINT lpBuffer)
285{
286 static GetCharWidth32W_Proc s_pfn_Get_Char_Width_32W = NULL;
287 HMODULE hm_unicows = NULL;
288 if (g_b_init_get_char_width_32_w == 0)
289 {
290 g_b_init_get_char_width_32_w = 1;
291 hm_unicows = w32_load_unicows_or_gdi32 ();
292 if (hm_unicows)
293 s_pfn_Get_Char_Width_32W = (GetCharWidth32W_Proc)
294 GetProcAddress (hm_unicows, "GetCharWidth32W");
295 }
296 eassert (s_pfn_Get_Char_Width_32W != NULL);
297 return s_pfn_Get_Char_Width_32W (hdc, uFirstChar, uLastChar, lpBuffer);
298}
299
277static int 300static int
278memq_no_quit (Lisp_Object elt, Lisp_Object list) 301memq_no_quit (Lisp_Object elt, Lisp_Object list)
279{ 302{
@@ -989,7 +1012,6 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity,
989 font->baseline_offset = 0; 1012 font->baseline_offset = 0;
990 font->relative_compose = 0; 1013 font->relative_compose = 0;
991 font->default_ascent = w32_font->metrics.tmAscent; 1014 font->default_ascent = w32_font->metrics.tmAscent;
992 font->font_encoder = NULL;
993 font->pixel_size = size; 1015 font->pixel_size = size;
994 font->driver = &w32font_driver; 1016 font->driver = &w32font_driver;
995 /* Use format cached during list, as the information we have access to 1017 /* Use format cached during list, as the information we have access to
@@ -2437,6 +2459,7 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
2437 GLYPHMETRICS gm; 2459 GLYPHMETRICS gm;
2438 MAT2 transform; 2460 MAT2 transform;
2439 unsigned int options = GGO_METRICS; 2461 unsigned int options = GGO_METRICS;
2462 INT width;
2440 2463
2441 if (w32_font->glyph_idx) 2464 if (w32_font->glyph_idx)
2442 options |= GGO_GLYPH_INDEX; 2465 options |= GGO_GLYPH_INDEX;
@@ -2453,6 +2476,13 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
2453 metrics->width = gm.gmCellIncX; 2476 metrics->width = gm.gmCellIncX;
2454 metrics->status = W32METRIC_SUCCESS; 2477 metrics->status = W32METRIC_SUCCESS;
2455 } 2478 }
2479 else if (get_char_width_32_w (dc, code, code, &width) != 0)
2480 {
2481 metrics->lbearing = 0;
2482 metrics->rbearing = width;
2483 metrics->width = width;
2484 metrics->status = W32METRIC_SUCCESS;
2485 }
2456 else 2486 else
2457 metrics->status = W32METRIC_FAIL; 2487 metrics->status = W32METRIC_FAIL;
2458} 2488}
@@ -2727,4 +2757,5 @@ globals_of_w32font (void)
2727 g_b_init_get_outline_metrics_w = 0; 2757 g_b_init_get_outline_metrics_w = 0;
2728 g_b_init_get_text_metrics_w = 0; 2758 g_b_init_get_text_metrics_w = 0;
2729 g_b_init_get_glyph_outline_w = 0; 2759 g_b_init_get_glyph_outline_w = 0;
2760 g_b_init_get_char_width_32_w = 0;
2730} 2761}
diff --git a/src/w32inevt.c b/src/w32inevt.c
index dc587de1183..d4c96bd9b8a 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -587,7 +587,7 @@ resize_event (WINDOW_BUFFER_SIZE_RECORD *event)
587{ 587{
588 struct frame *f = get_frame (); 588 struct frame *f = get_frame ();
589 589
590 change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1, 0); 590 change_frame_size (f, event->dwSize.X, event->dwSize.Y, 0, 1, 0, 0);
591 SET_FRAME_GARBAGED (f); 591 SET_FRAME_GARBAGED (f);
592} 592}
593 593
@@ -602,13 +602,13 @@ maybe_generate_resize_event (void)
602 /* It is okay to call this unconditionally, since it will do nothing 602 /* It is okay to call this unconditionally, since it will do nothing
603 if the size hasn't actually changed. */ 603 if the size hasn't actually changed. */
604 change_frame_size (f, 604 change_frame_size (f,
605 1 + info.srWindow.Bottom - info.srWindow.Top,
606 1 + info.srWindow.Right - info.srWindow.Left, 605 1 + info.srWindow.Right - info.srWindow.Left,
607 0, 0, 0); 606 1 + info.srWindow.Bottom - info.srWindow.Top,
607 0, 0, 0, 0);
608} 608}
609 609
610#if HAVE_W32NOTIFY 610#if HAVE_W32NOTIFY
611static int 611int
612handle_file_notifications (struct input_event *hold_quit) 612handle_file_notifications (struct input_event *hold_quit)
613{ 613{
614 BYTE *p = file_notifications; 614 BYTE *p = file_notifications;
@@ -676,7 +676,7 @@ handle_file_notifications (struct input_event *hold_quit)
676 return nevents; 676 return nevents;
677} 677}
678#else /* !HAVE_W32NOTIFY */ 678#else /* !HAVE_W32NOTIFY */
679static int 679int
680handle_file_notifications (struct input_event *hold_quit) 680handle_file_notifications (struct input_event *hold_quit)
681{ 681{
682 return 0; 682 return 0;
diff --git a/src/w32menu.c b/src/w32menu.c
index b25652017cd..4f8e8dbef05 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -114,7 +114,6 @@ static int fill_in_menu (HMENU, widget_value *);
114 114
115void w32_free_menu_strings (HWND); 115void w32_free_menu_strings (HWND);
116 116
117#ifdef HAVE_MENUS
118#ifdef HAVE_DIALOGS 117#ifdef HAVE_DIALOGS
119Lisp_Object 118Lisp_Object
120w32_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents) 119w32_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
@@ -506,7 +505,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
506 /* Force the window size to be recomputed so that the frame's text 505 /* Force the window size to be recomputed so that the frame's text
507 area remains the same, if menubar has just been created. */ 506 area remains the same, if menubar has just been created. */
508 if (old_widget == NULL) 507 if (old_widget == NULL)
509 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 508 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
510 } 509 }
511 510
512 unblock_input (); 511 unblock_input ();
@@ -1602,21 +1601,15 @@ w32_free_menu_strings (HWND hwnd)
1602 current_popup_menu = NULL; 1601 current_popup_menu = NULL;
1603} 1602}
1604 1603
1605#endif /* HAVE_MENUS */
1606
1607/* The following is used by delayed window autoselection. */ 1604/* The following is used by delayed window autoselection. */
1608 1605
1609DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, 1606DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
1610 doc: /* Return t if a menu or popup dialog is active on selected frame. */) 1607 doc: /* Return t if a menu or popup dialog is active on selected frame. */)
1611 (void) 1608 (void)
1612{ 1609{
1613#ifdef HAVE_MENUS
1614 struct frame *f; 1610 struct frame *f;
1615 f = SELECTED_FRAME (); 1611 f = SELECTED_FRAME ();
1616 return (f->output_data.w32->menubar_active > 0) ? Qt : Qnil; 1612 return (f->output_data.w32->menubar_active > 0) ? Qt : Qnil;
1617#else
1618 return Qnil;
1619#endif /* HAVE_MENUS */
1620} 1613}
1621 1614
1622void 1615void
diff --git a/src/w32notify.c b/src/w32notify.c
index a48a83daf53..373e20e8e92 100644
--- a/src/w32notify.c
+++ b/src/w32notify.c
@@ -163,7 +163,12 @@ send_notifications (BYTE *info, DWORD info_size, void *desc,
163 && PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0)) 163 && PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0))
164 || (FRAME_W32_P (f) 164 || (FRAME_W32_P (f)
165 && PostMessage (FRAME_W32_WINDOW (f), 165 && PostMessage (FRAME_W32_WINDOW (f),
166 WM_EMACS_FILENOTIFY, 0, 0))) 166 WM_EMACS_FILENOTIFY, 0, 0))
167 /* When we are running in batch mode, there's no one to
168 send a message, so we just signal the data is
169 available and hope sys_select will be called soon and
170 will read the data. */
171 || (FRAME_INITIAL_P (f) && noninteractive))
167 notification_buffer_in_use = 1; 172 notification_buffer_in_use = 1;
168 done = 1; 173 done = 1;
169 } 174 }
@@ -324,7 +329,7 @@ add_watch (const char *parent_dir, const char *file, BOOL subdirs, DWORD flags)
324 HANDLE hdir; 329 HANDLE hdir;
325 struct notification *dirwatch = NULL; 330 struct notification *dirwatch = NULL;
326 331
327 if (!file || !*file) 332 if (!file)
328 return NULL; 333 return NULL;
329 334
330 hdir = CreateFile (parent_dir, 335 hdir = CreateFile (parent_dir,
@@ -526,13 +531,21 @@ generate notifications correctly, though. */)
526 report_file_error ("GetFullPathName failed", 531 report_file_error ("GetFullPathName failed",
527 Fcons (lisp_errstr, Fcons (file, Qnil))); 532 Fcons (lisp_errstr, Fcons (file, Qnil)));
528 } 533 }
529 /* We need the parent directory without the slash that follows it. 534 /* filenotify.el always passes us a directory, either the parent
530 If BASENAME is NULL, the argument was the root directory on its 535 directory of a file to be watched, or the directory to be
531 drive. */ 536 watched. */
532 if (basename) 537 if (file_directory_p (parent_dir))
533 basename[-1] = '\0'; 538 basename = "";
534 else 539 else
535 subdirs = TRUE; 540 {
541 /* This should only happen if we are called directly, not via
542 filenotify.el. If BASENAME is NULL, the argument was the
543 root directory on its drive. */
544 if (basename)
545 basename[-1] = '\0';
546 else
547 subdirs = TRUE;
548 }
536 549
537 if (!NILP (Fmember (Qsubtree, filter))) 550 if (!NILP (Fmember (Qsubtree, filter)))
538 subdirs = TRUE; 551 subdirs = TRUE;
diff --git a/src/w32proc.c b/src/w32proc.c
index d2751d50680..7d4fb9825fa 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1941,12 +1941,17 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1941 FD_ZERO (rfds); 1941 FD_ZERO (rfds);
1942 nr = 0; 1942 nr = 0;
1943 1943
1944 /* Always wait on interrupt_handle, to detect C-g (quit). */ 1944 /* If interrupt_handle is available and valid, always wait on it, to
1945 wait_hnd[0] = interrupt_handle; 1945 detect C-g (quit). */
1946 fdindex[0] = -1; 1946 nh = 0;
1947 if (interrupt_handle && interrupt_handle != INVALID_HANDLE_VALUE)
1948 {
1949 wait_hnd[0] = interrupt_handle;
1950 fdindex[0] = -1;
1951 nh++;
1952 }
1947 1953
1948 /* Build a list of pipe handles to wait on. */ 1954 /* Build a list of pipe handles to wait on. */
1949 nh = 1;
1950 for (i = 0; i < nfds; i++) 1955 for (i = 0; i < nfds; i++)
1951 if (FD_ISSET (i, &orfds)) 1956 if (FD_ISSET (i, &orfds))
1952 { 1957 {
@@ -1967,6 +1972,11 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1967 FD_SET (i, rfds); 1972 FD_SET (i, rfds);
1968 return 1; 1973 return 1;
1969 } 1974 }
1975 else if (noninteractive)
1976 {
1977 if (handle_file_notifications (NULL))
1978 return 1;
1979 }
1970 } 1980 }
1971 else 1981 else
1972 { 1982 {
@@ -2067,6 +2077,11 @@ count_children:
2067 { 2077 {
2068 if (timeout) 2078 if (timeout)
2069 Sleep (timeout_ms); 2079 Sleep (timeout_ms);
2080 if (noninteractive)
2081 {
2082 if (handle_file_notifications (NULL))
2083 return 1;
2084 }
2070 return 0; 2085 return 0;
2071 } 2086 }
2072 2087
@@ -2093,6 +2108,11 @@ count_children:
2093 } 2108 }
2094 else if (active == WAIT_TIMEOUT) 2109 else if (active == WAIT_TIMEOUT)
2095 { 2110 {
2111 if (noninteractive)
2112 {
2113 if (handle_file_notifications (NULL))
2114 return 1;
2115 }
2096 return 0; 2116 return 0;
2097 } 2117 }
2098 else if (active >= WAIT_OBJECT_0 2118 else if (active >= WAIT_OBJECT_0
@@ -2199,6 +2219,12 @@ count_children:
2199 break; 2219 break;
2200 } while (active < nh + nc); 2220 } while (active < nh + nc);
2201 2221
2222 if (noninteractive)
2223 {
2224 if (handle_file_notifications (NULL))
2225 nr++;
2226 }
2227
2202 /* If no input has arrived and timeout hasn't expired, wait again. */ 2228 /* If no input has arrived and timeout hasn't expired, wait again. */
2203 if (nr == 0) 2229 if (nr == 0)
2204 { 2230 {
diff --git a/src/w32term.c b/src/w32term.c
index b29087ef57b..9c74304a83a 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -181,7 +181,7 @@ void x_lower_frame (struct frame *);
181void x_scroll_bar_clear (struct frame *); 181void x_scroll_bar_clear (struct frame *);
182void x_wm_set_size_hint (struct frame *, long, bool); 182void x_wm_set_size_hint (struct frame *, long, bool);
183void x_raise_frame (struct frame *); 183void x_raise_frame (struct frame *);
184void x_set_window_size (struct frame *, int, int, int); 184void x_set_window_size (struct frame *, int, int, int, bool);
185void x_wm_set_window_state (struct frame *, int); 185void x_wm_set_window_state (struct frame *, int);
186void x_wm_set_icon_pixmap (struct frame *, int); 186void x_wm_set_icon_pixmap (struct frame *, int);
187static void w32_initialize (void); 187static void w32_initialize (void);
@@ -622,6 +622,32 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
622} 622}
623 623
624 624
625/* Draw a window divider from (x0, y0) to (x1, y1) */
626
627static void
628w32_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
629{
630 struct frame *f = XFRAME (WINDOW_FRAME (w));
631 RECT r;
632 HDC hdc;
633 struct face *face;
634
635 r.left = x0;
636 r.right = x1;
637 r.top = y0;
638 r.bottom = y1;
639
640 hdc = get_frame_dc (f);
641 face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
642 if (face)
643 w32_fill_rect (f, hdc, face->foreground, &r);
644 else
645 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
646
647 release_frame_dc (f, hdc);
648}
649
650
625/* End update of window W. 651/* End update of window W.
626 652
627 Draw vertical borders between horizontally adjacent windows, and 653 Draw vertical borders between horizontally adjacent windows, and
@@ -649,7 +675,12 @@ x_update_window_end (struct window *w, bool cursor_on_p,
649 w->output_cursor.x, w->output_cursor.y); 675 w->output_cursor.x, w->output_cursor.y);
650 676
651 if (draw_window_fringes (w, 1)) 677 if (draw_window_fringes (w, 1))
652 x_draw_vertical_border (w); 678 {
679 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
680 x_draw_right_divider (w);
681 else
682 x_draw_vertical_border (w);
683 }
653 684
654 unblock_input (); 685 unblock_input ();
655 } 686 }
@@ -778,8 +809,7 @@ w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
778 if (sb_width > 0) 809 if (sb_width > 0)
779 { 810 {
780 int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w); 811 int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
781 int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w) 812 int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
782 * FRAME_COLUMN_WIDTH (f));
783 813
784 if (bx < 0) 814 if (bx < 0)
785 { 815 {
@@ -2676,8 +2706,7 @@ x_scroll_run (struct window *w, struct run *run)
2676 if (sb_width > 0) 2706 if (sb_width > 0)
2677 { 2707 {
2678 int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w); 2708 int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
2679 int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w) 2709 int bar_area_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
2680 * FRAME_COLUMN_WIDTH (f));
2681 2710
2682 if (bar_area_x + bar_area_width == x) 2711 if (bar_area_x + bar_area_width == x)
2683 { 2712 {
@@ -3761,7 +3790,7 @@ w32_set_vertical_scroll_bar (struct window *w,
3761 /* Get window dimensions. */ 3790 /* Get window dimensions. */
3762 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); 3791 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
3763 top = window_y; 3792 top = window_y;
3764 width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); 3793 width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
3765 height = window_height; 3794 height = window_height;
3766 3795
3767 /* Compute the left edge of the scroll bar area. */ 3796 /* Compute the left edge of the scroll bar area. */
@@ -4216,7 +4245,6 @@ w32_read_socket (struct terminal *terminal,
4216 struct frame *f; 4245 struct frame *f;
4217 struct w32_display_info *dpyinfo = &one_w32_display_info; 4246 struct w32_display_info *dpyinfo = &one_w32_display_info;
4218 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; 4247 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
4219 static char buf[1];
4220 4248
4221 block_input (); 4249 block_input ();
4222 4250
@@ -4702,6 +4730,47 @@ w32_read_socket (struct terminal *terminal,
4702 break; 4730 break;
4703 4731
4704 case SIZE_MAXIMIZED: 4732 case SIZE_MAXIMIZED:
4733 {
4734 bool iconified = FRAME_ICONIFIED_P (f);
4735
4736 SET_FRAME_VISIBLE (f, 1);
4737 SET_FRAME_ICONIFIED (f, 0);
4738
4739 /* wait_reading_process_output will notice this
4740 and update the frame's display structures. */
4741 SET_FRAME_GARBAGED (f);
4742
4743 if (iconified)
4744 {
4745 int x, y;
4746
4747 /* Reset top and left positions of the Window
4748 here since Windows sends a WM_MOVE message
4749 BEFORE telling us the Window is minimized
4750 when the Window is iconified, with 3000,3000
4751 as the co-ords. */
4752 x_real_positions (f, &x, &y);
4753 f->left_pos = x;
4754 f->top_pos = y;
4755
4756 inev.kind = DEICONIFY_EVENT;
4757 XSETFRAME (inev.frame_or_window, f);
4758 }
4759 else if (! NILP (Vframe_list)
4760 && ! NILP (XCDR (Vframe_list)))
4761 /* Force a redisplay sooner or later
4762 to update the frame titles
4763 in case this is the second frame. */
4764 record_asynch_buffer_change ();
4765 }
4766
4767 if (get_frame_param (f, Qfullscreen) == Qnil)
4768 set_frame_param (f, Qfullscreen, Qmaximized);
4769 else if (get_frame_param (f, Qfullscreen) != Qmaximized)
4770 set_frame_param (f, Qmaximized, Qmaximized);
4771
4772 break;
4773
4705 case SIZE_RESTORED: 4774 case SIZE_RESTORED:
4706 { 4775 {
4707 bool iconified = FRAME_ICONIFIED_P (f); 4776 bool iconified = FRAME_ICONIFIED_P (f);
@@ -4733,6 +4802,12 @@ w32_read_socket (struct terminal *terminal,
4733 in case this is the second frame. */ 4802 in case this is the second frame. */
4734 record_asynch_buffer_change (); 4803 record_asynch_buffer_change ();
4735 } 4804 }
4805
4806 if (get_frame_param (f, Qfullscreen) == Qmaximized)
4807 set_frame_param (f, Qfullscreen, Qnil);
4808 else if (get_frame_param (f, Qmaximized) != Qnil)
4809 set_frame_param (f, Qmaximized, Qnil);
4810
4736 break; 4811 break;
4737 } 4812 }
4738 } 4813 }
@@ -4740,16 +4815,14 @@ w32_read_socket (struct terminal *terminal,
4740 if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED) 4815 if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
4741 { 4816 {
4742 RECT rect; 4817 RECT rect;
4743 int rows; 4818 int rows, columns, width, height, text_width, text_height;
4744 int columns;
4745 int width;
4746 int height;
4747 4819
4748 GetClientRect (msg.msg.hwnd, &rect); 4820 GetClientRect (msg.msg.hwnd, &rect);
4749 4821
4750 height = rect.bottom - rect.top; 4822 height = rect.bottom - rect.top;
4751 width = rect.right - rect.left; 4823 width = rect.right - rect.left;
4752 4824 text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
4825 text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
4753 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); 4826 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
4754 columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); 4827 columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
4755 4828
@@ -4759,16 +4832,18 @@ w32_read_socket (struct terminal *terminal,
4759 not changed, the font size may have changed, so we need 4832 not changed, the font size may have changed, so we need
4760 to check the pixel dimensions as well. */ 4833 to check the pixel dimensions as well. */
4761 4834
4762 if (columns != FRAME_COLS (f) 4835 if (width != FRAME_PIXEL_WIDTH (f)
4763 || rows != FRAME_LINES (f) 4836 || height != FRAME_PIXEL_HEIGHT (f)
4764 || width != FRAME_PIXEL_WIDTH (f) 4837 || text_width != FRAME_TEXT_WIDTH (f)
4765 || height != FRAME_PIXEL_HEIGHT (f)) 4838 || text_height != FRAME_TEXT_HEIGHT (f))
4766 { 4839 {
4767 change_frame_size (f, rows, columns, 0, 1, 0); 4840 change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
4768 SET_FRAME_GARBAGED (f); 4841 SET_FRAME_GARBAGED (f);
4769 cancel_mouse_face (f); 4842 cancel_mouse_face (f);
4770 FRAME_PIXEL_WIDTH (f) = width; 4843 /* Do we want to set these here ???? */
4771 FRAME_PIXEL_HEIGHT (f) = height; 4844/** FRAME_PIXEL_WIDTH (f) = width; **/
4845/** FRAME_TEXT_WIDTH (f) = text_width; **/
4846/** FRAME_PIXEL_HEIGHT (f) = height; **/
4772 f->win_gravity = NorthWestGravity; 4847 f->win_gravity = NorthWestGravity;
4773 } 4848 }
4774 } 4849 }
@@ -5425,7 +5500,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
5425 doing it because it's done in Fx_show_tip, and it leads to 5500 doing it because it's done in Fx_show_tip, and it leads to
5426 problems because the tip frame has no widget. */ 5501 problems because the tip frame has no widget. */
5427 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 5502 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
5428 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 5503 x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
5504 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
5429 } 5505 }
5430 5506
5431 /* X version sets font of input methods here also. */ 5507 /* X version sets font of input methods here also. */
@@ -5563,7 +5639,7 @@ x_check_fullscreen (struct frame *f)
5563 when setting WM manager hints. */ 5639 when setting WM manager hints. */
5564 if (FRAME_COLS (f) != width || FRAME_LINES (f) != height) 5640 if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
5565 { 5641 {
5566 change_frame_size (f, height, width, 0, 1, 0); 5642 change_frame_size (f, width, height, 0, 1, 0, 0);
5567 SET_FRAME_GARBAGED (f); 5643 SET_FRAME_GARBAGED (f);
5568 cancel_mouse_face (f); 5644 cancel_mouse_face (f);
5569 5645
@@ -5627,20 +5703,28 @@ w32fullscreen_hook (struct frame *f)
5627 Otherwise we leave the window gravity unchanged. */ 5703 Otherwise we leave the window gravity unchanged. */
5628 5704
5629void 5705void
5630x_set_window_size (struct frame *f, int change_gravity, int cols, int rows) 5706x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
5631{ 5707{
5632 int pixelwidth, pixelheight; 5708 int pixelwidth, pixelheight;
5633 5709
5634 block_input (); 5710 block_input ();
5635 5711
5636 check_frame_size (f, &rows, &cols); 5712 check_frame_size (f, &width, &height, pixelwise);
5637 f->scroll_bar_actual_width 5713 f->scroll_bar_actual_width
5638 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f); 5714 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
5639 5715
5640 compute_fringe_widths (f, 0); 5716 compute_fringe_widths (f, 0);
5641 5717
5642 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); 5718 if (pixelwise)
5643 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); 5719 {
5720 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
5721 pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
5722 }
5723 else
5724 {
5725 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
5726 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
5727 }
5644 5728
5645 f->win_gravity = NorthWestGravity; 5729 f->win_gravity = NorthWestGravity;
5646 x_wm_set_size_hint (f, (long) 0, 0); 5730 x_wm_set_size_hint (f, (long) 0, 0);
@@ -5691,7 +5775,7 @@ x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
5691 5775
5692 We pass 1 for DELAY since we can't run Lisp code inside of 5776 We pass 1 for DELAY since we can't run Lisp code inside of
5693 a BLOCK_INPUT. */ 5777 a BLOCK_INPUT. */
5694 change_frame_size (f, rows, cols, 0, 1, 0); 5778 change_frame_size (f, width, height, 0, 1, 0, 0);
5695 FRAME_PIXEL_WIDTH (f) = pixelwidth; 5779 FRAME_PIXEL_WIDTH (f) = pixelwidth;
5696 FRAME_PIXEL_HEIGHT (f) = pixelheight; 5780 FRAME_PIXEL_HEIGHT (f) = pixelheight;
5697 5781
@@ -6072,7 +6156,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
6072 SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); 6156 SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
6073 SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); 6157 SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
6074 SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); 6158 SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
6075 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width); 6159 SetWindowLong (window, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
6076 6160
6077 leave_crit (); 6161 leave_crit ();
6078} 6162}
@@ -6212,6 +6296,7 @@ static struct redisplay_interface w32_redisplay_interface =
6212 w32_clear_frame_area, 6296 w32_clear_frame_area,
6213 w32_draw_window_cursor, 6297 w32_draw_window_cursor,
6214 w32_draw_vertical_window_border, 6298 w32_draw_vertical_window_border,
6299 w32_draw_window_divider,
6215 w32_shift_glyphs_for_insert 6300 w32_shift_glyphs_for_insert
6216}; 6301};
6217 6302
diff --git a/src/w32term.h b/src/w32term.h
index b3c0cf56c7b..89008b7348c 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -26,23 +26,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0) 26#define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0)
27#define WHITE_PIX_DEFAULT(f) PALETTERGB(255,255,255) 27#define WHITE_PIX_DEFAULT(f) PALETTERGB(255,255,255)
28 28
29#define FONT_WIDTH(f) ((f)->max_width)
30#define FONT_HEIGHT(f) ((f)->height)
31#define FONT_BASE(f) ((f)->ascent)
32#define FONT_DESCENT(f) ((f)->descent)
33
34#define CP_DEFAULT 1004 29#define CP_DEFAULT 1004
35 30
36#define CHECK_W32_FRAME(f, frame) \
37 if (NILP (frame)) \
38 f = SELECTED_FRAME (); \
39 else \
40 { \
41 CHECK_LIVE_FRAME (frame, 0); \
42 f = XFRAME (frame); \
43 } \
44 if (! FRAME_W32_P (f))
45
46/* Indicates whether we are in the readsocket call and the message we 31/* Indicates whether we are in the readsocket call and the message we
47 are processing in the current loop */ 32 are processing in the current loop */
48 33
@@ -230,7 +215,7 @@ extern struct w32_display_info *w32_term_init (Lisp_Object,
230extern int w32_defined_color (struct frame *f, const char *color, 215extern int w32_defined_color (struct frame *f, const char *color,
231 XColor *color_def, int alloc); 216 XColor *color_def, int alloc);
232extern void x_set_window_size (struct frame *f, int change_grav, 217extern void x_set_window_size (struct frame *f, int change_grav,
233 int cols, int rows); 218 int width, int height, bool pixelwise);
234extern int x_display_pixel_height (struct w32_display_info *); 219extern int x_display_pixel_height (struct w32_display_info *);
235extern int x_display_pixel_width (struct w32_display_info *); 220extern int x_display_pixel_width (struct w32_display_info *);
236extern Lisp_Object x_get_focus_frame (struct frame *); 221extern Lisp_Object x_get_focus_frame (struct frame *);
@@ -349,6 +334,7 @@ struct w32_output
349 Cursor hand_cursor; 334 Cursor hand_cursor;
350 Cursor hourglass_cursor; 335 Cursor hourglass_cursor;
351 Cursor horizontal_drag_cursor; 336 Cursor horizontal_drag_cursor;
337 Cursor vertical_drag_cursor;
352 338
353 /* Non-zero means hourglass cursor is currently displayed. */ 339 /* Non-zero means hourglass cursor is currently displayed. */
354 unsigned hourglass_p : 1; 340 unsigned hourglass_p : 1;
@@ -680,6 +666,7 @@ extern DWORD notifications_size;
680extern void *notifications_desc; 666extern void *notifications_desc;
681extern Lisp_Object w32_get_watch_object (void *); 667extern Lisp_Object w32_get_watch_object (void *);
682extern Lisp_Object lispy_file_action (DWORD); 668extern Lisp_Object lispy_file_action (DWORD);
669extern int handle_file_notifications (struct input_event *);
683 670
684extern void w32_initialize_display_info (Lisp_Object); 671extern void w32_initialize_display_info (Lisp_Object);
685extern void initialize_w32_display (struct terminal *, int *, int *); 672extern void initialize_w32_display (struct terminal *, int *, int *);
diff --git a/src/w32xfns.c b/src/w32xfns.c
index 07f75477863..b49abffa130 100644
--- a/src/w32xfns.c
+++ b/src/w32xfns.c
@@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include "lisp.h" 24#include "lisp.h"
25#include "keyboard.h" 25#include "keyboard.h"
26#include "frame.h" 26#include "frame.h"
27#include "window.h"
27#include "charset.h" 28#include "charset.h"
28#include "fontset.h" 29#include "fontset.h"
29#include "blockinput.h" 30#include "blockinput.h"
diff --git a/src/widget.c b/src/widget.c
index d6469d7eec5..89b43fdae76 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -412,7 +412,7 @@ set_frame_size (EmacsFrame ew)
412#if 0 /* This can run Lisp code, and it is dangerous to give 412#if 0 /* This can run Lisp code, and it is dangerous to give
413 out the frame to Lisp code before it officially exists. 413 out the frame to Lisp code before it officially exists.
414 This is handled in Fx_create_frame so not needed here. */ 414 This is handled in Fx_create_frame so not needed here. */
415 change_frame_size (f, h, w, 1, 0, 0); 415 change_frame_size (f, w, h, 1, 0, 0, 0);
416#endif 416#endif
417 char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height); 417 char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
418 ew->core.width = pixel_width; 418 ew->core.width = pixel_width;
@@ -467,7 +467,7 @@ update_wm_hints (EmacsFrame ew)
467 if (! wmshell) return; 467 if (! wmshell) return;
468 468
469#if 0 469#if 0
470 check_frame_size (ew->emacs_frame.frame, &min_rows, &min_cols); 470 check_frame_size (ew->emacs_frame.frame, &min_cols, &min_rows, 0);
471#endif 471#endif
472 472
473 pixel_to_char_size (ew, ew->core.width, ew->core.height, 473 pixel_to_char_size (ew, ew->core.width, ew->core.height,
@@ -681,7 +681,7 @@ EmacsFrameResize (Widget widget)
681 || ew->core.width != FRAME_PIXEL_WIDTH (f) 681 || ew->core.width != FRAME_PIXEL_WIDTH (f)
682 || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f)) 682 || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f))
683 { 683 {
684 change_frame_size (f, rows, columns, 0, 1, 0); 684 change_frame_size (f, columns, rows, 0, 1, 0, 0);
685 update_wm_hints (ew); 685 update_wm_hints (ew);
686 update_various_frame_slots (ew); 686 update_various_frame_slots (ew);
687 687
@@ -735,8 +735,8 @@ EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget, Ar
735 new->core.width = pixel_width; 735 new->core.width = pixel_width;
736 new->core.height = pixel_height; 736 new->core.height = pixel_height;
737 737
738 change_frame_size (new->emacs_frame.frame, char_height, char_width, 738 change_frame_size (new->emacs_frame.frame, char_width, char_height,
739 1, 0, 0); 739 1, 0, 0, 0);
740 needs_a_refresh = True; 740 needs_a_refresh = True;
741 } 741 }
742 742
@@ -798,7 +798,7 @@ EmacsFrameSetCharSize (Widget widget, int columns, int rows)
798 EmacsFrame ew = (EmacsFrame) widget; 798 EmacsFrame ew = (EmacsFrame) widget;
799 struct frame *f = ew->emacs_frame.frame; 799 struct frame *f = ew->emacs_frame.frame;
800 800
801 x_set_window_size (f, 0, columns, rows); 801 x_set_window_size (f, 0, columns, rows, 0);
802} 802}
803 803
804 804
diff --git a/src/window.c b/src/window.c
index bc0adaf459f..d1f3dd599b1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -51,6 +51,7 @@ static Lisp_Object Qrecord_window_buffer;
51static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 51static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
52static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 52static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
53static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; 53static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
54static Lisp_Object Qwindow_pixel_to_total;
54static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 55static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
55static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; 56static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
56 57
@@ -60,7 +61,6 @@ static int get_leaf_windows (struct window *, struct window **, int);
60static void window_scroll (Lisp_Object, EMACS_INT, bool, int); 61static void window_scroll (Lisp_Object, EMACS_INT, bool, int);
61static void window_scroll_pixel_based (Lisp_Object, int, bool, int); 62static void window_scroll_pixel_based (Lisp_Object, int, bool, int);
62static void window_scroll_line_based (Lisp_Object, int, bool, int); 63static void window_scroll_line_based (Lisp_Object, int, bool, int);
63static Lisp_Object window_list (void);
64static int add_window_to_list (struct window *, void *); 64static int add_window_to_list (struct window *, void *);
65static Lisp_Object next_window (Lisp_Object, Lisp_Object, 65static Lisp_Object next_window (Lisp_Object, Lisp_Object,
66 Lisp_Object, int); 66 Lisp_Object, int);
@@ -75,6 +75,7 @@ static int foreach_window_1 (struct window *,
75static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 75static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
76static int window_resize_check (struct window *, bool); 76static int window_resize_check (struct window *, bool);
77static void window_resize_apply (struct window *, bool); 77static void window_resize_apply (struct window *, bool);
78static void window_resize_apply_total (struct window *, bool);
78static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 79static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
79static void select_window_1 (Lisp_Object, bool); 80static void select_window_1 (Lisp_Object, bool);
80 81
@@ -113,6 +114,9 @@ Lisp_Object minibuf_selected_window;
113/* Hook run at end of temp_output_buffer_show. */ 114/* Hook run at end of temp_output_buffer_show. */
114static Lisp_Object Qtemp_buffer_show_hook; 115static Lisp_Object Qtemp_buffer_show_hook;
115 116
117/* Incremented for each window created. */
118static int sequence_number;
119
116/* Nonzero after init_window_once has finished. */ 120/* Nonzero after init_window_once has finished. */
117static int window_initialized; 121static int window_initialized;
118 122
@@ -482,6 +486,15 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
482 record_buffer before returning here. */ 486 record_buffer before returning here. */
483 goto record_and_return; 487 goto record_and_return;
484 488
489 if (NILP (norecord))
490 { /* Mark the window for redisplay since the selected-window has
491 a different mode-line. */
492 wset_redisplay (XWINDOW (selected_window));
493 wset_redisplay (w);
494 }
495 else
496 redisplay_other_windows ();
497
485 sf = SELECTED_FRAME (); 498 sf = SELECTED_FRAME ();
486 if (XFRAME (WINDOW_FRAME (w)) != sf) 499 if (XFRAME (WINDOW_FRAME (w)) != sf)
487 { 500 {
@@ -500,7 +513,6 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
500 513
501 select_window_1 (window, inhibit_point_swap); 514 select_window_1 (window, inhibit_point_swap);
502 bset_last_selected_window (XBUFFER (w->contents), window); 515 bset_last_selected_window (XBUFFER (w->contents), window);
503 windows_or_buffers_changed = 24;
504 516
505 record_and_return: 517 record_and_return:
506 /* record_buffer can run QUIT, so make sure it is run only after we have 518 /* record_buffer can run QUIT, so make sure it is run only after we have
@@ -669,6 +681,31 @@ selected one. */)
669 return make_number (decode_live_window (window)->use_time); 681 return make_number (decode_live_window (window)->use_time);
670} 682}
671 683
684DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
685 doc: /* Return the pixel width of window WINDOW.
686WINDOW must be a valid window and defaults to the selected one.
687
688The return value includes the fringes and margins of WINDOW as well as
689any vertical dividers or scroll bars belonging to WINDOW. If WINDOW is
690an internal window, its pixel width is the width of the screen areas
691spanned by its children. */)
692 (Lisp_Object window)
693{
694 return make_number (decode_valid_window (window)->pixel_width);
695}
696
697DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0,
698 doc: /* Return the pixel height of window WINDOW.
699WINDOW must be a valid window and defaults to the selected one.
700
701The return value includes the mode line and header line, if any. If
702WINDOW is an internal window, its pixel height is the height of the
703screen areas spanned by its children. */)
704 (Lisp_Object window)
705{
706 return make_number (decode_valid_window (window)->pixel_height);
707}
708
672DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0, 709DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
673 doc: /* Return the total height, in lines, of window WINDOW. 710 doc: /* Return the total height, in lines, of window WINDOW.
674WINDOW must be a valid window and defaults to the selected one. 711WINDOW must be a valid window and defaults to the selected one.
@@ -726,6 +763,30 @@ WINDOW must be a valid window and defaults to the selected one. */)
726 return decode_valid_window (window)->new_normal; 763 return decode_valid_window (window)->new_normal;
727} 764}
728 765
766DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
767 doc: /* Return new pixel size of window WINDOW.
768WINDOW must be a valid window and defaults to the selected one. */)
769 (Lisp_Object window)
770{
771 return decode_valid_window (window)->new_pixel;
772}
773
774DEFUN ("window-pixel-left", Fwindow_pixel_left, Swindow_pixel_left, 0, 1, 0,
775 doc: /* Return left pixel edge of window WINDOW.
776WINDOW must be a valid window and defaults to the selected one. */)
777 (Lisp_Object window)
778{
779 return make_number (decode_valid_window (window)->pixel_left);
780}
781
782DEFUN ("window-pixel-top", Fwindow_pixel_top, Swindow_pixel_top, 0, 1, 0,
783 doc: /* Return top pixel edge of window WINDOW.
784WINDOW must be a valid window and defaults to the selected one. */)
785 (Lisp_Object window)
786{
787 return make_number (decode_valid_window (window)->pixel_top);
788}
789
729DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0, 790DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
730 doc: /* Return left column of window WINDOW. 791 doc: /* Return left column of window WINDOW.
731This is the distance, in columns, between the left edge of WINDOW and 792This is the distance, in columns, between the left edge of WINDOW and
@@ -754,75 +815,118 @@ WINDOW must be a valid window and defaults to the selected one. */)
754 header line of W. */ 815 header line of W. */
755 816
756static int 817static int
757window_body_lines (struct window *w) 818window_body_height (struct window *w, bool pixelwise)
758{ 819{
759 int height = w->total_lines; 820 int pixels = (w->pixel_height
760 821 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
761 if (!MINI_WINDOW_P (w)) 822 - WINDOW_HEADER_LINE_HEIGHT (w)
762 { 823 - WINDOW_MODE_LINE_HEIGHT (w));
763 if (WINDOW_WANTS_MODELINE_P (w)) 824 int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
764 --height;
765 if (WINDOW_WANTS_HEADER_LINE_P (w))
766 --height;
767 }
768 825
769 return height; 826 return pixelwise ? pixels : ((pixels + unit - 1) / unit);
770} 827}
771 828
772/* Return the number of columns of W's body. Don't count columns 829/* Return the number of columns of W's body. Don't count columns
773 occupied by the scroll bar or the vertical bar separating W from its 830 occupied by the scroll bar or the vertical bar separating W from its
774 right sibling. On window-systems don't count fringes or display 831 right sibling. On window-systems don't count fringes or display
775 margins either. */ 832 margins either. */
776
777int 833int
778window_body_cols (struct window *w) 834window_body_width (struct window *w, bool pixelwise)
779{ 835{
780 struct frame *f = XFRAME (WINDOW_FRAME (w)); 836 struct frame *f = XFRAME (WINDOW_FRAME (w));
781 int width = w->total_cols;
782 837
783 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) 838 int pixels = (w->pixel_width
784 /* Scroll bars occupy a few columns. */ 839 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
785 width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w); 840 - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
786 else if (!FRAME_WINDOW_P (f) 841 ? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
787 && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w)) 842 : ((!FRAME_WINDOW_P (f)
788 /* The column of `|' characters separating side-by-side windows 843 && !WINDOW_RIGHTMOST_P (w)
789 occupies one column only. */ 844 && !WINDOW_RIGHT_DIVIDER_WIDTH (w)
790 width -= 1; 845 && !WINDOW_FULL_WIDTH_P (w))
846 /* According to Eli this is either 1 or 0. */
847 ? 1 : 0))
848 - WINDOW_MARGINS_WIDTH (w)
849 - (FRAME_WINDOW_P (f)
850 ? WINDOW_FRINGES_WIDTH (w)
851 : 0));
852 int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
853
854 return pixelwise ? pixels : ((pixels + unit - 1) / unit);
855}
856
857DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0,
858 doc: /* Return the height, in lines, of WINDOW's text area.
859WINDOW must be a live window and defaults to the selected one.
791 860
792 /* Display margins cannot be used for normal text. */ 861Optional argument PIXELWISE non-nil means return the height in pixels.
793 width -= WINDOW_LEFT_MARGIN_COLS (w) + WINDOW_RIGHT_MARGIN_COLS (w);
794 862
795 if (FRAME_WINDOW_P (f)) 863The returned height does not include the mode line or header line. On a
796 /* On window-systems, fringes cannot be used for normal text. */ 864graphical display, the height is expressed as an integer multiple of the
797 width -= WINDOW_FRINGE_COLS (w); 865default character height if PIXELWISE is nil.
798 866
799 return width; 867If PIXELWISE is nil and a line at the bottom of the text area is only
868partially visible, that counts as a whole line; to exclude
869partially-visible lines, use `window-text-height'. */)
870 (Lisp_Object window, Lisp_Object pixelwise)
871{
872 return make_number (window_body_height (decode_live_window (window),
873 NILP (pixelwise) ? 0 : 1));
800} 874}
801 875
802DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 1, 0, 876DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0,
803 doc: /* Return the height, in lines, of WINDOW's text area. 877 doc: /* Return the width, in columns, of WINDOW's text area.
804WINDOW must be a live window and defaults to the selected one. 878WINDOW must be a live window and defaults to the selected one.
805 879
806The returned height does not include the mode line or header line. 880Optional argument PIXELWISE non-nil means return the width in pixels.
807On a graphical display, the height is expressed as an integer multiple 881
808of the default character height. If a line at the bottom of the text 882The return value does not include any vertical dividers, fringe or
809area is only partially visible, that counts as a whole line; to 883marginal areas, or scroll bars. On a graphical display, the width is
810exclude partially-visible lines, use `window-text-height'. */) 884expressed as an integer multiple of the default character width if
885PIXELWISE is nil.
886
887If PIXELWISE is nil and a column at the right of the text area is only
888partially visible, that counts as a whole column; to exclude
889partially-visible columns, use `window-text-width'. */)
890 (Lisp_Object window, Lisp_Object pixelwise)
891{
892 return make_number (window_body_width (decode_live_window (window),
893 NILP (pixelwise) ? 0 : 1));
894}
895
896DEFUN ("window-mode-line-height", Fwindow_mode_line_height,
897 Swindow_mode_line_height, 0, 1, 0,
898 doc: /* Return the height in pixel of WINDOW's mode-line.
899WINDOW must be a live window and defaults to the selected one. */)
811 (Lisp_Object window) 900 (Lisp_Object window)
812{ 901{
813 return make_number (window_body_lines (decode_live_window (window))); 902 return (make_number (WINDOW_MODE_LINE_HEIGHT (decode_live_window (window))));
814} 903}
815 904
816DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0, 905DEFUN ("window-header-line-height", Fwindow_header_line_height,
817 doc: /* Return the width, in columns, of WINDOW's text area. 906 Swindow_header_line_height, 0, 1, 0,
818WINDOW must be a live window and defaults to the selected one. 907 doc: /* Return the height in pixel of WINDOW's header-line.
908WINDOW must be a live window and defaults to the selected one. */)
909 (Lisp_Object window)
910{
911 return (make_number (WINDOW_HEADER_LINE_HEIGHT (decode_live_window (window))));
912}
819 913
820The return value does not include any vertical dividers, fringe or 914DEFUN ("window-right-divider-width", Fwindow_right_divider_width,
821marginal areas, or scroll bars. On a graphical display, the width is 915 Swindow_right_divider_width, 0, 1, 0,
822expressed as an integer multiple of the default character width. */) 916 doc: /* Return the width of WINDOW's right divider.
917WINDOW must be a live window and defaults to the selected one. */)
918 (Lisp_Object window)
919{
920 return (make_number (WINDOW_RIGHT_DIVIDER_WIDTH (decode_live_window (window))));
921}
922
923DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width,
924 Swindow_bottom_divider_width, 0, 1, 0,
925 doc: /* Return the width of WINDOW's bottom divider.
926WINDOW must be a live window and defaults to the selected one. */)
823 (Lisp_Object window) 927 (Lisp_Object window)
824{ 928{
825 return make_number (window_body_cols (decode_live_window (window))); 929 return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window))));
826} 930}
827 931
828DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 932DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
@@ -1072,11 +1176,15 @@ display margins, fringes, header line, and/or mode line. */)
1072 1176
1073/* Test if the character at column X, row Y is within window W. 1177/* Test if the character at column X, row Y is within window W.
1074 If it is not, return ON_NOTHING; 1178 If it is not, return ON_NOTHING;
1179 if it is on the window's vertical divider, return
1180 ON_RIGHT_DIVIDER;
1181 if it is on the window's horizontal divider, return
1182 ON_BOTTOM_DIVIDER;
1075 if it is in the window's text area, return ON_TEXT; 1183 if it is in the window's text area, return ON_TEXT;
1076 if it is on the window's modeline, return ON_MODE_LINE; 1184 if it is on the window's modeline, return ON_MODE_LINE;
1077 if it is on the border between the window and its right sibling, 1185 if it is on the border between the window and its right sibling,
1078 return ON_VERTICAL_BORDER. 1186 return ON_VERTICAL_BORDER;
1079 if it is on a scroll bar, return ON_SCROLL_BAR. 1187 if it is on a scroll bar, return ON_SCROLL_BAR;
1080 if it is on the window's top line, return ON_HEADER_LINE; 1188 if it is on the window's top line, return ON_HEADER_LINE;
1081 if it is in left or right fringe of the window, 1189 if it is in left or right fringe of the window,
1082 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE; 1190 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
@@ -1104,13 +1212,28 @@ coordinates_in_window (register struct window *w, int x, int y)
1104 if (y < top_y || y >= bottom_y || x < left_x || x >= right_x) 1212 if (y < top_y || y >= bottom_y || x < left_x || x >= right_x)
1105 return ON_NOTHING; 1213 return ON_NOTHING;
1106 1214
1107 /* On the mode line or header line? */ 1215 /* On vertical window divider (which prevails horizontal
1108 if ((WINDOW_WANTS_MODELINE_P (w) 1216 dividers)? */
1109 && y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w) 1217 if (!WINDOW_RIGHTMOST_P (w)
1110 && (part = ON_MODE_LINE)) 1218 && WINDOW_RIGHT_DIVIDER_WIDTH (w)
1111 || (WINDOW_WANTS_HEADER_LINE_P (w) 1219 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1112 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w) 1220 && x <= right_x)
1113 && (part = ON_HEADER_LINE))) 1221 return ON_RIGHT_DIVIDER;
1222 /* On the horizontal window divider? */
1223 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1224 && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1225 && y <= bottom_y)
1226 return ON_BOTTOM_DIVIDER;
1227 /* On the mode or header line? */
1228 else if ((WINDOW_WANTS_MODELINE_P (w)
1229 && y >= (bottom_y
1230 - CURRENT_MODE_LINE_HEIGHT (w)
1231 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1232 && y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1233 && (part = ON_MODE_LINE))
1234 || (WINDOW_WANTS_HEADER_LINE_P (w)
1235 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
1236 && (part = ON_HEADER_LINE)))
1114 { 1237 {
1115 /* If it's under/over the scroll bar portion of the mode/header 1238 /* If it's under/over the scroll bar portion of the mode/header
1116 line, say it's on the vertical line. That's to be able to 1239 line, say it's on the vertical line. That's to be able to
@@ -1133,7 +1256,7 @@ coordinates_in_window (register struct window *w, int x, int y)
1133 if (w->pseudo_window_p) 1256 if (w->pseudo_window_p)
1134 { 1257 {
1135 left_x = 0; 1258 left_x = 0;
1136 right_x = WINDOW_TOTAL_WIDTH (w) - 1; 1259 right_x = WINDOW_PIXEL_WIDTH (w) - 1;
1137 } 1260 }
1138 else 1261 else
1139 { 1262 {
@@ -1163,6 +1286,8 @@ coordinates_in_window (register struct window *w, int x, int y)
1163 terminals, the vertical line's x coordinate is right_x. */ 1286 terminals, the vertical line's x coordinate is right_x. */
1164 else if (!w->pseudo_window_p 1287 else if (!w->pseudo_window_p
1165 && !WINDOW_RIGHTMOST_P (w) 1288 && !WINDOW_RIGHTMOST_P (w)
1289 /* Why check ux if we are not the rightmost window? Also
1290 shouldn't a pseudo window always be rightmost? */
1166 && x > right_x - ux) 1291 && x > right_x - ux)
1167 return ON_VERTICAL_BORDER; 1292 return ON_VERTICAL_BORDER;
1168 1293
@@ -1218,7 +1343,7 @@ window_relative_x_coord (struct window *w, enum window_part part, int x)
1218 case ON_RIGHT_MARGIN: 1343 case ON_RIGHT_MARGIN:
1219 return (x + 1 1344 return (x + 1
1220 - ((w->pseudo_window_p) 1345 - ((w->pseudo_window_p)
1221 ? WINDOW_TOTAL_WIDTH (w) 1346 ? WINDOW_PIXEL_WIDTH (w)
1222 : WINDOW_BOX_RIGHT_EDGE_X (w)) 1347 : WINDOW_BOX_RIGHT_EDGE_X (w))
1223 + window_box_width (w, RIGHT_MARGIN_AREA) 1348 + window_box_width (w, RIGHT_MARGIN_AREA)
1224 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) 1349 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
@@ -1303,6 +1428,12 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1303 /* Historically we are supposed to return nil in this case. */ 1428 /* Historically we are supposed to return nil in this case. */
1304 return Qnil; 1429 return Qnil;
1305 1430
1431 case ON_RIGHT_DIVIDER:
1432 return Qright_divider;
1433
1434 case ON_BOTTOM_DIVIDER:
1435 return Qbottom_divider;
1436
1306 default: 1437 default:
1307 emacs_abort (); 1438 emacs_abort ();
1308 } 1439 }
@@ -1553,7 +1684,7 @@ Return POS. */)
1553 set_marker_restricted (w->pointm, pos, w->contents); 1684 set_marker_restricted (w->pointm, pos, w->contents);
1554 /* We have to make sure that redisplay updates the window to show 1685 /* We have to make sure that redisplay updates the window to show
1555 the new value of point. */ 1686 the new value of point. */
1556 windows_or_buffers_changed = 25; 1687 wset_redisplay (w);
1557 } 1688 }
1558 1689
1559 return pos; 1690 return pos;
@@ -1574,9 +1705,9 @@ overriding motion of point in order to display at this exact start. */)
1574 if (NILP (noforce)) 1705 if (NILP (noforce))
1575 w->force_start = 1; 1706 w->force_start = 1;
1576 w->update_mode_line = 1; 1707 w->update_mode_line = 1;
1577 if (w != XWINDOW (selected_window)) 1708 /* Bug#15957. */
1578 /* Enforce full redisplay. FIXME: make it more selective. */ 1709 w->window_end_valid = 0;
1579 windows_or_buffers_changed = 26; 1710 wset_redisplay (w);
1580 1711
1581 return pos; 1712 return pos;
1582} 1713}
@@ -1995,6 +2126,10 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1995 2126
1996 if (setflag) 2127 if (setflag)
1997 { 2128 {
2129 n->pixel_left = o->pixel_left;
2130 n->pixel_top = o->pixel_top;
2131 n->pixel_width = o->pixel_width;
2132 n->pixel_height = o->pixel_height;
1998 n->left_col = o->left_col; 2133 n->left_col = o->left_col;
1999 n->top_line = o->top_line; 2134 n->top_line = o->top_line;
2000 n->total_cols = o->total_cols; 2135 n->total_cols = o->total_cols;
@@ -2075,13 +2210,13 @@ recombine_windows (Lisp_Object window)
2075 wset_parent (c, parent); 2210 wset_parent (c, parent);
2076 2211
2077 if (horflag) 2212 if (horflag)
2078 wset_normal_cols (c, 2213 wset_normal_cols
2079 make_float ((double) c->total_cols 2214 (c, make_float ((double) c->pixel_width
2080 / (double) p->total_cols)); 2215 / (double) p->pixel_width));
2081 else 2216 else
2082 wset_normal_lines (c, 2217 wset_normal_lines
2083 make_float ((double) c->total_lines 2218 (c, make_float ((double) c->pixel_height
2084 / (double) p->total_lines)); 2219 / (double) p->pixel_height));
2085 2220
2086 if (NILP (c->next)) 2221 if (NILP (c->next))
2087 { 2222 {
@@ -2137,7 +2272,7 @@ add_window_to_list (struct window *w, void *user_data)
2137 Vwindow_list is a list, return that list. Otherwise, build a new 2272 Vwindow_list is a list, return that list. Otherwise, build a new
2138 list, cache it in Vwindow_list, and return that. */ 2273 list, cache it in Vwindow_list, and return that. */
2139 2274
2140static Lisp_Object 2275Lisp_Object
2141window_list (void) 2276window_list (void)
2142{ 2277{
2143 if (!CONSP (Vwindow_list)) 2278 if (!CONSP (Vwindow_list))
@@ -2712,9 +2847,16 @@ selected frame and no others. */)
2712} 2847}
2713 2848
2714static Lisp_Object 2849static Lisp_Object
2715resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) 2850resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise)
2716{ 2851{
2717 return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore); 2852 return call5 (Qwindow_resize_root_window, window, delta, horizontal, ignore, pixelwise);
2853}
2854
2855
2856static Lisp_Object
2857window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
2858{
2859 return call2(Qwindow_pixel_to_total, frame, horizontal);
2718} 2860}
2719 2861
2720 2862
@@ -2778,8 +2920,8 @@ window-start value is reasonable when this function is called. */)
2778 { 2920 {
2779 startpos = marker_position (w->start); 2921 startpos = marker_position (w->start);
2780 startbyte = marker_byte_position (w->start); 2922 startbyte = marker_byte_position (w->start);
2781 top = WINDOW_TOP_EDGE_LINE (w) 2923 top = (WINDOW_TOP_EDGE_LINE (w)
2782 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2924 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))));
2783 /* Make sure WINDOW is the frame's selected window. */ 2925 /* Make sure WINDOW is the frame's selected window. */
2784 if (!EQ (window, FRAME_SELECTED_WINDOW (f))) 2926 if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
2785 { 2927 {
@@ -2837,7 +2979,7 @@ window-start value is reasonable when this function is called. */)
2837 } 2979 }
2838 free_window_matrices (r); 2980 free_window_matrices (r);
2839 2981
2840 windows_or_buffers_changed = 27; 2982 fset_redisplay (f);
2841 Vwindow_list = Qnil; 2983 Vwindow_list = Qnil;
2842 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 2984 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2843 resize_failed = 0; 2985 resize_failed = 0;
@@ -2845,16 +2987,23 @@ window-start value is reasonable when this function is called. */)
2845 if (!WINDOW_LEAF_P (w)) 2987 if (!WINDOW_LEAF_P (w))
2846 { 2988 {
2847 /* Resize child windows vertically. */ 2989 /* Resize child windows vertically. */
2848 XSETINT (delta, r->total_lines - w->total_lines); 2990 XSETINT (delta, r->pixel_height - w->pixel_height);
2991 w->pixel_top = r->pixel_top;
2849 w->top_line = r->top_line; 2992 w->top_line = r->top_line;
2850 resize_root_window (window, delta, Qnil, Qnil); 2993 resize_root_window (window, delta, Qnil, Qnil, Qt);
2851 if (window_resize_check (w, 0)) 2994 if (window_resize_check (w, 0))
2852 window_resize_apply (w, 0); 2995 {
2996 window_resize_apply (w, 0);
2997 window_pixel_to_total (w->frame, Qnil);
2998 }
2853 else 2999 else
2854 { 3000 {
2855 resize_root_window (window, delta, Qnil, Qt); 3001 resize_root_window (window, delta, Qnil, Qt, Qt);
2856 if (window_resize_check (w, 0)) 3002 if (window_resize_check (w, 0))
2857 window_resize_apply (w, 0); 3003 {
3004 window_resize_apply (w, 0);
3005 window_pixel_to_total (w->frame, Qnil);
3006 }
2858 else 3007 else
2859 resize_failed = 1; 3008 resize_failed = 1;
2860 } 3009 }
@@ -2863,15 +3012,22 @@ window-start value is reasonable when this function is called. */)
2863 if (!resize_failed) 3012 if (!resize_failed)
2864 { 3013 {
2865 w->left_col = r->left_col; 3014 w->left_col = r->left_col;
2866 XSETINT (delta, r->total_cols - w->total_cols); 3015 w->pixel_left = r->pixel_left;
2867 resize_root_window (window, delta, Qt, Qnil); 3016 XSETINT (delta, r->pixel_width - w->pixel_width);
3017 resize_root_window (window, delta, Qt, Qnil, Qt);
2868 if (window_resize_check (w, 1)) 3018 if (window_resize_check (w, 1))
2869 window_resize_apply (w, 1); 3019 {
3020 window_resize_apply (w, 1);
3021 window_pixel_to_total (w->frame, Qt);
3022 }
2870 else 3023 else
2871 { 3024 {
2872 resize_root_window (window, delta, Qt, Qt); 3025 resize_root_window (window, delta, Qt, Qt, Qt);
2873 if (window_resize_check (w, 1)) 3026 if (window_resize_check (w, 1))
2874 window_resize_apply (w, 1); 3027 {
3028 window_resize_apply (w, 1);
3029 window_pixel_to_total (w->frame, Qt);
3030 }
2875 else 3031 else
2876 resize_failed = 1; 3032 resize_failed = 1;
2877 } 3033 }
@@ -2980,27 +3136,46 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
2980 } 3136 }
2981} 3137}
2982 3138
2983/* If *ROWS or *COLS are too small a size for FRAME, set them to the 3139/* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
2984 minimum allowable size. */ 3140 minimum allowable size. PIXELWISE means interpret these as pixel
3141 sizes. */
2985 3142
2986void 3143void
2987check_frame_size (struct frame *frame, int *rows, int *cols) 3144check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise)
2988{ 3145{
2989 /* For height, we have to see: 3146 /* For height, we have to see:
2990 how many windows the frame has at minimum (one or two), 3147 how many windows the frame has at minimum (one or two),
2991 and whether it has a menu bar or other special stuff at the top. */ 3148 and whether it has a menu bar or other special stuff at the top. */
2992 int min_height 3149 if (pixelwise)
2993 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame)) 3150 {
2994 ? MIN_SAFE_WINDOW_HEIGHT 3151 int min_height = MIN_SAFE_WINDOW_HEIGHT * FRAME_LINE_HEIGHT (frame);
2995 : 2 * MIN_SAFE_WINDOW_HEIGHT); 3152 int min_width = MIN_SAFE_WINDOW_WIDTH * FRAME_COLUMN_WIDTH (frame);
3153
3154 if (!FRAME_MINIBUF_ONLY_P (frame) && FRAME_HAS_MINIBUF_P (frame))
3155 min_height = 2 * min_height;
2996 3156
2997 if (FRAME_TOP_MARGIN (frame) > 0) 3157 min_height += FRAME_TOP_MARGIN_HEIGHT (frame);
2998 min_height += FRAME_TOP_MARGIN (frame);
2999 3158
3000 if (*rows < min_height) 3159 if (*height < min_height)
3001 *rows = min_height; 3160 *height = min_height;
3002 if (*cols < MIN_SAFE_WINDOW_WIDTH) 3161 if (*width < min_width)
3003 *cols = MIN_SAFE_WINDOW_WIDTH; 3162 *width = min_width;
3163 }
3164 else
3165 {
3166 int min_height
3167 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
3168 ? MIN_SAFE_WINDOW_HEIGHT
3169 : 2 * MIN_SAFE_WINDOW_HEIGHT);
3170
3171 if (FRAME_TOP_MARGIN (frame) > 0)
3172 min_height += FRAME_TOP_MARGIN (frame);
3173
3174 if (*height < min_height)
3175 *height = min_height;
3176 if (*width < MIN_SAFE_WINDOW_WIDTH)
3177 *width = MIN_SAFE_WINDOW_WIDTH;
3178 }
3004} 3179}
3005 3180
3006/* Adjust the margins of window W if text area is too small. 3181/* Adjust the margins of window W if text area is too small.
@@ -3010,31 +3185,37 @@ check_frame_size (struct frame *frame, int *rows, int *cols)
3010static int 3185static int
3011adjust_window_margins (struct window *w) 3186adjust_window_margins (struct window *w)
3012{ 3187{
3013 int box_cols = (WINDOW_TOTAL_COLS (w) 3188 int box_width = (WINDOW_PIXEL_WIDTH (w)
3014 - WINDOW_FRINGE_COLS (w) 3189 - WINDOW_FRINGES_WIDTH (w)
3015 - WINDOW_SCROLL_BAR_COLS (w)); 3190 - WINDOW_SCROLL_BAR_AREA_WIDTH (w));
3016 int margin_cols = (WINDOW_LEFT_MARGIN_COLS (w) 3191 int margin_width = WINDOW_MARGINS_WIDTH (w);
3017 + WINDOW_RIGHT_MARGIN_COLS (w));
3018 3192
3019 if (box_cols - margin_cols >= MIN_SAFE_WINDOW_WIDTH) 3193 if (box_width - margin_width >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3020 return 1; 3194 return 1;
3021 3195
3022 if (margin_cols < 0 || box_cols < MIN_SAFE_WINDOW_WIDTH) 3196 if (margin_width < 0 || box_width < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3023 return 0; 3197 return 0;
3024 3198 else
3025 /* Window's text area is too narrow, but reducing the window 3199 /* Window's text area is too narrow, but reducing the window
3026 margins will fix that. */ 3200 margins will fix that. */
3027 margin_cols = box_cols - MIN_SAFE_WINDOW_WIDTH;
3028 if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
3029 { 3201 {
3030 if (WINDOW_LEFT_MARGIN_COLS (w) > 0) 3202 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
3031 w->left_margin_cols = w->right_margin_cols = margin_cols / 2; 3203
3204 margin_width = box_width - MIN_SAFE_WINDOW_PIXEL_WIDTH (w);
3205
3206 if (WINDOW_RIGHT_MARGIN_WIDTH (w) > 0)
3207 {
3208 if (WINDOW_LEFT_MARGIN_WIDTH (w) > 0)
3209 w->left_margin_cols = w->right_margin_cols =
3210 margin_width / (2 * unit);
3211 else
3212 w->right_margin_cols = margin_width / unit;
3213 }
3032 else 3214 else
3033 w->right_margin_cols = margin_cols; 3215 w->left_margin_cols = margin_width / unit;
3216
3217 return 1;
3034 } 3218 }
3035 else
3036 w->left_margin_cols = margin_cols;
3037 return 1;
3038} 3219}
3039 3220
3040/* The following three routines are needed for running a window's 3221/* The following three routines are needed for running a window's
@@ -3119,11 +3300,23 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
3119 return Qnil; 3300 return Qnil;
3120} 3301}
3121 3302
3122/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero 3303DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions,
3123 means it's allowed to run hooks. See make_frame for a case where 3304 Srun_window_scroll_functions, 0, 1, 0,
3124 it's not allowed. KEEP_MARGINS_P non-zero means that the current 3305 doc: /* Run `window-scroll-functions' for WINDOW.
3125 margins, fringes, and scroll-bar settings of the window are not 3306If WINDOW is omitted or nil, it defaults to the selected window. */)
3126 reset from the buffer's local settings. */ 3307 (Lisp_Object window)
3308{
3309 if (! NILP (Vwindow_scroll_functions))
3310 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3311 Fmarker_position (decode_live_window (window)->start));
3312 return Qnil;
3313}
3314
3315/* Make WINDOW display BUFFER. RUN_HOOKS_P non-zero means it's allowed
3316 to run hooks. See make_frame for a case where it's not allowed.
3317 KEEP_MARGINS_P non-zero means that the current margins, fringes, and
3318 scroll-bar settings of the window are not reset from the buffer's
3319 local settings. */
3127 3320
3128void 3321void
3129set_window_buffer (Lisp_Object window, Lisp_Object buffer, 3322set_window_buffer (Lisp_Object window, Lisp_Object buffer,
@@ -3132,7 +3325,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3132 struct window *w = XWINDOW (window); 3325 struct window *w = XWINDOW (window);
3133 struct buffer *b = XBUFFER (buffer); 3326 struct buffer *b = XBUFFER (buffer);
3134 ptrdiff_t count = SPECPDL_INDEX (); 3327 ptrdiff_t count = SPECPDL_INDEX ();
3135 int samebuf = EQ (buffer, w->contents); 3328 bool samebuf = EQ (buffer, w->contents);
3136 3329
3137 wset_buffer (w, buffer); 3330 wset_buffer (w, buffer);
3138 3331
@@ -3171,7 +3364,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3171 } 3364 }
3172 /* Maybe we could move this into the `if' but it's not obviously safe and 3365 /* Maybe we could move this into the `if' but it's not obviously safe and
3173 I doubt it's worth the trouble. */ 3366 I doubt it's worth the trouble. */
3174 windows_or_buffers_changed = 28; 3367 wset_redisplay (w);
3175 3368
3176 /* We must select BUFFER for running the window-scroll-functions. */ 3369 /* We must select BUFFER for running the window-scroll-functions. */
3177 /* We can't check ! NILP (Vwindow_scroll_functions) here 3370 /* We can't check ! NILP (Vwindow_scroll_functions) here
@@ -3202,14 +3395,15 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3202 if (! NILP (Vwindow_scroll_functions)) 3395 if (! NILP (Vwindow_scroll_functions))
3203 run_hook_with_args_2 (Qwindow_scroll_functions, window, 3396 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3204 Fmarker_position (w->start)); 3397 Fmarker_position (w->start));
3205 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w))); 3398 if (!samebuf)
3399 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w)));
3206 } 3400 }
3207 3401
3208 unbind_to (count, Qnil); 3402 unbind_to (count, Qnil);
3209} 3403}
3210 3404
3211DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, 3405DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
3212 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. 3406 doc: /* Make WINDOW display BUFFER-OR-NAME.
3213WINDOW must be a live window and defaults to the selected one. 3407WINDOW must be a live window and defaults to the selected one.
3214BUFFER-OR-NAME must be a buffer or the name of an existing buffer. 3408BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
3215 3409
@@ -3381,6 +3575,8 @@ make_parent_window (Lisp_Object window, bool horflag)
3381 adjust_window_count (p, 1); 3575 adjust_window_count (p, 1);
3382 XSETWINDOW (parent, p); 3576 XSETWINDOW (parent, p);
3383 3577
3578 p->sequence_number = ++sequence_number;
3579
3384 replace_window (window, parent, 1); 3580 replace_window (window, parent, 1);
3385 3581
3386 wset_next (o, Qnil); 3582 wset_next (o, Qnil);
@@ -3409,6 +3605,7 @@ make_window (void)
3409 wset_normal_cols (w, make_float (1.0)); 3605 wset_normal_cols (w, make_float (1.0));
3410 wset_new_total (w, make_number (0)); 3606 wset_new_total (w, make_number (0));
3411 wset_new_normal (w, make_number (0)); 3607 wset_new_normal (w, make_number (0));
3608 wset_new_pixel (w, make_number (0));
3412 wset_start (w, Fmake_marker ()); 3609 wset_start (w, Fmake_marker ());
3413 wset_pointm (w, Fmake_marker ()); 3610 wset_pointm (w, Fmake_marker ());
3414 wset_vertical_scroll_bar_type (w, Qt); 3611 wset_vertical_scroll_bar_type (w, Qt);
@@ -3426,6 +3623,7 @@ make_window (void)
3426 w->phys_cursor_type = NO_CURSOR; 3623 w->phys_cursor_type = NO_CURSOR;
3427 w->phys_cursor_width = -1; 3624 w->phys_cursor_width = -1;
3428#endif 3625#endif
3626 w->sequence_number = ++sequence_number;
3429 w->scroll_bar_width = -1; 3627 w->scroll_bar_width = -1;
3430 w->column_number_displayed = -1; 3628 w->column_number_displayed = -1;
3431 3629
@@ -3436,6 +3634,30 @@ make_window (void)
3436 return window; 3634 return window;
3437} 3635}
3438 3636
3637DEFUN ("set-window-new-pixel", Fset_window_new_pixel, Sset_window_new_pixel, 2, 3, 0,
3638 doc: /* Set new pixel size of WINDOW to SIZE.
3639WINDOW must be a valid window and defaults to the selected one.
3640Return SIZE.
3641
3642Optional argument ADD non-nil means add SIZE to the new pixel size of
3643WINDOW and return the sum.
3644
3645Note: This function does not operate on any child windows of WINDOW. */)
3646 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
3647{
3648 struct window *w = decode_valid_window (window);
3649 EMACS_INT size_min = NILP (add) ? 0 : - XINT (w->new_pixel);
3650 EMACS_INT size_max = size_min + min (INT_MAX, MOST_POSITIVE_FIXNUM);
3651
3652 CHECK_RANGED_INTEGER (size, size_min, size_max);
3653 if (NILP (add))
3654 wset_new_pixel (w, size);
3655 else
3656 wset_new_pixel (w, make_number (XINT (w->new_pixel) + XINT (size)));
3657
3658 return w->new_pixel;
3659}
3660
3439DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0, 3661DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
3440 doc: /* Set new total size of WINDOW to SIZE. 3662 doc: /* Set new total size of WINDOW to SIZE.
3441WINDOW must be a valid window and defaults to the selected one. 3663WINDOW must be a valid window and defaults to the selected one.
@@ -3470,8 +3692,8 @@ Note: This function does not operate on any child windows of WINDOW. */)
3470 return size; 3692 return size;
3471} 3693}
3472 3694
3473/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is 3695/* Return 1 if setting w->pixel_height (w->pixel_width if HORFLAG is
3474 non-zero) to w->new_total would result in correct heights (widths) 3696 non-zero) to w->new_pixel would result in correct heights (widths)
3475 for window W and recursively all child windows of W. 3697 for window W and recursively all child windows of W.
3476 3698
3477 Note: This function does not check any of `window-fixed-size-p', 3699 Note: This function does not check any of `window-fixed-size-p',
@@ -3480,6 +3702,7 @@ Note: This function does not operate on any child windows of WINDOW. */)
3480static int 3702static int
3481window_resize_check (struct window *w, bool horflag) 3703window_resize_check (struct window *w, bool horflag)
3482{ 3704{
3705 struct frame *f = XFRAME (w->frame);
3483 struct window *c; 3706 struct window *c;
3484 3707
3485 if (WINDOW_VERTICAL_COMBINATION_P (w)) 3708 if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -3491,26 +3714,33 @@ window_resize_check (struct window *w, bool horflag)
3491 { 3714 {
3492 while (c) 3715 while (c)
3493 { 3716 {
3494 if ((XINT (c->new_total) != XINT (w->new_total)) 3717 if (XINT (c->new_pixel) != XINT (w->new_pixel)
3495 || !window_resize_check (c, horflag)) 3718 || !window_resize_check (c, horflag))
3496 return 0; 3719 return 0;
3720
3497 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3721 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3498 } 3722 }
3723
3499 return 1; 3724 return 1;
3500 } 3725 }
3501 else 3726 else
3502 /* The sum of the heights of the child windows of W must equal 3727 /* The sum of the heights of the child windows of W must equal
3503 W's height. */ 3728 W's height. */
3504 { 3729 {
3505 int sum_of_sizes = 0; 3730 int remaining_pixels = XINT (w->new_pixel);
3731
3506 while (c) 3732 while (c)
3507 { 3733 {
3508 if (!window_resize_check (c, horflag)) 3734 if (!window_resize_check (c, horflag))
3509 return 0; 3735 return 0;
3510 sum_of_sizes = sum_of_sizes + XINT (c->new_total); 3736
3737 remaining_pixels -= XINT (c->new_pixel);
3738 if (remaining_pixels < 0)
3739 return 0;
3511 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3740 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3512 } 3741 }
3513 return (sum_of_sizes == XINT (w->new_total)); 3742
3743 return remaining_pixels == 0;
3514 } 3744 }
3515 } 3745 }
3516 else if (WINDOW_HORIZONTAL_COMBINATION_P (w)) 3746 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
@@ -3521,26 +3751,33 @@ window_resize_check (struct window *w, bool horflag)
3521 /* The sum of the widths of the child windows of W must equal W's 3751 /* The sum of the widths of the child windows of W must equal W's
3522 width. */ 3752 width. */
3523 { 3753 {
3524 int sum_of_sizes = 0; 3754 int remaining_pixels = XINT (w->new_pixel);
3755
3525 while (c) 3756 while (c)
3526 { 3757 {
3527 if (!window_resize_check (c, horflag)) 3758 if (!window_resize_check (c, horflag))
3528 return 0; 3759 return 0;
3529 sum_of_sizes = sum_of_sizes + XINT (c->new_total); 3760
3761 remaining_pixels -= XINT (c->new_pixel);
3762 if (remaining_pixels < 0)
3763 return 0;
3530 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3764 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3531 } 3765 }
3532 return (sum_of_sizes == XINT (w->new_total)); 3766
3767 return remaining_pixels == 0;
3533 } 3768 }
3534 else 3769 else
3535 /* All child windows of W must have the same height as W. */ 3770 /* All child windows of W must have the same height as W. */
3536 { 3771 {
3537 while (c) 3772 while (c)
3538 { 3773 {
3539 if ((XINT (c->new_total) != XINT (w->new_total)) 3774 if (XINT (c->new_pixel) != XINT (w->new_pixel)
3540 || !window_resize_check (c, horflag)) 3775 || !window_resize_check (c, horflag))
3541 return 0; 3776 return 0;
3777
3542 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3778 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3543 } 3779 }
3780
3544 return 1; 3781 return 1;
3545 } 3782 }
3546 } 3783 }
@@ -3548,12 +3785,15 @@ window_resize_check (struct window *w, bool horflag)
3548 /* A leaf window. Make sure it's not too small. The following 3785 /* A leaf window. Make sure it's not too small. The following
3549 hardcodes the values of `window-safe-min-width' (2) and 3786 hardcodes the values of `window-safe-min-width' (2) and
3550 `window-safe-min-height' (1) which are defined in window.el. */ 3787 `window-safe-min-height' (1) which are defined in window.el. */
3551 return XINT (w->new_total) >= (horflag ? 2 : 1); 3788 return (XINT (w->new_pixel) >= (horflag
3789 ? (2 * FRAME_COLUMN_WIDTH (f))
3790 : FRAME_LINE_HEIGHT (f)));
3552} 3791}
3553 3792
3554/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to 3793
3555 w->new_total for window W and recursively all child windows of W. 3794/* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to
3556 Also calculate and assign the new vertical (horizontal) start 3795 w->new_pixel for window W and recursively all child windows of W.
3796 Also calculate and assign the new vertical (horizontal) pixel start
3557 positions of each of these windows. 3797 positions of each of these windows.
3558 3798
3559 This function does not perform any error checks. Make sure you have 3799 This function does not perform any error checks. Make sure you have
@@ -3562,25 +3802,30 @@ static void
3562window_resize_apply (struct window *w, bool horflag) 3802window_resize_apply (struct window *w, bool horflag)
3563{ 3803{
3564 struct window *c; 3804 struct window *c;
3565 int pos; 3805 int edge;
3806 int unit = (horflag
3807 ? FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))
3808 : FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
3566 3809
3567 /* Note: Assigning new_normal requires that the new total size of the 3810 /* Note: Assigning new_normal requires that the new total size of the
3568 parent window has been set *before*. */ 3811 parent window has been set *before*. */
3569 if (horflag) 3812 if (horflag)
3570 { 3813 {
3571 w->total_cols = XFASTINT (w->new_total); 3814 w->pixel_width = XFASTINT (w->new_pixel);
3815 w->total_cols = w->pixel_width / unit;
3572 if (NUMBERP (w->new_normal)) 3816 if (NUMBERP (w->new_normal))
3573 wset_normal_cols (w, w->new_normal); 3817 wset_normal_cols (w, w->new_normal);
3574 3818
3575 pos = w->left_col; 3819 edge = w->pixel_left;
3576 } 3820 }
3577 else 3821 else
3578 { 3822 {
3579 w->total_lines = XFASTINT (w->new_total); 3823 w->pixel_height = XFASTINT (w->new_pixel);
3824 w->total_lines = w->pixel_height / unit;
3580 if (NUMBERP (w->new_normal)) 3825 if (NUMBERP (w->new_normal))
3581 wset_normal_lines (w, w->new_normal); 3826 wset_normal_lines (w, w->new_normal);
3582 3827
3583 pos = w->top_line; 3828 edge = w->pixel_top;
3584 } 3829 }
3585 3830
3586 if (WINDOW_VERTICAL_COMBINATION_P (w)) 3831 if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -3590,12 +3835,19 @@ window_resize_apply (struct window *w, bool horflag)
3590 while (c) 3835 while (c)
3591 { 3836 {
3592 if (horflag) 3837 if (horflag)
3593 c->left_col = pos; 3838 {
3839 c->pixel_left = edge;
3840 c->left_col = edge / unit;
3841 }
3594 else 3842 else
3595 c->top_line = pos; 3843 {
3844 c->pixel_top = edge;
3845 c->top_line = edge / unit;
3846 }
3596 window_resize_apply (c, horflag); 3847 window_resize_apply (c, horflag);
3597 if (!horflag) 3848 if (!horflag)
3598 pos = pos + c->total_lines; 3849 edge = edge + c->pixel_height;
3850
3599 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3851 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3600 } 3852 }
3601 } 3853 }
@@ -3606,18 +3858,90 @@ window_resize_apply (struct window *w, bool horflag)
3606 while (c) 3858 while (c)
3607 { 3859 {
3608 if (horflag) 3860 if (horflag)
3609 c->left_col = pos; 3861 {
3862 c->pixel_left = edge;
3863 c->left_col = edge / unit;
3864 }
3610 else 3865 else
3611 c->top_line = pos; 3866 {
3867 c->pixel_top = edge;
3868 c->top_line = edge / unit;
3869 }
3870
3612 window_resize_apply (c, horflag); 3871 window_resize_apply (c, horflag);
3613 if (horflag) 3872 if (horflag)
3614 pos = pos + c->total_cols; 3873 edge = edge + c->pixel_width;
3874
3615 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3875 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3616 } 3876 }
3617 } 3877 }
3878 else
3879 /* Bug#15957. */
3880 w->window_end_valid = 0;
3618} 3881}
3619 3882
3620 3883
3884/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
3885 w->new_total for window W and recursively all child windows of W.
3886 Also calculate and assign the new vertical (horizontal) start
3887 positions of each of these windows. */
3888static void
3889window_resize_apply_total (struct window *w, bool horflag)
3890{
3891 struct window *c;
3892 int edge;
3893
3894 /* Note: Assigning new_normal requires that the new total size of the
3895 parent window has been set *before*. */
3896 if (horflag)
3897 {
3898 w->total_cols = XFASTINT (w->new_total);
3899 edge = w->left_col;
3900 }
3901 else
3902 {
3903 w->total_lines = XFASTINT (w->new_total);
3904 edge = w->top_line;
3905 }
3906
3907 if (WINDOW_VERTICAL_COMBINATION_P (w))
3908 /* W is a vertical combination. */
3909 {
3910 c = XWINDOW (w->contents);
3911 while (c)
3912 {
3913 if (horflag)
3914 c->left_col = edge;
3915 else
3916 c->top_line = edge;
3917
3918 window_resize_apply_total (c, horflag);
3919 if (!horflag)
3920 edge = edge + c->total_lines;
3921
3922 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3923 }
3924 }
3925 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3926 /* W is a horizontal combination. */
3927 {
3928 c = XWINDOW (w->contents);
3929 while (c)
3930 {
3931 if (horflag)
3932 c->left_col = edge;
3933 else
3934 c->top_line = edge;
3935
3936 window_resize_apply_total (c, horflag);
3937 if (horflag)
3938 edge = edge + c->total_cols;
3939
3940 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3941 }
3942 }
3943}
3944
3621DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0, 3945DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
3622 doc: /* Apply requested size values for window-tree of FRAME. 3946 doc: /* Apply requested size values for window-tree of FRAME.
3623If FRAME is omitted or nil, it defaults to the selected frame. 3947If FRAME is omitted or nil, it defaults to the selected frame.
@@ -3639,20 +3963,44 @@ be applied on the Elisp level. */)
3639 bool horflag = !NILP (horizontal); 3963 bool horflag = !NILP (horizontal);
3640 3964
3641 if (!window_resize_check (r, horflag) 3965 if (!window_resize_check (r, horflag)
3642 || (XINT (r->new_total) 3966 || (XINT (r->new_pixel)
3643 != (horflag ? r->total_cols : r->total_lines))) 3967 != (horflag ? r->pixel_width : r->pixel_height)))
3644 return Qnil; 3968 return Qnil;
3645 3969
3646 block_input (); 3970 block_input ();
3647 window_resize_apply (r, horflag); 3971 window_resize_apply (r, horflag);
3648 3972
3649 windows_or_buffers_changed = 30; 3973 fset_redisplay (f);
3650 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 3974 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3651 3975
3652 adjust_frame_glyphs (f); 3976 adjust_frame_glyphs (f);
3653 unblock_input (); 3977 unblock_input ();
3654 3978
3655 run_window_configuration_change_hook (f); 3979 return Qt;
3980}
3981
3982
3983DEFUN ("window-resize-apply-total", Fwindow_resize_apply_total, Swindow_resize_apply_total, 0, 2, 0,
3984 doc: /* Apply requested total size values for window-tree of FRAME.
3985If FRAME is omitted or nil, it defaults to the selected frame.
3986
3987This function does not assign pixel or normal size values. You should
3988have run `window-resize-apply' before running this.
3989
3990Optional argument HORIZONTAL omitted or nil means apply requested
3991height values. HORIZONTAL non-nil means apply requested width
3992values. */)
3993 (Lisp_Object frame, Lisp_Object horizontal)
3994{
3995 struct frame *f = decode_live_frame (frame);
3996 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
3997
3998 block_input ();
3999 /* Necessary when deleting the top-/or leftmost window. */
4000 r->left_col = 0;
4001 r->top_line = FRAME_TOP_MARGIN (f);
4002 window_resize_apply_total (r, !NILP (horizontal));
4003 unblock_input ();
3656 4004
3657 return Qt; 4005 return Qt;
3658} 4006}
@@ -3660,59 +4008,107 @@ be applied on the Elisp level. */)
3660 4008
3661/* Resize frame F's windows when number of lines of F is set to SIZE. 4009/* Resize frame F's windows when number of lines of F is set to SIZE.
3662 HORFLAG 1 means resize windows when number of columns of F is set to 4010 HORFLAG 1 means resize windows when number of columns of F is set to
3663 SIZE. 4011 SIZE. PIXELWISE 1 means to interpret SIZE as pixels.
3664 4012
3665 This function can delete all windows but the selected one in order to 4013 This function can delete all windows but the selected one in order to
3666 satisfy the request. The result will be meaningful if and only if 4014 satisfy the request. The result will be meaningful if and only if
3667 F's windows have meaningful sizes when you call this. */ 4015 F's windows have meaningful sizes when you call this. */
3668void 4016void
3669resize_frame_windows (struct frame *f, int size, bool horflag) 4017resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
3670{ 4018{
3671 Lisp_Object root = f->root_window; 4019 Lisp_Object root = f->root_window;
3672 struct window *r = XWINDOW (root); 4020 struct window *r = XWINDOW (root);
3673 Lisp_Object mini = f->minibuffer_window; 4021 Lisp_Object mini = f->minibuffer_window;
3674 struct window *m; 4022 struct window *m;
4023 /* old_size is the old size of the frame's root window. */
4024 int old_size = horflag ? r->total_cols : r->total_lines;
4025 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
3675 /* new_size is the new size of the frame's root window. */ 4026 /* new_size is the new size of the frame's root window. */
3676 int new_size = (horflag 4027 int new_size, new_pixel_size;
3677 ? size 4028
3678 : (size 4029 if (pixelwise)
3679 - FRAME_TOP_MARGIN (f) 4030 {
3680 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 4031 new_pixel_size
3681 ? 1 : 0))); 4032 = (horflag
4033 ? size
4034 : (size
4035 - FRAME_TOP_MARGIN_HEIGHT (f)
4036 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4037 ? FRAME_LINE_HEIGHT (f) : 0)));
4038 new_size = new_pixel_size / (horflag
4039 ? FRAME_COLUMN_WIDTH (f)
4040 : FRAME_LINE_HEIGHT (f));
4041 }
4042 else
4043 {
4044 new_size= (horflag
4045 ? size
4046 : (size
4047 - FRAME_TOP_MARGIN (f)
4048 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4049 ? 1 : 0)));
4050 new_pixel_size = new_size * (horflag
4051 ? FRAME_COLUMN_WIDTH (f)
4052 : FRAME_LINE_HEIGHT (f));
4053 }
3682 4054
3683 r->top_line = FRAME_TOP_MARGIN (f); 4055 r->top_line = FRAME_TOP_MARGIN (f);
3684 if (WINDOW_LEAF_P (r)) 4056 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4057
4058 if (new_pixel_size == old_pixel_size)
4059 return;
4060 else if (WINDOW_LEAF_P (r))
3685 /* For a leaf root window just set the size. */ 4061 /* For a leaf root window just set the size. */
3686 if (horflag) 4062 if (horflag)
3687 r->total_cols = new_size; 4063 {
4064 r->total_cols = new_size;
4065 r->pixel_width = new_pixel_size;
4066 }
3688 else 4067 else
3689 r->total_lines = new_size; 4068 {
4069 r->total_lines = new_size;
4070 r->pixel_height = new_pixel_size;
4071 }
3690 else 4072 else
3691 { 4073 {
3692 /* old_size is the old size of the frame's root window. */
3693 int old_size = horflag ? r->total_cols : r->total_lines;
3694 Lisp_Object delta; 4074 Lisp_Object delta;
3695 4075
3696 XSETINT (delta, new_size - old_size); 4076 if (pixelwise)
4077 XSETINT (delta, new_pixel_size - old_pixel_size);
4078 else
4079 XSETINT (delta, new_size - old_size);
4080
3697 /* Try a "normal" resize first. */ 4081 /* Try a "normal" resize first. */
3698 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil); 4082 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil,
4083 pixelwise ? Qt : Qnil);
3699 if (window_resize_check (r, horflag) 4084 if (window_resize_check (r, horflag)
3700 && new_size == XINT (r->new_total)) 4085 && new_pixel_size == XINT (r->new_pixel))
3701 window_resize_apply (r, horflag); 4086 {
4087 window_resize_apply (r, horflag);
4088 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4089 }
3702 else 4090 else
3703 { 4091 {
3704 /* Try with "reasonable" minimum sizes next. */ 4092 /* Try with "reasonable" minimum sizes next. */
3705 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt); 4093 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt,
4094 pixelwise ? Qt : Qnil);
3706 if (window_resize_check (r, horflag) 4095 if (window_resize_check (r, horflag)
3707 && new_size == XINT (r->new_total)) 4096 && new_pixel_size == XINT (r->new_pixel))
3708 window_resize_apply (r, horflag); 4097 {
4098 window_resize_apply (r, horflag);
4099 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4100 }
3709 else 4101 else
3710 { 4102 {
3711 /* Finally, try with "safe" minimum sizes. */ 4103 /* Finally, try with "safe" minimum sizes. */
3712 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe); 4104 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe,
4105 pixelwise ? Qt : Qnil);
3713 if (window_resize_check (r, horflag) 4106 if (window_resize_check (r, horflag)
3714 && new_size == XINT (r->new_total)) 4107 && new_pixel_size == XINT (r->new_pixel))
3715 window_resize_apply (r, horflag); 4108 {
4109 window_resize_apply (r, horflag);
4110 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4111 }
3716 else 4112 else
3717 { 4113 {
3718 /* We lost. Delete all windows but the frame's 4114 /* We lost. Delete all windows but the frame's
@@ -3720,9 +4116,15 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
3720 root = f->selected_window; 4116 root = f->selected_window;
3721 Fdelete_other_windows_internal (root, Qnil); 4117 Fdelete_other_windows_internal (root, Qnil);
3722 if (horflag) 4118 if (horflag)
3723 XWINDOW (root)->total_cols = new_size; 4119 {
4120 XWINDOW (root)->total_cols = new_size;
4121 XWINDOW (root)->pixel_width = new_pixel_size;
4122 }
3724 else 4123 else
3725 XWINDOW (root)->total_lines = new_size; 4124 {
4125 XWINDOW (root)->total_lines = new_size;
4126 XWINDOW (root)->pixel_height = new_pixel_size;
4127 }
3726 } 4128 }
3727 } 4129 }
3728 } 4130 }
@@ -3732,42 +4134,47 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
3732 { 4134 {
3733 m = XWINDOW (mini); 4135 m = XWINDOW (mini);
3734 if (horflag) 4136 if (horflag)
3735 m->total_cols = size; 4137 {
4138 m->total_cols = size;
4139 m->pixel_width = new_pixel_size;
4140 }
3736 else 4141 else
3737 { 4142 {
3738 /* Are we sure we always want 1 line here? */ 4143 /* Are we sure we always want 1 line here? */
3739 m->total_lines = 1; 4144 m->total_lines = 1;
4145 m->pixel_height = FRAME_LINE_HEIGHT (f);
3740 m->top_line = r->top_line + r->total_lines; 4146 m->top_line = r->top_line + r->total_lines;
4147 m->pixel_top = r->pixel_top + r->pixel_height;
3741 } 4148 }
3742 } 4149 }
3743 4150
3744 windows_or_buffers_changed = 31; 4151 fset_redisplay (f);
3745} 4152}
3746 4153
3747 4154
3748DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0, 4155DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
3749 doc: /* Split window OLD. 4156 doc: /* Split window OLD.
3750Second argument TOTAL-SIZE specifies the number of lines or columns of the 4157Second argument PIXEL-SIZE specifies the number of pixels of the
3751new window. In any case TOTAL-SIZE must be a positive integer. 4158new window. In any case TOTAL-SIZE must be a positive integer.
3752 4159
3753Third argument SIDE nil (or `below') specifies that the new window shall 4160Third argument SIDE nil (or `below') specifies that the new window shall
3754be located below WINDOW. SIDE `above' means the new window shall be 4161be located below WINDOW. SIDE `above' means the new window shall be
3755located above WINDOW. In both cases TOTAL-SIZE specifies the number of 4162located above WINDOW. In both cases PIXEL-SIZE specifies the pixel
3756lines of the new window including space reserved for the mode and/or 4163height of the new window including space reserved for the mode and/or
3757header line. 4164header line.
3758 4165
3759SIDE t (or `right') specifies that the new window shall be located on 4166SIDE t (or `right') specifies that the new window shall be located on
3760the right side of WINDOW. SIDE `left' means the new window shall be 4167the right side of WINDOW. SIDE `left' means the new window shall be
3761located on the left of WINDOW. In both cases TOTAL-SIZE specifies the 4168located on the left of WINDOW. In both cases PIXEL-SIZE specifies the
3762number of columns of the new window including space reserved for fringes 4169width of the new window including space reserved for fringes and the
3763and the scrollbar or a divider column. 4170scrollbar or a divider column.
3764 4171
3765Fourth argument NORMAL-SIZE specifies the normal size of the new window 4172Fourth argument NORMAL-SIZE specifies the normal size of the new window
3766according to the SIDE argument. 4173according to the SIDE argument.
3767 4174
3768The new total and normal sizes of all involved windows must have been 4175The new pixel and normal sizes of all involved windows must have been
3769set correctly. See the code of `split-window' for how this is done. */) 4176set correctly. See the code of `split-window' for how this is done. */)
3770 (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size) 4177 (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size)
3771{ 4178{
3772 /* OLD (*o) is the window we have to split. (*p) is either OLD's 4179 /* OLD (*o) is the window we have to split. (*p) is either OLD's
3773 parent window or an internal window we have to install as OLD's new 4180 parent window or an internal window we have to install as OLD's new
@@ -3776,19 +4183,24 @@ set correctly. See the code of `split-window' for how this is done. */)
3776 NEW (*n) is the new window created with some parameters taken from 4183 NEW (*n) is the new window created with some parameters taken from
3777 REFERENCE (*r). */ 4184 REFERENCE (*r). */
3778 register Lisp_Object new, frame, reference; 4185 register Lisp_Object new, frame, reference;
3779 register struct window *o, *p, *n, *r; 4186 register struct window *o, *p, *n, *r, *c;
3780 struct frame *f; 4187 struct frame *f;
3781 bool horflag 4188 bool horflag
3782 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */ 4189 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3783 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright); 4190 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3784 int combination_limit = 0; 4191 int combination_limit = 0, sum = 0;
4192 int total_size;
3785 4193
3786 CHECK_WINDOW (old); 4194 CHECK_WINDOW (old);
3787 o = XWINDOW (old); 4195 o = XWINDOW (old);
3788 frame = WINDOW_FRAME (o); 4196 frame = WINDOW_FRAME (o);
3789 f = XFRAME (frame); 4197 f = XFRAME (frame);
3790 4198
3791 CHECK_NUMBER (total_size); 4199 CHECK_NUMBER (pixel_size);
4200 total_size
4201 = XINT (pixel_size) / (horflag
4202 ? FRAME_COLUMN_WIDTH (f)
4203 : FRAME_LINE_HEIGHT (f));
3792 4204
3793 /* Set combination_limit to 1 if we have to make a new parent window. 4205 /* Set combination_limit to 1 if we have to make a new parent window.
3794 We do that if either `window-combination-limit' is t, or OLD has no 4206 We do that if either `window-combination-limit' is t, or OLD has no
@@ -3812,7 +4224,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3812 /* The following bugs are caught by `split-window'. */ 4224 /* The following bugs are caught by `split-window'. */
3813 if (MINI_WINDOW_P (o)) 4225 if (MINI_WINDOW_P (o))
3814 error ("Attempt to split minibuffer window"); 4226 error ("Attempt to split minibuffer window");
3815 else if (XINT (total_size) < (horflag ? 2 : 1)) 4227 else if (total_size < (horflag ? 2 : 1))
3816 error ("Size of new window too small (after split)"); 4228 error ("Size of new window too small (after split)");
3817 else if (!combination_limit && !NILP (Vwindow_combination_resize)) 4229 else if (!combination_limit && !NILP (Vwindow_combination_resize))
3818 /* `window-combination-resize' non-nil means try to resize OLD's siblings 4230 /* `window-combination-resize' non-nil means try to resize OLD's siblings
@@ -3820,26 +4232,25 @@ set correctly. See the code of `split-window' for how this is done. */)
3820 { 4232 {
3821 p = XWINDOW (o->parent); 4233 p = XWINDOW (o->parent);
3822 /* Temporarily pretend we split the parent window. */ 4234 /* Temporarily pretend we split the parent window. */
3823 wset_new_total 4235 wset_new_pixel
3824 (p, make_number ((horflag ? p->total_cols : p->total_lines) 4236 (p, make_number ((horflag ? p->pixel_width : p->pixel_height)
3825 - XINT (total_size))); 4237 - XINT (pixel_size)));
3826 if (!window_resize_check (p, horflag)) 4238 if (!window_resize_check (p, horflag))
3827 error ("Window sizes don't fit"); 4239 error ("Window sizes don't fit");
3828 else 4240 else
3829 /* Undo the temporary pretension. */ 4241 /* Undo the temporary pretension. */
3830 wset_new_total (p, make_number 4242 wset_new_pixel (p, make_number (horflag ? p->pixel_width : p->pixel_height));
3831 (horflag ? p->total_cols : p->total_lines));
3832 } 4243 }
3833 else 4244 else
3834 { 4245 {
3835 if (!window_resize_check (o, horflag)) 4246 if (!window_resize_check (o, horflag))
3836 error ("Resizing old window failed"); 4247 error ("Resizing old window failed");
3837 else if (XINT (total_size) + XINT (o->new_total) 4248 else if (XINT (pixel_size) + XINT (o->new_pixel)
3838 != (horflag ? o->total_cols : o->total_lines)) 4249 != (horflag ? o->pixel_width : o->pixel_height))
3839 error ("Sum of sizes of old and new window don't fit"); 4250 error ("Sum of sizes of old and new window don't fit");
3840 } 4251 }
3841 4252
3842 /* This is our point of no return. */ 4253 /* This is our point of no return. */
3843 if (combination_limit) 4254 if (combination_limit)
3844 { 4255 {
3845 /* Save the old value of o->normal_cols/lines. It gets corrupted 4256 /* Save the old value of o->normal_cols/lines. It gets corrupted
@@ -3855,14 +4266,16 @@ set correctly. See the code of `split-window' for how this is done. */)
3855 that its children get merged into another window. */ 4266 that its children get merged into another window. */
3856 wset_combination_limit (p, Qt); 4267 wset_combination_limit (p, Qt);
3857 /* These get applied below. */ 4268 /* These get applied below. */
3858 wset_new_total (p, make_number 4269 wset_new_pixel
3859 (horflag ? o->total_cols : o->total_lines)); 4270 (p, make_number (horflag ? o->pixel_width : o->pixel_height));
4271 wset_new_total
4272 (p, make_number (horflag ? o->total_cols : o->total_lines));
3860 wset_new_normal (p, new_normal); 4273 wset_new_normal (p, new_normal);
3861 } 4274 }
3862 else 4275 else
3863 p = XWINDOW (o->parent); 4276 p = XWINDOW (o->parent);
3864 4277
3865 windows_or_buffers_changed = 32; 4278 fset_redisplay (f);
3866 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4279 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3867 new = make_window (); 4280 new = make_window ();
3868 n = XWINDOW (new); 4281 n = XWINDOW (new);
@@ -3903,18 +4316,33 @@ set correctly. See the code of `split-window' for how this is done. */)
3903 /* Directly assign orthogonal coordinates and sizes. */ 4316 /* Directly assign orthogonal coordinates and sizes. */
3904 if (horflag) 4317 if (horflag)
3905 { 4318 {
4319 n->pixel_top = o->pixel_top;
3906 n->top_line = o->top_line; 4320 n->top_line = o->top_line;
4321 n->pixel_height = o->pixel_height;
3907 n->total_lines = o->total_lines; 4322 n->total_lines = o->total_lines;
3908 } 4323 }
3909 else 4324 else
3910 { 4325 {
4326 n->pixel_left = o->pixel_left;
3911 n->left_col = o->left_col; 4327 n->left_col = o->left_col;
4328 n->pixel_width = o->pixel_width;
3912 n->total_cols = o->total_cols; 4329 n->total_cols = o->total_cols;
3913 } 4330 }
3914 4331
3915 /* Iso-coordinates and sizes are assigned by window_resize_apply, 4332 /* Iso-coordinates and sizes are assigned by window_resize_apply,
3916 get them ready here. */ 4333 get them ready here. */
3917 wset_new_total (n, total_size); 4334 wset_new_pixel (n, pixel_size);
4335 c = XWINDOW (p->contents);
4336 while (c)
4337 {
4338 if (c != n)
4339 sum = sum + XINT (c->new_total);
4340 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4341 }
4342 wset_new_total (n, make_number ((horflag
4343 ? p->total_cols
4344 : p->total_lines)
4345 - sum));
3918 wset_new_normal (n, normal_size); 4346 wset_new_normal (n, normal_size);
3919 4347
3920 block_input (); 4348 block_input ();
@@ -3993,15 +4421,14 @@ Signal an error when WINDOW is the only window on its frame. */)
3993 } 4421 }
3994 4422
3995 if (window_resize_check (r, horflag) 4423 if (window_resize_check (r, horflag)
3996 && (XINT (r->new_total) 4424 && (XINT (r->new_pixel)
3997 == (horflag ? r->total_cols : r->total_lines))) 4425 == (horflag ? r->pixel_width : r->pixel_height)))
3998 /* We can delete WINDOW now. */ 4426 /* We can delete WINDOW now. */
3999 { 4427 {
4000 4428
4001 /* Block input. */ 4429 /* Block input. */
4002 block_input (); 4430 block_input ();
4003 window_resize_apply (p, horflag); 4431 window_resize_apply (p, horflag);
4004
4005 /* If this window is referred to by the dpyinfo's mouse 4432 /* If this window is referred to by the dpyinfo's mouse
4006 highlight, invalidate that slot to be safe (Bug#9904). */ 4433 highlight, invalidate that slot to be safe (Bug#9904). */
4007 if (!FRAME_INITIAL_P (f)) 4434 if (!FRAME_INITIAL_P (f))
@@ -4012,7 +4439,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4012 hlinfo->mouse_face_window = Qnil; 4439 hlinfo->mouse_face_window = Qnil;
4013 } 4440 }
4014 4441
4015 windows_or_buffers_changed = 33; 4442 fset_redisplay (f);
4016 Vwindow_list = Qnil; 4443 Vwindow_list = Qnil;
4017 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4444 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4018 4445
@@ -4112,54 +4539,76 @@ Signal an error when WINDOW is the only window on its frame. */)
4112/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we 4539/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4113 can. */ 4540 can. */
4114void 4541void
4115grow_mini_window (struct window *w, int delta) 4542grow_mini_window (struct window *w, int delta, bool pixelwise)
4116{ 4543{
4117 struct frame *f = XFRAME (w->frame); 4544 struct frame *f = XFRAME (w->frame);
4118 struct window *r; 4545 struct window *r;
4119 Lisp_Object root, value; 4546 Lisp_Object root, height;
4547 int line_height, pixel_height;
4120 4548
4121 eassert (MINI_WINDOW_P (w)); 4549 eassert (MINI_WINDOW_P (w));
4122 eassert (delta >= 0); 4550 eassert (delta >= 0);
4123 4551
4124 root = FRAME_ROOT_WINDOW (f); 4552 if (delta > 0)
4125 r = XWINDOW (root);
4126 value = call2 (Qwindow_resize_root_window_vertically,
4127 root, make_number (- delta));
4128 if (INTEGERP (value) && window_resize_check (r, 0))
4129 { 4553 {
4130 block_input (); 4554 root = FRAME_ROOT_WINDOW (f);
4131 window_resize_apply (r, 0); 4555 r = XWINDOW (root);
4556 height = call3 (Qwindow_resize_root_window_vertically,
4557 root, make_number (- delta), pixelwise ? Qt : Qnil);
4558 if (INTEGERP (height) && window_resize_check (r, 0))
4559 {
4560 block_input ();
4561 window_resize_apply (r, 0);
4132 4562
4133 /* Grow the mini-window. */ 4563 if (pixelwise)
4134 w->top_line = r->top_line + r->total_lines; 4564 {
4135 w->total_lines -= XINT (value); 4565 pixel_height = min (-XINT (height), INT_MAX - w->pixel_height);
4136 /* Enforce full redisplay. FIXME: make it more selective. */ 4566 line_height = pixel_height / FRAME_LINE_HEIGHT (f);
4137 windows_or_buffers_changed = 34; 4567 }
4138 adjust_frame_glyphs (f); 4568 else
4139 unblock_input (); 4569 {
4570 line_height = min (-XINT (height),
4571 ((INT_MAX - w->pixel_height)
4572 / FRAME_LINE_HEIGHT (f)));
4573 pixel_height = line_height * FRAME_LINE_HEIGHT (f);
4574 }
4575
4576 /* Grow the mini-window. */
4577 w->pixel_top = r->pixel_top + r->pixel_height;
4578 w->top_line = r->top_line + r->total_lines;
4579 w->pixel_height += pixel_height;
4580 w->total_lines += line_height;
4581
4582 /* Enforce full redisplay of the frame. */
4583 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4584 fset_redisplay (f);
4585 adjust_frame_glyphs (f);
4586 unblock_input ();
4587 }
4140 } 4588 }
4141} 4589}
4142 4590
4143 4591/* Shrink mini-window W to one line. */
4144/* Shrink mini-window W. */
4145void 4592void
4146shrink_mini_window (struct window *w) 4593shrink_mini_window (struct window *w, bool pixelwise)
4147{ 4594{
4148 struct frame *f = XFRAME (w->frame); 4595 struct frame *f = XFRAME (w->frame);
4149 struct window *r; 4596 struct window *r;
4150 Lisp_Object root, value; 4597 Lisp_Object root, delta;
4151 EMACS_INT size; 4598 EMACS_INT height, unit;
4152 4599
4153 eassert (MINI_WINDOW_P (w)); 4600 eassert (MINI_WINDOW_P (w));
4154 4601
4155 size = w->total_lines; 4602 height = pixelwise ? w->pixel_height : w->total_lines;
4156 if (size > 1) 4603 unit = pixelwise ? FRAME_LINE_HEIGHT (f) : 1;
4604 if (height > unit)
4157 { 4605 {
4158 root = FRAME_ROOT_WINDOW (f); 4606 root = FRAME_ROOT_WINDOW (f);
4159 r = XWINDOW (root); 4607 r = XWINDOW (root);
4160 value = call2 (Qwindow_resize_root_window_vertically, 4608 delta = call3 (Qwindow_resize_root_window_vertically,
4161 root, make_number (size - 1)); 4609 root, make_number (height - unit),
4162 if (INTEGERP (value) && window_resize_check (r, 0)) 4610 pixelwise ? Qt : Qnil);
4611 if (INTEGERP (delta) && window_resize_check (r, 0))
4163 { 4612 {
4164 block_input (); 4613 block_input ();
4165 window_resize_apply (r, 0); 4614 window_resize_apply (r, 0);
@@ -4167,8 +4616,11 @@ shrink_mini_window (struct window *w)
4167 /* Shrink the mini-window. */ 4616 /* Shrink the mini-window. */
4168 w->top_line = r->top_line + r->total_lines; 4617 w->top_line = r->top_line + r->total_lines;
4169 w->total_lines = 1; 4618 w->total_lines = 1;
4170 /* Enforce full redisplay. FIXME: make it more selective. */ 4619 w->pixel_top = r->pixel_top + r->pixel_height;
4171 windows_or_buffers_changed = 35; 4620 w->pixel_height = FRAME_LINE_HEIGHT (f);
4621 /* Enforce full redisplay of the frame. */
4622 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4623 fset_redisplay (f);
4172 adjust_frame_glyphs (f); 4624 adjust_frame_glyphs (f);
4173 unblock_input (); 4625 unblock_input ();
4174 } 4626 }
@@ -4197,26 +4649,27 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4197 error ("Cannot resize a minibuffer-only frame"); 4649 error ("Cannot resize a minibuffer-only frame");
4198 4650
4199 r = XWINDOW (FRAME_ROOT_WINDOW (f)); 4651 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4200 height = r->total_lines + w->total_lines; 4652 height = r->pixel_height + w->pixel_height;
4201 if (window_resize_check (r, 0) 4653 if (window_resize_check (r, 0)
4202 && XINT (w->new_total) > 0 4654 && XINT (w->new_pixel) > 0
4203 && height == XINT (r->new_total) + XINT (w->new_total)) 4655 && height == XINT (r->new_pixel) + XINT (w->new_pixel))
4204 { 4656 {
4205 block_input (); 4657 block_input ();
4206 window_resize_apply (r, 0); 4658 window_resize_apply (r, 0);
4207 4659
4208 w->total_lines = XFASTINT (w->new_total); 4660 w->total_lines = XFASTINT (w->new_total);
4209 w->top_line = r->top_line + r->total_lines; 4661 w->top_line = r->top_line + r->total_lines;
4662 w->pixel_height = XFASTINT (w->new_pixel);
4663 w->pixel_top = r->pixel_top + r->pixel_height;
4210 4664
4211 windows_or_buffers_changed = 36; 4665 fset_redisplay (f);
4212 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4666 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4213 adjust_frame_glyphs (f); 4667 adjust_frame_glyphs (f);
4214 unblock_input (); 4668 unblock_input ();
4215
4216 run_window_configuration_change_hook (f);
4217 return Qt; 4669 return Qt;
4218 } 4670 }
4219 else error ("Failed to resize minibuffer window"); 4671 else
4672 error ("Failed to resize minibuffer window");
4220} 4673}
4221 4674
4222/* Mark window cursors off for all windows in the window tree rooted 4675/* Mark window cursors off for all windows in the window tree rooted
@@ -4279,6 +4732,8 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
4279 immediate_quit = 1; 4732 immediate_quit = 1;
4280 n = clip_to_bounds (INT_MIN, n, INT_MAX); 4733 n = clip_to_bounds (INT_MIN, n, INT_MAX);
4281 4734
4735 wset_redisplay (XWINDOW (window));
4736
4282 /* If we must, use the pixel-based version which is much slower than 4737 /* If we must, use the pixel-based version which is much slower than
4283 the line-based one but can handle varying line heights. */ 4738 the line-based one but can handle varying line heights. */
4284 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame))) 4739 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
@@ -4286,6 +4741,8 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
4286 else 4741 else
4287 window_scroll_line_based (window, n, whole, noerror); 4742 window_scroll_line_based (window, n, whole, noerror);
4288 4743
4744 /* Bug#15957. */
4745 XWINDOW (window)->window_end_valid = 0;
4289 immediate_quit = 0; 4746 immediate_quit = 0;
4290} 4747}
4291 4748
@@ -4828,9 +5285,6 @@ scroll_command (Lisp_Object n, int direction)
4828 { 5285 {
4829 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 5286 record_unwind_protect (save_excursion_restore, save_excursion_save ());
4830 Fset_buffer (XWINDOW (selected_window)->contents); 5287 Fset_buffer (XWINDOW (selected_window)->contents);
4831
4832 /* Make redisplay consider other windows than just selected_window. */
4833 windows_or_buffers_changed = 37;
4834 } 5288 }
4835 5289
4836 if (NILP (n)) 5290 if (NILP (n))
@@ -4940,7 +5394,6 @@ specifies the window to scroll. This takes precedence over
4940 5394
4941 /* Don't screw up if window_scroll gets an error. */ 5395 /* Don't screw up if window_scroll gets an error. */
4942 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 5396 record_unwind_protect (save_excursion_restore, save_excursion_save ());
4943 windows_or_buffers_changed = 38;
4944 5397
4945 Fset_buffer (w->contents); 5398 Fset_buffer (w->contents);
4946 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm)); 5399 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
@@ -4976,7 +5429,7 @@ by this function. This happens in an interactive call. */)
4976{ 5429{
4977 struct window *w = XWINDOW (selected_window); 5430 struct window *w = XWINDOW (selected_window);
4978 EMACS_INT requested_arg = (NILP (arg) 5431 EMACS_INT requested_arg = (NILP (arg)
4979 ? window_body_cols (w) - 2 5432 ? window_body_width (w, 0) - 2
4980 : XINT (Fprefix_numeric_value (arg))); 5433 : XINT (Fprefix_numeric_value (arg)));
4981 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg); 5434 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
4982 5435
@@ -4999,7 +5452,7 @@ by this function. This happens in an interactive call. */)
4999{ 5452{
5000 struct window *w = XWINDOW (selected_window); 5453 struct window *w = XWINDOW (selected_window);
5001 EMACS_INT requested_arg = (NILP (arg) 5454 EMACS_INT requested_arg = (NILP (arg)
5002 ? window_body_cols (w) - 2 5455 ? window_body_width (w, 0) - 2
5003 : XINT (Fprefix_numeric_value (arg))); 5456 : XINT (Fprefix_numeric_value (arg)));
5004 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg); 5457 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
5005 5458
@@ -5273,22 +5726,36 @@ and redisplay normally--don't erase and redraw the frame. */)
5273 return Qnil; 5726 return Qnil;
5274} 5727}
5275 5728
5276DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5729DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
5277 0, 1, 0, 5730 0, 1, 0,
5278 doc: /* Return the height in lines of the text display area of WINDOW. 5731 doc: /* Return the width in columns of the text display area of WINDOW.
5279WINDOW must be a live window and defaults to the selected one. 5732WINDOW must be a live window and defaults to the selected one.
5280 5733
5281The returned height does not include the mode line, any header line, 5734The returned width does not include dividers, scrollbars, margins,
5282nor any partial-height lines at the bottom of the text area. */) 5735fringes, nor any partial-width columns at the right of the text
5736area. */)
5283 (Lisp_Object window) 5737 (Lisp_Object window)
5284{ 5738{
5285 struct window *w = decode_live_window (window); 5739 struct window *w = decode_live_window (window);
5286 int pixel_height = window_box_height (w); 5740
5287 int line_height = pixel_height / FRAME_LINE_HEIGHT (XFRAME (w->frame)); 5741 return make_number (window_box_width (w, TEXT_AREA)
5288 return make_number (line_height); 5742 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
5289} 5743}
5290 5744
5745DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5746 0, 1, 0,
5747 doc: /* Return the height in lines of the text display area of WINDOW.
5748WINDOW must be a live window and defaults to the selected one.
5749
5750The returned height does not include dividers, the mode line, any header
5751line, nor any partial-height lines at the bottom of the text area. */)
5752 (Lisp_Object window)
5753{
5754 struct window *w = decode_live_window (window);
5291 5755
5756 return make_number (window_box_height (w)
5757 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
5758}
5292 5759
5293DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, 5760DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
5294 1, 1, "P", 5761 1, 1, "P",
@@ -5381,9 +5848,15 @@ struct save_window_data
5381 5848
5382 /* All fields above are traced by the GC. 5849 /* All fields above are traced by the GC.
5383 From `frame-cols' down, the fields are ignored by the GC. */ 5850 From `frame-cols' down, the fields are ignored by the GC. */
5384 5851 /* We should be able to do without the following two. */
5385 int frame_cols, frame_lines, frame_menu_bar_lines; 5852 int frame_cols, frame_lines;
5386 int frame_tool_bar_lines; 5853 /* These two should get eventually replaced by their pixel
5854 counterparts. */
5855 int frame_menu_bar_lines, frame_tool_bar_lines;
5856 int frame_text_width, frame_text_height;
5857 /* These are currently unused. We need them as soon as we convert
5858 to pixels. */
5859 int frame_menu_bar_height, frame_tool_bar_height;
5387 }; 5860 };
5388 5861
5389/* This is saved as a Lisp_Vector */ 5862/* This is saved as a Lisp_Vector */
@@ -5392,6 +5865,7 @@ struct saved_window
5392 struct vectorlike_header header; 5865 struct vectorlike_header header;
5393 5866
5394 Lisp_Object window, buffer, start, pointm, mark; 5867 Lisp_Object window, buffer, start, pointm, mark;
5868 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
5395 Lisp_Object left_col, top_line, total_cols, total_lines; 5869 Lisp_Object left_col, top_line, total_cols, total_lines;
5396 Lisp_Object normal_cols, normal_lines; 5870 Lisp_Object normal_cols, normal_lines;
5397 Lisp_Object hscroll, min_hscroll; 5871 Lisp_Object hscroll, min_hscroll;
@@ -5512,8 +5986,12 @@ the return value is nil. Otherwise the value is t. */)
5512 made, we change the frame to the size specified in the 5986 made, we change the frame to the size specified in the
5513 configuration, restore the configuration, and then resize it 5987 configuration, restore the configuration, and then resize it
5514 back. We keep track of the prevailing height in these variables. */ 5988 back. We keep track of the prevailing height in these variables. */
5515 int previous_frame_lines = FRAME_LINES (f); 5989 int previous_frame_text_height = FRAME_TEXT_HEIGHT (f);
5516 int previous_frame_cols = FRAME_COLS (f); 5990 int previous_frame_text_width = FRAME_TEXT_WIDTH (f);
5991 /* int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); */
5992 /* int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); */
5993 /* int previous_frame_lines = FRAME_LINES (f); */
5994 /* int previous_frame_cols = FRAME_COLS (f); */
5517 int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); 5995 int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
5518 int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); 5996 int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
5519 5997
@@ -5536,13 +6014,12 @@ the return value is nil. Otherwise the value is t. */)
5536 if it runs during this. */ 6014 if it runs during this. */
5537 block_input (); 6015 block_input ();
5538 6016
5539 if (data->frame_lines != previous_frame_lines 6017 if (data->frame_text_width != previous_frame_text_width
5540 || data->frame_cols != previous_frame_cols) 6018 || data->frame_text_height != previous_frame_text_height)
5541 change_frame_size (f, data->frame_lines, 6019 change_frame_size (f, data->frame_text_width,
5542 data->frame_cols, 0, 0, 0); 6020 data->frame_text_height, 0, 0, 0, 1);
5543#ifdef HAVE_MENUS 6021
5544 if (data->frame_menu_bar_lines 6022 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
5545 != previous_frame_menu_bar_lines)
5546 { 6023 {
5547#ifdef HAVE_WINDOW_SYSTEM 6024#ifdef HAVE_WINDOW_SYSTEM
5548 if (FRAME_WINDOW_P (f)) 6025 if (FRAME_WINDOW_P (f))
@@ -5553,10 +6030,8 @@ the return value is nil. Otherwise the value is t. */)
5553 set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), 6030 set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
5554 make_number (0)); 6031 make_number (0));
5555 } 6032 }
5556#endif
5557#ifdef HAVE_WINDOW_SYSTEM 6033#ifdef HAVE_WINDOW_SYSTEM
5558 if (data->frame_tool_bar_lines 6034 if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines)
5559 != previous_frame_tool_bar_lines)
5560 x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines), 6035 x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
5561 make_number (0)); 6036 make_number (0));
5562#endif 6037#endif
@@ -5575,7 +6050,7 @@ the return value is nil. Otherwise the value is t. */)
5575 BUF_PT_BYTE (XBUFFER (w->contents))); 6050 BUF_PT_BYTE (XBUFFER (w->contents)));
5576 } 6051 }
5577 6052
5578 windows_or_buffers_changed = 39; 6053 fset_redisplay (f);
5579 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 6054 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
5580 6055
5581 /* Problem: Freeing all matrices and later allocating them again 6056 /* Problem: Freeing all matrices and later allocating them again
@@ -5628,6 +6103,10 @@ the return value is nil. Otherwise the value is t. */)
5628 /* If we squirreled away the buffer, restore it now. */ 6103 /* If we squirreled away the buffer, restore it now. */
5629 if (BUFFERP (w->combination_limit)) 6104 if (BUFFERP (w->combination_limit))
5630 wset_buffer (w, w->combination_limit); 6105 wset_buffer (w, w->combination_limit);
6106 w->pixel_left = XFASTINT (p->pixel_left);
6107 w->pixel_top = XFASTINT (p->pixel_top);
6108 w->pixel_width = XFASTINT (p->pixel_width);
6109 w->pixel_height = XFASTINT (p->pixel_height);
5631 w->left_col = XFASTINT (p->left_col); 6110 w->left_col = XFASTINT (p->left_col);
5632 w->top_line = XFASTINT (p->top_line); 6111 w->top_line = XFASTINT (p->top_line);
5633 w->total_cols = XFASTINT (p->total_cols); 6112 w->total_cols = XFASTINT (p->total_cols);
@@ -5728,25 +6207,17 @@ the return value is nil. Otherwise the value is t. */)
5728 make_number (old_point), 6207 make_number (old_point),
5729 XWINDOW (data->current_window)->contents); 6208 XWINDOW (data->current_window)->contents);
5730 6209
5731 /* In the following call to `select-window', prevent "swapping out
5732 point" in the old selected window using the buffer that has
5733 been restored into it. We already swapped out that point from
5734 that window's old buffer. */
5735 select_window (data->current_window, Qnil, 1);
5736 BVAR (XBUFFER (XWINDOW (selected_window)->contents), last_selected_window)
5737 = selected_window;
5738
5739 if (NILP (data->focus_frame) 6210 if (NILP (data->focus_frame)
5740 || (FRAMEP (data->focus_frame) 6211 || (FRAMEP (data->focus_frame)
5741 && FRAME_LIVE_P (XFRAME (data->focus_frame)))) 6212 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
5742 Fredirect_frame_focus (frame, data->focus_frame); 6213 Fredirect_frame_focus (frame, data->focus_frame);
5743 6214
5744 /* Set the screen height to the value it had before this function. */ 6215 /* Set the frame size to the value it had before this function. */
5745 if (previous_frame_lines != FRAME_LINES (f) 6216 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
5746 || previous_frame_cols != FRAME_COLS (f)) 6217 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
5747 change_frame_size (f, previous_frame_lines, previous_frame_cols, 6218 change_frame_size (f, previous_frame_text_width,
5748 0, 0, 0); 6219 previous_frame_text_height, 0, 0, 0, 1);
5749#ifdef HAVE_MENUS 6220
5750 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) 6221 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
5751 { 6222 {
5752#ifdef HAVE_WINDOW_SYSTEM 6223#ifdef HAVE_WINDOW_SYSTEM
@@ -5759,7 +6230,6 @@ the return value is nil. Otherwise the value is t. */)
5759 set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines), 6230 set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines),
5760 make_number (0)); 6231 make_number (0));
5761 } 6232 }
5762#endif
5763#ifdef HAVE_WINDOW_SYSTEM 6233#ifdef HAVE_WINDOW_SYSTEM
5764 if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f)) 6234 if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f))
5765 x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines), 6235 x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines),
@@ -5786,6 +6256,20 @@ the return value is nil. Otherwise the value is t. */)
5786 delete_deletable_window (window); 6256 delete_deletable_window (window);
5787 } 6257 }
5788 6258
6259 /* In the following call to `select-window', prevent "swapping out
6260 point" in the old selected window using the buffer that has
6261 been restored into it. We already swapped out that point from
6262 that window's old buffer. */
6263 /* This `select_window' calls record_buffer which calls Fdelq which
6264 invokes QUIT, so we do it here at the end rather than earlier,
6265 to minimize the risk of interrupting the Fset_window_configuration
6266 in an inconsistent state (e.g. before frame-focus redirection is
6267 canceled). */
6268 select_window (data->current_window, Qnil, 1);
6269 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6270 last_selected_window)
6271 = selected_window;
6272
5789 /* Fselect_window will have made f the selected frame, so we 6273 /* Fselect_window will have made f the selected frame, so we
5790 reselect the proper frame here. Fhandle_switch_frame will change the 6274 reselect the proper frame here. Fhandle_switch_frame will change the
5791 selected window too, but that doesn't make the call to 6275 selected window too, but that doesn't make the call to
@@ -5938,6 +6422,10 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
5938 wset_temslot (w, make_number (i)); i++; 6422 wset_temslot (w, make_number (i)); i++;
5939 p->window = window; 6423 p->window = window;
5940 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil); 6424 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
6425 p->pixel_left = make_number (w->pixel_left);
6426 p->pixel_top = make_number (w->pixel_top);
6427 p->pixel_width = make_number (w->pixel_width);
6428 p->pixel_height = make_number (w->pixel_height);
5941 p->left_col = make_number (w->left_col); 6429 p->left_col = make_number (w->left_col);
5942 p->top_line = make_number (w->top_line); 6430 p->top_line = make_number (w->top_line);
5943 p->total_cols = make_number (w->total_cols); 6431 p->total_cols = make_number (w->total_cols);
@@ -6077,6 +6565,10 @@ saved by this function. */)
6077 data->frame_lines = FRAME_LINES (f); 6565 data->frame_lines = FRAME_LINES (f);
6078 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); 6566 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
6079 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); 6567 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
6568 data->frame_text_width = FRAME_TEXT_WIDTH (f);
6569 data->frame_text_height = FRAME_TEXT_HEIGHT (f);
6570 data->frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
6571 data->frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
6080 data->selected_frame = selected_frame; 6572 data->selected_frame = selected_frame;
6081 data->current_window = FRAME_SELECTED_WINDOW (f); 6573 data->current_window = FRAME_SELECTED_WINDOW (f);
6082 XSETBUFFER (data->current_buffer, current_buffer); 6574 XSETBUFFER (data->current_buffer, current_buffer);
@@ -6103,7 +6595,7 @@ apply_window_adjustment (struct window *w)
6103 adjust_window_margins (w); 6595 adjust_window_margins (w);
6104 clear_glyph_matrix (w->current_matrix); 6596 clear_glyph_matrix (w->current_matrix);
6105 w->window_end_valid = 0; 6597 w->window_end_valid = 0;
6106 windows_or_buffers_changed = 40; 6598 wset_redisplay (w);
6107 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w))); 6599 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w)));
6108} 6600}
6109 6601
@@ -6163,8 +6655,10 @@ as nil. */)
6163 (Lisp_Object window) 6655 (Lisp_Object window)
6164{ 6656{
6165 struct window *w = decode_live_window (window); 6657 struct window *w = decode_live_window (window);
6166 return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil, 6658 return Fcons (w->left_margin_cols
6167 w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil); 6659 ? make_number (w->left_margin_cols) : Qnil,
6660 w->right_margin_cols
6661 ? make_number (w->right_margin_cols) : Qnil);
6168} 6662}
6169 6663
6170 6664
@@ -6274,15 +6768,14 @@ DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6274 doc: /* Set width and type of scroll bars of window WINDOW. 6768 doc: /* Set width and type of scroll bars of window WINDOW.
6275WINDOW must be a live window and defaults to the selected one. 6769WINDOW must be a live window and defaults to the selected one.
6276 6770
6277Second parameter WIDTH specifies the pixel width for the scroll bar; 6771Second parameter WIDTH specifies the pixel width for the scroll bar.
6278this is automatically adjusted to a multiple of the frame column width.
6279Third parameter VERTICAL-TYPE specifies the type of the vertical scroll 6772Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6280bar: left, right, or nil. 6773bar: left, right, or nil.
6281If WIDTH is nil, use the frame's scroll-bar width. 6774If WIDTH is nil, use the frame's scroll-bar width.
6282If VERTICAL-TYPE is t, use the frame's scroll-bar type. 6775If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6283Fourth parameter HORIZONTAL-TYPE is currently unused. 6776Fourth parameter HORIZONTAL-TYPE is currently unused.
6284 6777
6285Return t if scroll bars was actually changed and nil otherwise. */) 6778Return t if scroll bars were actually changed and nil otherwise. */)
6286 (Lisp_Object window, Lisp_Object width, 6779 (Lisp_Object window, Lisp_Object width,
6287 Lisp_Object vertical_type, Lisp_Object horizontal_type) 6780 Lisp_Object vertical_type, Lisp_Object horizontal_type)
6288{ 6781{
@@ -6477,6 +6970,10 @@ compare_window_configurations (Lisp_Object configuration1,
6477 != EQ (d2->current_window, sw2->window) 6970 != EQ (d2->current_window, sw2->window)
6478 /* Windows' buffers must match. */ 6971 /* Windows' buffers must match. */
6479 || !EQ (sw1->buffer, sw2->buffer) 6972 || !EQ (sw1->buffer, sw2->buffer)
6973 || !EQ (sw1->pixel_left, sw2->pixel_left)
6974 || !EQ (sw1->pixel_top, sw2->pixel_top)
6975 || !EQ (sw1->pixel_height, sw2->pixel_height)
6976 || !EQ (sw1->pixel_width, sw2->pixel_width)
6480 || !EQ (sw1->left_col, sw2->left_col) 6977 || !EQ (sw1->left_col, sw2->left_col)
6481 || !EQ (sw1->top_line, sw2->top_line) 6978 || !EQ (sw1->top_line, sw2->top_line)
6482 || !EQ (sw1->total_cols, sw2->total_cols) 6979 || !EQ (sw1->total_cols, sw2->total_cols)
@@ -6555,6 +7052,7 @@ syms_of_window (void)
6555 DEFSYM (Qdelete_window, "delete-window"); 7052 DEFSYM (Qdelete_window, "delete-window");
6556 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window"); 7053 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
6557 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically"); 7054 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
7055 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
6558 DEFSYM (Qsafe, "safe"); 7056 DEFSYM (Qsafe, "safe");
6559 DEFSYM (Qdisplay_buffer, "display-buffer"); 7057 DEFSYM (Qdisplay_buffer, "display-buffer");
6560 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows"); 7058 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
@@ -6713,6 +7211,18 @@ Parameters not saved by `current-window-configuration' or
6713respectively are not installed by `window-state-put'. */); 7211respectively are not installed by `window-state-put'. */);
6714 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt)); 7212 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
6715 7213
7214 DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise,
7215 doc: /* Non-nil means resizing windows works pixelwise.
7216Functions currently affected by this option are `split-window',
7217`maximize-window', `minimize-window', `fit-window-to-buffer' and
7218`fit-frame-to-buffer' and all functions symmetrically resizing a
7219parent window.
7220
7221Note that when a frame's pixel size is not a multiple of the
7222frame's character size, at least one window may get resized
7223pixelwise even if this option is nil. */);
7224 window_resize_pixelwise = 0;
7225
6716 defsubr (&Sselected_window); 7226 defsubr (&Sselected_window);
6717 defsubr (&Sminibuffer_window); 7227 defsubr (&Sminibuffer_window);
6718 defsubr (&Swindow_minibuffer_p); 7228 defsubr (&Swindow_minibuffer_p);
@@ -6735,16 +7245,23 @@ respectively are not installed by `window-state-put'. */);
6735 defsubr (&Swindow_combination_limit); 7245 defsubr (&Swindow_combination_limit);
6736 defsubr (&Sset_window_combination_limit); 7246 defsubr (&Sset_window_combination_limit);
6737 defsubr (&Swindow_use_time); 7247 defsubr (&Swindow_use_time);
6738 defsubr (&Swindow_top_line); 7248 defsubr (&Swindow_pixel_width);
6739 defsubr (&Swindow_left_column); 7249 defsubr (&Swindow_pixel_height);
6740 defsubr (&Swindow_total_height);
6741 defsubr (&Swindow_total_width); 7250 defsubr (&Swindow_total_width);
7251 defsubr (&Swindow_total_height);
6742 defsubr (&Swindow_normal_size); 7252 defsubr (&Swindow_normal_size);
7253 defsubr (&Swindow_new_pixel);
6743 defsubr (&Swindow_new_total); 7254 defsubr (&Swindow_new_total);
6744 defsubr (&Swindow_new_normal); 7255 defsubr (&Swindow_new_normal);
7256 defsubr (&Swindow_pixel_left);
7257 defsubr (&Swindow_pixel_top);
7258 defsubr (&Swindow_left_column);
7259 defsubr (&Swindow_top_line);
7260 defsubr (&Sset_window_new_pixel);
6745 defsubr (&Sset_window_new_total); 7261 defsubr (&Sset_window_new_total);
6746 defsubr (&Sset_window_new_normal); 7262 defsubr (&Sset_window_new_normal);
6747 defsubr (&Swindow_resize_apply); 7263 defsubr (&Swindow_resize_apply);
7264 defsubr (&Swindow_resize_apply_total);
6748 defsubr (&Swindow_body_height); 7265 defsubr (&Swindow_body_height);
6749 defsubr (&Swindow_body_width); 7266 defsubr (&Swindow_body_width);
6750 defsubr (&Swindow_hscroll); 7267 defsubr (&Swindow_hscroll);
@@ -6754,6 +7271,10 @@ respectively are not installed by `window-state-put'. */);
6754 defsubr (&Swindow_edges); 7271 defsubr (&Swindow_edges);
6755 defsubr (&Swindow_pixel_edges); 7272 defsubr (&Swindow_pixel_edges);
6756 defsubr (&Swindow_absolute_pixel_edges); 7273 defsubr (&Swindow_absolute_pixel_edges);
7274 defsubr (&Swindow_mode_line_height);
7275 defsubr (&Swindow_header_line_height);
7276 defsubr (&Swindow_right_divider_width);
7277 defsubr (&Swindow_bottom_divider_width);
6757 defsubr (&Swindow_inside_edges); 7278 defsubr (&Swindow_inside_edges);
6758 defsubr (&Swindow_inside_pixel_edges); 7279 defsubr (&Swindow_inside_pixel_edges);
6759 defsubr (&Swindow_inside_absolute_pixel_edges); 7280 defsubr (&Swindow_inside_absolute_pixel_edges);
@@ -6776,6 +7297,7 @@ respectively are not installed by `window-state-put'. */);
6776 defsubr (&Sresize_mini_window_internal); 7297 defsubr (&Sresize_mini_window_internal);
6777 defsubr (&Sset_window_buffer); 7298 defsubr (&Sset_window_buffer);
6778 defsubr (&Srun_window_configuration_change_hook); 7299 defsubr (&Srun_window_configuration_change_hook);
7300 defsubr (&Srun_window_scroll_functions);
6779 defsubr (&Sselect_window); 7301 defsubr (&Sselect_window);
6780 defsubr (&Sforce_window_update); 7302 defsubr (&Sforce_window_update);
6781 defsubr (&Ssplit_window_internal); 7303 defsubr (&Ssplit_window_internal);
@@ -6787,6 +7309,7 @@ respectively are not installed by `window-state-put'. */);
6787 defsubr (&Sscroll_other_window); 7309 defsubr (&Sscroll_other_window);
6788 defsubr (&Sminibuffer_selected_window); 7310 defsubr (&Sminibuffer_selected_window);
6789 defsubr (&Srecenter); 7311 defsubr (&Srecenter);
7312 defsubr (&Swindow_text_width);
6790 defsubr (&Swindow_text_height); 7313 defsubr (&Swindow_text_height);
6791 defsubr (&Smove_to_window_line); 7314 defsubr (&Smove_to_window_line);
6792 defsubr (&Swindow_configuration_p); 7315 defsubr (&Swindow_configuration_p);
diff --git a/src/window.h b/src/window.h
index f619b82e8a3..b91161f4d32 100644
--- a/src/window.h
+++ b/src/window.h
@@ -111,6 +111,7 @@ struct window
111 to something beyond an integer, so C int can't be used here. */ 111 to something beyond an integer, so C int can't be used here. */
112 Lisp_Object new_total; 112 Lisp_Object new_total;
113 Lisp_Object new_normal; 113 Lisp_Object new_normal;
114 Lisp_Object new_pixel;
114 115
115 /* May be buffer, window, or nil. */ 116 /* May be buffer, window, or nil. */
116 Lisp_Object contents; 117 Lisp_Object contents;
@@ -180,14 +181,26 @@ struct window
180 /* Number saying how recently window was selected. */ 181 /* Number saying how recently window was selected. */
181 int use_time; 182 int use_time;
182 183
184 /* Unique number of window assigned when it was created. */
185 int sequence_number;
186
187 /* The upper left corner pixel coordinates of this window, as
188 integers relative to upper left corner of frame = 0, 0. */
189 int pixel_left;
190 int pixel_top;
191
183 /* The upper left corner coordinates of this window, 192 /* The upper left corner coordinates of this window,
184 relative to upper left corner of frame = 0, 0. */ 193 relative to upper left corner of frame = 0, 0. */
185 int left_col; 194 int left_col;
186 int top_line; 195 int top_line;
187 196
197 /* The pixel size of the window. */
198 int pixel_width;
199 int pixel_height;
200
188 /* The size of the window. */ 201 /* The size of the window. */
189 int total_lines;
190 int total_cols; 202 int total_cols;
203 int total_lines;
191 204
192 /* Number of columns display within the window is scrolled to the left. */ 205 /* Number of columns display within the window is scrolled to the left. */
193 ptrdiff_t hscroll; 206 ptrdiff_t hscroll;
@@ -337,6 +350,9 @@ struct window
337 the frame image that window_end_pos did not get onto the frame. */ 350 the frame image that window_end_pos did not get onto the frame. */
338 unsigned window_end_valid : 1; 351 unsigned window_end_valid : 1;
339 352
353 /* True if it needs to be redisplayed. */
354 unsigned redisplay : 1;
355
340 /* Amount by which lines of this window are scrolled in 356 /* Amount by which lines of this window are scrolled in
341 y-direction (smooth scrolling). */ 357 y-direction (smooth scrolling). */
342 int vscroll; 358 int vscroll;
@@ -344,7 +360,7 @@ struct window
344 /* Z_BYTE - buffer position of the last glyph in the current matrix of W. 360 /* Z_BYTE - buffer position of the last glyph in the current matrix of W.
345 Should be nonnegative, and only valid if window_end_valid is nonzero. */ 361 Should be nonnegative, and only valid if window_end_valid is nonzero. */
346 ptrdiff_t window_end_bytepos; 362 ptrdiff_t window_end_bytepos;
347}; 363 };
348 364
349/* Most code should use these functions to set Lisp fields in struct 365/* Most code should use these functions to set Lisp fields in struct
350 window. */ 366 window. */
@@ -353,31 +369,43 @@ wset_frame (struct window *w, Lisp_Object val)
353{ 369{
354 w->frame = val; 370 w->frame = val;
355} 371}
372
356INLINE void 373INLINE void
357wset_next (struct window *w, Lisp_Object val) 374wset_next (struct window *w, Lisp_Object val)
358{ 375{
359 w->next = val; 376 w->next = val;
360} 377}
378
361INLINE void 379INLINE void
362wset_prev (struct window *w, Lisp_Object val) 380wset_prev (struct window *w, Lisp_Object val)
363{ 381{
364 w->prev = val; 382 w->prev = val;
365} 383}
384
366INLINE void 385INLINE void
367wset_redisplay_end_trigger (struct window *w, Lisp_Object val) 386wset_redisplay_end_trigger (struct window *w, Lisp_Object val)
368{ 387{
369 w->redisplay_end_trigger = val; 388 w->redisplay_end_trigger = val;
370} 389}
390
391INLINE void
392wset_new_pixel (struct window *w, Lisp_Object val)
393{
394 w->new_pixel = val;
395}
396
371INLINE void 397INLINE void
372wset_vertical_scroll_bar (struct window *w, Lisp_Object val) 398wset_vertical_scroll_bar (struct window *w, Lisp_Object val)
373{ 399{
374 w->vertical_scroll_bar = val; 400 w->vertical_scroll_bar = val;
375} 401}
402
376INLINE void 403INLINE void
377wset_prev_buffers (struct window *w, Lisp_Object val) 404wset_prev_buffers (struct window *w, Lisp_Object val)
378{ 405{
379 w->prev_buffers = val; 406 w->prev_buffers = val;
380} 407}
408
381INLINE void 409INLINE void
382wset_next_buffers (struct window *w, Lisp_Object val) 410wset_next_buffers (struct window *w, Lisp_Object val)
383{ 411{
@@ -443,38 +471,44 @@ wset_next_buffers (struct window *w, Lisp_Object val)
443#define WINDOW_FRAME_LINE_HEIGHT(W) \ 471#define WINDOW_FRAME_LINE_HEIGHT(W) \
444 (FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W)))) 472 (FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W))))
445 473
446/* Return the width of window W in canonical column units. 474/* Return the pixel width of window W.
447 This includes scroll bars and fringes. */ 475 This includes scroll bars and fringes. */
476#define WINDOW_PIXEL_WIDTH(W) (W)->pixel_width
477
478/* Return the pixel height of window W.
479 This includes header and mode lines, if any. */
480#define WINDOW_PIXEL_HEIGHT(W) (W)->pixel_height
448 481
482/* Return the width of window W in canonical column units.
483 This includes scroll bars and fringes.
484 This value is adjusted such that the sum of the widths of all child
485 windows equals the width of their parent window. */
449#define WINDOW_TOTAL_COLS(W) (W)->total_cols 486#define WINDOW_TOTAL_COLS(W) (W)->total_cols
450 487
451/* Return the height of window W in canonical line units. 488/* Return the height of window W in canonical line units.
452 This includes header and mode lines, if any. */ 489 This includes header and mode lines, if any.
453 490 This value is adjusted such that the sum of the heights of all child
491 windows equals the height of their parent window. */
454#define WINDOW_TOTAL_LINES(W) (W)->total_lines 492#define WINDOW_TOTAL_LINES(W) (W)->total_lines
455 493
456/* Return the total pixel width of window W. */
457
458#define WINDOW_TOTAL_WIDTH(W) \
459 (WINDOW_TOTAL_COLS (W) * WINDOW_FRAME_COLUMN_WIDTH (W))
460
461/* Return the total pixel height of window W. */
462
463#define WINDOW_TOTAL_HEIGHT(W) \
464 (WINDOW_TOTAL_LINES (W) * WINDOW_FRAME_LINE_HEIGHT (W))
465
466/* For HORFLAG non-zero the total number of columns of window W. Otherwise
467 the total number of lines of W. */
468
469#define WINDOW_TOTAL_SIZE(w, horflag) \
470 (horflag ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
471
472/* The smallest acceptable dimensions for a window. Anything smaller 494/* The smallest acceptable dimensions for a window. Anything smaller
473 might crash Emacs. */ 495 might crash Emacs. */
496#define MIN_SAFE_WINDOW_WIDTH (2)
497
498#define MIN_SAFE_WINDOW_PIXEL_WIDTH(W) \
499 (2 * WINDOW_FRAME_COLUMN_WIDTH (W))
474 500
475#define MIN_SAFE_WINDOW_WIDTH (2)
476#define MIN_SAFE_WINDOW_HEIGHT (1) 501#define MIN_SAFE_WINDOW_HEIGHT (1)
477 502
503#define MIN_SAFE_WINDOW_PIXEL_HEIGHT(W) \
504 (WINDOW_FRAME_LINE_HEIGHT (W))
505
506/* Width of right divider of window W. */
507#define WINDOW_RIGHT_DIVIDER_WIDTH(W) \
508 ((WINDOW_RIGHTMOST_P (W) || MINI_WINDOW_P (W)) \
509 ? 0 \
510 : FRAME_RIGHT_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
511
478/* Return the canonical frame column at which window W starts. 512/* Return the canonical frame column at which window W starts.
479 This includes a left-hand scroll bar, if any. */ 513 This includes a left-hand scroll bar, if any. */
480 514
@@ -497,20 +531,37 @@ wset_next_buffers (struct window *w, Lisp_Object val)
497#define WINDOW_BOTTOM_EDGE_LINE(W) \ 531#define WINDOW_BOTTOM_EDGE_LINE(W) \
498 (WINDOW_TOP_EDGE_LINE (W) + WINDOW_TOTAL_LINES (W)) 532 (WINDOW_TOP_EDGE_LINE (W) + WINDOW_TOTAL_LINES (W))
499 533
534/* Return the left pixel edge at which window W starts.
535 This includes a left-hand scroll bar, if any. */
536#define WINDOW_LEFT_PIXEL_EDGE(W) (W)->pixel_left
537
538/* Return the right pixel edge before which window W ends.
539 This includes a right-hand scroll bar, if any. */
540#define WINDOW_RIGHT_PIXEL_EDGE(W) \
541 (WINDOW_LEFT_PIXEL_EDGE (W) + WINDOW_PIXEL_WIDTH (W))
542
543/* Return the top pixel edge at which window W starts.
544 This includes a header line, if any. */
545#define WINDOW_TOP_PIXEL_EDGE(W) (W)->pixel_top
546
547/* Return the bottom pixel edge before which window W ends.
548 This includes a mode line, if any. */
549#define WINDOW_BOTTOM_PIXEL_EDGE(W) \
550 (WINDOW_TOP_PIXEL_EDGE (W) + WINDOW_PIXEL_HEIGHT (W))
500 551
501/* Return the frame x-position at which window W starts. 552/* Return the frame x-position at which window W starts.
502 This includes a left-hand scroll bar, if any. */ 553 This includes a left-hand scroll bar, if any. */
503 554
504#define WINDOW_LEFT_EDGE_X(W) \ 555#define WINDOW_LEFT_EDGE_X(W) \
505 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \ 556 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
506 + WINDOW_LEFT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W)) 557 + WINDOW_LEFT_PIXEL_EDGE (W))
507 558
508/* Return the frame x- position before which window W ends. 559/* Return the frame x- position before which window W ends.
509 This includes a right-hand scroll bar, if any. */ 560 This includes a right-hand scroll bar, if any. */
510 561
511#define WINDOW_RIGHT_EDGE_X(W) \ 562#define WINDOW_RIGHT_EDGE_X(W) \
512 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \ 563 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
513 + WINDOW_RIGHT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W)) 564 + WINDOW_RIGHT_PIXEL_EDGE (W))
514 565
515/* 1 if W is a menu bar window. */ 566/* 1 if W is a menu bar window. */
516 567
@@ -533,37 +584,45 @@ wset_next_buffers (struct window *w, Lisp_Object val)
533#endif 584#endif
534 585
535/* Return the frame y-position at which window W starts. 586/* Return the frame y-position at which window W starts.
536 This includes a header line, if any. */ 587 This includes a header line, if any.
537 588
589 PXW: With a menu or tool bar this is not symmetric to the _X values
590 since it _does_ include the internal border width. */
538#define WINDOW_TOP_EDGE_Y(W) \ 591#define WINDOW_TOP_EDGE_Y(W) \
539 (((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \ 592 (((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
540 ? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \ 593 ? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \
541 + WINDOW_TOP_EDGE_LINE (W) * WINDOW_FRAME_LINE_HEIGHT (W)) 594 + WINDOW_TOP_PIXEL_EDGE (W))
542 595
543/* Return the frame y-position before which window W ends. 596/* Return the frame y-position before which window W ends.
544 This includes a mode line, if any. */ 597 This includes a mode line, if any. */
545 598#define WINDOW_BOTTOM_EDGE_Y(W) \
546#define WINDOW_BOTTOM_EDGE_Y(W) \ 599 (((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
547 (((WINDOW_MENU_BAR_P (W) || WINDOW_TOOL_BAR_P (W)) \
548 ? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \ 600 ? 0 : FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W))) \
549 + WINDOW_BOTTOM_EDGE_LINE (W) * WINDOW_FRAME_LINE_HEIGHT (W)) 601 + WINDOW_BOTTOM_PIXEL_EDGE (W))
550
551 602
552/* 1 if window W takes up the full width of its frame. */ 603/* 1 if window W takes up the full width of its frame. */
553 604#define WINDOW_FULL_WIDTH_P(W) \
554#define WINDOW_FULL_WIDTH_P(W) \ 605 (WINDOW_PIXEL_WIDTH (W) \
555 (WINDOW_TOTAL_COLS (W) == FRAME_TOTAL_COLS (WINDOW_XFRAME (W))) 606 == (WINDOW_PIXEL_WIDTH \
607 (XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
556 608
557/* 1 if window W's has no other windows to its left in its frame. */ 609/* 1 if window W's has no other windows to its left in its frame. */
558 610
559#define WINDOW_LEFTMOST_P(W) \ 611#define WINDOW_LEFTMOST_P(W) \
560 (WINDOW_LEFT_EDGE_COL (W) == 0) 612 (WINDOW_LEFT_PIXEL_EDGE (W) == 0)
561 613
562/* 1 if window W's has no other windows to its right in its frame. */ 614/* 1 if window W's has no other windows to its right in its frame. */
563 615#define WINDOW_RIGHTMOST_P(W) \
564#define WINDOW_RIGHTMOST_P(W) \ 616 (WINDOW_RIGHT_PIXEL_EDGE (W) \
565 (WINDOW_RIGHT_EDGE_COL (W) == FRAME_TOTAL_COLS (WINDOW_XFRAME (W))) 617 == (WINDOW_RIGHT_PIXEL_EDGE \
566 618 (XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
619
620/* 1 if window W's has no other windows below it in its frame
621 (the minibuffer window is not counted in this respect). */
622#define WINDOW_BOTTOMMOST_P(W) \
623 (WINDOW_BOTTOM_PIXEL_EDGE (W) \
624 == (WINDOW_BOTTOM_PIXEL_EDGE \
625 (XWINDOW (FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))) \
567 626
568/* Return the frame column at which the text (or left fringe) in 627/* Return the frame column at which the text (or left fringe) in
569 window W starts. This is different from the `LEFT_EDGE' because it 628 window W starts. This is different from the `LEFT_EDGE' because it
@@ -573,6 +632,13 @@ wset_next_buffers (struct window *w, Lisp_Object val)
573 (WINDOW_LEFT_EDGE_COL (W) \ 632 (WINDOW_LEFT_EDGE_COL (W) \
574 + WINDOW_LEFT_SCROLL_BAR_COLS (W)) 633 + WINDOW_LEFT_SCROLL_BAR_COLS (W))
575 634
635/* Return the pixel value where the text (or left fringe) in
636 window W starts. This is different from the `LEFT_EDGE' because it
637 does not include a left-hand scroll bar if any. */
638#define WINDOW_BOX_LEFT_PIXEL_EDGE(W) \
639 (WINDOW_LEFT_PIXEL_EDGE (W) \
640 + WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (W))
641
576/* Return the window column before which the text in window W ends. 642/* Return the window column before which the text in window W ends.
577 This is different from WINDOW_RIGHT_EDGE_COL because it does not 643 This is different from WINDOW_RIGHT_EDGE_COL because it does not
578 include a scroll bar or window-separating line on the right edge. */ 644 include a scroll bar or window-separating line on the right edge. */
@@ -581,59 +647,72 @@ wset_next_buffers (struct window *w, Lisp_Object val)
581 (WINDOW_RIGHT_EDGE_COL (W) \ 647 (WINDOW_RIGHT_EDGE_COL (W) \
582 - WINDOW_RIGHT_SCROLL_BAR_COLS (W)) 648 - WINDOW_RIGHT_SCROLL_BAR_COLS (W))
583 649
650/* Return the pixel value before which the text in window W ends. This
651 is different from the `RIGHT_EDGE' because it does not include a
652 right-hand scroll bar or window-separating line on the right
653 edge. */
654#define WINDOW_BOX_RIGHT_PIXEL_EDGE(W) \
655 (WINDOW_RIGHT_PIXEL_EDGE (W) \
656 - WINDOW_RIGHT_DIVIDER_WIDTH (W) \
657 - WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (W))
584 658
585/* Return the frame position at which the text (or left fringe) in 659/* Return the frame position at which the text (or left fringe) in
586 window W starts. This is different from the `LEFT_EDGE' because it 660 window W starts. This is different from the `LEFT_EDGE' because it
587 does not include a left-hand scroll bar if any. */ 661 does not include a left-hand scroll bar if any. */
588 662#define WINDOW_BOX_LEFT_EDGE_X(W) \
589#define WINDOW_BOX_LEFT_EDGE_X(W) \
590 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \ 663 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
591 + WINDOW_BOX_LEFT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W)) 664 + WINDOW_BOX_LEFT_PIXEL_EDGE (W))
592 665
593/* Return the window column before which the text in window W ends. 666/* Return the window column before which the text in window W ends.
594 This is different from WINDOW_RIGHT_EDGE_COL because it does not 667 This is different from WINDOW_RIGHT_EDGE_COL because it does not
595 include a scroll bar or window-separating line on the right edge. */ 668 include a scroll bar or window-separating line on the right edge. */
596 669#define WINDOW_BOX_RIGHT_EDGE_X(W) \
597#define WINDOW_BOX_RIGHT_EDGE_X(W) \
598 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \ 670 (FRAME_INTERNAL_BORDER_WIDTH (WINDOW_XFRAME (W)) \
599 + WINDOW_BOX_RIGHT_EDGE_COL (W) * WINDOW_FRAME_COLUMN_WIDTH (W)) 671 + WINDOW_BOX_RIGHT_PIXEL_EDGE (W))
600
601
602/* Width of left margin area in columns. */
603 672
673/* Widths of marginal areas in columns. */
604#define WINDOW_LEFT_MARGIN_COLS(W) (W->left_margin_cols) 674#define WINDOW_LEFT_MARGIN_COLS(W) (W->left_margin_cols)
605 675
606/* Width of right marginal area in columns. */
607
608#define WINDOW_RIGHT_MARGIN_COLS(W) (W->right_margin_cols) 676#define WINDOW_RIGHT_MARGIN_COLS(W) (W->right_margin_cols)
609 677
610/* Width of left margin area in pixels. */ 678#define WINDOW_MARGINS_COLS(W) \
679 (WINDOW_LEFT_MARGIN_COLS (W) \
680 + WINDOW_RIGHT_MARGIN_COLS (W))
611 681
682/* Widths of marginal areas in pixels. */
612#define WINDOW_LEFT_MARGIN_WIDTH(W) \ 683#define WINDOW_LEFT_MARGIN_WIDTH(W) \
613 (W->left_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W)) 684 (W->left_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W))
614 685
615/* Width of right marginal area in pixels. */ 686#define WINDOW_RIGHT_MARGIN_WIDTH(W) \
616
617#define WINDOW_RIGHT_MARGIN_WIDTH(W) \
618 (W->right_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W)) 687 (W->right_margin_cols * WINDOW_FRAME_COLUMN_WIDTH (W))
619 688
620/* Total width of fringes reserved for drawing truncation bitmaps, 689#define WINDOW_MARGINS_WIDTH(W) \
621 continuation bitmaps and alike. The width is in canonical char 690 (WINDOW_LEFT_MARGIN_WIDTH (W) \
622 units of the frame. This must currently be the case because window 691 + WINDOW_RIGHT_MARGIN_WIDTH (W))
623 sizes aren't pixel values. If it weren't the case, we wouldn't be
624 able to split windows horizontally nicely. */
625 692
693/* Pixel-widths of fringes. */
694#define WINDOW_LEFT_FRINGE_WIDTH(W) \
695 (W->left_fringe_width >= 0 \
696 ? W->left_fringe_width \
697 : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
698
699#define WINDOW_RIGHT_FRINGE_WIDTH(W) \
700 (W->right_fringe_width >= 0 \
701 ? W->right_fringe_width \
702 : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
703
704#define WINDOW_FRINGES_WIDTH(W) \
705 (WINDOW_LEFT_FRINGE_WIDTH (W) + WINDOW_RIGHT_FRINGE_WIDTH (W))
706
707/* Widths of fringes in columns. */
626#define WINDOW_FRINGE_COLS(W) \ 708#define WINDOW_FRINGE_COLS(W) \
627 ((W->left_fringe_width >= 0 \ 709 ((W->left_fringe_width >= 0 \
628 && W->right_fringe_width >= 0) \ 710 && W->right_fringe_width >= 0) \
629 ? ((W->left_fringe_width \ 711 ? ((WINDOW_FRINGES_WIDTH (W) \
630 + W->right_fringe_width \
631 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \ 712 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
632 / WINDOW_FRAME_COLUMN_WIDTH (W)) \ 713 / WINDOW_FRAME_COLUMN_WIDTH (W)) \
633 : FRAME_FRINGE_COLS (WINDOW_XFRAME (W))) 714 : FRAME_FRINGE_COLS (WINDOW_XFRAME (W)))
634 715
635/* Column-width of the left and right fringe. */
636
637#define WINDOW_LEFT_FRINGE_COLS(W) \ 716#define WINDOW_LEFT_FRINGE_COLS(W) \
638 ((WINDOW_LEFT_FRINGE_WIDTH ((W)) \ 717 ((WINDOW_LEFT_FRINGE_WIDTH ((W)) \
639 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \ 718 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
@@ -644,29 +723,12 @@ wset_next_buffers (struct window *w, Lisp_Object val)
644 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \ 723 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
645 / WINDOW_FRAME_COLUMN_WIDTH (W)) 724 / WINDOW_FRAME_COLUMN_WIDTH (W))
646 725
647/* Pixel-width of the left and right fringe. */
648
649#define WINDOW_LEFT_FRINGE_WIDTH(W) \
650 (W->left_fringe_width >= 0 ? W->left_fringe_width \
651 : FRAME_LEFT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
652
653#define WINDOW_RIGHT_FRINGE_WIDTH(W) \
654 (W->right_fringe_width >= 0 ? W->right_fringe_width \
655 : FRAME_RIGHT_FRINGE_WIDTH (WINDOW_XFRAME (W)))
656
657/* Total width of fringes in pixels. */
658
659#define WINDOW_TOTAL_FRINGE_WIDTH(W) \
660 (WINDOW_LEFT_FRINGE_WIDTH (W) + WINDOW_RIGHT_FRINGE_WIDTH (W))
661
662/* Are fringes outside display margins in window W. */ 726/* Are fringes outside display margins in window W. */
663
664#define WINDOW_HAS_FRINGES_OUTSIDE_MARGINS(W) \ 727#define WINDOW_HAS_FRINGES_OUTSIDE_MARGINS(W) \
665 ((W)->fringes_outside_margins) 728 ((W)->fringes_outside_margins)
666 729
667/* Say whether scroll bars are currently enabled for window W, 730/* Say whether scroll bars are currently enabled for window W,
668 and which side they are on. */ 731 and which side they are on. */
669
670#define WINDOW_VERTICAL_SCROLL_BAR_TYPE(w) \ 732#define WINDOW_VERTICAL_SCROLL_BAR_TYPE(w) \
671 (EQ (w->vertical_scroll_bar_type, Qt) \ 733 (EQ (w->vertical_scroll_bar_type, Qt) \
672 ? FRAME_VERTICAL_SCROLL_BAR_TYPE (WINDOW_XFRAME (w)) \ 734 ? FRAME_VERTICAL_SCROLL_BAR_TYPE (WINDOW_XFRAME (w)) \
@@ -694,15 +756,14 @@ wset_next_buffers (struct window *w, Lisp_Object val)
694/* Width that a scroll bar in window W should have, if there is one. 756/* Width that a scroll bar in window W should have, if there is one.
695 Measured in pixels. If scroll bars are turned off, this is still 757 Measured in pixels. If scroll bars are turned off, this is still
696 nonzero. */ 758 nonzero. */
697
698#define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \ 759#define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \
699 (w->scroll_bar_width >= 0 ? w->scroll_bar_width \ 760 (w->scroll_bar_width >= 0 \
761 ? w->scroll_bar_width \
700 : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w))) 762 : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w)))
701 763
702/* Width that a scroll bar in window W should have, if there is one. 764/* Width that a scroll bar in window W should have, if there is one.
703 Measured in columns (characters). If scroll bars are turned off, 765 Measured in columns (characters). If scroll bars are turned off,
704 this is still nonzero. */ 766 this is still nonzero. */
705
706#define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \ 767#define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \
707 (w->scroll_bar_width >= 0 \ 768 (w->scroll_bar_width >= 0 \
708 ? ((w->scroll_bar_width \ 769 ? ((w->scroll_bar_width \
@@ -710,65 +771,64 @@ wset_next_buffers (struct window *w, Lisp_Object val)
710 / WINDOW_FRAME_COLUMN_WIDTH (w)) \ 771 / WINDOW_FRAME_COLUMN_WIDTH (w)) \
711 : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w))) 772 : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w)))
712 773
713/* Width of a scroll bar in window W, measured in columns (characters), 774/* Width of left scroll bar in window W, measured in columns
714 but only if scroll bars are on the left. If scroll bars are on 775 (characters). If scroll bars are on the right in this frame, or
715 the right in this frame, or there are no scroll bars, value is 0. */ 776 there are no scroll bars, value is 0. */
716
717#define WINDOW_LEFT_SCROLL_BAR_COLS(w) \ 777#define WINDOW_LEFT_SCROLL_BAR_COLS(w) \
718 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \ 778 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
719 ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w)) \ 779 ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w)) \
720 : 0) 780 : 0)
721 781
722/* Width of a left scroll bar area in window W , measured in pixels. */ 782/* Width of right scroll bar in window W, measured in columns
723 783 (characters). If scroll bars are on the left in this frame, or there
724#define WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH(w) \ 784 are no scroll bars, value is 0. */
725 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
726 ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w)) \
727 : 0)
728
729/* Width of a scroll bar in window W, measured in columns (characters),
730 but only if scroll bars are on the right. If scroll bars are on
731 the left in this frame, or there are no scroll bars, value is 0. */
732
733#define WINDOW_RIGHT_SCROLL_BAR_COLS(w) \ 785#define WINDOW_RIGHT_SCROLL_BAR_COLS(w) \
734 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \ 786 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \
735 ? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \ 787 ? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \
736 : 0) 788 : 0)
737 789
738/* Width of a left scroll bar area in window W , measured in pixels. */ 790/* Width of a scroll bar in window W, measured in columns. */
739
740#define WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH(w) \
741 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \
742 ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w)) \
743 : 0)
744
745
746/* Actual width of a scroll bar in window W, measured in columns. */
747
748#define WINDOW_SCROLL_BAR_COLS(w) \ 791#define WINDOW_SCROLL_BAR_COLS(w) \
749 (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \ 792 (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \
750 ? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \ 793 ? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \
751 : 0) 794 : 0)
752 795
753/* Width of a left scroll bar area in window W , measured in pixels. */ 796/* Width of a left scroll bar area in window W, measured in pixels. */
797#define WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH(w) \
798 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
799 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \
800 : 0)
754 801
755#define WINDOW_SCROLL_BAR_AREA_WIDTH(w) \ 802/* Width of a right scroll bar area in window W, measured in pixels. */
756 (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \ 803#define WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH(w) \
757 ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w) * WINDOW_FRAME_COLUMN_WIDTH (w)) \ 804 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \
805 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \
758 : 0) 806 : 0)
759 807
808/* Width of scroll bar area in window W, measured in pixels. */
809#define WINDOW_SCROLL_BAR_AREA_WIDTH(w) \
810 (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \
811 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \
812 : 0)
760 813
761/* Return the frame position where the scroll bar of window W starts. */ 814/* Return the frame position where the scroll bar of window W starts. */
762
763#define WINDOW_SCROLL_BAR_AREA_X(W) \ 815#define WINDOW_SCROLL_BAR_AREA_X(W) \
764 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W) \ 816 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W) \
765 ? WINDOW_BOX_RIGHT_EDGE_X (W) \ 817 ? WINDOW_BOX_RIGHT_EDGE_X (W) \
766 : WINDOW_LEFT_EDGE_X (W)) 818 : WINDOW_LEFT_EDGE_X (W))
767 819
820/* Width of bottom divider of window W. */
821#define WINDOW_BOTTOM_DIVIDER_WIDTH(W) \
822 (((WINDOW_BOTTOMMOST_P (W) \
823 && NILP ((XWINDOW (FRAME_ROOT_WINDOW \
824 (WINDOW_XFRAME (W))))->next)) \
825 || EQ ((W)->prev, FRAME_ROOT_WINDOW (WINDOW_XFRAME (W))) \
826 || (W)->pseudo_window_p) \
827 ? 0 \
828 : FRAME_BOTTOM_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
768 829
769/* Height in pixels, and in lines, of the mode line. 830/* Height in pixels, and in lines, of the mode line.
770 May be zero if W doesn't have a mode line. */ 831 May be zero if W doesn't have a mode line. */
771
772#define WINDOW_MODE_LINE_HEIGHT(W) \ 832#define WINDOW_MODE_LINE_HEIGHT(W) \
773 (WINDOW_WANTS_MODELINE_P ((W)) \ 833 (WINDOW_WANTS_MODELINE_P ((W)) \
774 ? CURRENT_MODE_LINE_HEIGHT (W) \ 834 ? CURRENT_MODE_LINE_HEIGHT (W) \
@@ -779,7 +839,6 @@ wset_next_buffers (struct window *w, Lisp_Object val)
779 839
780/* Height in pixels, and in lines, of the header line. 840/* Height in pixels, and in lines, of the header line.
781 Zero if W doesn't have a header line. */ 841 Zero if W doesn't have a header line. */
782
783#define WINDOW_HEADER_LINE_HEIGHT(W) \ 842#define WINDOW_HEADER_LINE_HEIGHT(W) \
784 (WINDOW_WANTS_HEADER_LINE_P ((W)) \ 843 (WINDOW_WANTS_HEADER_LINE_P ((W)) \
785 ? CURRENT_HEADER_LINE_HEIGHT (W) \ 844 ? CURRENT_HEADER_LINE_HEIGHT (W) \
@@ -788,43 +847,38 @@ wset_next_buffers (struct window *w, Lisp_Object val)
788#define WINDOW_HEADER_LINE_LINES(W) \ 847#define WINDOW_HEADER_LINE_LINES(W) \
789 (!! WINDOW_WANTS_HEADER_LINE_P ((W))) 848 (!! WINDOW_WANTS_HEADER_LINE_P ((W)))
790 849
791/* Pixel height of window W without mode line. */ 850/* Pixel height of window W without mode line and bottom divider. */
792
793#define WINDOW_BOX_HEIGHT_NO_MODE_LINE(W) \ 851#define WINDOW_BOX_HEIGHT_NO_MODE_LINE(W) \
794 (WINDOW_TOTAL_HEIGHT ((W)) \ 852 (WINDOW_PIXEL_HEIGHT ((W)) \
853 - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \
795 - WINDOW_MODE_LINE_HEIGHT ((W))) 854 - WINDOW_MODE_LINE_HEIGHT ((W)))
796 855
797/* Pixel height of window W without mode and header line. */ 856/* Pixel height of window W without mode and header line and bottom
798 857 divider. */
799#define WINDOW_BOX_TEXT_HEIGHT(W) \ 858#define WINDOW_BOX_TEXT_HEIGHT(W) \
800 (WINDOW_TOTAL_HEIGHT ((W)) \ 859 (WINDOW_PIXEL_HEIGHT ((W)) \
860 - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \
801 - WINDOW_MODE_LINE_HEIGHT ((W)) \ 861 - WINDOW_MODE_LINE_HEIGHT ((W)) \
802 - WINDOW_HEADER_LINE_HEIGHT ((W))) 862 - WINDOW_HEADER_LINE_HEIGHT ((W)))
803 863
804
805/* Convert window W relative pixel X to frame pixel coordinates. */ 864/* Convert window W relative pixel X to frame pixel coordinates. */
806
807#define WINDOW_TO_FRAME_PIXEL_X(W, X) \ 865#define WINDOW_TO_FRAME_PIXEL_X(W, X) \
808 ((X) + WINDOW_BOX_LEFT_EDGE_X ((W))) 866 ((X) + WINDOW_BOX_LEFT_EDGE_X ((W)))
809 867
810/* Convert window W relative pixel Y to frame pixel coordinates. */ 868/* Convert window W relative pixel Y to frame pixel coordinates. */
811
812#define WINDOW_TO_FRAME_PIXEL_Y(W, Y) \ 869#define WINDOW_TO_FRAME_PIXEL_Y(W, Y) \
813 ((Y) + WINDOW_TOP_EDGE_Y ((W))) 870 ((Y) + WINDOW_TOP_EDGE_Y ((W)))
814 871
815/* Convert frame relative pixel X to window relative pixel X. */ 872/* Convert frame relative pixel X to window relative pixel X. */
816
817#define FRAME_TO_WINDOW_PIXEL_X(W, X) \ 873#define FRAME_TO_WINDOW_PIXEL_X(W, X) \
818 ((X) - WINDOW_BOX_LEFT_EDGE_X ((W))) 874 ((X) - WINDOW_BOX_LEFT_EDGE_X ((W)))
819 875
820/* Convert frame relative pixel Y to window relative pixel Y. */ 876/* Convert frame relative pixel Y to window relative pixel Y. */
821
822#define FRAME_TO_WINDOW_PIXEL_Y(W, Y) \ 877#define FRAME_TO_WINDOW_PIXEL_Y(W, Y) \
823 ((Y) - WINDOW_TOP_EDGE_Y ((W))) 878 ((Y) - WINDOW_TOP_EDGE_Y ((W)))
824 879
825/* Convert a text area relative x-position in window W to frame X 880/* Convert a text area relative x-position in window W to frame X
826 pixel coordinates. */ 881 pixel coordinates. */
827
828#define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ 882#define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \
829 (window_box_left ((W), TEXT_AREA) + (X)) 883 (window_box_left ((W), TEXT_AREA) + (X))
830 884
@@ -870,18 +924,17 @@ extern Lisp_Object minibuf_selected_window;
870extern Lisp_Object make_window (void); 924extern Lisp_Object make_window (void);
871extern Lisp_Object window_from_coordinates (struct frame *, int, int, 925extern Lisp_Object window_from_coordinates (struct frame *, int, int,
872 enum window_part *, bool); 926 enum window_part *, bool);
873extern void resize_frame_windows (struct frame *, int, bool); 927extern void resize_frame_windows (struct frame *, int, bool, bool);
874extern void restore_window_configuration (Lisp_Object); 928extern void restore_window_configuration (Lisp_Object);
875extern void delete_all_child_windows (Lisp_Object); 929extern void delete_all_child_windows (Lisp_Object);
876extern void grow_mini_window (struct window *, int); 930extern void grow_mini_window (struct window *, int, bool);
877extern void shrink_mini_window (struct window *); 931extern void shrink_mini_window (struct window *, bool);
878extern int window_relative_x_coord (struct window *, enum window_part, int); 932extern int window_relative_x_coord (struct window *, enum window_part, int);
879 933
880void run_window_configuration_change_hook (struct frame *f); 934void run_window_configuration_change_hook (struct frame *f);
881 935
882/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero 936/* Make WINDOW display BUFFER. RUN_HOOKS_P non-zero means it's allowed
883 means it's allowed to run hooks. See make_frame for a case where 937 to run hooks. See make_frame for a case where it's not allowed. */
884 it's not allowed. */
885 938
886void set_window_buffer (Lisp_Object window, Lisp_Object buffer, 939void set_window_buffer (Lisp_Object window, Lisp_Object buffer,
887 bool run_hooks_p, bool keep_margins_p); 940 bool run_hooks_p, bool keep_margins_p);
@@ -900,19 +953,36 @@ extern EMACS_INT command_loop_level;
900 953
901extern EMACS_INT minibuf_level; 954extern EMACS_INT minibuf_level;
902 955
903/* true if we should redraw the mode lines on the next redisplay. */ 956/* Non-zero if we should redraw the mode lines on the next redisplay.
957 Usually set to a unique small integer so we can track the main causes of
958 full redisplays in `redisplay--mode-lines-cause'. */
904 959
905extern int update_mode_lines; 960extern int update_mode_lines;
906 961
907/* Nonzero if window sizes or contents have changed since last 962/* Nonzero if window sizes or contents have changed since last
908 redisplay that finished. */ 963 redisplay that finished. Usually set to a unique small integer so
964 we can track the main causes of full redisplays in
965 `redisplay--all-windows-cause'. */
909 966
910extern int windows_or_buffers_changed; 967extern int windows_or_buffers_changed;
911 968
969/* The main redisplay routine usually only redisplays the selected-window,
970 so when something's changed elsewhere, we call one of the functions below
971 to indicate which other windows might also need to be redisplayed. */
972
973extern void wset_redisplay (struct window *w);
974extern void fset_redisplay (struct frame *f);
975extern void bset_redisplay (struct buffer *b);
976extern void bset_update_mode_line (struct buffer *b);
977/* Call this to tell redisplay to look for other windows than selected-window
978 that need to be redisplayed. Calling one of the *set_redisplay functions
979 above already does it, so it's only needed in unusual cases. */
980extern void redisplay_other_windows (void);
981
912/* If *ROWS or *COLS are too small a size for FRAME, set them to the 982/* If *ROWS or *COLS are too small a size for FRAME, set them to the
913 minimum allowable size. */ 983 minimum allowable size. */
914 984
915extern void check_frame_size (struct frame *frame, int *rows, int *cols); 985extern void check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise);
916 986
917/* Return a pointer to the glyph W's physical cursor is on. Value is 987/* Return a pointer to the glyph W's physical cursor is on. Value is
918 null if W's current matrix is invalid, so that no meaningful glyph 988 null if W's current matrix is invalid, so that no meaningful glyph
@@ -942,12 +1012,13 @@ struct glyph *get_phys_cursor_glyph (struct window *w);
942extern Lisp_Object Qwindow_live_p; 1012extern Lisp_Object Qwindow_live_p;
943extern Lisp_Object Vwindow_list; 1013extern Lisp_Object Vwindow_list;
944 1014
1015extern Lisp_Object window_list (void);
945extern struct window *decode_live_window (Lisp_Object); 1016extern struct window *decode_live_window (Lisp_Object);
946extern struct window *decode_any_window (Lisp_Object); 1017extern struct window *decode_any_window (Lisp_Object);
947extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool); 1018extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool);
948extern void mark_window_cursors_off (struct window *); 1019extern void mark_window_cursors_off (struct window *);
949extern int window_internal_height (struct window *); 1020extern int window_internal_height (struct window *);
950extern int window_body_cols (struct window *w); 1021extern int window_body_width (struct window *w, bool);
951extern void temp_output_buffer_show (Lisp_Object); 1022extern void temp_output_buffer_show (Lisp_Object);
952extern void replace_buffer_in_windows (Lisp_Object); 1023extern void replace_buffer_in_windows (Lisp_Object);
953extern void replace_buffer_in_windows_safely (Lisp_Object); 1024extern void replace_buffer_in_windows_safely (Lisp_Object);
diff --git a/src/xdisp.c b/src/xdisp.c
index 47855a1de3c..530eae3cb9e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -502,12 +502,20 @@ static Lisp_Object Vmessage_stack;
502 502
503static bool message_enable_multibyte; 503static bool message_enable_multibyte;
504 504
505/* Nonzero if we should redraw the mode lines on the next redisplay. */ 505/* Nonzero if we should redraw the mode lines on the next redisplay.
506 If it has value REDISPLAY_SOME, then only redisplay the mode lines where
507 the `redisplay' bit has been set. Otherwise, redisplay all mode lines
508 (the number used is then only used to track down the cause for this
509 full-redisplay). */
506 510
507int update_mode_lines; 511int update_mode_lines;
508 512
509/* Nonzero if window sizes or contents have changed since last 513/* Nonzero if window sizes or contents other than selected-window have changed
510 redisplay that finished. */ 514 since last redisplay that finished.
515 If it has value REDISPLAY_SOME, then only redisplay the windows where
516 the `redisplay' bit has been set. Otherwise, redisplay all windows
517 (the number used is then only used to track down the cause for this
518 full-redisplay). */
511 519
512int windows_or_buffers_changed; 520int windows_or_buffers_changed;
513 521
@@ -562,7 +570,7 @@ static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
562 570
563/* Ascent and height of the last line processed by move_it_to. */ 571/* Ascent and height of the last line processed by move_it_to. */
564 572
565static int last_height; 573static int last_max_ascent, last_height;
566 574
567/* Non-zero if there's a help-echo in the echo area. */ 575/* Non-zero if there's a help-echo in the echo area. */
568 576
@@ -599,6 +607,56 @@ bool help_echo_showing_p;
599 CACHE = NULL; \ 607 CACHE = NULL; \
600 } while (0) 608 } while (0)
601 609
610/* Functions to mark elements as needing redisplay. */
611enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
612
613void
614redisplay_other_windows (void)
615{
616 if (!windows_or_buffers_changed)
617 windows_or_buffers_changed = REDISPLAY_SOME;
618}
619
620void
621wset_redisplay (struct window *w)
622{
623 /* Beware: selected_window can be nil during early stages. */
624 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
625 redisplay_other_windows ();
626 w->redisplay = true;
627}
628
629void
630fset_redisplay (struct frame *f)
631{
632 redisplay_other_windows ();
633 f->redisplay = true;
634}
635
636void
637bset_redisplay (struct buffer *b)
638{
639 int count = buffer_window_count (b);
640 if (count > 0)
641 {
642 /* ... it's visible in other window than selected, */
643 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
644 redisplay_other_windows ();
645 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
646 so that if we later set windows_or_buffers_changed, this buffer will
647 not be omitted. */
648 b->text->redisplay = true;
649 }
650}
651
652void
653bset_update_mode_line (struct buffer *b)
654{
655 if (!update_mode_lines)
656 update_mode_lines = REDISPLAY_SOME;
657 b->text->redisplay = true;
658}
659
602#ifdef GLYPH_DEBUG 660#ifdef GLYPH_DEBUG
603 661
604/* Non-zero means print traces of redisplay if compiled with 662/* Non-zero means print traces of redisplay if compiled with
@@ -779,7 +837,7 @@ static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
779static int display_prop_string_p (Lisp_Object, Lisp_Object); 837static int display_prop_string_p (Lisp_Object, Lisp_Object);
780static int row_for_charpos_p (struct glyph_row *, ptrdiff_t); 838static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
781static int cursor_row_p (struct glyph_row *); 839static int cursor_row_p (struct glyph_row *);
782static int redisplay_mode_lines (Lisp_Object, int); 840static int redisplay_mode_lines (Lisp_Object, bool);
783static char *decode_mode_spec_coding (Lisp_Object, char *, int); 841static char *decode_mode_spec_coding (Lisp_Object, char *, int);
784 842
785static Lisp_Object get_it_property (struct it *it, Lisp_Object prop); 843static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
@@ -833,7 +891,7 @@ static void sync_frame_with_window_matrix_rows (struct window *);
833static void redisplay_internal (void); 891static void redisplay_internal (void);
834static int echo_area_display (int); 892static int echo_area_display (int);
835static void redisplay_windows (Lisp_Object); 893static void redisplay_windows (Lisp_Object);
836static void redisplay_window (Lisp_Object, int); 894static void redisplay_window (Lisp_Object, bool);
837static Lisp_Object redisplay_window_error (Lisp_Object); 895static Lisp_Object redisplay_window_error (Lisp_Object);
838static Lisp_Object redisplay_window_0 (Lisp_Object); 896static Lisp_Object redisplay_window_0 (Lisp_Object);
839static Lisp_Object redisplay_window_1 (Lisp_Object); 897static Lisp_Object redisplay_window_1 (Lisp_Object);
@@ -914,6 +972,7 @@ static int in_ellipses_for_invisible_text_p (struct display_pos *,
914static void x_consider_frame_title (Lisp_Object); 972static void x_consider_frame_title (Lisp_Object);
915static void update_tool_bar (struct frame *, int); 973static void update_tool_bar (struct frame *, int);
916static int redisplay_tool_bar (struct frame *); 974static int redisplay_tool_bar (struct frame *);
975static void x_draw_bottom_divider (struct window *w);
917static void notice_overwritten_cursor (struct window *, 976static void notice_overwritten_cursor (struct window *,
918 enum glyph_row_area, 977 enum glyph_row_area,
919 int, int, int, int); 978 int, int, int, int);
@@ -942,10 +1001,13 @@ static int coords_in_mouse_face_p (struct window *, int, int);
942int 1001int
943window_text_bottom_y (struct window *w) 1002window_text_bottom_y (struct window *w)
944{ 1003{
945 int height = WINDOW_TOTAL_HEIGHT (w); 1004 int height = WINDOW_PIXEL_HEIGHT (w);
1005
1006 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
946 1007
947 if (WINDOW_WANTS_MODELINE_P (w)) 1008 if (WINDOW_WANTS_MODELINE_P (w))
948 height -= CURRENT_MODE_LINE_HEIGHT (w); 1009 height -= CURRENT_MODE_LINE_HEIGHT (w);
1010
949 return height; 1011 return height;
950} 1012}
951 1013
@@ -956,32 +1018,23 @@ window_text_bottom_y (struct window *w)
956int 1018int
957window_box_width (struct window *w, enum glyph_row_area area) 1019window_box_width (struct window *w, enum glyph_row_area area)
958{ 1020{
959 int cols = w->total_cols; 1021 int pixels = w->pixel_width;
960 int pixels = 0;
961 1022
962 if (!w->pseudo_window_p) 1023 if (!w->pseudo_window_p)
963 { 1024 {
964 cols -= WINDOW_SCROLL_BAR_COLS (w); 1025 pixels -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
1026 pixels -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
965 1027
966 if (area == TEXT_AREA) 1028 if (area == TEXT_AREA)
967 { 1029 pixels -= (WINDOW_MARGINS_WIDTH (w)
968 cols -= max (0, w->left_margin_cols); 1030 + WINDOW_FRINGES_WIDTH (w));
969 cols -= max (0, w->right_margin_cols);
970 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
971 }
972 else if (area == LEFT_MARGIN_AREA) 1031 else if (area == LEFT_MARGIN_AREA)
973 { 1032 pixels = WINDOW_LEFT_MARGIN_WIDTH (w);
974 cols = max (0, w->left_margin_cols);
975 pixels = 0;
976 }
977 else if (area == RIGHT_MARGIN_AREA) 1033 else if (area == RIGHT_MARGIN_AREA)
978 { 1034 pixels = WINDOW_RIGHT_MARGIN_WIDTH (w);
979 cols = max (0, w->right_margin_cols);
980 pixels = 0;
981 }
982 } 1035 }
983 1036
984 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels; 1037 return pixels;
985} 1038}
986 1039
987 1040
@@ -992,10 +1045,12 @@ int
992window_box_height (struct window *w) 1045window_box_height (struct window *w)
993{ 1046{
994 struct frame *f = XFRAME (w->frame); 1047 struct frame *f = XFRAME (w->frame);
995 int height = WINDOW_TOTAL_HEIGHT (w); 1048 int height = WINDOW_PIXEL_HEIGHT (w);
996 1049
997 eassert (height >= 0); 1050 eassert (height >= 0);
998 1051
1052 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1053
999 /* Note: the code below that determines the mode-line/header-line 1054 /* Note: the code below that determines the mode-line/header-line
1000 height is essentially the same as that contained in the macro 1055 height is essentially the same as that contained in the macro
1001 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether 1056 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
@@ -1373,7 +1428,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1373 if (top_y < window_top_y) 1428 if (top_y < window_top_y)
1374 visible_p = bottom_y > window_top_y; 1429 visible_p = bottom_y > window_top_y;
1375 else if (top_y < it.last_visible_y) 1430 else if (top_y < it.last_visible_y)
1376 visible_p = 1; 1431 visible_p = true;
1377 if (bottom_y >= it.last_visible_y 1432 if (bottom_y >= it.last_visible_y
1378 && it.bidi_p && it.bidi_it.scan_dir == -1 1433 && it.bidi_p && it.bidi_it.scan_dir == -1
1379 && IT_CHARPOS (it) < charpos) 1434 && IT_CHARPOS (it) < charpos)
@@ -1611,7 +1666,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1611 if (charpos < IT_CHARPOS (it) 1666 if (charpos < IT_CHARPOS (it)
1612 || (it.what == IT_EOB && charpos == IT_CHARPOS (it))) 1667 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1613 { 1668 {
1614 visible_p = 1; 1669 visible_p = true;
1615 RESTORE_IT (&it2, &it2, it2data); 1670 RESTORE_IT (&it2, &it2, it2data);
1616 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS); 1671 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1617 *x = it2.current_x; 1672 *x = it2.current_x;
@@ -1854,6 +1909,7 @@ pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1854 FRAME_COLUMN_WIDTH (f) - 1, 1909 FRAME_COLUMN_WIDTH (f) - 1,
1855 FRAME_LINE_HEIGHT (f) - 1); 1910 FRAME_LINE_HEIGHT (f) - 1);
1856 1911
1912 /* PXW: Should we clip pixels before converting to columns/lines? */
1857 if (!noclip) 1913 if (!noclip)
1858 { 1914 {
1859 if (pix_x < 0) 1915 if (pix_x < 0)
@@ -1994,7 +2050,10 @@ get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int
1994 { 2050 {
1995 /* Draw full-width. X coordinates are relative to S->w->left_col. */ 2051 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1996 r.x = WINDOW_LEFT_EDGE_X (s->w); 2052 r.x = WINDOW_LEFT_EDGE_X (s->w);
1997 r.width = WINDOW_TOTAL_WIDTH (s->w); 2053 if (s->row->mode_line_p)
2054 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2055 else
2056 r.width = WINDOW_PIXEL_WIDTH (s->w);
1998 2057
1999 /* Unless displaying a mode or menu bar line, which are always 2058 /* Unless displaying a mode or menu bar line, which are always
2000 fully visible, clip to the visible part of the row. */ 2059 fully visible, clip to the visible part of the row. */
@@ -2262,9 +2321,14 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2262 /* Try to determine frame pixel position and size of the glyph under 2321 /* Try to determine frame pixel position and size of the glyph under
2263 frame pixel coordinates X/Y on frame F. */ 2322 frame pixel coordinates X/Y on frame F. */
2264 2323
2265 if (!f->glyphs_initialized_p 2324 if (window_resize_pixelwise)
2266 || (window = window_from_coordinates (f, gx, gy, &part, 0), 2325 {
2267 NILP (window))) 2326 width = height = 1;
2327 goto virtual_glyph;
2328 }
2329 else if (!f->glyphs_initialized_p
2330 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2331 NILP (window)))
2268 { 2332 {
2269 width = FRAME_SMALLEST_CHAR_WIDTH (f); 2333 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2270 height = FRAME_SMALLEST_FONT_HEIGHT (f); 2334 height = FRAME_SMALLEST_FONT_HEIGHT (f);
@@ -2751,6 +2815,7 @@ init_iterator (struct it *it, struct window *w,
2751 && ((!NILP (Vtruncate_partial_width_windows) 2815 && ((!NILP (Vtruncate_partial_width_windows)
2752 && !INTEGERP (Vtruncate_partial_width_windows)) 2816 && !INTEGERP (Vtruncate_partial_width_windows))
2753 || (INTEGERP (Vtruncate_partial_width_windows) 2817 || (INTEGERP (Vtruncate_partial_width_windows)
2818 /* PXW: Shall we do something about this? */
2754 && (WINDOW_TOTAL_COLS (it->w) 2819 && (WINDOW_TOTAL_COLS (it->w)
2755 < XINT (Vtruncate_partial_width_windows)))))) 2820 < XINT (Vtruncate_partial_width_windows))))))
2756 it->line_wrap = TRUNCATE; 2821 it->line_wrap = TRUNCATE;
@@ -2810,12 +2875,12 @@ init_iterator (struct it *it, struct window *w,
2810 { 2875 {
2811 /* Mode lines, menu bar in terminal frames. */ 2876 /* Mode lines, menu bar in terminal frames. */
2812 it->first_visible_x = 0; 2877 it->first_visible_x = 0;
2813 it->last_visible_x = WINDOW_TOTAL_WIDTH (w); 2878 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2814 } 2879 }
2815 else 2880 else
2816 { 2881 {
2817 it->first_visible_x = 2882 it->first_visible_x
2818 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f); 2883 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2819 it->last_visible_x = (it->first_visible_x 2884 it->last_visible_x = (it->first_visible_x
2820 + window_box_width (w, TEXT_AREA)); 2885 + window_box_width (w, TEXT_AREA));
2821 2886
@@ -2857,7 +2922,7 @@ init_iterator (struct it *it, struct window *w,
2857 with a left box line. */ 2922 with a left box line. */
2858 face = FACE_FROM_ID (it->f, remapped_base_face_id); 2923 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2859 if (face->box != FACE_NO_BOX) 2924 if (face->box != FACE_NO_BOX)
2860 it->start_of_box_run_p = 1; 2925 it->start_of_box_run_p = true;
2861 } 2926 }
2862 2927
2863 /* If a buffer position was specified, set the iterator there, 2928 /* If a buffer position was specified, set the iterator there,
@@ -3285,7 +3350,7 @@ handle_stop (struct it *it)
3285 pop_it (it); 3350 pop_it (it);
3286 else 3351 else
3287 { 3352 {
3288 it->ignore_overlay_strings_at_pos_p = 1; 3353 it->ignore_overlay_strings_at_pos_p = true;
3289 it->string_from_display_prop_p = 0; 3354 it->string_from_display_prop_p = 0;
3290 it->from_disp_prop_p = 0; 3355 it->from_disp_prop_p = 0;
3291 handle_overlay_change_p = 0; 3356 handle_overlay_change_p = 0;
@@ -4150,13 +4215,13 @@ handle_invisible_prop (struct it *it)
4150 prop = Fget_text_property (end_charpos, Qinvisible, it->string); 4215 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4151 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop); 4216 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4152 if (invis_p == 2) 4217 if (invis_p == 2)
4153 display_ellipsis_p = 1; 4218 display_ellipsis_p = true;
4154 } 4219 }
4155 } 4220 }
4156 while (invis_p && endpos < len); 4221 while (invis_p && endpos < len);
4157 4222
4158 if (display_ellipsis_p) 4223 if (display_ellipsis_p)
4159 it->ellipsis_p = 1; 4224 it->ellipsis_p = true;
4160 4225
4161 if (endpos < len) 4226 if (endpos < len)
4162 { 4227 {
@@ -4268,9 +4333,9 @@ handle_invisible_prop (struct it *it)
4268 tem = next_stop; 4333 tem = next_stop;
4269 4334
4270 /* If there are adjacent invisible texts, don't lose the 4335 /* If there are adjacent invisible texts, don't lose the
4271 second one's ellipsis. */ 4336 second one's ellipsis. */
4272 if (invis_p == 2) 4337 if (invis_p == 2)
4273 display_ellipsis_p = 1; 4338 display_ellipsis_p = true;
4274 } 4339 }
4275 while (invis_p); 4340 while (invis_p);
4276 4341
@@ -4278,10 +4343,10 @@ handle_invisible_prop (struct it *it)
4278 if (it->bidi_p) 4343 if (it->bidi_p)
4279 { 4344 {
4280 ptrdiff_t bpos = CHAR_TO_BYTE (newpos); 4345 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4281 int on_newline = 4346 int on_newline
4282 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n'; 4347 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4283 int after_newline = 4348 int after_newline
4284 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n'; 4349 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4285 4350
4286 /* If the invisible text ends on a newline or on a 4351 /* If the invisible text ends on a newline or on a
4287 character after a newline, we can avoid the costly, 4352 character after a newline, we can avoid the costly,
@@ -4388,7 +4453,7 @@ handle_invisible_prop (struct it *it)
4388 it->position.charpos = newpos - 1; 4453 it->position.charpos = newpos - 1;
4389 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos); 4454 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4390 } 4455 }
4391 it->ellipsis_p = 1; 4456 it->ellipsis_p = true;
4392 /* Let the ellipsis display before 4457 /* Let the ellipsis display before
4393 considering any properties of the following char. 4458 considering any properties of the following char.
4394 Fixes jasonr@gnu.org 01 Oct 07 bug. */ 4459 Fixes jasonr@gnu.org 01 Oct 07 bug. */
@@ -4433,7 +4498,7 @@ setup_for_ellipsis (struct it *it, int len)
4433 it->saved_face_id = it->face_id = DEFAULT_FACE_ID; 4498 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4434 4499
4435 it->method = GET_FROM_DISPLAY_VECTOR; 4500 it->method = GET_FROM_DISPLAY_VECTOR;
4436 it->ellipsis_p = 1; 4501 it->ellipsis_p = true;
4437} 4502}
4438 4503
4439 4504
@@ -4902,7 +4967,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4902 it->method = GET_FROM_IMAGE; 4967 it->method = GET_FROM_IMAGE;
4903 it->from_overlay = Qnil; 4968 it->from_overlay = Qnil;
4904 it->face_id = face_id; 4969 it->face_id = face_id;
4905 it->from_disp_prop_p = 1; 4970 it->from_disp_prop_p = true;
4906 4971
4907 /* Say that we haven't consumed the characters with 4972 /* Say that we haven't consumed the characters with
4908 `display' property yet. The call to pop_it in 4973 `display' property yet. The call to pop_it in
@@ -4984,7 +5049,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4984 when we are finished with the glyph property value. */ 5049 when we are finished with the glyph property value. */
4985 push_it (it, position); 5050 push_it (it, position);
4986 it->from_overlay = overlay; 5051 it->from_overlay = overlay;
4987 it->from_disp_prop_p = 1; 5052 it->from_disp_prop_p = true;
4988 5053
4989 if (NILP (location)) 5054 if (NILP (location))
4990 it->area = TEXT_AREA; 5055 it->area = TEXT_AREA;
@@ -5004,7 +5069,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
5004 it->stop_charpos = 0; 5069 it->stop_charpos = 0;
5005 it->prev_stop = 0; 5070 it->prev_stop = 0;
5006 it->base_level_stop = 0; 5071 it->base_level_stop = 0;
5007 it->string_from_display_prop_p = 1; 5072 it->string_from_display_prop_p = true;
5008 /* Say that we haven't consumed the characters with 5073 /* Say that we haven't consumed the characters with
5009 `display' property yet. The call to pop_it in 5074 `display' property yet. The call to pop_it in
5010 set_iterator_to_next will clean this up. */ 5075 set_iterator_to_next will clean this up. */
@@ -5370,7 +5435,7 @@ next_overlay_string (struct it *it)
5370 processed the overlay strings there already, so that 5435 processed the overlay strings there already, so that
5371 next_element_from_buffer doesn't try it again. */ 5436 next_element_from_buffer doesn't try it again. */
5372 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos) 5437 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5373 it->overlay_strings_at_end_processed_p = 1; 5438 it->overlay_strings_at_end_processed_p = true;
5374 } 5439 }
5375 else 5440 else
5376 { 5441 {
@@ -6053,7 +6118,7 @@ forward_to_next_line_start (struct it *it, int *skipped_p,
6053 if (bidi_it_prev) 6118 if (bidi_it_prev)
6054 *bidi_it_prev = bprev; 6119 *bidi_it_prev = bprev;
6055 } 6120 }
6056 *skipped_p = newline_found_p = 1; 6121 *skipped_p = newline_found_p = true;
6057 } 6122 }
6058 else 6123 else
6059 { 6124 {
@@ -6743,9 +6808,9 @@ get_next_display_element (struct it *it)
6743 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) 6808 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6744 { 6809 {
6745 if (c == 0xA0) 6810 if (c == 0xA0)
6746 nonascii_space_p = 1; 6811 nonascii_space_p = true;
6747 else if (c == 0xAD || c == 0x2010 || c == 0x2011) 6812 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6748 nonascii_hyphen_p = 1; 6813 nonascii_hyphen_p = true;
6749 } 6814 }
6750 6815
6751 /* Translate control characters into `\003' or `^C' form. 6816 /* Translate control characters into `\003' or `^C' form.
@@ -7204,12 +7269,12 @@ set_iterator_to_next (struct it *it, int reseat_p)
7204 if (it->method == GET_FROM_STRING 7269 if (it->method == GET_FROM_STRING
7205 && it->current.overlay_string_index >= 0 7270 && it->current.overlay_string_index >= 0
7206 && it->n_overlay_strings > 0) 7271 && it->n_overlay_strings > 0)
7207 it->ignore_overlay_strings_at_pos_p = 1; 7272 it->ignore_overlay_strings_at_pos_p = true;
7208 it->len = it->dpvec_char_len; 7273 it->len = it->dpvec_char_len;
7209 set_iterator_to_next (it, reseat_p); 7274 set_iterator_to_next (it, reseat_p);
7210 } 7275 }
7211 7276
7212 /* Maybe recheck faces after display vector */ 7277 /* Maybe recheck faces after display vector. */
7213 if (recheck_faces) 7278 if (recheck_faces)
7214 it->stop_charpos = IT_CHARPOS (*it); 7279 it->stop_charpos = IT_CHARPOS (*it);
7215 } 7280 }
@@ -7234,7 +7299,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
7234 else 7299 else
7235 { 7300 {
7236 /* Not an overlay string. There could be padding, so test 7301 /* Not an overlay string. There could be padding, so test
7237 against it->end_charpos . */ 7302 against it->end_charpos. */
7238 if (IT_STRING_CHARPOS (*it) >= it->end_charpos) 7303 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7239 goto consider_string_end; 7304 goto consider_string_end;
7240 } 7305 }
@@ -7746,7 +7811,7 @@ next_element_from_string (struct it *it)
7746static int 7811static int
7747next_element_from_c_string (struct it *it) 7812next_element_from_c_string (struct it *it)
7748{ 7813{
7749 int success_p = 1; 7814 bool success_p = true;
7750 7815
7751 eassert (it->s); 7816 eassert (it->s);
7752 eassert (!it->bidi_p || it->s == it->bidi_it.string.s); 7817 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
@@ -7805,7 +7870,7 @@ next_element_from_ellipsis (struct it *it)
7805 it->method = GET_FROM_BUFFER; 7870 it->method = GET_FROM_BUFFER;
7806 it->object = it->w->contents; 7871 it->object = it->w->contents;
7807 reseat_at_next_visible_line_start (it, 1); 7872 reseat_at_next_visible_line_start (it, 1);
7808 it->face_before_selective_p = 1; 7873 it->face_before_selective_p = true;
7809 } 7874 }
7810 7875
7811 return GET_NEXT_DISPLAY_ELEMENT (it); 7876 return GET_NEXT_DISPLAY_ELEMENT (it);
@@ -7874,7 +7939,7 @@ compute_stop_pos_backwards (struct it *it)
7874 it->prev_stop = it->stop_charpos; 7939 it->prev_stop = it->stop_charpos;
7875 else 7940 else
7876 it->prev_stop = BEGV; 7941 it->prev_stop = BEGV;
7877 it->bidi_p = 1; 7942 it->bidi_p = true;
7878 it->current = save_current; 7943 it->current = save_current;
7879 it->position = save_position; 7944 it->position = save_position;
7880 it->stop_charpos = save_stop_pos; 7945 it->stop_charpos = save_stop_pos;
@@ -7920,7 +7985,7 @@ handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7920 } 7985 }
7921 while (charpos <= where_we_are); 7986 while (charpos <= where_we_are);
7922 7987
7923 it->bidi_p = 1; 7988 it->bidi_p = true;
7924 it->current = save_current; 7989 it->current = save_current;
7925 it->position = save_position; 7990 it->position = save_position;
7926 next_stop = it->stop_charpos; 7991 next_stop = it->stop_charpos;
@@ -7937,7 +8002,7 @@ handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7937static int 8002static int
7938next_element_from_buffer (struct it *it) 8003next_element_from_buffer (struct it *it)
7939{ 8004{
7940 int success_p = 1; 8005 bool success_p = true;
7941 8006
7942 eassert (IT_CHARPOS (*it) >= BEGV); 8007 eassert (IT_CHARPOS (*it) >= BEGV);
7943 eassert (NILP (it->string) && !it->s); 8008 eassert (NILP (it->string) && !it->s);
@@ -7967,7 +8032,7 @@ next_element_from_buffer (struct it *it)
7967 overlay_strings_follow_p = 0; 8032 overlay_strings_follow_p = 0;
7968 else 8033 else
7969 { 8034 {
7970 it->overlay_strings_at_end_processed_p = 1; 8035 it->overlay_strings_at_end_processed_p = true;
7971 overlay_strings_follow_p = get_overlay_strings (it, 0); 8036 overlay_strings_follow_p = get_overlay_strings (it, 0);
7972 } 8037 }
7973 8038
@@ -8787,13 +8852,17 @@ move_it_in_display_line (struct it *it,
8787 8852
8788 If TO_CHARPOS is in invisible text, e.g. a truncated part of a 8853 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8789 screen line, this function will set IT to the next position that is 8854 screen line, this function will set IT to the next position that is
8790 displayed to the right of TO_CHARPOS on the screen. */ 8855 displayed to the right of TO_CHARPOS on the screen.
8791 8856
8792void 8857 Return the maximum pixel length of any line scanned but never more
8858 than it.last_visible_x. */
8859
8860int
8793move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op) 8861move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8794{ 8862{
8795 enum move_it_result skip, skip2 = MOVE_X_REACHED; 8863 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8796 int line_height, line_start_x = 0, reached = 0; 8864 int line_height, line_start_x = 0, reached = 0;
8865 int max_current_x = 0;
8797 void *backup_data = NULL; 8866 void *backup_data = NULL;
8798 8867
8799 for (;;) 8868 for (;;)
@@ -8924,6 +8993,9 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
8924 if (to_y >= it->current_y 8993 if (to_y >= it->current_y
8925 && to_y < it->current_y + line_height) 8994 && to_y < it->current_y + line_height)
8926 { 8995 {
8996 if (to_y > it->current_y)
8997 max_current_x = max (it->current_x, max_current_x);
8998
8927 /* When word-wrap is on, TO_X may lie past the end 8999 /* When word-wrap is on, TO_X may lie past the end
8928 of a wrapped line. Then it->current is the 9000 of a wrapped line. Then it->current is the
8929 character on the next line, so backtrack to the 9001 character on the next line, so backtrack to the
@@ -8936,12 +9008,16 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
8936 skip = move_it_in_display_line_to 9008 skip = move_it_in_display_line_to
8937 (it, -1, prev_x, MOVE_TO_X); 9009 (it, -1, prev_x, MOVE_TO_X);
8938 } 9010 }
9011
8939 reached = 6; 9012 reached = 6;
8940 } 9013 }
8941 } 9014 }
8942 9015
8943 if (reached) 9016 if (reached)
8944 break; 9017 {
9018 max_current_x = max (it->current_x, max_current_x);
9019 break;
9020 }
8945 } 9021 }
8946 else if (BUFFERP (it->object) 9022 else if (BUFFERP (it->object)
8947 && (it->method == GET_FROM_BUFFER 9023 && (it->method == GET_FROM_BUFFER
@@ -8961,15 +9037,18 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
8961 switch (skip) 9037 switch (skip)
8962 { 9038 {
8963 case MOVE_POS_MATCH_OR_ZV: 9039 case MOVE_POS_MATCH_OR_ZV:
9040 max_current_x = max (it->current_x, max_current_x);
8964 reached = 8; 9041 reached = 8;
8965 goto out; 9042 goto out;
8966 9043
8967 case MOVE_NEWLINE_OR_CR: 9044 case MOVE_NEWLINE_OR_CR:
9045 max_current_x = max (it->current_x, max_current_x);
8968 set_iterator_to_next (it, 1); 9046 set_iterator_to_next (it, 1);
8969 it->continuation_lines_width = 0; 9047 it->continuation_lines_width = 0;
8970 break; 9048 break;
8971 9049
8972 case MOVE_LINE_TRUNCATED: 9050 case MOVE_LINE_TRUNCATED:
9051 max_current_x = it->last_visible_x;
8973 it->continuation_lines_width = 0; 9052 it->continuation_lines_width = 0;
8974 reseat_at_next_visible_line_start (it, 0); 9053 reseat_at_next_visible_line_start (it, 0);
8975 if ((op & MOVE_TO_POS) != 0 9054 if ((op & MOVE_TO_POS) != 0
@@ -8981,6 +9060,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
8981 break; 9060 break;
8982 9061
8983 case MOVE_LINE_CONTINUED: 9062 case MOVE_LINE_CONTINUED:
9063 max_current_x = it->last_visible_x;
8984 /* For continued lines ending in a tab, some of the glyphs 9064 /* For continued lines ending in a tab, some of the glyphs
8985 associated with the tab are displayed on the current 9065 associated with the tab are displayed on the current
8986 line. Since it->current_x does not include these glyphs, 9066 line. Since it->current_x does not include these glyphs,
@@ -9016,6 +9096,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
9016 it->current_y += it->max_ascent + it->max_descent; 9096 it->current_y += it->max_ascent + it->max_descent;
9017 ++it->vpos; 9097 ++it->vpos;
9018 last_height = it->max_ascent + it->max_descent; 9098 last_height = it->max_ascent + it->max_descent;
9099 last_max_ascent = it->max_ascent;
9019 it->max_ascent = it->max_descent = 0; 9100 it->max_ascent = it->max_descent = 0;
9020 } 9101 }
9021 9102
@@ -9042,12 +9123,15 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos
9042 it->current_y += it->max_ascent + it->max_descent; 9123 it->current_y += it->max_ascent + it->max_descent;
9043 ++it->vpos; 9124 ++it->vpos;
9044 last_height = it->max_ascent + it->max_descent; 9125 last_height = it->max_ascent + it->max_descent;
9126 last_max_ascent = it->max_ascent;
9045 } 9127 }
9046 9128
9047 if (backup_data) 9129 if (backup_data)
9048 bidi_unshelve_cache (backup_data, 1); 9130 bidi_unshelve_cache (backup_data, 1);
9049 9131
9050 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); 9132 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9133
9134 return max_current_x;
9051} 9135}
9052 9136
9053 9137
@@ -9395,6 +9479,145 @@ in_display_vector_p (struct it *it)
9395 && it->dpvec + it->current.dpvec_index != it->dpend); 9479 && it->dpvec + it->current.dpvec_index != it->dpend);
9396} 9480}
9397 9481
9482DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9483 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9484WINDOW must be a live window and defaults to the selected one. The
9485return value is a cons of the maximum pixel-width of any text line and
9486the maximum pixel-height of all text lines.
9487
9488The optional argument FROM, if non-nil, specifies the first text
9489position and defaults to the minimum accessible position of the buffer.
9490If FROM is t, use the minimum accessible position that is not a newline
9491character. TO, if non-nil, specifies the last text position and
9492defaults to the maximum accessible position of the buffer. If TO is t,
9493use the maximum accessible position that is not a newline character.
9494
9495The optional argument X_LIMIT, if non-nil, specifies the maximum text
9496width that can be returned. X_LIMIT nil or omitted, means to use the
9497pixel-width of WINDOW's body; use this if you do not intend to change
9498the width of WINDOW. Use the maximum width WINDOW may assume if you
9499intend to change WINDOW's width.
9500
9501The optional argument Y_LIMIT, if non-nil, specifies the maximum text
9502height that can be returned. Text lines whose y-coordinate is beyond
9503Y_LIMIT are ignored. Since calculating the text height of a large
9504buffer can take some time, it makes sense to specify this argument if
9505the size of the buffer is unknown.
9506
9507Optional argument MODE_AND_HEADER_LINE nil or omitted means do not
9508include the height of the mode- or header-line of WINDOW in the return
9509value. If it is either the symbol `mode-line' or `header-line', include
9510only the height of that line, if present, in the return value. If t,
9511include the height of any of these lines in the return value. */)
9512 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
9513 Lisp_Object mode_and_header_line)
9514{
9515 struct window *w = decode_live_window (window);
9516 Lisp_Object buf;
9517 struct buffer *b;
9518 struct it it;
9519 struct buffer *old_buffer = NULL;
9520 ptrdiff_t start, end, pos;
9521 struct text_pos startp;
9522 void *itdata = NULL;
9523 int c, max_y = -1, x = 0, y = 0;
9524
9525 buf = w->contents;
9526 CHECK_BUFFER (buf);
9527 b = XBUFFER (buf);
9528
9529 if (b != current_buffer)
9530 {
9531 old_buffer = current_buffer;
9532 set_buffer_internal (b);
9533 }
9534
9535 if (NILP (from))
9536 start = BEGV;
9537 else if (EQ (from, Qt))
9538 {
9539 start = pos = BEGV;
9540 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
9541 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9542 start = pos;
9543 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9544 start = pos;
9545 }
9546 else
9547 {
9548 CHECK_NUMBER_COERCE_MARKER (from);
9549 start = min (max (XINT (from), BEGV), ZV);
9550 }
9551
9552 if (NILP (to))
9553 end = ZV;
9554 else if (EQ (to, Qt))
9555 {
9556 end = pos = ZV;
9557 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
9558 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
9559 end = pos;
9560 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
9561 end = pos;
9562 }
9563 else
9564 {
9565 CHECK_NUMBER_COERCE_MARKER (to);
9566 end = max (start, min (XINT (to), ZV));
9567 }
9568
9569 if (!NILP (y_limit))
9570 {
9571 CHECK_NUMBER (y_limit);
9572 max_y = min (XINT (y_limit), INT_MAX);
9573 }
9574
9575 itdata = bidi_shelve_cache ();
9576 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
9577 start_display (&it, w, startp);
9578
9579 /** move_it_vertically_backward (&it, 0); **/
9580 if (NILP (x_limit))
9581 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
9582 else
9583 {
9584 CHECK_NUMBER (x_limit);
9585 it.last_visible_x = min (XINT (x_limit), INFINITY);
9586 /* Actually, we never want move_it_to stop at to_x. But to make
9587 sure that move_it_in_display_line_to always moves far enough,
9588 we set it to INT_MAX and specify MOVE_TO_X. */
9589 x = move_it_to (&it, end, INT_MAX, max_y, -1,
9590 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
9591 }
9592
9593 if (start == end)
9594 y = it.current_y;
9595 else
9596 {
9597 /* Count last line. */
9598 last_height = 0;
9599 y = line_bottom_y (&it); /* - y; */
9600 }
9601
9602 if (!EQ (mode_and_header_line, Qheader_line)
9603 && !EQ (mode_and_header_line, Qt))
9604 /* Do not count the header-line which was counted automatically by
9605 start_display. */
9606 y = y - WINDOW_HEADER_LINE_HEIGHT (w);
9607
9608 if (EQ (mode_and_header_line, Qmode_line)
9609 || EQ (mode_and_header_line, Qt))
9610 /* Do count the mode-line which is not included automatically by
9611 start_display. */
9612 y = y + WINDOW_MODE_LINE_HEIGHT (w);
9613
9614 bidi_unshelve_cache (itdata, 0);
9615
9616 if (old_buffer)
9617 set_buffer_internal (old_buffer);
9618
9619 return Fcons (make_number (x), make_number (y));
9620}
9398 9621
9399/*********************************************************************** 9622/***********************************************************************
9400 Messages 9623 Messages
@@ -9468,7 +9691,6 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9468 ptrdiff_t point_at_end = 0; 9691 ptrdiff_t point_at_end = 0;
9469 ptrdiff_t zv_at_end = 0; 9692 ptrdiff_t zv_at_end = 0;
9470 Lisp_Object old_deactivate_mark; 9693 Lisp_Object old_deactivate_mark;
9471 bool shown;
9472 struct gcpro gcpro1; 9694 struct gcpro gcpro1;
9473 9695
9474 old_deactivate_mark = Vdeactivate_mark; 9696 old_deactivate_mark = Vdeactivate_mark;
@@ -9482,8 +9704,8 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9482 9704
9483 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name)); 9705 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9484 9706
9485 if (newbuffer && 9707 if (newbuffer
9486 !NILP (Ffboundp (intern ("messages-buffer-mode")))) 9708 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
9487 call0 (intern ("messages-buffer-mode")); 9709 call0 (intern ("messages-buffer-mode"));
9488 } 9710 }
9489 9711
@@ -9625,18 +9847,17 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
9625 unchain_marker (XMARKER (oldbegv)); 9847 unchain_marker (XMARKER (oldbegv));
9626 unchain_marker (XMARKER (oldzv)); 9848 unchain_marker (XMARKER (oldzv));
9627 9849
9628 shown = buffer_window_count (current_buffer) > 0;
9629 set_buffer_internal (oldbuf);
9630 /* We called insert_1_both above with its 5th argument (PREPARE) 9850 /* We called insert_1_both above with its 5th argument (PREPARE)
9631 zero, which prevents insert_1_both from calling 9851 zero, which prevents insert_1_both from calling
9632 prepare_to_modify_buffer, which in turns prevents us from 9852 prepare_to_modify_buffer, which in turns prevents us from
9633 incrementing windows_or_buffers_changed even if *Messages* is 9853 incrementing windows_or_buffers_changed even if *Messages* is
9634 shown in some window. So we must manually incrementing 9854 shown in some window. So we must manually set
9635 windows_or_buffers_changed here to make up for that. */ 9855 windows_or_buffers_changed here to make up for that. */
9636 if (shown)
9637 windows_or_buffers_changed = 41;
9638 else
9639 windows_or_buffers_changed = old_windows_or_buffers_changed; 9856 windows_or_buffers_changed = old_windows_or_buffers_changed;
9857 bset_redisplay (current_buffer);
9858
9859 set_buffer_internal (oldbuf);
9860
9640 message_log_need_newline = !nlflag; 9861 message_log_need_newline = !nlflag;
9641 Vdeactivate_mark = old_deactivate_mark; 9862 Vdeactivate_mark = old_deactivate_mark;
9642 } 9863 }
@@ -9692,7 +9913,7 @@ message3 (Lisp_Object m)
9692 struct gcpro gcpro1; 9913 struct gcpro gcpro1;
9693 9914
9694 GCPRO1 (m); 9915 GCPRO1 (m);
9695 clear_message (1,1); 9916 clear_message (true, true);
9696 cancel_echoing (); 9917 cancel_echoing ();
9697 9918
9698 /* First flush out any partial line written with print. */ 9919 /* First flush out any partial line written with print. */
@@ -9762,7 +9983,7 @@ message3_nolog (Lisp_Object m)
9762 echo_message_buffer = Qnil; 9983 echo_message_buffer = Qnil;
9763 } 9984 }
9764 else 9985 else
9765 clear_message (1, 1); 9986 clear_message (true, true);
9766 9987
9767 do_pending_window_change (0); 9988 do_pending_window_change (0);
9768 echo_area_display (1); 9989 echo_area_display (1);
@@ -10035,7 +10256,7 @@ with_echo_area_buffer (struct window *w, int which,
10035 else 10256 else
10036 { 10257 {
10037 this_one = 0, the_other = 1; 10258 this_one = 0, the_other = 1;
10038 clear_buffer_p = 1; 10259 clear_buffer_p = true;
10039 10260
10040 /* We need a fresh one in case the current echo buffer equals 10261 /* We need a fresh one in case the current echo buffer equals
10041 the one containing the last displayed echo area message. */ 10262 the one containing the last displayed echo area message. */
@@ -10052,7 +10273,7 @@ with_echo_area_buffer (struct window *w, int which,
10052 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one]) 10273 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10053 ? echo_buffer[the_other] 10274 ? echo_buffer[the_other]
10054 : echo_buffer[this_one]); 10275 : echo_buffer[this_one]);
10055 clear_buffer_p = 1; 10276 clear_buffer_p = true;
10056 } 10277 }
10057 10278
10058 buffer = echo_area_buffer[this_one]; 10279 buffer = echo_area_buffer[this_one];
@@ -10325,15 +10546,8 @@ resize_echo_area_exactly (void)
10325 && WINDOWP (echo_area_window)) 10546 && WINDOWP (echo_area_window))
10326 { 10547 {
10327 struct window *w = XWINDOW (echo_area_window); 10548 struct window *w = XWINDOW (echo_area_window);
10328 int resized_p; 10549 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
10329 Lisp_Object resize_exactly; 10550 int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10330
10331 if (minibuf_level == 0)
10332 resize_exactly = Qt;
10333 else
10334 resize_exactly = Qnil;
10335
10336 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10337 (intptr_t) w, resize_exactly); 10551 (intptr_t) w, resize_exactly);
10338 if (resized_p) 10552 if (resized_p)
10339 { 10553 {
@@ -10400,11 +10614,10 @@ resize_mini_window (struct window *w, int exact_p)
10400 if (!FRAME_MINIBUF_ONLY_P (f)) 10614 if (!FRAME_MINIBUF_ONLY_P (f))
10401 { 10615 {
10402 struct it it; 10616 struct it it;
10403 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); 10617 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
10404 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w); 10618 + WINDOW_PIXEL_HEIGHT (w));
10405 int height;
10406 EMACS_INT max_height;
10407 int unit = FRAME_LINE_HEIGHT (f); 10619 int unit = FRAME_LINE_HEIGHT (f);
10620 int height, max_height;
10408 struct text_pos start; 10621 struct text_pos start;
10409 struct buffer *old_current_buffer = NULL; 10622 struct buffer *old_current_buffer = NULL;
10410 10623
@@ -10418,18 +10631,18 @@ resize_mini_window (struct window *w, int exact_p)
10418 10631
10419 /* Compute the max. number of lines specified by the user. */ 10632 /* Compute the max. number of lines specified by the user. */
10420 if (FLOATP (Vmax_mini_window_height)) 10633 if (FLOATP (Vmax_mini_window_height))
10421 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f); 10634 max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
10422 else if (INTEGERP (Vmax_mini_window_height)) 10635 else if (INTEGERP (Vmax_mini_window_height))
10423 max_height = XINT (Vmax_mini_window_height); 10636 max_height = XINT (Vmax_mini_window_height) * unit;
10424 else 10637 else
10425 max_height = total_height / 4; 10638 max_height = total_height / 4;
10426 10639
10427 /* Correct that max. height if it's bogus. */ 10640 /* Correct that max. height if it's bogus. */
10428 max_height = clip_to_bounds (1, max_height, total_height); 10641 max_height = clip_to_bounds (unit, max_height, total_height);
10429 10642
10430 /* Find out the height of the text in the window. */ 10643 /* Find out the height of the text in the window. */
10431 if (it.line_wrap == TRUNCATE) 10644 if (it.line_wrap == TRUNCATE)
10432 height = 1; 10645 height = unit;
10433 else 10646 else
10434 { 10647 {
10435 last_height = 0; 10648 last_height = 0;
@@ -10439,7 +10652,6 @@ resize_mini_window (struct window *w, int exact_p)
10439 else 10652 else
10440 height = it.current_y + it.max_ascent + it.max_descent; 10653 height = it.current_y + it.max_ascent + it.max_descent;
10441 height -= min (it.extra_line_spacing, it.max_extra_line_spacing); 10654 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10442 height = (height + unit - 1) / unit;
10443 } 10655 }
10444 10656
10445 /* Compute a suitable window start. */ 10657 /* Compute a suitable window start. */
@@ -10447,7 +10659,7 @@ resize_mini_window (struct window *w, int exact_p)
10447 { 10659 {
10448 height = max_height; 10660 height = max_height;
10449 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID); 10661 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10450 move_it_vertically_backward (&it, (height - 1) * unit); 10662 move_it_vertically_backward (&it, height);
10451 start = it.current.pos; 10663 start = it.current.pos;
10452 } 10664 }
10453 else 10665 else
@@ -10458,49 +10670,49 @@ resize_mini_window (struct window *w, int exact_p)
10458 { 10670 {
10459 /* Let it grow only, until we display an empty message, in which 10671 /* Let it grow only, until we display an empty message, in which
10460 case the window shrinks again. */ 10672 case the window shrinks again. */
10461 if (height > WINDOW_TOTAL_LINES (w)) 10673 if (height > WINDOW_PIXEL_HEIGHT (w))
10462 { 10674 {
10463 int old_height = WINDOW_TOTAL_LINES (w); 10675 int old_height = WINDOW_PIXEL_HEIGHT (w);
10464 10676
10465 FRAME_WINDOWS_FROZEN (f) = 1; 10677 FRAME_WINDOWS_FROZEN (f) = 1;
10466 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 10678 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10467 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 10679 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10468 } 10680 }
10469 else if (height < WINDOW_TOTAL_LINES (w) 10681 else if (height < WINDOW_PIXEL_HEIGHT (w)
10470 && (exact_p || BEGV == ZV)) 10682 && (exact_p || BEGV == ZV))
10471 { 10683 {
10472 int old_height = WINDOW_TOTAL_LINES (w); 10684 int old_height = WINDOW_PIXEL_HEIGHT (w);
10473 10685
10474 FRAME_WINDOWS_FROZEN (f) = 0; 10686 FRAME_WINDOWS_FROZEN (f) = 0;
10475 shrink_mini_window (w); 10687 shrink_mini_window (w, 1);
10476 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 10688 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10477 } 10689 }
10478 } 10690 }
10479 else 10691 else
10480 { 10692 {
10481 /* Always resize to exact size needed. */ 10693 /* Always resize to exact size needed. */
10482 if (height > WINDOW_TOTAL_LINES (w)) 10694 if (height > WINDOW_PIXEL_HEIGHT (w))
10483 { 10695 {
10484 int old_height = WINDOW_TOTAL_LINES (w); 10696 int old_height = WINDOW_PIXEL_HEIGHT (w);
10485 10697
10486 FRAME_WINDOWS_FROZEN (f) = 1; 10698 FRAME_WINDOWS_FROZEN (f) = 1;
10487 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 10699 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10488 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 10700 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10489 } 10701 }
10490 else if (height < WINDOW_TOTAL_LINES (w)) 10702 else if (height < WINDOW_PIXEL_HEIGHT (w))
10491 { 10703 {
10492 int old_height = WINDOW_TOTAL_LINES (w); 10704 int old_height = WINDOW_PIXEL_HEIGHT (w);
10493 10705
10494 FRAME_WINDOWS_FROZEN (f) = 0; 10706 FRAME_WINDOWS_FROZEN (f) = 0;
10495 shrink_mini_window (w); 10707 shrink_mini_window (w, 1);
10496 10708
10497 if (height) 10709 if (height)
10498 { 10710 {
10499 FRAME_WINDOWS_FROZEN (f) = 1; 10711 FRAME_WINDOWS_FROZEN (f) = 1;
10500 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w)); 10712 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
10501 } 10713 }
10502 10714
10503 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height; 10715 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
10504 } 10716 }
10505 } 10717 }
10506 10718
@@ -10685,12 +10897,12 @@ set_message_1 (ptrdiff_t a1, Lisp_Object string)
10685 last displayed. */ 10897 last displayed. */
10686 10898
10687void 10899void
10688clear_message (int current_p, int last_displayed_p) 10900clear_message (bool current_p, bool last_displayed_p)
10689{ 10901{
10690 if (current_p) 10902 if (current_p)
10691 { 10903 {
10692 echo_area_buffer[0] = Qnil; 10904 echo_area_buffer[0] = Qnil;
10693 message_cleared_p = 1; 10905 message_cleared_p = true;
10694 } 10906 }
10695 10907
10696 if (last_displayed_p) 10908 if (last_displayed_p)
@@ -10714,7 +10926,6 @@ clear_garbaged_frames (void)
10714 if (frame_garbaged) 10926 if (frame_garbaged)
10715 { 10927 {
10716 Lisp_Object tail, frame; 10928 Lisp_Object tail, frame;
10717 int changed_count = 0;
10718 10929
10719 FOR_EACH_FRAME (tail, frame) 10930 FOR_EACH_FRAME (tail, frame)
10720 { 10931 {
@@ -10726,15 +10937,13 @@ clear_garbaged_frames (void)
10726 redraw_frame (f); 10937 redraw_frame (f);
10727 else 10938 else
10728 clear_current_matrices (f); 10939 clear_current_matrices (f);
10729 changed_count++; 10940 fset_redisplay (f);
10730 f->garbaged = 0; 10941 f->garbaged = false;
10731 f->resized_p = 0; 10942 f->resized_p = false;
10732 } 10943 }
10733 } 10944 }
10734 10945
10735 frame_garbaged = 0; 10946 frame_garbaged = false;
10736 if (changed_count)
10737 windows_or_buffers_changed = 43;
10738 } 10947 }
10739} 10948}
10740 10949
@@ -10775,7 +10984,7 @@ echo_area_display (int update_frame_p)
10775 { 10984 {
10776 echo_area_window = mini_window; 10985 echo_area_window = mini_window;
10777 window_height_changed_p = display_echo_area (w); 10986 window_height_changed_p = display_echo_area (w);
10778 w->must_be_updated_p = 1; 10987 w->must_be_updated_p = true;
10779 10988
10780 /* Update the display, unless called from redisplay_internal. 10989 /* Update the display, unless called from redisplay_internal.
10781 Also don't update the screen during redisplay itself. The 10990 Also don't update the screen during redisplay itself. The
@@ -10791,7 +11000,7 @@ echo_area_display (int update_frame_p)
10791 been called, so that mode lines above the echo area are 11000 been called, so that mode lines above the echo area are
10792 garbaged. This looks odd, so we prevent it here. */ 11001 garbaged. This looks odd, so we prevent it here. */
10793 if (!display_completed) 11002 if (!display_completed)
10794 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0); 11003 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
10795 11004
10796 if (window_height_changed_p 11005 if (window_height_changed_p
10797 /* Don't do this if Emacs is shutting down. Redisplay 11006 /* Don't do this if Emacs is shutting down. Redisplay
@@ -10822,11 +11031,11 @@ echo_area_display (int update_frame_p)
10822 redisplay displays the minibuffer, so that the cursor will 11031 redisplay displays the minibuffer, so that the cursor will
10823 be replaced with what the minibuffer wants. */ 11032 be replaced with what the minibuffer wants. */
10824 if (cursor_in_echo_area) 11033 if (cursor_in_echo_area)
10825 windows_or_buffers_changed = 45; 11034 wset_redisplay (XWINDOW (mini_window));
10826 } 11035 }
10827 } 11036 }
10828 else if (!EQ (mini_window, selected_window)) 11037 else if (!EQ (mini_window, selected_window))
10829 windows_or_buffers_changed = 46; 11038 wset_redisplay (XWINDOW (mini_window));
10830 11039
10831 /* Last displayed message is now the current message. */ 11040 /* Last displayed message is now the current message. */
10832 echo_area_buffer[1] = echo_area_buffer[0]; 11041 echo_area_buffer[1] = echo_area_buffer[0];
@@ -10842,16 +11051,6 @@ echo_area_display (int update_frame_p)
10842 return window_height_changed_p; 11051 return window_height_changed_p;
10843} 11052}
10844 11053
10845/* Nonzero if the current window's buffer is shown in more than one
10846 window and was modified since last redisplay. */
10847
10848static int
10849buffer_shared_and_changed (void)
10850{
10851 return (buffer_window_count (current_buffer) > 1
10852 && UNCHANGED_MODIFIED < MODIFF);
10853}
10854
10855/* Nonzero if W's buffer was changed but not saved. */ 11054/* Nonzero if W's buffer was changed but not saved. */
10856 11055
10857static int 11056static int
@@ -11164,6 +11363,12 @@ x_consider_frame_title (Lisp_Object frame)
11164 Menu Bars 11363 Menu Bars
11165 ***********************************************************************/ 11364 ***********************************************************************/
11166 11365
11366/* Non-zero if we will not redisplay all visible windows. */
11367#define REDISPLAY_SOME_P() \
11368 ((windows_or_buffers_changed == 0 \
11369 || windows_or_buffers_changed == REDISPLAY_SOME) \
11370 && (update_mode_lines == 0 \
11371 || update_mode_lines == REDISPLAY_SOME))
11167 11372
11168/* Prepare for redisplay by updating menu-bar item lists when 11373/* Prepare for redisplay by updating menu-bar item lists when
11169 appropriate. This can call eval. */ 11374 appropriate. This can call eval. */
@@ -11171,9 +11376,9 @@ x_consider_frame_title (Lisp_Object frame)
11171static void 11376static void
11172prepare_menu_bars (void) 11377prepare_menu_bars (void)
11173{ 11378{
11174 int all_windows; 11379 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11380 bool some_windows = REDISPLAY_SOME_P ();
11175 struct gcpro gcpro1, gcpro2; 11381 struct gcpro gcpro1, gcpro2;
11176 struct frame *f;
11177 Lisp_Object tooltip_frame; 11382 Lisp_Object tooltip_frame;
11178 11383
11179#ifdef HAVE_WINDOW_SYSTEM 11384#ifdef HAVE_WINDOW_SYSTEM
@@ -11182,17 +11387,45 @@ prepare_menu_bars (void)
11182 tooltip_frame = Qnil; 11387 tooltip_frame = Qnil;
11183#endif 11388#endif
11184 11389
11390 if (FUNCTIONP (Vpre_redisplay_function))
11391 {
11392 Lisp_Object windows = all_windows ? Qt : Qnil;
11393 if (all_windows && some_windows)
11394 {
11395 Lisp_Object ws = window_list ();
11396 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
11397 {
11398 Lisp_Object this = XCAR (ws);
11399 struct window *w = XWINDOW (this);
11400 if (w->redisplay
11401 || XFRAME (w->frame)->redisplay
11402 || XBUFFER (w->contents)->text->redisplay)
11403 {
11404 windows = Fcons (this, windows);
11405 }
11406 }
11407 }
11408 safe_call1 (Vpre_redisplay_function, windows);
11409 }
11410
11185 /* Update all frame titles based on their buffer names, etc. We do 11411 /* Update all frame titles based on their buffer names, etc. We do
11186 this before the menu bars so that the buffer-menu will show the 11412 this before the menu bars so that the buffer-menu will show the
11187 up-to-date frame titles. */ 11413 up-to-date frame titles. */
11188#ifdef HAVE_WINDOW_SYSTEM 11414#ifdef HAVE_WINDOW_SYSTEM
11189 if (windows_or_buffers_changed || update_mode_lines) 11415 if (all_windows)
11190 { 11416 {
11191 Lisp_Object tail, frame; 11417 Lisp_Object tail, frame;
11192 11418
11193 FOR_EACH_FRAME (tail, frame) 11419 FOR_EACH_FRAME (tail, frame)
11194 { 11420 {
11195 f = XFRAME (frame); 11421 struct frame *f = XFRAME (frame);
11422 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11423 if (some_windows
11424 && !f->redisplay
11425 && !w->redisplay
11426 && !XBUFFER (w->contents)->text->redisplay)
11427 continue;
11428
11196 if (!EQ (frame, tooltip_frame) 11429 if (!EQ (frame, tooltip_frame)
11197 && (FRAME_ICONIFIED_P (f) 11430 && (FRAME_ICONIFIED_P (f)
11198 || FRAME_VISIBLE_P (f) == 1 11431 || FRAME_VISIBLE_P (f) == 1
@@ -11213,12 +11446,6 @@ prepare_menu_bars (void)
11213 11446
11214 /* Update the menu bar item lists, if appropriate. This has to be 11447 /* Update the menu bar item lists, if appropriate. This has to be
11215 done before any actual redisplay or generation of display lines. */ 11448 done before any actual redisplay or generation of display lines. */
11216 all_windows = (update_mode_lines
11217 || buffer_shared_and_changed ()
11218 || windows_or_buffers_changed);
11219
11220 if (FUNCTIONP (Vpre_redisplay_function))
11221 safe_call1 (Vpre_redisplay_function, all_windows ? Qt : Qnil);
11222 11449
11223 if (all_windows) 11450 if (all_windows)
11224 { 11451 {
@@ -11232,12 +11459,19 @@ prepare_menu_bars (void)
11232 11459
11233 FOR_EACH_FRAME (tail, frame) 11460 FOR_EACH_FRAME (tail, frame)
11234 { 11461 {
11235 f = XFRAME (frame); 11462 struct frame *f = XFRAME (frame);
11463 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11236 11464
11237 /* Ignore tooltip frame. */ 11465 /* Ignore tooltip frame. */
11238 if (EQ (frame, tooltip_frame)) 11466 if (EQ (frame, tooltip_frame))
11239 continue; 11467 continue;
11240 11468
11469 if (some_windows
11470 && !f->redisplay
11471 && !w->redisplay
11472 && !XBUFFER (w->contents)->text->redisplay)
11473 continue;
11474
11241 /* If a window on this frame changed size, report that to 11475 /* If a window on this frame changed size, report that to
11242 the user and clear the size-change flag. */ 11476 the user and clear the size-change flag. */
11243 if (FRAME_WINDOW_SIZES_CHANGED (f)) 11477 if (FRAME_WINDOW_SIZES_CHANGED (f))
@@ -11432,8 +11666,8 @@ update_tool_bar (struct frame *f, int save_match_data)
11432#if defined (USE_GTK) || defined (HAVE_NS) 11666#if defined (USE_GTK) || defined (HAVE_NS)
11433 int do_update = FRAME_EXTERNAL_TOOL_BAR (f); 11667 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11434#else 11668#else
11435 int do_update = WINDOWP (f->tool_bar_window) 11669 int do_update = (WINDOWP (f->tool_bar_window)
11436 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0; 11670 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0);
11437#endif 11671#endif
11438 11672
11439 if (do_update) 11673 if (do_update)
@@ -11815,7 +12049,8 @@ display_tool_bar_line (struct it *it, int height)
11815} 12049}
11816 12050
11817 12051
11818/* Max tool-bar height. */ 12052/* Max tool-bar height. Basically, this is what makes all other windows
12053 disappear when the frame gets too small. Rethink this! */
11819 12054
11820#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \ 12055#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11821 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f))) 12056 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
@@ -11825,11 +12060,11 @@ display_tool_bar_line (struct it *it, int height)
11825 returned in *N_ROWS if non-NULL. */ 12060 returned in *N_ROWS if non-NULL. */
11826 12061
11827static int 12062static int
11828tool_bar_lines_needed (struct frame *f, int *n_rows) 12063tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
11829{ 12064{
11830 struct window *w = XWINDOW (f->tool_bar_window); 12065 struct window *w = XWINDOW (f->tool_bar_window);
11831 struct it it; 12066 struct it it;
11832 /* tool_bar_lines_needed is called from redisplay_tool_bar after building 12067 /* tool_bar_height is called from redisplay_tool_bar after building
11833 the desired matrix, so use (unused) mode-line row as temporary row to 12068 the desired matrix, so use (unused) mode-line row as temporary row to
11834 avoid destroying the first tool-bar row. */ 12069 avoid destroying the first tool-bar row. */
11835 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix); 12070 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
@@ -11838,6 +12073,7 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
11838 F->desired_tool_bar_string in the tool-bar window of frame F. */ 12073 F->desired_tool_bar_string in the tool-bar window of frame F. */
11839 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID); 12074 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11840 it.first_visible_x = 0; 12075 it.first_visible_x = 0;
12076 /* PXW: Use FRAME_PIXEL_WIDTH (f) here? */
11841 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 12077 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11842 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); 12078 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11843 it.paragraph_embedding = L2R; 12079 it.paragraph_embedding = L2R;
@@ -11854,39 +12090,44 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
11854 if (n_rows) 12090 if (n_rows)
11855 *n_rows = it.vpos > 0 ? it.vpos : -1; 12091 *n_rows = it.vpos > 0 ? it.vpos : -1;
11856 12092
11857 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f); 12093 if (pixelwise)
12094 return it.current_y;
12095 else
12096 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11858} 12097}
11859 12098
11860#endif /* !USE_GTK && !HAVE_NS */ 12099#endif /* !USE_GTK && !HAVE_NS */
11861 12100
11862#if defined USE_GTK || defined HAVE_NS 12101#if defined USE_GTK || defined HAVE_NS
12102EXFUN (Ftool_bar_height, 2) ATTRIBUTE_CONST;
11863EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST; 12103EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
11864#endif 12104#endif
11865 12105
11866DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed, 12106DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
11867 0, 1, 0, 12107 0, 2, 0,
11868 doc: /* Return the number of lines occupied by the tool bar of FRAME. 12108 doc: /* Return the number of lines occupied by the tool bar of FRAME.
11869If FRAME is nil or omitted, use the selected frame. */) 12109If FRAME is nil or omitted, use the selected frame. Optional argument
11870 (Lisp_Object frame) 12110PIXELWISE non-nil means return the height of the tool bar inpixels. */)
12111 (Lisp_Object frame, Lisp_Object pixelwise)
11871{ 12112{
11872 int nlines = 0; 12113 int height = 0;
12114
11873#if ! defined (USE_GTK) && ! defined (HAVE_NS) 12115#if ! defined (USE_GTK) && ! defined (HAVE_NS)
11874 struct frame *f = decode_any_frame (frame); 12116 struct frame *f = decode_any_frame (frame);
11875 struct window *w;
11876 12117
11877 if (WINDOWP (f->tool_bar_window) 12118 if (WINDOWP (f->tool_bar_window)
11878 && (w = XWINDOW (f->tool_bar_window), 12119 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
11879 WINDOW_TOTAL_LINES (w) > 0))
11880 { 12120 {
11881 update_tool_bar (f, 1); 12121 update_tool_bar (f, 1);
11882 if (f->n_tool_bar_items) 12122 if (f->n_tool_bar_items)
11883 { 12123 {
11884 build_desired_tool_bar_string (f); 12124 build_desired_tool_bar_string (f);
11885 nlines = tool_bar_lines_needed (f, NULL); 12125 height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
11886 } 12126 }
11887 } 12127 }
11888#endif 12128#endif
11889 return make_number (nlines); 12129
12130 return make_number (height);
11890} 12131}
11891 12132
11892 12133
@@ -11914,13 +12155,13 @@ redisplay_tool_bar (struct frame *f)
11914 can turn off tool-bars by specifying tool-bar-lines zero. */ 12155 can turn off tool-bars by specifying tool-bar-lines zero. */
11915 if (!WINDOWP (f->tool_bar_window) 12156 if (!WINDOWP (f->tool_bar_window)
11916 || (w = XWINDOW (f->tool_bar_window), 12157 || (w = XWINDOW (f->tool_bar_window),
11917 WINDOW_TOTAL_LINES (w) == 0)) 12158 WINDOW_PIXEL_HEIGHT (w) == 0))
11918 return 0; 12159 return 0;
11919 12160
11920 /* Set up an iterator for the tool-bar window. */ 12161 /* Set up an iterator for the tool-bar window. */
11921 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID); 12162 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11922 it.first_visible_x = 0; 12163 it.first_visible_x = 0;
11923 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 12164 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
11924 row = it.glyph_row; 12165 row = it.glyph_row;
11925 12166
11926 /* Build a string that represents the contents of the tool-bar. */ 12167 /* Build a string that represents the contents of the tool-bar. */
@@ -11937,24 +12178,22 @@ redisplay_tool_bar (struct frame *f)
11937 12178
11938 if (f->n_tool_bar_rows == 0) 12179 if (f->n_tool_bar_rows == 0)
11939 { 12180 {
11940 int nlines; 12181 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
11941 12182
11942 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows), 12183 if (new_height != WINDOW_PIXEL_HEIGHT (w))
11943 nlines != WINDOW_TOTAL_LINES (w)))
11944 { 12184 {
11945 Lisp_Object frame; 12185 Lisp_Object frame;
11946 int old_height = WINDOW_TOTAL_LINES (w); 12186 int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
12187 / FRAME_LINE_HEIGHT (f));
11947 12188
11948 XSETFRAME (frame, f); 12189 XSETFRAME (frame, f);
11949 Fmodify_frame_parameters (frame, 12190 Fmodify_frame_parameters (frame,
11950 list1 (Fcons (Qtool_bar_lines, 12191 list1 (Fcons (Qtool_bar_lines,
11951 make_number (nlines)))); 12192 make_number (new_lines))));
11952 if (WINDOW_TOTAL_LINES (w) != old_height) 12193 /* Always do that now. */
11953 { 12194 clear_glyph_matrix (w->desired_matrix);
11954 clear_glyph_matrix (w->desired_matrix); 12195 f->fonts_changed = 1;
11955 f->fonts_changed = 1; 12196 return 1;
11956 return 1;
11957 }
11958 } 12197 }
11959 } 12198 }
11960 12199
@@ -12003,6 +12242,7 @@ redisplay_tool_bar (struct frame *f)
12003 12242
12004 if (!NILP (Vauto_resize_tool_bars)) 12243 if (!NILP (Vauto_resize_tool_bars))
12005 { 12244 {
12245 /* Do we really allow the toolbar to occupy the whole frame? */
12006 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f); 12246 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12007 int change_height_p = 0; 12247 int change_height_p = 0;
12008 12248
@@ -12033,29 +12273,29 @@ redisplay_tool_bar (struct frame *f)
12033 if (change_height_p) 12273 if (change_height_p)
12034 { 12274 {
12035 Lisp_Object frame; 12275 Lisp_Object frame;
12036 int old_height = WINDOW_TOTAL_LINES (w);
12037 int nrows; 12276 int nrows;
12038 int nlines = tool_bar_lines_needed (f, &nrows); 12277 int new_height = tool_bar_height (f, &nrows, 1);
12039 12278
12040 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only) 12279 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12041 && !f->minimize_tool_bar_window_p) 12280 && !f->minimize_tool_bar_window_p)
12042 ? (nlines > old_height) 12281 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12043 : (nlines != old_height)); 12282 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12044 f->minimize_tool_bar_window_p = 0; 12283 f->minimize_tool_bar_window_p = 0;
12045 12284
12046 if (change_height_p) 12285 if (change_height_p)
12047 { 12286 {
12287 int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
12288 / FRAME_LINE_HEIGHT (f));
12289
12048 XSETFRAME (frame, f); 12290 XSETFRAME (frame, f);
12049 Fmodify_frame_parameters (frame, 12291 Fmodify_frame_parameters (frame,
12050 list1 (Fcons (Qtool_bar_lines, 12292 list1 (Fcons (Qtool_bar_lines,
12051 make_number (nlines)))); 12293 make_number (new_lines))));
12052 if (WINDOW_TOTAL_LINES (w) != old_height) 12294 /* Always do that now. */
12053 { 12295 clear_glyph_matrix (w->desired_matrix);
12054 clear_glyph_matrix (w->desired_matrix); 12296 f->n_tool_bar_rows = nrows;
12055 f->n_tool_bar_rows = nrows; 12297 f->fonts_changed = 1;
12056 f->fonts_changed = 1; 12298 return 1;
12057 return 1;
12058 }
12059 } 12299 }
12060 } 12300 }
12061 } 12301 }
@@ -12384,7 +12624,7 @@ hscroll_window_tree (Lisp_Object window)
12384 /* For left-to-right rows, hscroll when cursor is either 12624 /* For left-to-right rows, hscroll when cursor is either
12385 (i) inside the right hscroll margin, or (ii) if it is 12625 (i) inside the right hscroll margin, or (ii) if it is
12386 inside the left margin and the window is already 12626 inside the left margin and the window is already
12387 hscrolled. */ 12627 hscrolled. */
12388 && ((!row_r2l_p 12628 && ((!row_r2l_p
12389 && ((w->hscroll 12629 && ((w->hscroll
12390 && w->cursor.x <= h_margin) 12630 && w->cursor.x <= h_margin)
@@ -12401,7 +12641,7 @@ hscroll_window_tree (Lisp_Object window)
12401 && ((cursor_row->enabled_p 12641 && ((cursor_row->enabled_p
12402 /* FIXME: It is confusing to set the 12642 /* FIXME: It is confusing to set the
12403 truncated_on_right_p flag when R2L rows 12643 truncated_on_right_p flag when R2L rows
12404 are actually truncated on the left. */ 12644 are actually truncated on the left. */
12405 && cursor_row->truncated_on_right_p 12645 && cursor_row->truncated_on_right_p
12406 && w->cursor.x <= h_margin) 12646 && w->cursor.x <= h_margin)
12407 || (w->hscroll 12647 || (w->hscroll
@@ -12860,6 +13100,28 @@ reconsider_clip_changes (struct window *w)
12860 } 13100 }
12861} 13101}
12862 13102
13103static void
13104propagate_buffer_redisplay (void)
13105{ /* Resetting b->text->redisplay is problematic!
13106 We can't just reset it in the case that some window that displays
13107 it has not been redisplayed; and such a window can stay
13108 unredisplayed for a long time if it's currently invisible.
13109 But we do want to reset it at the end of redisplay otherwise
13110 its displayed windows will keep being redisplayed over and over
13111 again.
13112 So we copy all b->text->redisplay flags up to their windows here,
13113 such that mark_window_display_accurate can safely reset
13114 b->text->redisplay. */
13115 Lisp_Object ws = window_list ();
13116 for (; CONSP (ws); ws = XCDR (ws))
13117 {
13118 struct window *thisw = XWINDOW (XCAR (ws));
13119 struct buffer *thisb = XBUFFER (thisw->contents);
13120 if (thisb->text->redisplay)
13121 thisw->redisplay = true;
13122 }
13123}
13124
12863#define STOP_POLLING \ 13125#define STOP_POLLING \
12864do { if (! polling_stopped_here) stop_polling (); \ 13126do { if (! polling_stopped_here) stop_polling (); \
12865 polling_stopped_here = 1; } while (0) 13127 polling_stopped_here = 1; } while (0)
@@ -12956,7 +13218,6 @@ redisplay_internal (void)
12956 /* Since frames on a single ASCII terminal share the same 13218 /* Since frames on a single ASCII terminal share the same
12957 display area, displaying a different frame means redisplay 13219 display area, displaying a different frame means redisplay
12958 the whole thing. */ 13220 the whole thing. */
12959 windows_or_buffers_changed = 48;
12960 SET_FRAME_GARBAGED (sf); 13221 SET_FRAME_GARBAGED (sf);
12961#ifndef DOS_NT 13222#ifndef DOS_NT
12962 set_tty_color_mode (FRAME_TTY (sf), sf); 13223 set_tty_color_mode (FRAME_TTY (sf), sf);
@@ -13005,9 +13266,6 @@ redisplay_internal (void)
13005 if (NILP (Vmemory_full)) 13266 if (NILP (Vmemory_full))
13006 prepare_menu_bars (); 13267 prepare_menu_bars ();
13007 13268
13008 if (windows_or_buffers_changed && !update_mode_lines)
13009 update_mode_lines = 32;
13010
13011 reconsider_clip_changes (w); 13269 reconsider_clip_changes (w);
13012 13270
13013 /* In most cases selected window displays current buffer. */ 13271 /* In most cases selected window displays current buffer. */
@@ -13016,27 +13274,12 @@ redisplay_internal (void)
13016 { 13274 {
13017 /* Detect case that we need to write or remove a star in the mode line. */ 13275 /* Detect case that we need to write or remove a star in the mode line. */
13018 if ((SAVE_MODIFF < MODIFF) != w->last_had_star) 13276 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13019 {
13020 w->update_mode_line = 1; 13277 w->update_mode_line = 1;
13021 if (buffer_shared_and_changed ())
13022 update_mode_lines = 33;
13023 }
13024 13278
13025 if (mode_line_update_needed (w)) 13279 if (mode_line_update_needed (w))
13026 w->update_mode_line = 1; 13280 w->update_mode_line = 1;
13027 } 13281 }
13028 13282
13029 consider_all_windows_p = (update_mode_lines
13030 || buffer_shared_and_changed ());
13031
13032 /* If specs for an arrow have changed, do thorough redisplay
13033 to ensure we remove any arrow that should no longer exist. */
13034 if (overlay_arrows_changed_p ())
13035 {
13036 consider_all_windows_p = true;
13037 windows_or_buffers_changed = 49;
13038 }
13039
13040 /* Normally the message* functions will have already displayed and 13283 /* Normally the message* functions will have already displayed and
13041 updated the echo area, but the frame may have been trashed, or 13284 updated the echo area, but the frame may have been trashed, or
13042 the update may have been preempted, so display the echo area 13285 the update may have been preempted, so display the echo area
@@ -13066,8 +13309,6 @@ redisplay_internal (void)
13066 13309
13067 if (window_height_changed_p) 13310 if (window_height_changed_p)
13068 { 13311 {
13069 consider_all_windows_p = true;
13070 update_mode_lines = 34;
13071 windows_or_buffers_changed = 50; 13312 windows_or_buffers_changed = 50;
13072 13313
13073 /* If window configuration was changed, frames may have been 13314 /* If window configuration was changed, frames may have been
@@ -13083,13 +13324,6 @@ redisplay_internal (void)
13083 /* Resized active mini-window to fit the size of what it is 13324 /* Resized active mini-window to fit the size of what it is
13084 showing if its contents might have changed. */ 13325 showing if its contents might have changed. */
13085 must_finish = 1; 13326 must_finish = 1;
13086 /* FIXME: this causes all frames to be updated, which seems unnecessary
13087 since only the current frame needs to be considered. This function
13088 needs to be rewritten with two variables, consider_all_windows and
13089 consider_all_frames. */
13090 consider_all_windows_p = true;
13091 windows_or_buffers_changed = 51;
13092 update_mode_lines = 35;
13093 13327
13094 /* If window configuration was changed, frames may have been 13328 /* If window configuration was changed, frames may have been
13095 marked garbaged. Clear them or we will experience 13329 marked garbaged. Clear them or we will experience
@@ -13097,23 +13331,29 @@ redisplay_internal (void)
13097 clear_garbaged_frames (); 13331 clear_garbaged_frames ();
13098 } 13332 }
13099 13333
13100 if (VECTORP (Vredisplay__all_windows_cause) 13334 if (windows_or_buffers_changed && !update_mode_lines)
13101 && windows_or_buffers_changed >= 0 13335 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
13102 && windows_or_buffers_changed < ASIZE (Vredisplay__all_windows_cause) 13336 only the windows's contents needs to be refreshed, or whether the
13103 && INTEGERP (AREF (Vredisplay__all_windows_cause, 13337 mode-lines also need a refresh. */
13104 windows_or_buffers_changed))) 13338 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
13105 ASET (Vredisplay__all_windows_cause, windows_or_buffers_changed, 13339 ? REDISPLAY_SOME : 32);
13106 make_number (1 + XINT (AREF (Vredisplay__all_windows_cause, 13340
13107 windows_or_buffers_changed)))); 13341 /* If specs for an arrow have changed, do thorough redisplay
13108 13342 to ensure we remove any arrow that should no longer exist. */
13109 if (VECTORP (Vredisplay__mode_lines_cause) 13343 if (overlay_arrows_changed_p ())
13110 && update_mode_lines >= 0 13344 /* Apparently, this is the only case where we update other windows,
13111 && update_mode_lines < ASIZE (Vredisplay__mode_lines_cause) 13345 without updating other mode-lines. */
13112 && INTEGERP (AREF (Vredisplay__mode_lines_cause, 13346 windows_or_buffers_changed = 49;
13113 update_mode_lines))) 13347
13114 ASET (Vredisplay__mode_lines_cause, update_mode_lines, 13348 consider_all_windows_p = (update_mode_lines
13115 make_number (1 + XINT (AREF (Vredisplay__mode_lines_cause, 13349 || windows_or_buffers_changed);
13116 update_mode_lines)))); 13350
13351#define AINC(a,i) \
13352 if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
13353 ASET (a, i, make_number (1 + XINT (AREF (a, i))))
13354
13355 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
13356 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
13117 13357
13118 /* Optimize the case that only the line containing the cursor in the 13358 /* Optimize the case that only the line containing the cursor in the
13119 selected window has changed. Variables starting with this_ are 13359 selected window has changed. Variables starting with this_ are
@@ -13254,6 +13494,8 @@ redisplay_internal (void)
13254 PT == w->last_point 13494 PT == w->last_point
13255 /* Make sure the cursor was last displayed 13495 /* Make sure the cursor was last displayed
13256 in this window. Otherwise we have to reposition it. */ 13496 in this window. Otherwise we have to reposition it. */
13497
13498 /* PXW: Must be converted to pixels, probably. */
13257 && 0 <= w->cursor.vpos 13499 && 0 <= w->cursor.vpos
13258 && w->cursor.vpos < WINDOW_TOTAL_LINES (w)) 13500 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
13259 { 13501 {
@@ -13330,6 +13572,8 @@ redisplay_internal (void)
13330 FOR_EACH_FRAME (tail, frame) 13572 FOR_EACH_FRAME (tail, frame)
13331 XFRAME (frame)->updated_p = 0; 13573 XFRAME (frame)->updated_p = 0;
13332 13574
13575 propagate_buffer_redisplay ();
13576
13333 FOR_EACH_FRAME (tail, frame) 13577 FOR_EACH_FRAME (tail, frame)
13334 { 13578 {
13335 struct frame *f = XFRAME (frame); 13579 struct frame *f = XFRAME (frame);
@@ -13344,13 +13588,20 @@ redisplay_internal (void)
13344 13588
13345 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) 13589 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13346 { 13590 {
13591 bool gcscrollbars
13592 /* Only GC scrollbars when we redisplay the whole frame. */
13593 = f->redisplay || !REDISPLAY_SOME_P ();
13347 /* Mark all the scroll bars to be removed; we'll redeem 13594 /* Mark all the scroll bars to be removed; we'll redeem
13348 the ones we want when we redisplay their windows. */ 13595 the ones we want when we redisplay their windows. */
13349 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook) 13596 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13350 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); 13597 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13351 13598
13352 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) 13599 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13353 redisplay_windows (FRAME_ROOT_WINDOW (f)); 13600 redisplay_windows (FRAME_ROOT_WINDOW (f));
13601 /* Remember that the invisible frames need to be redisplayed next
13602 time they're visible. */
13603 else if (!REDISPLAY_SOME_P ())
13604 f->redisplay = true;
13354 13605
13355 /* The X error handler may have deleted that frame. */ 13606 /* The X error handler may have deleted that frame. */
13356 if (!FRAME_LIVE_P (f)) 13607 if (!FRAME_LIVE_P (f))
@@ -13358,7 +13609,7 @@ redisplay_internal (void)
13358 13609
13359 /* Any scroll bars which redisplay_windows should have 13610 /* Any scroll bars which redisplay_windows should have
13360 nuked should now go away. */ 13611 nuked should now go away. */
13361 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook) 13612 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13362 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); 13613 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13363 13614
13364 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) 13615 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
@@ -13381,19 +13632,11 @@ redisplay_internal (void)
13381 13632
13382 /* Prevent various kinds of signals during display 13633 /* Prevent various kinds of signals during display
13383 update. stdio is not robust about handling 13634 update. stdio is not robust about handling
13384 signals, which can cause an apparent I/O 13635 signals, which can cause an apparent I/O error. */
13385 error. */
13386 if (interrupt_input) 13636 if (interrupt_input)
13387 unrequest_sigio (); 13637 unrequest_sigio ();
13388 STOP_POLLING; 13638 STOP_POLLING;
13389 13639
13390 /* Mark windows on frame F to update. If we decide to
13391 update all frames but windows_or_buffers_changed is
13392 zero, we assume that only the windows that shows
13393 current buffer should be really updated. */
13394 set_window_update_flags
13395 (XWINDOW (f->root_window),
13396 (windows_or_buffers_changed ? NULL : current_buffer), 1);
13397 pending |= update_frame (f, 0, 0); 13640 pending |= update_frame (f, 0, 0);
13398 f->cursor_type_changed = 0; 13641 f->cursor_type_changed = 0;
13399 f->updated_p = 1; 13642 f->updated_p = 1;
@@ -13413,6 +13656,7 @@ redisplay_internal (void)
13413 struct frame *f = XFRAME (frame); 13656 struct frame *f = XFRAME (frame);
13414 if (f->updated_p) 13657 if (f->updated_p)
13415 { 13658 {
13659 f->redisplay = false;
13416 mark_window_display_accurate (f->root_window, 1); 13660 mark_window_display_accurate (f->root_window, 1);
13417 if (FRAME_TERMINAL (f)->frame_up_to_date_hook) 13661 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13418 FRAME_TERMINAL (f)->frame_up_to_date_hook (f); 13662 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
@@ -13455,7 +13699,7 @@ redisplay_internal (void)
13455 if (hscroll_windows (selected_window)) 13699 if (hscroll_windows (selected_window))
13456 goto retry; 13700 goto retry;
13457 13701
13458 XWINDOW (selected_window)->must_be_updated_p = 1; 13702 XWINDOW (selected_window)->must_be_updated_p = true;
13459 pending = update_frame (sf, 0, 0); 13703 pending = update_frame (sf, 0, 0);
13460 sf->cursor_type_changed = 0; 13704 sf->cursor_type_changed = 0;
13461 } 13705 }
@@ -13470,7 +13714,7 @@ redisplay_internal (void)
13470 13714
13471 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame)) 13715 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13472 { 13716 {
13473 XWINDOW (mini_window)->must_be_updated_p = 1; 13717 XWINDOW (mini_window)->must_be_updated_p = true;
13474 pending |= update_frame (mini_frame, 0, 0); 13718 pending |= update_frame (mini_frame, 0, 0);
13475 mini_frame->cursor_type_changed = 0; 13719 mini_frame->cursor_type_changed = 0;
13476 if (!pending && hscroll_windows (mini_window)) 13720 if (!pending && hscroll_windows (mini_window))
@@ -13502,6 +13746,11 @@ redisplay_internal (void)
13502 { 13746 {
13503 /* This has already been done above if 13747 /* This has already been done above if
13504 consider_all_windows_p is set. */ 13748 consider_all_windows_p is set. */
13749 if (XBUFFER (w->contents)->text->redisplay
13750 && buffer_window_count (XBUFFER (w->contents)) > 1)
13751 /* This can happen if b->text->redisplay was set during
13752 jit-lock. */
13753 propagate_buffer_redisplay ();
13505 mark_window_display_accurate_1 (w, 1); 13754 mark_window_display_accurate_1 (w, 1);
13506 13755
13507 /* Say overlay arrows are up to date. */ 13756 /* Say overlay arrows are up to date. */
@@ -13535,12 +13784,7 @@ redisplay_internal (void)
13535 13784
13536 FOR_EACH_FRAME (tail, frame) 13785 FOR_EACH_FRAME (tail, frame)
13537 { 13786 {
13538 int this_is_visible = 0;
13539
13540 if (XFRAME (frame)->visible) 13787 if (XFRAME (frame)->visible)
13541 this_is_visible = 1;
13542
13543 if (this_is_visible)
13544 new_count++; 13788 new_count++;
13545 } 13789 }
13546 13790
@@ -13578,6 +13822,9 @@ redisplay_internal (void)
13578#endif /* HAVE_WINDOW_SYSTEM */ 13822#endif /* HAVE_WINDOW_SYSTEM */
13579 13823
13580 end_of_redisplay: 13824 end_of_redisplay:
13825 if (interrupt_input && interrupts_deferred)
13826 request_sigio ();
13827
13581 unbind_to (count, Qnil); 13828 unbind_to (count, Qnil);
13582 RESUME_POLLING; 13829 RESUME_POLLING;
13583} 13830}
@@ -13639,8 +13886,13 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
13639 13886
13640 if (accurate_p) 13887 if (accurate_p)
13641 { 13888 {
13642 b->clip_changed = 0; 13889 b->clip_changed = false;
13643 b->prevent_redisplay_optimizations_p = 0; 13890 b->prevent_redisplay_optimizations_p = false;
13891 eassert (buffer_window_count (b) > 0);
13892 /* Resetting b->text->redisplay is problematic!
13893 In order to make it safer to do it here, redisplay_internal must
13894 have copied all b->text->redisplay to their respective windows. */
13895 b->text->redisplay = false;
13644 13896
13645 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b); 13897 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13646 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b); 13898 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
@@ -13659,9 +13911,11 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
13659 else 13911 else
13660 w->last_point = marker_position (w->pointm); 13912 w->last_point = marker_position (w->pointm);
13661 13913
13662 w->window_end_valid = 1; 13914 w->window_end_valid = true;
13663 w->update_mode_line = 0; 13915 w->update_mode_line = false;
13664 } 13916 }
13917
13918 w->redisplay = !accurate_p;
13665} 13919}
13666 13920
13667 13921
@@ -13764,7 +14018,7 @@ static Lisp_Object
13764redisplay_window_0 (Lisp_Object window) 14018redisplay_window_0 (Lisp_Object window)
13765{ 14019{
13766 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer)) 14020 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13767 redisplay_window (window, 0); 14021 redisplay_window (window, false);
13768 return Qnil; 14022 return Qnil;
13769} 14023}
13770 14024
@@ -13772,7 +14026,7 @@ static Lisp_Object
13772redisplay_window_1 (Lisp_Object window) 14026redisplay_window_1 (Lisp_Object window)
13773{ 14027{
13774 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer)) 14028 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13775 redisplay_window (window, 1); 14029 redisplay_window (window, true);
13776 return Qnil; 14030 return Qnil;
13777} 14031}
13778 14032
@@ -14314,9 +14568,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
14314 occlude point. Only set w->cursor if we found a better 14568 occlude point. Only set w->cursor if we found a better
14315 approximation to the cursor position than we have from previously 14569 approximation to the cursor position than we have from previously
14316 examined candidate rows belonging to the same continued line. */ 14570 examined candidate rows belonging to the same continued line. */
14317 if (/* we already have a candidate row */ 14571 if (/* We already have a candidate row. */
14318 w->cursor.vpos >= 0 14572 w->cursor.vpos >= 0
14319 /* that candidate is not the row we are processing */ 14573 /* That candidate is not the row we are processing. */
14320 && MATRIX_ROW (matrix, w->cursor.vpos) != row 14574 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14321 /* Make sure cursor.vpos specifies a row whose start and end 14575 /* Make sure cursor.vpos specifies a row whose start and end
14322 charpos occlude point, and it is valid candidate for being a 14576 charpos occlude point, and it is valid candidate for being a
@@ -14327,30 +14581,30 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
14327 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) 14581 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14328 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos))) 14582 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14329 { 14583 {
14330 struct glyph *g1 = 14584 struct glyph *g1
14331 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos; 14585 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14332 14586
14333 /* Don't consider glyphs that are outside TEXT_AREA. */ 14587 /* Don't consider glyphs that are outside TEXT_AREA. */
14334 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)) 14588 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14335 return 0; 14589 return 0;
14336 /* Keep the candidate whose buffer position is the closest to 14590 /* Keep the candidate whose buffer position is the closest to
14337 point or has the `cursor' property. */ 14591 point or has the `cursor' property. */
14338 if (/* previous candidate is a glyph in TEXT_AREA of that row */ 14592 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
14339 w->cursor.hpos >= 0 14593 w->cursor.hpos >= 0
14340 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos) 14594 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14341 && ((BUFFERP (g1->object) 14595 && ((BUFFERP (g1->object)
14342 && (g1->charpos == pt_old /* an exact match always wins */ 14596 && (g1->charpos == pt_old /* An exact match always wins. */
14343 || (BUFFERP (glyph->object) 14597 || (BUFFERP (glyph->object)
14344 && eabs (g1->charpos - pt_old) 14598 && eabs (g1->charpos - pt_old)
14345 < eabs (glyph->charpos - pt_old)))) 14599 < eabs (glyph->charpos - pt_old))))
14346 /* previous candidate is a glyph from a string that has 14600 /* Previous candidate is a glyph from a string that has
14347 a non-nil `cursor' property */ 14601 a non-nil `cursor' property. */
14348 || (STRINGP (g1->object) 14602 || (STRINGP (g1->object)
14349 && (!NILP (Fget_char_property (make_number (g1->charpos), 14603 && (!NILP (Fget_char_property (make_number (g1->charpos),
14350 Qcursor, g1->object)) 14604 Qcursor, g1->object))
14351 /* previous candidate is from the same display 14605 /* Previous candidate is from the same display
14352 string as this one, and the display string 14606 string as this one, and the display string
14353 came from a text property */ 14607 came from a text property. */
14354 || (EQ (g1->object, glyph->object) 14608 || (EQ (g1->object, glyph->object)
14355 && string_from_text_prop) 14609 && string_from_text_prop)
14356 /* this candidate is from newline and its 14610 /* this candidate is from newline and its
@@ -14793,7 +15047,7 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14793 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0) 15047 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14794 /* It's possible that the cursor is on the first line of the 15048 /* It's possible that the cursor is on the first line of the
14795 buffer, which is partially obscured due to a vscroll 15049 buffer, which is partially obscured due to a vscroll
14796 (Bug#7537). In that case, avoid looping forever . */ 15050 (Bug#7537). In that case, avoid looping forever. */
14797 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1) 15051 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14798 { 15052 {
14799 clear_glyph_matrix (w->desired_matrix); 15053 clear_glyph_matrix (w->desired_matrix);
@@ -14848,6 +15102,7 @@ compute_window_start_on_continuation_line (struct window *w)
14848 /* If the line start is "too far" away from the window start, 15102 /* If the line start is "too far" away from the window start,
14849 say it takes too much time to compute a new window start. */ 15103 say it takes too much time to compute a new window start. */
14850 if (CHARPOS (start_pos) - IT_CHARPOS (it) 15104 if (CHARPOS (start_pos) - IT_CHARPOS (it)
15105 /* PXW: Do we need upper bounds here? */
14851 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)) 15106 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14852 { 15107 {
14853 int min_distance, distance; 15108 int min_distance, distance;
@@ -15298,7 +15553,7 @@ set_vertical_scroll_bar (struct window *w)
15298 changed on window's frame. In that case, redisplay_internal will retry. */ 15553 changed on window's frame. In that case, redisplay_internal will retry. */
15299 15554
15300static void 15555static void
15301redisplay_window (Lisp_Object window, int just_this_one_p) 15556redisplay_window (Lisp_Object window, bool just_this_one_p)
15302{ 15557{
15303 struct window *w = XWINDOW (window); 15558 struct window *w = XWINDOW (window);
15304 struct frame *f = XFRAME (w->frame); 15559 struct frame *f = XFRAME (w->frame);
@@ -15309,11 +15564,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15309 int tem; 15564 int tem;
15310 struct it it; 15565 struct it it;
15311 /* Record it now because it's overwritten. */ 15566 /* Record it now because it's overwritten. */
15312 int current_matrix_up_to_date_p = 0; 15567 bool current_matrix_up_to_date_p = false;
15313 int used_current_matrix_p = 0; 15568 bool used_current_matrix_p = false;
15314 /* This is less strict than current_matrix_up_to_date_p. 15569 /* This is less strict than current_matrix_up_to_date_p.
15315 It indicates that the buffer contents and narrowing are unchanged. */ 15570 It indicates that the buffer contents and narrowing are unchanged. */
15316 int buffer_unchanged_p = 0; 15571 bool buffer_unchanged_p = false;
15317 int temp_scroll_step = 0; 15572 int temp_scroll_step = 0;
15318 ptrdiff_t count = SPECPDL_INDEX (); 15573 ptrdiff_t count = SPECPDL_INDEX ();
15319 int rc; 15574 int rc;
@@ -15329,6 +15584,13 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15329 *w->desired_matrix->method = 0; 15584 *w->desired_matrix->method = 0;
15330#endif 15585#endif
15331 15586
15587 if (!just_this_one_p
15588 && REDISPLAY_SOME_P ()
15589 && !w->redisplay
15590 && !f->redisplay
15591 && !buffer->text->redisplay)
15592 return;
15593
15332 /* Make sure that both W's markers are valid. */ 15594 /* Make sure that both W's markers are valid. */
15333 eassert (XMARKER (w->start)->buffer == buffer); 15595 eassert (XMARKER (w->start)->buffer == buffer);
15334 eassert (XMARKER (w->pointm)->buffer == buffer); 15596 eassert (XMARKER (w->pointm)->buffer == buffer);
@@ -15343,6 +15605,11 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15343 || buffer->clip_changed 15605 || buffer->clip_changed
15344 || buffer->prevent_redisplay_optimizations_p); 15606 || buffer->prevent_redisplay_optimizations_p);
15345 15607
15608 if (!just_this_one_p)
15609 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
15610 cleverly elsewhere. */
15611 w->must_be_updated_p = true;
15612
15346 if (MINI_WINDOW_P (w)) 15613 if (MINI_WINDOW_P (w))
15347 { 15614 {
15348 if (w == XWINDOW (echo_area_window) 15615 if (w == XWINDOW (echo_area_window)
@@ -15423,10 +15690,10 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15423 if (XMARKER (w->start)->buffer == current_buffer) 15690 if (XMARKER (w->start)->buffer == current_buffer)
15424 compute_window_start_on_continuation_line (w); 15691 compute_window_start_on_continuation_line (w);
15425 15692
15426 w->window_end_valid = 0; 15693 w->window_end_valid = false;
15427 /* If so, we also can't rely on current matrix 15694 /* If so, we also can't rely on current matrix
15428 and should not fool try_cursor_movement below. */ 15695 and should not fool try_cursor_movement below. */
15429 current_matrix_up_to_date_p = 0; 15696 current_matrix_up_to_date_p = false;
15430 } 15697 }
15431 15698
15432 /* Some sanity checks. */ 15699 /* Some sanity checks. */
@@ -16044,7 +16311,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
16044 16311
16045 SET_TEXT_POS_FROM_MARKER (startp, w->start); 16312 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16046 w->start_at_line_beg = (CHARPOS (startp) == BEGV 16313 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16047 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'); 16314 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16048 16315
16049 /* Display the mode line, if we must. */ 16316 /* Display the mode line, if we must. */
16050 if ((update_mode_line 16317 if ((update_mode_line
@@ -16064,6 +16331,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
16064 && (WINDOW_WANTS_MODELINE_P (w) 16331 && (WINDOW_WANTS_MODELINE_P (w)
16065 || WINDOW_WANTS_HEADER_LINE_P (w))) 16332 || WINDOW_WANTS_HEADER_LINE_P (w)))
16066 { 16333 {
16334
16067 display_mode_lines (w); 16335 display_mode_lines (w);
16068 16336
16069 /* If mode line height has changed, arrange for a thorough 16337 /* If mode line height has changed, arrange for a thorough
@@ -16129,7 +16397,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
16129 redisplay_tool_bar (f); 16397 redisplay_tool_bar (f);
16130#else 16398#else
16131 if (WINDOWP (f->tool_bar_window) 16399 if (WINDOWP (f->tool_bar_window)
16132 && (FRAME_TOOL_BAR_LINES (f) > 0 16400 && (FRAME_TOOL_BAR_HEIGHT (f) > 0
16133 || !NILP (Vauto_resize_tool_bars)) 16401 || !NILP (Vauto_resize_tool_bars))
16134 && redisplay_tool_bar (f)) 16402 && redisplay_tool_bar (f))
16135 ignore_mouse_drag_p = 1; 16403 ignore_mouse_drag_p = 1;
@@ -16147,10 +16415,18 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
16147 update_begin (f); 16415 update_begin (f);
16148 block_input (); 16416 block_input ();
16149 if (draw_window_fringes (w, 1)) 16417 if (draw_window_fringes (w, 1))
16150 x_draw_vertical_border (w); 16418 {
16419 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
16420 x_draw_right_divider (w);
16421 else
16422 x_draw_vertical_border (w);
16423 }
16151 unblock_input (); 16424 unblock_input ();
16152 update_end (f); 16425 update_end (f);
16153 } 16426 }
16427
16428 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
16429 x_draw_bottom_divider (w);
16154#endif /* HAVE_WINDOW_SYSTEM */ 16430#endif /* HAVE_WINDOW_SYSTEM */
16155 16431
16156 /* We go to this label, with fonts_changed set, if it is 16432 /* We go to this label, with fonts_changed set, if it is
@@ -16184,7 +16460,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
16184 16460
16185 set_buffer_internal_1 (old); 16461 set_buffer_internal_1 (old);
16186 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become 16462 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16187 shorter. This can be caused by log truncation in *Messages*. */ 16463 shorter. This can be caused by log truncation in *Messages*. */
16188 if (CHARPOS (lpoint) <= ZV) 16464 if (CHARPOS (lpoint) <= ZV)
16189 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint)); 16465 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16190 16466
@@ -20453,6 +20729,7 @@ display_menu_bar (struct window *w)
20453 eassert (!FRAME_WINDOW_P (f)); 20729 eassert (!FRAME_WINDOW_P (f));
20454 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID); 20730 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20455 it.first_visible_x = 0; 20731 it.first_visible_x = 0;
20732 /* PXW: Use FRAME_PIXEL_WIDTH (f) here? */
20456 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 20733 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20457#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */ 20734#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
20458 if (FRAME_WINDOW_P (f)) 20735 if (FRAME_WINDOW_P (f))
@@ -20464,6 +20741,7 @@ display_menu_bar (struct window *w)
20464 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows, 20741 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20465 MENU_FACE_ID); 20742 MENU_FACE_ID);
20466 it.first_visible_x = 0; 20743 it.first_visible_x = 0;
20744 /* PXW: Use FRAME_PIXEL_WIDTH (f) here? */
20467 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 20745 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20468 } 20746 }
20469 else 20747 else
@@ -20519,7 +20797,6 @@ display_menu_bar (struct window *w)
20519 compute_line_metrics (&it); 20797 compute_line_metrics (&it);
20520} 20798}
20521 20799
20522#ifdef HAVE_MENUS
20523/* Deep copy of a glyph row, including the glyphs. */ 20800/* Deep copy of a glyph row, including the glyphs. */
20524static void 20801static void
20525deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from) 20802deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
@@ -20641,7 +20918,6 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
20641 row->full_width_p = saved_width; 20918 row->full_width_p = saved_width;
20642 row->reversed_p = saved_reversed; 20919 row->reversed_p = saved_reversed;
20643} 20920}
20644#endif /* HAVE_MENUS */
20645 20921
20646/*********************************************************************** 20922/***********************************************************************
20647 Mode Line 20923 Mode Line
@@ -20653,7 +20929,7 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
20653 the number of windows whose mode lines were redisplayed. */ 20929 the number of windows whose mode lines were redisplayed. */
20654 20930
20655static int 20931static int
20656redisplay_mode_lines (Lisp_Object window, int force) 20932redisplay_mode_lines (Lisp_Object window, bool force)
20657{ 20933{
20658 int nwindows = 0; 20934 int nwindows = 0;
20659 20935
@@ -20687,10 +20963,7 @@ redisplay_mode_lines (Lisp_Object window, int force)
20687 /* Display mode lines. */ 20963 /* Display mode lines. */
20688 clear_glyph_matrix (w->desired_matrix); 20964 clear_glyph_matrix (w->desired_matrix);
20689 if (display_mode_lines (w)) 20965 if (display_mode_lines (w))
20690 { 20966 ++nwindows;
20691 ++nwindows;
20692 w->must_be_updated_p = 1;
20693 }
20694 20967
20695 /* Restore old settings. */ 20968 /* Restore old settings. */
20696 set_buffer_internal_1 (old); 20969 set_buffer_internal_1 (old);
@@ -20746,6 +21019,8 @@ display_mode_lines (struct window *w)
20746 XFRAME (new_frame)->selected_window = old_frame_selected_window; 21019 XFRAME (new_frame)->selected_window = old_frame_selected_window;
20747 selected_frame = old_selected_frame; 21020 selected_frame = old_selected_frame;
20748 selected_window = old_selected_window; 21021 selected_window = old_selected_window;
21022 if (n > 0)
21023 w->must_be_updated_p = true;
20749 return n; 21024 return n;
20750} 21025}
20751 21026
@@ -23841,7 +24116,8 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
23841 /* X is relative to the left edge of W, without scroll bars 24116 /* X is relative to the left edge of W, without scroll bars
23842 or fringes. */ 24117 or fringes. */
23843 area_left = WINDOW_LEFT_EDGE_X (w); 24118 area_left = WINDOW_LEFT_EDGE_X (w);
23844 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w); 24119 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
24120 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
23845 } 24121 }
23846 else 24122 else
23847 { 24123 {
@@ -25879,7 +26155,8 @@ x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
25879 f = XFRAME (w->frame); 26155 f = XFRAME (w->frame);
25880 26156
25881 if (updated_row->full_width_p) 26157 if (updated_row->full_width_p)
25882 max_x = WINDOW_TOTAL_WIDTH (w); 26158 max_x = (WINDOW_PIXEL_WIDTH (w)
26159 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
25883 else 26160 else
25884 max_x = window_box_width (w, updated_area); 26161 max_x = window_box_width (w, updated_area);
25885 max_y = window_text_bottom_y (w); 26162 max_y = window_text_bottom_y (w);
@@ -26796,7 +27073,10 @@ clear_mouse_face (Mouse_HLInfo *hlinfo)
26796 cleared = 1; 27073 cleared = 1;
26797 } 27074 }
26798 27075
26799 reset_mouse_highlight (hlinfo); 27076 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
27077 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
27078 hlinfo->mouse_face_window = Qnil;
27079 hlinfo->mouse_face_overlay = Qnil;
26800 return cleared; 27080 return cleared;
26801} 27081}
26802 27082
@@ -27720,6 +28000,8 @@ define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27720 cursor = FRAME_X_OUTPUT (f)->text_cursor; 28000 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27721 else if (EQ (pointer, intern ("hdrag"))) 28001 else if (EQ (pointer, intern ("hdrag")))
27722 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor; 28002 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28003 else if (EQ (pointer, intern ("nhdrag")))
28004 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
27723#ifdef HAVE_X_WINDOWS 28005#ifdef HAVE_X_WINDOWS
27724 else if (EQ (pointer, intern ("vdrag"))) 28006 else if (EQ (pointer, intern ("vdrag")))
27725 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; 28007 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
@@ -28133,6 +28415,16 @@ note_mouse_highlight (struct frame *f, int x, int y)
28133 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor; 28415 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28134 help_echo_string = build_string ("drag-mouse-1: resize"); 28416 help_echo_string = build_string ("drag-mouse-1: resize");
28135 } 28417 }
28418 else if (part == ON_RIGHT_DIVIDER)
28419 {
28420 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
28421 help_echo_string = build_string ("drag-mouse-1: resize");
28422 }
28423 else if (part == ON_BOTTOM_DIVIDER)
28424 {
28425 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
28426 help_echo_string = build_string ("drag-mouse-1: resize");
28427 }
28136 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE 28428 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28137 || part == ON_SCROLL_BAR) 28429 || part == ON_SCROLL_BAR)
28138 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 28430 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -28773,7 +29065,7 @@ x_draw_vertical_border (struct window *w)
28773 do it for frames with vertical scroll bars because either the 29065 do it for frames with vertical scroll bars because either the
28774 right scroll bar of a window, or the left scroll bar of its 29066 right scroll bar of a window, or the left scroll bar of its
28775 neighbor will suffice as a border. */ 29067 neighbor will suffice as a border. */
28776 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame))) 29068 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
28777 return; 29069 return;
28778 29070
28779 /* Note: It is necessary to redraw both the left and the right 29071 /* Note: It is necessary to redraw both the left and the right
@@ -28792,6 +29084,7 @@ x_draw_vertical_border (struct window *w)
28792 29084
28793 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1); 29085 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28794 } 29086 }
29087
28795 if (!WINDOW_LEFTMOST_P (w) 29088 if (!WINDOW_LEFTMOST_P (w)
28796 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)) 29089 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28797 { 29090 {
@@ -28808,6 +29101,44 @@ x_draw_vertical_border (struct window *w)
28808} 29101}
28809 29102
28810 29103
29104/* Draw window dividers for window W. */
29105
29106void
29107x_draw_right_divider (struct window *w)
29108{
29109 struct frame *f = WINDOW_XFRAME (w);
29110
29111 if (w->mini || w->pseudo_window_p)
29112 return;
29113 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
29114 {
29115 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
29116 int x1 = WINDOW_RIGHT_EDGE_X (w);
29117 int y0 = WINDOW_TOP_EDGE_Y (w);
29118 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
29119
29120 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29121 }
29122}
29123
29124static void
29125x_draw_bottom_divider (struct window *w)
29126{
29127 struct frame *f = XFRAME (WINDOW_FRAME (w));
29128
29129 if (w->mini || w->pseudo_window_p)
29130 return;
29131 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
29132 {
29133 int x0 = WINDOW_LEFT_EDGE_X (w);
29134 int x1 = WINDOW_RIGHT_EDGE_X (w);
29135 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
29136 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
29137
29138 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
29139 }
29140}
29141
28811/* Redraw the part of window W intersection rectangle FR. Pixel 29142/* Redraw the part of window W intersection rectangle FR. Pixel
28812 coordinates in FR are frame-relative. Call this function with 29143 coordinates in FR are frame-relative. Call this function with
28813 input blocked. Value is non-zero if the exposure overwrites 29144 input blocked. Value is non-zero if the exposure overwrites
@@ -28839,8 +29170,8 @@ expose_window (struct window *w, XRectangle *fr)
28839 /* Frame-relative pixel rectangle of W. */ 29170 /* Frame-relative pixel rectangle of W. */
28840 wr.x = WINDOW_LEFT_EDGE_X (w); 29171 wr.x = WINDOW_LEFT_EDGE_X (w);
28841 wr.y = WINDOW_TOP_EDGE_Y (w); 29172 wr.y = WINDOW_TOP_EDGE_Y (w);
28842 wr.width = WINDOW_TOTAL_WIDTH (w); 29173 wr.width = WINDOW_PIXEL_WIDTH (w);
28843 wr.height = WINDOW_TOTAL_HEIGHT (w); 29174 wr.height = WINDOW_PIXEL_HEIGHT (w);
28844 29175
28845 if (x_intersect_rectangles (fr, &wr, &r)) 29176 if (x_intersect_rectangles (fr, &wr, &r))
28846 { 29177 {
@@ -28936,7 +29267,13 @@ expose_window (struct window *w, XRectangle *fr)
28936 fr); 29267 fr);
28937 29268
28938 /* Draw border between windows. */ 29269 /* Draw border between windows. */
28939 x_draw_vertical_border (w); 29270 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
29271 x_draw_right_divider (w);
29272 else
29273 x_draw_vertical_border (w);
29274
29275 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
29276 x_draw_bottom_divider (w);
28940 29277
28941 /* Turn the cursor on again. */ 29278 /* Turn the cursor on again. */
28942 if (cursor_cleared_p 29279 if (cursor_cleared_p
@@ -29154,13 +29491,14 @@ syms_of_xdisp (void)
29154 defsubr (&Strace_to_stderr); 29491 defsubr (&Strace_to_stderr);
29155#endif 29492#endif
29156#ifdef HAVE_WINDOW_SYSTEM 29493#ifdef HAVE_WINDOW_SYSTEM
29157 defsubr (&Stool_bar_lines_needed); 29494 defsubr (&Stool_bar_height);
29158 defsubr (&Slookup_image_map); 29495 defsubr (&Slookup_image_map);
29159#endif 29496#endif
29160 defsubr (&Sline_pixel_height); 29497 defsubr (&Sline_pixel_height);
29161 defsubr (&Sformat_mode_line); 29498 defsubr (&Sformat_mode_line);
29162 defsubr (&Sinvisible_p); 29499 defsubr (&Sinvisible_p);
29163 defsubr (&Scurrent_bidi_paragraph_direction); 29500 defsubr (&Scurrent_bidi_paragraph_direction);
29501 defsubr (&Swindow_text_pixel_size);
29164 defsubr (&Smove_point_visually); 29502 defsubr (&Smove_point_visually);
29165 29503
29166 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook"); 29504 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
@@ -29788,12 +30126,18 @@ init_xdisp (void)
29788 echo_area_window = minibuf_window; 30126 echo_area_window = minibuf_window;
29789 30127
29790 r->top_line = FRAME_TOP_MARGIN (f); 30128 r->top_line = FRAME_TOP_MARGIN (f);
29791 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f); 30129 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
29792 r->total_cols = FRAME_COLS (f); 30130 r->total_cols = FRAME_COLS (f);
30131 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
30132 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
30133 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
29793 30134
29794 m->top_line = FRAME_LINES (f) - 1; 30135 m->top_line = FRAME_LINES (f) - 1;
29795 m->total_lines = 1; 30136 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
29796 m->total_cols = FRAME_COLS (f); 30137 m->total_cols = FRAME_COLS (f);
30138 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
30139 m->total_lines = 1;
30140 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
29797 30141
29798 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs; 30142 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29799 scratch_glyph_row.glyphs[TEXT_AREA + 1] 30143 scratch_glyph_row.glyphs[TEXT_AREA + 1]
diff --git a/src/xfaces.c b/src/xfaces.c
index b9ddddfd9e2..8a74c92b10d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -323,6 +323,7 @@ Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
323static Lisp_Object Qborder, Qmouse, Qmenu; 323static Lisp_Object Qborder, Qmouse, Qmenu;
324Lisp_Object Qmode_line_inactive; 324Lisp_Object Qmode_line_inactive;
325static Lisp_Object Qvertical_border; 325static Lisp_Object Qvertical_border;
326static Lisp_Object Qwindow_divider;
326 327
327/* The symbol `face-alias'. A symbols having that property is an 328/* The symbol `face-alias'. A symbols having that property is an
328 alias for another face. Value of the property is the name of 329 alias for another face. Value of the property is the name of
@@ -911,8 +912,6 @@ load_pixmap (struct frame *f, Lisp_Object name)
911 X Colors 912 X Colors
912 ***********************************************************************/ 913 ***********************************************************************/
913 914
914#define NEAR_SAME_COLOR_THRESHOLD 30000
915
916/* Parse RGB_LIST, and fill in the RGB fields of COLOR. 915/* Parse RGB_LIST, and fill in the RGB fields of COLOR.
917 RGB_LIST should contain (at least) 3 lisp integers. 916 RGB_LIST should contain (at least) 3 lisp integers.
918 Return 0 if there's a problem with RGB_LIST, otherwise return 1. */ 917 Return 0 if there's a problem with RGB_LIST, otherwise return 1. */
@@ -1264,6 +1263,8 @@ load_color (struct frame *f, struct face *face, Lisp_Object name,
1264 1263
1265#ifdef HAVE_WINDOW_SYSTEM 1264#ifdef HAVE_WINDOW_SYSTEM
1266 1265
1266#define NEAR_SAME_COLOR_THRESHOLD 30000
1267
1267/* Load colors for face FACE which is used on frame F. Colors are 1268/* Load colors for face FACE which is used on frame F. Colors are
1268 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX 1269 specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
1269 of ATTRS. If the background color specified is not supported on F, 1270 of ATTRS. If the background color specified is not supported on F,
@@ -5246,6 +5247,7 @@ realize_basic_faces (struct frame *f)
5246 realize_named_face (f, Qmouse, MOUSE_FACE_ID); 5247 realize_named_face (f, Qmouse, MOUSE_FACE_ID);
5247 realize_named_face (f, Qmenu, MENU_FACE_ID); 5248 realize_named_face (f, Qmenu, MENU_FACE_ID);
5248 realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID); 5249 realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
5250 realize_named_face (f, Qwindow_divider, WINDOW_DIVIDER_FACE_ID);
5249 5251
5250 /* Reflect changes in the `menu' face in menu bars. */ 5252 /* Reflect changes in the `menu' face in menu bars. */
5251 if (FRAME_FACE_CACHE (f)->menu_face_changed_p) 5253 if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
@@ -6448,6 +6450,7 @@ syms_of_xfaces (void)
6448 DEFSYM (Qmouse, "mouse"); 6450 DEFSYM (Qmouse, "mouse");
6449 DEFSYM (Qmode_line_inactive, "mode-line-inactive"); 6451 DEFSYM (Qmode_line_inactive, "mode-line-inactive");
6450 DEFSYM (Qvertical_border, "vertical-border"); 6452 DEFSYM (Qvertical_border, "vertical-border");
6453 DEFSYM (Qwindow_divider, "window-divider");
6451 DEFSYM (Qtty_color_desc, "tty-color-desc"); 6454 DEFSYM (Qtty_color_desc, "tty-color-desc");
6452 DEFSYM (Qtty_color_standard_values, "tty-color-standard-values"); 6455 DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
6453 DEFSYM (Qtty_color_by_index, "tty-color-by-index"); 6456 DEFSYM (Qtty_color_by_index, "tty-color-by-index");
diff --git a/src/xfns.c b/src/xfns.c
index 46f377042f6..3c8df12f8c5 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -612,7 +612,7 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
612 struct x_output *x = f->output_data.x; 612 struct x_output *x = f->output_data.x;
613 Display *dpy = FRAME_X_DISPLAY (f); 613 Display *dpy = FRAME_X_DISPLAY (f);
614 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor; 614 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
615 Cursor hourglass_cursor, horizontal_drag_cursor; 615 Cursor hourglass_cursor, horizontal_drag_cursor, vertical_drag_cursor;
616 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); 616 unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
617 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f); 617 unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
618 618
@@ -680,7 +680,7 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
680 680
681 if (!NILP (Vx_window_horizontal_drag_shape)) 681 if (!NILP (Vx_window_horizontal_drag_shape))
682 { 682 {
683 CHECK_NUMBER (Vx_window_horizontal_drag_shape); 683 CHECK_TYPE_RANGED_INTEGER (unsigned, Vx_window_horizontal_drag_shape);
684 horizontal_drag_cursor 684 horizontal_drag_cursor
685 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape)); 685 = XCreateFontCursor (dpy, XINT (Vx_window_horizontal_drag_shape));
686 } 686 }
@@ -688,6 +688,16 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
688 horizontal_drag_cursor 688 horizontal_drag_cursor
689 = XCreateFontCursor (dpy, XC_sb_h_double_arrow); 689 = XCreateFontCursor (dpy, XC_sb_h_double_arrow);
690 690
691 if (!NILP (Vx_window_vertical_drag_shape))
692 {
693 CHECK_NUMBER (Vx_window_vertical_drag_shape);
694 vertical_drag_cursor
695 = XCreateFontCursor (dpy, XINT (Vx_window_vertical_drag_shape));
696 }
697 else
698 vertical_drag_cursor
699 = XCreateFontCursor (dpy, XC_sb_v_double_arrow);
700
691 /* Check and report errors with the above calls. */ 701 /* Check and report errors with the above calls. */
692 x_check_errors (dpy, "can't set cursor shape: %s"); 702 x_check_errors (dpy, "can't set cursor shape: %s");
693 x_uncatch_errors (); 703 x_uncatch_errors ();
@@ -745,6 +755,11 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
745 XFreeCursor (dpy, x->horizontal_drag_cursor); 755 XFreeCursor (dpy, x->horizontal_drag_cursor);
746 x->horizontal_drag_cursor = horizontal_drag_cursor; 756 x->horizontal_drag_cursor = horizontal_drag_cursor;
747 757
758 if (vertical_drag_cursor != x->vertical_drag_cursor
759 && x->vertical_drag_cursor != 0)
760 XFreeCursor (dpy, x->vertical_drag_cursor);
761 x->vertical_drag_cursor = vertical_drag_cursor;
762
748 XFlush (dpy); 763 XFlush (dpy);
749 unblock_input (); 764 unblock_input ();
750 765
@@ -963,6 +978,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
963 978
964#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 979#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
965 FRAME_MENU_BAR_LINES (f) = 0; 980 FRAME_MENU_BAR_LINES (f) = 0;
981 FRAME_MENU_BAR_HEIGHT (f) = 0;
966 if (nlines) 982 if (nlines)
967 { 983 {
968 FRAME_EXTERNAL_MENU_BAR (f) = 1; 984 FRAME_EXTERNAL_MENU_BAR (f) = 1;
@@ -980,7 +996,8 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
980 } 996 }
981#else /* not USE_X_TOOLKIT && not USE_GTK */ 997#else /* not USE_X_TOOLKIT && not USE_GTK */
982 FRAME_MENU_BAR_LINES (f) = nlines; 998 FRAME_MENU_BAR_LINES (f) = nlines;
983 resize_frame_windows (f, FRAME_LINES (f), 0); 999 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1000 resize_frame_windows (f, FRAME_LINES (f), 0, 0);
984 1001
985 /* If the menu bar height gets changed, the internal border below 1002 /* If the menu bar height gets changed, the internal border below
986 the top margin has to be cleared. Also, if the menu bar gets 1003 the top margin has to be cleared. Also, if the menu bar gets
@@ -993,7 +1010,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
993 int y; 1010 int y;
994 1011
995 /* height can be zero here. */ 1012 /* height can be zero here. */
996 if (height > 0 && width > 0) 1013 if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
997 { 1014 {
998 y = FRAME_TOP_MARGIN_HEIGHT (f); 1015 y = FRAME_TOP_MARGIN_HEIGHT (f);
999 1016
@@ -1051,6 +1068,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1051#ifdef USE_GTK 1068#ifdef USE_GTK
1052 1069
1053 FRAME_TOOL_BAR_LINES (f) = 0; 1070 FRAME_TOOL_BAR_LINES (f) = 0;
1071 FRAME_TOOL_BAR_HEIGHT (f) = 0;
1054 if (nlines) 1072 if (nlines)
1055 { 1073 {
1056 FRAME_EXTERNAL_TOOL_BAR (f) = 1; 1074 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
@@ -1083,7 +1101,8 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1083 } 1101 }
1084 1102
1085 FRAME_TOOL_BAR_LINES (f) = nlines; 1103 FRAME_TOOL_BAR_LINES (f) = nlines;
1086 resize_frame_windows (f, FRAME_LINES (f), 0); 1104 FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1105 resize_frame_windows (f, FRAME_LINES (f), 0, 0);
1087 adjust_frame_glyphs (f); 1106 adjust_frame_glyphs (f);
1088 1107
1089 /* We also have to make sure that the internal border at the top of 1108 /* We also have to make sure that the internal border at the top of
@@ -1092,7 +1111,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1092 below the tool bar if one is displayed, but is below the menu bar 1111 below the tool bar if one is displayed, but is below the menu bar
1093 if there isn't a tool bar. The tool bar draws into the area 1112 if there isn't a tool bar. The tool bar draws into the area
1094 below the menu bar. */ 1113 below the menu bar. */
1095 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0) 1114 if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1096 { 1115 {
1097 clear_frame (f); 1116 clear_frame (f);
1098 clear_current_matrices (f); 1117 clear_current_matrices (f);
@@ -1471,13 +1490,13 @@ x_set_scroll_bar_default_width (struct frame *f)
1471 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + wid - 1) / wid; 1490 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + wid - 1) / wid;
1472 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw; 1491 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
1473#else 1492#else
1474 /* Make the actual width at least 14 pixels and a multiple of a 1493 /* Make the actual width 16 pixels and a multiple of a
1475 character width. */ 1494 character width. */
1476 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid; 1495 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (16 + wid - 1) / wid;
1477 1496
1478 /* Use all of that space (aside from required margins) for the 1497 /* Use all of that space (aside from required margins) for the
1479 scroll bar. */ 1498 scroll bar. */
1480 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 0; 1499 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 16;
1481#endif 1500#endif
1482} 1501}
1483 1502
@@ -3050,6 +3069,22 @@ This function is an internal primitive--use `make-frame' instead. */)
3050 happen. */ 3069 happen. */
3051 init_frame_faces (f); 3070 init_frame_faces (f);
3052 3071
3072#ifdef USE_GTK
3073 /* PXW: This is a duplicate from below. We have to do it here since
3074 otherwise x_set_tool_bar_lines will work with the character sizes
3075 installed by init_frame_faces while the frame's pixel size is still
3076 calculated from a character size of 1 and we subsequently hit the
3077 eassert (height >= 0) assertion in window_box_height. The
3078 non-pixelwise code apparently worked around this because it had one
3079 frame line vs one toolbar line which left us with a zero root
3080 window height which was obviously wrong as well ... */
3081 width = FRAME_TEXT_WIDTH (f);
3082 height = FRAME_TEXT_HEIGHT (f);
3083 FRAME_TEXT_HEIGHT (f) = 0;
3084 SET_FRAME_WIDTH (f, 0);
3085 change_frame_size (f, width, height, 1, 0, 0, 1);
3086#endif /* USE_GTK */
3087
3053 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't 3088 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3054 look up the X resources controlling the menu-bar and tool-bar 3089 look up the X resources controlling the menu-bar and tool-bar
3055 here; they are processed specially at startup, and reflected in 3090 here; they are processed specially at startup, and reflected in
@@ -3130,12 +3165,11 @@ This function is an internal primitive--use `make-frame' instead. */)
3130 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. 3165 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
3131 Change will not be effected unless different from the current 3166 Change will not be effected unless different from the current
3132 FRAME_LINES (f). */ 3167 FRAME_LINES (f). */
3133 width = FRAME_COLS (f); 3168 width = FRAME_TEXT_WIDTH (f);
3134 height = FRAME_LINES (f); 3169 height = FRAME_TEXT_HEIGHT (f);
3135 3170 FRAME_TEXT_HEIGHT (f) = 0;
3136 SET_FRAME_COLS (f, 0); 3171 SET_FRAME_WIDTH (f, 0);
3137 FRAME_LINES (f) = 0; 3172 change_frame_size (f, width, height, 1, 0, 0, 1);
3138 change_frame_size (f, height, width, 1, 0, 0);
3139 3173
3140#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 3174#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3141 /* Create the menu bar. */ 3175 /* Create the menu bar. */
@@ -4918,6 +4952,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
4918 x_default_parameter (f, parms, Qinternal_border_width, make_number (1), 4952 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
4919 "internalBorderWidth", "internalBorderWidth", 4953 "internalBorderWidth", "internalBorderWidth",
4920 RES_TYPE_NUMBER); 4954 RES_TYPE_NUMBER);
4955 x_default_parameter (f, parms, Qright_divider_width, make_number (0),
4956 NULL, NULL, RES_TYPE_NUMBER);
4957 x_default_parameter (f, parms, Qbottom_divider_width, make_number (0),
4958 NULL, NULL, RES_TYPE_NUMBER);
4921 4959
4922 /* Also do the stuff which must be set before the window exists. */ 4960 /* Also do the stuff which must be set before the window exists. */
4923 x_default_parameter (f, parms, Qforeground_color, build_string ("black"), 4961 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
@@ -5000,7 +5038,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5000 height = FRAME_LINES (f); 5038 height = FRAME_LINES (f);
5001 SET_FRAME_COLS (f, 0); 5039 SET_FRAME_COLS (f, 0);
5002 FRAME_LINES (f) = 0; 5040 FRAME_LINES (f) = 0;
5003 change_frame_size (f, height, width, 1, 0, 0); 5041 change_frame_size (f, width, height, 1, 0, 0, 0);
5004 5042
5005 /* Add `tooltip' frame parameter's default value. */ 5043 /* Add `tooltip' frame parameter's default value. */
5006 if (NILP (Fframe_parameter (frame, Qtooltip))) 5044 if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -5260,6 +5298,10 @@ Text larger than the specified size is clipped. */)
5260 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms); 5298 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5261 if (NILP (Fassq (Qborder_width, parms))) 5299 if (NILP (Fassq (Qborder_width, parms)))
5262 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms); 5300 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5301 if (NILP (Fassq (Qbottom_divider_width, parms)))
5302 parms = Fcons (Fcons (Qbottom_divider_width, make_number (0)), parms);
5303 if (NILP (Fassq (Qright_divider_width, parms)))
5304 parms = Fcons (Fcons (Qright_divider_width, make_number (0)), parms);
5263 if (NILP (Fassq (Qborder_color, parms))) 5305 if (NILP (Fassq (Qborder_color, parms)))
5264 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms); 5306 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5265 if (NILP (Fassq (Qbackground_color, parms))) 5307 if (NILP (Fassq (Qbackground_color, parms)))
@@ -5275,6 +5317,8 @@ Text larger than the specified size is clipped. */)
5275 w = XWINDOW (FRAME_ROOT_WINDOW (f)); 5317 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5276 w->left_col = 0; 5318 w->left_col = 0;
5277 w->top_line = 0; 5319 w->top_line = 0;
5320 w->pixel_left = 0;
5321 w->pixel_top = 0;
5278 5322
5279 if (CONSP (Vx_max_tooltip_size) 5323 if (CONSP (Vx_max_tooltip_size)
5280 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX) 5324 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
@@ -5289,6 +5333,9 @@ Text larger than the specified size is clipped. */)
5289 w->total_lines = 40; 5333 w->total_lines = 40;
5290 } 5334 }
5291 5335
5336 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (f);
5337 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (f);
5338
5292 FRAME_TOTAL_COLS (f) = w->total_cols; 5339 FRAME_TOTAL_COLS (f) = w->total_cols;
5293 adjust_frame_glyphs (f); 5340 adjust_frame_glyphs (f);
5294 w->pseudo_window_p = 1; 5341 w->pseudo_window_p = 1;
@@ -5355,9 +5402,11 @@ Text larger than the specified size is clipped. */)
5355 { 5402 {
5356 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, 5403 /* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
5357 not in pixels. */ 5404 not in pixels. */
5405 w->pixel_width = width;
5358 width /= WINDOW_FRAME_COLUMN_WIDTH (w); 5406 width /= WINDOW_FRAME_COLUMN_WIDTH (w);
5359 w->total_cols = width; 5407 w->total_cols = width;
5360 FRAME_TOTAL_COLS (f) = width; 5408 FRAME_TOTAL_COLS (f) = width;
5409 SET_FRAME_WIDTH (f, width);
5361 adjust_frame_glyphs (f); 5410 adjust_frame_glyphs (f);
5362 clear_glyph_matrix (w->desired_matrix); 5411 clear_glyph_matrix (w->desired_matrix);
5363 clear_glyph_matrix (w->current_matrix); 5412 clear_glyph_matrix (w->current_matrix);
@@ -5958,6 +6007,8 @@ frame_parm_handler x_frame_parm_handlers[] =
5958 x_set_icon_name, 6007 x_set_icon_name,
5959 x_set_icon_type, 6008 x_set_icon_type,
5960 x_set_internal_border_width, 6009 x_set_internal_border_width,
6010 x_set_right_divider_width,
6011 x_set_bottom_divider_width,
5961 x_set_menu_bar_lines, 6012 x_set_menu_bar_lines,
5962 x_set_mouse_color, 6013 x_set_mouse_color,
5963 x_explicitly_set_name, 6014 x_explicitly_set_name,
@@ -6041,6 +6092,13 @@ This variable takes effect when you create a new frame
6041or when you set the mouse color. */); 6092or when you set the mouse color. */);
6042 Vx_window_horizontal_drag_shape = Qnil; 6093 Vx_window_horizontal_drag_shape = Qnil;
6043 6094
6095 DEFVAR_LISP ("x-window-vertical-drag-cursor",
6096 Vx_window_vertical_drag_shape,
6097 doc: /* Pointer shape to use for indicating a window can be dragged vertically.
6098This variable takes effect when you create a new frame
6099or when you set the mouse color. */);
6100 Vx_window_vertical_drag_shape = Qnil;
6101
6044 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel, 6102 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
6045 doc: /* A string indicating the foreground color of the cursor box. */); 6103 doc: /* A string indicating the foreground color of the cursor box. */);
6046 Vx_cursor_fore_pixel = Qnil; 6104 Vx_cursor_fore_pixel = Qnil;
diff --git a/src/xmenu.c b/src/xmenu.c
index b2c7fb5f073..d587610fdd7 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1168,7 +1168,7 @@ free_frame_menubar (struct frame *f)
1168 if (x1 == 0 && y1 == 0) 1168 if (x1 == 0 && y1 == 0)
1169 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL); 1169 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
1170#endif 1170#endif
1171 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 1171 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
1172 } 1172 }
1173 unblock_input (); 1173 unblock_input ();
1174 } 1174 }
@@ -2440,11 +2440,7 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
2440 doc: /* Return t if a menu or popup dialog is active. */) 2440 doc: /* Return t if a menu or popup dialog is active. */)
2441 (void) 2441 (void)
2442{ 2442{
2443#ifdef HAVE_MENUS
2444 return (popup_activated ()) ? Qt : Qnil; 2443 return (popup_activated ()) ? Qt : Qnil;
2445#else
2446 return Qnil;
2447#endif /* HAVE_MENUS */
2448} 2444}
2449 2445
2450void 2446void
diff --git a/src/xrdb.c b/src/xrdb.c
index ea823b2b313..7220915e631 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -179,7 +179,7 @@ magic_db (const char *string, ptrdiff_t string_len, const char *class,
179 else 179 else
180 next = p, next_len = 1; 180 next = p, next_len = 1;
181 181
182 /* Do we have room for this component followed by a '\0' ? */ 182 /* Do we have room for this component followed by a '\0'? */
183 if (path_size - path_len <= next_len) 183 if (path_size - path_len <= next_len)
184 { 184 {
185 if (min (PTRDIFF_MAX, SIZE_MAX) / 2 - 1 - path_len < next_len) 185 if (min (PTRDIFF_MAX, SIZE_MAX) / 2 - 1 - path_len < next_len)
diff --git a/src/xterm.c b/src/xterm.c
index 446b2cf1e45..e8e69c666ee 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -98,7 +98,7 @@ extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
98 98
99#ifdef USE_TOOLKIT_SCROLL_BARS 99#ifdef USE_TOOLKIT_SCROLL_BARS
100#if defined USE_MOTIF 100#if defined USE_MOTIF
101#include <Xm/Xm.h> /* for LESSTIF_VERSION */ 101#include <Xm/Xm.h> /* For LESSTIF_VERSION */
102#include <Xm/ScrollBar.h> 102#include <Xm/ScrollBar.h>
103#else /* !USE_MOTIF i.e. use Xaw */ 103#else /* !USE_MOTIF i.e. use Xaw */
104 104
@@ -165,11 +165,6 @@ static bool toolkit_scroll_bar_interaction;
165 165
166static Time ignore_next_mouse_click_timeout; 166static Time ignore_next_mouse_click_timeout;
167 167
168/* Incremented by XTread_socket whenever it really tries to read
169 events. */
170
171static int volatile input_signal_count;
172
173/* Used locally within XTread_socket. */ 168/* Used locally within XTread_socket. */
174 169
175static int x_noop_count; 170static int x_noop_count;
@@ -214,7 +209,7 @@ enum xembed_message
214 }; 209 };
215 210
216static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); 211static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
217static void x_set_window_size_1 (struct frame *, int, int, int); 212static void x_set_window_size_1 (struct frame *, int, int, int, bool);
218static void x_raise_frame (struct frame *); 213static void x_raise_frame (struct frame *);
219static void x_lower_frame (struct frame *); 214static void x_lower_frame (struct frame *);
220static const XColor *x_color_cells (Display *, int *); 215static const XColor *x_color_cells (Display *, int *);
@@ -253,9 +248,6 @@ static void x_sync_with_move (struct frame *, int, int, int);
253static int handle_one_xevent (struct x_display_info *, 248static int handle_one_xevent (struct x_display_info *,
254 const XEvent *, int *, 249 const XEvent *, int *,
255 struct input_event *); 250 struct input_event *);
256#ifdef USE_GTK
257static int x_dispatch_event (XEvent *, Display *);
258#endif
259/* Don't declare this _Noreturn because we want no 251/* Don't declare this _Noreturn because we want no
260 interference with debugging failing X calls. */ 252 interference with debugging failing X calls. */
261static void x_connection_closed (Display *, const char *); 253static void x_connection_closed (Display *, const char *);
@@ -509,6 +501,23 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
509 f->output_data.x->normal_gc, x, y0, x, y1); 501 f->output_data.x->normal_gc, x, y0, x, y1);
510} 502}
511 503
504/* Draw a window divider from (x0,y0) to (x1,y1) */
505
506static void
507x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
508{
509 struct frame *f = XFRAME (WINDOW_FRAME (w));
510 struct face *face;
511
512 face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
513 if (face)
514 XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
515 face->foreground);
516
517 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
518 f->output_data.x->normal_gc, x0, y0, x1 - x0, y1 - y0);
519}
520
512/* End update of window W. 521/* End update of window W.
513 522
514 Draw vertical borders between horizontally adjacent windows, and 523 Draw vertical borders between horizontally adjacent windows, and
@@ -536,7 +545,12 @@ x_update_window_end (struct window *w, bool cursor_on_p,
536 w->output_cursor.x, w->output_cursor.y); 545 w->output_cursor.x, w->output_cursor.y);
537 546
538 if (draw_window_fringes (w, 1)) 547 if (draw_window_fringes (w, 1))
539 x_draw_vertical_border (w); 548 {
549 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
550 x_draw_right_divider (w);
551 else
552 x_draw_vertical_border (w);
553 }
540 554
541 unblock_input (); 555 unblock_input ();
542 } 556 }
@@ -631,10 +645,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
631 /* Must clip because of partially visible lines. */ 645 /* Must clip because of partially visible lines. */
632 x_clip_to_row (w, row, ANY_AREA, gc); 646 x_clip_to_row (w, row, ANY_AREA, gc);
633 647
634 if (!p->overlay_p) 648 if (p->bx >= 0 && !p->overlay_p)
635 { 649 {
636 int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
637
638 /* In case the same realized face is used for fringes and 650 /* In case the same realized face is used for fringes and
639 for something displayed in the text (e.g. face `region' on 651 for something displayed in the text (e.g. face `region' on
640 mono-displays, the fill style may have been changed to 652 mono-displays, the fill style may have been changed to
@@ -644,55 +656,8 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
644 else 656 else
645 XSetForeground (display, face->gc, face->background); 657 XSetForeground (display, face->gc, face->background);
646 658
647#ifdef USE_TOOLKIT_SCROLL_BARS 659 XFillRectangle (display, window, face->gc,
648 /* If the fringe is adjacent to the left (right) scroll bar of a 660 p->bx, p->by, p->nx, p->ny);
649 leftmost (rightmost, respectively) window, then extend its
650 background to the gap between the fringe and the bar. */
651 if ((WINDOW_LEFTMOST_P (w)
652 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
653 || (WINDOW_RIGHTMOST_P (w)
654 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
655 {
656 int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
657
658 if (sb_width > 0)
659 {
660 int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
661 int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
662 * FRAME_COLUMN_WIDTH (f));
663
664 if (bx < 0)
665 {
666 /* Bitmap fills the fringe. */
667 if (bar_area_x + bar_area_width == p->x)
668 bx = bar_area_x + sb_width;
669 else if (p->x + p->wd == bar_area_x)
670 bx = bar_area_x;
671 if (bx >= 0)
672 {
673 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
674
675 nx = bar_area_width - sb_width;
676 by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
677 row->y));
678 ny = row->visible_height;
679 }
680 }
681 else
682 {
683 if (bar_area_x + bar_area_width == bx)
684 {
685 bx = bar_area_x + sb_width;
686 nx += bar_area_width - sb_width;
687 }
688 else if (bx + nx == bar_area_x)
689 nx += bar_area_width - sb_width;
690 }
691 }
692 }
693#endif
694 if (bx >= 0 && nx > 0)
695 XFillRectangle (display, window, face->gc, bx, by, nx, ny);
696 661
697 if (!face->stipple) 662 if (!face->stipple)
698 XSetForeground (display, face->gc, face->foreground); 663 XSetForeground (display, face->gc, face->foreground);
@@ -2947,7 +2912,7 @@ XTflash (struct frame *f)
2947#endif 2912#endif
2948 { 2913 {
2949 /* Get the height not including a menu bar widget. */ 2914 /* Get the height not including a menu bar widget. */
2950 int height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f)); 2915 int height = FRAME_PIXEL_HEIGHT (f);
2951 /* Height of each line to flash. */ 2916 /* Height of each line to flash. */
2952 int flash_height = FRAME_LINE_HEIGHT (f); 2917 int flash_height = FRAME_LINE_HEIGHT (f);
2953 /* These will be the left and right margins of the rectangles. */ 2918 /* These will be the left and right margins of the rectangles. */
@@ -3107,34 +3072,6 @@ x_scroll_run (struct window *w, struct run *run)
3107 fringe of W. */ 3072 fringe of W. */
3108 window_box (w, ANY_AREA, &x, &y, &width, &height); 3073 window_box (w, ANY_AREA, &x, &y, &width, &height);
3109 3074
3110#ifdef USE_TOOLKIT_SCROLL_BARS
3111 /* If the fringe is adjacent to the left (right) scroll bar of a
3112 leftmost (rightmost, respectively) window, then extend its
3113 background to the gap between the fringe and the bar. */
3114 if ((WINDOW_LEFTMOST_P (w)
3115 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
3116 || (WINDOW_RIGHTMOST_P (w)
3117 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
3118 {
3119 int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
3120
3121 if (sb_width > 0)
3122 {
3123 int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
3124 int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
3125 * FRAME_COLUMN_WIDTH (f));
3126
3127 if (bar_area_x + bar_area_width == x)
3128 {
3129 x = bar_area_x + sb_width;
3130 width += bar_area_width - sb_width;
3131 }
3132 else if (x + width == bar_area_x)
3133 width += bar_area_width - sb_width;
3134 }
3135 }
3136#endif
3137
3138 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); 3075 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
3139 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); 3076 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
3140 bottom_y = y + height; 3077 bottom_y = y + height;
@@ -3528,7 +3465,7 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
3528} 3465}
3529 3466
3530 3467
3531#if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK 3468#if !defined USE_X_TOOLKIT && !defined USE_GTK
3532/* Handle an event saying the mouse has moved out of an Emacs frame. */ 3469/* Handle an event saying the mouse has moved out of an Emacs frame. */
3533 3470
3534void 3471void
@@ -4945,7 +4882,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
4945 /* Clear the area of W that will serve as a scroll bar. This is 4882 /* Clear the area of W that will serve as a scroll bar. This is
4946 for the case that a window has been split horizontally. In 4883 for the case that a window has been split horizontally. In
4947 this case, no clear_frame is generated to reduce flickering. */ 4884 this case, no clear_frame is generated to reduce flickering. */
4948 if (width > 0 && height > 0) 4885 if (width > 0 && window_box_height (w) > 0)
4949 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 4886 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
4950 left, top, width, window_box_height (w)); 4887 left, top, width, window_box_height (w));
4951 4888
@@ -4971,7 +4908,6 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
4971 bar->start = 0; 4908 bar->start = 0;
4972 bar->end = 0; 4909 bar->end = 0;
4973 bar->dragging = -1; 4910 bar->dragging = -1;
4974 bar->fringe_extended_p = 0;
4975#if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID) 4911#if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID)
4976 bar->last_seen_part = scroll_bar_nowhere; 4912 bar->last_seen_part = scroll_bar_nowhere;
4977#endif 4913#endif
@@ -5147,44 +5083,17 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5147 struct frame *f = XFRAME (w->frame); 5083 struct frame *f = XFRAME (w->frame);
5148 Lisp_Object barobj; 5084 Lisp_Object barobj;
5149 struct scroll_bar *bar; 5085 struct scroll_bar *bar;
5150 int top, height, left, sb_left, width, sb_width; 5086 int top, height, left, width;
5151 int window_y, window_height; 5087 int window_y, window_height;
5152#ifdef USE_TOOLKIT_SCROLL_BARS
5153 bool fringe_extended_p;
5154#endif
5155 5088
5156 /* Get window dimensions. */ 5089 /* Get window dimensions. */
5157 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); 5090 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
5158 top = window_y; 5091 top = window_y;
5159 width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
5160 height = window_height; 5092 height = window_height;
5161 5093
5162 /* Compute the left edge of the scroll bar area. */ 5094 /* Compute the left edge and the width of the scroll bar area. */
5163 left = WINDOW_SCROLL_BAR_AREA_X (w); 5095 left = WINDOW_SCROLL_BAR_AREA_X (w);
5164 5096 width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
5165 /* Compute the width of the scroll bar which might be less than
5166 the width of the area reserved for the scroll bar. */
5167 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0)
5168 sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
5169 else
5170 sb_width = width;
5171
5172 /* Compute the left edge of the scroll bar. */
5173#ifdef USE_TOOLKIT_SCROLL_BARS
5174 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
5175 sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
5176 else
5177 sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
5178#else
5179 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
5180 sb_left = left + width - sb_width;
5181 else
5182 sb_left = left;
5183#endif
5184
5185#ifdef USE_TOOLKIT_SCROLL_BARS
5186 fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w);
5187#endif
5188 5097
5189 /* Does the scroll bar exist yet? */ 5098 /* Does the scroll bar exist yet? */
5190 if (NILP (w->vertical_scroll_bar)) 5099 if (NILP (w->vertical_scroll_bar))
@@ -5192,18 +5101,12 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5192 if (width > 0 && height > 0) 5101 if (width > 0 && height > 0)
5193 { 5102 {
5194 block_input (); 5103 block_input ();
5195#ifdef USE_TOOLKIT_SCROLL_BARS 5104 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5196 if (fringe_extended_p) 5105 left, top, width, height);
5197 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5198 sb_left, top, sb_width, height);
5199 else
5200#endif
5201 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5202 left, top, width, height);
5203 unblock_input (); 5106 unblock_input ();
5204 } 5107 }
5205 5108
5206 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height); 5109 bar = x_scroll_bar_create (w, top, left, width, max (height, 1));
5207 } 5110 }
5208 else 5111 else
5209 { 5112 {
@@ -5214,11 +5117,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5214 5117
5215 block_input (); 5118 block_input ();
5216 5119
5217 if (sb_left != bar->left) 5120 if (left != bar->left)
5218 mask |= CWX; 5121 mask |= CWX;
5219 if (top != bar->top) 5122 if (top != bar->top)
5220 mask |= CWY; 5123 mask |= CWY;
5221 if (sb_width != bar->width) 5124 if (width != bar->width)
5222 mask |= CWWidth; 5125 mask |= CWWidth;
5223 if (height != bar->height) 5126 if (height != bar->height)
5224 mask |= CWHeight; 5127 mask |= CWHeight;
@@ -5226,55 +5129,31 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5226#ifdef USE_TOOLKIT_SCROLL_BARS 5129#ifdef USE_TOOLKIT_SCROLL_BARS
5227 5130
5228 /* Move/size the scroll bar widget. */ 5131 /* Move/size the scroll bar widget. */
5229 if (mask || bar->fringe_extended_p != fringe_extended_p) 5132 if (mask)
5230 { 5133 {
5231 /* Since toolkit scroll bars are smaller than the space reserved 5134 /* Since toolkit scroll bars are smaller than the space reserved
5232 for them on the frame, we have to clear "under" them. */ 5135 for them on the frame, we have to clear "under" them. */
5233 if (width > 0 && height > 0) 5136 if (width > 0 && height > 0)
5234 { 5137 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5235 if (fringe_extended_p) 5138 left, top, width, height);
5236 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5237 sb_left, top, sb_width, height);
5238 else
5239 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5240 left, top, width, height);
5241 }
5242#ifdef USE_GTK 5139#ifdef USE_GTK
5243 xg_update_scrollbar_pos (f, bar->x_window, top, 5140 xg_update_scrollbar_pos (f, bar->x_window, top,
5244 sb_left, sb_width, max (height, 1)); 5141 left, width, max (height, 1));
5245#else /* not USE_GTK */ 5142#else /* not USE_GTK */
5246 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar), 5143 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
5247 sb_left, top, sb_width, max (height, 1), 0); 5144 left, top, width, max (height, 1), 0);
5248#endif /* not USE_GTK */ 5145#endif /* not USE_GTK */
5249 } 5146 }
5250#else /* not USE_TOOLKIT_SCROLL_BARS */ 5147#else /* not USE_TOOLKIT_SCROLL_BARS */
5251 5148
5252 /* Clear areas not covered by the scroll bar because it's not as
5253 wide as the area reserved for it. This makes sure a
5254 previous mode line display is cleared after C-x 2 C-x 1, for
5255 example. */
5256 {
5257 int area_width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
5258 int rest = area_width - sb_width;
5259 if (rest > 0 && height > 0)
5260 {
5261 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
5262 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5263 left + area_width - rest, top, rest, height);
5264 else
5265 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5266 left, top, rest, height);
5267 }
5268 }
5269
5270 /* Move/size the scroll bar window. */ 5149 /* Move/size the scroll bar window. */
5271 if (mask) 5150 if (mask)
5272 { 5151 {
5273 XWindowChanges wc; 5152 XWindowChanges wc;
5274 5153
5275 wc.x = sb_left; 5154 wc.x = left;
5276 wc.y = top; 5155 wc.y = top;
5277 wc.width = sb_width; 5156 wc.width = width;
5278 wc.height = height; 5157 wc.height = height;
5279 XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window, 5158 XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
5280 mask, &wc); 5159 mask, &wc);
@@ -5283,17 +5162,15 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5283#endif /* not USE_TOOLKIT_SCROLL_BARS */ 5162#endif /* not USE_TOOLKIT_SCROLL_BARS */
5284 5163
5285 /* Remember new settings. */ 5164 /* Remember new settings. */
5286 bar->left = sb_left; 5165 bar->left = left;
5287 bar->top = top; 5166 bar->top = top;
5288 bar->width = sb_width; 5167 bar->width = width;
5289 bar->height = height; 5168 bar->height = height;
5290 5169
5291 unblock_input (); 5170 unblock_input ();
5292 } 5171 }
5293 5172
5294#ifdef USE_TOOLKIT_SCROLL_BARS 5173#ifdef USE_TOOLKIT_SCROLL_BARS
5295 bar->fringe_extended_p = fringe_extended_p;
5296
5297 x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); 5174 x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
5298#else /* not USE_TOOLKIT_SCROLL_BARS */ 5175#else /* not USE_TOOLKIT_SCROLL_BARS */
5299 /* Set the scroll bar's current state, unless we're currently being 5176 /* Set the scroll bar's current state, unless we're currently being
@@ -5774,7 +5651,7 @@ static void xembed_send_message (struct frame *f, Time,
5774 *FINISH is X_EVENT_DROP if event should not be passed to the toolkit. 5651 *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
5775 *EVENT is unchanged unless we're processing KeyPress event. 5652 *EVENT is unchanged unless we're processing KeyPress event.
5776 5653
5777 We return the number of characters stored into the buffer. */ 5654 We return the number of characters stored into the buffer. */
5778 5655
5779static int 5656static int
5780handle_one_xevent (struct x_display_info *dpyinfo, 5657handle_one_xevent (struct x_display_info *dpyinfo,
@@ -6202,7 +6079,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6202 SET_FRAME_GARBAGED (f); 6079 SET_FRAME_GARBAGED (f);
6203 6080
6204 /* Check if fullscreen was specified before we where mapped the 6081 /* Check if fullscreen was specified before we where mapped the
6205 first time, i.e. from the command line. */ 6082 first time, i.e. from the command line. */
6206 if (!f->output_data.x->has_been_visible) 6083 if (!f->output_data.x->has_been_visible)
6207 x_check_fullscreen (f); 6084 x_check_fullscreen (f);
6208 6085
@@ -6722,8 +6599,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6722 { 6599 {
6723#ifndef USE_X_TOOLKIT 6600#ifndef USE_X_TOOLKIT
6724#ifndef USE_GTK 6601#ifndef USE_GTK
6725 int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, event->xconfigure.height); 6602 int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width);
6726 int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, event->xconfigure.width); 6603 int height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, event->xconfigure.height);
6727 6604
6728 /* In the toolkit version, change_frame_size 6605 /* In the toolkit version, change_frame_size
6729 is called by the code that handles resizing 6606 is called by the code that handles resizing
@@ -6732,12 +6609,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6732 /* Even if the number of character rows and columns has 6609 /* Even if the number of character rows and columns has
6733 not changed, the font size may have changed, so we need 6610 not changed, the font size may have changed, so we need
6734 to check the pixel dimensions as well. */ 6611 to check the pixel dimensions as well. */
6735 if (columns != FRAME_COLS (f) 6612 if (width != FRAME_TEXT_WIDTH (f)
6736 || rows != FRAME_LINES (f) 6613 || height != FRAME_TEXT_HEIGHT (f)
6737 || event->xconfigure.width != FRAME_PIXEL_WIDTH (f) 6614 || event->xconfigure.width != FRAME_PIXEL_WIDTH (f)
6738 || event->xconfigure.height != FRAME_PIXEL_HEIGHT (f)) 6615 || event->xconfigure.height != FRAME_PIXEL_HEIGHT (f))
6739 { 6616 {
6740 change_frame_size (f, rows, columns, 0, 1, 0); 6617 change_frame_size (f, width, height, 0, 1, 0, 1);
6741 SET_FRAME_GARBAGED (f); 6618 SET_FRAME_GARBAGED (f);
6742 cancel_mouse_face (f); 6619 cancel_mouse_face (f);
6743 } 6620 }
@@ -6968,8 +6845,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6968 return count; 6845 return count;
6969} 6846}
6970 6847
6971#if defined USE_GTK || defined USE_X_TOOLKIT
6972
6973/* Handles the XEvent EVENT on display DISPLAY. 6848/* Handles the XEvent EVENT on display DISPLAY.
6974 This is used for event loops outside the normal event handling, 6849 This is used for event loops outside the normal event handling,
6975 i.e. looping while a popup menu or a dialog is posted. 6850 i.e. looping while a popup menu or a dialog is posted.
@@ -6988,8 +6863,6 @@ x_dispatch_event (XEvent *event, Display *display)
6988 6863
6989 return finish; 6864 return finish;
6990} 6865}
6991#endif
6992
6993 6866
6994/* Read events coming from the X server. 6867/* Read events coming from the X server.
6995 Return as soon as there are no more events to be read. 6868 Return as soon as there are no more events to be read.
@@ -7008,9 +6881,6 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
7008 6881
7009 block_input (); 6882 block_input ();
7010 6883
7011 /* So people can tell when we have read the available input. */
7012 input_signal_count++;
7013
7014 /* For debugging, this gives a way to fake an I/O error. */ 6884 /* For debugging, this gives a way to fake an I/O error. */
7015 if (dpyinfo == XTread_socket_fake_io_error) 6885 if (dpyinfo == XTread_socket_fake_io_error)
7016 { 6886 {
@@ -7822,12 +7692,15 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7822 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0) 7692 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
7823 { 7693 {
7824 int wid = FRAME_COLUMN_WIDTH (f); 7694 int wid = FRAME_COLUMN_WIDTH (f);
7695
7825 FRAME_CONFIG_SCROLL_BAR_COLS (f) 7696 FRAME_CONFIG_SCROLL_BAR_COLS (f)
7826 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid; 7697 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid;
7827 } 7698 }
7828 else 7699 else
7829 { 7700 {
7830 int wid = FRAME_COLUMN_WIDTH (f); 7701 int wid = FRAME_COLUMN_WIDTH (f);
7702
7703 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = 14;
7831 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid; 7704 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
7832 } 7705 }
7833 7706
@@ -7837,7 +7710,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7837 doing it because it's done in Fx_show_tip, and it leads to 7710 doing it because it's done in Fx_show_tip, and it leads to
7838 problems because the tip frame has no widget. */ 7711 problems because the tip frame has no widget. */
7839 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 7712 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
7840 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); 7713 x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
7714 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
7841 } 7715 }
7842 7716
7843#ifdef HAVE_X_I18N 7717#ifdef HAVE_X_I18N
@@ -8652,11 +8526,11 @@ x_wait_for_event (struct frame *f, int eventtype)
8652 size changes. Otherwise we leave the window gravity unchanged. */ 8526 size changes. Otherwise we leave the window gravity unchanged. */
8653 8527
8654static void 8528static void
8655x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows) 8529x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
8656{ 8530{
8657 int pixelwidth, pixelheight; 8531 int pixelwidth, pixelheight;
8658 8532
8659 check_frame_size (f, &rows, &cols); 8533 check_frame_size (f, &width, &height, pixelwise);
8660 f->scroll_bar_actual_width 8534 f->scroll_bar_actual_width
8661 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f) 8535 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
8662 ? 0 8536 ? 0
@@ -8664,9 +8538,11 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
8664 8538
8665 compute_fringe_widths (f, 0); 8539 compute_fringe_widths (f, 0);
8666 8540
8667 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols) 8541 pixelwidth =
8542 (pixelwise ? width : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width))
8668 + FRAME_TOOLBAR_WIDTH (f); 8543 + FRAME_TOOLBAR_WIDTH (f);
8669 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows) 8544 pixelheight =
8545 (pixelwise ? height : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))
8670 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); 8546 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
8671 8547
8672 if (change_gravity) f->win_gravity = NorthWestGravity; 8548 if (change_gravity) f->win_gravity = NorthWestGravity;
@@ -8702,7 +8578,7 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
8702 x_wait_for_event (f, ConfigureNotify); 8578 x_wait_for_event (f, ConfigureNotify);
8703 else 8579 else
8704 { 8580 {
8705 change_frame_size (f, rows, cols, 0, 1, 0); 8581 change_frame_size (f, width, height, 0, 1, 0, 1);
8706 FRAME_PIXEL_WIDTH (f) = pixelwidth; 8582 FRAME_PIXEL_WIDTH (f) = pixelwidth;
8707 FRAME_PIXEL_HEIGHT (f) = pixelheight; 8583 FRAME_PIXEL_HEIGHT (f) = pixelheight;
8708 x_sync (f); 8584 x_sync (f);
@@ -8716,17 +8592,19 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int cols, int rows)
8716 Otherwise we leave the window gravity unchanged. */ 8592 Otherwise we leave the window gravity unchanged. */
8717 8593
8718void 8594void
8719x_set_window_size (struct frame *f, int change_gravity, int cols, int rows) 8595x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
8720{ 8596{
8721 block_input (); 8597 block_input ();
8722 8598
8599 check_frame_size (f, &width, &height, pixelwise);
8600
8723 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 8601 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
8724 { 8602 {
8725 int r, c; 8603 int text_width, text_height;
8726 8604
8727 /* When the frame is maximized/fullscreen or running under for 8605 /* When the frame is maximized/fullscreen or running under for
8728 example Xmonad, x_set_window_size_1 will be a no-op. 8606 example Xmonad, x_set_window_size_1 will be a no-op.
8729 In that case, the right thing to do is extend rows/cols to 8607 In that case, the right thing to do is extend rows/width to
8730 the current frame size. We do that first if x_set_window_size_1 8608 the current frame size. We do that first if x_set_window_size_1
8731 turns out to not be a no-op (there is no way to know). 8609 turns out to not be a no-op (there is no way to know).
8732 The size will be adjusted again if the frame gets a 8610 The size will be adjusted again if the frame gets a
@@ -8737,23 +8615,27 @@ x_set_window_size (struct frame *f, int change_gravity, int cols, int rows)
8737 is however. */ 8615 is however. */
8738 pixelh -= FRAME_MENUBAR_HEIGHT (f); 8616 pixelh -= FRAME_MENUBAR_HEIGHT (f);
8739#endif 8617#endif
8740 r = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelh); 8618 text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, FRAME_PIXEL_WIDTH (f));
8619 text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelh);
8741 /* Update f->scroll_bar_actual_width because it is used in 8620 /* Update f->scroll_bar_actual_width because it is used in
8742 FRAME_PIXEL_WIDTH_TO_TEXT_COLS. */ 8621 FRAME_PIXEL_WIDTH_TO_TEXT_COLS. */
8743 f->scroll_bar_actual_width 8622 f->scroll_bar_actual_width
8744 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f); 8623 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
8745 c = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, FRAME_PIXEL_WIDTH (f)); 8624 change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
8746 change_frame_size (f, r, c, 0, 1, 0);
8747 } 8625 }
8748 8626
8749#ifdef USE_GTK 8627#ifdef USE_GTK
8750 if (FRAME_GTK_WIDGET (f)) 8628 if (FRAME_GTK_WIDGET (f))
8751 xg_frame_set_char_size (f, cols, rows); 8629 if (! pixelwise)
8630 xg_frame_set_char_size (f, width * FRAME_COLUMN_WIDTH (f),
8631 height * FRAME_LINE_HEIGHT (f));
8632 else
8633 xg_frame_set_char_size (f, width, height);
8752 else 8634 else
8753 x_set_window_size_1 (f, change_gravity, cols, rows); 8635 x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
8754#else /* not USE_GTK */ 8636#else /* not USE_GTK */
8755 8637
8756 x_set_window_size_1 (f, change_gravity, cols, rows); 8638 x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
8757 8639
8758#endif /* not USE_GTK */ 8640#endif /* not USE_GTK */
8759 8641
@@ -8929,9 +8811,6 @@ void
8929x_make_frame_visible (struct frame *f) 8811x_make_frame_visible (struct frame *f)
8930{ 8812{
8931 int original_top, original_left; 8813 int original_top, original_left;
8932 int retry_count = 2;
8933
8934 retry:
8935 8814
8936 block_input (); 8815 block_input ();
8937 8816
@@ -8980,7 +8859,6 @@ x_make_frame_visible (struct frame *f)
8980 so that incoming events are handled. */ 8859 so that incoming events are handled. */
8981 { 8860 {
8982 Lisp_Object frame; 8861 Lisp_Object frame;
8983 int count;
8984 /* This must be before UNBLOCK_INPUT 8862 /* This must be before UNBLOCK_INPUT
8985 since events that arrive in response to the actions above 8863 since events that arrive in response to the actions above
8986 will set it when they are handled. */ 8864 will set it when they are handled. */
@@ -9034,46 +8912,18 @@ x_make_frame_visible (struct frame *f)
9034 8912
9035 XSETFRAME (frame, f); 8913 XSETFRAME (frame, f);
9036 8914
9037 /* Wait until the frame is visible. Process X events until a 8915 /* Process X events until a MapNotify event has been seen. */
9038 MapNotify event has been seen, or until we think we won't get a 8916 while (!FRAME_VISIBLE_P (f))
9039 MapNotify at all.. */
9040 for (count = input_signal_count + 10;
9041 input_signal_count < count && !FRAME_VISIBLE_P (f);)
9042 { 8917 {
9043 /* Force processing of queued events. */ 8918 /* Force processing of queued events. */
9044 x_sync (f); 8919 x_sync (f);
9045 8920 if (XPending (FRAME_X_DISPLAY (f)))
9046 /* Machines that do polling rather than SIGIO have been
9047 observed to go into a busy-wait here. So we'll fake an
9048 alarm signal to let the handler know that there's something
9049 to be read. We used to raise a real alarm, but it seems
9050 that the handler isn't always enabled here. This is
9051 probably a bug. */
9052 if (input_polling_used ())
9053 { 8921 {
9054 /* It could be confusing if a real alarm arrives while 8922 XEvent xev;
9055 processing the fake one. Turn it off and let the 8923 XNextEvent (FRAME_X_DISPLAY (f), &xev);
9056 handler reset it. */ 8924 x_dispatch_event (&xev, FRAME_X_DISPLAY (f));
9057 int old_poll_suppress_count = poll_suppress_count;
9058 poll_suppress_count = 1;
9059 poll_for_input_1 ();
9060 poll_suppress_count = old_poll_suppress_count;
9061 } 8925 }
9062 } 8926 }
9063
9064 /* 2000-09-28: In
9065
9066 (let ((f (selected-frame)))
9067 (iconify-frame f)
9068 (raise-frame f))
9069
9070 the frame is not raised with various window managers on
9071 FreeBSD, GNU/Linux and Solaris. It turns out that, for some
9072 unknown reason, the call to XtMapWidget is completely ignored.
9073 Mapping the widget a second time works. */
9074
9075 if (!FRAME_VISIBLE_P (f) && --retry_count != 0)
9076 goto retry;
9077 } 8927 }
9078} 8928}
9079 8929
@@ -9439,7 +9289,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
9439 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); 9289 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
9440 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); 9290 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
9441 9291
9442 check_frame_size (f, &min_rows, &min_cols); 9292 check_frame_size (f, &min_cols, &min_rows, 0);
9443 9293
9444 /* The window manager uses the base width hints to calculate the 9294 /* The window manager uses the base width hints to calculate the
9445 current number of rows and columns in the frame while 9295 current number of rows and columns in the frame while
@@ -10352,6 +10202,7 @@ static struct redisplay_interface x_redisplay_interface =
10352 x_clear_frame_area, 10202 x_clear_frame_area,
10353 x_draw_window_cursor, 10203 x_draw_window_cursor,
10354 x_draw_vertical_window_border, 10204 x_draw_vertical_window_border,
10205 x_draw_window_divider,
10355 x_shift_glyphs_for_insert 10206 x_shift_glyphs_for_insert
10356 }; 10207 };
10357 10208
diff --git a/src/xterm.h b/src/xterm.h
index 753debff1bb..3d954fb8600 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -84,11 +84,6 @@ typedef GtkWidget *xt_or_gtk_widget;
84#define WHITE_PIX_DEFAULT(f) \ 84#define WHITE_PIX_DEFAULT(f) \
85 WhitePixel (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f)) 85 WhitePixel (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))
86 86
87#define FONT_WIDTH(f) ((f)->max_width)
88#define FONT_HEIGHT(f) ((f)->ascent + (f)->descent)
89#define FONT_BASE(f) ((f)->ascent)
90#define FONT_DESCENT(f) ((f)->descent)
91
92/* The mask of events that text windows always want to receive. This 87/* The mask of events that text windows always want to receive. This
93 includes mouse movement events, since handling the mouse-font text property 88 includes mouse movement events, since handling the mouse-font text property
94 means that we must track mouse motion all the time. */ 89 means that we must track mouse motion all the time. */
@@ -549,6 +544,7 @@ struct x_output
549 Cursor hand_cursor; 544 Cursor hand_cursor;
550 Cursor hourglass_cursor; 545 Cursor hourglass_cursor;
551 Cursor horizontal_drag_cursor; 546 Cursor horizontal_drag_cursor;
547 Cursor vertical_drag_cursor;
552 Cursor current_cursor; 548 Cursor current_cursor;
553 549
554 /* Window whose cursor is hourglass_cursor. This window is temporarily 550 /* Window whose cursor is hourglass_cursor. This window is temporarily
@@ -811,10 +807,6 @@ struct scroll_bar
811 /* Last scroll bar part seen in xaw_jump_callback and xaw_scroll_callback. */ 807 /* Last scroll bar part seen in xaw_jump_callback and xaw_scroll_callback. */
812 enum scroll_bar_part last_seen_part; 808 enum scroll_bar_part last_seen_part;
813#endif 809#endif
814
815 /* 1 if the background of the fringe that is adjacent to a scroll
816 bar is extended to the gap between the fringe and the bar. */
817 unsigned fringe_extended_p : 1;
818}; 810};
819 811
820/* Turning a lisp vector value into a pointer to a struct scroll_bar. */ 812/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
@@ -930,7 +922,7 @@ extern void x_check_errors (Display *, const char *)
930extern bool x_had_errors_p (Display *); 922extern bool x_had_errors_p (Display *);
931extern void x_uncatch_errors (void); 923extern void x_uncatch_errors (void);
932extern void x_clear_errors (Display *); 924extern void x_clear_errors (Display *);
933extern void x_set_window_size (struct frame *, int, int, int); 925extern void x_set_window_size (struct frame *, int, int, int, bool);
934extern void x_set_mouse_position (struct frame *, int, int); 926extern void x_set_mouse_position (struct frame *, int, int);
935extern void x_set_mouse_pixel_position (struct frame *, int, int); 927extern void x_set_mouse_pixel_position (struct frame *, int, int);
936extern void xembed_request_focus (struct frame *); 928extern void xembed_request_focus (struct frame *);
@@ -949,13 +941,11 @@ extern bool x_alloc_lighter_color_for_widget (Widget, Display *, Colormap,
949extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *); 941extern bool x_alloc_nearest_color (struct frame *, Colormap, XColor *);
950extern void x_query_color (struct frame *f, XColor *); 942extern void x_query_color (struct frame *f, XColor *);
951extern void x_clear_area (Display *, Window, int, int, int, int); 943extern void x_clear_area (Display *, Window, int, int, int, int);
952#if defined HAVE_MENUS && !defined USE_X_TOOLKIT && !defined USE_GTK 944#if !defined USE_X_TOOLKIT && !defined USE_GTK
953extern void x_mouse_leave (struct x_display_info *); 945extern void x_mouse_leave (struct x_display_info *);
954#endif 946#endif
955 947
956#ifdef USE_X_TOOLKIT
957extern int x_dispatch_event (XEvent *, Display *); 948extern int x_dispatch_event (XEvent *, Display *);
958#endif
959extern int x_x_to_emacs_modifiers (struct x_display_info *, int); 949extern int x_x_to_emacs_modifiers (struct x_display_info *, int);
960extern int x_display_pixel_height (struct x_display_info *); 950extern int x_display_pixel_height (struct x_display_info *);
961extern int x_display_pixel_width (struct x_display_info *); 951extern int x_display_pixel_width (struct x_display_info *);
@@ -963,7 +953,7 @@ extern int x_display_pixel_width (struct x_display_info *);
963extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); 953extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object);
964extern void x_wait_for_event (struct frame *, int); 954extern void x_wait_for_event (struct frame *, int);
965 955
966/* Defined in xselect.c */ 956/* Defined in xselect.c. */
967 957
968extern void x_handle_property_notify (const XPropertyEvent *); 958extern void x_handle_property_notify (const XPropertyEvent *);
969extern void x_handle_selection_notify (const XSelectionEvent *); 959extern void x_handle_selection_notify (const XSelectionEvent *);