aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2014-07-27 15:21:30 +0200
committerMartin Rudalics2014-07-27 15:21:30 +0200
commit3477e27021dbe9366c3c1aaba80feb72f1138b29 (patch)
treec1ebfb6695e8d7f90ddad1a5bfaaf353be677514 /src
parent11fb71017b03f01a7e9e2db24973e756a41e16ec (diff)
downloademacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.tar.gz
emacs-3477e27021dbe9366c3c1aaba80feb72f1138b29.zip
Complete pixelwise frame/window resizing, add horizontal scrollbar support.
* frame.el (frame-notice-user-settings): Rewrite using frame-initial-frame-tool-bar-height. * menu-bar.el (menu-bar-horizontal-scroll-bar) (menu-bar-no-horizontal-scroll-bar): New functions. (menu-bar-showhide-scroll-bar-menu): Add bindings for horizontal scroll bars. * scroll-bar.el (scroll-bar-lines) (set-horizontal-scroll-bar-mode) (get-horizontal-scroll-bar-mode, horizontal-scroll-bar-mode) (scroll-bar-horizontal-drag-1, scroll-bar-horizontal-drag) (scroll-bar-toolkit-horizontal-scroll): New functions. (horizontal-scroll-bar-mode) (previous-horizontal-scroll-bar-mode) (horizontal-scroll-bar-mode-explicit): New variables. (horizontal-scroll-bar-mode): New option. (toggle-horizontal-scroll-bar): Do something. (top-level): Bind horizontal-scroll-bar mouse-1. * startup.el (tool-bar-originally-present): Remove variable. (command-line): Don't set tool-bar-originally-present. * window.el (window-min-height): Update doc-string. (window--dump-frame): Dump horizontal scroll bar values. (window--min-size-1): Handle minibuffer window separately. Count in margins and horizontal scroll bar. Return safe value iff IGNORE equals 'safe. (frame-windows-min-size): New function (used by frame resizing routines). (fit-frame-to-buffer, fit-window-to-buffer): Count in horizontal scroll bars. (window--sanitize-window-sizes): New function. (window-split-min-size): Remove. (split-window): Count divider-width. Don't use `window-split-min-size' any more. Reword error messages. Sanitize windows sizes after splitting. * buffer.h (struct buffer): New fields scroll_bar_height and horizontal_scroll_bar_type. * buffer.c (bset_scroll_bar_height) (bset_horizontal_scroll_bar_type): New functions. (Fbuffer_swap_text): Handle old_pointm field. (init_buffer_once): Set defaults for scroll_bar_height and horizontal_scroll_bar_type. (syms_of_buffer): New variables scroll_bar_height and horizontal_scroll_bar_type. * dispextern.h (window_part): Rename ON_SCROLL_BAR to ON_VERTICAL_SCROLL_BAR. Add ON_HORIZONTAL_SCROLL_BAR. (set_vertical_scroll_bar): Remove prototype. (x_change_tool_bar_height): Add prototype. * dispnew.c (adjust_frame_glyphs_for_frame_redisplay) (window_to_frame_vpos, update_frame_1, scrolling, init_display): Use FRAME_TOTAL_COLS and FRAME_TOTAL_LINES instead of FRAME_COLS and FRAME_LINES. (adjust_frame_glyphs_for_window_redisplay): Rearrange lines. (update_window): Start mode_line_row->y after horizontal scroll bar. (change_frame_size_1): Call adjust_frame_size. (init_display): When changing the size of a tty frame do not pass height of menu bar. (Qframe_windows_min_size): New symbol. * frame.h (struct frame): List tool bar fields after menu bar fields. Add official, total_lines, horizontal_scroll_bars, config_scroll_bar_height and config_scroll_bar_lines fields. (FRAME_HAS_HORIZONTAL_SCROLL_BARS) (FRAME_CONFIG_SCROLL_BAR_HEIGHT, FRAME_CONFIG_SCROLL_BAR_LINES) (FRAME_SCROLL_BAR_AREA_HEIGHT, FRAME_SCROLL_BAR_COLS) (FRAME_SCROLL_BAR_LINES, FRAME_TOTAL_LINES, SET_FRAME_LINES) (FRAME_WINDOWS_HEIGHT): New macros. (SET_FRAME_HEIGHT, FRAME_TEXT_LINES_TO_PIXEL_HEIGHT) (FRAME_PIXEL_Y_TO_LINE, FRAME_PIXEL_HEIGHT_TO_TEXT_LINES) (FRAME_TEXT_TO_PIXEL_HEIGHT): Separately count top margin and horizontal scroll bar. (frame_inhibit_resize, adjust_frame_size) (frame_windows_min_size): Add declarations. (Qscroll_bar_height, Qhorizontal_scroll_bars) (x_set_scroll_bar_default_height, x_set_left_fringe) (x_set_right_fringe, x_set_vertical_scroll_bars) (x_set_horizontal_scroll_bars, x_set_scroll_bar_width) (x_set_scroll_bar_height): Add external declarations. * frame.c: (frame_inhibit_resize, frame_windows_min_size) (adjust_frame_size): New functions. (make_frame): Initial horizontal_scroll_bars field. Use SET_FRAME_LINES. Don't allow horizontal scroll bar in minibuffer window. (make_initial_frame, make_terminal_frame): No horizontal scroll bar in initial and terminal frames. Use adjust_frame_size. (Fframe_total_cols): Fix doc-string. (Fframe_total_lines, Fscroll_bar_height): New Lisp functions. (Fset_frame_height, Fset_frame_width, Fset_frame_size): Rewrite using adjust_frame_size. (Qscroll_bar_height, Qhorizontal_scroll_bars) (Qframe_windows_min_size): New symbols. (x_set_frame_parameters): Remove call of check_frame_size. (x_report_frame_params): Return scroll_bar_height value. (x_set_left_fringe, x_set_right_fringe): New functions. (adjust_frame_height, x_set_internal_border_width) (x_set_fringe_width): Remove. (x_set_internal_border_width, x_set_vertical_scroll_bars) (x_set_scroll_bar_width, x_set_right_divider_width) (x_set_bottom_divider_width): Rewrite using adjust_frame_size. (x_set_horizontal_scroll_bars, x_set_scroll_bar_height): New functions. (x_figure_window_size): Rewrite to make frame display the expected number of lines. (Vdefault_frame_scroll_bars): Rewrite doc-string. (Vdefault_frame_horizontal_scroll_bars) (Vframe_initial_frame_tool_bar_height) (frame_inhibit_implied_resize): New variables. * fringe.c (compute_fringe_widths): Remove. * gtkutil.h (YG_SB_MIN, YG_SB_MAX, YG_SB_RANGE): Define. (xg_create_horizontal_scroll_bar) (xg_update_horizontal_scrollbar_pos) (xg_set_toolkit_horizontal_scroll_bar_thumb) (xg_get_default_scrollbar_height) (xg_clear_under_internal_border): Extern. * gtkutil.c (xg_frame_resized): Don't call do_pending_window_change. (xg_frame_set_char_size): Use adjust_frame_size. (style_changed_cb): Call update_theme_scrollbar_height and x_set_scroll_bar_default_height. (x_wm_set_size_hint): Don't call check_frame_size. (update_theme_scrollbar_height) (xg_get_default_scrollbar_height) (xg_create_horizontal_scroll_bar) (xg_update_horizontal_scrollbar_pos) (xg_set_toolkit_horizontal_scroll_bar_thumb): New functions. (xg_create_scroll_bar): Set horizontal slot of bar. (xg_initialize): Call update_theme_scrollbar_height. (xg_clear_under_internal_border): No more static. * insdel.c (adjust_suspend_auto_hscroll): New function. (adjust_markers_for_delete, adjust_markers_for_insert) (adjust_markers_for_replace): Call adjust_suspend_auto_hscroll. * keyboard.c (readable_events, discard_mouse_events) (make_lispy_event): Handle horizontal scroll bar click events. (Fsuspend_emacs): When changing the size of a tty frame do not pass height of menu bar. (Qbefore_handle, Qhorizontal_handle, Qafter_handle, Qleft) (Qright, Qleftmost, Qrightmost): New symbols. * menu.c (Fx_popup_dialog): Use FRAME_TOTAL_LINES instead of FRAME_LINES. * minibuf.c (read_minibuf): Initialize suspend_auto_hscroll. * nsfns.m (x_set_internal_border_width): New function. * nsterm.m (ns_draw_fringe_bitmap, ns_set_vertical_scroll_bar): Remove extended fringe code. (x_set_window_size, x_new_font): Don't call compute_fringe_widths. * term.c (Fresume_tty): When changing the size of a tty frame do not pass height of menu bar. (clear_tty_hooks, set_tty_hooks): Clear horizontal_scroll_bar_hook. (init_tty): Frame has no horizontal scroll bars. * termhooks.h (enum scroll_bar_part): Add scroll_bar_move_ratio, scroll_bar_before_handle, scroll_bar_horizontal_handle, scroll_bar_after_handle, scroll_bar_left_arrow, scroll_bar_right_arrow, scroll_bar_to_leftmost and scroll_bar_to_rightmost entries. (enum event_kind): Add HORIZONTAL_SCROLL_BAR_CLICK_EVENT (struct terminal): Add set_horizontal_scroll_bar_hook. * w32console.c (initialize_w32_display): Clear horizontal_scroll_bar_hook. * w32fns.c (x_set_mouse_color): Use FRAME_W32_DISPLAY instead of FRAME_X_DISPLAY. (x_clear_under_internal_border, x_set_internal_border_width): New functions. (x_set_menu_bar_lines): Rewrite using frame_inhibit_resize. Set windows_or_buffers_changed when adding the menu bar. (x_set_tool_bar_lines): Rewrite using adjust_frame_size. (x_change_tool_bar_height, x_set_scroll_bar_default_height) (w32_createhscrollbar): New functions. (w32_createscrollbar): Rename to w32_createvscrollbar. (w32_createwindow): Init WND_HSCROLLBAR_INDEX. (w32_name_of_message): Replace WM_EMACS_CREATESCROLLBAR by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR. Add WM_EMACS_SHOWCURSOR. (w32_wnd_proc): Handle WM_HSCROLL case. In WM_WINDOWPOSCHANGING case do not artificially impose WM size hints. Handle WM_EMACS_SHOWCURSOR case. Replace WM_EMACS_CREATESCROLLBAR case by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR cases. (my_create_tip_window): Replace WND_SCROLLBAR_INDEX by WND_VSCROLLBAR_INDEX and WND_HSCROLLBAR_INDEX. (unwind_create_frame_1): Remove. (Fx_create_frame): Make both scrollbars the system standard width and height. Use official field of frame structure to inhibit running window-configuration-change-hook. (x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size pixelwise. Handle frame's official field. (w32_frame_parm_handlers): Remove x_set_fringe_width entries. Add x_set_scroll_bar_height, x_set_horizontal_scroll_bars, x_set_left_fringe and x_set_right_fringe. * w32inevt.c (resize_event, maybe_generate_resize_event): Do not pass height of menu bar to change_frame_size. * w32menu.c (set_frame_menubar): Rewrite using frame_inhibit_resize. * w32term.h (struct w32_display_info): Add horizontal_scroll_bar_cursor and cursor_display_counter. (struct scroll_bar): Add horizontal. (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT) (HORIZONTAL_SCROLL_BAR_LEFT_RANGE) (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH) (HORIZONTAL_SCROLL_BAR_LEFT_BORDER) (HORIZONTAL_SCROLL_BAR_RIGHT_BORDER) (HORIZONTAL_SCROLL_BAR_TOP_BORDER) (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER) (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): New macros. (WM_EMACS_CREATEVSCROLLBAR, WM_EMACS_CREATEHSCROLLBAR): Define instead of WM_EMACS_CREATESCROLLBAR. (WND_VSCROLLBAR_INDEX, WND_HSCROLLBAR_INDEX): Define instead of WND_SCROLLBAR_INDEX. * w32term.c (horizontal_scroll_bar_min_handle) (horizontal_scroll_bar_left_border) (horizontal_scroll_bar_right_border): New integers. (x_set_frame_alpha): Replace x_highlight_frame by w32_focus_frame. (x_window_to_scroll_bar): New argument "type". Update callers accordingly. (w32_set_horizontal_scroll_bar_thumb) (x_horizontal_scroll_bar_report_motion) (w32_set_horizontal_scroll_bar) (w32_horizontal_scroll_bar_handle_click) (x_horizontal_scroll_bar_report_motion): New functions. (w32_mouse_position): Discriminate horizontal and vertical scrollbar cases. (my_create_scrollbar): Replace with two new functions my_create_vscrollbar and my_create_hscrollbar. (x_scroll_bar_create): New argument "horizontal". Update callers accordingly. (x_scroll_bar_remove, w32_condemn_scroll_bars) (w32_redeem_scroll_bar, x_scroll_bar_clear): Handle horizontal scroll bar case. (w32_read_socket): Handle WM_HSCROLL cae. (x_new_font): Don't recompute fringe widths. Use frame_inhibit_resize. Calculate new menu bar height iff we build without toolkit. Always clear under internal border. (x_set_window_size): Don't check frame size or recompute fringes. Reset fullscreen status before applying sizes. Always resize as requested by pixelwise argument. Don't call do_pending_window_change. (x_wm_set_size_hint): Add call for FRAME_SCROLL_BAR_AREA_HEIGHT. (w32_initialize_display_info): Initialize dpyinfo's horizontal_scroll_bar_cursor entry. (w32_create_terminal): Add set_horizontal_scroll_bar_hook. (w32_initialize): Init horizontal_scroll_bar_min_handle and horizontal_scroll_bar_left_border. (w32fullscreen_hook): Intermittently resize window to normal when switching from fullscreen to maximized state. (run_window_configuration_change_hook): Don't run it if frame is not official yet. (unwind_change_frame): Remove. (Fset_window_configuration): Rewrite using frame's official field. * widget.c (set_frame_size): Don't call compute_fringe_widths. (EmacsFrameSetCharSize): Obey frame_inhibit_resize. * window.h (struct window): New fields old_pointm, horizontal_scroll_bar, horizontal_scroll_bar_type, hscroll_whole, scroll_bar_height and suspend_auto_hscroll. (wset_horizontal_scroll_bar, wset_horizontal_scroll_bar_type): New functions. (sanitize_window_sizes): Extern. (MINI_NON_ONLY_WINDOW_P, MINI_ONLY_WINDOW_P, WINDOW_PSEUDO_P) (WINDOW_TOPMOST_P, WINDOW_HAS_HORIZONTAL_SCROLL_BAR) (WINDOW_CONFIG_SCROLL_BAR_HEIGHT) (WINDOW_CONFIG_SCROLL_BAR_LINES) (WINDOW_SCROLL_BAR_LINES, WINDOW_SCROLL_BAR_AREA_HEIGHT): New macros. (WINDOW_LEFT_FRINGE_COLS, WINDOW_RIGHT_FRINGE_COLS) (WINDOW_FRINGE_COLS, WINDOW_FRINGE_EXTENDED_P): Remove macros. (WINDOW_VERTICAL_SCROLL_BAR_TYPE) (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT) (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT) (WINDOW_HAS_VERTICAL_SCROLL_BAR): Minor rewrite. (WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT) (WINDOW_SCROLL_BAR_AREA_Y): Count in scroll bar height. * window.c (wset_old_pointm, Fwindow_scroll_bar_height) (Fwindow_old_point, sanitize_window_sizes): New functions. (Qwindow_sanitize_window_sizes): New symbol. (window_body_height): Count in horizontal scroll bar. (set_window_hscroll, Fscroll_left, Fscroll_right): Set suspend_auto_hscroll slot. (Fwindow_inside_edges): Count fringes pixelwise. (coordinates_in_window, Fcoordinates_in_window_p): Consider horizontal scroll bar. (check_frame_size, adjust_window_margins): Remove functions and corresponding calls. (set_window_buffer): Initialize old_pointm and horizontal scroll bars. (temp_output_buffer_show): Reset hscroll related fields. Initialize old_pointm. (make_parent_window): Initialize old_pointm. (make_window): Initialize old_pointm, horizontal scroll bar type, and scroll bar height. (resize_frame_windows): Don't count top margin in new sizes. Don't use safe sizes when shrinking a frame; let the window manager do the clipping. (Fsplit_window_internal): Inherit horizontal scroll bar type and height. (Fdelete_window_internal): Unchain old_pointm marker. (window_scroll_pixel_based, Fscroll_other_window): Adjust old_pointm. (Fwindow_text_width, Fwindow_text_height): New argument "pixelwise". (struct saved_window): New fields, old_pointm, hscroll_whole, suspend_auto_hscroll, scroll_bar_height and horizontal_scroll_bar_type. (Fset_window_configuration, save_window_save): Set new fields of saved_window. (apply_window_adjustment): Don't call adjust_window_margins. (set_window_margins): Don't change margins if new sizes don't fit into window. (set_window_scroll_bars): New argument "horizontal_type". Handle horizontal scroll bars. Don't change scroll bars if they don't fit into window. (Fset_window_scroll_bars): New argument "horizontal_type". (Fwindow_scroll_bars): Return values for horizontal scroll bars. (compare_window_configurations): Compare horizontal scroll bar settings. * xdisp.c (window_text_bottom_y, window_box_height): Count in horizontal scroll bar height. (pixel_to_glyph_coords, init_xdisp): Use FRAME_TOTAL_LINES instead of FRAME_LINES. (remember_mouse_glyph): Case ON_SCROLL_BAR changed to ON_VERTICAL_SCROLL_BAR. (with_echo_area_buffer): Initialize old_pointm. (with_echo_area_buffer_unwind_data): Store old_pointm values in vector. (unwind_with_echo_area_buffer): Handle old_pointm. (update_tool_bar): Set do_update when the tool bar window has at least one line (since this is what the user sets). (MAX_FRAME_TOOL_BAR_HEIGHT): Remove macro. (redisplay_tool_bar): Return early when toolbar has zero lines. Call x_change_tool_bar_height. Don't use max_tool_bar_height. (hscroll_window_tree): Handle suspension of auto_hscroll and old_pointm. (set_horizontal_scroll_bar): New function. (redisplay_window): Set ignore_mouse_drag_p when tool bar has more than one line. Handle horizontal scroll bars. (note_mouse_highlight): Handle horizontal scrol bars. (expose_frame): Set dimensions of XRectangle from frame's text sizes. (Vvoid_text_area_pointer): Update doc-string. * xfns.c (x_set_menu_bar_lines): Use adjust_frame_size. (x_change_tool_bar_height, x_set_scroll_bar_default_height) (x_set_internal_border_width): New functions. (x_set_tool_bar_lines): Call x_change_tool_bar_height. (unwind_create_frame_1): Remove. (Fx_create_frame): Handle horizontal scroll bars. Use official field of frame structure to inhibit running window-configuration-change-hook. (x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size pixelwise. Handle frame's official field. (x_frame_parm_handlers): Add x_set_scroll_bar_height, x_set_horizontal_scroll_bars, x_set_left_fringe, x_set_right_fringe. * xmenu.c (update_frame_menubar, free_frame_menubar): Use adjust_frame_size. * xterm.h (struct x_display_info): Add horizontal_scroll_bar_cursor and Xatom_Horizontal_Scrollbar slots. (struct scroll_bar): Add horizontal slot. (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT) (HORIZONTAL_SCROLL_BAR_LEFT_RANGE) (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH): New macros. (HORIZONTAL_SCROLL_BAR_LEFT_BORDER) (HORIZONTAL_SCROLL_BAR_RIGHT_BORDER) (HORIZONTAL_SCROLL_BAR_TOP_BORDER) (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER) (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): Define. (x_clear_under_internal_border): Remove. * xterm.c (XTmouse_position): Handle horizontal scroll bars. (x_window_to_scroll_bar): New argument TYPE. Update callers. (x_send_scroll_bar_event, x_scroll_bar_create): New arguments HORIZONTAL. Update callers. (horizontal_action_hook_id): New action hook id. (x_horizontal_scroll_bar_to_input_event) (x_create_horizontal_toolkit_scroll_bar) (xt_horizontal_action_hook) (x_set_toolkit_horizontal_scroll_bar_thumb) (XTset_horizontal_scroll_bar, x_net_wm_state) (x_horizontal_scroll_bar_report_motion): New functions. (xg_scroll_callback, x_scroll_bar_handle_click): Handle horizontal scroll bars. (SCROLL_BAR_HORIZONTAL_NAME): Define. (XTset_vertical_scroll_bar): Attempt to clear areas not covered by scroll bar. (XTcondemn_scroll_bars, XTredeem_scroll_bar): Rewrite. Handle horizontal scroll bars. (handle_one_xevent): Handle horizontal scroll bar events. Call x_net_wm_state. (x_set_window_size_1, x_wm_set_size_hint): Don't call check_frame_size. (x_set_window_size): Don't call check_frame_size and do_pending_window_change. (x_term_init): Init horizontal_scroll_bar_cursor display info. (x_create_terminal): Add set_horizontal_scroll_bar_hook. (x_scroll_bar_set_handle): Add some checks when calling x_clear_area.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog363
-rw-r--r--src/buffer.c42
-rw-r--r--src/buffer.h7
-rw-r--r--src/dispextern.h7
-rw-r--r--src/dispnew.c241
-rw-r--r--src/eval.c6
-rw-r--r--src/frame.c809
-rw-r--r--src/frame.h288
-rw-r--r--src/fringe.c92
-rw-r--r--src/gtkutil.c220
-rw-r--r--src/gtkutil.h21
-rw-r--r--src/insdel.c22
-rw-r--r--src/keyboard.c56
-rw-r--r--src/minibuf.c1
-rw-r--r--src/nsfns.m47
-rw-r--r--src/nsterm.h35
-rw-r--r--src/nsterm.m213
-rw-r--r--src/term.c4
-rw-r--r--src/termhooks.h32
-rw-r--r--src/w32console.c1
-rw-r--r--src/w32fns.c348
-rw-r--r--src/w32inevt.c7
-rw-r--r--src/w32menu.c3
-rw-r--r--src/w32term.c615
-rw-r--r--src/w32term.h103
-rw-r--r--src/widget.c19
-rw-r--r--src/window.c824
-rw-r--r--src/window.h297
-rw-r--r--src/xdisp.c189
-rw-r--r--src/xfns.c263
-rw-r--r--src/xmenu.c23
-rw-r--r--src/xterm.c1068
-rw-r--r--src/xterm.h48
33 files changed, 4603 insertions, 1711 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 6843cfac089..28fc913903c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,366 @@
12014-07-27 Martin Rudalics <rudalics@gmx.at>
2
3 * buffer.h (struct buffer): New fields scroll_bar_height and
4 horizontal_scroll_bar_type.
5 * buffer.c (bset_scroll_bar_height)
6 (bset_horizontal_scroll_bar_type): New functions.
7 (Fbuffer_swap_text): Handle old_pointm field.
8 (init_buffer_once): Set defaults for scroll_bar_height and
9 horizontal_scroll_bar_type.
10 (syms_of_buffer): New variables scroll_bar_height and
11 horizontal_scroll_bar_type.
12 * dispextern.h (window_part): Rename ON_SCROLL_BAR to
13 ON_VERTICAL_SCROLL_BAR. Add ON_HORIZONTAL_SCROLL_BAR.
14 (set_vertical_scroll_bar): Remove prototype.
15 (x_change_tool_bar_height): Add prototype.
16 * dispnew.c (adjust_frame_glyphs_for_frame_redisplay)
17 (window_to_frame_vpos, update_frame_1, scrolling, init_display):
18 Use FRAME_TOTAL_COLS and FRAME_TOTAL_LINES instead of FRAME_COLS
19 and FRAME_LINES.
20 (adjust_frame_glyphs_for_window_redisplay): Rearrange lines.
21 (update_window): Start mode_line_row->y after horizontal scroll
22 bar.
23 (change_frame_size_1): Call adjust_frame_size.
24 (init_display): When changing the size of a tty frame do not
25 pass height of menu bar.
26 (Qframe_windows_min_size): New symbol.
27 * frame.h (struct frame): List tool bar fields after menu bar
28 fields. Add official, total_lines, horizontal_scroll_bars,
29 config_scroll_bar_height and config_scroll_bar_lines fields.
30 (FRAME_HAS_HORIZONTAL_SCROLL_BARS)
31 (FRAME_CONFIG_SCROLL_BAR_HEIGHT, FRAME_CONFIG_SCROLL_BAR_LINES)
32 (FRAME_SCROLL_BAR_AREA_HEIGHT, FRAME_SCROLL_BAR_COLS)
33 (FRAME_SCROLL_BAR_LINES, FRAME_TOTAL_LINES, SET_FRAME_LINES)
34 (FRAME_WINDOWS_HEIGHT): New macros.
35 (SET_FRAME_HEIGHT, FRAME_TEXT_LINES_TO_PIXEL_HEIGHT)
36 (FRAME_PIXEL_Y_TO_LINE, FRAME_PIXEL_HEIGHT_TO_TEXT_LINES)
37 (FRAME_TEXT_TO_PIXEL_HEIGHT): Separately count top margin and
38 horizontal scroll bar.
39 (frame_inhibit_resize, adjust_frame_size)
40 (frame_windows_min_size): Add declarations.
41 (Qscroll_bar_height, Qhorizontal_scroll_bars)
42 (x_set_scroll_bar_default_height, x_set_left_fringe)
43 (x_set_right_fringe, x_set_vertical_scroll_bars)
44 (x_set_horizontal_scroll_bars, x_set_scroll_bar_width)
45 (x_set_scroll_bar_height): Add external declarations.
46 * frame.c: (frame_inhibit_resize, frame_windows_min_size)
47 (adjust_frame_size): New functions.
48 (make_frame): Initial horizontal_scroll_bars field. Use
49 SET_FRAME_LINES. Don't allow horizontal scroll bar in
50 minibuffer window.
51 (make_initial_frame, make_terminal_frame): No horizontal scroll
52 bar in initial and terminal frames. Use adjust_frame_size.
53 (Fframe_total_cols): Fix doc-string.
54 (Fframe_total_lines, Fscroll_bar_height): New Lisp functions.
55 (Fset_frame_height, Fset_frame_width, Fset_frame_size): Rewrite
56 using adjust_frame_size.
57 (Qscroll_bar_height, Qhorizontal_scroll_bars)
58 (Qframe_windows_min_size): New symbols.
59 (x_set_frame_parameters): Remove call of check_frame_size.
60 (x_report_frame_params): Return scroll_bar_height value.
61 (x_set_left_fringe, x_set_right_fringe): New functions.
62 (adjust_frame_height, x_set_internal_border_width)
63 (x_set_fringe_width): Remove.
64 (x_set_internal_border_width, x_set_vertical_scroll_bars)
65 (x_set_scroll_bar_width, x_set_right_divider_width)
66 (x_set_bottom_divider_width): Rewrite using adjust_frame_size.
67 (x_set_horizontal_scroll_bars, x_set_scroll_bar_height): New
68 functions.
69 (x_figure_window_size): Rewrite to make frame display the
70 expected number of lines.
71 (Vdefault_frame_scroll_bars): Rewrite doc-string.
72 (Vdefault_frame_horizontal_scroll_bars)
73 (Vframe_initial_frame_tool_bar_height)
74 (frame_inhibit_implied_resize): New variables.
75 * fringe.c (compute_fringe_widths): Remove.
76 * gtkutil.h (YG_SB_MIN, YG_SB_MAX, YG_SB_RANGE): Define.
77 (xg_create_horizontal_scroll_bar)
78 (xg_update_horizontal_scrollbar_pos)
79 (xg_set_toolkit_horizontal_scroll_bar_thumb)
80 (xg_get_default_scrollbar_height)
81 (xg_clear_under_internal_border): Extern.
82 * gtkutil.c (xg_frame_resized): Don't call
83 do_pending_window_change.
84 (xg_frame_set_char_size): Use adjust_frame_size.
85 (style_changed_cb): Call update_theme_scrollbar_height and
86 x_set_scroll_bar_default_height.
87 (x_wm_set_size_hint): Don't call check_frame_size.
88 (update_theme_scrollbar_height)
89 (xg_get_default_scrollbar_height)
90 (xg_create_horizontal_scroll_bar)
91 (xg_update_horizontal_scrollbar_pos)
92 (xg_set_toolkit_horizontal_scroll_bar_thumb): New functions.
93 (xg_create_scroll_bar): Set horizontal slot of bar.
94 (xg_initialize): Call update_theme_scrollbar_height.
95 (xg_clear_under_internal_border): No more static.
96 * insdel.c (adjust_suspend_auto_hscroll): New function.
97 (adjust_markers_for_delete, adjust_markers_for_insert)
98 (adjust_markers_for_replace): Call adjust_suspend_auto_hscroll.
99 * keyboard.c (readable_events, discard_mouse_events)
100 (make_lispy_event): Handle horizontal scroll bar click events.
101 (Fsuspend_emacs): When changing the size of a tty frame do not
102 pass height of menu bar.
103 (Qbefore_handle, Qhorizontal_handle, Qafter_handle, Qleft)
104 (Qright, Qleftmost, Qrightmost): New symbols.
105 * menu.c (Fx_popup_dialog): Use FRAME_TOTAL_LINES instead of
106 FRAME_LINES.
107 * minibuf.c (read_minibuf): Initialize suspend_auto_hscroll.
108 * nsfns.m (x_set_internal_border_width): New function.
109 * nsterm.m (ns_draw_fringe_bitmap, ns_set_vertical_scroll_bar):
110 Remove extended fringe code.
111 (x_set_window_size, x_new_font): Don't call
112 compute_fringe_widths.
113 * term.c (Fresume_tty): When changing the size of a tty frame do
114 not pass height of menu bar.
115 (clear_tty_hooks, set_tty_hooks): Clear
116 horizontal_scroll_bar_hook.
117 (init_tty): Frame has no horizontal scroll bars.
118 * termhooks.h (enum scroll_bar_part): Add scroll_bar_move_ratio,
119 scroll_bar_before_handle, scroll_bar_horizontal_handle,
120 scroll_bar_after_handle, scroll_bar_left_arrow,
121 scroll_bar_right_arrow, scroll_bar_to_leftmost and
122 scroll_bar_to_rightmost entries.
123 (enum event_kind): Add HORIZONTAL_SCROLL_BAR_CLICK_EVENT
124 (struct terminal): Add set_horizontal_scroll_bar_hook.
125 * w32console.c (initialize_w32_display): Clear
126 horizontal_scroll_bar_hook.
127 * w32fns.c (x_set_mouse_color): Use FRAME_W32_DISPLAY instead of
128 FRAME_X_DISPLAY.
129 (x_clear_under_internal_border, x_set_internal_border_width):
130 New functions.
131 (x_set_menu_bar_lines): Rewrite using frame_inhibit_resize. Set
132 windows_or_buffers_changed when adding the menu bar.
133 (x_set_tool_bar_lines): Rewrite using adjust_frame_size.
134 (x_change_tool_bar_height, x_set_scroll_bar_default_height)
135 (w32_createhscrollbar): New functions.
136 (w32_createscrollbar): Rename to w32_createvscrollbar.
137 (w32_createwindow): Init WND_HSCROLLBAR_INDEX.
138 (w32_name_of_message): Replace WM_EMACS_CREATESCROLLBAR by
139 WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR. Add
140 WM_EMACS_SHOWCURSOR.
141 (w32_wnd_proc): Handle WM_HSCROLL case. In WM_WINDOWPOSCHANGING
142 case do not artificially impose WM size hints. Handle
143 WM_EMACS_SHOWCURSOR case. Replace WM_EMACS_CREATESCROLLBAR case
144 by WM_EMACS_CREATEVSCROLLBAR and WM_EMACS_CREATEHSCROLLBAR
145 cases.
146 (my_create_tip_window): Replace WND_SCROLLBAR_INDEX by
147 WND_VSCROLLBAR_INDEX and WND_HSCROLLBAR_INDEX.
148 (unwind_create_frame_1): Remove.
149 (Fx_create_frame): Make both scrollbars the system standard
150 width and height. Use official field of frame structure to
151 inhibit running window-configuration-change-hook.
152 (x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size
153 pixelwise. Handle frame's official field.
154 (w32_frame_parm_handlers): Remove x_set_fringe_width
155 entries. Add x_set_scroll_bar_height,
156 x_set_horizontal_scroll_bars, x_set_left_fringe and
157 x_set_right_fringe.
158 * w32inevt.c (resize_event, maybe_generate_resize_event): Do not
159 pass height of menu bar to change_frame_size.
160 * w32menu.c (set_frame_menubar): Rewrite using
161 frame_inhibit_resize.
162 * w32term.h (struct w32_display_info): Add
163 horizontal_scroll_bar_cursor and cursor_display_counter.
164 (struct scroll_bar): Add horizontal.
165 (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
166 (HORIZONTAL_SCROLL_BAR_LEFT_RANGE)
167 (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH)
168 (HORIZONTAL_SCROLL_BAR_LEFT_BORDER)
169 (HORIZONTAL_SCROLL_BAR_RIGHT_BORDER)
170 (HORIZONTAL_SCROLL_BAR_TOP_BORDER)
171 (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
172 (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): New macros.
173 (WM_EMACS_CREATEVSCROLLBAR, WM_EMACS_CREATEHSCROLLBAR): Define
174 instead of WM_EMACS_CREATESCROLLBAR.
175 (WND_VSCROLLBAR_INDEX, WND_HSCROLLBAR_INDEX): Define instead of
176 WND_SCROLLBAR_INDEX.
177 * w32term.c (horizontal_scroll_bar_min_handle)
178 (horizontal_scroll_bar_left_border)
179 (horizontal_scroll_bar_right_border): New integers.
180 (x_set_frame_alpha): Replace x_highlight_frame by
181 w32_focus_frame.
182 (x_window_to_scroll_bar): New argument "type". Update callers
183 accordingly.
184 (w32_set_horizontal_scroll_bar_thumb)
185 (x_horizontal_scroll_bar_report_motion)
186 (w32_set_horizontal_scroll_bar)
187 (w32_horizontal_scroll_bar_handle_click)
188 (x_horizontal_scroll_bar_report_motion): New functions.
189 (w32_mouse_position): Discriminate horizontal and vertical
190 scrollbar cases.
191 (my_create_scrollbar): Replace with two new functions
192 my_create_vscrollbar and my_create_hscrollbar.
193 (x_scroll_bar_create): New argument "horizontal". Update
194 callers accordingly.
195 (x_scroll_bar_remove, w32_condemn_scroll_bars)
196 (w32_redeem_scroll_bar, x_scroll_bar_clear): Handle horizontal
197 scroll bar case.
198 (w32_read_socket): Handle WM_HSCROLL cae.
199 (x_new_font): Don't recompute fringe widths. Use
200 frame_inhibit_resize. Calculate new menu bar height iff we
201 build without toolkit. Always clear under internal border.
202 (x_set_window_size): Don't check frame size or recompute
203 fringes. Reset fullscreen status before applying sizes. Always
204 resize as requested by pixelwise argument. Don't call
205 do_pending_window_change.
206 (x_wm_set_size_hint): Add call for FRAME_SCROLL_BAR_AREA_HEIGHT.
207 (w32_initialize_display_info): Initialize dpyinfo's
208 horizontal_scroll_bar_cursor entry.
209 (w32_create_terminal): Add set_horizontal_scroll_bar_hook.
210 (w32_initialize): Init horizontal_scroll_bar_min_handle and
211 horizontal_scroll_bar_left_border.
212 (w32fullscreen_hook): Intermittently resize window to normal
213 when switching from fullscreen to maximized state.
214 (run_window_configuration_change_hook): Don't run it if frame is
215 not official yet.
216 (unwind_change_frame): Remove.
217 (Fset_window_configuration): Rewrite using frame's official field.
218 * widget.c (set_frame_size): Don't call compute_fringe_widths.
219 (EmacsFrameSetCharSize): Obey frame_inhibit_resize.
220 * window.h (struct window): New fields old_pointm,
221 horizontal_scroll_bar, horizontal_scroll_bar_type, hscroll_whole,
222 scroll_bar_height and suspend_auto_hscroll.
223 (wset_horizontal_scroll_bar, wset_horizontal_scroll_bar_type):
224 New functions.
225 (sanitize_window_sizes): Extern.
226 (MINI_NON_ONLY_WINDOW_P, MINI_ONLY_WINDOW_P, WINDOW_PSEUDO_P)
227 (WINDOW_TOPMOST_P, WINDOW_HAS_HORIZONTAL_SCROLL_BAR)
228 (WINDOW_CONFIG_SCROLL_BAR_HEIGHT)
229 (WINDOW_CONFIG_SCROLL_BAR_LINES)
230 (WINDOW_SCROLL_BAR_LINES, WINDOW_SCROLL_BAR_AREA_HEIGHT): New
231 macros.
232 (WINDOW_LEFT_FRINGE_COLS, WINDOW_RIGHT_FRINGE_COLS)
233 (WINDOW_FRINGE_COLS, WINDOW_FRINGE_EXTENDED_P): Remove macros.
234 (WINDOW_VERTICAL_SCROLL_BAR_TYPE)
235 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT)
236 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT)
237 (WINDOW_HAS_VERTICAL_SCROLL_BAR): Minor rewrite.
238 (WINDOW_BOX_HEIGHT_NO_MODE_LINE, WINDOW_BOX_TEXT_HEIGHT)
239 (WINDOW_SCROLL_BAR_AREA_Y): Count in scroll bar height.
240 * window.c (wset_old_pointm, Fwindow_scroll_bar_height)
241 (Fwindow_old_point, sanitize_window_sizes): New functions.
242 (Qwindow_sanitize_window_sizes): New symbol.
243 (window_body_height): Count in horizontal scroll bar.
244 (set_window_hscroll, Fscroll_left, Fscroll_right): Set
245 suspend_auto_hscroll slot.
246 (Fwindow_inside_edges): Count fringes pixelwise.
247 (coordinates_in_window, Fcoordinates_in_window_p): Consider
248 horizontal scroll bar.
249 (check_frame_size, adjust_window_margins): Remove functions and
250 corresponding calls.
251 (set_window_buffer): Initialize old_pointm and horizontal scroll
252 bars.
253 (temp_output_buffer_show): Reset hscroll related fields.
254 Initialize old_pointm.
255 (make_parent_window): Initialize old_pointm.
256 (make_window): Initialize old_pointm, horizontal scroll bar type,
257 and scroll bar height.
258 (resize_frame_windows): Don't count top margin in new sizes.
259 Don't use safe sizes when shrinking a frame; let the window
260 manager do the clipping.
261 (Fsplit_window_internal): Inherit horizontal scroll bar type and
262 height.
263 (Fdelete_window_internal): Unchain old_pointm marker.
264 (window_scroll_pixel_based, Fscroll_other_window): Adjust
265 old_pointm.
266 (Fwindow_text_width, Fwindow_text_height): New argument
267 "pixelwise".
268 (struct saved_window): New fields, old_pointm, hscroll_whole,
269 suspend_auto_hscroll, scroll_bar_height and
270 horizontal_scroll_bar_type.
271 (Fset_window_configuration, save_window_save): Set new fields of
272 saved_window.
273 (apply_window_adjustment): Don't call adjust_window_margins.
274 (set_window_margins): Don't change margins if new sizes don't
275 fit into window.
276 (set_window_scroll_bars): New argument "horizontal_type".
277 Handle horizontal scroll bars. Don't change scroll bars if they
278 don't fit into window.
279 (Fset_window_scroll_bars): New argument "horizontal_type".
280 (Fwindow_scroll_bars): Return values for horizontal scroll bars.
281 (compare_window_configurations): Compare horizontal scroll bar
282 settings.
283 * xdisp.c (window_text_bottom_y, window_box_height): Count in
284 horizontal scroll bar height.
285 (pixel_to_glyph_coords, init_xdisp): Use FRAME_TOTAL_LINES
286 instead of FRAME_LINES.
287 (remember_mouse_glyph): Case ON_SCROLL_BAR changed to
288 ON_VERTICAL_SCROLL_BAR.
289 (with_echo_area_buffer): Initialize old_pointm.
290 (with_echo_area_buffer_unwind_data): Store old_pointm values in
291 vector.
292 (unwind_with_echo_area_buffer): Handle old_pointm.
293 (update_tool_bar): Set do_update when the tool bar window has at
294 least one line (since this is what the user sets).
295 (MAX_FRAME_TOOL_BAR_HEIGHT): Remove macro.
296 (redisplay_tool_bar): Return early when toolbar has zero lines.
297 Call x_change_tool_bar_height. Don't use max_tool_bar_height.
298 (hscroll_window_tree): Handle suspension of auto_hscroll and
299 old_pointm.
300 (set_horizontal_scroll_bar): New function.
301 (redisplay_window): Set ignore_mouse_drag_p when tool bar has
302 more than one line. Handle horizontal scroll bars.
303 (note_mouse_highlight): Handle horizontal scrol bars.
304 (expose_frame): Set dimensions of XRectangle from frame's text
305 sizes.
306 (Vvoid_text_area_pointer): Update doc-string.
307 * xfns.c (x_set_menu_bar_lines): Use adjust_frame_size.
308 (x_change_tool_bar_height, x_set_scroll_bar_default_height)
309 (x_set_internal_border_width): New functions.
310 (x_set_tool_bar_lines): Call x_change_tool_bar_height.
311 (unwind_create_frame_1): Remove.
312 (Fx_create_frame): Handle horizontal scroll bars. Use official
313 field of frame structure to inhibit running
314 window-configuration-change-hook.
315 (x_create_tip_frame): Call SET_FRAME_LINES and change_frame_size
316 pixelwise. Handle frame's official field.
317 (x_frame_parm_handlers): Add x_set_scroll_bar_height,
318 x_set_horizontal_scroll_bars, x_set_left_fringe,
319 x_set_right_fringe.
320 * xmenu.c (update_frame_menubar, free_frame_menubar): Use
321 adjust_frame_size.
322 * xterm.h (struct x_display_info): Add
323 horizontal_scroll_bar_cursor and Xatom_Horizontal_Scrollbar
324 slots.
325 (struct scroll_bar): Add horizontal slot.
326 (HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT)
327 (HORIZONTAL_SCROLL_BAR_LEFT_RANGE)
328 (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH): New macros.
329 (HORIZONTAL_SCROLL_BAR_LEFT_BORDER)
330 (HORIZONTAL_SCROLL_BAR_RIGHT_BORDER)
331 (HORIZONTAL_SCROLL_BAR_TOP_BORDER)
332 (HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
333 (HORIZONTAL_SCROLL_BAR_MIN_HANDLE): Define.
334 (x_clear_under_internal_border): Remove.
335 * xterm.c (XTmouse_position): Handle horizontal scroll bars.
336 (x_window_to_scroll_bar): New argument TYPE. Update callers.
337 (x_send_scroll_bar_event, x_scroll_bar_create): New arguments
338 HORIZONTAL. Update callers.
339 (horizontal_action_hook_id): New action hook id.
340 (x_horizontal_scroll_bar_to_input_event)
341 (x_create_horizontal_toolkit_scroll_bar)
342 (xt_horizontal_action_hook)
343 (x_set_toolkit_horizontal_scroll_bar_thumb)
344 (XTset_horizontal_scroll_bar, x_net_wm_state)
345 (x_horizontal_scroll_bar_report_motion): New functions.
346 (xg_scroll_callback, x_scroll_bar_handle_click): Handle
347 horizontal scroll bars.
348 (SCROLL_BAR_HORIZONTAL_NAME): Define.
349 (XTset_vertical_scroll_bar): Attempt to clear areas not covered
350 by scroll bar.
351 (XTcondemn_scroll_bars, XTredeem_scroll_bar): Rewrite. Handle
352 horizontal scroll bars.
353 (handle_one_xevent): Handle horizontal scroll bar events. Call
354 x_net_wm_state.
355 (x_set_window_size_1, x_wm_set_size_hint): Don't call
356 check_frame_size.
357 (x_set_window_size): Don't call check_frame_size and
358 do_pending_window_change.
359 (x_term_init): Init horizontal_scroll_bar_cursor display info.
360 (x_create_terminal): Add set_horizontal_scroll_bar_hook.
361 (x_scroll_bar_set_handle): Add some checks when calling
362 x_clear_area.
363
12014-07-26 Paul Eggert <eggert@cs.ucla.edu> 3642014-07-26 Paul Eggert <eggert@cs.ucla.edu>
2 365
3 Revert previous change. 366 Revert previous change.
diff --git a/src/buffer.c b/src/buffer.c
index 53cc25e2c8f..1973a93a57d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -145,7 +145,8 @@ Lisp_Object Qmodification_hooks;
145Lisp_Object Qinsert_in_front_hooks; 145Lisp_Object Qinsert_in_front_hooks;
146Lisp_Object Qinsert_behind_hooks; 146Lisp_Object Qinsert_behind_hooks;
147 147
148Lisp_Object Qchoice, Qrange, Qleft, Qright, Qvertical_scroll_bar; 148Lisp_Object Qchoice, Qrange, Qleft, Qright;
149Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar;
149static Lisp_Object Qoverwrite_mode, Qfraction; 150static Lisp_Object Qoverwrite_mode, Qfraction;
150 151
151static void alloc_buffer_text (struct buffer *, ptrdiff_t); 152static void alloc_buffer_text (struct buffer *, ptrdiff_t);
@@ -343,6 +344,11 @@ bset_scroll_bar_width (struct buffer *b, Lisp_Object val)
343 b->INTERNAL_FIELD (scroll_bar_width) = val; 344 b->INTERNAL_FIELD (scroll_bar_width) = val;
344} 345}
345static void 346static void
347bset_scroll_bar_height (struct buffer *b, Lisp_Object val)
348{
349 b->INTERNAL_FIELD (scroll_bar_height) = val;
350}
351static void
346bset_scroll_down_aggressively (struct buffer *b, Lisp_Object val) 352bset_scroll_down_aggressively (struct buffer *b, Lisp_Object val)
347{ 353{
348 b->INTERNAL_FIELD (scroll_down_aggressively) = val; 354 b->INTERNAL_FIELD (scroll_down_aggressively) = val;
@@ -368,6 +374,11 @@ bset_vertical_scroll_bar_type (struct buffer *b, Lisp_Object val)
368 b->INTERNAL_FIELD (vertical_scroll_bar_type) = val; 374 b->INTERNAL_FIELD (vertical_scroll_bar_type) = val;
369} 375}
370static void 376static void
377bset_horizontal_scroll_bar_type (struct buffer *b, Lisp_Object val)
378{
379 b->INTERNAL_FIELD (horizontal_scroll_bar_type) = val;
380}
381static void
371bset_word_wrap (struct buffer *b, Lisp_Object val) 382bset_word_wrap (struct buffer *b, Lisp_Object val)
372{ 383{
373 b->INTERNAL_FIELD (word_wrap) = val; 384 b->INTERNAL_FIELD (word_wrap) = val;
@@ -2429,6 +2440,14 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
2429 make_number 2440 make_number
2430 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))), 2441 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2431 XWINDOW (w)->contents); 2442 XWINDOW (w)->contents);
2443 /* Blindly copied from pointm part. */
2444 if (MARKERP (XWINDOW (w)->old_pointm)
2445 && (EQ (XWINDOW (w)->contents, buf1)
2446 || EQ (XWINDOW (w)->contents, buf2)))
2447 Fset_marker (XWINDOW (w)->old_pointm,
2448 make_number
2449 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2450 XWINDOW (w)->contents);
2432 if (MARKERP (XWINDOW (w)->start) 2451 if (MARKERP (XWINDOW (w)->start)
2433 && (EQ (XWINDOW (w)->contents, buf1) 2452 && (EQ (XWINDOW (w)->contents, buf1)
2434 || EQ (XWINDOW (w)->contents, buf2))) 2453 || EQ (XWINDOW (w)->contents, buf2)))
@@ -5157,7 +5176,9 @@ init_buffer_once (void)
5157 bset_right_fringe_width (&buffer_defaults, Qnil); 5176 bset_right_fringe_width (&buffer_defaults, Qnil);
5158 bset_fringes_outside_margins (&buffer_defaults, Qnil); 5177 bset_fringes_outside_margins (&buffer_defaults, Qnil);
5159 bset_scroll_bar_width (&buffer_defaults, Qnil); 5178 bset_scroll_bar_width (&buffer_defaults, Qnil);
5179 bset_scroll_bar_height (&buffer_defaults, Qnil);
5160 bset_vertical_scroll_bar_type (&buffer_defaults, Qt); 5180 bset_vertical_scroll_bar_type (&buffer_defaults, Qt);
5181 bset_horizontal_scroll_bar_type (&buffer_defaults, Qt);
5161 bset_indicate_empty_lines (&buffer_defaults, Qnil); 5182 bset_indicate_empty_lines (&buffer_defaults, Qnil);
5162 bset_indicate_buffer_boundaries (&buffer_defaults, Qnil); 5183 bset_indicate_buffer_boundaries (&buffer_defaults, Qnil);
5163 bset_fringe_indicator_alist (&buffer_defaults, Qnil); 5184 bset_fringe_indicator_alist (&buffer_defaults, Qnil);
@@ -5225,7 +5246,9 @@ init_buffer_once (void)
5225 XSETFASTINT (BVAR (&buffer_local_flags, right_fringe_width), idx); ++idx; 5246 XSETFASTINT (BVAR (&buffer_local_flags, right_fringe_width), idx); ++idx;
5226 XSETFASTINT (BVAR (&buffer_local_flags, fringes_outside_margins), idx); ++idx; 5247 XSETFASTINT (BVAR (&buffer_local_flags, fringes_outside_margins), idx); ++idx;
5227 XSETFASTINT (BVAR (&buffer_local_flags, scroll_bar_width), idx); ++idx; 5248 XSETFASTINT (BVAR (&buffer_local_flags, scroll_bar_width), idx); ++idx;
5249 XSETFASTINT (BVAR (&buffer_local_flags, scroll_bar_height), idx); ++idx;
5228 XSETFASTINT (BVAR (&buffer_local_flags, vertical_scroll_bar_type), idx); ++idx; 5250 XSETFASTINT (BVAR (&buffer_local_flags, vertical_scroll_bar_type), idx); ++idx;
5251 XSETFASTINT (BVAR (&buffer_local_flags, horizontal_scroll_bar_type), idx); ++idx;
5229 XSETFASTINT (BVAR (&buffer_local_flags, indicate_empty_lines), idx); ++idx; 5252 XSETFASTINT (BVAR (&buffer_local_flags, indicate_empty_lines), idx); ++idx;
5230 XSETFASTINT (BVAR (&buffer_local_flags, indicate_buffer_boundaries), idx); ++idx; 5253 XSETFASTINT (BVAR (&buffer_local_flags, indicate_buffer_boundaries), idx); ++idx;
5231 XSETFASTINT (BVAR (&buffer_local_flags, fringe_indicator_alist), idx); ++idx; 5254 XSETFASTINT (BVAR (&buffer_local_flags, fringe_indicator_alist), idx); ++idx;
@@ -5446,6 +5469,7 @@ syms_of_buffer (void)
5446 5469
5447 DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar"); 5470 DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
5448 Fput (Qvertical_scroll_bar, Qchoice, list4 (Qnil, Qt, Qleft, Qright)); 5471 Fput (Qvertical_scroll_bar, Qchoice, list4 (Qnil, Qt, Qleft, Qright));
5472 DEFSYM (Qhorizontal_scroll_bar, "horizontal-scroll-bar");
5449 5473
5450 DEFSYM (Qfraction, "fraction"); 5474 DEFSYM (Qfraction, "fraction");
5451 Fput (Qfraction, Qrange, Fcons (make_float (0.0), make_float (1.0))); 5475 Fput (Qfraction, Qrange, Fcons (make_float (0.0), make_float (1.0)));
@@ -5954,6 +5978,11 @@ in a window. To make the change take effect, call `set-window-buffer'. */);
5954 doc: /* Width of this buffer's scroll bars in pixels. 5978 doc: /* Width of this buffer's scroll bars in pixels.
5955A value of nil means to use the scroll bar width from the window's frame. */); 5979A value of nil means to use the scroll bar width from the window's frame. */);
5956 5980
5981 DEFVAR_PER_BUFFER ("scroll-bar-height", &BVAR (current_buffer, scroll_bar_height),
5982 Qintegerp,
5983 doc: /* Height of this buffer's scroll bars in pixels.
5984A value of nil means to use the scroll bar heiht from the window's frame. */);
5985
5957 DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type), 5986 DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type),
5958 Qvertical_scroll_bar, 5987 Qvertical_scroll_bar,
5959 doc: /* Position of this buffer's vertical scroll bar. 5988 doc: /* Position of this buffer's vertical scroll bar.
@@ -5964,6 +5993,17 @@ A value of `left' or `right' means put the vertical scroll bar at that side
5964of the window; a value of nil means don't show any vertical scroll bars. 5993of the window; a value of nil means don't show any vertical scroll bars.
5965A value of t (the default) means do whatever the window's frame specifies. */); 5994A value of t (the default) means do whatever the window's frame specifies. */);
5966 5995
5996 DEFVAR_PER_BUFFER ("horizontal-scroll-bar", &BVAR (current_buffer, horizontal_scroll_bar_type),
5997 Qnil,
5998 doc: /* Position of this buffer's horizontal scroll bar.
5999The value takes effect whenever you tell a window to display this buffer;
6000for instance, with `set-window-buffer' or when `display-buffer' displays it.
6001
6002A value of `bottom' means put the horizontal scroll bar at the bottom of
6003the window; a value of nil means don't show any horizonal scroll bars.
6004A value of t (the default) means do whatever the window's frame
6005specifies. */);
6006
5967 DEFVAR_PER_BUFFER ("indicate-empty-lines", 6007 DEFVAR_PER_BUFFER ("indicate-empty-lines",
5968 &BVAR (current_buffer, indicate_empty_lines), Qnil, 6008 &BVAR (current_buffer, indicate_empty_lines), Qnil,
5969 doc: /* Visually indicate empty lines after the buffer end. 6009 doc: /* Visually indicate empty lines after the buffer end.
diff --git a/src/buffer.h b/src/buffer.h
index 3c29019554c..fd989925976 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -694,10 +694,12 @@ struct buffer
694 othersize draw them between margin areas and text. */ 694 othersize draw them between margin areas and text. */
695 Lisp_Object INTERNAL_FIELD (fringes_outside_margins); 695 Lisp_Object INTERNAL_FIELD (fringes_outside_margins);
696 696
697 /* Width and type of scroll bar areas for windows displaying 697 /* Width, height and types of scroll bar areas for windows displaying
698 this buffer. */ 698 this buffer. */
699 Lisp_Object INTERNAL_FIELD (scroll_bar_width); 699 Lisp_Object INTERNAL_FIELD (scroll_bar_width);
700 Lisp_Object INTERNAL_FIELD (scroll_bar_height);
700 Lisp_Object INTERNAL_FIELD (vertical_scroll_bar_type); 701 Lisp_Object INTERNAL_FIELD (vertical_scroll_bar_type);
702 Lisp_Object INTERNAL_FIELD (horizontal_scroll_bar_type);
701 703
702 /* Non-nil means indicate lines not displaying text (in a style 704 /* Non-nil means indicate lines not displaying text (in a style
703 like vi). */ 705 like vi). */
@@ -1135,7 +1137,8 @@ extern Lisp_Object Qbefore_change_functions;
1135extern Lisp_Object Qafter_change_functions; 1137extern Lisp_Object Qafter_change_functions;
1136extern Lisp_Object Qfirst_change_hook; 1138extern Lisp_Object Qfirst_change_hook;
1137extern Lisp_Object Qpriority, Qbefore_string, Qafter_string; 1139extern Lisp_Object Qpriority, Qbefore_string, Qafter_string;
1138extern Lisp_Object Qchoice, Qrange, Qleft, Qright, Qvertical_scroll_bar; 1140extern Lisp_Object Qchoice, Qrange, Qleft, Qright;
1141extern Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar;
1139 1142
1140/* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is 1143/* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is
1141 a `for' loop which iterates over the buffers from Vbuffer_alist. */ 1144 a `for' loop which iterates over the buffers from Vbuffer_alist. */
diff --git a/src/dispextern.h b/src/dispextern.h
index 400de336965..bb6f1eb2b5e 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -118,7 +118,8 @@ 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_VERTICAL_SCROLL_BAR,
122 ON_HORIZONTAL_SCROLL_BAR,
122 ON_RIGHT_DIVIDER, 123 ON_RIGHT_DIVIDER,
123 ON_BOTTOM_DIVIDER 124 ON_BOTTOM_DIVIDER
124}; 125};
@@ -3163,6 +3164,7 @@ int display_prop_intangible_p (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t);
3163void resize_echo_area_exactly (void); 3164void resize_echo_area_exactly (void);
3164int resize_mini_window (struct window *, int); 3165int resize_mini_window (struct window *, int);
3165void set_vertical_scroll_bar (struct window *); 3166void set_vertical_scroll_bar (struct window *);
3167void set_horizontal_scroll_bar (struct window *);
3166int try_window (Lisp_Object, struct text_pos, int); 3168int try_window (Lisp_Object, struct text_pos, int);
3167void window_box (struct window *, enum glyph_row_area, 3169void window_box (struct window *, enum glyph_row_area,
3168 int *, int *, int *, int *); 3170 int *, int *, int *, int *);
@@ -3201,6 +3203,7 @@ extern bool help_echo_showing_p;
3201extern Lisp_Object help_echo_string, help_echo_window; 3203extern Lisp_Object help_echo_string, help_echo_window;
3202extern Lisp_Object help_echo_object, previous_help_echo_string; 3204extern Lisp_Object help_echo_object, previous_help_echo_string;
3203extern ptrdiff_t help_echo_pos; 3205extern ptrdiff_t help_echo_pos;
3206extern int last_tool_bar_item;
3204extern void reseat_at_previous_visible_line_start (struct it *); 3207extern void reseat_at_previous_visible_line_start (struct it *);
3205extern Lisp_Object lookup_glyphless_char_display (int, struct it *); 3208extern Lisp_Object lookup_glyphless_char_display (int, struct it *);
3206extern ptrdiff_t compute_display_string_pos (struct text_pos *, 3209extern ptrdiff_t compute_display_string_pos (struct text_pos *,
@@ -3273,7 +3276,6 @@ void draw_fringe_bitmap (struct window *, struct glyph_row *, int);
3273void draw_row_fringe_bitmaps (struct window *, struct glyph_row *); 3276void draw_row_fringe_bitmaps (struct window *, struct glyph_row *);
3274bool draw_window_fringes (struct window *, bool); 3277bool draw_window_fringes (struct window *, bool);
3275bool update_window_fringes (struct window *, bool); 3278bool update_window_fringes (struct window *, bool);
3276void compute_fringe_widths (struct frame *, bool);
3277 3279
3278#ifdef HAVE_NTGUI 3280#ifdef HAVE_NTGUI
3279void w32_init_fringe (struct redisplay_interface *); 3281void w32_init_fringe (struct redisplay_interface *);
@@ -3390,6 +3392,7 @@ void gamma_correct (struct frame *, COLORREF *);
3390#ifdef HAVE_WINDOW_SYSTEM 3392#ifdef HAVE_WINDOW_SYSTEM
3391 3393
3392void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); 3394void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
3395void x_change_tool_bar_height (struct frame *f, int);
3393 3396
3394extern Lisp_Object tip_frame; 3397extern Lisp_Object tip_frame;
3395extern Window tip_window; 3398extern Window tip_window;
diff --git a/src/dispnew.c b/src/dispnew.c
index 2d137b4abbd..289431d6dc4 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -72,7 +72,6 @@ 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, bool);
76static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t); 75static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
77static void build_frame_matrix_from_window_tree (struct glyph_matrix *, 76static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
78 struct window *); 77 struct window *);
@@ -2016,12 +2015,12 @@ adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
2016 /* Size of frame matrices must equal size of frame. Note 2015 /* Size of frame matrices must equal size of frame. Note
2017 that we are called for X frames with window widths NOT equal 2016 that we are called for X frames with window widths NOT equal
2018 to the frame width (from CHANGE_FRAME_SIZE_1). */ 2017 to the frame width (from CHANGE_FRAME_SIZE_1). */
2019 if (matrix_dim.width != FRAME_COLS (f) 2018 if (matrix_dim.width != FRAME_TOTAL_COLS (f)
2020 || matrix_dim.height != FRAME_LINES (f)) 2019 || matrix_dim.height != FRAME_TOTAL_LINES (f))
2021 return; 2020 return;
2022 2021
2023 eassert (matrix_dim.width == FRAME_COLS (f) 2022 eassert (matrix_dim.width == FRAME_TOTAL_COLS (f)
2024 && matrix_dim.height == FRAME_LINES (f)); 2023 && matrix_dim.height == FRAME_TOTAL_LINES (f));
2025 2024
2026 /* Pointers to glyph memory in glyph rows are exchanged during 2025 /* Pointers to glyph memory in glyph rows are exchanged during
2027 the update phase of redisplay, which means in general that a 2026 the update phase of redisplay, which means in general that a
@@ -2123,11 +2122,11 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2123 w->left_col = 0; 2122 w->left_col = 0;
2124 w->pixel_top = FRAME_MENU_BAR_HEIGHT (f); 2123 w->pixel_top = FRAME_MENU_BAR_HEIGHT (f);
2125 w->top_line = FRAME_MENU_BAR_LINES (f); 2124 w->top_line = FRAME_MENU_BAR_LINES (f);
2125 w->total_cols = FRAME_TOTAL_COLS (f);
2126 w->pixel_width = (FRAME_PIXEL_WIDTH (f) 2126 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2127 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); 2127 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2128 w->total_cols = FRAME_TOTAL_COLS (f);
2129 w->pixel_height = FRAME_TOOL_BAR_HEIGHT (f);
2130 w->total_lines = FRAME_TOOL_BAR_LINES (f); 2128 w->total_lines = FRAME_TOOL_BAR_LINES (f);
2129 w->pixel_height = FRAME_TOOL_BAR_HEIGHT (f);
2131 allocate_matrices_for_window_redisplay (w); 2130 allocate_matrices_for_window_redisplay (w);
2132 } 2131 }
2133#endif 2132#endif
@@ -2956,7 +2955,7 @@ window_to_frame_vpos (struct window *w, int vpos)
2956 eassert (!FRAME_WINDOW_P (XFRAME (w->frame))); 2955 eassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
2957 eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows); 2956 eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
2958 vpos += WINDOW_TOP_EDGE_LINE (w); 2957 vpos += WINDOW_TOP_EDGE_LINE (w);
2959 eassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (w->frame))); 2958 eassert (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame)));
2960 return vpos; 2959 return vpos;
2961} 2960}
2962 2961
@@ -3421,7 +3420,7 @@ update_window (struct window *w, bool force_p)
3421 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix); 3420 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3422 if (mode_line_row->mode_line_p && mode_line_row->enabled_p) 3421 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3423 { 3422 {
3424 mode_line_row->y = yb; 3423 mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
3425 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row, 3424 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3426 desired_matrix), 3425 desired_matrix),
3427 &mouse_face_overwritten_p); 3426 &mouse_face_overwritten_p);
@@ -4537,7 +4536,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4537 } 4536 }
4538 } 4537 }
4539 4538
4540 pause_p = 0 < i && i < FRAME_LINES (f) - 1; 4539 pause_p = 0 < i && i < FRAME_TOTAL_LINES (f) - 1;
4541 4540
4542 /* Now just clean up termcap drivers and set cursor, etc. */ 4541 /* Now just clean up termcap drivers and set cursor, etc. */
4543 if (!pause_p && set_cursor_p) 4542 if (!pause_p && set_cursor_p)
@@ -4570,7 +4569,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4570 cursor at the end of the prompt. If the mini-buffer 4569 cursor at the end of the prompt. If the mini-buffer
4571 is several lines high, find the last line that has 4570 is several lines high, find the last line that has
4572 any text on it. */ 4571 any text on it. */
4573 row = FRAME_LINES (f); 4572 row = FRAME_TOTAL_LINES (f);
4574 do 4573 do
4575 { 4574 {
4576 --row; 4575 --row;
@@ -4598,7 +4597,7 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4598 if (col >= FRAME_CURSOR_X_LIMIT (f)) 4597 if (col >= FRAME_CURSOR_X_LIMIT (f))
4599 { 4598 {
4600 /* If we have another row, advance cursor into it. */ 4599 /* If we have another row, advance cursor into it. */
4601 if (row < FRAME_LINES (f) - 1) 4600 if (row < FRAME_TOTAL_LINES (f) - 1)
4602 { 4601 {
4603 col = FRAME_LEFT_SCROLL_BAR_COLS (f); 4602 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
4604 row++; 4603 row++;
@@ -4648,12 +4647,12 @@ scrolling (struct frame *frame)
4648 int unchanged_at_top, unchanged_at_bottom; 4647 int unchanged_at_top, unchanged_at_bottom;
4649 int window_size; 4648 int window_size;
4650 int changed_lines; 4649 int changed_lines;
4651 int *old_hash = alloca (FRAME_LINES (frame) * sizeof (int)); 4650 int *old_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int));
4652 int *new_hash = alloca (FRAME_LINES (frame) * sizeof (int)); 4651 int *new_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int));
4653 int *draw_cost = alloca (FRAME_LINES (frame) * sizeof (int)); 4652 int *draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int));
4654 int *old_draw_cost = alloca (FRAME_LINES (frame) * sizeof (int)); 4653 int *old_draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int));
4655 register int i; 4654 register int i;
4656 int free_at_end_vpos = FRAME_LINES (frame); 4655 int free_at_end_vpos = FRAME_TOTAL_LINES (frame);
4657 struct glyph_matrix *current_matrix = frame->current_matrix; 4656 struct glyph_matrix *current_matrix = frame->current_matrix;
4658 struct glyph_matrix *desired_matrix = frame->desired_matrix; 4657 struct glyph_matrix *desired_matrix = frame->desired_matrix;
4659 4658
@@ -4664,8 +4663,8 @@ scrolling (struct frame *frame)
4664 number of unchanged lines at the end. */ 4663 number of unchanged lines at the end. */
4665 changed_lines = 0; 4664 changed_lines = 0;
4666 unchanged_at_top = 0; 4665 unchanged_at_top = 0;
4667 unchanged_at_bottom = FRAME_LINES (frame); 4666 unchanged_at_bottom = FRAME_TOTAL_LINES (frame);
4668 for (i = 0; i < FRAME_LINES (frame); i++) 4667 for (i = 0; i < FRAME_TOTAL_LINES (frame); i++)
4669 { 4668 {
4670 /* Give up on this scrolling if some old lines are not enabled. */ 4669 /* Give up on this scrolling if some old lines are not enabled. */
4671 if (!MATRIX_ROW_ENABLED_P (current_matrix, i)) 4670 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
@@ -4687,7 +4686,7 @@ scrolling (struct frame *frame)
4687 if (old_hash[i] != new_hash[i]) 4686 if (old_hash[i] != new_hash[i])
4688 { 4687 {
4689 changed_lines++; 4688 changed_lines++;
4690 unchanged_at_bottom = FRAME_LINES (frame) - i - 1; 4689 unchanged_at_bottom = FRAME_TOTAL_LINES (frame) - i - 1;
4691 } 4690 }
4692 else if (i == unchanged_at_top) 4691 else if (i == unchanged_at_top)
4693 unchanged_at_top++; 4692 unchanged_at_top++;
@@ -4697,10 +4696,10 @@ scrolling (struct frame *frame)
4697 /* If changed lines are few, don't allow preemption, don't scroll. */ 4696 /* If changed lines are few, don't allow preemption, don't scroll. */
4698 if ((!FRAME_SCROLL_REGION_OK (frame) 4697 if ((!FRAME_SCROLL_REGION_OK (frame)
4699 && changed_lines < baud_rate / 2400) 4698 && changed_lines < baud_rate / 2400)
4700 || unchanged_at_bottom == FRAME_LINES (frame)) 4699 || unchanged_at_bottom == FRAME_TOTAL_LINES (frame))
4701 return 1; 4700 return 1;
4702 4701
4703 window_size = (FRAME_LINES (frame) - unchanged_at_top 4702 window_size = (FRAME_TOTAL_LINES (frame) - unchanged_at_top
4704 - unchanged_at_bottom); 4703 - unchanged_at_bottom);
4705 4704
4706 if (FRAME_SCROLL_REGION_OK (frame)) 4705 if (FRAME_SCROLL_REGION_OK (frame))
@@ -4714,7 +4713,7 @@ scrolling (struct frame *frame)
4714 && window_size >= 18 && baud_rate > 2400 4713 && window_size >= 18 && baud_rate > 2400
4715 && (window_size >= 4714 && (window_size >=
4716 10 * scrolling_max_lines_saved (unchanged_at_top, 4715 10 * scrolling_max_lines_saved (unchanged_at_top,
4717 FRAME_LINES (frame) - unchanged_at_bottom, 4716 FRAME_TOTAL_LINES (frame) - unchanged_at_bottom,
4718 old_hash, new_hash, draw_cost))) 4717 old_hash, new_hash, draw_cost)))
4719 return 0; 4718 return 0;
4720 4719
@@ -5471,52 +5470,11 @@ do_pending_window_change (bool safe)
5471 } 5470 }
5472} 5471}
5473 5472
5474/* Change the frame height and/or width. Values may be given as zero to
5475 indicate no change is to take place.
5476
5477 new_height and new_width refer to the text portion of the frame. It
5478 doesn't matter for new_height, since text and total portion are the
5479 same in that case. But new_width must be enlarged to get the total
5480 width of the frame.
5481
5482 If DELAY, assume we're being called from a signal handler, and
5483 queue the change for later - perhaps the next redisplay.
5484 Since this tries to resize windows, we can't call it
5485 from a signal handler.
5486
5487 SAFE means this function is called from a place where it's
5488 safe to change frame sizes while a redisplay is in progress. */
5489
5490void
5491change_frame_size (struct frame *f, int new_width, int new_height,
5492 bool pretend, bool delay, bool safe, bool pixelwise)
5493{
5494 Lisp_Object tail, frame;
5495
5496 if (FRAME_MSDOS_P (f))
5497 {
5498 /* On MS-DOS, all frames use the same screen, so a change in
5499 size affects all frames. Termcap now supports multiple
5500 ttys. */
5501 FOR_EACH_FRAME (tail, frame)
5502 if (! FRAME_WINDOW_P (XFRAME (frame)))
5503 change_frame_size_1 (XFRAME (frame), new_width, new_height,
5504 pretend, delay, safe, pixelwise);
5505 }
5506 else
5507 change_frame_size_1 (f, new_width, new_height, pretend, delay, safe,
5508 pixelwise);
5509}
5510 5473
5511static void 5474static void
5512change_frame_size_1 (struct frame *f, int new_width, int new_height, 5475change_frame_size_1 (struct frame *f, int new_width, int new_height,
5513 bool pretend, bool delay, bool safe, bool pixelwise) 5476 bool pretend, bool delay, bool safe, bool pixelwise)
5514{ 5477{
5515 int new_text_width, new_text_height, new_root_width;
5516 int old_root_width = WINDOW_PIXEL_WIDTH (XWINDOW (FRAME_ROOT_WINDOW (f)));
5517 int new_cols, new_lines;
5518 ptrdiff_t count = SPECPDL_INDEX ();
5519
5520 /* If we can't deal with the change now, queue it for later. */ 5478 /* If we can't deal with the change now, queue it for later. */
5521 if (delay || (redisplaying_p && !safe)) 5479 if (delay || (redisplaying_p && !safe))
5522 { 5480 {
@@ -5524,123 +5482,63 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
5524 f->new_height = new_height; 5482 f->new_height = new_height;
5525 f->new_pixelwise = pixelwise; 5483 f->new_pixelwise = pixelwise;
5526 delayed_size_change = 1; 5484 delayed_size_change = 1;
5527 return;
5528 }
5529
5530 /* This size-change overrides any pending one for this frame. */
5531 f->new_height = 0;
5532 f->new_width = 0;
5533 f->new_pixelwise = 0;
5534
5535 /* If an argument is zero, set it to the current value. */
5536 if (pixelwise)
5537 {
5538 new_text_width = (new_width == 0) ? FRAME_TEXT_WIDTH (f) : new_width;
5539 new_text_height = (new_height == 0) ? FRAME_TEXT_HEIGHT (f) : new_height;
5540 /* Consider rounding here: Currently, the root window can be
5541 larger than the frame in terms of columns/lines. */
5542 new_cols = new_text_width / FRAME_COLUMN_WIDTH (f);
5543 new_lines = new_text_height / FRAME_LINE_HEIGHT (f);
5544 } 5485 }
5545 else 5486 else
5546 { 5487 {
5547 new_cols = (new_width == 0) ? FRAME_COLS (f) : new_width; 5488 /* This size-change overrides any pending one for this frame. */
5548 new_lines = (new_height == 0) ? FRAME_LINES (f) : new_height; 5489 f->new_height = 0;
5549 new_text_width = new_cols * FRAME_COLUMN_WIDTH (f); 5490 f->new_width = 0;
5550 new_text_height = new_lines * FRAME_LINE_HEIGHT (f); 5491 f->new_pixelwise = 0;
5551 }
5552
5553 /* Compute width of windows in F. */
5554 /* Round up to the smallest acceptable size. */
5555 check_frame_size (f, &new_text_width, &new_text_height, 1);
5556
5557 /* This is the width of the frame without vertical scroll bars and
5558 fringe columns. Do this after rounding - see discussion of
5559 bug#9723. */
5560 new_root_width = (new_text_width
5561 + FRAME_SCROLL_BAR_AREA_WIDTH (f)
5562 + FRAME_TOTAL_FRINGE_WIDTH (f));
5563 /* If we're not changing the frame size, quit now. */
5564 /* Frame width may be unchanged but the text portion may change, for
5565 example, fullscreen and remove/add scroll bar. */
5566 if (new_text_height == FRAME_TEXT_HEIGHT (f)
5567 && new_text_width == FRAME_TEXT_WIDTH (f)
5568 && new_root_width == old_root_width
5569 && (FRAME_PIXEL_HEIGHT (f) ==
5570 FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height))
5571 && (FRAME_PIXEL_WIDTH (f) ==
5572 FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width)))
5573 return;
5574
5575 block_input ();
5576
5577#ifdef MSDOS
5578 /* We only can set screen dimensions to certain values supported
5579 by our video hardware. Try to find the smallest size greater
5580 or equal to the requested dimensions. */
5581 dos_set_window_size (&new_lines, &new_cols);
5582#endif
5583
5584 if (new_text_height != FRAME_TEXT_HEIGHT (f))
5585 {
5586 resize_frame_windows (f, new_text_height, 0, 1);
5587
5588 /* MSDOS frames cannot PRETEND, as they change frame size by
5589 manipulating video hardware. */
5590 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
5591 FrameRows (FRAME_TTY (f)) = new_lines;
5592 }
5593
5594 if (new_text_width != FRAME_TEXT_WIDTH (f)
5595 || new_root_width != old_root_width)
5596 {
5597 resize_frame_windows (f, new_root_width, 1, 1);
5598
5599 /* MSDOS frames cannot PRETEND, as they change frame size by
5600 manipulating video hardware. */
5601 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
5602 FrameCols (FRAME_TTY (f)) = new_cols;
5603 5492
5604#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS) 5493 /* If an argument is zero, set it to the current value. */
5605 if (WINDOWP (f->tool_bar_window)) 5494 if (pixelwise)
5606 { 5495 {
5607 XWINDOW (f->tool_bar_window)->total_cols = new_cols; 5496 new_width = (new_width <= 0) ? FRAME_TEXT_WIDTH (f) : new_width;
5608 XWINDOW (f->tool_bar_window)->pixel_width = new_root_width; 5497 new_height = (new_height <= 0) ? FRAME_TEXT_HEIGHT (f) : new_height;
5498 }
5499 else
5500 {
5501 new_width = (((new_width <= 0) ? FRAME_COLS (f) : new_width)
5502 * FRAME_COLUMN_WIDTH (f));
5503 new_height = (((new_height <= 0) ? FRAME_LINES (f) : new_height)
5504 * FRAME_LINE_HEIGHT (f));
5609 } 5505 }
5610#endif
5611 }
5612
5613 SET_FRAME_COLS (f, new_cols);
5614 FRAME_LINES (f) = new_lines;
5615 FRAME_TEXT_WIDTH (f) = new_text_width;
5616 FRAME_TEXT_HEIGHT (f) = new_text_height;
5617 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width);
5618 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height);
5619 5506
5620 { 5507 /* Adjust frame size but make sure x_set_window_size does not
5621 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); 5508 get called. */
5622 int text_area_x, text_area_y, text_area_width, text_area_height; 5509 adjust_frame_size (f, new_width, new_height, 5, pretend);
5623 5510 }
5624 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width, 5511}
5625 &text_area_height);
5626 if (w->cursor.x >= text_area_x + text_area_width)
5627 w->cursor.hpos = w->cursor.x = 0;
5628 if (w->cursor.y >= text_area_y + text_area_height)
5629 w->cursor.vpos = w->cursor.y = 0;
5630 }
5631 5512
5632 adjust_frame_glyphs (f);
5633 calculate_costs (f);
5634 SET_FRAME_GARBAGED (f);
5635 f->resized_p = 1;
5636 5513
5637 unblock_input (); 5514/* Change text height/width of frame F. Values may be given as zero to
5515 indicate that no change is needed.
5638 5516
5639 record_unwind_current_buffer (); 5517 If DELAY, assume we're being called from a signal handler, and queue
5518 the change for later - perhaps the next redisplay. Since this tries
5519 to resize windows, we can't call it from a signal handler.
5640 5520
5641 run_window_configuration_change_hook (f); 5521 SAFE means this function is called from a place where it's safe to
5522 change frame sizes while a redisplay is in progress. */
5523void
5524change_frame_size (struct frame *f, int new_width, int new_height,
5525 bool pretend, bool delay, bool safe, bool pixelwise)
5526{
5527 Lisp_Object tail, frame;
5642 5528
5643 unbind_to (count, Qnil); 5529 if (FRAME_MSDOS_P (f))
5530 {
5531 /* On MS-DOS, all frames use the same screen, so a change in
5532 size affects all frames. Termcap now supports multiple
5533 ttys. */
5534 FOR_EACH_FRAME (tail, frame)
5535 if (! FRAME_WINDOW_P (XFRAME (frame)))
5536 change_frame_size_1 (XFRAME (frame), new_width, new_height,
5537 pretend, delay, safe, pixelwise);
5538 }
5539 else
5540 change_frame_size_1 (f, new_width, new_height, pretend, delay, safe,
5541 pixelwise);
5644} 5542}
5645 5543
5646/*********************************************************************** 5544/***********************************************************************
@@ -6171,7 +6069,8 @@ init_display (void)
6171 t->display_info.tty->top_frame = selected_frame; 6069 t->display_info.tty->top_frame = selected_frame;
6172 change_frame_size (XFRAME (selected_frame), 6070 change_frame_size (XFRAME (selected_frame),
6173 FrameCols (t->display_info.tty), 6071 FrameCols (t->display_info.tty),
6174 FrameRows (t->display_info.tty), 0, 0, 1, 0); 6072 FrameRows (t->display_info.tty)
6073 - FRAME_MENU_BAR_LINES (f), 0, 0, 1, 0);
6175 6074
6176 /* Delete the initial terminal. */ 6075 /* Delete the initial terminal. */
6177 if (--initial_terminal->reference_count == 0 6076 if (--initial_terminal->reference_count == 0
@@ -6193,7 +6092,7 @@ init_display (void)
6193 { 6092 {
6194 struct frame *sf = SELECTED_FRAME (); 6093 struct frame *sf = SELECTED_FRAME ();
6195 int width = FRAME_TOTAL_COLS (sf); 6094 int width = FRAME_TOTAL_COLS (sf);
6196 int height = FRAME_LINES (sf); 6095 int height = FRAME_TOTAL_LINES (sf);
6197 6096
6198 /* If these sizes are so big they cause overflow, just ignore the 6097 /* If these sizes are so big they cause overflow, just ignore the
6199 change. It's not clear what better we could do. The rest of 6098 change. It's not clear what better we could do. The rest of
diff --git a/src/eval.c b/src/eval.c
index 7d54ddb18f5..4b2e256a722 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -92,10 +92,8 @@ static EMACS_INT when_entered_debugger;
92/* FIXME: We should probably get rid of this! */ 92/* FIXME: We should probably get rid of this! */
93Lisp_Object Vsignaling_function; 93Lisp_Object Vsignaling_function;
94 94
95/* If non-nil, Lisp code must not be run since some part of Emacs is 95/* If non-nil, Lisp code must not be run since some part of Emacs is in
96 in an inconsistent state. Currently, x-create-frame uses this to 96 an inconsistent state. Currently unused. */
97 avoid triggering window-configuration-change-hook while the new
98 frame is half-initialized. */
99Lisp_Object inhibit_lisp_code; 97Lisp_Object inhibit_lisp_code;
100 98
101/* These would ordinarily be static, but they need to be visible to GDB. */ 99/* These would ordinarily be static, but they need to be visible to GDB. */
diff --git a/src/frame.c b/src/frame.c
index 80046bee788..0501b1e2c9c 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -85,6 +85,7 @@ Lisp_Object Qright_divider_width, Qbottom_divider_width;
85Lisp_Object Qmouse_color; 85Lisp_Object Qmouse_color;
86Lisp_Object Qminibuffer; 86Lisp_Object Qminibuffer;
87Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; 87Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
88Lisp_Object Qscroll_bar_height, Qhorizontal_scroll_bars;
88Lisp_Object Qvisibility; 89Lisp_Object Qvisibility;
89Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; 90Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
90Lisp_Object Qscreen_gamma; 91Lisp_Object Qscreen_gamma;
@@ -116,7 +117,7 @@ Lisp_Object Qface_set_after_frame_default;
116static Lisp_Object Qfocus_in_hook; 117static Lisp_Object Qfocus_in_hook;
117static Lisp_Object Qfocus_out_hook; 118static Lisp_Object Qfocus_out_hook;
118static Lisp_Object Qdelete_frame_functions; 119static Lisp_Object Qdelete_frame_functions;
119 120static Lisp_Object Qframe_windows_min_size;
120static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource; 121static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
121 122
122/* The currently selected frame. */ 123/* The currently selected frame. */
@@ -193,6 +194,48 @@ check_window_system (struct frame *f)
193 : "Window system is not in use or not initialized"); 194 : "Window system is not in use or not initialized");
194} 195}
195 196
197
198/* Return the value of frame parameter PROP in frame FRAME. */
199#ifdef HAVE_WINDOW_SYSTEM
200Lisp_Object
201get_frame_param (register struct frame *frame, Lisp_Object prop)
202{
203 register Lisp_Object tem;
204
205 tem = Fassq (prop, frame->param_alist);
206 if (EQ (tem, Qnil))
207 return tem;
208 return Fcdr (tem);
209}
210#endif
211
212
213/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
214 state of frame F would be affected by a vertical (horizontal if
215 HORIZONTAL is true) resize. */
216bool
217frame_inhibit_resize (struct frame *f, bool horizontal)
218{
219
220 return (frame_inhibit_implied_resize
221 || !NILP (get_frame_param (f, Qfullscreen)));
222}
223
224#if 0
225bool
226frame_inhibit_resize (struct frame *f, bool horizontal)
227{
228 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
229
230 return (frame_inhibit_implied_resize
231 || EQ (fullscreen, Qfullboth)
232 || EQ (fullscreen, Qfullscreen)
233 || EQ (fullscreen, Qmaximized)
234 || (horizontal && EQ (fullscreen, Qfullwidth))
235 || (!horizontal && EQ (fullscreen, Qfullheight)));
236}
237#endif
238
196static void 239static void
197set_menu_bar_lines_1 (Lisp_Object window, int n) 240set_menu_bar_lines_1 (Lisp_Object window, int n)
198{ 241{
@@ -324,6 +367,247 @@ predicates which report frame's specific UI-related capabilities. */)
324 return type; 367 return type;
325} 368}
326 369
370int
371frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal, Lisp_Object pixelwise)
372{
373 return XINT (call3 (Qframe_windows_min_size, frame, horizontal, pixelwise));
374}
375
376
377/* Make sure windows sizes of frame F are OK. new_width and new_height
378 are in pixels. A value of -1 means no change is requested for that
379 size (but the frame may still have to be resized to accomodate
380 windows with their minimum sizes.
381
382 The argument INHIBIT can assume the following values:
383
384 0 means to unconditionally call x_set_window_size even if sizes
385 apparently do not change. Fx_create_frame uses this to pass the
386 initial size to the window manager.
387
388 1 means to call x_set_window_size iff the pixel size really changes.
389 Fset_frame_size, Fset_frame_height, ... use this.
390
391 2 means to unconditionally call x_set_window_size provided
392 frame_inhibit_resize allows it. The menu bar code uses this.
393
394 3 means call x_set_window_size iff window minimum sizes must be
395 preserved or frame_inhibit_resize allows it, x_set_left_fringe,
396 x_set_scroll_bar_width, ... use this.
397
398 4 means call x_set_window_size iff window minimum sizes must be
399 preserved. x_set_tool_bar_lines, x_set_right_divider_width, ... use
400 this. BUT maybe the toolbar code shouldn't ....
401
402 5 means to never call x_set_window_size. change_frame_size uses
403 this.
404
405 For 2 and 3 note that if frame_inhibit_resize inhibits resizing and
406 minimum sizes are not violated no internal resizing takes place
407 either. For 2, 3, 4 and 5 note that even if no x_set_window_size
408 call is issued, window sizes may have to be adjusted in order to
409 support minimum size constraints for the frame's windows.
410
411 PRETEND is as for change_frame_size. */
412void
413adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, bool pretend)
414{
415 int unit_width = FRAME_COLUMN_WIDTH (f);
416 int unit_height = FRAME_LINE_HEIGHT (f);
417 int old_pixel_width = FRAME_PIXEL_WIDTH (f);
418 int old_pixel_height = FRAME_PIXEL_HEIGHT (f);
419 int new_pixel_width, new_pixel_height;
420 /* The following two values are calculated from the old frame pixel
421 sizes and any "new" settings for tool bar, menu bar and internal
422 borders. We do it this way to detect whether we have to call
423 x_set_window_size as consequence of the new settings. */
424 int windows_width = FRAME_WINDOWS_WIDTH (f);
425 int windows_height = FRAME_WINDOWS_HEIGHT (f);
426 int min_windows_width, min_windows_height;
427 /* These are a bit tedious, maybe we should use a macro. */
428 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
429 int old_windows_width = WINDOW_PIXEL_WIDTH (r);
430 int old_windows_height
431 = (WINDOW_PIXEL_HEIGHT (r)
432 + (FRAME_HAS_MINIBUF_P (f)
433 ? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f)))
434 : 0));
435 int new_windows_width, new_windows_height;
436 int old_text_width = FRAME_TEXT_WIDTH (f);
437 int old_text_height = FRAME_TEXT_HEIGHT (f);
438 /* If a size is < 0 use the old value. */
439 int new_text_width = (new_width >= 0) ? new_width : old_text_width;
440 int new_text_height = (new_height >= 0) ? new_height : old_text_height;
441 int new_cols, new_lines;
442 bool inhibit_horizontal, inhibit_vertical;
443 Lisp_Object frame;
444
445 XSETFRAME (frame, f);
446 /* The following two values are calculated from the old window body
447 sizes and any "new" settings for scroll bars, dividers, fringes and
448 margins (though the latter should have been processed already). */
449 min_windows_width = frame_windows_min_size (frame, Qt, Qt);
450 min_windows_height = frame_windows_min_size (frame, Qnil, Qt);
451
452 if (inhibit >= 2 && inhibit <= 4)
453 /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay
454 within the limits and either frame_inhibit_resize tells us to do
455 so or INHIBIT equals 4. */
456 {
457 inhibit_horizontal = ((windows_width >= min_windows_width
458 && (inhibit == 4 || frame_inhibit_resize (f, true)))
459 ? true : false);
460 inhibit_vertical = ((windows_height >= min_windows_height
461 && (inhibit == 4 || frame_inhibit_resize (f, false)))
462 ? true : false);
463 }
464 else
465 /* Otherwise inhibit if INHIBIT equals 5. */
466 inhibit_horizontal = inhibit_vertical = inhibit == 5;
467
468 new_pixel_width = ((inhibit_horizontal && (inhibit < 5))
469 ? old_pixel_width
470 : max (FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width),
471 min_windows_width
472 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
473 new_windows_width = new_pixel_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
474 new_text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, new_pixel_width);
475 new_cols = new_text_width / unit_width;
476
477 new_pixel_height = ((inhibit_vertical && (inhibit < 5))
478 ? old_pixel_height
479 : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
480 min_windows_height
481 + FRAME_TOP_MARGIN_HEIGHT (f)
482 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
483 new_windows_height = (new_pixel_height
484 - FRAME_TOP_MARGIN_HEIGHT (f)
485 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
486 new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_pixel_height);
487 new_lines = new_text_height / unit_height;
488
489#ifdef HAVE_WINDOW_SYSTEM
490 if (FRAME_X_WINDOW (f)
491 && f->official
492 && ((!inhibit_horizontal
493 && (new_pixel_width != old_pixel_width
494 || inhibit == 0 || inhibit == 2))
495 || (!inhibit_vertical
496 && (new_pixel_height != old_pixel_height
497 || inhibit == 0 || inhibit == 2))))
498 /* We are either allowed to change the frame size or the minimum
499 sizes request such a change. Do not care for fixing minimum
500 sizes here, we do that eventually when we're called from
501 change_frame_size. */
502 {
503 /* Make sure we respect fullheight and fullwidth. */
504 if (inhibit_horizontal)
505 new_text_width = old_text_width;
506 else if (inhibit_vertical)
507 new_text_height = old_text_height;
508
509 x_set_window_size (f, 0, new_text_width, new_text_height, 1);
510 f->resized_p = true;
511
512 return;
513 }
514#endif
515
516 if (new_text_width == old_text_width
517 && new_text_height == old_text_height
518 && new_windows_width == old_windows_width
519 && new_windows_height == old_windows_height
520 && new_pixel_width == old_pixel_width
521 && new_pixel_height == old_pixel_height)
522 /* No change. Sanitize window sizes and return. */
523 {
524 sanitize_window_sizes (frame, Qt);
525 sanitize_window_sizes (frame, Qnil);
526
527 return;
528 }
529
530 block_input ();
531
532#ifdef MSDOS
533 /* We only can set screen dimensions to certain values supported
534 by our video hardware. Try to find the smallest size greater
535 or equal to the requested dimensions. */
536 dos_set_window_size (&new_lines, &new_cols);
537#endif
538
539 if (new_windows_width != old_windows_width)
540 {
541 resize_frame_windows (f, new_windows_width, 1, 1);
542
543 /* MSDOS frames cannot PRETEND, as they change frame size by
544 manipulating video hardware. */
545 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
546 FrameCols (FRAME_TTY (f)) = new_cols;
547
548#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
549 if (WINDOWP (f->tool_bar_window))
550 {
551 XWINDOW (f->tool_bar_window)->pixel_width = new_windows_width;
552 XWINDOW (f->tool_bar_window)->total_cols
553 = new_windows_width / unit_width;
554 }
555#endif
556 }
557
558 if (new_windows_height != old_windows_height
559 /* When the top margin has changed we have to recalculate the top
560 edges of all windows. No such calculation is necessary for the
561 left edges. */
562 || WINDOW_TOP_PIXEL_EDGE (r) != FRAME_TOP_MARGIN_HEIGHT (f))
563 {
564 resize_frame_windows (f, new_windows_height, 0, 1);
565
566 /* MSDOS frames cannot PRETEND, as they change frame size by
567 manipulating video hardware. */
568 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
569 FrameRows (FRAME_TTY (f)) = new_lines;
570 }
571
572 /* Assign new sizes. */
573 FRAME_TEXT_WIDTH (f) = new_text_width;
574 FRAME_TEXT_HEIGHT (f) = new_text_height;
575 FRAME_PIXEL_WIDTH (f) = new_pixel_width;
576 FRAME_PIXEL_HEIGHT (f) = new_pixel_height;
577 SET_FRAME_COLS (f, new_cols);
578 SET_FRAME_LINES (f, new_lines);
579
580 {
581 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
582 int text_area_x, text_area_y, text_area_width, text_area_height;
583
584 window_box (w, TEXT_AREA, &text_area_x, &text_area_y, &text_area_width,
585 &text_area_height);
586 if (w->cursor.x >= text_area_x + text_area_width)
587 w->cursor.hpos = w->cursor.x = 0;
588 if (w->cursor.y >= text_area_y + text_area_height)
589 w->cursor.vpos = w->cursor.y = 0;
590 }
591
592 /* Sanitize window sizes. */
593 sanitize_window_sizes (frame, Qt);
594 sanitize_window_sizes (frame, Qnil);
595
596 adjust_frame_glyphs (f);
597 calculate_costs (f);
598 SET_FRAME_GARBAGED (f);
599
600 /* A frame was "resized" if one of its pixelsizes changed, even if its
601 X window wasn't resized at all. */
602 f->resized_p = (new_pixel_width != old_pixel_width
603 || new_pixel_height != old_pixel_height);
604
605 unblock_input ();
606
607 run_window_configuration_change_hook (f);
608}
609
610
327struct frame * 611struct frame *
328make_frame (bool mini_p) 612make_frame (bool mini_p)
329{ 613{
@@ -349,10 +633,12 @@ make_frame (bool mini_p)
349 f->wants_modeline = true; 633 f->wants_modeline = true;
350 f->redisplay = true; 634 f->redisplay = true;
351 f->garbaged = true; 635 f->garbaged = true;
636 f->official = false;
352 f->column_width = 1; /* !FRAME_WINDOW_P value. */ 637 f->column_width = 1; /* !FRAME_WINDOW_P value. */
353 f->line_height = 1; /* !FRAME_WINDOW_P value. */ 638 f->line_height = 1; /* !FRAME_WINDOW_P value. */
354#ifdef HAVE_WINDOW_SYSTEM 639#ifdef HAVE_WINDOW_SYSTEM
355 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 640 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
641 f->horizontal_scroll_bars = false;
356 f->want_fullscreen = FULLSCREEN_NONE; 642 f->want_fullscreen = FULLSCREEN_NONE;
357#if ! defined (USE_GTK) && ! defined (HAVE_NS) 643#if ! defined (USE_GTK) && ! defined (HAVE_NS)
358 f->last_tool_bar_item = -1; 644 f->last_tool_bar_item = -1;
@@ -382,10 +668,10 @@ make_frame (bool mini_p)
382 668
383 /* 10 is arbitrary, 669 /* 10 is arbitrary,
384 just so that there is "something there." 670 just so that there is "something there."
385 Correct size will be set up later with change_frame_size. */ 671 Correct size will be set up later with adjust_frame_size. */
386 672
387 SET_FRAME_COLS (f, 10); 673 SET_FRAME_COLS (f, 10);
388 FRAME_LINES (f) = 10; 674 SET_FRAME_LINES (f, 10);
389 SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f)); 675 SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
390 SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f)); 676 SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
391 677
@@ -423,11 +709,15 @@ make_frame (bool mini_p)
423 } 709 }
424 710
425 if (mini_p) 711 if (mini_p)
426 set_window_buffer (mini_window, 712 {
427 (NILP (Vminibuffer_list) 713 set_window_buffer (mini_window,
428 ? get_minibuffer (0) 714 (NILP (Vminibuffer_list)
429 : Fcar (Vminibuffer_list)), 715 ? get_minibuffer (0)
430 0, 0); 716 : Fcar (Vminibuffer_list)),
717 0, 0);
718 /* No horizontal scroll bars in minibuffers. */
719 wset_horizontal_scroll_bar (mw, Qnil);
720 }
431 721
432 fset_root_window (f, root_window); 722 fset_root_window (f, root_window);
433 fset_selected_window (f, root_window); 723 fset_selected_window (f, root_window);
@@ -573,6 +863,7 @@ make_initial_frame (void)
573 863
574#ifdef HAVE_WINDOW_SYSTEM 864#ifdef HAVE_WINDOW_SYSTEM
575 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 865 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
866 FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) = false;
576#endif 867#endif
577 868
578 /* The default value of menu-bar-mode is t. */ 869 /* The default value of menu-bar-mode is t. */
@@ -625,6 +916,7 @@ make_terminal_frame (struct terminal *terminal)
625 916
626#ifdef HAVE_WINDOW_SYSTEM 917#ifdef HAVE_WINDOW_SYSTEM
627 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 918 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
919 FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) = false;
628#endif 920#endif
629 921
630 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1; 922 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
@@ -748,7 +1040,7 @@ affects all frames on the same terminal device. */)
748 { 1040 {
749 int width, height; 1041 int width, height;
750 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height); 1042 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
751 change_frame_size (f, width, height, 0, 0, 0, 0); 1043 adjust_frame_size (f, width, height, 5, 0);
752 } 1044 }
753 1045
754 adjust_frame_glyphs (f); 1046 adjust_frame_glyphs (f);
@@ -1983,21 +2275,6 @@ If there is no window system support, this function does nothing. */)
1983} 2275}
1984 2276
1985 2277
1986/* Return the value of frame parameter PROP in frame FRAME. */
1987
1988#ifdef HAVE_WINDOW_SYSTEM
1989Lisp_Object
1990get_frame_param (register struct frame *frame, Lisp_Object prop)
1991{
1992 register Lisp_Object tem;
1993
1994 tem = Fassq (prop, frame->param_alist);
1995 if (EQ (tem, Qnil))
1996 return tem;
1997 return Fcdr (tem);
1998}
1999#endif
2000
2001/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */ 2278/* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2002 2279
2003void 2280void
@@ -2240,7 +2517,7 @@ If FRAME is omitted or nil, return information on the currently selected frame.
2240 ? (f->new_pixelwise 2517 ? (f->new_pixelwise
2241 ? (f->new_height / FRAME_LINE_HEIGHT (f)) 2518 ? (f->new_height / FRAME_LINE_HEIGHT (f))
2242 : f->new_height) 2519 : f->new_height)
2243 : FRAME_LINES (f)) - FRAME_TOP_MARGIN (f); 2520 : FRAME_LINES (f));
2244 store_in_alist (&alist, Qheight, make_number (height)); 2521 store_in_alist (&alist, Qheight, make_number (height));
2245 width = (f->new_width 2522 width = (f->new_width
2246 ? (f->new_pixelwise 2523 ? (f->new_pixelwise
@@ -2511,12 +2788,19 @@ DEFUN ("frame-text-lines", Fframe_text_lines, Sframe_text_lines, 0, 1, 0,
2511} 2788}
2512 2789
2513DEFUN ("frame-total-cols", Fframe_total_cols, Sframe_total_cols, 0, 1, 0, 2790DEFUN ("frame-total-cols", Fframe_total_cols, Sframe_total_cols, 0, 1, 0,
2514 doc: /* Return total columns of FRAME. */) 2791 doc: /* Return number of total columns of FRAME. */)
2515 (Lisp_Object frame) 2792 (Lisp_Object frame)
2516{ 2793{
2517 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame))); 2794 return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame)));
2518} 2795}
2519 2796
2797DEFUN ("frame-total-lines", Fframe_total_lines, Sframe_total_lines, 0, 1, 0,
2798 doc: /* Return number of total lines of FRAME. */)
2799 (Lisp_Object frame)
2800{
2801 return make_number (FRAME_TOTAL_LINES (decode_any_frame (frame)));
2802}
2803
2520DEFUN ("frame-text-width", Fframe_text_width, Sframe_text_width, 0, 1, 0, 2804DEFUN ("frame-text-width", Fframe_text_width, Sframe_text_width, 0, 1, 0,
2521 doc: /* Return text area width of FRAME in pixels. */) 2805 doc: /* Return text area width of FRAME in pixels. */)
2522 (Lisp_Object frame) 2806 (Lisp_Object frame)
@@ -2538,6 +2822,13 @@ DEFUN ("frame-scroll-bar-width", Fscroll_bar_width, Sscroll_bar_width, 0, 1, 0,
2538 return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame))); 2822 return make_number (FRAME_SCROLL_BAR_AREA_WIDTH (decode_any_frame (frame)));
2539} 2823}
2540 2824
2825DEFUN ("frame-scroll-bar-height", Fscroll_bar_height, Sscroll_bar_height, 0, 1, 0,
2826 doc: /* Return scroll bar height of FRAME in pixels. */)
2827 (Lisp_Object frame)
2828{
2829 return make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (decode_any_frame (frame)));
2830}
2831
2541DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0, 2832DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
2542 doc: /* Return fringe width of FRAME in pixels. */) 2833 doc: /* Return fringe width of FRAME in pixels. */)
2543 (Lisp_Object frame) 2834 (Lisp_Object frame)
@@ -2566,20 +2857,6 @@ DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_widt
2566 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame))); 2857 return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame)));
2567} 2858}
2568 2859
2569/* For requested height in *HEIGHTP, calculate new height of frame F in
2570 character units and return true if actual height should be changed. */
2571
2572static bool
2573adjust_frame_height (struct frame *f, int *heightp)
2574{
2575 if (FRAME_LINES (f) - FRAME_TOP_MARGIN (f) != *heightp)
2576 {
2577 *heightp += FRAME_TOP_MARGIN (f);
2578 return 1;
2579 }
2580 return 0;
2581}
2582
2583DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, 0, 2860DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, 0,
2584 doc: /* Specify that the frame FRAME has HEIGHT text lines. 2861 doc: /* Specify that the frame FRAME has HEIGHT text lines.
2585Optional third arg PRETEND non-nil means that redisplay should use 2862Optional third arg PRETEND non-nil means that redisplay should use
@@ -2588,33 +2865,17 @@ not be changed. Optional fourth argument PIXELWISE non-nil means that
2588FRAME should be HEIGHT pixels high. */) 2865FRAME should be HEIGHT pixels high. */)
2589 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise) 2866 (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
2590{ 2867{
2591 register struct frame *f = decode_live_frame (frame); 2868 struct frame *f = decode_live_frame (frame);
2869 int pixel_height;
2592 2870
2593 CHECK_TYPE_RANGED_INTEGER (int, height); 2871 CHECK_TYPE_RANGED_INTEGER (int, height);
2594 2872
2595 /* I think this should be done with a hook. */ 2873 pixel_height = (!NILP (pixelwise)
2596#ifdef HAVE_WINDOW_SYSTEM 2874 ? XINT (height)
2597 if (FRAME_WINDOW_P (f)) 2875 : XINT (height) * FRAME_LINE_HEIGHT (f));
2598 { 2876 if (pixel_height != FRAME_TEXT_HEIGHT (f))
2599 if (NILP (pixelwise)) 2877 adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend));
2600 {
2601 int h = XINT (height);
2602
2603 if (adjust_frame_height (f, &h))
2604 x_set_window_size (f, 1, FRAME_COLS (f), h, 0);
2605 2878
2606 do_pending_window_change (0);
2607 }
2608 else if (XINT (height) != FRAME_TEXT_HEIGHT (f))
2609 {
2610 x_set_window_size (f, 1, FRAME_TEXT_WIDTH (f), XINT (height), 1);
2611 do_pending_window_change (0);
2612 }
2613 }
2614 else
2615#endif
2616 change_frame_size (f, 0, XINT (height), !NILP (pretend), 0, 0,
2617 NILP (pixelwise) ? 0 : 1);
2618 return Qnil; 2879 return Qnil;
2619} 2880}
2620 2881
@@ -2626,31 +2887,17 @@ be changed. Optional fourth argument PIXELWISE non-nil means that FRAME
2626should be WIDTH pixels wide. */) 2887should be WIDTH pixels wide. */)
2627 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise) 2888 (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
2628{ 2889{
2629 register struct frame *f = decode_live_frame (frame); 2890 struct frame *f = decode_live_frame (frame);
2891 int pixel_width;
2630 2892
2631 CHECK_TYPE_RANGED_INTEGER (int, width); 2893 CHECK_TYPE_RANGED_INTEGER (int, width);
2632 2894
2633 /* I think this should be done with a hook. */ 2895 pixel_width = (!NILP (pixelwise)
2634#ifdef HAVE_WINDOW_SYSTEM 2896 ? XINT (width)
2635 if (FRAME_WINDOW_P (f)) 2897 : XINT (width) * FRAME_COLUMN_WIDTH (f));
2636 { 2898 if (pixel_width != FRAME_TEXT_WIDTH (f))
2637 if (NILP (pixelwise)) 2899 adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend));
2638 {
2639 if (XINT (width) != FRAME_COLS (f))
2640 x_set_window_size (f, 1, XINT (width), FRAME_LINES (f), 0);
2641 2900
2642 do_pending_window_change (0);
2643 }
2644 else if (XINT (width) != FRAME_TEXT_WIDTH (f))
2645 {
2646 x_set_window_size (f, 1, XINT (width), FRAME_TEXT_HEIGHT (f), 1);
2647 do_pending_window_change (0);
2648 }
2649 }
2650 else
2651#endif
2652 change_frame_size (f, XINT (width), 0, !NILP (pretend), 0, 0,
2653 NILP (pixelwise) ? 0 : 1);
2654 return Qnil; 2901 return Qnil;
2655} 2902}
2656 2903
@@ -2659,34 +2906,22 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 4, 0,
2659Optional argument PIXELWISE non-nil means to measure in pixels. */) 2906Optional argument PIXELWISE non-nil means to measure in pixels. */)
2660 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise) 2907 (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
2661{ 2908{
2662 register struct frame *f = decode_live_frame (frame); 2909 struct frame *f = decode_live_frame (frame);
2910 int pixel_width, pixel_height;
2663 2911
2664 CHECK_TYPE_RANGED_INTEGER (int, width); 2912 CHECK_TYPE_RANGED_INTEGER (int, width);
2665 CHECK_TYPE_RANGED_INTEGER (int, height); 2913 CHECK_TYPE_RANGED_INTEGER (int, height);
2666 2914
2667 /* I think this should be done with a hook. */ 2915 pixel_width = (!NILP (pixelwise)
2668#ifdef HAVE_WINDOW_SYSTEM 2916 ? XINT (width)
2669 if (FRAME_WINDOW_P (f)) 2917 : XINT (width) * FRAME_COLUMN_WIDTH (f));
2670 { 2918 pixel_height = (!NILP (pixelwise)
2671 int h = XINT (height); 2919 ? XINT (height)
2672 2920 : XINT (height) * FRAME_LINE_HEIGHT (f));
2673 if (!NILP (pixelwise) 2921
2674 ? (XINT (width) != FRAME_TEXT_WIDTH (f) 2922 if (pixel_width != FRAME_TEXT_WIDTH (f)
2675 || h != FRAME_TEXT_HEIGHT (f) 2923 || pixel_height != FRAME_TEXT_HEIGHT (f))
2676 || f->new_height || f->new_width) 2924 adjust_frame_size (f, pixel_width, pixel_height, 1, 0);
2677 : (adjust_frame_height (f, &h)
2678 || XINT (width) != FRAME_COLS (f)
2679 || f->new_height || f->new_width))
2680 {
2681 x_set_window_size (f, 1, XINT (width), h,
2682 NILP (pixelwise) ? 0 : 1);
2683 do_pending_window_change (0);
2684 }
2685 }
2686 else
2687#endif
2688 change_frame_size (f, XINT (width), XINT (height), 0, 0, 0,
2689 NILP (pixelwise) ? 0 : 1);
2690 2925
2691 return Qnil; 2926 return Qnil;
2692} 2927}
@@ -2751,9 +2986,11 @@ static const struct frame_parm_table frame_parms[] =
2751 {"mouse-color", &Qmouse_color}, 2986 {"mouse-color", &Qmouse_color},
2752 {"name", &Qname}, 2987 {"name", &Qname},
2753 {"scroll-bar-width", &Qscroll_bar_width}, 2988 {"scroll-bar-width", &Qscroll_bar_width},
2989 {"scroll-bar-height", &Qscroll_bar_height},
2754 {"title", &Qtitle}, 2990 {"title", &Qtitle},
2755 {"unsplittable", &Qunsplittable}, 2991 {"unsplittable", &Qunsplittable},
2756 {"vertical-scroll-bars", &Qvertical_scroll_bars}, 2992 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2993 {"horizontal-scroll-bars", &Qhorizontal_scroll_bars},
2757 {"visibility", &Qvisibility}, 2994 {"visibility", &Qvisibility},
2758 {"tool-bar-lines", &Qtool_bar_lines}, 2995 {"tool-bar-lines", &Qtool_bar_lines},
2759 {"scroll-bar-foreground", &Qscroll_bar_foreground}, 2996 {"scroll-bar-foreground", &Qscroll_bar_foreground},
@@ -2786,7 +3023,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
2786 /* If both of these parameters are present, it's more efficient to 3023 /* If both of these parameters are present, it's more efficient to
2787 set them both at once. So we wait until we've looked at the 3024 set them both at once. So we wait until we've looked at the
2788 entire list before we set them. */ 3025 entire list before we set them. */
2789 int width = 0, height = 0; 3026 int width, height;
2790 bool width_change = 0, height_change = 0; 3027 bool width_change = 0, height_change = 0;
2791 3028
2792 /* Same here. */ 3029 /* Same here. */
@@ -2964,9 +3201,6 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
2964 { 3201 {
2965 Lisp_Object frame; 3202 Lisp_Object frame;
2966 3203
2967 /* Make this 1, eventually. */
2968 check_frame_size (f, &width, &height, 1);
2969
2970 XSETFRAME (frame, f); 3204 XSETFRAME (frame, f);
2971 3205
2972 if ((width_change || height_change) 3206 if ((width_change || height_change)
@@ -3117,6 +3351,14 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
3117 for non-toolkit scroll bar. 3351 for non-toolkit scroll bar.
3118 ruler-mode.el depends on this. */ 3352 ruler-mode.el depends on this. */
3119 : Qnil)); 3353 : Qnil));
3354 store_in_alist (alistptr, Qscroll_bar_height,
3355 (! FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)
3356 ? make_number (0)
3357 : FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0
3358 ? make_number (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f))
3359 /* nil means "use default height"
3360 for non-toolkit scroll bar. */
3361 : Qnil));
3120 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on 3362 /* FRAME_X_WINDOW is not guaranteed to return an integer. E.g., on
3121 MS-Windows it returns a value whose type is HANDLE, which is 3363 MS-Windows it returns a value whose type is HANDLE, which is
3122 actually a pointer. Explicit casting avoids compiler 3364 actually a pointer. Explicit casting avoids compiler
@@ -3393,58 +3635,66 @@ x_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
3393 } 3635 }
3394} 3636}
3395 3637
3396
3397void 3638void
3398x_set_fringe_width (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) 3639x_set_left_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3399{ 3640{
3400 compute_fringe_widths (f, 1); 3641 int unit = FRAME_COLUMN_WIDTH (f);
3401#ifdef HAVE_X_WINDOWS 3642 int old_width = FRAME_LEFT_FRINGE_WIDTH (f);
3402 /* Must adjust this so window managers report correct number of columns. */ 3643 int new_width;
3403 if (FRAME_X_WINDOW (f) != 0) 3644
3404 x_wm_set_size_hint (f, 0, 0); 3645 new_width = (RANGED_INTEGERP (-INT_MAX, new_value, INT_MAX)
3405#endif 3646 ? eabs (XINT (new_value)) : 8);
3647
3648 if (new_width != old_width)
3649 {
3650 FRAME_LEFT_FRINGE_WIDTH (f) = new_width;
3651 FRAME_FRINGE_COLS (f) /* Round up. */
3652 = (new_width + FRAME_RIGHT_FRINGE_WIDTH (f) + unit - 1) / unit;
3653
3654 if (FRAME_X_WINDOW (f) != 0)
3655 adjust_frame_size (f, -1, -1, 3, 0);
3656
3657 SET_FRAME_GARBAGED (f);
3658 }
3406} 3659}
3407 3660
3661
3408void 3662void
3409x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 3663x_set_right_fringe (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
3410{ 3664{
3411 CHECK_TYPE_RANGED_INTEGER (int, arg); 3665 int unit = FRAME_COLUMN_WIDTH (f);
3666 int old_width = FRAME_RIGHT_FRINGE_WIDTH (f);
3667 int new_width;
3412 3668
3413 if (XINT (arg) == f->border_width) 3669 new_width = (RANGED_INTEGERP (-INT_MAX, new_value, INT_MAX)
3414 return; 3670 ? eabs (XINT (new_value)) : 8);
3415 3671
3416 if (FRAME_X_WINDOW (f) != 0) 3672 if (new_width != old_width)
3417 error ("Cannot change the border width of a frame"); 3673 {
3674 FRAME_RIGHT_FRINGE_WIDTH (f) = new_width;
3675 FRAME_FRINGE_COLS (f) /* Round up. */
3676 = (new_width + FRAME_LEFT_FRINGE_WIDTH (f) + unit - 1) / unit;
3418 3677
3419 f->border_width = XINT (arg); 3678 if (FRAME_X_WINDOW (f) != 0)
3679 adjust_frame_size (f, -1, -1, 3, 0);
3680
3681 SET_FRAME_GARBAGED (f);
3682 }
3420} 3683}
3421 3684
3685
3422void 3686void
3423x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 3687x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3424{ 3688{
3425 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
3426
3427 CHECK_TYPE_RANGED_INTEGER (int, arg); 3689 CHECK_TYPE_RANGED_INTEGER (int, arg);
3428 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3429 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3430 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
3431 3690
3432#ifdef USE_X_TOOLKIT 3691 if (XINT (arg) == f->border_width)
3433 if (FRAME_X_OUTPUT (f)->edit_widget)
3434 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3435#endif
3436
3437 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
3438 return; 3692 return;
3439 3693
3440 if (FRAME_X_WINDOW (f) != 0) 3694 if (FRAME_X_WINDOW (f) != 0)
3441 { 3695 error ("Cannot change the border width of a frame");
3442 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); 3696
3443 SET_FRAME_GARBAGED (f); 3697 f->border_width = XINT (arg);
3444 do_pending_window_change (0);
3445 }
3446 else
3447 SET_FRAME_GARBAGED (f);
3448} 3698}
3449 3699
3450void 3700void
@@ -3456,18 +3706,13 @@ x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3456 FRAME_RIGHT_DIVIDER_WIDTH (f) = XINT (arg); 3706 FRAME_RIGHT_DIVIDER_WIDTH (f) = XINT (arg);
3457 if (FRAME_RIGHT_DIVIDER_WIDTH (f) < 0) 3707 if (FRAME_RIGHT_DIVIDER_WIDTH (f) < 0)
3458 FRAME_RIGHT_DIVIDER_WIDTH (f) = 0; 3708 FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
3459 3709 if (FRAME_RIGHT_DIVIDER_WIDTH (f) != old)
3460 if (FRAME_RIGHT_DIVIDER_WIDTH (f) == old)
3461 return;
3462
3463 if (FRAME_X_WINDOW (f) != 0)
3464 { 3710 {
3465 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); 3711 adjust_frame_size (f, -1, -1, 4, 0);
3712 adjust_frame_glyphs (f);
3466 SET_FRAME_GARBAGED (f); 3713 SET_FRAME_GARBAGED (f);
3467 do_pending_window_change (0);
3468 } 3714 }
3469 else 3715
3470 SET_FRAME_GARBAGED (f);
3471} 3716}
3472 3717
3473void 3718void
@@ -3479,18 +3724,12 @@ x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3479 FRAME_BOTTOM_DIVIDER_WIDTH (f) = XINT (arg); 3724 FRAME_BOTTOM_DIVIDER_WIDTH (f) = XINT (arg);
3480 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) < 0) 3725 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) < 0)
3481 FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0; 3726 FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
3482 3727 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) != old)
3483 if (FRAME_BOTTOM_DIVIDER_WIDTH (f) == old)
3484 return;
3485
3486 if (FRAME_X_WINDOW (f) != 0)
3487 { 3728 {
3488 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); 3729 adjust_frame_size (f, -1, -1, 4, 0);
3730 adjust_frame_glyphs (f);
3489 SET_FRAME_GARBAGED (f); 3731 SET_FRAME_GARBAGED (f);
3490 do_pending_window_change (0);
3491 } 3732 }
3492 else
3493 SET_FRAME_GARBAGED (f);
3494} 3733}
3495 3734
3496void 3735void
@@ -3531,7 +3770,7 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3531 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) 3770 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3532 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) 3771 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3533 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f)) 3772 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3534 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))) 3773 || (!NILP (arg) && !FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3535 { 3774 {
3536 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) 3775 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3537 = (NILP (arg) 3776 = (NILP (arg)
@@ -3551,13 +3790,35 @@ x_set_vertical_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval
3551 However, if the window hasn't been created yet, we shouldn't 3790 However, if the window hasn't been created yet, we shouldn't
3552 call x_set_window_size. */ 3791 call x_set_window_size. */
3553 if (FRAME_X_WINDOW (f)) 3792 if (FRAME_X_WINDOW (f))
3554 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), 3793 adjust_frame_size (f, -1, -1, 3, 0);
3555 FRAME_TEXT_HEIGHT (f), 1); 3794
3556 do_pending_window_change (0); 3795 SET_FRAME_GARBAGED (f);
3557 } 3796 }
3558} 3797}
3559 3798
3560void 3799void
3800x_set_horizontal_scroll_bars (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3801{
3802#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
3803 if ((NILP (arg) && FRAME_HAS_HORIZONTAL_SCROLL_BARS (f))
3804 || (!NILP (arg) && !FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)))
3805 {
3806 FRAME_HAS_HORIZONTAL_SCROLL_BARS (f)
3807 = NILP (arg) ? false : true;
3808
3809 /* We set this parameter before creating the X window for the
3810 frame, so we can get the geometry right from the start.
3811 However, if the window hasn't been created yet, we shouldn't
3812 call x_set_window_size. */
3813 if (FRAME_X_WINDOW (f))
3814 adjust_frame_size (f, -1, -1, 3, 0);
3815
3816 SET_FRAME_GARBAGED (f);
3817 }
3818#endif
3819}
3820
3821void
3561x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 3822x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3562{ 3823{
3563 int unit = FRAME_COLUMN_WIDTH (f); 3824 int unit = FRAME_COLUMN_WIDTH (f);
@@ -3567,9 +3828,9 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3567 x_set_scroll_bar_default_width (f); 3828 x_set_scroll_bar_default_width (f);
3568 3829
3569 if (FRAME_X_WINDOW (f)) 3830 if (FRAME_X_WINDOW (f))
3570 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), 3831 adjust_frame_size (f, -1, -1, 3, 0);
3571 FRAME_TEXT_HEIGHT (f), 1); 3832
3572 do_pending_window_change (0); 3833 SET_FRAME_GARBAGED (f);
3573 } 3834 }
3574 else if (RANGED_INTEGERP (1, arg, INT_MAX) 3835 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3575 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f)) 3836 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
@@ -3577,19 +3838,47 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3577 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg); 3838 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3578 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit; 3839 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
3579 if (FRAME_X_WINDOW (f)) 3840 if (FRAME_X_WINDOW (f))
3580 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), 3841 adjust_frame_size (f, -1, -1, 3, 0);
3581 FRAME_TEXT_HEIGHT (f), 1); 3842
3582 do_pending_window_change (0); 3843 SET_FRAME_GARBAGED (f);
3583 } 3844 }
3584 3845
3585 /* Eventually remove the following call. It should have been done by
3586 x_set_window_size already. */
3587 change_frame_size (f, 0, 0, 0, 0, 0, 1);
3588 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0; 3846 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3589 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0; 3847 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3590} 3848}
3591 3849
3592void 3850void
3851x_set_scroll_bar_height (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3852{
3853#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
3854 int unit = FRAME_LINE_HEIGHT (f);
3855
3856 if (NILP (arg))
3857 {
3858 x_set_scroll_bar_default_height (f);
3859
3860 if (FRAME_X_WINDOW (f))
3861 adjust_frame_size (f, -1, -1, 3, 0);
3862
3863 SET_FRAME_GARBAGED (f);
3864 }
3865 else if (RANGED_INTEGERP (1, arg, INT_MAX)
3866 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_HEIGHT (f))
3867 {
3868 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = XFASTINT (arg);
3869 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (XFASTINT (arg) + unit - 1) / unit;
3870 if (FRAME_X_WINDOW (f))
3871 adjust_frame_size (f, -1, -1, 3, 0);
3872
3873 SET_FRAME_GARBAGED (f);
3874 }
3875
3876 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.vpos = 0;
3877 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.y = 0;
3878#endif
3879}
3880
3881void
3593x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 3882x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
3594{ 3883{
3595 double alpha = 1.0; 3884 double alpha = 1.0;
@@ -4190,7 +4479,7 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
4190long 4479long
4191x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p) 4480x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4192{ 4481{
4193 register Lisp_Object tem0, tem1, tem2; 4482 Lisp_Object height, width, user_size, top, left, user_position;
4194 long window_prompting = 0; 4483 long window_prompting = 0;
4195 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); 4484 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
4196 4485
@@ -4200,58 +4489,54 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4200 SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f)); 4489 SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
4201 SET_FRAME_COLS (f, DEFAULT_COLS); 4490 SET_FRAME_COLS (f, DEFAULT_COLS);
4202 SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f)); 4491 SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
4203 FRAME_LINES (f) = DEFAULT_ROWS; 4492 SET_FRAME_LINES (f, DEFAULT_ROWS);
4204 4493
4205 /* Window managers expect that if program-specified 4494 /* Window managers expect that if program-specified
4206 positions are not (0,0), they're intentional, not defaults. */ 4495 positions are not (0,0), they're intentional, not defaults. */
4207 f->top_pos = 0; 4496 f->top_pos = 0;
4208 f->left_pos = 0; 4497 f->left_pos = 0;
4209 4498
4210 /* Ensure that old new_width and new_height will not override the 4499 /* Ensure that earlier new_width and new_height settings won't
4211 values set here. */ 4500 override what we specify below. */
4212 /* ++KFS: This was specific to W32, but seems ok for all platforms */ 4501 f->new_width = f->new_height = 0;
4213 f->new_width = f->new_height = f->new_pixelwise = 0;
4214 4502
4215 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER); 4503 height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4216 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER); 4504 width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4217 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER); 4505 if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
4218 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4219 { 4506 {
4220 if (!EQ (tem0, Qunbound)) 4507 if (!EQ (width, Qunbound))
4221 { 4508 {
4222 CHECK_NUMBER (tem0); 4509 CHECK_NUMBER (width);
4223 if (! (0 <= XINT (tem0) && XINT (tem0) <= INT_MAX)) 4510 if (! (0 <= XINT (width) && XINT (width) <= INT_MAX))
4224 xsignal1 (Qargs_out_of_range, tem0); 4511 xsignal1 (Qargs_out_of_range, width);
4225 FRAME_LINES (f) = XINT (tem0); 4512
4513 SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
4226 } 4514 }
4227 if (!EQ (tem1, Qunbound)) 4515
4516 if (!EQ (height, Qunbound))
4228 { 4517 {
4229 CHECK_NUMBER (tem1); 4518 CHECK_NUMBER (height);
4230 if (! (0 <= XINT (tem1) && XINT (tem1) <= INT_MAX)) 4519 if (! (0 <= XINT (height) && XINT (height) <= INT_MAX))
4231 xsignal1 (Qargs_out_of_range, tem1); 4520 xsignal1 (Qargs_out_of_range, height);
4232 SET_FRAME_COLS (f, XINT (tem1)); 4521
4522 SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
4233 } 4523 }
4234 if (!NILP (tem2) && !EQ (tem2, Qunbound)) 4524
4525 user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4526 if (!NILP (user_size) && !EQ (user_size, Qunbound))
4235 window_prompting |= USSize; 4527 window_prompting |= USSize;
4236 else 4528 else
4237 window_prompting |= PSize; 4529 window_prompting |= PSize;
4238 } 4530 }
4239 4531
4240 4532 /* Add a tool bar height to the initial frame height so that the user
4241 /* This used to be done _before_ calling x_figure_window_size, but 4533 gets a text display area of the size he specified with -g or via
4242 since the height is reset here, this was really a no-op. I 4534 .Xdefaults. Later changes of the tool bar height don't change the
4243 assume that moving it here does what Gerd intended (although he 4535 frame size. This is done so that users can create tall Emacs
4244 no longer can remember what that was... ++KFS, 2003-03-25. */ 4536 frames without having to guess how tall the tool bar will get. */
4245 4537 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4246 /* Add the tool-bar height to the initial frame height so that the
4247 user gets a text display area of the size he specified with -g or
4248 via .Xdefaults. Later changes of the tool-bar height don't
4249 change the frame size. This is done so that users can create
4250 tall Emacs frames without having to guess how tall the tool-bar
4251 will get. */
4252 if (toolbar_p && FRAME_TOOL_BAR_HEIGHT (f))
4253 { 4538 {
4254 int margin, relief, bar_height; 4539 int margin, relief;
4255 4540
4256 relief = (tool_bar_button_relief >= 0 4541 relief = (tool_bar_button_relief >= 0
4257 ? tool_bar_button_relief 4542 ? tool_bar_button_relief
@@ -4265,78 +4550,73 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
4265 else 4550 else
4266 margin = 0; 4551 margin = 0;
4267 4552
4268 /* PXW: We should be able to not round here. */ 4553 FRAME_TOOL_BAR_HEIGHT (f)
4269 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; 4554 = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4270 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f); 4555 Vframe_initial_frame_tool_bar_height = make_number (FRAME_TOOL_BAR_HEIGHT (f));
4271 } 4556 }
4272 4557
4273 compute_fringe_widths (f, 0); 4558 top = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4274 4559 left = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4275 SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f)); 4560 user_position = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4276 SET_FRAME_HEIGHT(f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f)); 4561 if (! EQ (top, Qunbound) || ! EQ (left, Qunbound))
4277
4278 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4279 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4280 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4281 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4282 { 4562 {
4283 if (EQ (tem0, Qminus)) 4563 if (EQ (top, Qminus))
4284 { 4564 {
4285 f->top_pos = 0; 4565 f->top_pos = 0;
4286 window_prompting |= YNegative; 4566 window_prompting |= YNegative;
4287 } 4567 }
4288 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus) 4568 else if (CONSP (top) && EQ (XCAR (top), Qminus)
4289 && CONSP (XCDR (tem0)) 4569 && CONSP (XCDR (top))
4290 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem0)), INT_MAX)) 4570 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
4291 { 4571 {
4292 f->top_pos = - XINT (XCAR (XCDR (tem0))); 4572 f->top_pos = - XINT (XCAR (XCDR (top)));
4293 window_prompting |= YNegative; 4573 window_prompting |= YNegative;
4294 } 4574 }
4295 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus) 4575 else if (CONSP (top) && EQ (XCAR (top), Qplus)
4296 && CONSP (XCDR (tem0)) 4576 && CONSP (XCDR (top))
4297 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem0)))) 4577 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
4298 { 4578 {
4299 f->top_pos = XINT (XCAR (XCDR (tem0))); 4579 f->top_pos = XINT (XCAR (XCDR (top)));
4300 } 4580 }
4301 else if (EQ (tem0, Qunbound)) 4581 else if (EQ (top, Qunbound))
4302 f->top_pos = 0; 4582 f->top_pos = 0;
4303 else 4583 else
4304 { 4584 {
4305 CHECK_TYPE_RANGED_INTEGER (int, tem0); 4585 CHECK_TYPE_RANGED_INTEGER (int, top);
4306 f->top_pos = XINT (tem0); 4586 f->top_pos = XINT (top);
4307 if (f->top_pos < 0) 4587 if (f->top_pos < 0)
4308 window_prompting |= YNegative; 4588 window_prompting |= YNegative;
4309 } 4589 }
4310 4590
4311 if (EQ (tem1, Qminus)) 4591 if (EQ (left, Qminus))
4312 { 4592 {
4313 f->left_pos = 0; 4593 f->left_pos = 0;
4314 window_prompting |= XNegative; 4594 window_prompting |= XNegative;
4315 } 4595 }
4316 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus) 4596 else if (CONSP (left) && EQ (XCAR (left), Qminus)
4317 && CONSP (XCDR (tem1)) 4597 && CONSP (XCDR (left))
4318 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem1)), INT_MAX)) 4598 && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
4319 { 4599 {
4320 f->left_pos = - XINT (XCAR (XCDR (tem1))); 4600 f->left_pos = - XINT (XCAR (XCDR (left)));
4321 window_prompting |= XNegative; 4601 window_prompting |= XNegative;
4322 } 4602 }
4323 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus) 4603 else if (CONSP (left) && EQ (XCAR (left), Qplus)
4324 && CONSP (XCDR (tem1)) 4604 && CONSP (XCDR (left))
4325 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem1)))) 4605 && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
4326 { 4606 {
4327 f->left_pos = XINT (XCAR (XCDR (tem1))); 4607 f->left_pos = XINT (XCAR (XCDR (left)));
4328 } 4608 }
4329 else if (EQ (tem1, Qunbound)) 4609 else if (EQ (left, Qunbound))
4330 f->left_pos = 0; 4610 f->left_pos = 0;
4331 else 4611 else
4332 { 4612 {
4333 CHECK_TYPE_RANGED_INTEGER (int, tem1); 4613 CHECK_TYPE_RANGED_INTEGER (int, left);
4334 f->left_pos = XINT (tem1); 4614 f->left_pos = XINT (left);
4335 if (f->left_pos < 0) 4615 if (f->left_pos < 0)
4336 window_prompting |= XNegative; 4616 window_prompting |= XNegative;
4337 } 4617 }
4338 4618
4339 if (!NILP (tem2) && ! EQ (tem2, Qunbound)) 4619 if (!NILP (user_position) && ! EQ (user_position, Qunbound))
4340 window_prompting |= USPosition; 4620 window_prompting |= USPosition;
4341 else 4621 else
4342 window_prompting |= PPosition; 4622 window_prompting |= PPosition;
@@ -4483,6 +4763,7 @@ syms_of_frame (void)
4483{ 4763{
4484 DEFSYM (Qframep, "framep"); 4764 DEFSYM (Qframep, "framep");
4485 DEFSYM (Qframe_live_p, "frame-live-p"); 4765 DEFSYM (Qframe_live_p, "frame-live-p");
4766 DEFSYM (Qframe_windows_min_size, "frame-windows-min-size");
4486 DEFSYM (Qexplicit_name, "explicit-name"); 4767 DEFSYM (Qexplicit_name, "explicit-name");
4487 DEFSYM (Qheight, "height"); 4768 DEFSYM (Qheight, "height");
4488 DEFSYM (Qicon, "icon"); 4769 DEFSYM (Qicon, "icon");
@@ -4601,7 +4882,7 @@ Setting this variable does not affect existing frames, only new ones. */);
4601 Vdefault_frame_alist = Qnil; 4882 Vdefault_frame_alist = Qnil;
4602 4883
4603 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars, 4884 DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars,
4604 doc: /* Default position of scroll bars on this window-system. */); 4885 doc: /* Default position of vertical scroll bars on this window-system. */);
4605#ifdef HAVE_WINDOW_SYSTEM 4886#ifdef HAVE_WINDOW_SYSTEM
4606#if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)) 4887#if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
4607 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by 4888 /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
@@ -4614,6 +4895,14 @@ Setting this variable does not affect existing frames, only new ones. */);
4614 Vdefault_frame_scroll_bars = Qnil; 4895 Vdefault_frame_scroll_bars = Qnil;
4615#endif 4896#endif
4616 4897
4898 DEFVAR_LISP ("default-frame-horizontal-scroll-bars", Vdefault_frame_horizontal_scroll_bars,
4899 doc: /* Default value for horizontal scroll bars on this window-system. */);
4900#ifdef HAVE_WINDOW_SYSTEM
4901 Vdefault_frame_horizontal_scroll_bars = Qt;
4902#else
4903 Vdefault_frame_horizontal_scroll_bars = Qnil;
4904#endif
4905
4617 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion", 4906 DEFVAR_BOOL ("scroll-bar-adjust-thumb-portion",
4618 scroll_bar_adjust_thumb_portion_p, 4907 scroll_bar_adjust_thumb_portion_p,
4619 doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF. 4908 doc: /* Adjust thumb for overscrolling for Gtk+ and MOTIF.
@@ -4690,6 +4979,10 @@ or call the function `tool-bar-mode'. */);
4690 Vtool_bar_mode = Qnil; 4979 Vtool_bar_mode = Qnil;
4691#endif 4980#endif
4692 4981
4982 DEFVAR_LISP ("frame-initial-frame-tool-bar-height", Vframe_initial_frame_tool_bar_height,
4983 doc: /* Height of tool bar of initial frame. */);
4984 Vframe_initial_frame_tool_bar_height = make_number (0);
4985
4693 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame, 4986 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4694 doc: /* Minibufferless frames use this frame's minibuffer. 4987 doc: /* Minibufferless frames use this frame's minibuffer.
4695Emacs cannot create minibufferless frames unless this is set to an 4988Emacs cannot create minibufferless frames unless this is set to an
@@ -4718,11 +5011,19 @@ current values of `frame-char-height' and `frame-char-width'. If this
4718is non-nil, no rounding occurs, hence frame sizes can increase/decrease 5011is non-nil, no rounding occurs, hence frame sizes can increase/decrease
4719by one pixel. 5012by one pixel.
4720 5013
4721With some window managers you have to set this to non-nil in order to 5014With some window managers you may have to set this to non-nil in order
4722fully maximize frames. To resize your initial frame pixelwise, 5015to fully maximize frames. To resize your initial frame pixelwise, set
4723set this option to a non-nil value in your init file. */); 5016this option to a non-nil value in your init file. */);
4724 frame_resize_pixelwise = 0; 5017 frame_resize_pixelwise = 0;
4725 5018
5019 DEFVAR_BOOL ("frame-inhibit-implied-resize", frame_inhibit_implied_resize,
5020 doc: /* Non-nil means do not resize frame implicitly.
5021If this option is nil, setting default font, menubar mode, fringe width,
5022or scroll bar mode of a specific frame may resize the frame in order to
5023preserve the number of columns or lines it displays. If this option is
5024non-nil, no such resizing is done. */);
5025 frame_inhibit_implied_resize = 0;
5026
4726 staticpro (&Vframe_list); 5027 staticpro (&Vframe_list);
4727 5028
4728 defsubr (&Sframep); 5029 defsubr (&Sframep);
@@ -4765,9 +5066,11 @@ set this option to a non-nil value in your init file. */);
4765 defsubr (&Sframe_text_cols); 5066 defsubr (&Sframe_text_cols);
4766 defsubr (&Sframe_text_lines); 5067 defsubr (&Sframe_text_lines);
4767 defsubr (&Sframe_total_cols); 5068 defsubr (&Sframe_total_cols);
5069 defsubr (&Sframe_total_lines);
4768 defsubr (&Sframe_text_width); 5070 defsubr (&Sframe_text_width);
4769 defsubr (&Sframe_text_height); 5071 defsubr (&Sframe_text_height);
4770 defsubr (&Sscroll_bar_width); 5072 defsubr (&Sscroll_bar_width);
5073 defsubr (&Sscroll_bar_height);
4771 defsubr (&Sfringe_width); 5074 defsubr (&Sfringe_width);
4772 defsubr (&Sborder_width); 5075 defsubr (&Sborder_width);
4773 defsubr (&Sright_divider_width); 5076 defsubr (&Sright_divider_width);
diff --git a/src/frame.h b/src/frame.h
index 999a29d56ae..fde815c3b84 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -313,7 +313,6 @@ struct frame
313 ENUM_BF (output_method) output_method : 3; 313 ENUM_BF (output_method) output_method : 3;
314 314
315#ifdef HAVE_WINDOW_SYSTEM 315#ifdef HAVE_WINDOW_SYSTEM
316
317 /* See FULLSCREEN_ enum on top. */ 316 /* See FULLSCREEN_ enum on top. */
318 ENUM_BF (fullscreen_type) want_fullscreen : 4; 317 ENUM_BF (fullscreen_type) want_fullscreen : 4;
319 318
@@ -321,14 +320,26 @@ struct frame
321 display the scroll bars of this type on this frame. */ 320 display the scroll bars of this type on this frame. */
322 ENUM_BF (vertical_scroll_bar_type) vertical_scroll_bar_type : 2; 321 ENUM_BF (vertical_scroll_bar_type) vertical_scroll_bar_type : 2;
323 322
323 /* Nonzero if we should actually display horizontal scroll bars on this frame. */
324 bool_bf horizontal_scroll_bars : 1;
324#endif /* HAVE_WINDOW_SYSTEM */ 325#endif /* HAVE_WINDOW_SYSTEM */
325 326
327 /* Whether new_height and new_width shall be interpreted
328 in pixels. */
329 bool_bf new_pixelwise : 1;
330
331 /* True if frame has been added to Vframe_list and is henceforth
332 considered official. For in-official frames we neither process
333 x_set_window_size requests nor do we allow running
334 window-configuration-change-hook when resizing windows. */
335 bool_bf official : 1;
336
326 /* Bitfield area ends here. */ 337 /* Bitfield area ends here. */
327 338
328 /* Margin at the top of the frame. Used to display the tool-bar. */ 339 /* Number of lines (rounded up) of tool bar. REMOVE THIS */
329 int tool_bar_lines; 340 int tool_bar_lines;
330 341
331 /* Pixel height of tool bar. */ 342 /* Height of frame internal tool bar in pixels. */
332 int tool_bar_height; 343 int tool_bar_height;
333 344
334 int n_tool_bar_rows; 345 int n_tool_bar_rows;
@@ -347,18 +358,22 @@ struct frame
347 /* Cost of deleting n lines on this frame. */ 358 /* Cost of deleting n lines on this frame. */
348 int *delete_n_lines_cost; 359 int *delete_n_lines_cost;
349 360
350 /* Text width of this frame (excluding fringes, scroll bars and 361 /* Text width of this frame (excluding fringes, vertical scroll bar
351 internal border width) and text height (excluding internal border 362 and internal border widths) and text height (excluding menu bar,
352 width) in units of canonical characters. */ 363 tool bar, horizontal scroll bar and internal border widths) in
364 units of canonical characters. */
353 int text_cols, text_lines; 365 int text_cols, text_lines;
354 366
355 /* Total width of this frame (including fringes and scroll bars) in 367 /* Total width of this frame (including fringes, vertical scroll bar
368 and internal border widths) and total height (including menu bar,
369 tool bar, horizontal scroll bar and internal border widths) in
356 units of canonical characters. */ 370 units of canonical characters. */
357 int total_cols; 371 int total_cols, total_lines;
358 372
359 /* Text width of this frame (excluding fringes, scroll bars and 373 /* Text width of this frame (excluding fringes, vertical scroll bar
360 internal border width) and text height (excluding internal border 374 and internal border widths) and text height (excluding menu bar,
361 width) in pixels. */ 375 tool bar, horizontal scroll bar and internal border widths) in
376 pixels. */
362 int text_width, text_height; 377 int text_width, text_height;
363 378
364 /* New text height and width for pending size change. 0 if no change 379 /* New text height and width for pending size change. 0 if no change
@@ -367,14 +382,12 @@ struct frame
367 text width/height of the frame. */ 382 text width/height of the frame. */
368 int new_width, new_height; 383 int new_width, new_height;
369 384
370 /* Whether new_height and new_width shall be interpreted
371 in pixels. */
372 bool new_pixelwise;
373
374 /* Pixel position of the frame window (x and y offsets in root window). */ 385 /* Pixel position of the frame window (x and y offsets in root window). */
375 int left_pos, top_pos; 386 int left_pos, top_pos;
376 387
377 /* Size of the frame window (including internal border widths) in 388 /* Total width of this frame (including fringes, vertical scroll bar
389 and internal border widths) and total height (including menu bar,
390 tool bar, horizontal scroll bar and internal border widths) in
378 pixels. */ 391 pixels. */
379 int pixel_width, pixel_height; 392 int pixel_width, pixel_height;
380 393
@@ -396,9 +409,21 @@ struct frame
396 a highlighting is displayed inside the internal border. */ 409 a highlighting is displayed inside the internal border. */
397 int internal_border_width; 410 int internal_border_width;
398 411
399 /* Width of borders between this frame's windows. */ 412 /* Widths of dividers between this frame's windows in pixels. */
400 int right_divider_width; 413 int right_divider_width, bottom_divider_width;
401 int bottom_divider_width; 414
415 /* Widths of fringes in pixels. */
416 int left_fringe_width, right_fringe_width;
417
418 /* Total width of fringes reserved for drawing truncation bitmaps,
419 continuation bitmaps and alike - REMOVE THIS !!!!. */
420 int fringe_cols;
421
422 /* Number of lines of menu bar. */
423 int menu_bar_lines;
424
425 /* Pixel height of menubar. */
426 int menu_bar_height;
402 427
403 /* Canonical X unit. Width of default font, in pixels. */ 428 /* Canonical X unit. Width of default font, in pixels. */
404 int column_width; 429 int column_width;
@@ -426,22 +451,6 @@ struct frame
426 /* List of font-drivers available on the frame. */ 451 /* List of font-drivers available on the frame. */
427 struct font_driver_list *font_driver_list; 452 struct font_driver_list *font_driver_list;
428 453
429 /* Total width of fringes reserved for drawing truncation bitmaps,
430 continuation bitmaps and alike. The width is in canonical char
431 units of the frame. This must currently be the case because window
432 sizes aren't pixel values. If it weren't the case, we wouldn't be
433 able to split windows horizontally nicely. */
434 int fringe_cols;
435
436 /* The extra width (in pixels) currently allotted for fringes. */
437 int left_fringe_width, right_fringe_width;
438
439 /* Number of lines of menu bar. */
440 int menu_bar_lines;
441
442 /* Pixel height of menubar. */
443 int menu_bar_height;
444
445#if defined (HAVE_X_WINDOWS) 454#if defined (HAVE_X_WINDOWS)
446 /* Used by x_wait_for_event when watching for an X event on this frame. */ 455 /* Used by x_wait_for_event when watching for an X event on this frame. */
447 int wait_event_type; 456 int wait_event_type;
@@ -469,6 +478,14 @@ struct frame
469 int config_scroll_bar_width; 478 int config_scroll_bar_width;
470 int config_scroll_bar_cols; 479 int config_scroll_bar_cols;
471 480
481 /* Configured height of the scroll bar, in pixels and in characters.
482 config_scroll_bar_lines tracks config_scroll_bar_height if the
483 latter is positive; a zero value in config_scroll_bar_height means
484 to compute the actual width on the fly, using
485 config_scroll_bar_lines and the current font width. */
486 int config_scroll_bar_height;
487 int config_scroll_bar_lines;
488
472 /* The baud rate that was used to calculate costs for this frame. */ 489 /* The baud rate that was used to calculate costs for this frame. */
473 int cost_calculation_baud_rate; 490 int cost_calculation_baud_rate;
474 491
@@ -716,8 +733,7 @@ default_pixels_per_inch_y (void)
716/* Pixel width of frame F. */ 733/* Pixel width of frame F. */
717#define FRAME_PIXEL_WIDTH(f) ((f)->pixel_width) 734#define FRAME_PIXEL_WIDTH(f) ((f)->pixel_width)
718 735
719/* Pixel height of frame F, including non-toolkit menu bar and 736/* Pixel height of frame F. */
720 non-toolkit tool bar lines. */
721#define FRAME_PIXEL_HEIGHT(f) ((f)->pixel_height) 737#define FRAME_PIXEL_HEIGHT(f) ((f)->pixel_height)
722 738
723/* Width of frame F, measured in canonical character columns, 739/* Width of frame F, measured in canonical character columns,
@@ -733,7 +749,7 @@ default_pixels_per_inch_y (void)
733#define FRAME_TEXT_WIDTH(f) (f)->text_width 749#define FRAME_TEXT_WIDTH(f) (f)->text_width
734 750
735/* Height of frame F, measured in pixels not including the height 751/* Height of frame F, measured in pixels not including the height
736 for internal borders. */ 752 for scroll bar and internal borders. */
737#define FRAME_TEXT_HEIGHT(f) (f)->text_height 753#define FRAME_TEXT_HEIGHT(f) (f)->text_height
738 754
739/* Number of lines of frame F used for menu bar. 755/* Number of lines of frame F used for menu bar.
@@ -782,6 +798,8 @@ default_pixels_per_inch_y (void)
782#else 798#else
783#define FRAME_EXTERNAL_MENU_BAR(f) false 799#define FRAME_EXTERNAL_MENU_BAR(f) false
784#endif 800#endif
801
802/* True if frame F is currently visible. */
785#define FRAME_VISIBLE_P(f) (f)->visible 803#define FRAME_VISIBLE_P(f) (f)->visible
786 804
787/* True if frame F is currently visible but hidden. */ 805/* True if frame F is currently visible but hidden. */
@@ -828,12 +846,14 @@ default_pixels_per_inch_y (void)
828#define FRAME_FOCUS_FRAME(f) f->focus_frame 846#define FRAME_FOCUS_FRAME(f) f->focus_frame
829 847
830#ifdef HAVE_WINDOW_SYSTEM 848#ifdef HAVE_WINDOW_SYSTEM
831 849
832/* This frame slot says whether scroll bars are currently enabled for frame F, 850/* This frame slot says whether scroll bars are currently enabled for frame F,
833 and which side they are on. */ 851 and which side they are on. */
834#define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((f)->vertical_scroll_bar_type) 852#define FRAME_VERTICAL_SCROLL_BAR_TYPE(f) ((f)->vertical_scroll_bar_type)
835#define FRAME_HAS_VERTICAL_SCROLL_BARS(f) \ 853#define FRAME_HAS_VERTICAL_SCROLL_BARS(f) \
836 ((f)->vertical_scroll_bar_type != vertical_scroll_bar_none) 854 ((f)->vertical_scroll_bar_type != vertical_scroll_bar_none)
855#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \
856 ((f)->horizontal_scroll_bars)
837#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) \ 857#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) \
838 ((f)->vertical_scroll_bar_type == vertical_scroll_bar_left) 858 ((f)->vertical_scroll_bar_type == vertical_scroll_bar_left)
839#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) \ 859#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) \
@@ -854,61 +874,85 @@ default_pixels_per_inch_y (void)
854 If scroll bars are turned off, this is still nonzero. */ 874 If scroll bars are turned off, this is still nonzero. */
855#define FRAME_CONFIG_SCROLL_BAR_WIDTH(f) ((f)->config_scroll_bar_width) 875#define FRAME_CONFIG_SCROLL_BAR_WIDTH(f) ((f)->config_scroll_bar_width)
856 876
877/* Height that a scroll bar in frame F should have, if there is one.
878 Measured in pixels.
879 If scroll bars are turned off, this is still nonzero. */
880#define FRAME_CONFIG_SCROLL_BAR_HEIGHT(f) ((f)->config_scroll_bar_height)
881
857/* Width that a scroll bar in frame F should have, if there is one. 882/* Width that a scroll bar in frame F should have, if there is one.
858 Measured in columns (characters). 883 Measured in columns (characters).
859 If scroll bars are turned off, this is still nonzero. */ 884 If scroll bars are turned off, this is still nonzero. */
860#define FRAME_CONFIG_SCROLL_BAR_COLS(f) ((f)->config_scroll_bar_cols) 885#define FRAME_CONFIG_SCROLL_BAR_COLS(f) ((f)->config_scroll_bar_cols)
861 886
862/* Width of a scroll bar in frame F, measured in columns (characters), 887/* Height that a scroll bar in frame F should have, if there is one.
863 but only if scroll bars are on the left. If scroll bars are on 888 Measured in lines (characters).
864 the right in this frame, or there are no scroll bars, value is 0. */ 889 If scroll bars are turned off, this is still nonzero. */
865 890#define FRAME_CONFIG_SCROLL_BAR_LINES(f) ((f)->config_scroll_bar_lines)
866#define FRAME_LEFT_SCROLL_BAR_COLS(f) \
867 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \
868 ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
869 : 0)
870 891
871/* Width of a left scroll bar in frame F, measured in pixels */ 892/* Width of a left scroll bar in frame F, measured in pixels */
872
873#define FRAME_LEFT_SCROLL_BAR_AREA_WIDTH(f) \ 893#define FRAME_LEFT_SCROLL_BAR_AREA_WIDTH(f) \
874 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \ 894 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \
875 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \ 895 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
876 : 0) 896 : 0)
877 897
878/* Width of a scroll bar in frame F, measured in columns (characters),
879 but only if scroll bars are on the right. If scroll bars are on
880 the left in this frame, or there are no scroll bars, value is 0. */
881
882#define FRAME_RIGHT_SCROLL_BAR_COLS(f) \
883 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \
884 ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
885 : 0)
886
887/* Width of a right scroll bar area in frame F, measured in pixels */ 898/* Width of a right scroll bar area in frame F, measured in pixels */
888
889#define FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH(f) \ 899#define FRAME_RIGHT_SCROLL_BAR_AREA_WIDTH(f) \
890 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \ 900 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \
891 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \ 901 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
892 : 0) 902 : 0)
893 903
894/* Actual width of a scroll bar in frame F, measured in columns. */ 904/* Width of a left scroll bar in frame F, measured in columns
905 (characters), but only if scroll bars are on the left. If scroll
906 bars are on the right in this frame, or there are no scroll bars,
907 value is 0. */
908#define FRAME_LEFT_SCROLL_BAR_COLS(f) \
909 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f) \
910 ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
911 : 0)
895 912
896#define FRAME_SCROLL_BAR_COLS(f) \ 913/* Width of a right scroll bar in frame F, measured in columns
897 (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \ 914 (characters), but only if scroll bars are on the right. If scroll
915 bars are on the left in this frame, or there are no scroll bars,
916 value is 0. */
917#define FRAME_RIGHT_SCROLL_BAR_COLS(f) \
918 (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f) \
898 ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \ 919 ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
899 : 0) 920 : 0)
900 921
901/* Actual width of a scroll bar area in frame F, measured in pixels. */ 922/* Width of a vertical scroll bar area in frame F, measured in
923 pixels. */
924#define FRAME_SCROLL_BAR_AREA_WIDTH(f) \
925 (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
926 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
927 : 0)
902 928
903#define FRAME_SCROLL_BAR_AREA_WIDTH(f) \ 929/* Height of horizontal scroll bar area in frame F, measured in
904 (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \ 930 pixels. */
905 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \ 931#define FRAME_SCROLL_BAR_AREA_HEIGHT(f) \
932 (FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) \
933 ? FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) \
934 : 0)
935
936/* Width of vertical scroll bar in frame F, measured in columns. */
937#define FRAME_SCROLL_BAR_COLS(f) \
938 (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
939 ? FRAME_CONFIG_SCROLL_BAR_COLS (f) \
940 : 0)
941
942/* Height of horizontal scroll bar in frame F, measured in lines. */
943#define FRAME_SCROLL_BAR_LINES(f) \
944 (FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) \
945 ? FRAME_CONFIG_SCROLL_BAR_LINES (f) \
906 : 0) 946 : 0)
907 947
908/* Total width of frame F, in columns (characters), 948/* Total width of frame F, in columns (characters),
909 including the width used by scroll bars if any. */ 949 including the width used by scroll bars if any. */
910#define FRAME_TOTAL_COLS(f) ((f)->total_cols) 950#define FRAME_TOTAL_COLS(f) ((f)->total_cols)
911 951
952/* Total height of frame F, in lines (characters),
953 including the height used by scroll bars if any. */
954#define FRAME_TOTAL_LINES(f) ((f)->total_lines)
955
912/* Set the character widths of frame F. WIDTH specifies a nominal 956/* Set the character widths of frame F. WIDTH specifies a nominal
913 character text width. */ 957 character text width. */
914#define SET_FRAME_COLS(f, width) \ 958#define SET_FRAME_COLS(f, width) \
@@ -917,8 +961,16 @@ default_pixels_per_inch_y (void)
917 + FRAME_SCROLL_BAR_COLS (f) \ 961 + FRAME_SCROLL_BAR_COLS (f) \
918 + FRAME_FRINGE_COLS (f))) 962 + FRAME_FRINGE_COLS (f)))
919 963
920/* Set the pixel widths of frame F. WIDTH specifies a nominal pixel 964/* Set the character heights of frame F. HEIGHT specifies a nominal
921 text width. */ 965 character text height. */
966#define SET_FRAME_LINES(f, height) \
967 ((f)->text_lines = (height), \
968 (f)->total_lines = ((height) \
969 + FRAME_TOP_MARGIN (f) \
970 + FRAME_SCROLL_BAR_LINES (f)))
971
972/* Set the widths of frame F. WIDTH specifies a nominal pixel text
973 width. */
922#define SET_FRAME_WIDTH(f, width) \ 974#define SET_FRAME_WIDTH(f, width) \
923 ((f)->text_width = (width), \ 975 ((f)->text_width = (width), \
924 (f)->pixel_width = ((width) \ 976 (f)->pixel_width = ((width) \
@@ -926,21 +978,23 @@ default_pixels_per_inch_y (void)
926 + FRAME_TOTAL_FRINGE_WIDTH (f) \ 978 + FRAME_TOTAL_FRINGE_WIDTH (f) \
927 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))) 979 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
928 980
929/* Set the pixel heights of frame F. HEIGHT specifies a nominal pixel 981/* Set the heights of frame F. HEIGHT specifies a nominal pixel text
930 text width. */ 982 height. */
931#define SET_FRAME_HEIGHT(f, height) \ 983#define SET_FRAME_HEIGHT(f, height) \
932 ((f)->text_height = (height), \ 984 ((f)->text_height = (height), \
933 (f)->pixel_height = ((height) \ 985 (f)->pixel_height = ((height) \
934 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))) 986 + FRAME_TOP_MARGIN_HEIGHT (f) \
987 + FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
988 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
935 989
936/* Maximum + 1 legitimate value for FRAME_CURSOR_X. */ 990/* Maximum + 1 legitimate value for FRAME_CURSOR_X. */
937
938#define FRAME_CURSOR_X_LIMIT(f) \ 991#define FRAME_CURSOR_X_LIMIT(f) \
939 (FRAME_COLS (f) + FRAME_LEFT_SCROLL_BAR_COLS (f)) 992 (FRAME_COLS (f) + FRAME_LEFT_SCROLL_BAR_COLS (f))
940 993
994/* Nonzero if frame F has scroll bars. */
941#define FRAME_SCROLL_BARS(f) (f->scroll_bars) 995#define FRAME_SCROLL_BARS(f) (f->scroll_bars)
942
943#define FRAME_CONDEMNED_SCROLL_BARS(f) (f->condemned_scroll_bars) 996#define FRAME_CONDEMNED_SCROLL_BARS(f) (f->condemned_scroll_bars)
997
944#define FRAME_MENU_BAR_ITEMS(f) (f->menu_bar_items) 998#define FRAME_MENU_BAR_ITEMS(f) (f->menu_bar_items)
945#define FRAME_COST_BAUD_RATE(f) ((f)->cost_calculation_baud_rate) 999#define FRAME_COST_BAUD_RATE(f) ((f)->cost_calculation_baud_rate)
946 1000
@@ -1053,6 +1107,7 @@ extern void check_window_system (struct frame *);
1053extern void frame_make_pointer_invisible (struct frame *); 1107extern void frame_make_pointer_invisible (struct frame *);
1054extern void frame_make_pointer_visible (struct frame *); 1108extern void frame_make_pointer_visible (struct frame *);
1055extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); 1109extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
1110extern bool frame_inhibit_resize (struct frame *, bool);
1056 1111
1057extern Lisp_Object Vframe_list; 1112extern Lisp_Object Vframe_list;
1058 1113
@@ -1073,12 +1128,10 @@ extern Lisp_Object Vframe_list;
1073/* Canonical y-unit on frame F. 1128/* Canonical y-unit on frame F.
1074 This value currently equals the line height of the frame (which is 1129 This value currently equals the line height of the frame (which is
1075 the height of the default font of F). */ 1130 the height of the default font of F). */
1076
1077#define FRAME_LINE_HEIGHT(F) ((F)->line_height) 1131#define FRAME_LINE_HEIGHT(F) ((F)->line_height)
1078 1132
1079/* Canonical x-unit on frame F. 1133/* Canonical x-unit on frame F.
1080 This value currently equals the average width of the default font of F. */ 1134 This value currently equals the average width of the default font of F. */
1081
1082#define FRAME_COLUMN_WIDTH(F) ((F)->column_width) 1135#define FRAME_COLUMN_WIDTH(F) ((F)->column_width)
1083 1136
1084/* Pixel width of areas used to display truncation marks, continuation 1137/* Pixel width of areas used to display truncation marks, continuation
@@ -1091,7 +1144,6 @@ extern Lisp_Object Vframe_list;
1091 units of the frame. This must currently be the case because window 1144 units of the frame. This must currently be the case because window
1092 sizes aren't pixel values. If it weren't the case, we wouldn't be 1145 sizes aren't pixel values. If it weren't the case, we wouldn't be
1093 able to split windows horizontally nicely. */ 1146 able to split windows horizontally nicely. */
1094
1095#define FRAME_FRINGE_COLS(F) ((F)->fringe_cols) 1147#define FRAME_FRINGE_COLS(F) ((F)->fringe_cols)
1096 1148
1097/* Pixel-width of the left and right fringe. */ 1149/* Pixel-width of the left and right fringe. */
@@ -1134,7 +1186,6 @@ extern Lisp_Object Vframe_list;
1134/* Convert canonical value X to pixels. F is the frame whose 1186/* Convert canonical value X to pixels. F is the frame whose
1135 canonical char width is to be used. X must be a Lisp integer or 1187 canonical char width is to be used. X must be a Lisp integer or
1136 float. Value is a C integer. */ 1188 float. Value is a C integer. */
1137
1138#define FRAME_PIXEL_X_FROM_CANON_X(F, X) \ 1189#define FRAME_PIXEL_X_FROM_CANON_X(F, X) \
1139 (INTEGERP (X) \ 1190 (INTEGERP (X) \
1140 ? XINT (X) * FRAME_COLUMN_WIDTH (F) \ 1191 ? XINT (X) * FRAME_COLUMN_WIDTH (F) \
@@ -1143,7 +1194,6 @@ extern Lisp_Object Vframe_list;
1143/* Convert canonical value Y to pixels. F is the frame whose 1194/* Convert canonical value Y to pixels. F is the frame whose
1144 canonical character height is to be used. X must be a Lisp integer 1195 canonical character height is to be used. X must be a Lisp integer
1145 or float. Value is a C integer. */ 1196 or float. Value is a C integer. */
1146
1147#define FRAME_PIXEL_Y_FROM_CANON_Y(F, Y) \ 1197#define FRAME_PIXEL_Y_FROM_CANON_Y(F, Y) \
1148 (INTEGERP (Y) \ 1198 (INTEGERP (Y) \
1149 ? XINT (Y) * FRAME_LINE_HEIGHT (F) \ 1199 ? XINT (Y) * FRAME_LINE_HEIGHT (F) \
@@ -1153,7 +1203,6 @@ extern Lisp_Object Vframe_list;
1153 canonical character width is to be used. X is a C integer. Result 1203 canonical character width is to be used. X is a C integer. Result
1154 is a Lisp float if X is not a multiple of the canon width, 1204 is a Lisp float if X is not a multiple of the canon width,
1155 otherwise it's a Lisp integer. */ 1205 otherwise it's a Lisp integer. */
1156
1157#define FRAME_CANON_X_FROM_PIXEL_X(F, X) \ 1206#define FRAME_CANON_X_FROM_PIXEL_X(F, X) \
1158 ((X) % FRAME_COLUMN_WIDTH (F) != 0 \ 1207 ((X) % FRAME_COLUMN_WIDTH (F) != 0 \
1159 ? make_float ((double) (X) / FRAME_COLUMN_WIDTH (F)) \ 1208 ? make_float ((double) (X) / FRAME_COLUMN_WIDTH (F)) \
@@ -1163,7 +1212,6 @@ extern Lisp_Object Vframe_list;
1163 canonical character height is to be used. Y is a C integer. 1212 canonical character height is to be used. Y is a C integer.
1164 Result is a Lisp float if Y is not a multiple of the canon width, 1213 Result is a Lisp float if Y is not a multiple of the canon width,
1165 otherwise it's a Lisp integer. */ 1214 otherwise it's a Lisp integer. */
1166
1167#define FRAME_CANON_Y_FROM_PIXEL_Y(F, Y) \ 1215#define FRAME_CANON_Y_FROM_PIXEL_Y(F, Y) \
1168 ((Y) % FRAME_LINE_HEIGHT (F) \ 1216 ((Y) % FRAME_LINE_HEIGHT (F) \
1169 ? make_float ((double) (Y) / FRAME_LINE_HEIGHT (F)) \ 1217 ? make_float ((double) (Y) / FRAME_LINE_HEIGHT (F)) \
@@ -1177,7 +1225,6 @@ extern Lisp_Object Vframe_list;
1177 1225
1178 Return the upper/left pixel position of the character cell on frame F 1226 Return the upper/left pixel position of the character cell on frame F
1179 at ROW/COL. */ 1227 at ROW/COL. */
1180
1181#define FRAME_LINE_TO_PIXEL_Y(f, row) \ 1228#define FRAME_LINE_TO_PIXEL_Y(f, row) \
1182 (((row) < FRAME_TOP_MARGIN (f) ? 0 : FRAME_INTERNAL_BORDER_WIDTH (f)) \ 1229 (((row) < FRAME_TOP_MARGIN (f) ? 0 : FRAME_INTERNAL_BORDER_WIDTH (f)) \
1183 + (row) * FRAME_LINE_HEIGHT (f)) 1230 + (row) * FRAME_LINE_HEIGHT (f))
@@ -1188,25 +1235,27 @@ extern Lisp_Object Vframe_list;
1188 1235
1189/* Return the pixel width/height of frame F if it has 1236/* Return the pixel width/height of frame F if it has
1190 COLS columns/LINES rows. */ 1237 COLS columns/LINES rows. */
1191
1192#define FRAME_TEXT_COLS_TO_PIXEL_WIDTH(f, cols) \ 1238#define FRAME_TEXT_COLS_TO_PIXEL_WIDTH(f, cols) \
1193 (FRAME_COL_TO_PIXEL_X (f, cols) \ 1239 ((cols) * FRAME_COLUMN_WIDTH (f) \
1194 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \ 1240 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
1195 + FRAME_TOTAL_FRINGE_WIDTH (f) \ 1241 + FRAME_TOTAL_FRINGE_WIDTH (f) \
1196 + FRAME_INTERNAL_BORDER_WIDTH (f)) 1242 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1197 1243
1198#define FRAME_TEXT_LINES_TO_PIXEL_HEIGHT(f, lines) \ 1244#define FRAME_TEXT_LINES_TO_PIXEL_HEIGHT(f, lines) \
1199 ((lines) * FRAME_LINE_HEIGHT (f) \ 1245 ((lines) * FRAME_LINE_HEIGHT (f) \
1246 + FRAME_TOP_MARGIN_HEIGHT (f) \
1247 + FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
1200 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1248 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1201 1249
1202/* Return the row/column (zero-based) of the character cell containing 1250/* Return the row/column (zero-based) of the character cell containing
1203 the pixel on FRAME at Y/X. */ 1251 the pixel on FRAME at Y/X. */
1204
1205#define FRAME_PIXEL_Y_TO_LINE(f, y) \ 1252#define FRAME_PIXEL_Y_TO_LINE(f, y) \
1206 (((y) < FRAME_TOP_MARGIN_HEIGHT (f) \ 1253 (((y) < FRAME_TOP_MARGIN_HEIGHT (f) \
1207 ? (y) \ 1254 ? (y) \
1208 : ((y) < FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \ 1255 : ((y) < (FRAME_TOP_MARGIN_HEIGHT (f) \
1209 ? (y) - (FRAME_TOP_MARGIN_HEIGHT (f) + FRAME_INTERNAL_BORDER_WIDTH (f) \ 1256 + FRAME_INTERNAL_BORDER_WIDTH (f)) \
1257 ? (y) - (FRAME_TOP_MARGIN_HEIGHT (f) \
1258 + FRAME_INTERNAL_BORDER_WIDTH (f) \
1210 /* Arrange for the division to round down. */ \ 1259 /* Arrange for the division to round down. */ \
1211 + FRAME_LINE_HEIGHT (f) - 1) \ 1260 + FRAME_LINE_HEIGHT (f) - 1) \
1212 : (y) - FRAME_INTERNAL_BORDER_WIDTH (f))) \ 1261 : (y) - FRAME_INTERNAL_BORDER_WIDTH (f))) \
@@ -1217,21 +1266,23 @@ extern Lisp_Object Vframe_list;
1217 / FRAME_COLUMN_WIDTH (f)) 1266 / FRAME_COLUMN_WIDTH (f))
1218 1267
1219/* How many columns/rows of text can we fit in WIDTH/HEIGHT pixels on 1268/* How many columns/rows of text can we fit in WIDTH/HEIGHT pixels on
1220 frame F? */ 1269 frame F (so we round down)? */
1221
1222#define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width) \ 1270#define FRAME_PIXEL_WIDTH_TO_TEXT_COLS(f, width) \
1223 (FRAME_PIXEL_X_TO_COL (f, ((width) \ 1271 (((width) \
1224 - FRAME_INTERNAL_BORDER_WIDTH (f) \ 1272 - FRAME_TOTAL_FRINGE_WIDTH (f) \
1225 - FRAME_TOTAL_FRINGE_WIDTH (f) \ 1273 - FRAME_SCROLL_BAR_AREA_WIDTH (f) \
1226 - FRAME_SCROLL_BAR_AREA_WIDTH (f)))) \ 1274 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) \
1275 / FRAME_COLUMN_WIDTH (f)) \
1227 1276
1228#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \ 1277#define FRAME_PIXEL_HEIGHT_TO_TEXT_LINES(f, height) \
1229 (FRAME_PIXEL_Y_TO_LINE (f, ((height) \ 1278 (((height) \
1230 - FRAME_INTERNAL_BORDER_WIDTH (f)))) 1279 - FRAME_TOP_MARGIN_HEIGHT (f) \
1280 - FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
1281 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) \
1282 / FRAME_LINE_HEIGHT (f))
1231 1283
1232/* Return the pixel width/height of frame F with a text size of 1284/* Return the pixel width/height of frame F with a text size of
1233 width/height. */ 1285 width/heigh. */
1234
1235#define FRAME_TEXT_TO_PIXEL_WIDTH(f, width) \ 1286#define FRAME_TEXT_TO_PIXEL_WIDTH(f, width) \
1236 ((width) \ 1287 ((width) \
1237 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \ 1288 + FRAME_SCROLL_BAR_AREA_WIDTH (f) \
@@ -1239,11 +1290,13 @@ extern Lisp_Object Vframe_list;
1239 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1290 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1240 1291
1241#define FRAME_TEXT_TO_PIXEL_HEIGHT(f, height) \ 1292#define FRAME_TEXT_TO_PIXEL_HEIGHT(f, height) \
1242 ((height) + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1293 ((height) \
1294 + FRAME_TOP_MARGIN_HEIGHT (f) \
1295 + FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
1296 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1243 1297
1244/* Return the text width/height of frame F with a pixel size of 1298/* Return the text width/height of frame F with a pixel size of
1245 width/height. */ 1299 width/height. */
1246
1247#define FRAME_PIXEL_TO_TEXT_WIDTH(f, width) \ 1300#define FRAME_PIXEL_TO_TEXT_WIDTH(f, width) \
1248 ((width) \ 1301 ((width) \
1249 - FRAME_SCROLL_BAR_AREA_WIDTH (f) \ 1302 - FRAME_SCROLL_BAR_AREA_WIDTH (f) \
@@ -1251,15 +1304,26 @@ extern Lisp_Object Vframe_list;
1251 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1304 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1252 1305
1253#define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height) \ 1306#define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height) \
1254 ((height) - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)) 1307 ((height) \
1308 - FRAME_TOP_MARGIN_HEIGHT (f) \
1309 - FRAME_SCROLL_BAR_AREA_HEIGHT (f) \
1310 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1311
1312/* Return the width/height reserved for the windows of frame F. */
1313#define FRAME_WINDOWS_WIDTH(f) \
1314 (FRAME_PIXEL_WIDTH (f) \
1315 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1255 1316
1256/* Value is the smallest width of any character in any font on frame F. */ 1317#define FRAME_WINDOWS_HEIGHT(f) \
1318 (FRAME_PIXEL_HEIGHT (f) \
1319 - FRAME_TOP_MARGIN_HEIGHT (f) \
1320 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
1257 1321
1322/* Value is the smallest width of any character in any font on frame F. */
1258#define FRAME_SMALLEST_CHAR_WIDTH(f) \ 1323#define FRAME_SMALLEST_CHAR_WIDTH(f) \
1259 FRAME_DISPLAY_INFO (f)->smallest_char_width 1324 FRAME_DISPLAY_INFO (f)->smallest_char_width
1260 1325
1261/* Value is the smallest height of any font on frame F. */ 1326/* Value is the smallest height of any font on frame F. */
1262
1263#define FRAME_SMALLEST_FONT_HEIGHT(f) \ 1327#define FRAME_SMALLEST_FONT_HEIGHT(f) \
1264 FRAME_DISPLAY_INFO (f)->smallest_font_height 1328 FRAME_DISPLAY_INFO (f)->smallest_font_height
1265 1329
@@ -1282,6 +1346,7 @@ extern Lisp_Object Qname, Qtitle;
1282extern Lisp_Object Qparent_id; 1346extern Lisp_Object Qparent_id;
1283extern Lisp_Object Qunsplittable, Qvisibility; 1347extern Lisp_Object Qunsplittable, Qvisibility;
1284extern Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; 1348extern Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
1349extern Lisp_Object Qscroll_bar_height, Qhorizontal_scroll_bars;
1285extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; 1350extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
1286extern Lisp_Object Qscreen_gamma; 1351extern Lisp_Object Qscreen_gamma;
1287extern Lisp_Object Qline_spacing; 1352extern Lisp_Object Qline_spacing;
@@ -1311,25 +1376,24 @@ extern Lisp_Object Qrun_hook_with_args;
1311/* The class of this X application. */ 1376/* The class of this X application. */
1312#define EMACS_CLASS "Emacs" 1377#define EMACS_CLASS "Emacs"
1313 1378
1314/* These are in xterm.c, w32term.c, etc. */ 1379/* If these are not in frame.c they are in xterm.c, w32term.c, etc. */
1380extern void adjust_frame_size (struct frame *, int, int, int, bool);
1381extern int frame_windows_min_size (Lisp_Object, Lisp_Object, Lisp_Object);
1315 1382
1316extern void x_set_scroll_bar_default_width (struct frame *); 1383extern void x_set_scroll_bar_default_width (struct frame *);
1384extern void x_set_scroll_bar_default_height (struct frame *);
1317extern void x_set_offset (struct frame *, int, int, int); 1385extern void x_set_offset (struct frame *, int, int, int);
1318extern void x_wm_set_size_hint (struct frame *f, long flags, bool user_position); 1386extern void x_wm_set_size_hint (struct frame *f, long flags, bool user_position);
1319
1320extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int); 1387extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int);
1321
1322
1323extern Lisp_Object Qface_set_after_frame_default; 1388extern Lisp_Object Qface_set_after_frame_default;
1324
1325extern void x_set_frame_parameters (struct frame *, Lisp_Object); 1389extern void x_set_frame_parameters (struct frame *, Lisp_Object);
1326
1327extern void x_set_fullscreen (struct frame *, Lisp_Object, Lisp_Object); 1390extern void x_set_fullscreen (struct frame *, Lisp_Object, Lisp_Object);
1328extern void x_set_line_spacing (struct frame *, Lisp_Object, Lisp_Object); 1391extern void x_set_line_spacing (struct frame *, Lisp_Object, Lisp_Object);
1329extern void x_set_screen_gamma (struct frame *, Lisp_Object, Lisp_Object); 1392extern void x_set_screen_gamma (struct frame *, Lisp_Object, Lisp_Object);
1330extern void x_set_font (struct frame *, Lisp_Object, Lisp_Object); 1393extern void x_set_font (struct frame *, Lisp_Object, Lisp_Object);
1331extern void x_set_font_backend (struct frame *, Lisp_Object, Lisp_Object); 1394extern void x_set_font_backend (struct frame *, Lisp_Object, Lisp_Object);
1332extern void x_set_fringe_width (struct frame *, Lisp_Object, Lisp_Object); 1395extern void x_set_left_fringe (struct frame *, Lisp_Object, Lisp_Object);
1396extern void x_set_right_fringe (struct frame *, Lisp_Object, Lisp_Object);
1333extern void x_set_border_width (struct frame *, Lisp_Object, Lisp_Object); 1397extern void x_set_border_width (struct frame *, Lisp_Object, Lisp_Object);
1334extern void x_set_internal_border_width (struct frame *, Lisp_Object, 1398extern void x_set_internal_border_width (struct frame *, Lisp_Object,
1335 Lisp_Object); 1399 Lisp_Object);
@@ -1341,10 +1405,10 @@ extern void x_set_visibility (struct frame *, Lisp_Object, Lisp_Object);
1341extern void x_set_autoraise (struct frame *, Lisp_Object, Lisp_Object); 1405extern void x_set_autoraise (struct frame *, Lisp_Object, Lisp_Object);
1342extern void x_set_autolower (struct frame *, Lisp_Object, Lisp_Object); 1406extern void x_set_autolower (struct frame *, Lisp_Object, Lisp_Object);
1343extern void x_set_unsplittable (struct frame *, Lisp_Object, Lisp_Object); 1407extern void x_set_unsplittable (struct frame *, Lisp_Object, Lisp_Object);
1344extern void x_set_vertical_scroll_bars (struct frame *, Lisp_Object, 1408extern void x_set_vertical_scroll_bars (struct frame *, Lisp_Object, Lisp_Object);
1345 Lisp_Object); 1409extern void x_set_horizontal_scroll_bars (struct frame *, Lisp_Object, Lisp_Object);
1346extern void x_set_scroll_bar_width (struct frame *, Lisp_Object, 1410extern void x_set_scroll_bar_width (struct frame *, Lisp_Object, Lisp_Object);
1347 Lisp_Object); 1411extern void x_set_scroll_bar_height (struct frame *, Lisp_Object, Lisp_Object);
1348 1412
1349extern long x_figure_window_size (struct frame *, Lisp_Object, bool); 1413extern long x_figure_window_size (struct frame *, Lisp_Object, bool);
1350 1414
diff --git a/src/fringe.c b/src/fringe.c
index 54f880dc624..3c0e883b2e9 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1329,98 +1329,6 @@ update_window_fringes (struct window *w, bool keep_current_p)
1329} 1329}
1330 1330
1331 1331
1332/* Compute actual fringe widths for frame F.
1333
1334 If REDRAW is 1, redraw F if the fringe settings was actually
1335 modified and F is visible.
1336
1337 Since the combined left and right fringe must occupy an integral
1338 number of columns, we may need to add some pixels to each fringe.
1339 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
1340 but a negative width value is taken literally (after negating it).
1341
1342 We never make the fringes narrower than specified.
1343*/
1344
1345void
1346compute_fringe_widths (struct frame *f, bool redraw_p)
1347{
1348 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
1349 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
1350 int o_cols = FRAME_FRINGE_COLS (f);
1351
1352 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
1353 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
1354 int left_fringe_width, right_fringe_width;
1355
1356 if (!NILP (left_fringe))
1357 left_fringe = Fcdr (left_fringe);
1358 if (!NILP (right_fringe))
1359 right_fringe = Fcdr (right_fringe);
1360
1361 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
1362 XINT (left_fringe));
1363 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
1364 XINT (right_fringe));
1365
1366 if (left_fringe_width || right_fringe_width)
1367 {
1368 int left_wid = eabs (left_fringe_width);
1369 int right_wid = eabs (right_fringe_width);
1370 int conf_wid = left_wid + right_wid;
1371 int font_wid = FRAME_COLUMN_WIDTH (f);
1372 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
1373 int real_wid = cols * font_wid;
1374 if (left_wid && right_wid)
1375 {
1376 if (left_fringe_width < 0)
1377 {
1378 /* Left fringe width is fixed, adjust right fringe if necessary */
1379 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
1380 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
1381 }
1382 else if (right_fringe_width < 0)
1383 {
1384 /* Right fringe width is fixed, adjust left fringe if necessary */
1385 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
1386 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
1387 }
1388 else
1389 {
1390 /* Adjust both fringes with an equal amount.
1391 Note that we are doing integer arithmetic here, so don't
1392 lose a pixel if the total width is an odd number. */
1393 int fill = real_wid - conf_wid;
1394 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
1395 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
1396 }
1397 }
1398 else if (left_fringe_width)
1399 {
1400 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
1401 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1402 }
1403 else
1404 {
1405 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1406 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
1407 }
1408 FRAME_FRINGE_COLS (f) = cols;
1409 }
1410 else
1411 {
1412 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1413 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1414 FRAME_FRINGE_COLS (f) = 0;
1415 }
1416
1417 if (redraw_p && FRAME_VISIBLE_P (f))
1418 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
1419 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
1420 o_cols != FRAME_FRINGE_COLS (f))
1421 redraw_frame (f);
1422}
1423
1424 1332
1425/* Free resources used by a user-defined bitmap. */ 1333/* Free resources used by a user-defined bitmap. */
1426 1334
diff --git a/src/gtkutil.c b/src/gtkutil.c
index afa41f3269a..b18e5f325e1 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -115,6 +115,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
115#define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x)) 115#define XG_BIN_CHILD(x) gtk_bin_get_child (GTK_BIN (x))
116 116
117static void update_theme_scrollbar_width (void); 117static void update_theme_scrollbar_width (void);
118static void update_theme_scrollbar_height (void);
118 119
119#define TB_INFO_KEY "xg_frame_tb_info" 120#define TB_INFO_KEY "xg_frame_tb_info"
120struct xg_frame_tb_info 121struct xg_frame_tb_info
@@ -821,7 +822,7 @@ xg_set_geometry (struct frame *f)
821/* Clear under internal border if any. As we use a mix of Gtk+ and X calls 822/* Clear under internal border if any. As we use a mix of Gtk+ and X calls
822 and use a GtkFixed widget, this doesn't happen automatically. */ 823 and use a GtkFixed widget, this doesn't happen automatically. */
823 824
824static void 825void
825xg_clear_under_internal_border (struct frame *f) 826xg_clear_under_internal_border (struct frame *f)
826{ 827{
827 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0) 828 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
@@ -883,6 +884,8 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
883 change_frame_size (f, width, height, 0, 1, 0, 1); 884 change_frame_size (f, width, height, 0, 1, 0, 1);
884 SET_FRAME_GARBAGED (f); 885 SET_FRAME_GARBAGED (f);
885 cancel_mouse_face (f); 886 cancel_mouse_face (f);
887
888 do_pending_window_change (0);
886 } 889 }
887} 890}
888 891
@@ -927,7 +930,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
927 x_wait_for_event (f, ConfigureNotify); 930 x_wait_for_event (f, ConfigureNotify);
928 } 931 }
929 else 932 else
930 change_frame_size (f, width, height, 0, 1, 0, 1); 933 adjust_frame_size (f, -1, -1, 5, 0);
931} 934}
932 935
933/* Handle height/width changes (i.e. add/remove/move menu/toolbar). 936/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
@@ -1017,6 +1020,7 @@ style_changed_cb (GObject *go,
1017 kbd_buffer_store_event (&event); 1020 kbd_buffer_store_event (&event);
1018 1021
1019 update_theme_scrollbar_width (); 1022 update_theme_scrollbar_width ();
1023 update_theme_scrollbar_height ();
1020 1024
1021 /* If scroll bar width changed, we need set the new size on all frames 1025 /* If scroll bar width changed, we need set the new size on all frames
1022 on this display. */ 1026 on this display. */
@@ -1031,6 +1035,7 @@ style_changed_cb (GObject *go,
1031 && FRAME_X_DISPLAY (f) == dpy) 1035 && FRAME_X_DISPLAY (f) == dpy)
1032 { 1036 {
1033 x_set_scroll_bar_default_width (f); 1037 x_set_scroll_bar_default_width (f);
1038 x_set_scroll_bar_default_height (f);
1034 xg_frame_set_char_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f)); 1039 xg_frame_set_char_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f));
1035 } 1040 }
1036 } 1041 }
@@ -1314,7 +1319,6 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
1314 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1) 1319 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 1)
1315 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f); 1320 + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
1316 1321
1317 check_frame_size (f, &min_cols, &min_rows, 0);
1318 if (min_cols > 0) --min_cols; /* We used one col in base_width = ... 1); */ 1322 if (min_cols > 0) --min_cols; /* We used one col in base_width = ... 1); */
1319 if (min_rows > 0) --min_rows; /* We used one row in base_height = ... 1); */ 1323 if (min_rows > 0) --min_rows; /* We used one row in base_height = ... 1); */
1320 1324
@@ -3419,9 +3423,9 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event)
3419 3423
3420bool xg_ignore_gtk_scrollbar; 3424bool xg_ignore_gtk_scrollbar;
3421 3425
3422/* The width of the scroll bar for the current theme. */ 3426/* Width and height of scroll bars for the current theme. */
3423
3424static int scroll_bar_width_for_theme; 3427static int scroll_bar_width_for_theme;
3428static int scroll_bar_height_for_theme;
3425 3429
3426/* Xlib's `Window' fits in 32 bits. But we want to store pointers, and they 3430/* Xlib's `Window' fits in 32 bits. But we want to store pointers, and they
3427 may be larger than 32 bits. Keep a mapping from integer index to widget 3431 may be larger than 32 bits. Keep a mapping from integer index to widget
@@ -3524,12 +3528,41 @@ update_theme_scrollbar_width (void)
3524 scroll_bar_width_for_theme = w; 3528 scroll_bar_width_for_theme = w;
3525} 3529}
3526 3530
3531static void
3532update_theme_scrollbar_height (void)
3533{
3534#ifdef HAVE_GTK3
3535 GtkAdjustment *hadj;
3536#else
3537 GtkObject *hadj;
3538#endif
3539 GtkWidget *wscroll;
3540 int w = 0, b = 0;
3541
3542 hadj = gtk_adjustment_new (YG_SB_MIN, YG_SB_MIN, YG_SB_MAX, 0.1, 0.1, 0.1);
3543 wscroll = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (hadj));
3544 g_object_ref_sink (G_OBJECT (wscroll));
3545 gtk_widget_style_get (wscroll, "slider-width", &w, "trough-border", &b, NULL);
3546 gtk_widget_destroy (wscroll);
3547 g_object_unref (G_OBJECT (wscroll));
3548 w += 2*b;
3549 if (w < 12) w = 12;
3550 scroll_bar_height_for_theme = w;
3551}
3552
3527int 3553int
3528xg_get_default_scrollbar_width (void) 3554xg_get_default_scrollbar_width (void)
3529{ 3555{
3530 return scroll_bar_width_for_theme; 3556 return scroll_bar_width_for_theme;
3531} 3557}
3532 3558
3559int
3560xg_get_default_scrollbar_height (void)
3561{
3562 /* Apparently there's no default height for themes. */
3563 return scroll_bar_width_for_theme;
3564}
3565
3533/* Return the scrollbar id for X Window WID on display DPY. 3566/* Return the scrollbar id for X Window WID on display DPY.
3534 Return -1 if WID not in id_to_widget. */ 3567 Return -1 if WID not in id_to_widget. */
3535 3568
@@ -3628,6 +3661,74 @@ xg_create_scroll_bar (struct frame *f,
3628 xg_set_cursor (webox, FRAME_DISPLAY_INFO (f)->xg_cursor); 3661 xg_set_cursor (webox, FRAME_DISPLAY_INFO (f)->xg_cursor);
3629 3662
3630 bar->x_window = scroll_id; 3663 bar->x_window = scroll_id;
3664 bar->horizontal = 0;
3665}
3666
3667/* Create a horizontal scroll bar widget for frame F. Store the scroll
3668 bar in BAR. SCROLL_CALLBACK is the callback to invoke when the value
3669 of the bar changes. END_CALLBACK is the callback to invoke when
3670 scrolling ends. SCROLL_BAR_NAME is the name we use for the scroll
3671 bar. Can be used to set resources for the widget. */
3672
3673void
3674xg_create_horizontal_scroll_bar (struct frame *f,
3675 struct scroll_bar *bar,
3676 GCallback scroll_callback,
3677 GCallback end_callback,
3678 const char *scroll_bar_name)
3679{
3680 GtkWidget *wscroll;
3681 GtkWidget *webox;
3682 intptr_t scroll_id;
3683#ifdef HAVE_GTK3
3684 GtkAdjustment *hadj;
3685#else
3686 GtkObject *hadj;
3687#endif
3688
3689 /* Page, step increment values are not so important here, they
3690 will be corrected in x_set_toolkit_scroll_bar_thumb. */
3691 hadj = gtk_adjustment_new (YG_SB_MIN, YG_SB_MIN, YG_SB_MAX,
3692 0.1, 0.1, 0.1);
3693
3694 wscroll = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (hadj));
3695 webox = gtk_event_box_new ();
3696 gtk_widget_set_name (wscroll, scroll_bar_name);
3697#ifndef HAVE_GTK3
3698 gtk_range_set_update_policy (GTK_RANGE (wscroll), GTK_UPDATE_CONTINUOUS);
3699#endif
3700 g_object_set_data (G_OBJECT (wscroll), XG_FRAME_DATA, (gpointer)f);
3701
3702 scroll_id = xg_store_widget_in_map (wscroll);
3703
3704 g_signal_connect (G_OBJECT (wscroll),
3705 "destroy",
3706 G_CALLBACK (xg_gtk_scroll_destroy),
3707 (gpointer) scroll_id);
3708 g_signal_connect (G_OBJECT (wscroll),
3709 "change-value",
3710 scroll_callback,
3711 (gpointer) bar);
3712 g_signal_connect (G_OBJECT (wscroll),
3713 "button-release-event",
3714 end_callback,
3715 (gpointer) bar);
3716
3717 /* The scroll bar widget does not draw on a window of its own. Instead
3718 it draws on the parent window, in this case the edit widget. So
3719 whenever the edit widget is cleared, the scroll bar needs to redraw
3720 also, which causes flicker. Put an event box between the edit widget
3721 and the scroll bar, so the scroll bar instead draws itself on the
3722 event box window. */
3723 gtk_fixed_put (GTK_FIXED (f->output_data.x->edit_widget), webox, -1, -1);
3724 gtk_container_add (GTK_CONTAINER (webox), wscroll);
3725
3726
3727 /* Set the cursor to an arrow. */
3728 xg_set_cursor (webox, FRAME_DISPLAY_INFO (f)->xg_cursor);
3729
3730 bar->x_window = scroll_id;
3731 bar->horizontal = 1;
3631} 3732}
3632 3733
3633/* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */ 3734/* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */
@@ -3710,6 +3811,73 @@ xg_update_scrollbar_pos (struct frame *f,
3710 } 3811 }
3711} 3812}
3712 3813
3814
3815/* Update the position of the horizontal scroll bar represented by SCROLLBAR_ID
3816 in frame F.
3817 TOP/LEFT are the new pixel positions where the bar shall appear.
3818 WIDTH, HEIGHT is the size in pixels the bar shall have. */
3819
3820void
3821xg_update_horizontal_scrollbar_pos (struct frame *f,
3822 ptrdiff_t scrollbar_id,
3823 int top,
3824 int left,
3825 int width,
3826 int height)
3827{
3828
3829 GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id);
3830
3831 if (wscroll)
3832 {
3833 GtkWidget *wfixed = f->output_data.x->edit_widget;
3834 GtkWidget *wparent = gtk_widget_get_parent (wscroll);
3835 gint msl;
3836
3837 /* Clear out old position. */
3838 int oldx = -1, oldy = -1, oldw, oldh;
3839 if (gtk_widget_get_parent (wparent) == wfixed)
3840 {
3841 gtk_container_child_get (GTK_CONTAINER (wfixed), wparent,
3842 "x", &oldx, "y", &oldy, NULL);
3843 gtk_widget_get_size_request (wscroll, &oldw, &oldh);
3844 }
3845
3846 /* Move and resize to new values. */
3847 gtk_fixed_move (GTK_FIXED (wfixed), wparent, left, top);
3848 gtk_widget_style_get (wscroll, "min-slider-length", &msl, NULL);
3849 if (msl > width)
3850 {
3851 /* No room. Hide scroll bar as some themes output a warning if
3852 the width is less than the min size. */
3853 gtk_widget_hide (wparent);
3854 gtk_widget_hide (wscroll);
3855 }
3856 else
3857 {
3858 gtk_widget_show_all (wparent);
3859 gtk_widget_set_size_request (wscroll, width, height);
3860 }
3861 gtk_widget_queue_draw (wfixed);
3862 gdk_window_process_all_updates ();
3863 if (oldx != -1 && oldw > 0 && oldh > 0)
3864 /* Clear under old scroll bar position. This must be done after
3865 the gtk_widget_queue_draw and gdk_window_process_all_updates
3866 above. */
3867 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3868 oldx, oldy, oldw, oldh);
3869
3870 /* GTK does not redraw until the main loop is entered again, but
3871 if there are no X events pending we will not enter it. So we sync
3872 here to get some events. */
3873
3874 x_sync (f);
3875 SET_FRAME_GARBAGED (f);
3876 cancel_mouse_face (f);
3877 }
3878}
3879
3880
3713/* Get the current value of the range, truncated to an integer. */ 3881/* Get the current value of the range, truncated to an integer. */
3714 3882
3715static int 3883static int
@@ -3804,6 +3972,47 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
3804 } 3972 }
3805} 3973}
3806 3974
3975/* Set the thumb size and position of horizontal scroll bar BAR. We are
3976 currently displaying PORTION out of a whole WHOLE, and our position
3977 POSITION. */
3978void
3979xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
3980 int portion,
3981 int position,
3982 int whole)
3983{
3984 GtkWidget *wscroll = xg_get_widget_from_map (bar->x_window);
3985
3986 if (wscroll && bar->dragging == -1)
3987 {
3988 GtkAdjustment *adj;
3989 int lower = 0;
3990 int upper = max (whole - 1, 0);
3991 int pagesize = min (upper, max (portion, 0));
3992 int value = max (0, min (position, upper - pagesize));
3993 /* These should be set to something more <portion, whole>
3994 related. */
3995 int page_increment = 4;
3996 int step_increment = 1;
3997
3998 block_input ();
3999 adj = gtk_range_get_adjustment (GTK_RANGE (wscroll));
4000
4001 /* gtk_adjustment_set_lower (adj, (gdouble) lower);
4002 gtk_adjustment_set_upper (adj, (gdouble) upper);
4003 gtk_adjustment_set_page_size (adj, (gdouble) pagesize);
4004 gtk_adjustment_set_value (adj, (gdouble) value);
4005 gtk_adjustment_set_page_increment (adj, (gdouble) page_increment);
4006 gtk_adjustment_set_step_increment (adj, (gdouble)
4007 step_increment); */
4008 gtk_adjustment_configure (adj, (gdouble) value, (gdouble) lower,
4009 (gdouble) upper, (gdouble) step_increment,
4010 (gdouble) page_increment, (gdouble) pagesize);
4011 gtk_adjustment_changed (adj);
4012 unblock_input ();
4013 }
4014}
4015
3807/* Return true if EVENT is for a scroll bar in frame F. 4016/* Return true if EVENT is for a scroll bar in frame F.
3808 When the same X window is used for several Gtk+ widgets, we cannot 4017 When the same X window is used for several Gtk+ widgets, we cannot
3809 say for sure based on the X window alone if an event is for the 4018 say for sure based on the X window alone if an event is for the
@@ -5010,6 +5219,7 @@ xg_initialize (void)
5010 gtk_binding_entry_add_signal (binding_set, GDK_KEY_g, GDK_CONTROL_MASK, 5219 gtk_binding_entry_add_signal (binding_set, GDK_KEY_g, GDK_CONTROL_MASK,
5011 "cancel", 0); 5220 "cancel", 0);
5012 update_theme_scrollbar_width (); 5221 update_theme_scrollbar_width ();
5222 update_theme_scrollbar_height ();
5013 5223
5014#ifdef HAVE_FREETYPE 5224#ifdef HAVE_FREETYPE
5015 x_last_font_name = NULL; 5225 x_last_font_name = NULL;
diff --git a/src/gtkutil.h b/src/gtkutil.h
index a69932cc25c..5c7d8b03379 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -33,6 +33,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
33#define XG_SB_MIN 1 33#define XG_SB_MIN 1
34#define XG_SB_MAX 10000000 34#define XG_SB_MAX 10000000
35#define XG_SB_RANGE (XG_SB_MAX-XG_SB_MIN) 35#define XG_SB_RANGE (XG_SB_MAX-XG_SB_MIN)
36#define YG_SB_MIN 1
37#define YG_SB_MAX 10000000
38#define YG_SB_RANGE (YG_SB_MAX-YG_SB_MIN)
36 39
37/* Key for data that is valid for menus and scroll bars in a frame */ 40/* Key for data that is valid for menus and scroll bars in a frame */
38#define XG_FRAME_DATA "emacs_frame" 41#define XG_FRAME_DATA "emacs_frame"
@@ -114,6 +117,11 @@ extern void xg_create_scroll_bar (struct frame *f,
114 GCallback scroll_callback, 117 GCallback scroll_callback,
115 GCallback end_callback, 118 GCallback end_callback,
116 const char *scroll_bar_name); 119 const char *scroll_bar_name);
120extern void xg_create_horizontal_scroll_bar (struct frame *f,
121 struct scroll_bar *bar,
122 GCallback scroll_callback,
123 GCallback end_callback,
124 const char *scroll_bar_name);
117extern void xg_remove_scroll_bar (struct frame *f, ptrdiff_t scrollbar_id); 125extern void xg_remove_scroll_bar (struct frame *f, ptrdiff_t scrollbar_id);
118 126
119extern void xg_update_scrollbar_pos (struct frame *f, 127extern void xg_update_scrollbar_pos (struct frame *f,
@@ -122,18 +130,30 @@ extern void xg_update_scrollbar_pos (struct frame *f,
122 int left, 130 int left,
123 int width, 131 int width,
124 int height); 132 int height);
133extern void xg_update_horizontal_scrollbar_pos (struct frame *f,
134 ptrdiff_t scrollbar_id,
135 int top,
136 int left,
137 int width,
138 int height);
125 139
126extern void xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, 140extern void xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
127 int portion, 141 int portion,
128 int position, 142 int position,
129 int whole); 143 int whole);
144extern void xg_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
145 int portion,
146 int position,
147 int whole);
130extern bool xg_event_is_for_scrollbar (struct frame *, const XEvent *); 148extern bool xg_event_is_for_scrollbar (struct frame *, const XEvent *);
131extern int xg_get_default_scrollbar_width (void); 149extern int xg_get_default_scrollbar_width (void);
150extern int xg_get_default_scrollbar_height (void);
132 151
133extern void update_frame_tool_bar (struct frame *f); 152extern void update_frame_tool_bar (struct frame *f);
134extern void free_frame_tool_bar (struct frame *f); 153extern void free_frame_tool_bar (struct frame *f);
135extern void xg_change_toolbar_position (struct frame *f, Lisp_Object pos); 154extern void xg_change_toolbar_position (struct frame *f, Lisp_Object pos);
136 155
156extern void xg_clear_under_internal_border (struct frame *f);
137extern void xg_frame_resized (struct frame *f, 157extern void xg_frame_resized (struct frame *f,
138 int pixelwidth, 158 int pixelwidth,
139 int pixelheight); 159 int pixelheight);
@@ -162,7 +182,6 @@ extern bool xg_prepare_tooltip (struct frame *f,
162extern void xg_show_tooltip (struct frame *f, int root_x, int root_y); 182extern void xg_show_tooltip (struct frame *f, int root_x, int root_y);
163extern bool xg_hide_tooltip (struct frame *f); 183extern bool xg_hide_tooltip (struct frame *f);
164 184
165
166/* Mark all callback data that are Lisp_object:s during GC. */ 185/* Mark all callback data that are Lisp_object:s during GC. */
167extern void xg_mark_data (void); 186extern void xg_mark_data (void);
168 187
diff --git a/src/insdel.c b/src/insdel.c
index 876e2869978..463392dcada 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -203,6 +203,25 @@ gap_right (ptrdiff_t charpos, ptrdiff_t bytepos)
203 QUIT; 203 QUIT;
204} 204}
205 205
206/* If the selected window's old pointm is adjacent or covered by the
207 region from FROM to TO, unsuspend auto hscroll in that window. */
208
209static void
210adjust_suspend_auto_hscroll (ptrdiff_t from, ptrdiff_t to)
211{
212 if (WINDOWP (selected_window))
213 {
214 struct window *w = XWINDOW (selected_window);
215
216 if (BUFFERP (w->contents)
217 && XBUFFER (w->contents) == current_buffer
218 && XMARKER (w->old_pointm)->charpos >= from
219 && XMARKER (w->old_pointm)->charpos <= to)
220 w->suspend_auto_hscroll = 0;
221 }
222}
223
224
206/* Adjust all markers for a deletion 225/* Adjust all markers for a deletion
207 whose range in bytes is FROM_BYTE to TO_BYTE. 226 whose range in bytes is FROM_BYTE to TO_BYTE.
208 The range in charpos is FROM to TO. 227 The range in charpos is FROM to TO.
@@ -217,6 +236,7 @@ adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte,
217 struct Lisp_Marker *m; 236 struct Lisp_Marker *m;
218 ptrdiff_t charpos; 237 ptrdiff_t charpos;
219 238
239 adjust_suspend_auto_hscroll (from, to);
220 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 240 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
221 { 241 {
222 charpos = m->charpos; 242 charpos = m->charpos;
@@ -256,6 +276,7 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t from_byte,
256 ptrdiff_t nchars = to - from; 276 ptrdiff_t nchars = to - from;
257 ptrdiff_t nbytes = to_byte - from_byte; 277 ptrdiff_t nbytes = to_byte - from_byte;
258 278
279 adjust_suspend_auto_hscroll (from, to);
259 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 280 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
260 { 281 {
261 eassert (m->bytepos >= m->charpos 282 eassert (m->bytepos >= m->charpos
@@ -321,6 +342,7 @@ adjust_markers_for_replace (ptrdiff_t from, ptrdiff_t from_byte,
321 ptrdiff_t diff_chars = new_chars - old_chars; 342 ptrdiff_t diff_chars = new_chars - old_chars;
322 ptrdiff_t diff_bytes = new_bytes - old_bytes; 343 ptrdiff_t diff_bytes = new_bytes - old_bytes;
323 344
345 adjust_suspend_auto_hscroll (from, from + old_chars);
324 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 346 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
325 { 347 {
326 if (m->bytepos >= prev_to_byte) 348 if (m->bytepos >= prev_to_byte)
diff --git a/src/keyboard.c b/src/keyboard.c
index 8fe6926a17c..a684f18c756 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3464,7 +3464,8 @@ readable_events (int flags)
3464 event->kind == FOCUS_IN_EVENT) 3464 event->kind == FOCUS_IN_EVENT)
3465#ifdef USE_TOOLKIT_SCROLL_BARS 3465#ifdef USE_TOOLKIT_SCROLL_BARS
3466 && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) 3466 && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
3467 && event->kind == SCROLL_BAR_CLICK_EVENT 3467 && (event->kind == SCROLL_BAR_CLICK_EVENT
3468 || event->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
3468 && event->part == scroll_bar_handle 3469 && event->part == scroll_bar_handle
3469 && event->modifiers == 0) 3470 && event->modifiers == 0)
3470#endif 3471#endif
@@ -3761,7 +3762,8 @@ discard_mouse_events (void)
3761#ifdef HAVE_GPM 3762#ifdef HAVE_GPM
3762 || sp->kind == GPM_CLICK_EVENT 3763 || sp->kind == GPM_CLICK_EVENT
3763#endif 3764#endif
3764 || sp->kind == SCROLL_BAR_CLICK_EVENT) 3765 || sp->kind == SCROLL_BAR_CLICK_EVENT
3766 || sp->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
3765 { 3767 {
3766 sp->kind = NO_EVENT; 3768 sp->kind = NO_EVENT;
3767 } 3769 }
@@ -5160,15 +5162,18 @@ static const char *const lispy_drag_n_drop_names[] =
5160 5162
5161/* Scroll bar parts. */ 5163/* Scroll bar parts. */
5162static Lisp_Object Qabove_handle, Qhandle, Qbelow_handle; 5164static Lisp_Object Qabove_handle, Qhandle, Qbelow_handle;
5163Lisp_Object Qup, Qdown, Qbottom; 5165static Lisp_Object Qbefore_handle, Qhorizontal_handle, Qafter_handle;
5166Lisp_Object Qup, Qdown, Qtop, Qbottom;
5167Lisp_Object Qleft, Qright, Qleftmost, Qrightmost;
5164static Lisp_Object Qend_scroll; 5168static Lisp_Object Qend_scroll;
5165Lisp_Object Qtop;
5166static Lisp_Object Qratio; 5169static Lisp_Object Qratio;
5167 5170
5168/* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */ 5171/* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */
5169static Lisp_Object *const scroll_bar_parts[] = { 5172static Lisp_Object *const scroll_bar_parts[] = {
5170 &Qabove_handle, &Qhandle, &Qbelow_handle, 5173 &Qabove_handle, &Qhandle, &Qbelow_handle,
5171 &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio 5174 &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio,
5175 &Qbefore_handle, &Qhorizontal_handle, &Qafter_handle,
5176 &Qleft, &Qright, &Qleftmost, &Qrightmost, &Qend_scroll, &Qratio
5172}; 5177};
5173 5178
5174/* A vector, indexed by button number, giving the down-going location 5179/* A vector, indexed by button number, giving the down-going location
@@ -5546,6 +5551,7 @@ make_lispy_event (struct input_event *event)
5546#endif 5551#endif
5547#ifndef USE_TOOLKIT_SCROLL_BARS 5552#ifndef USE_TOOLKIT_SCROLL_BARS
5548 case SCROLL_BAR_CLICK_EVENT: 5553 case SCROLL_BAR_CLICK_EVENT:
5554 case HORIZONTAL_SCROLL_BAR_CLICK_EVENT:
5549#endif 5555#endif
5550 { 5556 {
5551 int button = event->code; 5557 int button = event->code;
@@ -5946,6 +5952,36 @@ make_lispy_event (struct input_event *event)
5946 return list2 (head, position); 5952 return list2 (head, position);
5947 } 5953 }
5948 5954
5955 case HORIZONTAL_SCROLL_BAR_CLICK_EVENT:
5956 {
5957 Lisp_Object position, head, window, portion_whole, part;
5958
5959 window = event->frame_or_window;
5960 portion_whole = Fcons (event->x, event->y);
5961 part = *scroll_bar_parts[(int) event->part];
5962
5963 position = list5 (window, Qhorizontal_scroll_bar, portion_whole,
5964 make_number (event->timestamp), part);
5965
5966 /* Always treat scroll bar events as clicks. */
5967 event->modifiers |= click_modifier;
5968 event->modifiers &= ~up_modifier;
5969
5970 if (event->code >= ASIZE (mouse_syms))
5971 mouse_syms = larger_vector (mouse_syms,
5972 event->code - ASIZE (mouse_syms) + 1,
5973 -1);
5974
5975 /* Get the symbol we should use for the mouse click. */
5976 head = modify_event_symbol (event->code,
5977 event->modifiers,
5978 Qmouse_click,
5979 Vlispy_mouse_stem,
5980 NULL, &mouse_syms,
5981 ASIZE (mouse_syms));
5982 return list2 (head, position);
5983 }
5984
5949#endif /* USE_TOOLKIT_SCROLL_BARS */ 5985#endif /* USE_TOOLKIT_SCROLL_BARS */
5950 5986
5951 case DRAG_N_DROP_EVENT: 5987 case DRAG_N_DROP_EVENT:
@@ -10177,7 +10213,8 @@ On such systems, Emacs starts a subshell instead of suspending. */)
10177 with a window system; but suspend should be disabled in that case. */ 10213 with a window system; but suspend should be disabled in that case. */
10178 get_tty_size (fileno (CURTTY ()->input), &width, &height); 10214 get_tty_size (fileno (CURTTY ()->input), &width, &height);
10179 if (width != old_width || height != old_height) 10215 if (width != old_width || height != old_height)
10180 change_frame_size (SELECTED_FRAME (), width, height, 0, 0, 0, 0); 10216 change_frame_size (SELECTED_FRAME (), width, height
10217 - FRAME_MENU_BAR_LINES (SELECTED_FRAME ()), 0, 0, 0, 0);
10181 10218
10182 /* Run suspend-resume-hook. */ 10219 /* Run suspend-resume-hook. */
10183 hook = intern ("suspend-resume-hook"); 10220 hook = intern ("suspend-resume-hook");
@@ -11026,6 +11063,13 @@ syms_of_keyboard (void)
11026 DEFSYM (Qbottom, "bottom"); 11063 DEFSYM (Qbottom, "bottom");
11027 DEFSYM (Qend_scroll, "end-scroll"); 11064 DEFSYM (Qend_scroll, "end-scroll");
11028 DEFSYM (Qratio, "ratio"); 11065 DEFSYM (Qratio, "ratio");
11066 DEFSYM (Qbefore_handle, "before-handle");
11067 DEFSYM (Qhorizontal_handle, "horizontal-handle");
11068 DEFSYM (Qafter_handle, "after-handle");
11069 DEFSYM (Qleft, "left");
11070 DEFSYM (Qright, "right");
11071 DEFSYM (Qleftmost, "leftmost");
11072 DEFSYM (Qrightmost, "rightmost");
11029 11073
11030 DEFSYM (Qevent_kind, "event-kind"); 11074 DEFSYM (Qevent_kind, "event-kind");
11031 DEFSYM (Qevent_symbol_elements, "event-symbol-elements"); 11075 DEFSYM (Qevent_symbol_elements, "event-symbol-elements");
diff --git a/src/minibuf.c b/src/minibuf.c
index b85d3f57df3..93e19d5c120 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -651,6 +651,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
651 set_window_buffer (minibuf_window, Fcurrent_buffer (), 0, 0); 651 set_window_buffer (minibuf_window, Fcurrent_buffer (), 0, 0);
652 Fselect_window (minibuf_window, Qnil); 652 Fselect_window (minibuf_window, Qnil);
653 XWINDOW (minibuf_window)->hscroll = 0; 653 XWINDOW (minibuf_window)->hscroll = 0;
654 XWINDOW (minibuf_window)->suspend_auto_hscroll = 0;
654 655
655 Fmake_local_variable (Qprint_escape_newlines); 656 Fmake_local_variable (Qprint_escape_newlines);
656 print_escape_newlines = 1; 657 print_escape_newlines = 1;
diff --git a/src/nsfns.m b/src/nsfns.m
index 8f1a45d03f1..8bce1da2e5d 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -76,10 +76,12 @@ extern Lisp_Object Qicon_top;
76extern Lisp_Object Qtop; 76extern Lisp_Object Qtop;
77extern Lisp_Object Qdisplay; 77extern Lisp_Object Qdisplay;
78extern Lisp_Object Qvertical_scroll_bars; 78extern Lisp_Object Qvertical_scroll_bars;
79extern Lisp_Object Qhorizontal_scroll_bars;
79extern Lisp_Object Qauto_raise; 80extern Lisp_Object Qauto_raise;
80extern Lisp_Object Qauto_lower; 81extern Lisp_Object Qauto_lower;
81extern Lisp_Object Qbox; 82extern Lisp_Object Qbox;
82extern Lisp_Object Qscroll_bar_width; 83extern Lisp_Object Qscroll_bar_width;
84extern Lisp_Object Qscroll_bar_height;
83extern Lisp_Object Qx_resource_name; 85extern Lisp_Object Qx_resource_name;
84extern Lisp_Object Qface_set_after_frame_default; 86extern Lisp_Object Qface_set_after_frame_default;
85extern Lisp_Object Qunderline, Qundefined; 87extern Lisp_Object Qunderline, Qundefined;
@@ -705,6 +707,26 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
705} 707}
706 708
707 709
710void
711x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
712{
713 int old_width = FRAME_INTERNAL_BORDER_WIDTH (f);
714
715 CHECK_TYPE_RANGED_INTEGER (int, arg);
716 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
717 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
718 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
719
720 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old_width)
721 return;
722
723 if (FRAME_X_WINDOW (f) != 0)
724 adjust_frame_size (f, -1, -1, 3, 0);
725
726 SET_FRAME_GARBAGED (f);
727}
728
729
708static void 730static void
709ns_implicitly_set_icon_type (struct frame *f) 731ns_implicitly_set_icon_type (struct frame *f)
710{ 732{
@@ -954,17 +976,19 @@ frame_parm_handler ns_frame_parm_handlers[] =
954 x_set_mouse_color, 976 x_set_mouse_color,
955 x_explicitly_set_name, 977 x_explicitly_set_name,
956 x_set_scroll_bar_width, /* generic OK */ 978 x_set_scroll_bar_width, /* generic OK */
979 x_set_scroll_bar_height, /* generic OK */
957 x_set_title, 980 x_set_title,
958 x_set_unsplittable, /* generic OK */ 981 x_set_unsplittable, /* generic OK */
959 x_set_vertical_scroll_bars, /* generic OK */ 982 x_set_vertical_scroll_bars, /* generic OK */
983 x_set_horizontal_scroll_bars, /* generic OK */
960 x_set_visibility, /* generic OK */ 984 x_set_visibility, /* generic OK */
961 x_set_tool_bar_lines, 985 x_set_tool_bar_lines,
962 0, /* x_set_scroll_bar_foreground, will ignore (not possible on NS) */ 986 0, /* x_set_scroll_bar_foreground, will ignore (not possible on NS) */
963 0, /* x_set_scroll_bar_background, will ignore (not possible on NS) */ 987 0, /* x_set_scroll_bar_background, will ignore (not possible on NS) */
964 x_set_screen_gamma, /* generic OK */ 988 x_set_screen_gamma, /* generic OK */
965 x_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */ 989 x_set_line_spacing, /* generic OK, sets f->extra_line_spacing to int */
966 x_set_fringe_width, /* generic OK */ 990 x_set_left_fringe, /* generic OK */
967 x_set_fringe_width, /* generic OK */ 991 x_set_right_fringe, /* generic OK */
968 0, /* x_set_wait_for_wm, will ignore */ 992 0, /* x_set_wait_for_wm, will ignore */
969 x_set_fullscreen, /* generic OK */ 993 x_set_fullscreen, /* generic OK */
970 x_set_font_backend, /* generic OK */ 994 x_set_font_backend, /* generic OK */
@@ -1208,7 +1232,7 @@ This function is an internal primitive--use `make-frame' instead. */)
1208 "internalBorderWidth", "InternalBorderWidth", 1232 "internalBorderWidth", "InternalBorderWidth",
1209 RES_TYPE_NUMBER); 1233 RES_TYPE_NUMBER);
1210 1234
1211 /* default scrollbars on right on Mac */ 1235 /* default vertical scrollbars on right on Mac */
1212 { 1236 {
1213 Lisp_Object spos 1237 Lisp_Object spos
1214#ifdef NS_IMPL_GNUSTEP 1238#ifdef NS_IMPL_GNUSTEP
@@ -1220,6 +1244,9 @@ This function is an internal primitive--use `make-frame' instead. */)
1220 "verticalScrollBars", "VerticalScrollBars", 1244 "verticalScrollBars", "VerticalScrollBars",
1221 RES_TYPE_SYMBOL); 1245 RES_TYPE_SYMBOL);
1222 } 1246 }
1247 x_default_parameter (f, parms, Qhorizontal_scroll_bars, Qt,
1248 "horizontalScrollBars", "HorizontalScrollBars",
1249 RES_TYPE_SYMBOL);
1223 x_default_parameter (f, parms, Qforeground_color, build_string ("Black"), 1250 x_default_parameter (f, parms, Qforeground_color, build_string ("Black"),
1224 "foreground", "Foreground", RES_TYPE_STRING); 1251 "foreground", "Foreground", RES_TYPE_STRING);
1225 x_default_parameter (f, parms, Qbackground_color, build_string ("White"), 1252 x_default_parameter (f, parms, Qbackground_color, build_string ("White"),
@@ -1280,6 +1307,8 @@ This function is an internal primitive--use `make-frame' instead. */)
1280 f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor]; 1307 f->output_data.ns->vertical_drag_cursor = [NSCursor resizeUpDownCursor];
1281 FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor 1308 FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor
1282 = [NSCursor arrowCursor]; 1309 = [NSCursor arrowCursor];
1310 FRAME_DISPLAY_INFO (f)->horizontal_scroll_bar_cursor
1311 = [NSCursor arrowCursor];
1283 f->output_data.ns->current_pointer = f->output_data.ns->text_cursor; 1312 f->output_data.ns->current_pointer = f->output_data.ns->text_cursor;
1284 1313
1285 [[EmacsView alloc] initFrameFromEmacs: f]; 1314 [[EmacsView alloc] initFrameFromEmacs: f];
@@ -1305,6 +1334,9 @@ This function is an internal primitive--use `make-frame' instead. */)
1305 x_default_parameter (f, parms, Qscroll_bar_width, Qnil, 1334 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
1306 "scrollBarWidth", "ScrollBarWidth", 1335 "scrollBarWidth", "ScrollBarWidth",
1307 RES_TYPE_NUMBER); 1336 RES_TYPE_NUMBER);
1337 x_default_parameter (f, parms, Qscroll_bar_height, Qnil,
1338 "scrollBarHeight", "ScrollBarHeight",
1339 RES_TYPE_NUMBER);
1308 x_default_parameter (f, parms, Qalpha, Qnil, 1340 x_default_parameter (f, parms, Qalpha, Qnil,
1309 "alpha", "Alpha", RES_TYPE_NUMBER); 1341 "alpha", "Alpha", RES_TYPE_NUMBER);
1310 x_default_parameter (f, parms, Qfullscreen, Qnil, 1342 x_default_parameter (f, parms, Qfullscreen, Qnil,
@@ -2231,6 +2263,15 @@ x_set_scroll_bar_default_width (struct frame *f)
2231 wid - 1) / wid; 2263 wid - 1) / wid;
2232} 2264}
2233 2265
2266void
2267x_set_scroll_bar_default_height (struct frame *f)
2268{
2269 int height = FRAME_LINE_HEIGHT (f);
2270 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = NS_SCROLL_BAR_WIDTH_DEFAULT;
2271 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) +
2272 height - 1) / height;
2273}
2274
2234/* terms impl this instead of x-get-resource directly */ 2275/* terms impl this instead of x-get-resource directly */
2235char * 2276char *
2236x_get_string_resource (XrmDatabase rdb, const char *name, const char *class) 2277x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
diff --git a/src/nsterm.h b/src/nsterm.h
index 7ed23f583f6..00a0b54add9 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -606,6 +606,9 @@ struct ns_display_info
606 /* The cursor to use for vertical scroll bars. */ 606 /* The cursor to use for vertical scroll bars. */
607 Cursor vertical_scroll_bar_cursor; 607 Cursor vertical_scroll_bar_cursor;
608 608
609 /* The cursor to use for horizontal scroll bars. */
610 Cursor horizontal_scroll_bar_cursor;
611
609 /* Information about the range of text currently shown in 612 /* Information about the range of text currently shown in
610 mouse-face. */ 613 mouse-face. */
611 Mouse_HLInfo mouse_highlight; 614 Mouse_HLInfo mouse_highlight;
@@ -746,12 +749,20 @@ struct x_output
746#endif 749#endif
747 750
748/* Compute pixel size for vertical scroll bars */ 751/* Compute pixel size for vertical scroll bars */
749#define NS_SCROLL_BAR_WIDTH(f) \ 752#define NS_SCROLL_BAR_WIDTH(f) \
750(FRAME_HAS_VERTICAL_SCROLL_BARS (f) \ 753 (FRAME_HAS_VERTICAL_SCROLL_BARS (f) \
751 ? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0 \ 754 ? rint (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0 \
752 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \ 755 ? FRAME_CONFIG_SCROLL_BAR_WIDTH (f) \
753 : (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f))) \ 756 : (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f))) \
754 : 0) 757 : 0)
758
759/* Compute pixel size for horizontal scroll bars */
760#define NS_SCROLL_BAR_HEIGHT(f) \
761 (FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) \
762 ? rint (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0 \
763 ? FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) \
764 : (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f))) \
765 : 0)
755 766
756/* Difference btwn char-column-calculated and actual SB widths. 767/* Difference btwn char-column-calculated and actual SB widths.
757 This is only a concern for rendering when SB on left. */ 768 This is only a concern for rendering when SB on left. */
@@ -760,6 +771,13 @@ struct x_output
760 (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f) \ 771 (FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f) \
761 - NS_SCROLL_BAR_WIDTH (f)) : 0) 772 - NS_SCROLL_BAR_WIDTH (f)) : 0)
762 773
774/* Difference btwn char-line-calculated and actual SB heights.
775 This is only a concern for rendering when SB on top. */
776#define NS_SCROLL_BAR_ADJUST_HORIZONTALLY(w, f) \
777 (WINDOW_HAS_HORIZONTAL_SCROLL_BARS (w) ? \
778 (FRAME_SCROLL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f) \
779 - NS_SCROLL_BAR_HEIGHT (f)) : 0)
780
763/* XXX: fix for GNUstep inconsistent accounting for titlebar */ 781/* XXX: fix for GNUstep inconsistent accounting for titlebar */
764#ifdef NS_IMPL_GNUSTEP 782#ifdef NS_IMPL_GNUSTEP
765#define NS_TOP_POS(f) ((f)->top_pos + 18) 783#define NS_TOP_POS(f) ((f)->top_pos + 18)
@@ -777,8 +795,8 @@ struct x_output
777 795
778/* First position where characters can be shown (instead of scrollbar, if 796/* First position where characters can be shown (instead of scrollbar, if
779 it is on left. */ 797 it is on left. */
780#define FIRST_CHAR_POSITION(f) \ 798#define FIRST_CHAR_POSITION(f) \
781 (! (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) ? 0 \ 799 (! (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) ? 0 \
782 : FRAME_SCROLL_BAR_COLS (f)) 800 : FRAME_SCROLL_BAR_COLS (f))
783 801
784extern struct ns_display_info *ns_term_init (Lisp_Object display_name); 802extern struct ns_display_info *ns_term_init (Lisp_Object display_name);
@@ -918,6 +936,7 @@ extern char gnustep_base_version[]; /* version tracking */
918#define SCREENMAX 16000 936#define SCREENMAX 16000
919 937
920#define NS_SCROLL_BAR_WIDTH_DEFAULT [EmacsScroller scrollerWidth] 938#define NS_SCROLL_BAR_WIDTH_DEFAULT [EmacsScroller scrollerWidth]
939#define NS_SCROLL_BAR_HEIGHT_DEFAULT [EmacsScroller scrollerHeight]
921/* This is to match emacs on other platforms, ugly though it is. */ 940/* This is to match emacs on other platforms, ugly though it is. */
922#define NS_SELECTION_BG_COLOR_DEFAULT @"LightGoldenrod2"; 941#define NS_SELECTION_BG_COLOR_DEFAULT @"LightGoldenrod2";
923#define NS_SELECTION_FG_COLOR_DEFAULT @"Black"; 942#define NS_SELECTION_FG_COLOR_DEFAULT @"Black";
diff --git a/src/nsterm.m b/src/nsterm.m
index 3b1c945c6bf..9c64ab5f93b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1342,10 +1342,6 @@ x_set_window_size (struct frame *f,
1342 1342
1343 block_input (); 1343 block_input ();
1344 1344
1345 check_frame_size (f, &width, &height, pixelwise);
1346
1347 compute_fringe_widths (f, 0);
1348
1349 if (pixelwise) 1345 if (pixelwise)
1350 { 1346 {
1351 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); 1347 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
@@ -1417,6 +1413,8 @@ x_set_window_size (struct frame *f,
1417 cancel_mouse_face (f); 1413 cancel_mouse_face (f);
1418 1414
1419 unblock_input (); 1415 unblock_input ();
1416
1417 do_pending_window_change (0);
1420} 1418}
1421 1419
1422 1420
@@ -2315,52 +2313,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
2315 { 2313 {
2316 int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny; 2314 int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
2317 2315
2318 /* If the fringe is adjacent to the left (right) scroll bar of a
2319 leftmost (rightmost, respectively) window, then extend its
2320 background to the gap between the fringe and the bar. */
2321 if ((WINDOW_LEFTMOST_P (w)
2322 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
2323 || (WINDOW_RIGHTMOST_P (w)
2324 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
2325 {
2326 int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
2327
2328 if (sb_width > 0)
2329 {
2330 int bar_area_x = WINDOW_SCROLL_BAR_AREA_X (w);
2331 int bar_area_width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
2332 * FRAME_COLUMN_WIDTH (f));
2333
2334 if (bx < 0)
2335 {
2336 /* Bitmap fills the fringe. */
2337 if (bar_area_x + bar_area_width == p->x)
2338 bx = bar_area_x + sb_width;
2339 else if (p->x + p->wd == bar_area_x)
2340 bx = bar_area_x;
2341 if (bx >= 0)
2342 {
2343 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
2344
2345 nx = bar_area_width - sb_width;
2346 by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
2347 row->y));
2348 ny = row->visible_height;
2349 }
2350 }
2351 else
2352 {
2353 if (bar_area_x + bar_area_width == bx)
2354 {
2355 bx = bar_area_x + sb_width;
2356 nx += bar_area_width - sb_width;
2357 }
2358 else if (bx + nx == bar_area_x)
2359 nx += bar_area_width - sb_width;
2360 }
2361 }
2362 }
2363
2364 if (bx >= 0 && nx > 0) 2316 if (bx >= 0 && nx > 0)
2365 { 2317 {
2366 NSRect r = NSMakeRect (bx, by, nx, ny); 2318 NSRect r = NSMakeRect (bx, by, nx, ny);
@@ -3792,10 +3744,9 @@ ns_set_vertical_scroll_bar (struct window *window,
3792 NSRect r, v; 3744 NSRect r, v;
3793 struct frame *f = XFRAME (WINDOW_FRAME (window)); 3745 struct frame *f = XFRAME (WINDOW_FRAME (window));
3794 EmacsView *view = FRAME_NS_VIEW (f); 3746 EmacsView *view = FRAME_NS_VIEW (f);
3795 int window_y, window_height;
3796 int top, left, height, width, sb_width, sb_left;
3797 EmacsScroller *bar; 3747 EmacsScroller *bar;
3798 BOOL fringe_extended_p; 3748 int window_y, window_height;
3749 int top, left, height, width;
3799 3750
3800 /* optimization; display engine sends WAY too many of these.. */ 3751 /* optimization; display engine sends WAY too many of these.. */
3801 if (!NILP (window->vertical_scroll_bar)) 3752 if (!NILP (window->vertical_scroll_bar))
@@ -3822,18 +3773,11 @@ ns_set_vertical_scroll_bar (struct window *window,
3822 width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f); 3773 width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f);
3823 left = WINDOW_SCROLL_BAR_AREA_X (window); 3774 left = WINDOW_SCROLL_BAR_AREA_X (window);
3824 3775
3825 /* allow for displaying a skinnier scrollbar than char area allotted */ 3776 r = NSMakeRect (left, top, width, height);
3826 sb_width = (WINDOW_CONFIG_SCROLL_BAR_WIDTH (window) > 0) ?
3827 WINDOW_CONFIG_SCROLL_BAR_WIDTH (window) : width;
3828 sb_left = left;
3829
3830 r = NSMakeRect (sb_left, top, sb_width, height);
3831 /* the parent view is flipped, so we need to flip y value */ 3777 /* the parent view is flipped, so we need to flip y value */
3832 v = [view frame]; 3778 v = [view frame];
3833 r.origin.y = (v.size.height - r.size.height - r.origin.y); 3779 r.origin.y = (v.size.height - r.size.height - r.origin.y);
3834 3780
3835 fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (window);
3836
3837 XSETWINDOW (win, window); 3781 XSETWINDOW (win, window);
3838 block_input (); 3782 block_input ();
3839 3783
@@ -3846,7 +3790,7 @@ ns_set_vertical_scroll_bar (struct window *window,
3846 [bar removeFromSuperview]; 3790 [bar removeFromSuperview];
3847 wset_vertical_scroll_bar (window, Qnil); 3791 wset_vertical_scroll_bar (window, Qnil);
3848 } 3792 }
3849 ns_clear_frame_area (f, sb_left, top, width, height); 3793 ns_clear_frame_area (f, left, top, width, height);
3850 unblock_input (); 3794 unblock_input ();
3851 return; 3795 return;
3852 } 3796 }
@@ -3854,12 +3798,7 @@ ns_set_vertical_scroll_bar (struct window *window,
3854 if (NILP (window->vertical_scroll_bar)) 3798 if (NILP (window->vertical_scroll_bar))
3855 { 3799 {
3856 if (width > 0 && height > 0) 3800 if (width > 0 && height > 0)
3857 { 3801 ns_clear_frame_area (f, left, top, width, height);
3858 if (fringe_extended_p)
3859 ns_clear_frame_area (f, sb_left, top, sb_width, height);
3860 else
3861 ns_clear_frame_area (f, left, top, width, height);
3862 }
3863 3802
3864 bar = [[EmacsScroller alloc] initFrame: r window: win]; 3803 bar = [[EmacsScroller alloc] initFrame: r window: win];
3865 wset_vertical_scroll_bar (window, make_save_ptr (bar)); 3804 wset_vertical_scroll_bar (window, make_save_ptr (bar));
@@ -3873,7 +3812,97 @@ ns_set_vertical_scroll_bar (struct window *window,
3873 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r)) 3812 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
3874 { 3813 {
3875 if (oldRect.origin.x != r.origin.x) 3814 if (oldRect.origin.x != r.origin.x)
3876 ns_clear_frame_area (f, sb_left, top, width, height); 3815 ns_clear_frame_area (f, left, top, width, height);
3816 [bar setFrame: r];
3817 }
3818 }
3819
3820 [bar setPosition: position portion: portion whole: whole];
3821 unblock_input ();
3822}
3823
3824
3825static void
3826ns_set_horizontal_scroll_bar (struct window *window,
3827 int portion, int whole, int position)
3828/* --------------------------------------------------------------------------
3829 External (hook): Update or add scrollbar
3830 -------------------------------------------------------------------------- */
3831{
3832 Lisp_Object win;
3833 NSRect r, v;
3834 struct frame *f = XFRAME (WINDOW_FRAME (window));
3835 EmacsView *view = FRAME_NS_VIEW (f);
3836 EmacsScroller *bar;
3837 int top, height, left, width;
3838 int window_x, window_width;
3839 int pixel_width = WINDOW_PIXEL_WIDTH (window);
3840
3841 /* optimization; display engine sends WAY too many of these.. */
3842 if (!NILP (window->horizontal_scroll_bar))
3843 {
3844 bar = XNS_SCROLL_BAR (window->horizontal_scroll_bar);
3845 if ([bar checkSamePosition: position portion: portion whole: whole])
3846 {
3847 if (view->scrollbarsNeedingUpdate == 0)
3848 {
3849 if (!windows_or_buffers_changed)
3850 return;
3851 }
3852 else
3853 view->scrollbarsNeedingUpdate--;
3854 }
3855 }
3856
3857 NSTRACE (ns_set_horizontal_scroll_bar);
3858
3859 /* Get dimensions. */
3860 window_box (window, ANY_AREA, 0, &window_x, &window_width, 0);
3861 left = window_x;
3862 width = window_width;
3863 height = WINDOW_CONFIG_SCROLL_BAR_LINES (window) * FRAME_LINE_HEIGHT (f);
3864 top = WINDOW_SCROLL_BAR_AREA_Y (window);
3865
3866 r = NSMakeRect (left, top, width, height);
3867 /* the parent view is flipped, so we need to flip y value */
3868 v = [view frame];
3869 /* ??????? PXW/scrollbars !!!!!!!!!!!!!!!!!!!! */
3870 r.origin.y = (v.size.height - r.size.height - r.origin.y);
3871
3872 XSETWINDOW (win, window);
3873 block_input ();
3874
3875 if (WINDOW_TOTAL_COLS (window) < 5)
3876 {
3877 if (!NILP (window->horizontal_scroll_bar))
3878 {
3879 bar = XNS_SCROLL_BAR (window->horizontal_scroll_bar);
3880 [bar removeFromSuperview];
3881 wset_horizontal_scroll_bar (window, Qnil);
3882 }
3883 ns_clear_frame_area (f, left, top, width, height);
3884 unblock_input ();
3885 return;
3886 }
3887
3888 if (NILP (window->horizontal_scroll_bar))
3889 {
3890 if (width > 0 && height > 0)
3891 ns_clear_frame_area (f, left, top, width, height);
3892
3893 bar = [[EmacsScroller alloc] initFrame: r window: win];
3894 wset_horizontal_scroll_bar (window, make_save_ptr (bar));
3895 }
3896 else
3897 {
3898 NSRect oldRect;
3899 bar = XNS_SCROLL_BAR (window->horizontal_scroll_bar);
3900 oldRect = [bar frame];
3901 r.size.width = oldRect.size.width;
3902 if (FRAME_LIVE_P (f) && !NSEqualRects (oldRect, r))
3903 {
3904 if (oldRect.origin.x != r.origin.x)
3905 ns_clear_frame_area (f, left, top, width, height);
3877 [bar setFrame: r]; 3906 [bar setFrame: r];
3878 } 3907 }
3879 } 3908 }
@@ -3919,6 +3948,12 @@ ns_redeem_scroll_bar (struct window *window)
3919 bar = XNS_SCROLL_BAR (window->vertical_scroll_bar); 3948 bar = XNS_SCROLL_BAR (window->vertical_scroll_bar);
3920 [bar reprieve]; 3949 [bar reprieve];
3921 } 3950 }
3951
3952 if (!NILP (window->horizontal_scroll_bar))
3953 {
3954 bar = XNS_SCROLL_BAR (window->horizontal_scroll_bar);
3955 [bar reprieve];
3956 }
3922} 3957}
3923 3958
3924 3959
@@ -4483,7 +4518,7 @@ ns_term_shutdown (int sig)
4483 [self sendEvent:event]; 4518 [self sendEvent:event];
4484 [self updateWindows]; 4519 [self updateWindows];
4485 } while (shouldKeepRunning); 4520 } while (shouldKeepRunning);
4486 4521
4487 [pool release]; 4522 [pool release];
4488} 4523}
4489 4524
@@ -4652,30 +4687,9 @@ ns_term_shutdown (int sig)
4652 ((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES; 4687 ((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES;
4653#endif 4688#endif
4654 [NSApp setServicesProvider: NSApp]; 4689 [NSApp setServicesProvider: NSApp];
4655
4656 [self antialiasThresholdDidChange:nil];
4657#ifdef NS_IMPL_COCOA
4658#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
4659 [[NSNotificationCenter defaultCenter]
4660 addObserver:self
4661 selector:@selector(antialiasThresholdDidChange:)
4662 name:NSAntialiasThresholdChangedNotification
4663 object:nil];
4664#endif
4665#endif
4666
4667 ns_send_appdefined (-2); 4690 ns_send_appdefined (-2);
4668} 4691}
4669 4692
4670- (void)antialiasThresholdDidChange:(NSNotification *)notification
4671{
4672#ifdef NS_IMPL_COCOA
4673#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
4674 macfont_update_antialias_threshold ();
4675#endif
4676#endif
4677}
4678
4679 4693
4680/* Termination sequences: 4694/* Termination sequences:
4681 C-x C-c: 4695 C-x C-c:
@@ -7021,7 +7035,7 @@ if (cols > 0 && rows > 0)
7021 7035
7022 if (nr_eff_screens == 1) 7036 if (nr_eff_screens == 1)
7023 return [super constrainFrameRect:frameRect toScreen:screen]; 7037 return [super constrainFrameRect:frameRect toScreen:screen];
7024 7038
7025 /* The default implementation does two things 1) ensure that the top 7039 /* The default implementation does two things 1) ensure that the top
7026 of the rectangle is below the menu bar (or below the top of the 7040 of the rectangle is below the menu bar (or below the top of the
7027 screen) and 2) resizes windows larger than the screen. As we 7041 screen) and 2) resizes windows larger than the screen. As we
@@ -7506,8 +7520,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7506 FRAME_COLUMN_WIDTH (f) = font->average_width; 7520 FRAME_COLUMN_WIDTH (f) = font->average_width;
7507 FRAME_LINE_HEIGHT (f) = font->height; 7521 FRAME_LINE_HEIGHT (f) = font->height;
7508 7522
7509 compute_fringe_widths (f, 1);
7510
7511 /* Compute the scroll bar width in character columns. */ 7523 /* Compute the scroll bar width in character columns. */
7512 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0) 7524 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
7513 { 7525 {
@@ -7521,6 +7533,19 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7521 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid; 7533 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
7522 } 7534 }
7523 7535
7536 /* Compute the scroll bar height in character lines. */
7537 if (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) > 0)
7538 {
7539 int height = FRAME_LINE_HEIGHT (f);
7540 FRAME_CONFIG_SCROLL_BAR_LINES (f)
7541 = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + height - 1) / height;
7542 }
7543 else
7544 {
7545 int height = FRAME_LINE_HEIGHT (f);
7546 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
7547 }
7548
7524 /* Now make the frame display the given font. */ 7549 /* Now make the frame display the given font. */
7525 if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen]) 7550 if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen])
7526 x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 7551 x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
diff --git a/src/term.c b/src/term.c
index 9081790745c..8c004ccbecb 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2411,7 +2411,7 @@ frame's terminal). */)
2411 was suspended. */ 2411 was suspended. */
2412 get_tty_size (fileno (t->display_info.tty->input), &width, &height); 2412 get_tty_size (fileno (t->display_info.tty->input), &width, &height);
2413 if (width != old_width || height != old_height) 2413 if (width != old_width || height != old_height)
2414 change_frame_size (f, width, height, 0, 0, 0, 0); 2414 change_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 0, 0, 0, 0);
2415 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); 2415 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
2416 } 2416 }
2417 2417
@@ -3904,6 +3904,7 @@ clear_tty_hooks (struct terminal *terminal)
3904 terminal->fullscreen_hook = 0; 3904 terminal->fullscreen_hook = 0;
3905 terminal->menu_show_hook = 0; 3905 terminal->menu_show_hook = 0;
3906 terminal->set_vertical_scroll_bar_hook = 0; 3906 terminal->set_vertical_scroll_bar_hook = 0;
3907 terminal->set_horizontal_scroll_bar_hook = 0;
3907 terminal->condemn_scroll_bars_hook = 0; 3908 terminal->condemn_scroll_bars_hook = 0;
3908 terminal->redeem_scroll_bar_hook = 0; 3909 terminal->redeem_scroll_bar_hook = 0;
3909 terminal->judge_scroll_bars_hook = 0; 3910 terminal->judge_scroll_bars_hook = 0;
@@ -4225,6 +4226,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
4225 tty->specified_window = height; 4226 tty->specified_window = height;
4226 4227
4227 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; 4228 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
4229 FRAME_HAS_HORIZONTAL_SCROLL_BARS (f) = 0;
4228 tty->char_ins_del_ok = 1; 4230 tty->char_ins_del_ok = 1;
4229 baud_rate = 19200; 4231 baud_rate = 19200;
4230 } 4232 }
diff --git a/src/termhooks.h b/src/termhooks.h
index f9bf9d785b6..04104eb41e9 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -37,7 +37,14 @@ enum scroll_bar_part {
37 scroll_bar_to_top, 37 scroll_bar_to_top,
38 scroll_bar_to_bottom, 38 scroll_bar_to_bottom,
39 scroll_bar_end_scroll, 39 scroll_bar_end_scroll,
40 scroll_bar_move_ratio 40 scroll_bar_move_ratio,
41 scroll_bar_before_handle,
42 scroll_bar_horizontal_handle,
43 scroll_bar_after_handle,
44 scroll_bar_left_arrow,
45 scroll_bar_right_arrow,
46 scroll_bar_to_leftmost,
47 scroll_bar_to_rightmost
41}; 48};
42 49
43/* Output method of a terminal (and frames on this terminal, respectively). */ 50/* Output method of a terminal (and frames on this terminal, respectively). */
@@ -130,6 +137,19 @@ enum event_kind
130 whose scroll bar was clicked in. 137 whose scroll bar was clicked in.
131 .timestamp gives a timestamp (in 138 .timestamp gives a timestamp (in
132 milliseconds) for the click. */ 139 milliseconds) for the click. */
140 HORIZONTAL_SCROLL_BAR_CLICK_EVENT, /* .code gives the number of the mouse button
141 that was clicked.
142 .modifiers holds the state of the modifier
143 keys.
144 .part is a lisp symbol indicating which
145 part of the scroll bar got clicked.
146 .x gives the distance from the start of the
147 scroll bar of the click; .y gives the total
148 length of the scroll bar.
149 .frame_or_window gives the window
150 whose scroll bar was clicked in.
151 .timestamp gives a timestamp (in
152 milliseconds) for the click. */
133 SELECTION_REQUEST_EVENT, /* Another X client wants a selection from us. 153 SELECTION_REQUEST_EVENT, /* Another X client wants a selection from us.
134 See `struct selection_input_event'. */ 154 See `struct selection_input_event'. */
135 SELECTION_CLEAR_EVENT, /* Another X client cleared our selection. */ 155 SELECTION_CLEAR_EVENT, /* Another X client cleared our selection. */
@@ -518,6 +538,16 @@ struct terminal
518 int position); 538 int position);
519 539
520 540
541 /* Set the horizontal scroll bar for WINDOW to have its upper left
542 corner at (TOP, LEFT), and be LENGTH rows high. Set its handle to
543 indicate that we are displaying PORTION characters out of a total
544 of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
545 have a scroll bar, create one for it. */
546 void (*set_horizontal_scroll_bar_hook) (struct window *window,
547 int portion, int whole,
548 int position);
549
550
521 /* The following three hooks are used when we're doing a thorough 551 /* The following three hooks are used when we're doing a thorough
522 redisplay of the frame. We don't explicitly know which scroll bars 552 redisplay of the frame. We don't explicitly know which scroll bars
523 are going to be deleted, because keeping track of when windows go 553 are going to be deleted, because keeping track of when windows go
diff --git a/src/w32console.c b/src/w32console.c
index 2fbc190ee2d..98f68145191 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -657,6 +657,7 @@ initialize_w32_display (struct terminal *term, int *width, int *height)
657 term->frame_rehighlight_hook = 0; 657 term->frame_rehighlight_hook = 0;
658 term->frame_raise_lower_hook = 0; 658 term->frame_raise_lower_hook = 0;
659 term->set_vertical_scroll_bar_hook = 0; 659 term->set_vertical_scroll_bar_hook = 0;
660 term->set_horizontal_scroll_bar_hook = 0;
660 term->condemn_scroll_bars_hook = 0; 661 term->condemn_scroll_bars_hook = 0;
661 term->redeem_scroll_bar_hook = 0; 662 term->redeem_scroll_bar_hook = 0;
662 term->judge_scroll_bars_hook = 0; 663 term->judge_scroll_bars_hook = 0;
diff --git a/src/w32fns.c b/src/w32fns.c
index 14d1cb4e771..ac0e693e1c0 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -328,8 +328,7 @@ void x_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
328void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object); 328void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
329void x_set_title (struct frame *, Lisp_Object, Lisp_Object); 329void x_set_title (struct frame *, Lisp_Object, Lisp_Object);
330void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object); 330void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
331 331void x_set_internal_border_width (struct frame *f, Lisp_Object, Lisp_Object);
332
333 332
334 333
335/* Store the screen positions of frame F into XPTR and YPTR. 334/* Store the screen positions of frame F into XPTR and YPTR.
@@ -1361,23 +1360,23 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1361 { 1360 {
1362 CHECK_NUMBER (Vx_window_horizontal_drag_shape); 1361 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1363 horizontal_drag_cursor 1362 horizontal_drag_cursor
1364 = XCreateFontCursor (FRAME_X_DISPLAY (f), 1363 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1365 XINT (Vx_window_horizontal_drag_shape)); 1364 XINT (Vx_window_horizontal_drag_shape));
1366 } 1365 }
1367 else 1366 else
1368 horizontal_drag_cursor 1367 horizontal_drag_cursor
1369 = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow); 1368 = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_h_double_arrow);
1370 1369
1371 if (!NILP (Vx_window_vertical_drag_shape)) 1370 if (!NILP (Vx_window_vertical_drag_shape))
1372 { 1371 {
1373 CHECK_NUMBER (Vx_window_vertical_drag_shape); 1372 CHECK_NUMBER (Vx_window_vertical_drag_shape);
1374 vertical_drag_cursor 1373 vertical_drag_cursor
1375 = XCreateFontCursor (FRAME_X_DISPLAY (f), 1374 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1376 XINT (Vx_window_vertical_drag_shape)); 1375 XINT (Vx_window_vertical_drag_shape));
1377 } 1376 }
1378 else 1377 else
1379 vertical_drag_cursor 1378 vertical_drag_cursor
1380 = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_v_double_arrow); 1379 = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_v_double_arrow);
1381 1380
1382 /* Check and report errors with the above calls. */ 1381 /* Check and report errors with the above calls. */
1383 x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s"); 1382 x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
@@ -1599,9 +1598,54 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1599 unblock_input (); 1598 unblock_input ();
1600#endif 1599#endif
1601} 1600}
1602
1603 1601
1604void 1602void
1603x_clear_under_internal_border (struct frame *f)
1604{
1605 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1606
1607 /* Clear border if it's larger than before. */
1608 if (border != 0)
1609 {
1610 HDC hdc = get_frame_dc (f);
1611 int width = FRAME_PIXEL_WIDTH (f);
1612 int height = FRAME_PIXEL_HEIGHT (f);
1613
1614 block_input ();
1615 w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border);
1616 w32_clear_area (f, hdc, 0, 0, border, height);
1617 w32_clear_area (f, hdc, width - border, 0, border, height);
1618 w32_clear_area (f, hdc, 0, height - border, width, border);
1619 release_frame_dc (f, hdc);
1620 unblock_input ();
1621 }
1622}
1623
1624
1625void
1626x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1627{
1628 int border;
1629
1630 CHECK_TYPE_RANGED_INTEGER (int, arg);
1631 border = max (XINT (arg), 0);
1632
1633 if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
1634 {
1635 FRAME_INTERNAL_BORDER_WIDTH (f) = border;
1636
1637 if (FRAME_X_WINDOW (f) != 0)
1638 {
1639 adjust_frame_size (f, -1, -1, 3, 0);
1640
1641 if (FRAME_VISIBLE_P (f))
1642 x_clear_under_internal_border (f);
1643 }
1644 }
1645}
1646
1647
1648void
1605x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) 1649x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1606{ 1650{
1607 int nlines; 1651 int nlines;
@@ -1621,7 +1665,10 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1621 FRAME_MENU_BAR_LINES (f) = 0; 1665 FRAME_MENU_BAR_LINES (f) = 0;
1622 FRAME_MENU_BAR_HEIGHT (f) = 0; 1666 FRAME_MENU_BAR_HEIGHT (f) = 0;
1623 if (nlines) 1667 if (nlines)
1624 FRAME_EXTERNAL_MENU_BAR (f) = 1; 1668 {
1669 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1670 windows_or_buffers_changed = 23;
1671 }
1625 else 1672 else
1626 { 1673 {
1627 if (FRAME_EXTERNAL_MENU_BAR (f) == 1) 1674 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
@@ -1630,11 +1677,16 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1630 1677
1631 /* Adjust the frame size so that the client (text) dimensions 1678 /* Adjust the frame size so that the client (text) dimensions
1632 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being 1679 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
1633 set correctly. */ 1680 set correctly. Note that we resize twice: The first time upon
1634 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); 1681 a request from the window manager who wants to keep the height
1635 do_pending_window_change (0); 1682 of the outer rectangle (including decorations) unchanged, and a
1683 second time because we want to keep the height of the inner
1684 rectangle (without the decorations unchanged). */
1685 adjust_frame_size (f, -1, -1, 2, 1);
1686
1687 /* Not sure whether this is needed. */
1688 x_clear_under_internal_border (f);
1636 } 1689 }
1637 adjust_frame_glyphs (f);
1638} 1690}
1639 1691
1640 1692
@@ -1648,8 +1700,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1648void 1700void
1649x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) 1701x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1650{ 1702{
1651 int delta, nlines, root_height; 1703 int nlines;
1652 int unit = FRAME_LINE_HEIGHT (f);
1653 1704
1654 /* Treat tool bars like menu bars. */ 1705 /* Treat tool bars like menu bars. */
1655 if (FRAME_MINIBUF_ONLY_P (f)) 1706 if (FRAME_MINIBUF_ONLY_P (f))
@@ -1661,66 +1712,50 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1661 else 1712 else
1662 nlines = 0; 1713 nlines = 0;
1663 1714
1664 /* Make sure we redisplay all windows in this frame. */ 1715 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1665 windows_or_buffers_changed = 23; 1716}
1666 1717
1667 /* DELTA is in pixels now. */
1668 delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
1669 1718
1670 /* Don't resize the tool-bar to more than we have room for. Note: The 1719/* Set the pixel height of the tool bar of frame F to HEIGHT. */
1671 calculations below and the subsequent call to resize_frame_windows 1720void
1672 are inherently flawed because they can make the toolbar higher than 1721x_change_tool_bar_height (struct frame *f, int height)
1673 the containing frame. */ 1722{
1674 if (delta > 0) 1723 Lisp_Object frame;
1675 { 1724 int unit = FRAME_LINE_HEIGHT (f);
1676 root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f))); 1725 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1677 if (root_height - delta < unit) 1726 int lines = (height + unit - 1) / unit;
1678 { 1727 int old_text_height = FRAME_TEXT_HEIGHT (f);
1679 delta = root_height - unit;
1680 /* When creating a new frame and toolbar mode is enabled, we
1681 need at least one toolbar line. */
1682 nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1);
1683 }
1684 }
1685 1728
1686 FRAME_TOOL_BAR_LINES (f) = nlines; 1729 /* Make sure we redisplay all windows in this frame. */
1687 FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); 1730 windows_or_buffers_changed = 23;
1688 ++windows_or_buffers_changed; 1731
1689 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1); 1732 /* Recalculate tool bar and frame text sizes. */
1690 adjust_frame_glyphs (f); 1733 FRAME_TOOL_BAR_HEIGHT (f) = height;
1734 FRAME_TOOL_BAR_LINES (f) = lines;
1735 FRAME_TEXT_HEIGHT (f)
1736 = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f));
1737 FRAME_LINES (f)
1738 = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f));
1739 /* Store the `tool-bar-lines' and `height' frame parameters. */
1740 store_frame_param (f, Qtool_bar_lines, make_number (lines));
1741 store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
1691 1742
1692 /* We also have to make sure that the internal border at the top of
1693 the frame, below the menu bar or tool bar, is redrawn when the
1694 tool bar disappears. This is so because the internal border is
1695 below the tool bar if one is displayed, but is below the menu bar
1696 if there isn't a tool bar. The tool bar draws into the area
1697 below the menu bar. */
1698 if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0) 1743 if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1699 { 1744 {
1700 clear_frame (f); 1745 clear_frame (f);
1701 clear_current_matrices (f); 1746 clear_current_matrices (f);
1702 } 1747 }
1703 1748
1704 /* If the tool bar gets smaller, the internal border below it 1749 if ((height < old_height) && WINDOWP (f->tool_bar_window))
1705 has to be cleared. It was formerly part of the display 1750 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1706 of the larger tool bar, and updating windows won't clear it. */
1707 if (FRAME_INTERNAL_BORDER_WIDTH (f) != 0 && FRAME_VISIBLE_P (f))
1708 {
1709 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1710 int width = FRAME_PIXEL_WIDTH (f);
1711 int y = nlines * unit;
1712 HDC hdc = get_frame_dc (f);
1713 1751
1714 block_input (); 1752 /* Recalculate toolbar height. */
1715 w32_clear_area (f, hdc, 0, y, width, height); 1753 f->n_tool_bar_rows = 0;
1716 release_frame_dc (f, hdc);
1717 unblock_input ();
1718 }
1719 1754
1720 if (delta < 0 && WINDOWP (f->tool_bar_window)) 1755 adjust_frame_size (f, -1, -1, 4, 0);
1721 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1722 1756
1723 run_window_configuration_change_hook (f); 1757 if (FRAME_X_WINDOW (f))
1758 x_clear_under_internal_border (f);
1724} 1759}
1725 1760
1726 1761
@@ -1839,6 +1874,16 @@ x_set_scroll_bar_default_width (struct frame *f)
1839 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit; 1874 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
1840} 1875}
1841 1876
1877
1878void
1879x_set_scroll_bar_default_height (struct frame *f)
1880{
1881 int unit = FRAME_LINE_HEIGHT (f);
1882
1883 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL);
1884 FRAME_CONFIG_SCROLL_BAR_LINES (f)
1885 = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + unit - 1) / unit;
1886}
1842 1887
1843/* Subroutines for creating a frame. */ 1888/* Subroutines for creating a frame. */
1844 1889
@@ -1893,7 +1938,7 @@ w32_init_class (HINSTANCE hinst)
1893} 1938}
1894 1939
1895static HWND 1940static HWND
1896w32_createscrollbar (struct frame *f, struct scroll_bar * bar) 1941w32_createvscrollbar (struct frame *f, struct scroll_bar * bar)
1897{ 1942{
1898 return CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE, 1943 return CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
1899 /* Position and size of scroll bar. */ 1944 /* Position and size of scroll bar. */
@@ -1901,6 +1946,15 @@ w32_createscrollbar (struct frame *f, struct scroll_bar * bar)
1901 FRAME_W32_WINDOW (f), NULL, hinst, NULL); 1946 FRAME_W32_WINDOW (f), NULL, hinst, NULL);
1902} 1947}
1903 1948
1949static HWND
1950w32_createhscrollbar (struct frame *f, struct scroll_bar * bar)
1951{
1952 return CreateWindow ("SCROLLBAR", "", SBS_HORZ | WS_CHILD | WS_VISIBLE,
1953 /* Position and size of scroll bar. */
1954 bar->left, bar->top, bar->width, bar->height,
1955 FRAME_W32_WINDOW (f), NULL, hinst, NULL);
1956}
1957
1904static void 1958static void
1905w32_createwindow (struct frame *f) 1959w32_createwindow (struct frame *f)
1906{ 1960{
@@ -1952,7 +2006,8 @@ w32_createwindow (struct frame *f)
1952 SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); 2006 SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
1953 SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); 2007 SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
1954 SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); 2008 SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
1955 SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f)); 2009 SetWindowLong (hwnd, WND_VSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
2010 SetWindowLong (hwnd, WND_HSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_HEIGHT (f));
1956 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f)); 2011 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
1957 2012
1958 /* Enable drag-n-drop. */ 2013 /* Enable drag-n-drop. */
@@ -2367,7 +2422,8 @@ w32_name_of_message (UINT msg)
2367 M (WM_EMACS_KILL), 2422 M (WM_EMACS_KILL),
2368 M (WM_EMACS_CREATEWINDOW), 2423 M (WM_EMACS_CREATEWINDOW),
2369 M (WM_EMACS_DONE), 2424 M (WM_EMACS_DONE),
2370 M (WM_EMACS_CREATESCROLLBAR), 2425 M (WM_EMACS_CREATEVSCROLLBAR),
2426 M (WM_EMACS_CREATEHSCROLLBAR),
2371 M (WM_EMACS_SHOWWINDOW), 2427 M (WM_EMACS_SHOWWINDOW),
2372 M (WM_EMACS_SETWINDOWPOS), 2428 M (WM_EMACS_SETWINDOWPOS),
2373 M (WM_EMACS_DESTROYWINDOW), 2429 M (WM_EMACS_DESTROYWINDOW),
@@ -2384,6 +2440,7 @@ w32_name_of_message (UINT msg)
2384 M (WM_EMACS_SHOW_CARET), 2440 M (WM_EMACS_SHOW_CARET),
2385 M (WM_EMACS_HIDE_CARET), 2441 M (WM_EMACS_HIDE_CARET),
2386 M (WM_EMACS_SETCURSOR), 2442 M (WM_EMACS_SETCURSOR),
2443 M (WM_EMACS_SHOWCURSOR),
2387 M (WM_EMACS_PAINT), 2444 M (WM_EMACS_PAINT),
2388 M (WM_CHAR), 2445 M (WM_CHAR),
2389#undef M 2446#undef M
@@ -3441,6 +3498,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3441 track_mouse_event_fn (&tme); 3498 track_mouse_event_fn (&tme);
3442 track_mouse_window = hwnd; 3499 track_mouse_window = hwnd;
3443 } 3500 }
3501 case WM_HSCROLL:
3444 case WM_VSCROLL: 3502 case WM_VSCROLL:
3445 if (w32_mouse_move_interval <= 0 3503 if (w32_mouse_move_interval <= 0
3446 || (msg == WM_MOUSEMOVE && button_state == 0)) 3504 || (msg == WM_MOUSEMOVE && button_state == 0))
@@ -3779,10 +3837,14 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3779 return 0; 3837 return 0;
3780 3838
3781 case WM_WINDOWPOSCHANGING: 3839 case WM_WINDOWPOSCHANGING:
3782 /* Don't restrict the sizing of tip frames. */ 3840 /* Don't restrict the sizing of any kind of frames. If the window
3783 if (frame_resize_pixelwise || hwnd == tip_window) 3841 manager doesn't, there's no reason to do it ourselves. */
3784 return 0; 3842#if 0
3843 if (frame_resize_pixelwise || hwnd == tip_window)
3844#endif
3845 return 0;
3785 3846
3847#if 0
3786 /* Don't restrict the sizing of fullscreened frames, allowing them to be 3848 /* Don't restrict the sizing of fullscreened frames, allowing them to be
3787 flush with the sides of the screen. */ 3849 flush with the sides of the screen. */
3788 f = x_window_to_frame (dpyinfo, hwnd); 3850 f = x_window_to_frame (dpyinfo, hwnd);
@@ -3805,7 +3867,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3805 DWORD font_width; 3867 DWORD font_width;
3806 DWORD line_height; 3868 DWORD line_height;
3807 DWORD internal_border; 3869 DWORD internal_border;
3808 DWORD scrollbar_extra; 3870 DWORD vscrollbar_extra;
3871 DWORD hscrollbar_extra;
3809 RECT wr; 3872 RECT wr;
3810 3873
3811 wp.length = sizeof (wp); 3874 wp.length = sizeof (wp);
@@ -3816,7 +3879,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3816 font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX); 3879 font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);
3817 line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX); 3880 line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);
3818 internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX); 3881 internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);
3819 scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX); 3882 vscrollbar_extra = GetWindowLong (hwnd, WND_VSCROLLBAR_INDEX);
3883 hscrollbar_extra = GetWindowLong (hwnd, WND_HSCROLLBAR_INDEX);
3820 3884
3821 leave_crit (); 3885 leave_crit ();
3822 3886
@@ -3827,10 +3891,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3827 /* Force width and height of client area to be exact 3891 /* Force width and height of client area to be exact
3828 multiples of the character cell dimensions. */ 3892 multiples of the character cell dimensions. */
3829 wdiff = (lppos->cx - (rect.right - rect.left) 3893 wdiff = (lppos->cx - (rect.right - rect.left)
3830 - 2 * internal_border - scrollbar_extra) 3894 - 2 * internal_border - vscrollbar_extra)
3831 % font_width; 3895 % font_width;
3832 hdiff = (lppos->cy - (rect.bottom - rect.top) 3896 hdiff = (lppos->cy - (rect.bottom - rect.top)
3833 - 2 * internal_border) 3897 - 2 * internal_border - hscrollbar_extra)
3834 % line_height; 3898 % line_height;
3835 3899
3836 if (wdiff || hdiff) 3900 if (wdiff || hdiff)
@@ -3865,6 +3929,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3865 } 3929 }
3866 3930
3867 goto dflt; 3931 goto dflt;
3932#endif
3868 3933
3869 case WM_GETMINMAXINFO: 3934 case WM_GETMINMAXINFO:
3870 /* Hack to allow resizing the Emacs frame above the screen size. 3935 /* Hack to allow resizing the Emacs frame above the screen size.
@@ -3899,9 +3964,20 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3899 return 0; 3964 return 0;
3900 } 3965 }
3901 3966
3902 case WM_EMACS_CREATESCROLLBAR: 3967 case WM_EMACS_SHOWCURSOR:
3903 return (LRESULT) w32_createscrollbar ((struct frame *) wParam, 3968 {
3904 (struct scroll_bar *) lParam); 3969 ShowCursor ((BOOL) wParam);
3970
3971 return 0;
3972 }
3973
3974 case WM_EMACS_CREATEVSCROLLBAR:
3975 return (LRESULT) w32_createvscrollbar ((struct frame *) wParam,
3976 (struct scroll_bar *) lParam);
3977
3978 case WM_EMACS_CREATEHSCROLLBAR:
3979 return (LRESULT) w32_createhscrollbar ((struct frame *) wParam,
3980 (struct scroll_bar *) lParam);
3905 3981
3906 case WM_EMACS_SHOWWINDOW: 3982 case WM_EMACS_SHOWWINDOW:
3907 return ShowWindow ((HWND) wParam, (WPARAM) lParam); 3983 return ShowWindow ((HWND) wParam, (WPARAM) lParam);
@@ -4104,7 +4180,8 @@ my_create_tip_window (struct frame *f)
4104 SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f)); 4180 SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
4105 4181
4106 /* Tip frames have no scrollbars. */ 4182 /* Tip frames have no scrollbars. */
4107 SetWindowLong (tip_window, WND_SCROLLBAR_INDEX, 0); 4183 SetWindowLong (tip_window, WND_VSCROLLBAR_INDEX, 0);
4184 SetWindowLong (tip_window, WND_HSCROLLBAR_INDEX, 0);
4108 4185
4109 /* Do this to discard the default setting specified by our parent. */ 4186 /* Do this to discard the default setting specified by our parent. */
4110 ShowWindow (tip_window, SW_HIDE); 4187 ShowWindow (tip_window, SW_HIDE);
@@ -4336,7 +4413,6 @@ This function is an internal primitive--use `make-frame' instead. */)
4336 Lisp_Object name; 4413 Lisp_Object name;
4337 int minibuffer_only = 0; 4414 int minibuffer_only = 0;
4338 long window_prompting = 0; 4415 long window_prompting = 0;
4339 int width, height;
4340 ptrdiff_t count = SPECPDL_INDEX (); 4416 ptrdiff_t count = SPECPDL_INDEX ();
4341 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 4417 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4342 Lisp_Object display; 4418 Lisp_Object display;
@@ -4404,8 +4480,9 @@ This function is an internal primitive--use `make-frame' instead. */)
4404 4480
4405 XSETFRAME (frame, f); 4481 XSETFRAME (frame, f);
4406 4482
4407 /* By default, make scrollbars the system standard width. */ 4483 /* By default, make scrollbars the system standard width and height. */
4408 x_set_scroll_bar_default_width (f); 4484 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
4485 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL);
4409 4486
4410 f->terminal = dpyinfo->terminal; 4487 f->terminal = dpyinfo->terminal;
4411 4488
@@ -4431,7 +4508,6 @@ This function is an internal primitive--use `make-frame' instead. */)
4431#endif /* GLYPH_DEBUG */ 4508#endif /* GLYPH_DEBUG */
4432 4509
4433 /* Specify the parent under which to make this window. */ 4510 /* Specify the parent under which to make this window. */
4434
4435 if (!NILP (parent)) 4511 if (!NILP (parent))
4436 { 4512 {
4437 f->output_data.w32->parent_desc = (Window) XFASTINT (parent); 4513 f->output_data.w32->parent_desc = (Window) XFASTINT (parent);
@@ -4454,7 +4530,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4454 { 4530 {
4455 fset_name (f, name); 4531 fset_name (f, name);
4456 f->explicit_name = 1; 4532 f->explicit_name = 1;
4457 /* use the frame's title when getting resources for this frame. */ 4533 /* Use the frame's title when getting resources for this frame. */
4458 specbind (Qx_resource_name, name); 4534 specbind (Qx_resource_name, name);
4459 } 4535 }
4460 4536
@@ -4464,9 +4540,11 @@ This function is an internal primitive--use `make-frame' instead. */)
4464 4540
4465 x_default_parameter (f, parameters, Qfont_backend, Qnil, 4541 x_default_parameter (f, parameters, Qfont_backend, Qnil,
4466 "fontBackend", "FontBackend", RES_TYPE_STRING); 4542 "fontBackend", "FontBackend", RES_TYPE_STRING);
4543
4467 /* Extract the window parameters from the supplied values 4544 /* Extract the window parameters from the supplied values
4468 that are needed to determine window geometry. */ 4545 that are needed to determine window geometry. */
4469 x_default_font_parameter (f, parameters); 4546 x_default_font_parameter (f, parameters);
4547
4470 x_default_parameter (f, parameters, Qborder_width, make_number (2), 4548 x_default_parameter (f, parameters, Qborder_width, make_number (2),
4471 "borderWidth", "BorderWidth", RES_TYPE_NUMBER); 4549 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4472 4550
@@ -4480,7 +4558,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4480 "internalBorder", "InternalBorder", RES_TYPE_NUMBER); 4558 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
4481 if (! EQ (value, Qunbound)) 4559 if (! EQ (value, Qunbound))
4482 parameters = Fcons (Fcons (Qinternal_border_width, value), 4560 parameters = Fcons (Fcons (Qinternal_border_width, value),
4483 parameters); 4561 parameters);
4484 } 4562 }
4485 /* Default internalBorderWidth to 0 on Windows to match other programs. */ 4563 /* Default internalBorderWidth to 0 on Windows to match other programs. */
4486 x_default_parameter (f, parameters, Qinternal_border_width, make_number (0), 4564 x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
@@ -4491,6 +4569,8 @@ This function is an internal primitive--use `make-frame' instead. */)
4491 NULL, NULL, RES_TYPE_NUMBER); 4569 NULL, NULL, RES_TYPE_NUMBER);
4492 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright, 4570 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
4493 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL); 4571 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
4572 x_default_parameter (f, parameters, Qhorizontal_scroll_bars, Qbottom,
4573 "horizontalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
4494 4574
4495 /* Also do the stuff which must be set before the window exists. */ 4575 /* Also do the stuff which must be set before the window exists. */
4496 x_default_parameter (f, parameters, Qforeground_color, build_string ("black"), 4576 x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
@@ -4511,57 +4591,42 @@ This function is an internal primitive--use `make-frame' instead. */)
4511 "rightFringe", "RightFringe", RES_TYPE_NUMBER); 4591 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
4512 /* Process alpha here (Bug#16619). */ 4592 /* Process alpha here (Bug#16619). */
4513 x_default_parameter (f, parameters, Qalpha, Qnil, 4593 x_default_parameter (f, parameters, Qalpha, Qnil,
4514 "alpha", "Alpha", RES_TYPE_NUMBER); 4594 "alpha", "Alpha", RES_TYPE_NUMBER);
4515 4595
4516 /* Init faces before x_default_parameter is called for scroll-bar 4596 /* Init faces first since we need the frame's column width/line
4517 parameters because that function calls x_set_scroll_bar_width, 4597 height in various occasions. */
4518 which calls change_frame_size, which calls Fset_window_buffer,
4519 which runs hooks, which call Fvertical_motion. At the end, we
4520 end up in init_iterator with a null face cache, which should not
4521 happen. */
4522 init_frame_faces (f); 4598 init_frame_faces (f);
4523 4599
4524 /* Avoid calling window-configuration-change-hook; otherwise we 4600 /* The following call of change_frame_size is needed since otherwise
4525 could get an infloop in next_frame since the frame is not yet in 4601 x_set_tool_bar_lines will already work with the character sizes
4526 Vframe_list. */ 4602 installed by init_frame_faces while the frame's pixel size is
4527 { 4603 still calculated from a character size of 1 and we subsequently
4528 ptrdiff_t count2 = SPECPDL_INDEX (); 4604 hit the (height >= 0) assertion in window_box_height.
4529 4605
4530 record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code); 4606 The non-pixelwise code apparently worked around this because it
4531 inhibit_lisp_code = Qt; 4607 had one frame line vs one toolbar line which left us with a zero
4532 4608 root window height which was obviously wrong as well ... */
4533 /* PXW: This is a duplicate from below. We have to do it here since 4609 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
4534 otherwise x_set_tool_bar_lines will work with the character sizes 4610 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1);
4535 installed by init_frame_faces while the frame's pixel size is still 4611
4536 calculated from a character size of 1 and we subsequently hit the 4612 /* The X resources controlling the menu-bar and tool-bar are
4537 eassert (height >= 0) assertion in window_box_height. The 4613 processed specially at startup, and reflected in the mode
4538 non-pixelwise code apparently worked around this because it had one 4614 variables; ignore them here. */
4539 frame line vs one toolbar line which left us with a zero root 4615 x_default_parameter (f, parameters, Qmenu_bar_lines,
4540 window height which was obviously wrong as well ... */ 4616 NILP (Vmenu_bar_mode)
4541 change_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 4617 ? make_number (0) : make_number (1),
4542 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1, 0, 0, 1); 4618 NULL, NULL, RES_TYPE_NUMBER);
4543 4619 x_default_parameter (f, parameters, Qtool_bar_lines,
4544 /* The X resources controlling the menu-bar and tool-bar are 4620 NILP (Vtool_bar_mode)
4545 processed specially at startup, and reflected in the mode 4621 ? make_number (0) : make_number (1),
4546 variables; ignore them here. */ 4622 NULL, NULL, RES_TYPE_NUMBER);
4547 x_default_parameter (f, parameters, Qmenu_bar_lines,
4548 NILP (Vmenu_bar_mode)
4549 ? make_number (0) : make_number (1),
4550 NULL, NULL, RES_TYPE_NUMBER);
4551 x_default_parameter (f, parameters, Qtool_bar_lines,
4552 NILP (Vtool_bar_mode)
4553 ? make_number (0) : make_number (1),
4554 NULL, NULL, RES_TYPE_NUMBER);
4555
4556 unbind_to (count2, Qnil);
4557 }
4558 4623
4559 x_default_parameter (f, parameters, Qbuffer_predicate, Qnil, 4624 x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
4560 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL); 4625 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
4561 x_default_parameter (f, parameters, Qtitle, Qnil, 4626 x_default_parameter (f, parameters, Qtitle, Qnil,
4562 "title", "Title", RES_TYPE_STRING); 4627 "title", "Title", RES_TYPE_STRING);
4563 x_default_parameter (f, parameters, Qfullscreen, Qnil, 4628 x_default_parameter (f, parameters, Qfullscreen, Qnil,
4564 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); 4629 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
4565 4630
4566 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; 4631 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
4567 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 4632 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
@@ -4604,15 +4669,13 @@ This function is an internal primitive--use `make-frame' instead. */)
4604 "cursorType", "CursorType", RES_TYPE_SYMBOL); 4669 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4605 x_default_parameter (f, parameters, Qscroll_bar_width, Qnil, 4670 x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
4606 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER); 4671 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
4672 x_default_parameter (f, parameters, Qscroll_bar_height, Qnil,
4673 "scrollBarHeight", "ScrollBarHeight", RES_TYPE_NUMBER);
4674
4675 /* Consider frame official, now. */
4676 f->official = true;
4607 4677
4608 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. 4678 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1);
4609 Change will not be effected unless different from the current
4610 FRAME_LINES (f). */
4611 width = FRAME_TEXT_WIDTH (f);
4612 height = FRAME_TEXT_HEIGHT (f);
4613 FRAME_TEXT_HEIGHT (f) = 0;
4614 SET_FRAME_WIDTH (f, 0);
4615 change_frame_size (f, width, height, 1, 0, 0, 1);
4616 4679
4617 /* Tell the server what size and position, etc, we want, and how 4680 /* Tell the server what size and position, etc, we want, and how
4618 badly we want them. This should be done after we have the menu 4681 badly we want them. This should be done after we have the menu
@@ -5672,13 +5735,12 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5672 "cursorColor", "Foreground", RES_TYPE_STRING); 5735 "cursorColor", "Foreground", RES_TYPE_STRING);
5673 x_default_parameter (f, parms, Qborder_color, build_string ("black"), 5736 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
5674 "borderColor", "BorderColor", RES_TYPE_STRING); 5737 "borderColor", "BorderColor", RES_TYPE_STRING);
5738 x_default_parameter (f, parms, Qalpha, Qnil,
5739 "alpha", "Alpha", RES_TYPE_NUMBER);
5675 5740
5676 /* Init faces before x_default_parameter is called for scroll-bar 5741 /* Init faces before x_default_parameter is called for the
5677 parameters because that function calls x_set_scroll_bar_width, 5742 scroll-bar-width parameter because otherwise we end up in
5678 which calls change_frame_size, which calls Fset_window_buffer, 5743 init_iterator with a null face cache, which should not happen. */
5679 which runs hooks, which call Fvertical_motion. At the end, we
5680 end up in init_iterator with a null face cache, which should not
5681 happen. */
5682 init_frame_faces (f); 5744 init_frame_faces (f);
5683 5745
5684 f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED; 5746 f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
@@ -5709,9 +5771,10 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5709 from the current FRAME_LINES (f). */ 5771 from the current FRAME_LINES (f). */
5710 width = FRAME_COLS (f); 5772 width = FRAME_COLS (f);
5711 height = FRAME_LINES (f); 5773 height = FRAME_LINES (f);
5712 FRAME_LINES (f) = 0;
5713 SET_FRAME_COLS (f, 0); 5774 SET_FRAME_COLS (f, 0);
5714 change_frame_size (f, width, height, 1, 0, 0, 0); 5775 SET_FRAME_LINES (f, 0);
5776 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
5777 height * FRAME_LINE_HEIGHT (f), 0, 1);
5715 5778
5716 /* Add `tooltip' frame parameter's default value. */ 5779 /* Add `tooltip' frame parameter's default value. */
5717 if (NILP (Fframe_parameter (frame, Qtooltip))) 5780 if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -5756,6 +5819,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5756 below. And the frame needs to be on Vframe_list or making it 5819 below. And the frame needs to be on Vframe_list or making it
5757 visible won't work. */ 5820 visible won't work. */
5758 Vframe_list = Fcons (frame, Vframe_list); 5821 Vframe_list = Fcons (frame, Vframe_list);
5822 f->official = true;
5759 5823
5760 /* Setting attributes of faces of the tooltip frame from resources 5824 /* Setting attributes of faces of the tooltip frame from resources
5761 and similar will increment face_change_count, which leads to the 5825 and similar will increment face_change_count, which leads to the
@@ -7966,17 +8030,19 @@ frame_parm_handler w32_frame_parm_handlers[] =
7966 x_set_mouse_color, 8030 x_set_mouse_color,
7967 x_explicitly_set_name, 8031 x_explicitly_set_name,
7968 x_set_scroll_bar_width, 8032 x_set_scroll_bar_width,
8033 x_set_scroll_bar_height,
7969 x_set_title, 8034 x_set_title,
7970 x_set_unsplittable, 8035 x_set_unsplittable,
7971 x_set_vertical_scroll_bars, 8036 x_set_vertical_scroll_bars,
8037 x_set_horizontal_scroll_bars,
7972 x_set_visibility, 8038 x_set_visibility,
7973 x_set_tool_bar_lines, 8039 x_set_tool_bar_lines,
7974 0, /* x_set_scroll_bar_foreground, */ 8040 0, /* x_set_scroll_bar_foreground, */
7975 0, /* x_set_scroll_bar_background, */ 8041 0, /* x_set_scroll_bar_background, */
7976 x_set_screen_gamma, 8042 x_set_screen_gamma,
7977 x_set_line_spacing, 8043 x_set_line_spacing,
7978 x_set_fringe_width, 8044 x_set_left_fringe,
7979 x_set_fringe_width, 8045 x_set_right_fringe,
7980 0, /* x_set_wait_for_wm, */ 8046 0, /* x_set_wait_for_wm, */
7981 x_set_fullscreen, 8047 x_set_fullscreen,
7982 x_set_font_backend, 8048 x_set_font_backend,
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 50538c5b4ba..ccb5a900a16 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -587,7 +587,8 @@ 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.X, event->dwSize.Y, 0, 1, 0, 0); 590 change_frame_size (f, event->dwSize.X, event->dwSize.Y
591 - FRAME_MENU_BAR_LINES (f), 0, 1, 0, 0);
591 SET_FRAME_GARBAGED (f); 592 SET_FRAME_GARBAGED (f);
592} 593}
593 594
@@ -603,8 +604,8 @@ maybe_generate_resize_event (void)
603 if the size hasn't actually changed. */ 604 if the size hasn't actually changed. */
604 change_frame_size (f, 605 change_frame_size (f,
605 1 + info.srWindow.Right - info.srWindow.Left, 606 1 + info.srWindow.Right - info.srWindow.Left,
606 1 + info.srWindow.Bottom - info.srWindow.Top, 607 1 + info.srWindow.Bottom - info.srWindow.Top
607 0, 0, 0, 0); 608 - FRAME_MENU_BAR_LINES (f), 0, 0, 0, 0);
608} 609}
609 610
610#if HAVE_W32NOTIFY 611#if HAVE_W32NOTIFY
diff --git a/src/w32menu.c b/src/w32menu.c
index 6276c840fc6..9f777167bf0 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -503,7 +503,8 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
503 /* Force the window size to be recomputed so that the frame's text 503 /* Force the window size to be recomputed so that the frame's text
504 area remains the same, if menubar has just been created. */ 504 area remains the same, if menubar has just been created. */
505 if (old_widget == NULL) 505 if (old_widget == NULL)
506 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); 506 adjust_frame_size (f, FRAME_TEXT_WIDTH (f),
507 FRAME_TEXT_HEIGHT (f), 2, 0);
507 } 508 }
508 509
509 unblock_input (); 510 unblock_input ();
diff --git a/src/w32term.c b/src/w32term.c
index fd902ee7cd5..dfda29fb903 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -158,8 +158,11 @@ DWORD dwMainThreadId = 0;
158HANDLE hMainThread = NULL; 158HANDLE hMainThread = NULL;
159 159
160int vertical_scroll_bar_min_handle; 160int vertical_scroll_bar_min_handle;
161int horizontal_scroll_bar_min_handle;
161int vertical_scroll_bar_top_border; 162int vertical_scroll_bar_top_border;
162int vertical_scroll_bar_bottom_border; 163int vertical_scroll_bar_bottom_border;
164int horizontal_scroll_bar_left_border;
165int horizontal_scroll_bar_right_border;
163 166
164int last_scroll_bar_drag_pos; 167int last_scroll_bar_drag_pos;
165 168
@@ -455,7 +458,7 @@ x_set_frame_alpha (struct frame *f)
455 if (!pfnSetLayeredWindowAttributes) 458 if (!pfnSetLayeredWindowAttributes)
456 return; 459 return;
457 460
458 if (dpyinfo->x_highlight_frame == f) 461 if (dpyinfo->w32_focus_frame == f)
459 alpha = f->alpha[0]; 462 alpha = f->alpha[0];
460 else 463 else
461 alpha = f->alpha[1]; 464 alpha = f->alpha[1];
@@ -3337,11 +3340,15 @@ note_mouse_movement (struct frame *frame, MSG *msg)
3337 Mouse Face 3340 Mouse Face
3338 ************************************************************************/ 3341 ************************************************************************/
3339 3342
3340static struct scroll_bar *x_window_to_scroll_bar (Window); 3343static struct scroll_bar *x_window_to_scroll_bar (Window, int);
3341static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, 3344static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
3342 enum scroll_bar_part *, 3345 enum scroll_bar_part *,
3343 Lisp_Object *, Lisp_Object *, 3346 Lisp_Object *, Lisp_Object *,
3344 unsigned long *); 3347 unsigned long *);
3348static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
3349 enum scroll_bar_part *,
3350 Lisp_Object *, Lisp_Object *,
3351 unsigned long *);
3345static void x_check_fullscreen (struct frame *); 3352static void x_check_fullscreen (struct frame *);
3346 3353
3347static void 3354static void
@@ -3349,6 +3356,7 @@ w32_define_cursor (Window window, Cursor cursor)
3349{ 3356{
3350 PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0); 3357 PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
3351} 3358}
3359
3352/* Return the current position of the mouse. 3360/* Return the current position of the mouse.
3353 *fp should be a frame which indicates which display to ask about. 3361 *fp should be a frame which indicates which display to ask about.
3354 3362
@@ -3380,7 +3388,14 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3380 block_input (); 3388 block_input ();
3381 3389
3382 if (dpyinfo->last_mouse_scroll_bar && insist == 0) 3390 if (dpyinfo->last_mouse_scroll_bar && insist == 0)
3383 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); 3391 {
3392 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
3393
3394 if (bar->horizontal)
3395 x_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
3396 else
3397 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
3398 }
3384 else 3399 else
3385 { 3400 {
3386 POINT pt; 3401 POINT pt;
@@ -3408,7 +3423,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3408 if (! f1) 3423 if (! f1)
3409 { 3424 {
3410 struct scroll_bar *bar 3425 struct scroll_bar *bar
3411 = x_window_to_scroll_bar (WindowFromPoint (pt)); 3426 = x_window_to_scroll_bar (WindowFromPoint (pt), 2);
3412 3427
3413 if (bar) 3428 if (bar)
3414 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 3429 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
@@ -3475,12 +3490,12 @@ w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
3475 3490
3476/* Scroll bar support. */ 3491/* Scroll bar support. */
3477 3492
3478/* Given a window ID, find the struct scroll_bar which manages it. 3493/* Given a window ID, find the struct scroll_bar which manages it
3479 This can be called in GC, so we have to make sure to strip off mark 3494 vertically. This can be called in GC, so we have to make sure to
3480 bits. */ 3495 strip off mark bits. */
3481 3496
3482static struct scroll_bar * 3497static struct scroll_bar *
3483x_window_to_scroll_bar (Window window_id) 3498x_window_to_scroll_bar (Window window_id, int type)
3484{ 3499{
3485 Lisp_Object tail, frame; 3500 Lisp_Object tail, frame;
3486 3501
@@ -3498,7 +3513,10 @@ x_window_to_scroll_bar (Window window_id)
3498 condemned = Qnil, 3513 condemned = Qnil,
3499 ! NILP (bar)); 3514 ! NILP (bar));
3500 bar = XSCROLL_BAR (bar)->next) 3515 bar = XSCROLL_BAR (bar)->next)
3501 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id) 3516 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id
3517 && (type = 2
3518 || (type == 1 && XSCROLL_BAR (bar)->horizontal)
3519 || (type == 0 && !XSCROLL_BAR (bar)->horizontal)))
3502 return XSCROLL_BAR (bar); 3520 return XSCROLL_BAR (bar);
3503 } 3521 }
3504 3522
@@ -3507,7 +3525,7 @@ x_window_to_scroll_bar (Window window_id)
3507 3525
3508 3526
3509 3527
3510/* Set the thumb size and position of scroll bar BAR. We are currently 3528/* Set the thumb size and position of vertical scroll bar BAR. We are currently
3511 displaying PORTION out of a whole WHOLE, and our position POSITION. */ 3529 displaying PORTION out of a whole WHOLE, and our position POSITION. */
3512 3530
3513static void 3531static void
@@ -3581,16 +3599,49 @@ w32_set_scroll_bar_thumb (struct scroll_bar *bar,
3581 unblock_input (); 3599 unblock_input ();
3582} 3600}
3583 3601
3602/* Set the thumb size and position of horizontal scroll bar BAR. We are currently
3603 displaying PORTION out of a whole WHOLE, and our position POSITION. */
3604
3605static void
3606w32_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
3607 int portion, int position, int whole)
3608{
3609 Window w = SCROLL_BAR_W32_WINDOW (bar);
3610 SCROLLINFO si;
3611
3612 block_input ();
3613
3614 si.cbSize = sizeof (si);
3615 si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
3616 si.nMin = 0;
3617 si.nMax = whole;
3618 /* Allow nPage to be one larger than nPos so we don't allow to scroll
3619 an already fully visible buffer. */
3620 si.nPage = min (portion, si.nMax) + 1;
3621 si.nPos = min (position, si.nMax);
3622 SetScrollInfo (w, SB_CTL, &si, TRUE);
3623
3624 unblock_input ();
3625}
3626
3584 3627
3585/************************************************************************ 3628/************************************************************************
3586 Scroll bars, general 3629 Scroll bars, general
3587 ************************************************************************/ 3630 ************************************************************************/
3588 3631
3589static HWND 3632static HWND
3590my_create_scrollbar (struct frame * f, struct scroll_bar * bar) 3633my_create_vscrollbar (struct frame * f, struct scroll_bar * bar)
3634{
3635 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
3636 WM_EMACS_CREATEVSCROLLBAR, (WPARAM) f,
3637 (LPARAM) bar);
3638}
3639
3640static HWND
3641my_create_hscrollbar (struct frame * f, struct scroll_bar * bar)
3591{ 3642{
3592 return (HWND) SendMessage (FRAME_W32_WINDOW (f), 3643 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
3593 WM_EMACS_CREATESCROLLBAR, (WPARAM) f, 3644 WM_EMACS_CREATEHSCROLLBAR, (WPARAM) f,
3594 (LPARAM) bar); 3645 (LPARAM) bar);
3595} 3646}
3596 3647
@@ -3660,7 +3711,7 @@ my_bring_window_to_top (HWND hwnd)
3660 scroll bar. */ 3711 scroll bar. */
3661 3712
3662static struct scroll_bar * 3713static struct scroll_bar *
3663x_scroll_bar_create (struct window *w, int top, int left, int width, int height) 3714x_scroll_bar_create (struct window *w, int left, int top, int width, int height, bool horizontal)
3664{ 3715{
3665 struct frame *f = XFRAME (WINDOW_FRAME (w)); 3716 struct frame *f = XFRAME (WINDOW_FRAME (w));
3666 HWND hwnd; 3717 HWND hwnd;
@@ -3679,16 +3730,24 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
3679 bar->start = 0; 3730 bar->start = 0;
3680 bar->end = 0; 3731 bar->end = 0;
3681 bar->dragging = 0; 3732 bar->dragging = 0;
3733 bar->horizontal = horizontal;
3682 3734
3683 /* Requires geometry to be set before call to create the real window */ 3735 /* Requires geometry to be set before call to create the real window */
3684 3736
3685 hwnd = my_create_scrollbar (f, bar); 3737 if (horizontal)
3738 hwnd = my_create_hscrollbar (f, bar);
3739 else
3740 hwnd = my_create_vscrollbar (f, bar);
3686 3741
3687 si.cbSize = sizeof (si); 3742 si.cbSize = sizeof (si);
3688 si.fMask = SIF_ALL; 3743 si.fMask = SIF_ALL;
3689 si.nMin = 0; 3744 si.nMin = 0;
3690 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height) 3745 if (horizontal)
3691 + VERTICAL_SCROLL_BAR_MIN_HANDLE; 3746 si.nMax = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width)
3747 + HORIZONTAL_SCROLL_BAR_MIN_HANDLE;
3748 else
3749 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
3750 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3692 si.nPage = si.nMax; 3751 si.nPage = si.nMax;
3693 si.nPos = 0; 3752 si.nPos = 0;
3694 3753
@@ -3724,15 +3783,18 @@ x_scroll_bar_remove (struct scroll_bar *bar)
3724 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar)); 3783 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
3725 3784
3726 /* Dissociate this scroll bar from its window. */ 3785 /* Dissociate this scroll bar from its window. */
3727 wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil); 3786 if (bar->horizontal)
3787 wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
3788 else
3789 wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
3728 3790
3729 unblock_input (); 3791 unblock_input ();
3730} 3792}
3731 3793
3732/* Set the handle of the vertical scroll bar for WINDOW to indicate 3794/* Set the handle of the vertical scroll bar for WINDOW to indicate that
3733 that we are displaying PORTION characters out of a total of WHOLE 3795 we are displaying PORTION characters out of a total of WHOLE
3734 characters, starting at POSITION. If WINDOW has no scroll bar, 3796 characters, starting at POSITION. If WINDOW has no vertical scroll
3735 create one. */ 3797 bar, create one. */
3736static void 3798static void
3737w32_set_vertical_scroll_bar (struct window *w, 3799w32_set_vertical_scroll_bar (struct window *w,
3738 int portion, int whole, int position) 3800 int portion, int whole, int position)
@@ -3765,7 +3827,7 @@ w32_set_vertical_scroll_bar (struct window *w,
3765 } 3827 }
3766 unblock_input (); 3828 unblock_input ();
3767 3829
3768 bar = x_scroll_bar_create (w, top, left, width, height); 3830 bar = x_scroll_bar_create (w, left, top, width, height, 0);
3769 } 3831 }
3770 else 3832 else
3771 { 3833 {
@@ -3829,6 +3891,106 @@ w32_set_vertical_scroll_bar (struct window *w,
3829 wset_vertical_scroll_bar (w, barobj); 3891 wset_vertical_scroll_bar (w, barobj);
3830} 3892}
3831 3893
3894/* Set the handle of the horizontal scroll bar for WINDOW to indicate
3895 that we are displaying PORTION characters out of a total of WHOLE
3896 characters, starting at POSITION. If WINDOW has no horizontal scroll
3897 bar, create one. */
3898static void
3899w32_set_horizontal_scroll_bar (struct window *w,
3900 int portion, int whole, int position)
3901{
3902 struct frame *f = XFRAME (w->frame);
3903 Lisp_Object barobj;
3904 struct scroll_bar *bar;
3905 int top, height, left, width;
3906 int window_x, window_width;
3907 int clear_left = WINDOW_LEFT_EDGE_X (w);
3908 int clear_width = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
3909
3910 /* Get window dimensions. */
3911 window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
3912 left = window_x;
3913 height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
3914 width = window_width;
3915 top = WINDOW_SCROLL_BAR_AREA_Y (w);
3916
3917 /* Does the scroll bar exist yet? */
3918 if (NILP (w->horizontal_scroll_bar))
3919 {
3920 HDC hdc;
3921 block_input ();
3922 if (width > 0 && height > 0)
3923 {
3924 hdc = get_frame_dc (f);
3925 w32_clear_area (f, hdc, clear_left, top, clear_width, height);
3926 release_frame_dc (f, hdc);
3927 }
3928 unblock_input ();
3929
3930 bar = x_scroll_bar_create (w, left, top, width, height, 1);
3931 }
3932 else
3933 {
3934 /* It may just need to be moved and resized. */
3935 HWND hwnd;
3936
3937 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
3938 hwnd = SCROLL_BAR_W32_WINDOW (bar);
3939
3940 /* If already correctly positioned, do nothing. */
3941 if (bar->left == left && bar->top == top
3942 && bar->width == width && bar->height == height)
3943 {
3944 /* Redraw after clear_frame. */
3945 if (!my_show_window (f, hwnd, SW_NORMAL))
3946 InvalidateRect (hwnd, NULL, FALSE);
3947 }
3948 else
3949 {
3950 HDC hdc;
3951 SCROLLINFO si;
3952
3953 block_input ();
3954 if (width && height)
3955 {
3956 hdc = get_frame_dc (f);
3957 /* Since Windows scroll bars are smaller than the space reserved
3958 for them on the frame, we have to clear "under" them. */
3959 w32_clear_area (f, hdc, clear_left, top, clear_width, height);
3960 release_frame_dc (f, hdc);
3961 }
3962 /* Make sure scroll bar is "visible" before moving, to ensure the
3963 area of the parent window now exposed will be refreshed. */
3964 my_show_window (f, hwnd, SW_HIDE);
3965 MoveWindow (hwnd, left, top, width, max (height, 1), TRUE);
3966
3967 /* +++ SetScrollInfo +++ */
3968 si.cbSize = sizeof (si);
3969 si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
3970 si.nMin = 0;
3971 si.nMax = whole;
3972 si.nPage = min (portion, si.nMax) + 1;
3973 si.nPos = min (position, si.nMax);
3974 SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
3975
3976 my_show_window (f, hwnd, SW_NORMAL);
3977 /* InvalidateRect (w, NULL, FALSE); */
3978
3979 /* Remember new settings. */
3980 bar->left = left;
3981 bar->top = top;
3982 bar->width = width;
3983 bar->height = height;
3984
3985 unblock_input ();
3986 }
3987 }
3988
3989 w32_set_horizontal_scroll_bar_thumb (bar, portion, position, whole);
3990 XSETVECTOR (barobj, bar);
3991 wset_horizontal_scroll_bar (w, barobj);
3992}
3993
3832 3994
3833/* The following three hooks are used when we're doing a thorough 3995/* The following three hooks are used when we're doing a thorough
3834 redisplay of the frame. We don't explicitly know which scroll bars 3996 redisplay of the frame. We don't explicitly know which scroll bars
@@ -3845,17 +4007,22 @@ w32_set_vertical_scroll_bar (struct window *w,
3845static void 4007static void
3846w32_condemn_scroll_bars (struct frame *frame) 4008w32_condemn_scroll_bars (struct frame *frame)
3847{ 4009{
3848 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */ 4010 if (!NILP (FRAME_SCROLL_BARS (frame)))
3849 while (! NILP (FRAME_SCROLL_BARS (frame)))
3850 { 4011 {
3851 Lisp_Object bar; 4012 if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
3852 bar = FRAME_SCROLL_BARS (frame); 4013 {
3853 fset_scroll_bars (frame, XSCROLL_BAR (bar)->next); 4014 /* Prepend scrollbars to already condemned ones. */
3854 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame); 4015 Lisp_Object last = FRAME_SCROLL_BARS (frame);
3855 XSCROLL_BAR (bar)->prev = Qnil; 4016
3856 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame))) 4017 while (!NILP (XSCROLL_BAR (last)->next))
3857 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar; 4018 last = XSCROLL_BAR (last)->next;
3858 fset_condemned_scroll_bars (frame, bar); 4019
4020 XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
4021 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
4022 }
4023
4024 fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
4025 fset_scroll_bars (frame, Qnil);
3859 } 4026 }
3860} 4027}
3861 4028
@@ -3864,47 +4031,84 @@ w32_condemn_scroll_bars (struct frame *frame)
3864 Note that WINDOW isn't necessarily condemned at all. */ 4031 Note that WINDOW isn't necessarily condemned at all. */
3865 4032
3866static void 4033static void
3867w32_redeem_scroll_bar (struct window *window) 4034w32_redeem_scroll_bar (struct window *w)
3868{ 4035{
3869 struct scroll_bar *bar; 4036 struct scroll_bar *bar;
3870 Lisp_Object barobj; 4037 Lisp_Object barobj;
3871 struct frame *f; 4038 struct frame *f;
3872 4039
3873 /* We can't redeem this window's scroll bar if it doesn't have one. */ 4040 /* We can't redeem this window's scroll bar if it doesn't have one. */
3874 if (NILP (window->vertical_scroll_bar)) 4041 if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
3875 emacs_abort (); 4042 emacs_abort ();
3876 4043
3877 bar = XSCROLL_BAR (window->vertical_scroll_bar); 4044 if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
3878
3879 /* Unlink it from the condemned list. */
3880 f = XFRAME (WINDOW_FRAME (window));
3881 if (NILP (bar->prev))
3882 { 4045 {
3883 /* If the prev pointer is nil, it must be the first in one of 4046 bar = XSCROLL_BAR (w->vertical_scroll_bar);
3884 the lists. */ 4047 /* Unlink it from the condemned list. */
3885 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar)) 4048 f = XFRAME (WINDOW_FRAME (w));
3886 /* It's not condemned. Everything's fine. */ 4049 if (NILP (bar->prev))
3887 return; 4050 {
3888 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), 4051 /* If the prev pointer is nil, it must be the first in one of
3889 window->vertical_scroll_bar)) 4052 the lists. */
3890 fset_condemned_scroll_bars (f, bar->next); 4053 if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
4054 /* It's not condemned. Everything's fine. */
4055 goto horizontal;
4056 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
4057 w->vertical_scroll_bar))
4058 fset_condemned_scroll_bars (f, bar->next);
4059 else
4060 /* If its prev pointer is nil, it must be at the front of
4061 one or the other! */
4062 emacs_abort ();
4063 }
3891 else 4064 else
3892 /* If its prev pointer is nil, it must be at the front of 4065 XSCROLL_BAR (bar->prev)->next = bar->next;
3893 one or the other! */ 4066
3894 emacs_abort (); 4067 if (! NILP (bar->next))
4068 XSCROLL_BAR (bar->next)->prev = bar->prev;
4069
4070 bar->next = FRAME_SCROLL_BARS (f);
4071 bar->prev = Qnil;
4072 XSETVECTOR (barobj, bar);
4073 fset_scroll_bars (f, barobj);
4074 if (! NILP (bar->next))
4075 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
3895 } 4076 }
3896 else
3897 XSCROLL_BAR (bar->prev)->next = bar->next;
3898 4077
3899 if (! NILP (bar->next)) 4078 horizontal:
3900 XSCROLL_BAR (bar->next)->prev = bar->prev; 4079 if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
4080 {
4081 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
4082 /* Unlink it from the condemned list. */
4083 f = XFRAME (WINDOW_FRAME (w));
4084 if (NILP (bar->prev))
4085 {
4086 /* If the prev pointer is nil, it must be the first in one of
4087 the lists. */
4088 if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
4089 /* It's not condemned. Everything's fine. */
4090 return;
4091 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
4092 w->horizontal_scroll_bar))
4093 fset_condemned_scroll_bars (f, bar->next);
4094 else
4095 /* If its prev pointer is nil, it must be at the front of
4096 one or the other! */
4097 emacs_abort ();
4098 }
4099 else
4100 XSCROLL_BAR (bar->prev)->next = bar->next;
3901 4101
3902 bar->next = FRAME_SCROLL_BARS (f); 4102 if (! NILP (bar->next))
3903 bar->prev = Qnil; 4103 XSCROLL_BAR (bar->next)->prev = bar->prev;
3904 XSETVECTOR (barobj, bar); 4104
3905 fset_scroll_bars (f, barobj); 4105 bar->next = FRAME_SCROLL_BARS (f);
3906 if (! NILP (bar->next)) 4106 bar->prev = Qnil;
3907 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); 4107 XSETVECTOR (barobj, bar);
4108 fset_scroll_bars (f, barobj);
4109 if (! NILP (bar->next))
4110 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
4111 }
3908} 4112}
3909 4113
3910/* Remove all scroll bars on FRAME that haven't been saved since the 4114/* Remove all scroll bars on FRAME that haven't been saved since the
@@ -3935,8 +4139,9 @@ w32_judge_scroll_bars (struct frame *f)
3935 and they should get garbage-collected. */ 4139 and they should get garbage-collected. */
3936} 4140}
3937 4141
3938/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind 4142/* Handle a mouse click on the vertical scroll bar BAR. If
3939 is set to something other than NO_EVENT, it is enqueued. 4143 *EMACS_EVENT's kind is set to something other than NO_EVENT, it is
4144 enqueued.
3940 4145
3941 This may be called from a signal handler, so we have to ignore GC 4146 This may be called from a signal handler, so we have to ignore GC
3942 mark bits. */ 4147 mark bits. */
@@ -4043,9 +4248,120 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4043 } 4248 }
4044} 4249}
4045 4250
4046/* Return information to the user about the current position of the mouse 4251/* Handle a mouse click on the horizontal scroll bar BAR. If
4047 on the scroll bar. */ 4252 *EMACS_EVENT's kind is set to something other than NO_EVENT, it is
4253 enqueued.
4254
4255 This may be called from a signal handler, so we have to ignore GC
4256 mark bits. */
4048 4257
4258static int
4259w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4260 struct input_event *emacs_event)
4261{
4262 if (! WINDOWP (bar->window))
4263 emacs_abort ();
4264
4265 emacs_event->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
4266 emacs_event->code = 0;
4267 /* not really meaningful to distinguish left/right */
4268 emacs_event->modifiers = msg->dwModifiers;
4269 emacs_event->frame_or_window = bar->window;
4270 emacs_event->arg = Qnil;
4271 emacs_event->timestamp = msg->msg.time;
4272
4273 {
4274 int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
4275 int x;
4276 int dragging = bar->dragging;
4277 SCROLLINFO si;
4278
4279 si.cbSize = sizeof (si);
4280 si.fMask = SIF_POS;
4281
4282 GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
4283 x = si.nPos;
4284
4285 bar->dragging = 0;
4286 FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
4287
4288 switch (LOWORD (msg->msg.wParam))
4289 {
4290 case SB_LINELEFT:
4291 emacs_event->part = scroll_bar_left_arrow;
4292 break;
4293 case SB_LINERIGHT:
4294 emacs_event->part = scroll_bar_right_arrow;
4295 break;
4296 case SB_PAGELEFT:
4297 emacs_event->part = scroll_bar_before_handle;
4298 break;
4299 case SB_PAGERIGHT:
4300 emacs_event->part = scroll_bar_after_handle;
4301 break;
4302 case SB_LEFT:
4303 emacs_event->part = scroll_bar_horizontal_handle;
4304 x = 0;
4305 break;
4306 case SB_RIGHT:
4307 emacs_event->part = scroll_bar_horizontal_handle;
4308 x = left_range;
4309 break;
4310 case SB_THUMBTRACK:
4311 case SB_THUMBPOSITION:
4312 if (HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width) <= 0xffff)
4313 x = HIWORD (msg->msg.wParam);
4314 bar->dragging = 1;
4315 emacs_event->part = scroll_bar_horizontal_handle;
4316
4317 /* "Silently" update current position. */
4318 {
4319 SCROLLINFO si;
4320
4321 si.cbSize = sizeof (si);
4322 si.fMask = SIF_POS;
4323 si.nPos = min (x, XWINDOW (bar->window)->hscroll_whole - 1);
4324 /* Remember apparent position (we actually lag behind the real
4325 position, so don't set that directly). */
4326 last_scroll_bar_drag_pos = x;
4327
4328 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
4329 }
4330 break;
4331 case SB_ENDSCROLL:
4332 /* If this is the end of a drag sequence, then reset the scroll
4333 handle size to normal and do a final redraw. Otherwise do
4334 nothing. */
4335 if (dragging)
4336 {
4337 SCROLLINFO si;
4338 int start = bar->start;
4339 int end = bar->end;
4340
4341 si.cbSize = sizeof (si);
4342/** si.fMask = SIF_PAGE | SIF_POS; **/
4343 si.fMask = SIF_POS;
4344/** si.nPage = end - start + HORIZONTAL_SCROLL_BAR_MIN_HANDLE; **/
4345 si.nPos = min (last_scroll_bar_drag_pos,
4346 XWINDOW (bar->window)->hscroll_whole - 1);
4347/** si.nPos = last_scroll_bar_drag_pos; **/
4348 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
4349 }
4350 /* fall through */
4351 default:
4352 emacs_event->kind = NO_EVENT;
4353 return FALSE;
4354 }
4355
4356 XSETINT (emacs_event->x, x);
4357 XSETINT (emacs_event->y, left_range);
4358
4359 return TRUE;
4360 }
4361}
4362
4363/* Return information to the user about the current position of the mouse
4364 on the vertical scroll bar. */
4049static void 4365static void
4050x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, 4366x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4051 enum scroll_bar_part *part, 4367 enum scroll_bar_part *part,
@@ -4100,6 +4416,62 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4100 unblock_input (); 4416 unblock_input ();
4101} 4417}
4102 4418
4419/* Return information to the user about the current position of the mouse
4420 on the horizontal scroll bar. */
4421static void
4422x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4423 enum scroll_bar_part *part,
4424 Lisp_Object *x, Lisp_Object *y,
4425 unsigned long *time)
4426{
4427 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
4428 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
4429 Window w = SCROLL_BAR_W32_WINDOW (bar);
4430 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
4431 int pos;
4432 int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
4433 SCROLLINFO si;
4434
4435 block_input ();
4436
4437 *fp = f;
4438 *bar_window = bar->window;
4439
4440 si.cbSize = sizeof (si);
4441 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
4442
4443 GetScrollInfo (w, SB_CTL, &si);
4444 pos = si.nPos;
4445 left_range = si.nMax - si.nPage + 1;
4446
4447 switch (LOWORD (dpyinfo->last_mouse_scroll_bar_pos))
4448 {
4449 case SB_THUMBPOSITION:
4450 case SB_THUMBTRACK:
4451 *part = scroll_bar_handle;
4452 if (HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width) <= 0xffff)
4453 pos = HIWORD (dpyinfo->last_mouse_scroll_bar_pos);
4454 break;
4455 case SB_LINERIGHT:
4456 *part = scroll_bar_handle;
4457 pos++;
4458 break;
4459 default:
4460 *part = scroll_bar_handle;
4461 break;
4462 }
4463
4464 XSETINT (*y, pos);
4465 XSETINT (*x, left_range);
4466
4467 f->mouse_moved = 0;
4468 dpyinfo->last_mouse_scroll_bar = NULL;
4469
4470 *time = dpyinfo->last_mouse_movement_time;
4471
4472 unblock_input ();
4473}
4474
4103 4475
4104/* The screen has been cleared so we may have changed foreground or 4476/* The screen has been cleared so we may have changed foreground or
4105 background colors, and the scroll bars may need to be redrawn. 4477 background colors, and the scroll bars may need to be redrawn.
@@ -4114,7 +4486,8 @@ x_scroll_bar_clear (struct frame *f)
4114 /* We can have scroll bars even if this is 0, 4486 /* We can have scroll bars even if this is 0,
4115 if we just turned off scroll bar mode. 4487 if we just turned off scroll bar mode.
4116 But in that case we should not clear them. */ 4488 But in that case we should not clear them. */
4117 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) 4489 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
4490 || FRAME_HAS_HORIZONTAL_SCROLL_BARS (f))
4118 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar); 4491 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
4119 bar = XSCROLL_BAR (bar)->next) 4492 bar = XSCROLL_BAR (bar)->next)
4120 { 4493 {
@@ -4589,10 +4962,20 @@ w32_read_socket (struct terminal *terminal,
4589 construct_drag_n_drop (&inev, &msg, f); 4962 construct_drag_n_drop (&inev, &msg, f);
4590 break; 4963 break;
4591 4964
4965 case WM_HSCROLL:
4966 {
4967 struct scroll_bar *bar =
4968 x_window_to_scroll_bar ((HWND)msg.msg.lParam, 1);
4969
4970 if (bar)
4971 w32_horizontal_scroll_bar_handle_click (bar, &msg, &inev);
4972 break;
4973 }
4974
4592 case WM_VSCROLL: 4975 case WM_VSCROLL:
4593 { 4976 {
4594 struct scroll_bar *bar = 4977 struct scroll_bar *bar =
4595 x_window_to_scroll_bar ((HWND)msg.msg.lParam); 4978 x_window_to_scroll_bar ((HWND)msg.msg.lParam, 0);
4596 4979
4597 if (bar) 4980 if (bar)
4598 w32_scroll_bar_handle_click (bar, &msg, &inev); 4981 w32_scroll_bar_handle_click (bar, &msg, &inev);
@@ -4787,10 +5170,6 @@ w32_read_socket (struct terminal *terminal,
4787 change_frame_size (f, text_width, text_height, 0, 1, 0, 1); 5170 change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
4788 SET_FRAME_GARBAGED (f); 5171 SET_FRAME_GARBAGED (f);
4789 cancel_mouse_face (f); 5172 cancel_mouse_face (f);
4790 /* Do we want to set these here ???? */
4791/** FRAME_PIXEL_WIDTH (f) = width; **/
4792/** FRAME_TEXT_WIDTH (f) = text_width; **/
4793/** FRAME_PIXEL_HEIGHT (f) = height; **/
4794 f->win_gravity = NorthWestGravity; 5173 f->win_gravity = NorthWestGravity;
4795 } 5174 }
4796 } 5175 }
@@ -5430,8 +5809,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
5430 FRAME_COLUMN_WIDTH (f) = unit = font->average_width; 5809 FRAME_COLUMN_WIDTH (f) = unit = font->average_width;
5431 FRAME_LINE_HEIGHT (f) = font->height; 5810 FRAME_LINE_HEIGHT (f) = font->height;
5432 5811
5433 compute_fringe_widths (f, 1);
5434
5435 /* Compute number of scrollbar columns. */ 5812 /* Compute number of scrollbar columns. */
5436 unit = FRAME_COLUMN_WIDTH (f); 5813 unit = FRAME_COLUMN_WIDTH (f);
5437 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0) 5814 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
@@ -5451,8 +5828,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
5451 doing it because it's done in Fx_show_tip, and it leads to 5828 doing it because it's done in Fx_show_tip, and it leads to
5452 problems because the tip frame has no widget. */ 5829 problems because the tip frame has no widget. */
5453 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 5830 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
5454 x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 5831 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
5455 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1); 5832 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 0);
5456 } 5833 }
5457 5834
5458 /* X version sets font of input methods here also. */ 5835 /* X version sets font of input methods here also. */
@@ -5649,6 +6026,7 @@ w32fullscreen_hook (struct frame *f)
5649 HWND hwnd = FRAME_W32_WINDOW(f); 6026 HWND hwnd = FRAME_W32_WINDOW(f);
5650 DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE); 6027 DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
5651 RECT rect; 6028 RECT rect;
6029 enum fullscreen_type prev_fsmode = FRAME_PREV_FSMODE (f);
5652 6030
5653 block_input(); 6031 block_input();
5654 f->want_fullscreen &= ~FULLSCREEN_WAIT; 6032 f->want_fullscreen &= ~FULLSCREEN_WAIT;
@@ -5670,7 +6048,14 @@ w32fullscreen_hook (struct frame *f)
5670 if (f->want_fullscreen == FULLSCREEN_NONE) 6048 if (f->want_fullscreen == FULLSCREEN_NONE)
5671 ShowWindow (hwnd, SW_SHOWNORMAL); 6049 ShowWindow (hwnd, SW_SHOWNORMAL);
5672 else if (f->want_fullscreen == FULLSCREEN_MAXIMIZED) 6050 else if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
5673 ShowWindow (hwnd, SW_MAXIMIZE); 6051 {
6052 if (prev_fsmode == FULLSCREEN_BOTH || prev_fsmode == FULLSCREEN_WIDTH
6053 || prev_fsmode == FULLSCREEN_HEIGHT)
6054 /* Make window normal since otherwise the subsequent
6055 maximization might fail in some cases. */
6056 ShowWindow (hwnd, SW_SHOWNORMAL);
6057 ShowWindow (hwnd, SW_MAXIMIZE);
6058 }
5674 else if (f->want_fullscreen == FULLSCREEN_BOTH) 6059 else if (f->want_fullscreen == FULLSCREEN_BOTH)
5675 { 6060 {
5676 w32_fullscreen_rect (hwnd, f->want_fullscreen, 6061 w32_fullscreen_rect (hwnd, f->want_fullscreen,
@@ -5705,70 +6090,40 @@ void
5705x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise) 6090x_set_window_size (struct frame *f, int change_gravity, int width, int height, bool pixelwise)
5706{ 6091{
5707 int pixelwidth, pixelheight; 6092 int pixelwidth, pixelheight;
6093 RECT rect;
5708 6094
5709 block_input (); 6095 block_input ();
5710 6096
5711 check_frame_size (f, &width, &height, pixelwise); 6097 if (pixelwise)
5712
5713 compute_fringe_widths (f, 0);
5714
5715 if (frame_resize_pixelwise)
5716 { 6098 {
5717 if (pixelwise) 6099 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
5718 { 6100 pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
5719 pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
5720 pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
5721 }
5722 else
5723 {
5724 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
5725 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
5726 }
5727 } 6101 }
5728 else 6102 else
5729 { 6103 {
5730 /* If we don't resize frames pixelwise, round sizes to multiples 6104 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
5731 of character sizes here. Otherwise, when enforcing size hints 6105 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
5732 while processing WM_WINDOWPOSCHANGING in w32_wnd_proc, we might
5733 clip our frame rectangle to a multiple of the frame's character
5734 size and subsequently lose our mode line or scroll bar.
5735 Bug#16923 could be one possible consequence of this. Carefully
5736 reverse-engineer what WM_WINDOWPOSCHANGING does here since
5737 otherwise we might make our frame too small, see Bug#17077. */
5738 int unit_width = FRAME_COLUMN_WIDTH (f);
5739 int unit_height = FRAME_LINE_HEIGHT (f);
5740
5741 pixelwidth = (((((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f)))
5742 + FRAME_TOTAL_FRINGE_WIDTH (f))
5743 / unit_width) * unit_width)
5744 + FRAME_SCROLL_BAR_AREA_WIDTH (f)
5745 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
5746
5747 pixelheight = ((((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f)))
5748 / unit_height) * unit_height)
5749 + 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
5750 } 6106 }
5751 6107
5752 f->win_gravity = NorthWestGravity; 6108 f->win_gravity = NorthWestGravity;
5753 x_wm_set_size_hint (f, (long) 0, 0); 6109 x_wm_set_size_hint (f, (long) 0, 0);
5754 6110
5755 { 6111 f->want_fullscreen = FULLSCREEN_NONE;
5756 RECT rect; 6112 w32fullscreen_hook (f);
5757 6113
5758 rect.left = rect.top = 0; 6114 rect.left = rect.top = 0;
5759 rect.right = pixelwidth; 6115 rect.right = pixelwidth;
5760 rect.bottom = pixelheight; 6116 rect.bottom = pixelheight;
5761 6117
5762 AdjustWindowRect (&rect, f->output_data.w32->dwStyle, 6118 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
5763 FRAME_EXTERNAL_MENU_BAR (f)); 6119 FRAME_EXTERNAL_MENU_BAR (f));
5764 6120
5765 my_set_window_pos (FRAME_W32_WINDOW (f), 6121 my_set_window_pos (FRAME_W32_WINDOW (f),
5766 NULL, 6122 NULL,
5767 0, 0, 6123 0, 0,
5768 rect.right - rect.left, 6124 rect.right - rect.left,
5769 rect.bottom - rect.top, 6125 rect.bottom - rect.top,
5770 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); 6126 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
5771 }
5772 6127
5773 /* If w32_enable_frame_resize_hack is non-nil, immediately apply the 6128 /* If w32_enable_frame_resize_hack is non-nil, immediately apply the
5774 new pixel sizes to the frame and its subwindows. 6129 new pixel sizes to the frame and its subwindows.
@@ -5817,6 +6172,8 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
5817 } 6172 }
5818 6173
5819 unblock_input (); 6174 unblock_input ();
6175
6176 do_pending_window_change (0);
5820} 6177}
5821 6178
5822/* Mouse warping. */ 6179/* Mouse warping. */
@@ -6156,7 +6513,8 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
6156 SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); 6513 SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
6157 SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); 6514 SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
6158 SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); 6515 SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
6159 SetWindowLong (window, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f)); 6516 SetWindowLong (window, WND_VSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
6517 SetWindowLong (window, WND_HSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_HEIGHT (f));
6160 6518
6161 leave_crit (); 6519 leave_crit ();
6162} 6520}
@@ -6243,6 +6601,7 @@ w32_initialize_display_info (Lisp_Object display_name)
6243 dpyinfo->smallest_font_height = 1; 6601 dpyinfo->smallest_font_height = 1;
6244 dpyinfo->smallest_char_width = 1; 6602 dpyinfo->smallest_char_width = 1;
6245 dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW); 6603 dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
6604 dpyinfo->horizontal_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
6246 /* TODO: dpyinfo->gray */ 6605 /* TODO: dpyinfo->gray */
6247 6606
6248 reset_mouse_highlight (&dpyinfo->mouse_highlight); 6607 reset_mouse_highlight (&dpyinfo->mouse_highlight);
@@ -6363,6 +6722,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
6363 terminal->menu_show_hook = w32_menu_show; 6722 terminal->menu_show_hook = w32_menu_show;
6364 terminal->popup_dialog_hook = w32_popup_dialog; 6723 terminal->popup_dialog_hook = w32_popup_dialog;
6365 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar; 6724 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
6725 terminal->set_horizontal_scroll_bar_hook = w32_set_horizontal_scroll_bar;
6366 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars; 6726 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
6367 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar; 6727 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
6368 terminal->judge_scroll_bars_hook = w32_judge_scroll_bars; 6728 terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
@@ -6595,13 +6955,16 @@ w32_initialize (void)
6595 6955
6596#undef LOAD_PROC 6956#undef LOAD_PROC
6597 6957
6598 /* Ensure scrollbar handle is at least 5 pixels. */ 6958 /* Ensure scrollbar handles are at least 5 pixels. */
6599 vertical_scroll_bar_min_handle = 5; 6959 vertical_scroll_bar_min_handle = 5;
6960 horizontal_scroll_bar_min_handle = 5;
6600 6961
6601 /* For either kind of scroll bar, take account of the arrows; these 6962 /* For either kind of scroll bar, take account of the arrows; these
6602 effectively form the border of the main scroll bar range. */ 6963 effectively form the border of the main scroll bar range. */
6603 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border 6964 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
6604 = GetSystemMetrics (SM_CYVSCROLL); 6965 = GetSystemMetrics (SM_CYVSCROLL);
6966 horizontal_scroll_bar_left_border = horizontal_scroll_bar_right_border
6967 = GetSystemMetrics (SM_CYHSCROLL);
6605 } 6968 }
6606} 6969}
6607 6970
diff --git a/src/w32term.h b/src/w32term.h
index ae666925833..0fabe12819c 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -99,6 +99,9 @@ struct w32_display_info
99 /* The cursor to use for vertical scroll bars. */ 99 /* The cursor to use for vertical scroll bars. */
100 Cursor vertical_scroll_bar_cursor; 100 Cursor vertical_scroll_bar_cursor;
101 101
102 /* The cursor to use for horizontal scroll bars. */
103 Cursor horizontal_scroll_bar_cursor;
104
102 /* Resource data base */ 105 /* Resource data base */
103 XrmDatabase xrdb; 106 XrmDatabase xrdb;
104 107
@@ -194,6 +197,9 @@ struct w32_display_info
194 197
195 /* Time of last mouse movement. */ 198 /* Time of last mouse movement. */
196 Time last_mouse_movement_time; 199 Time last_mouse_movement_time;
200
201 /* Value returned by last call of ShowCursor. */
202 int cursor_display_counter;
197}; 203};
198 204
199/* This is a chain of structures for all the displays currently in use. */ 205/* This is a chain of structures for all the displays currently in use. */
@@ -231,6 +237,9 @@ extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
231extern void x_set_tool_bar_lines (struct frame *f, 237extern void x_set_tool_bar_lines (struct frame *f,
232 Lisp_Object value, 238 Lisp_Object value,
233 Lisp_Object oldval); 239 Lisp_Object oldval);
240extern void x_set_internal_border_width (struct frame *f,
241 Lisp_Object value,
242 Lisp_Object oldval);
234extern void x_activate_menubar (struct frame *); 243extern void x_activate_menubar (struct frame *);
235extern int x_bitmap_icon (struct frame *, Lisp_Object); 244extern int x_bitmap_icon (struct frame *, Lisp_Object);
236extern void initialize_frame_menubar (struct frame *); 245extern void initialize_frame_menubar (struct frame *);
@@ -451,6 +460,9 @@ struct scroll_bar {
451 place where the user grabbed it. If the handle isn't currently 460 place where the user grabbed it. If the handle isn't currently
452 being dragged, this is Qnil. */ 461 being dragged, this is Qnil. */
453 int dragging; 462 int dragging;
463
464 /* true if the scroll bar is horizontal. */
465 bool horizontal;
454}; 466};
455 467
456/* Turning a lisp vector value into a pointer to a struct scroll_bar. */ 468/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
@@ -484,9 +496,9 @@ struct scroll_bar {
484 496
485/* Return the inside width of a vertical scroll bar, given the outside 497/* Return the inside width of a vertical scroll bar, given the outside
486 width. */ 498 width. */
487#define VERTICAL_SCROLL_BAR_INSIDE_WIDTH(f,width) \ 499#define VERTICAL_SCROLL_BAR_INSIDE_WIDTH(f,width) \
488 ((width) \ 500 ((width) \
489 - VERTICAL_SCROLL_BAR_LEFT_BORDER \ 501 - VERTICAL_SCROLL_BAR_LEFT_BORDER \
490 - VERTICAL_SCROLL_BAR_RIGHT_BORDER) 502 - VERTICAL_SCROLL_BAR_RIGHT_BORDER)
491 503
492/* Return the length of the rectangle within which the top of the 504/* Return the length of the rectangle within which the top of the
@@ -496,14 +508,36 @@ struct scroll_bar {
496 This is the real range of motion for the scroll bar, so when we're 508 This is the real range of motion for the scroll bar, so when we're
497 scaling buffer positions to scroll bar positions, we use this, not 509 scaling buffer positions to scroll bar positions, we use this, not
498 VERTICAL_SCROLL_BAR_INSIDE_HEIGHT. */ 510 VERTICAL_SCROLL_BAR_INSIDE_HEIGHT. */
499#define VERTICAL_SCROLL_BAR_TOP_RANGE(f,height) \ 511#define VERTICAL_SCROLL_BAR_TOP_RANGE(f,height) \
500 (VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, height) - VERTICAL_SCROLL_BAR_MIN_HANDLE) 512 (VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, height) - VERTICAL_SCROLL_BAR_MIN_HANDLE)
501 513
502/* Return the inside height of vertical scroll bar, given the outside 514/* Return the inside height of vertical scroll bar, given the outside
503 height. See VERTICAL_SCROLL_BAR_TOP_RANGE too. */ 515 height. See VERTICAL_SCROLL_BAR_TOP_RANGE too. */
504#define VERTICAL_SCROLL_BAR_INSIDE_HEIGHT(f,height) \ 516#define VERTICAL_SCROLL_BAR_INSIDE_HEIGHT(f,height) \
505 ((height) - VERTICAL_SCROLL_BAR_TOP_BORDER - VERTICAL_SCROLL_BAR_BOTTOM_BORDER) 517 ((height) - VERTICAL_SCROLL_BAR_TOP_BORDER - VERTICAL_SCROLL_BAR_BOTTOM_BORDER)
506 518
519/* Return the inside height of a horizontal scroll bar, given the
520 outside height. */
521#define HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT(f,height) \
522 ((height) \
523 - HORIZONTAL_SCROLL_BAR_TOP_BORDER \
524 - HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
525
526/* Return the length of the rectangle within which the left of the
527 handle must stay. This isn't equivalent to the inside width,
528 because the scroll bar handle has a minimum width.
529
530 This is the real range of motion for the scroll bar, so when we're
531 scaling buffer positions to scroll bar positions, we use this, not
532 HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH. */
533#define HORIZONTAL_SCROLL_BAR_LEFT_RANGE(f,width) \
534 (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH (f, width) - HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
535
536/* Return the inside width of horizontal scroll bar, given the outside
537 width. See HORIZONTAL_SCROLL_BAR_LEFT_RANGE too. */
538#define HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH(f,width) \
539 ((width) - HORIZONTAL_SCROLL_BAR_LEFT_BORDER - HORIZONTAL_SCROLL_BAR_RIGHT_BORDER)
540
507 541
508/* Border widths for scroll bars. 542/* Border widths for scroll bars.
509 543
@@ -521,8 +555,14 @@ struct scroll_bar {
521#define VERTICAL_SCROLL_BAR_TOP_BORDER (vertical_scroll_bar_top_border) 555#define VERTICAL_SCROLL_BAR_TOP_BORDER (vertical_scroll_bar_top_border)
522#define VERTICAL_SCROLL_BAR_BOTTOM_BORDER (vertical_scroll_bar_bottom_border) 556#define VERTICAL_SCROLL_BAR_BOTTOM_BORDER (vertical_scroll_bar_bottom_border)
523 557
558#define HORIZONTAL_SCROLL_BAR_LEFT_BORDER (horizontal_scroll_bar_left_border)
559#define HORIZONTAL_SCROLL_BAR_RIGHT_BORDER (horizontal_scroll_bar_right_border)
560#define HORIZONTAL_SCROLL_BAR_TOP_BORDER (0)
561#define HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER (0)
562
524/* Minimum lengths for scroll bar handles, in pixels. */ 563/* Minimum lengths for scroll bar handles, in pixels. */
525#define VERTICAL_SCROLL_BAR_MIN_HANDLE (vertical_scroll_bar_min_handle) 564#define VERTICAL_SCROLL_BAR_MIN_HANDLE (vertical_scroll_bar_min_handle)
565#define HORIZONTAL_SCROLL_BAR_MIN_HANDLE (horizontal_scroll_bar_min_handle)
526 566
527struct frame; /* from frame.h */ 567struct frame; /* from frame.h */
528 568
@@ -584,35 +624,38 @@ do { \
584#define WM_EMACS_KILL (WM_EMACS_START + 0) 624#define WM_EMACS_KILL (WM_EMACS_START + 0)
585#define WM_EMACS_CREATEWINDOW (WM_EMACS_START + 1) 625#define WM_EMACS_CREATEWINDOW (WM_EMACS_START + 1)
586#define WM_EMACS_DONE (WM_EMACS_START + 2) 626#define WM_EMACS_DONE (WM_EMACS_START + 2)
587#define WM_EMACS_CREATESCROLLBAR (WM_EMACS_START + 3) 627#define WM_EMACS_CREATEVSCROLLBAR (WM_EMACS_START + 3)
588#define WM_EMACS_SHOWWINDOW (WM_EMACS_START + 4) 628#define WM_EMACS_CREATEHSCROLLBAR (WM_EMACS_START + 4)
589#define WM_EMACS_SETWINDOWPOS (WM_EMACS_START + 5) 629#define WM_EMACS_SHOWWINDOW (WM_EMACS_START + 5)
590#define WM_EMACS_DESTROYWINDOW (WM_EMACS_START + 6) 630#define WM_EMACS_SETWINDOWPOS (WM_EMACS_START + 6)
591#define WM_EMACS_TRACKPOPUPMENU (WM_EMACS_START + 7) 631#define WM_EMACS_DESTROYWINDOW (WM_EMACS_START + 7)
592#define WM_EMACS_SETFOCUS (WM_EMACS_START + 8) 632#define WM_EMACS_TRACKPOPUPMENU (WM_EMACS_START + 8)
593#define WM_EMACS_SETFOREGROUND (WM_EMACS_START + 9) 633#define WM_EMACS_SETFOCUS (WM_EMACS_START + 9)
594#define WM_EMACS_SETLOCALE (WM_EMACS_START + 10) 634#define WM_EMACS_SETFOREGROUND (WM_EMACS_START + 10)
595#define WM_EMACS_SETKEYBOARDLAYOUT (WM_EMACS_START + 11) 635#define WM_EMACS_SETLOCALE (WM_EMACS_START + 11)
596#define WM_EMACS_REGISTER_HOT_KEY (WM_EMACS_START + 12) 636#define WM_EMACS_SETKEYBOARDLAYOUT (WM_EMACS_START + 12)
597#define WM_EMACS_UNREGISTER_HOT_KEY (WM_EMACS_START + 13) 637#define WM_EMACS_REGISTER_HOT_KEY (WM_EMACS_START + 13)
598#define WM_EMACS_TOGGLE_LOCK_KEY (WM_EMACS_START + 14) 638#define WM_EMACS_UNREGISTER_HOT_KEY (WM_EMACS_START + 14)
599#define WM_EMACS_TRACK_CARET (WM_EMACS_START + 15) 639#define WM_EMACS_TOGGLE_LOCK_KEY (WM_EMACS_START + 15)
600#define WM_EMACS_DESTROY_CARET (WM_EMACS_START + 16) 640#define WM_EMACS_TRACK_CARET (WM_EMACS_START + 16)
601#define WM_EMACS_SHOW_CARET (WM_EMACS_START + 17) 641#define WM_EMACS_DESTROY_CARET (WM_EMACS_START + 17)
602#define WM_EMACS_HIDE_CARET (WM_EMACS_START + 18) 642#define WM_EMACS_SHOW_CARET (WM_EMACS_START + 18)
603#define WM_EMACS_SETCURSOR (WM_EMACS_START + 19) 643#define WM_EMACS_HIDE_CARET (WM_EMACS_START + 19)
604#define WM_EMACS_PAINT (WM_EMACS_START + 20) 644#define WM_EMACS_SETCURSOR (WM_EMACS_START + 20)
605#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 21) 645#define WM_EMACS_SHOWCURSOR (WM_EMACS_START + 21)
606#define WM_EMACS_INPUT_READY (WM_EMACS_START + 22) 646#define WM_EMACS_PAINT (WM_EMACS_START + 22)
607#define WM_EMACS_FILENOTIFY (WM_EMACS_START + 23) 647#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 23)
608#define WM_EMACS_END (WM_EMACS_START + 24) 648#define WM_EMACS_INPUT_READY (WM_EMACS_START + 24)
649#define WM_EMACS_FILENOTIFY (WM_EMACS_START + 25)
650#define WM_EMACS_END (WM_EMACS_START + 26)
609 651
610#define WND_FONTWIDTH_INDEX (0) 652#define WND_FONTWIDTH_INDEX (0)
611#define WND_LINEHEIGHT_INDEX (4) 653#define WND_LINEHEIGHT_INDEX (4)
612#define WND_BORDER_INDEX (8) 654#define WND_BORDER_INDEX (8)
613#define WND_SCROLLBAR_INDEX (12) 655#define WND_VSCROLLBAR_INDEX (12)
614#define WND_BACKGROUND_INDEX (16) 656#define WND_HSCROLLBAR_INDEX (16)
615#define WND_LAST_INDEX (20) 657#define WND_BACKGROUND_INDEX (20)
658#define WND_LAST_INDEX (24)
616 659
617#define WND_EXTRA_BYTES (WND_LAST_INDEX) 660#define WND_EXTRA_BYTES (WND_LAST_INDEX)
618 661
diff --git a/src/widget.c b/src/widget.c
index bd0fe826e68..45118a88730 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -404,7 +404,6 @@ set_frame_size (EmacsFrame ew)
404 } 404 }
405#endif /* 0 */ 405#endif /* 0 */
406 { 406 {
407 struct frame *f = ew->emacs_frame.frame;
408 Dimension pixel_width, pixel_height; 407 Dimension pixel_width, pixel_height;
409 408
410 /* Take into account the size of the scrollbar. Always use the 409 /* Take into account the size of the scrollbar. Always use the
@@ -413,8 +412,6 @@ set_frame_size (EmacsFrame ew)
413 frame's character width which is bad for vertically split 412 frame's character width which is bad for vertically split
414 windows. */ 413 windows. */
415 414
416 compute_fringe_widths (f, 0);
417
418#if 0 /* This can run Lisp code, and it is dangerous to give 415#if 0 /* This can run Lisp code, and it is dangerous to give
419 out the frame to Lisp code before it officially exists. 416 out the frame to Lisp code before it officially exists.
420 This is handled in Fx_create_frame so not needed here. */ 417 This is handled in Fx_create_frame so not needed here. */
@@ -472,10 +469,6 @@ update_wm_hints (EmacsFrame ew)
472 /* This happens when the frame is just created. */ 469 /* This happens when the frame is just created. */
473 if (! wmshell) return; 470 if (! wmshell) return;
474 471
475#if 0
476 check_frame_size (ew->emacs_frame.frame, &min_cols, &min_rows, 0);
477#endif
478
479 pixel_to_char_size (ew, ew->core.width, ew->core.height, 472 pixel_to_char_size (ew, ew->core.width, ew->core.height,
480 &char_width, &char_height); 473 &char_width, &char_height);
481 char_to_pixel_size (ew, char_width, char_height, 474 char_to_pixel_size (ew, char_width, char_height,
@@ -690,6 +683,15 @@ EmacsFrameResize (Widget widget)
690 if (true || frame_resize_pixelwise) 683 if (true || frame_resize_pixelwise)
691 { 684 {
692 int width, height; 685 int width, height;
686/** int width = (ew->core.width **/
687/** - FRAME_SCROLL_BAR_AREA_WIDTH (f) **/
688/** - FRAME_TOTAL_FRINGE_WIDTH (f) **/
689/** - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
690
691/** int height = (ew->core.height **/
692/** - FRAME_TOOLBAR_HEIGHT (f) **/
693/** - FRAME_SCROLL_BAR_AREA_HEIGHT (f) **/
694/** - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
693 695
694 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height); 696 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
695 change_frame_size (f, width, height, 0, 1, 0, 1); 697 change_frame_size (f, width, height, 0, 1, 0, 1);
@@ -829,7 +831,8 @@ EmacsFrameSetCharSize (Widget widget, int columns, int rows)
829 EmacsFrame ew = (EmacsFrame) widget; 831 EmacsFrame ew = (EmacsFrame) widget;
830 struct frame *f = ew->emacs_frame.frame; 832 struct frame *f = ew->emacs_frame.frame;
831 833
832 x_set_window_size (f, 0, columns, rows, 0); 834 if (!frame_inhibit_resize (f, 0) && !frame_inhibit_resize (f, 1))
835 x_set_window_size (f, 0, columns, rows, 0);
833} 836}
834 837
835 838
diff --git a/src/window.c b/src/window.c
index 6afe7454149..ae28b714720 100644
--- a/src/window.c
+++ b/src/window.c
@@ -52,6 +52,7 @@ static Lisp_Object Qrecord_window_buffer;
52static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 52static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
53static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 53static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
54static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; 54static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
55static Lisp_Object Qwindow_sanitize_window_sizes;
55static Lisp_Object Qwindow_pixel_to_total; 56static Lisp_Object Qwindow_pixel_to_total;
56static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 57static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
57static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; 58static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
@@ -87,7 +88,7 @@ static struct window *set_window_fringes (struct window *, Lisp_Object,
87static struct window *set_window_margins (struct window *, Lisp_Object, 88static struct window *set_window_margins (struct window *, Lisp_Object,
88 Lisp_Object); 89 Lisp_Object);
89static struct window *set_window_scroll_bars (struct window *, Lisp_Object, 90static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
90 Lisp_Object, Lisp_Object); 91 Lisp_Object, Lisp_Object, Lisp_Object);
91static void apply_window_adjustment (struct window *); 92static void apply_window_adjustment (struct window *);
92 93
93/* This is the window in which the terminal's cursor should 94/* This is the window in which the terminal's cursor should
@@ -143,66 +144,85 @@ wset_combination_limit (struct window *w, Lisp_Object val)
143{ 144{
144 w->combination_limit = val; 145 w->combination_limit = val;
145} 146}
147
146static void 148static void
147wset_dedicated (struct window *w, Lisp_Object val) 149wset_dedicated (struct window *w, Lisp_Object val)
148{ 150{
149 w->dedicated = val; 151 w->dedicated = val;
150} 152}
153
151static void 154static void
152wset_display_table (struct window *w, Lisp_Object val) 155wset_display_table (struct window *w, Lisp_Object val)
153{ 156{
154 w->display_table = val; 157 w->display_table = val;
155} 158}
159
156static void 160static void
157wset_new_normal (struct window *w, Lisp_Object val) 161wset_new_normal (struct window *w, Lisp_Object val)
158{ 162{
159 w->new_normal = val; 163 w->new_normal = val;
160} 164}
165
161static void 166static void
162wset_new_total (struct window *w, Lisp_Object val) 167wset_new_total (struct window *w, Lisp_Object val)
163{ 168{
164 w->new_total = val; 169 w->new_total = val;
165} 170}
171
166static void 172static void
167wset_normal_cols (struct window *w, Lisp_Object val) 173wset_normal_cols (struct window *w, Lisp_Object val)
168{ 174{
169 w->normal_cols = val; 175 w->normal_cols = val;
170} 176}
177
171static void 178static void
172wset_normal_lines (struct window *w, Lisp_Object val) 179wset_normal_lines (struct window *w, Lisp_Object val)
173{ 180{
174 w->normal_lines = val; 181 w->normal_lines = val;
175} 182}
183
176static void 184static void
177wset_parent (struct window *w, Lisp_Object val) 185wset_parent (struct window *w, Lisp_Object val)
178{ 186{
179 w->parent = val; 187 w->parent = val;
180} 188}
189
181static void 190static void
182wset_pointm (struct window *w, Lisp_Object val) 191wset_pointm (struct window *w, Lisp_Object val)
183{ 192{
184 w->pointm = val; 193 w->pointm = val;
185} 194}
195
196static void
197wset_old_pointm (struct window *w, Lisp_Object val)
198{
199 w->old_pointm = val;
200}
201
186static void 202static void
187wset_start (struct window *w, Lisp_Object val) 203wset_start (struct window *w, Lisp_Object val)
188{ 204{
189 w->start = val; 205 w->start = val;
190} 206}
207
191static void 208static void
192wset_temslot (struct window *w, Lisp_Object val) 209wset_temslot (struct window *w, Lisp_Object val)
193{ 210{
194 w->temslot = val; 211 w->temslot = val;
195} 212}
213
196static void 214static void
197wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val) 215wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
198{ 216{
199 w->vertical_scroll_bar_type = val; 217 w->vertical_scroll_bar_type = val;
200} 218}
219
201static void 220static void
202wset_window_parameters (struct window *w, Lisp_Object val) 221wset_window_parameters (struct window *w, Lisp_Object val)
203{ 222{
204 w->window_parameters = val; 223 w->window_parameters = val;
205} 224}
225
206static void 226static void
207wset_combination (struct window *w, bool horflag, Lisp_Object val) 227wset_combination (struct window *w, bool horflag, Lisp_Object val)
208{ 228{
@@ -871,6 +891,9 @@ window_body_height (struct window *w, bool pixelwise)
871{ 891{
872 int height = (w->pixel_height 892 int height = (w->pixel_height
873 - WINDOW_HEADER_LINE_HEIGHT (w) 893 - WINDOW_HEADER_LINE_HEIGHT (w)
894 - (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
895 ? WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
896 : 0)
874 - WINDOW_MODE_LINE_HEIGHT (w) 897 - WINDOW_MODE_LINE_HEIGHT (w)
875 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)); 898 - WINDOW_BOTTOM_DIVIDER_WIDTH (w));
876 899
@@ -991,6 +1014,15 @@ WINDOW must be a live window and defaults to the selected one. */)
991 return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window)))); 1014 return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window))));
992} 1015}
993 1016
1017DEFUN ("window-scroll-bar-height", Fwindow_scroll_bar_height,
1018 Swindow_scroll_bar_height, 0, 1, 0,
1019 doc: /* Return the height in pixels of WINDOW's horizontal scrollbar.
1020WINDOW must be a live window and defaults to the selected one. */)
1021 (Lisp_Object window)
1022{
1023 return (make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (decode_live_window (window))));
1024}
1025
994DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 1026DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
995 doc: /* Return the number of columns by which WINDOW is scrolled from left margin. 1027 doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
996WINDOW must be a live window and defaults to the selected one. */) 1028WINDOW must be a live window and defaults to the selected one. */)
@@ -1018,6 +1050,8 @@ set_window_hscroll (struct window *w, EMACS_INT hscroll)
1018 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1; 1050 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
1019 1051
1020 w->hscroll = new_hscroll; 1052 w->hscroll = new_hscroll;
1053 w->suspend_auto_hscroll = 1;
1054
1021 return make_number (new_hscroll); 1055 return make_number (new_hscroll);
1022} 1056}
1023 1057
@@ -1167,12 +1201,16 @@ display margins, fringes, header line, and/or mode line. */)
1167 1201
1168 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w) 1202 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
1169 + WINDOW_LEFT_MARGIN_COLS (w) 1203 + WINDOW_LEFT_MARGIN_COLS (w)
1170 + WINDOW_LEFT_FRINGE_COLS (w)), 1204 + ((WINDOW_LEFT_FRINGE_WIDTH (w)
1205 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
1206 / WINDOW_FRAME_COLUMN_WIDTH (w))),
1171 (WINDOW_TOP_EDGE_LINE (w) 1207 (WINDOW_TOP_EDGE_LINE (w)
1172 + WINDOW_HEADER_LINE_LINES (w)), 1208 + WINDOW_HEADER_LINE_LINES (w)),
1173 (WINDOW_BOX_RIGHT_EDGE_COL (w) 1209 (WINDOW_BOX_RIGHT_EDGE_COL (w)
1174 - WINDOW_RIGHT_MARGIN_COLS (w) 1210 - WINDOW_RIGHT_MARGIN_COLS (w)
1175 - WINDOW_RIGHT_FRINGE_COLS (w)), 1211 - ((WINDOW_RIGHT_FRINGE_WIDTH (w)
1212 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
1213 / WINDOW_FRAME_COLUMN_WIDTH (w))),
1176 (WINDOW_BOTTOM_EDGE_LINE (w) 1214 (WINDOW_BOTTOM_EDGE_LINE (w)
1177 - WINDOW_MODE_LINE_LINES (w))); 1215 - WINDOW_MODE_LINE_LINES (w)));
1178} 1216}
@@ -1286,6 +1324,17 @@ coordinates_in_window (register struct window *w, int x, int y)
1286 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w) 1324 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1287 && x <= right_x) 1325 && x <= right_x)
1288 return ON_RIGHT_DIVIDER; 1326 return ON_RIGHT_DIVIDER;
1327 /* On the horizontal scroll bar? (Including the empty space at its
1328 right!) */
1329 else if ((WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
1330 && y >= (bottom_y
1331 - WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
1332 - CURRENT_MODE_LINE_HEIGHT (w)
1333 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1334 && y <= (bottom_y
1335 - CURRENT_MODE_LINE_HEIGHT (w)
1336 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))))
1337 return ON_HORIZONTAL_SCROLL_BAR;
1289 /* On the mode or header line? */ 1338 /* On the mode or header line? */
1290 else if ((WINDOW_WANTS_MODELINE_P (w) 1339 else if ((WINDOW_WANTS_MODELINE_P (w)
1291 && y >= (bottom_y 1340 && y >= (bottom_y
@@ -1329,7 +1378,7 @@ coordinates_in_window (register struct window *w, int x, int y)
1329 1378
1330 /* Outside any interesting column? */ 1379 /* Outside any interesting column? */
1331 if (x < left_x || x > right_x) 1380 if (x < left_x || x > right_x)
1332 return ON_SCROLL_BAR; 1381 return ON_VERTICAL_SCROLL_BAR;
1333 1382
1334 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA); 1383 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
1335 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA); 1384 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
@@ -1493,10 +1542,13 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1493 case ON_RIGHT_MARGIN: 1542 case ON_RIGHT_MARGIN:
1494 return Qright_margin; 1543 return Qright_margin;
1495 1544
1496 case ON_SCROLL_BAR: 1545 case ON_VERTICAL_SCROLL_BAR:
1497 /* Historically we are supposed to return nil in this case. */ 1546 /* Historically we are supposed to return nil in this case. */
1498 return Qnil; 1547 return Qnil;
1499 1548
1549 case ON_HORIZONTAL_SCROLL_BAR:
1550 return Qnil;
1551
1500 case ON_RIGHT_DIVIDER: 1552 case ON_RIGHT_DIVIDER:
1501 return Qright_divider; 1553 return Qright_divider;
1502 1554
@@ -1637,6 +1689,14 @@ correct to return the top-level value of `point', outside of any
1637 return Fmarker_position (w->pointm); 1689 return Fmarker_position (w->pointm);
1638} 1690}
1639 1691
1692DEFUN ("window-old-point", Fwindow_old_point, Swindow_old_point, 0, 1, 0,
1693 doc: /* Return old value of point in WINDOW.
1694WINDOW must be a live window and defaults to the selected one. */)
1695 (Lisp_Object window)
1696{
1697 return Fmarker_position (decode_live_window (window)->old_pointm);
1698}
1699
1640DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0, 1700DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
1641 doc: /* Return position at which display currently starts in WINDOW. 1701 doc: /* Return position at which display currently starts in WINDOW.
1642WINDOW must be a live window and defaults to the selected one. 1702WINDOW must be a live window and defaults to the selected one.
@@ -2915,6 +2975,7 @@ selected frame and no others. */)
2915 return Qnil; 2975 return Qnil;
2916} 2976}
2917 2977
2978
2918static Lisp_Object 2979static Lisp_Object
2919resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise) 2980resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise)
2920{ 2981{
@@ -2922,10 +2983,17 @@ resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizonta
2922} 2983}
2923 2984
2924 2985
2986Lisp_Object
2987sanitize_window_sizes (Lisp_Object frame, Lisp_Object horizontal)
2988{
2989 return call2 (Qwindow_sanitize_window_sizes, frame, horizontal);
2990}
2991
2992
2925static Lisp_Object 2993static Lisp_Object
2926window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal) 2994window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
2927{ 2995{
2928 return call2(Qwindow_pixel_to_total, frame, horizontal); 2996 return call2 (Qwindow_pixel_to_total, frame, horizontal);
2929} 2997}
2930 2998
2931 2999
@@ -3204,89 +3272,6 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
3204 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame); 3272 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
3205 } 3273 }
3206} 3274}
3207
3208/* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
3209 minimum allowable size. PIXELWISE means interpret these as pixel
3210 sizes. */
3211
3212void
3213check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise)
3214{
3215 /* For height, we have to see:
3216 how many windows the frame has at minimum (one or two),
3217 and whether it has a menu bar or other special stuff at the top. */
3218 if (pixelwise)
3219 {
3220 int min_height = MIN_SAFE_WINDOW_HEIGHT * FRAME_LINE_HEIGHT (frame);
3221 int min_width = MIN_SAFE_WINDOW_WIDTH * FRAME_COLUMN_WIDTH (frame);
3222
3223 if (!FRAME_MINIBUF_ONLY_P (frame) && FRAME_HAS_MINIBUF_P (frame))
3224 min_height = 2 * min_height;
3225
3226 min_height += FRAME_TOP_MARGIN_HEIGHT (frame);
3227 min_height += FRAME_INTERNAL_BORDER_WIDTH (frame);
3228
3229 if (*height < min_height)
3230 *height = min_height;
3231 if (*width < min_width)
3232 *width = min_width;
3233 }
3234 else
3235 {
3236 int min_height
3237 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
3238 ? MIN_SAFE_WINDOW_HEIGHT
3239 : 2 * MIN_SAFE_WINDOW_HEIGHT);
3240
3241 if (FRAME_TOP_MARGIN (frame) > 0)
3242 min_height += FRAME_TOP_MARGIN (frame);
3243
3244 if (*height < min_height)
3245 *height = min_height;
3246 if (*width < MIN_SAFE_WINDOW_WIDTH)
3247 *width = MIN_SAFE_WINDOW_WIDTH;
3248 }
3249}
3250
3251/* Adjust the margins of window W if text area is too small.
3252 Return 1 if window width is ok after adjustment; 0 if window
3253 is still too narrow. */
3254
3255static int
3256adjust_window_margins (struct window *w)
3257{
3258 int box_width = (WINDOW_PIXEL_WIDTH (w)
3259 - WINDOW_FRINGES_WIDTH (w)
3260 - WINDOW_SCROLL_BAR_AREA_WIDTH (w));
3261 int margin_width = WINDOW_MARGINS_WIDTH (w);
3262
3263 if (box_width - margin_width >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3264 return 1;
3265
3266 if (margin_width < 0 || box_width < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3267 return 0;
3268 else
3269 /* Window's text area is too narrow, but reducing the window
3270 margins will fix that. */
3271 {
3272 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
3273
3274 margin_width = box_width - MIN_SAFE_WINDOW_PIXEL_WIDTH (w);
3275
3276 if (WINDOW_RIGHT_MARGIN_WIDTH (w) > 0)
3277 {
3278 if (WINDOW_LEFT_MARGIN_WIDTH (w) > 0)
3279 w->left_margin_cols = w->right_margin_cols =
3280 margin_width / (2 * unit);
3281 else
3282 w->right_margin_cols = margin_width / unit;
3283 }
3284 else
3285 w->left_margin_cols = margin_width / unit;
3286
3287 return 1;
3288 }
3289}
3290 3275
3291/* The following three routines are needed for running a window's 3276/* The following three routines are needed for running a window's
3292 configuration change hook. */ 3277 configuration change hook. */
@@ -3320,7 +3305,7 @@ run_window_configuration_change_hook (struct frame *f)
3320 = Fdefault_value (Qwindow_configuration_change_hook); 3305 = Fdefault_value (Qwindow_configuration_change_hook);
3321 XSETFRAME (frame, f); 3306 XSETFRAME (frame, f);
3322 3307
3323 if (NILP (Vrun_hooks) || !NILP (inhibit_lisp_code)) 3308 if (NILP (Vrun_hooks) || !(f->official))
3324 return; 3309 return;
3325 3310
3326 /* Use the right buffer. Matters when running the local hooks. */ 3311 /* Use the right buffer. Matters when running the local hooks. */
@@ -3415,17 +3400,21 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3415 w->last_cursor_vpos = 0; 3400 w->last_cursor_vpos = 0;
3416 3401
3417 if (!(keep_margins_p && samebuf)) 3402 if (!(keep_margins_p && samebuf))
3418 { /* If we're not actually changing the buffer, don't reset hscroll and 3403 { /* If we're not actually changing the buffer, don't reset hscroll
3419 vscroll. This case happens for example when called from 3404 and vscroll. This case happens for example when called from
3420 change_frame_size_1, where we use a dummy call to 3405 change_frame_size_1, where we use a dummy call to
3421 Fset_window_buffer on the frame's selected window (and no other) 3406 Fset_window_buffer on the frame's selected window (and no
3422 just in order to run window-configuration-change-hook. 3407 other) just in order to run window-configuration-change-hook
3423 Resetting hscroll and vscroll here is problematic for things like 3408 (no longer true since change_frame_size_1 directly calls
3424 image-mode and doc-view-mode since it resets the image's position 3409 run_window_configuration_change_hook). Resetting hscroll and
3425 whenever we resize the frame. */ 3410 vscroll here is problematic for things like image-mode and
3426 w->hscroll = w->min_hscroll = 0; 3411 doc-view-mode since it resets the image's position whenever we
3412 resize the frame. */
3413 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
3414 w->suspend_auto_hscroll = 0;
3427 w->vscroll = 0; 3415 w->vscroll = 0;
3428 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b)); 3416 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
3417 set_marker_both (w->old_pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
3429 set_marker_restricted (w->start, 3418 set_marker_restricted (w->start,
3430 make_number (b->last_window_start), 3419 make_number (b->last_window_start),
3431 buffer); 3420 buffer);
@@ -3443,6 +3432,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3443 Fset_buffer (buffer); 3432 Fset_buffer (buffer);
3444 3433
3445 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type); 3434 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
3435 XMARKER (w->old_pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
3446 3436
3447 if (!keep_margins_p) 3437 if (!keep_margins_p)
3448 { 3438 {
@@ -3451,7 +3441,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3451 BVAR (b, right_fringe_width), 3441 BVAR (b, right_fringe_width),
3452 BVAR (b, fringes_outside_margins)); 3442 BVAR (b, fringes_outside_margins));
3453 set_window_scroll_bars (w, BVAR (b, scroll_bar_width), 3443 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
3454 BVAR (b, vertical_scroll_bar_type), Qnil); 3444 BVAR (b, vertical_scroll_bar_type),
3445 BVAR (b, scroll_bar_height),
3446 BVAR (b, horizontal_scroll_bar_type));
3455 set_window_margins (w, BVAR (b, left_margin_cols), 3447 set_window_margins (w, BVAR (b, left_margin_cols),
3456 BVAR (b, right_margin_cols)); 3448 BVAR (b, right_margin_cols));
3457 apply_window_adjustment (w); 3449 apply_window_adjustment (w);
@@ -3597,10 +3589,11 @@ temp_output_buffer_show (register Lisp_Object buf)
3597 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); 3589 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
3598 Vminibuf_scroll_window = window; 3590 Vminibuf_scroll_window = window;
3599 w = XWINDOW (window); 3591 w = XWINDOW (window);
3600 w->hscroll = 0; 3592 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
3601 w->min_hscroll = 0; 3593 w->suspend_auto_hscroll = 0;
3602 set_marker_restricted_both (w->start, buf, BEG, BEG); 3594 set_marker_restricted_both (w->start, buf, BEG, BEG);
3603 set_marker_restricted_both (w->pointm, buf, BEG, BEG); 3595 set_marker_restricted_both (w->pointm, buf, BEG, BEG);
3596 set_marker_restricted_both (w->old_pointm, buf, BEG, BEG);
3604 3597
3605 /* Run temp-buffer-show-hook, with the chosen window selected 3598 /* Run temp-buffer-show-hook, with the chosen window selected
3606 and its buffer current. */ 3599 and its buffer current. */
@@ -3652,6 +3645,7 @@ make_parent_window (Lisp_Object window, bool horflag)
3652 /* ...but now P becomes an internal window. */ 3645 /* ...but now P becomes an internal window. */
3653 wset_start (p, Qnil); 3646 wset_start (p, Qnil);
3654 wset_pointm (p, Qnil); 3647 wset_pointm (p, Qnil);
3648 wset_old_pointm (p, Qnil);
3655 wset_buffer (p, Qnil); 3649 wset_buffer (p, Qnil);
3656 wset_combination (p, horflag, window); 3650 wset_combination (p, horflag, window);
3657 wset_combination_limit (p, Qnil); 3651 wset_combination_limit (p, Qnil);
@@ -3675,7 +3669,9 @@ make_window (void)
3675 wset_new_pixel (w, make_number (0)); 3669 wset_new_pixel (w, make_number (0));
3676 wset_start (w, Fmake_marker ()); 3670 wset_start (w, Fmake_marker ());
3677 wset_pointm (w, Fmake_marker ()); 3671 wset_pointm (w, Fmake_marker ());
3672 wset_old_pointm (w, Fmake_marker ());
3678 wset_vertical_scroll_bar_type (w, Qt); 3673 wset_vertical_scroll_bar_type (w, Qt);
3674 wset_horizontal_scroll_bar_type (w, Qt);
3679 /* These Lisp fields are marked specially so they're not set to nil by 3675 /* These Lisp fields are marked specially so they're not set to nil by
3680 allocate_window. */ 3676 allocate_window. */
3681 wset_prev_buffers (w, Qnil); 3677 wset_prev_buffers (w, Qnil);
@@ -3692,8 +3688,8 @@ make_window (void)
3692#endif 3688#endif
3693 w->sequence_number = ++sequence_number; 3689 w->sequence_number = ++sequence_number;
3694 w->scroll_bar_width = -1; 3690 w->scroll_bar_width = -1;
3691 w->scroll_bar_height = -1;
3695 w->column_number_displayed = -1; 3692 w->column_number_displayed = -1;
3696
3697 /* Reset window_list. */ 3693 /* Reset window_list. */
3698 Vwindow_list = Qnil; 3694 Vwindow_list = Qnil;
3699 /* Return window. */ 3695 /* Return window. */
@@ -3943,11 +3939,8 @@ window_resize_apply (struct window *w, bool horflag)
3943 } 3939 }
3944 } 3940 }
3945 else 3941 else
3946 { 3942 /* Bug#15957. */
3947 adjust_window_margins (w); 3943 w->window_end_valid = 0;
3948 /* Bug#15957. */
3949 w->window_end_valid = 0;
3950 }
3951} 3944}
3952 3945
3953 3946
@@ -4107,6 +4100,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4107 /* old_size is the old size of the frame's root window. */ 4100 /* old_size is the old size of the frame's root window. */
4108 int old_size = horflag ? r->total_cols : r->total_lines; 4101 int old_size = horflag ? r->total_cols : r->total_lines;
4109 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height; 4102 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
4103 int old_pixel_top = r->pixel_top;
4110 /* new_size is the new size of the frame's root window. */ 4104 /* new_size is the new size of the frame's root window. */
4111 int new_size, new_pixel_size; 4105 int new_size, new_pixel_size;
4112 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f); 4106 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
@@ -4121,7 +4115,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4121 new_pixel_size = max (horflag 4115 new_pixel_size = max (horflag
4122 ? size 4116 ? size
4123 : (size 4117 : (size
4124 - FRAME_TOP_MARGIN_HEIGHT (f) 4118/** - FRAME_TOP_MARGIN_HEIGHT (f) **/
4125 - ((FRAME_HAS_MINIBUF_P (f) 4119 - ((FRAME_HAS_MINIBUF_P (f)
4126 && !FRAME_MINIBUF_ONLY_P (f)) 4120 && !FRAME_MINIBUF_ONLY_P (f))
4127 ? FRAME_LINE_HEIGHT (f) : 0)), 4121 ? FRAME_LINE_HEIGHT (f) : 0)),
@@ -4133,7 +4127,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4133 new_size = max (horflag 4127 new_size = max (horflag
4134 ? size 4128 ? size
4135 : (size 4129 : (size
4136 - FRAME_TOP_MARGIN (f) 4130/** - FRAME_TOP_MARGIN (f) **/
4137 - ((FRAME_HAS_MINIBUF_P (f) 4131 - ((FRAME_HAS_MINIBUF_P (f)
4138 && !FRAME_MINIBUF_ONLY_P (f)) 4132 && !FRAME_MINIBUF_ONLY_P (f))
4139 ? 1 : 0)), 4133 ? 1 : 0)),
@@ -4144,7 +4138,8 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4144 r->top_line = FRAME_TOP_MARGIN (f); 4138 r->top_line = FRAME_TOP_MARGIN (f);
4145 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); 4139 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4146 4140
4147 if (new_pixel_size == old_pixel_size) 4141 if (new_pixel_size == old_pixel_size
4142 && r->pixel_top == old_pixel_top)
4148 ; 4143 ;
4149 else if (WINDOW_LEAF_P (r)) 4144 else if (WINDOW_LEAF_P (r))
4150 /* For a leaf root window just set the size. */ 4145 /* For a leaf root window just set the size. */
@@ -4186,6 +4181,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4186 { 4181 {
4187 window_resize_apply (r, horflag); 4182 window_resize_apply (r, horflag);
4188 window_pixel_to_total (r->frame, horflag ? Qt : Qnil); 4183 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4184#if 0 /* Let's try without safe sizes and/or killing other windows. */
4189 } 4185 }
4190 else 4186 else
4191 { 4187 {
@@ -4198,7 +4194,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4198 window_resize_apply (r, horflag); 4194 window_resize_apply (r, horflag);
4199 window_pixel_to_total (r->frame, horflag ? Qt : Qnil); 4195 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4200 } 4196 }
4201#if 0 /* Let's try without killing other windows. */
4202 else 4197 else
4203 { 4198 {
4204 /* We lost. Delete all windows but the frame's 4199 /* We lost. Delete all windows but the frame's
@@ -4402,7 +4397,9 @@ set correctly. See the code of `split-window' for how this is done. */)
4402 n->right_fringe_width = r->right_fringe_width; 4397 n->right_fringe_width = r->right_fringe_width;
4403 n->fringes_outside_margins = r->fringes_outside_margins; 4398 n->fringes_outside_margins = r->fringes_outside_margins;
4404 n->scroll_bar_width = r->scroll_bar_width; 4399 n->scroll_bar_width = r->scroll_bar_width;
4400 n->scroll_bar_height = r->scroll_bar_height;
4405 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); 4401 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
4402 wset_horizontal_scroll_bar_type (n, r->horizontal_scroll_bar_type);
4406 4403
4407 /* Directly assign orthogonal coordinates and sizes. */ 4404 /* Directly assign orthogonal coordinates and sizes. */
4408 if (horflag) 4405 if (horflag)
@@ -4546,6 +4543,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4546 { 4543 {
4547 unshow_buffer (w); 4544 unshow_buffer (w);
4548 unchain_marker (XMARKER (w->pointm)); 4545 unchain_marker (XMARKER (w->pointm));
4546 unchain_marker (XMARKER (w->old_pointm));
4549 unchain_marker (XMARKER (w->start)); 4547 unchain_marker (XMARKER (w->start));
4550 wset_buffer (w, Qnil); 4548 wset_buffer (w, Qnil);
4551 } 4549 }
@@ -4807,6 +4805,7 @@ window_internal_height (struct window *w)
4807 4805
4808 return ht; 4806 return ht;
4809} 4807}
4808
4810 4809
4811/************************************************************************ 4810/************************************************************************
4812 Window Scrolling 4811 Window Scrolling
@@ -4857,6 +4856,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4857 void *itdata = NULL; 4856 void *itdata = NULL;
4858 int window_total_lines; 4857 int window_total_lines;
4859 int frame_line_height = default_line_pixel_height (w); 4858 int frame_line_height = default_line_pixel_height (w);
4859 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
4860 Fwindow_old_point (window)));
4860 4861
4861 SET_TEXT_POS_FROM_MARKER (start, w->start); 4862 SET_TEXT_POS_FROM_MARKER (start, w->start);
4862 /* Scrolling a minibuffer window via scroll bar when the echo area 4863 /* Scrolling a minibuffer window via scroll bar when the echo area
@@ -4985,6 +4986,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4985 { 4986 {
4986 ptrdiff_t start_pos = IT_CHARPOS (it); 4987 ptrdiff_t start_pos = IT_CHARPOS (it);
4987 int dy = frame_line_height; 4988 int dy = frame_line_height;
4989
4988 dy = max ((window_box_height (w) 4990 dy = max ((window_box_height (w)
4989 - next_screen_context_lines * dy), 4991 - next_screen_context_lines * dy),
4990 dy) * n; 4992 dy) * n;
@@ -5228,6 +5230,13 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
5228 } 5230 }
5229 } 5231 }
5230 bidi_unshelve_cache (itdata, 0); 5232 bidi_unshelve_cache (itdata, 0);
5233
5234 if (adjust_old_pointm)
5235 Fset_marker (w->old_pointm,
5236 ((w == XWINDOW (selected_window))
5237 ? make_number (BUF_PT (XBUFFER (w->contents)))
5238 : Fmarker_position (w->pointm)),
5239 w->contents);
5231} 5240}
5232 5241
5233 5242
@@ -5252,6 +5261,8 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5252 ptrdiff_t startpos = marker_position (w->start); 5261 ptrdiff_t startpos = marker_position (w->start);
5253 ptrdiff_t startbyte = marker_byte_position (w->start); 5262 ptrdiff_t startbyte = marker_byte_position (w->start);
5254 Lisp_Object original_pos = Qnil; 5263 Lisp_Object original_pos = Qnil;
5264 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
5265 Fwindow_old_point (window)));
5255 5266
5256 /* If scrolling screen-fulls, compute the number of lines to 5267 /* If scrolling screen-fulls, compute the number of lines to
5257 scroll from the window's height. */ 5268 scroll from the window's height. */
@@ -5267,6 +5278,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5267 struct position posit 5278 struct position posit
5268 = *compute_motion (startpos, startbyte, 0, 0, 0, 5279 = *compute_motion (startpos, startbyte, 0, 0, 0,
5269 PT, ht, 0, -1, w->hscroll, 0, w); 5280 PT, ht, 0, -1, w->hscroll, 0, w);
5281
5270 window_scroll_preserve_vpos = posit.vpos; 5282 window_scroll_preserve_vpos = posit.vpos;
5271 window_scroll_preserve_hpos = posit.hpos + w->hscroll; 5283 window_scroll_preserve_hpos = posit.hpos + w->hscroll;
5272 } 5284 }
@@ -5382,6 +5394,13 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5382 else 5394 else
5383 xsignal0 (Qend_of_buffer); 5395 xsignal0 (Qend_of_buffer);
5384 } 5396 }
5397
5398 if (adjust_old_pointm)
5399 Fset_marker (w->old_pointm,
5400 ((w == XWINDOW (selected_window))
5401 ? make_number (BUF_PT (XBUFFER (w->contents)))
5402 : Fmarker_position (w->pointm)),
5403 w->contents);
5385} 5404}
5386 5405
5387 5406
@@ -5518,6 +5537,7 @@ specifies the window to scroll. This takes precedence over
5518 5537
5519 Fset_buffer (w->contents); 5538 Fset_buffer (w->contents);
5520 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm)); 5539 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
5540 SET_PT_BOTH (marker_position (w->old_pointm), marker_byte_position (w->old_pointm));
5521 5541
5522 if (NILP (arg)) 5542 if (NILP (arg))
5523 window_scroll (window, 1, 1, 1); 5543 window_scroll (window, 1, 1, 1);
@@ -5532,6 +5552,7 @@ specifies the window to scroll. This takes precedence over
5532 } 5552 }
5533 5553
5534 set_marker_both (w->pointm, Qnil, PT, PT_BYTE); 5554 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
5555 set_marker_both (w->old_pointm, Qnil, PT, PT_BYTE);
5535 unbind_to (count, Qnil); 5556 unbind_to (count, Qnil);
5536 5557
5537 return Qnil; 5558 return Qnil;
@@ -5557,6 +5578,8 @@ by this function. This happens in an interactive call. */)
5557 if (!NILP (set_minimum)) 5578 if (!NILP (set_minimum))
5558 w->min_hscroll = w->hscroll; 5579 w->min_hscroll = w->hscroll;
5559 5580
5581 w->suspend_auto_hscroll = 1;
5582
5560 return result; 5583 return result;
5561} 5584}
5562 5585
@@ -5580,6 +5603,8 @@ by this function. This happens in an interactive call. */)
5580 if (!NILP (set_minimum)) 5603 if (!NILP (set_minimum))
5581 w->min_hscroll = w->hscroll; 5604 w->min_hscroll = w->hscroll;
5582 5605
5606 w->suspend_auto_hscroll = 1;
5607
5583 return result; 5608 return result;
5584} 5609}
5585 5610
@@ -5677,7 +5702,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5677 5702
5678 if (buf != current_buffer) 5703 if (buf != current_buffer)
5679 error ("`recenter'ing a window that does not display current-buffer."); 5704 error ("`recenter'ing a window that does not display current-buffer.");
5680 5705
5681 /* If redisplay is suppressed due to an error, try again. */ 5706 /* If redisplay is suppressed due to an error, try again. */
5682 buf->display_error_modiff = 0; 5707 buf->display_error_modiff = 0;
5683 5708
@@ -5847,34 +5872,46 @@ and redisplay normally--don't erase and redraw the frame. */)
5847} 5872}
5848 5873
5849DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width, 5874DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
5850 0, 1, 0, 5875 0, 2, 0,
5851 doc: /* Return the width in columns of the text display area of WINDOW. 5876 doc: /* Return the width in columns of the text display area of WINDOW.
5852WINDOW must be a live window and defaults to the selected one. 5877WINDOW must be a live window and defaults to the selected one.
5853 5878
5854The returned width does not include dividers, scrollbars, margins, 5879The returned width does not include dividers, scrollbars, margins,
5855fringes, nor any partial-width columns at the right of the text 5880fringes, nor any partial-width columns at the right of the text
5856area. */) 5881area.
5857 (Lisp_Object window) 5882
5883Optional argument PIXELWISE non-nil, means to return the width in
5884pixels. */)
5885 (Lisp_Object window, Lisp_Object pixelwise)
5858{ 5886{
5859 struct window *w = decode_live_window (window); 5887 struct window *w = decode_live_window (window);
5860 5888
5861 return make_number (window_box_width (w, TEXT_AREA) 5889 if (NILP (pixelwise))
5862 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))); 5890 return make_number (window_box_width (w, TEXT_AREA)
5891 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
5892 else
5893 return make_number (window_box_width (w, TEXT_AREA));
5863} 5894}
5864 5895
5865DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5896DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5866 0, 1, 0, 5897 0, 2, 0,
5867 doc: /* Return the height in lines of the text display area of WINDOW. 5898 doc: /* Return the height in lines of the text display area of WINDOW.
5868WINDOW must be a live window and defaults to the selected one. 5899WINDOW must be a live window and defaults to the selected one.
5869 5900
5870The returned height does not include dividers, the mode line, any header 5901The returned height does not include dividers, the mode line, any header
5871line, nor any partial-height lines at the bottom of the text area. */) 5902line, nor any partial-height lines at the bottom of the text area.
5872 (Lisp_Object window) 5903
5904Optional argument PIXELWISE non-nil, means to return the height in
5905pixels. */)
5906 (Lisp_Object window, Lisp_Object pixelwise)
5873{ 5907{
5874 struct window *w = decode_live_window (window); 5908 struct window *w = decode_live_window (window);
5875 5909
5876 return make_number (window_box_height (w) 5910 if (NILP (pixelwise))
5877 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w))); 5911 return make_number (window_box_height (w)
5912 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
5913 else
5914 return make_number (window_box_height (w));
5878} 5915}
5879 5916
5880DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, 5917DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
@@ -5984,17 +6021,18 @@ struct saved_window
5984{ 6021{
5985 struct vectorlike_header header; 6022 struct vectorlike_header header;
5986 6023
5987 Lisp_Object window, buffer, start, pointm; 6024 Lisp_Object window, buffer, start, pointm, old_pointm;
5988 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width; 6025 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
5989 Lisp_Object left_col, top_line, total_cols, total_lines; 6026 Lisp_Object left_col, top_line, total_cols, total_lines;
5990 Lisp_Object normal_cols, normal_lines; 6027 Lisp_Object normal_cols, normal_lines;
5991 Lisp_Object hscroll, min_hscroll; 6028 Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll;
5992 Lisp_Object parent, prev; 6029 Lisp_Object parent, prev;
5993 Lisp_Object start_at_line_beg; 6030 Lisp_Object start_at_line_beg;
5994 Lisp_Object display_table; 6031 Lisp_Object display_table;
5995 Lisp_Object left_margin_cols, right_margin_cols; 6032 Lisp_Object left_margin_cols, right_margin_cols;
5996 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 6033 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
5997 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated; 6034 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
6035 Lisp_Object scroll_bar_height, horizontal_scroll_bar_type;
5998 Lisp_Object combination_limit, window_parameters; 6036 Lisp_Object combination_limit, window_parameters;
5999}; 6037};
6000 6038
@@ -6022,13 +6060,359 @@ DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_config
6022 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame; 6060 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
6023} 6061}
6024 6062
6025/* From Chong's unwind_create_frame_1. */ 6063DEFUN ("set-window-configuration", Fset_window_configuration,
6026static void 6064 Sset_window_configuration, 1, 1, 0,
6027unwind_change_frame (Lisp_Object val) 6065 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
6066CONFIGURATION must be a value previously returned
6067by `current-window-configuration' (which see).
6068If CONFIGURATION was made from a frame that is now deleted,
6069only frame-independent values can be restored. In this case,
6070the return value is nil. Otherwise the value is t. */)
6071 (Lisp_Object configuration)
6028{ 6072{
6029 inhibit_lisp_code = val; 6073 register struct save_window_data *data;
6074 struct Lisp_Vector *saved_windows;
6075 Lisp_Object new_current_buffer;
6076 Lisp_Object frame;
6077 struct frame *f;
6078 ptrdiff_t old_point = -1;
6079
6080 CHECK_WINDOW_CONFIGURATION (configuration);
6081
6082 data = (struct save_window_data *) XVECTOR (configuration);
6083 saved_windows = XVECTOR (data->saved_windows);
6084
6085 new_current_buffer = data->current_buffer;
6086 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
6087 new_current_buffer = Qnil;
6088 else
6089 {
6090 if (XBUFFER (new_current_buffer) == current_buffer)
6091 /* The code further down "preserves point" by saving here PT in
6092 old_point and then setting it later back into PT. When the
6093 current-selected-window and the final-selected-window both show
6094 the current buffer, this suffers from the problem that the
6095 current PT is the window-point of the current-selected-window,
6096 while the final PT is the point of the final-selected-window, so
6097 this copy from one PT to the other would end up moving the
6098 window-point of the final-selected-window to the window-point of
6099 the current-selected-window. So we have to be careful which
6100 point of the current-buffer we copy into old_point. */
6101 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6102 && WINDOWP (selected_window)
6103 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
6104 && !EQ (selected_window, data->current_window))
6105 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6106 else
6107 old_point = PT;
6108 else
6109 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6110 point in new_current_buffer as of the last time this buffer was
6111 used. This can be non-deterministic since it can be changed by
6112 things like jit-lock by mere temporary selection of some random
6113 window that happens to show this buffer.
6114 So if possible we want this arbitrary choice of "which point" to
6115 be the one from the to-be-selected-window so as to prevent this
6116 window's cursor from being copied from another window. */
6117 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6118 /* If current_window = selected_window, its point is in BUF_PT. */
6119 && !EQ (selected_window, data->current_window))
6120 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6121 else
6122 old_point = BUF_PT (XBUFFER (new_current_buffer));
6123 }
6124
6125 frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
6126 f = XFRAME (frame);
6127
6128 /* If f is a dead frame, don't bother rebuilding its window tree.
6129 However, there is other stuff we should still try to do below. */
6130 if (FRAME_LIVE_P (f))
6131 {
6132 Lisp_Object window;
6133 Lisp_Object dead_windows = Qnil;
6134 register Lisp_Object tem, par, pers;
6135 register struct window *w;
6136 register struct saved_window *p;
6137 struct window *root_window;
6138 struct window **leaf_windows;
6139 int n_leaf_windows;
6140 ptrdiff_t k;
6141 int i, n;
6142
6143 /* Don't do this within the main loop below: This may call Lisp
6144 code and is thus potentially unsafe while input is blocked. */
6145 for (k = 0; k < saved_windows->header.size; k++)
6146 {
6147 p = SAVED_WINDOW_N (saved_windows, k);
6148 window = p->window;
6149 w = XWINDOW (window);
6150 if (BUFFERP (w->contents)
6151 && !EQ (w->contents, p->buffer)
6152 && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6153 /* If a window we restore gets another buffer, record the
6154 window's old buffer. */
6155 call1 (Qrecord_window_buffer, window);
6156 }
6157
6158 /* Consider frame unofficial, temporarily. */
6159 f->official = false;
6160 /* The mouse highlighting code could get screwed up
6161 if it runs during this. */
6162 block_input ();
6163
6164 /* "Swap out" point from the selected window's buffer
6165 into the window itself. (Normally the pointm of the selected
6166 window holds garbage.) We do this now, before
6167 restoring the window contents, and prevent it from
6168 being done later on when we select a new window. */
6169 if (! NILP (XWINDOW (selected_window)->contents))
6170 {
6171 w = XWINDOW (selected_window);
6172 set_marker_both (w->pointm,
6173 w->contents,
6174 BUF_PT (XBUFFER (w->contents)),
6175 BUF_PT_BYTE (XBUFFER (w->contents)));
6176 }
6177
6178 fset_redisplay (f);
6179 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
6180
6181 /* Problem: Freeing all matrices and later allocating them again
6182 is a serious redisplay flickering problem. What we would
6183 really like to do is to free only those matrices not reused
6184 below. */
6185 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
6186 leaf_windows = alloca (count_windows (root_window)
6187 * sizeof *leaf_windows);
6188 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
6189
6190 /* Kludge Alert!
6191 Mark all windows now on frame as "deleted".
6192 Restoring the new configuration "undeletes" any that are in it.
6193
6194 Save their current buffers in their height fields, since we may
6195 need it later, if a buffer saved in the configuration is now
6196 dead. */
6197 delete_all_child_windows (FRAME_ROOT_WINDOW (f));
6198
6199 for (k = 0; k < saved_windows->header.size; k++)
6200 {
6201 p = SAVED_WINDOW_N (saved_windows, k);
6202 window = p->window;
6203 w = XWINDOW (window);
6204 wset_next (w, Qnil);
6205
6206 if (!NILP (p->parent))
6207 wset_parent
6208 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window);
6209 else
6210 wset_parent (w, Qnil);
6211
6212 if (!NILP (p->prev))
6213 {
6214 wset_prev
6215 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window);
6216 wset_next (XWINDOW (w->prev), p->window);
6217 }
6218 else
6219 {
6220 wset_prev (w, Qnil);
6221 if (!NILP (w->parent))
6222 wset_combination (XWINDOW (w->parent),
6223 (XINT (p->total_cols)
6224 != XWINDOW (w->parent)->total_cols),
6225 p->window);
6226 }
6227
6228 /* If we squirreled away the buffer, restore it now. */
6229 if (BUFFERP (w->combination_limit))
6230 wset_buffer (w, w->combination_limit);
6231 w->pixel_left = XFASTINT (p->pixel_left);
6232 w->pixel_top = XFASTINT (p->pixel_top);
6233 w->pixel_width = XFASTINT (p->pixel_width);
6234 w->pixel_height = XFASTINT (p->pixel_height);
6235 w->left_col = XFASTINT (p->left_col);
6236 w->top_line = XFASTINT (p->top_line);
6237 w->total_cols = XFASTINT (p->total_cols);
6238 w->total_lines = XFASTINT (p->total_lines);
6239 wset_normal_cols (w, p->normal_cols);
6240 wset_normal_lines (w, p->normal_lines);
6241 w->hscroll = XFASTINT (p->hscroll);
6242 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
6243 w->min_hscroll = XFASTINT (p->min_hscroll);
6244 w->hscroll_whole = XFASTINT (p->hscroll_whole);
6245 wset_display_table (w, p->display_table);
6246 w->left_margin_cols = XINT (p->left_margin_cols);
6247 w->right_margin_cols = XINT (p->right_margin_cols);
6248 w->left_fringe_width = XINT (p->left_fringe_width);
6249 w->right_fringe_width = XINT (p->right_fringe_width);
6250 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6251 w->scroll_bar_width = XINT (p->scroll_bar_width);
6252 w->scroll_bar_height = XINT (p->scroll_bar_height);
6253 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6254 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6255 wset_dedicated (w, p->dedicated);
6256 wset_combination_limit (w, p->combination_limit);
6257 /* Restore any window parameters that have been saved.
6258 Parameters that have not been saved are left alone. */
6259 for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
6260 {
6261 pers = XCAR (tem);
6262 if (CONSP (pers))
6263 {
6264 if (NILP (XCDR (pers)))
6265 {
6266 par = Fassq (XCAR (pers), w->window_parameters);
6267 if (CONSP (par) && !NILP (XCDR (par)))
6268 /* Reset a parameter to nil if and only if it
6269 has a non-nil association. Don't make new
6270 associations. */
6271 Fsetcdr (par, Qnil);
6272 }
6273 else
6274 /* Always restore a non-nil value. */
6275 Fset_window_parameter (window, XCAR (pers), XCDR (pers));
6276 }
6277 }
6278
6279 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6280 /* If saved buffer is alive, install it. */
6281 {
6282 wset_buffer (w, p->buffer);
6283 w->start_at_line_beg = !NILP (p->start_at_line_beg);
6284 set_marker_restricted (w->start, p->start, w->contents);
6285 set_marker_restricted (w->pointm, p->pointm, w->contents);
6286 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
6287 /* As documented in Fcurrent_window_configuration, don't
6288 restore the location of point in the buffer which was
6289 current when the window configuration was recorded. */
6290 if (!EQ (p->buffer, new_current_buffer)
6291 && XBUFFER (p->buffer) == current_buffer)
6292 Fgoto_char (w->pointm);
6293 }
6294 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
6295 /* Keep window's old buffer; make sure the markers are real. */
6296 {
6297 /* Set window markers at start of visible range. */
6298 if (XMARKER (w->start)->buffer == 0)
6299 set_marker_restricted_both (w->start, w->contents, 0, 0);
6300 if (XMARKER (w->pointm)->buffer == 0)
6301 set_marker_restricted_both
6302 (w->pointm, w->contents,
6303 BUF_PT (XBUFFER (w->contents)),
6304 BUF_PT_BYTE (XBUFFER (w->contents)));
6305 if (XMARKER (w->old_pointm)->buffer == 0)
6306 set_marker_restricted_both
6307 (w->old_pointm, w->contents,
6308 BUF_PT (XBUFFER (w->contents)),
6309 BUF_PT_BYTE (XBUFFER (w->contents)));
6310 w->start_at_line_beg = 1;
6311 }
6312 else if (!NILP (w->start))
6313 /* Leaf window has no live buffer, get one. */
6314 {
6315 /* Get the buffer via other_buffer_safely in order to
6316 avoid showing an unimportant buffer and, if necessary, to
6317 recreate *scratch* in the course (part of Juanma's bs-show
6318 scenario from March 2011). */
6319 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
6320 /* This will set the markers to beginning of visible
6321 range. */
6322 set_marker_restricted_both (w->start, w->contents, 0, 0);
6323 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
6324 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
6325 w->start_at_line_beg = 1;
6326 if (!NILP (w->dedicated))
6327 /* Record this window as dead. */
6328 dead_windows = Fcons (window, dead_windows);
6329 /* Make sure window is no more dedicated. */
6330 wset_dedicated (w, Qnil);
6331 }
6332 }
6333
6334 fset_root_window (f, data->root_window);
6335 /* Arrange *not* to restore point in the buffer that was
6336 current when the window configuration was saved. */
6337 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6338 set_marker_restricted (XWINDOW (data->current_window)->pointm,
6339 make_number (old_point),
6340 XWINDOW (data->current_window)->contents);
6341
6342 /* In the following call to `select-window', prevent "swapping out
6343 point" in the old selected window using the buffer that has
6344 been restored into it. We already swapped out that point from
6345 that window's old buffer.
6346
6347 Do not record the buffer here. We do that in a separate call
6348 to select_window below. See also Bug#16207. */
6349 select_window (data->current_window, Qt, 1);
6350 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6351 last_selected_window)
6352 = selected_window;
6353
6354 if (NILP (data->focus_frame)
6355 || (FRAMEP (data->focus_frame)
6356 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
6357 Fredirect_frame_focus (frame, data->focus_frame);
6358
6359 /* Now, free glyph matrices in windows that were not reused. */
6360 for (i = n = 0; i < n_leaf_windows; ++i)
6361 {
6362 if (NILP (leaf_windows[i]->contents))
6363 free_window_matrices (leaf_windows[i]);
6364 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
6365 ++n;
6366 }
6367
6368 /* Make frame official again and apply frame size changes if
6369 needed. */
6370 f->official = true;
6371 adjust_frame_size (f, -1, -1, 1, 0);
6372
6373 adjust_frame_glyphs (f);
6374 unblock_input ();
6375
6376 /* Scan dead buffer windows. */
6377 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
6378 {
6379 window = XCAR (dead_windows);
6380 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
6381 delete_deletable_window (window);
6382 }
6383
6384 /* Record the selected window's buffer here. The window should
6385 already be the selected one from the call above. */
6386 select_window (data->current_window, Qnil, 0);
6387
6388 /* Fselect_window will have made f the selected frame, so we
6389 reselect the proper frame here. Fhandle_switch_frame will change the
6390 selected window too, but that doesn't make the call to
6391 Fselect_window above totally superfluous; it still sets f's
6392 selected window. */
6393 if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
6394 do_switch_frame (data->selected_frame, 0, 0, Qnil);
6395
6396 run_window_configuration_change_hook (f);
6397 }
6398
6399 if (!NILP (new_current_buffer))
6400 {
6401 Fset_buffer (new_current_buffer);
6402 /* If the new current buffer doesn't appear in the selected
6403 window, go to its old point (see bug#12208). */
6404 if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6405 Fgoto_char (make_number (old_point));
6406 }
6407
6408 Vminibuf_scroll_window = data->minibuf_scroll_window;
6409 minibuf_selected_window = data->minibuf_selected_window;
6410
6411 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6030} 6412}
6031 6413
6414
6415#if 0
6032DEFUN ("set-window-configuration", Fset_window_configuration, 6416DEFUN ("set-window-configuration", Fset_window_configuration,
6033 Sset_window_configuration, 1, 1, 0, 6417 Sset_window_configuration, 1, 1, 0,
6034 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. 6418 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
@@ -6137,18 +6521,18 @@ the return value is nil. Otherwise the value is t. */)
6137 call1 (Qrecord_window_buffer, window); 6521 call1 (Qrecord_window_buffer, window);
6138 } 6522 }
6139 6523
6140 /* Don't run lisp in the following segment since the frame is in a 6524 /* Consider frame unofficial, temporarily. */
6141 completely inconsistent state. See Bug#16207. */ 6525 f->official = false;
6142 record_unwind_protect (unwind_change_frame, inhibit_lisp_code);
6143 inhibit_lisp_code = Qt;
6144 /* The mouse highlighting code could get screwed up 6526 /* The mouse highlighting code could get screwed up
6145 if it runs during this. */ 6527 if it runs during this. */
6146 block_input (); 6528 block_input ();
6147 6529
6148 if (data->frame_text_width != previous_frame_text_width 6530 if (data->frame_text_width != previous_frame_text_width
6149 || data->frame_text_height != previous_frame_text_height) 6531 || data->frame_text_height != previous_frame_text_height)
6150 change_frame_size (f, data->frame_text_width, 6532 /* Make frame size fit the one in data, so window sizes restored
6151 data->frame_text_height, 0, 0, 0, 1); 6533 from data match those of the frame. */
6534 adjust_frame_size (f, data->frame_text_width,
6535 data->frame_text_height, 5, 0);
6152 6536
6153 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines) 6537 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
6154 { 6538 {
@@ -6245,7 +6629,9 @@ the return value is nil. Otherwise the value is t. */)
6245 wset_normal_cols (w, p->normal_cols); 6629 wset_normal_cols (w, p->normal_cols);
6246 wset_normal_lines (w, p->normal_lines); 6630 wset_normal_lines (w, p->normal_lines);
6247 w->hscroll = XFASTINT (p->hscroll); 6631 w->hscroll = XFASTINT (p->hscroll);
6632 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
6248 w->min_hscroll = XFASTINT (p->min_hscroll); 6633 w->min_hscroll = XFASTINT (p->min_hscroll);
6634 w->hscroll_whole = XFASTINT (p->hscroll_whole);
6249 wset_display_table (w, p->display_table); 6635 wset_display_table (w, p->display_table);
6250 w->left_margin_cols = XINT (p->left_margin_cols); 6636 w->left_margin_cols = XINT (p->left_margin_cols);
6251 w->right_margin_cols = XINT (p->right_margin_cols); 6637 w->right_margin_cols = XINT (p->right_margin_cols);
@@ -6253,7 +6639,9 @@ the return value is nil. Otherwise the value is t. */)
6253 w->right_fringe_width = XINT (p->right_fringe_width); 6639 w->right_fringe_width = XINT (p->right_fringe_width);
6254 w->fringes_outside_margins = !NILP (p->fringes_outside_margins); 6640 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6255 w->scroll_bar_width = XINT (p->scroll_bar_width); 6641 w->scroll_bar_width = XINT (p->scroll_bar_width);
6642 w->scroll_bar_height = XINT (p->scroll_bar_height);
6256 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); 6643 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6644 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6257 wset_dedicated (w, p->dedicated); 6645 wset_dedicated (w, p->dedicated);
6258 wset_combination_limit (w, p->combination_limit); 6646 wset_combination_limit (w, p->combination_limit);
6259 /* Restore any window parameters that have been saved. 6647 /* Restore any window parameters that have been saved.
@@ -6284,16 +6672,15 @@ the return value is nil. Otherwise the value is t. */)
6284 wset_buffer (w, p->buffer); 6672 wset_buffer (w, p->buffer);
6285 w->start_at_line_beg = !NILP (p->start_at_line_beg); 6673 w->start_at_line_beg = !NILP (p->start_at_line_beg);
6286 set_marker_restricted (w->start, p->start, w->contents); 6674 set_marker_restricted (w->start, p->start, w->contents);
6287 set_marker_restricted (w->pointm, p->pointm, 6675 set_marker_restricted (w->pointm, p->pointm, w->contents);
6288 w->contents); 6676 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
6289
6290 /* As documented in Fcurrent_window_configuration, don't 6677 /* As documented in Fcurrent_window_configuration, don't
6291 restore the location of point in the buffer which was 6678 restore the location of point in the buffer which was
6292 current when the window configuration was recorded. */ 6679 current when the window configuration was recorded. */
6293 if (!EQ (p->buffer, new_current_buffer) 6680 if (!EQ (p->buffer, new_current_buffer)
6294 && XBUFFER (p->buffer) == current_buffer) 6681 && XBUFFER (p->buffer) == current_buffer)
6295 Fgoto_char (w->pointm); 6682 Fgoto_char (w->pointm);
6296 } 6683 }
6297 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents))) 6684 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
6298 /* Keep window's old buffer; make sure the markers are real. */ 6685 /* Keep window's old buffer; make sure the markers are real. */
6299 { 6686 {
@@ -6305,20 +6692,26 @@ the return value is nil. Otherwise the value is t. */)
6305 (w->pointm, w->contents, 6692 (w->pointm, w->contents,
6306 BUF_PT (XBUFFER (w->contents)), 6693 BUF_PT (XBUFFER (w->contents)),
6307 BUF_PT_BYTE (XBUFFER (w->contents))); 6694 BUF_PT_BYTE (XBUFFER (w->contents)));
6695 if (XMARKER (w->old_pointm)->buffer == 0)
6696 set_marker_restricted_both
6697 (w->old_pointm, w->contents,
6698 BUF_PT (XBUFFER (w->contents)),
6699 BUF_PT_BYTE (XBUFFER (w->contents)));
6308 w->start_at_line_beg = 1; 6700 w->start_at_line_beg = 1;
6309 } 6701 }
6310 else if (!NILP (w->start)) 6702 else if (!NILP (w->start))
6311 /* Leaf window has no live buffer, get one. */ 6703 /* Leaf window has no live buffer, get one. */
6312 { 6704 {
6313 /* Get the buffer via other_buffer_safely in order to 6705 /* Get the buffer via other_buffer_safely in order to
6314 avoid showing an unimportant buffer and, if necessary, to 6706 avoid showing an unimportant buffer and, if necessary, to
6315 recreate *scratch* in the course (part of Juanma's bs-show 6707 recreate *scratch* in the course (part of Juanma's bs-show
6316 scenario from March 2011). */ 6708 scenario from March 2011). */
6317 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); 6709 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
6318 /* This will set the markers to beginning of visible 6710 /* This will set the markers to beginning of visible
6319 range. */ 6711 range. */
6320 set_marker_restricted_both (w->start, w->contents, 0, 0); 6712 set_marker_restricted_both (w->start, w->contents, 0, 0);
6321 set_marker_restricted_both (w->pointm, w->contents, 0, 0); 6713 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
6714 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
6322 w->start_at_line_beg = 1; 6715 w->start_at_line_beg = 1;
6323 if (!NILP (w->dedicated)) 6716 if (!NILP (w->dedicated))
6324 /* Record this window as dead. */ 6717 /* Record this window as dead. */
@@ -6356,8 +6749,8 @@ the return value is nil. Otherwise the value is t. */)
6356 /* Set the frame size to the value it had before this function. */ 6749 /* Set the frame size to the value it had before this function. */
6357 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f) 6750 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
6358 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f)) 6751 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
6359 change_frame_size (f, previous_frame_text_width, 6752 adjust_frame_size (f, previous_frame_text_width,
6360 previous_frame_text_height, 0, 0, 0, 1); 6753 previous_frame_text_height, 5, 0);
6361 6754
6362 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) 6755 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
6363 { 6756 {
@@ -6386,9 +6779,13 @@ the return value is nil. Otherwise the value is t. */)
6386 ++n; 6779 ++n;
6387 } 6780 }
6388 6781
6782 /* Make frame official again and apply frame size changes if
6783 needed. */
6784 f->official = true;
6785 adjust_frame_size (f, -1, -1, 1, 0);
6786
6389 adjust_frame_glyphs (f); 6787 adjust_frame_glyphs (f);
6390 unblock_input (); 6788 unblock_input ();
6391 unbind_to (count, Qnil);
6392 6789
6393 /* Scan dead buffer windows. */ 6790 /* Scan dead buffer windows. */
6394 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows)) 6791 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
@@ -6427,6 +6824,7 @@ the return value is nil. Otherwise the value is t. */)
6427 6824
6428 return (FRAME_LIVE_P (f) ? Qt : Qnil); 6825 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6429} 6826}
6827#endif
6430 6828
6431void 6829void
6432restore_window_configuration (Lisp_Object configuration) 6830restore_window_configuration (Lisp_Object configuration)
@@ -6459,6 +6857,7 @@ delete_all_child_windows (Lisp_Object window)
6459 { 6857 {
6460 unshow_buffer (w); 6858 unshow_buffer (w);
6461 unchain_marker (XMARKER (w->pointm)); 6859 unchain_marker (XMARKER (w->pointm));
6860 unchain_marker (XMARKER (w->old_pointm));
6462 unchain_marker (XMARKER (w->start)); 6861 unchain_marker (XMARKER (w->start));
6463 /* Since combination limit makes sense for an internal windows 6862 /* Since combination limit makes sense for an internal windows
6464 only, we use this slot to save the buffer for the sake of 6863 only, we use this slot to save the buffer for the sake of
@@ -6565,7 +6964,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6565 p->normal_cols = w->normal_cols; 6964 p->normal_cols = w->normal_cols;
6566 p->normal_lines = w->normal_lines; 6965 p->normal_lines = w->normal_lines;
6567 XSETFASTINT (p->hscroll, w->hscroll); 6966 XSETFASTINT (p->hscroll, w->hscroll);
6967 p->suspend_auto_hscroll = w->suspend_auto_hscroll ? Qt : Qnil;
6568 XSETFASTINT (p->min_hscroll, w->min_hscroll); 6968 XSETFASTINT (p->min_hscroll, w->min_hscroll);
6969 XSETFASTINT (p->hscroll_whole, w->hscroll_whole);
6569 p->display_table = w->display_table; 6970 p->display_table = w->display_table;
6570 p->left_margin_cols = make_number (w->left_margin_cols); 6971 p->left_margin_cols = make_number (w->left_margin_cols);
6571 p->right_margin_cols = make_number (w->right_margin_cols); 6972 p->right_margin_cols = make_number (w->right_margin_cols);
@@ -6573,7 +6974,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6573 p->right_fringe_width = make_number (w->right_fringe_width); 6974 p->right_fringe_width = make_number (w->right_fringe_width);
6574 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; 6975 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
6575 p->scroll_bar_width = make_number (w->scroll_bar_width); 6976 p->scroll_bar_width = make_number (w->scroll_bar_width);
6977 p->scroll_bar_height = make_number (w->scroll_bar_height);
6576 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 6978 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
6979 p->horizontal_scroll_bar_type = w->horizontal_scroll_bar_type;
6577 p->dedicated = w->dedicated; 6980 p->dedicated = w->dedicated;
6578 p->combination_limit = w->combination_limit; 6981 p->combination_limit = w->combination_limit;
6579 p->window_parameters = Qnil; 6982 p->window_parameters = Qnil;
@@ -6635,9 +7038,13 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6635 BUF_PT_BYTE (XBUFFER (w->contents))); 7038 BUF_PT_BYTE (XBUFFER (w->contents)));
6636 else 7039 else
6637 p->pointm = Fcopy_marker (w->pointm, Qnil); 7040 p->pointm = Fcopy_marker (w->pointm, Qnil);
7041 p->old_pointm = Fcopy_marker (w->old_pointm, Qnil);
6638 XMARKER (p->pointm)->insertion_type 7042 XMARKER (p->pointm)->insertion_type
6639 = !NILP (buffer_local_value /* Don't signal error if void. */ 7043 = !NILP (buffer_local_value /* Don't signal error if void. */
6640 (Qwindow_point_insertion_type, w->contents)); 7044 (Qwindow_point_insertion_type, w->contents));
7045 XMARKER (p->old_pointm)->insertion_type
7046 = !NILP (buffer_local_value /* Don't signal error if void. */
7047 (Qwindow_point_insertion_type, w->contents));
6641 7048
6642 p->start = Fcopy_marker (w->start, Qnil); 7049 p->start = Fcopy_marker (w->start, Qnil);
6643 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil; 7050 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
@@ -6645,6 +7052,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6645 else 7052 else
6646 { 7053 {
6647 p->pointm = Qnil; 7054 p->pointm = Qnil;
7055 p->old_pointm = Qnil;
6648 p->start = Qnil; 7056 p->start = Qnil;
6649 p->start_at_line_beg = Qnil; 7057 p->start_at_line_beg = Qnil;
6650 } 7058 }
@@ -6714,7 +7122,6 @@ static void
6714apply_window_adjustment (struct window *w) 7122apply_window_adjustment (struct window *w)
6715{ 7123{
6716 eassert (w); 7124 eassert (w);
6717 adjust_window_margins (w);
6718 clear_glyph_matrix (w->current_matrix); 7125 clear_glyph_matrix (w->current_matrix);
6719 w->window_end_valid = 0; 7126 w->window_end_valid = 0;
6720 windows_or_buffers_changed = 30; 7127 windows_or_buffers_changed = 30;
@@ -6732,8 +7139,8 @@ set_window_margins (struct window *w, Lisp_Object left_width,
6732 Lisp_Object right_width) 7139 Lisp_Object right_width)
6733{ 7140{
6734 int left, right; 7141 int left, right;
7142 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
6735 7143
6736 /* FIXME: what about margins that are too wide? */
6737 left = (NILP (left_width) ? 0 7144 left = (NILP (left_width) ? 0
6738 : (CHECK_NATNUM (left_width), XINT (left_width))); 7145 : (CHECK_NATNUM (left_width), XINT (left_width)));
6739 right = (NILP (right_width) ? 0 7146 right = (NILP (right_width) ? 0
@@ -6741,11 +7148,23 @@ set_window_margins (struct window *w, Lisp_Object left_width,
6741 7148
6742 if (w->left_margin_cols != left || w->right_margin_cols != right) 7149 if (w->left_margin_cols != left || w->right_margin_cols != right)
6743 { 7150 {
6744 w->left_margin_cols = left; 7151 /* Don't change anything if new margins won't fit. */
6745 w->right_margin_cols = right; 7152 if ((WINDOW_PIXEL_WIDTH (w)
6746 return w; 7153 - WINDOW_FRINGES_WIDTH (w)
7154 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7155 - (left + right) * unit)
7156 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7157 {
7158 w->left_margin_cols = left;
7159 w->right_margin_cols = right;
7160
7161 return w;
7162 }
7163 else
7164 return NULL;
6747 } 7165 }
6748 return NULL; 7166 else
7167 return NULL;
6749} 7168}
6750 7169
6751DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, 7170DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
@@ -6807,12 +7226,25 @@ set_window_fringes (struct window *w, Lisp_Object left_width,
6807 || w->right_fringe_width != right 7226 || w->right_fringe_width != right
6808 || w->fringes_outside_margins != outside)) 7227 || w->fringes_outside_margins != outside))
6809 { 7228 {
7229 if (left > 0 || right > 0)
7230 {
7231 /* Don't change anything if new fringes don't fit. */
7232 if ((WINDOW_PIXEL_WIDTH (w)
7233 - WINDOW_MARGINS_WIDTH (w)
7234 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7235 - max (left, 0) - max (right, 0))
7236 < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7237 return NULL;
7238 }
7239
6810 w->left_fringe_width = left; 7240 w->left_fringe_width = left;
6811 w->right_fringe_width = right; 7241 w->right_fringe_width = right;
6812 w->fringes_outside_margins = outside; 7242 w->fringes_outside_margins = outside;
7243
6813 return w; 7244 return w;
6814 } 7245 }
6815 return NULL; 7246 else
7247 return NULL;
6816} 7248}
6817 7249
6818DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 7250DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
@@ -6863,9 +7295,12 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6863 7295
6864static struct window * 7296static struct window *
6865set_window_scroll_bars (struct window *w, Lisp_Object width, 7297set_window_scroll_bars (struct window *w, Lisp_Object width,
6866 Lisp_Object vertical_type, Lisp_Object horizontal_type) 7298 Lisp_Object vertical_type, Lisp_Object height,
7299 Lisp_Object horizontal_type)
6867{ 7300{
6868 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width))); 7301 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
7302 int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height)));
7303 bool changed = 0;
6869 7304
6870 if (iwidth == 0) 7305 if (iwidth == 0)
6871 vertical_type = Qnil; 7306 vertical_type = Qnil;
@@ -6879,32 +7314,69 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
6879 if (w->scroll_bar_width != iwidth 7314 if (w->scroll_bar_width != iwidth
6880 || !EQ (w->vertical_scroll_bar_type, vertical_type)) 7315 || !EQ (w->vertical_scroll_bar_type, vertical_type))
6881 { 7316 {
6882 w->scroll_bar_width = iwidth; 7317 /* Don't change anything if new scroll bar won't fit. */
6883 wset_vertical_scroll_bar_type (w, vertical_type); 7318 if ((WINDOW_PIXEL_WIDTH (w)
6884 return w; 7319 - WINDOW_MARGINS_WIDTH (w)
7320 - WINDOW_FRINGES_WIDTH (w)
7321 - max (iwidth, 0))
7322 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7323 {
7324 w->scroll_bar_width = iwidth;
7325 wset_vertical_scroll_bar_type (w, vertical_type);
7326 changed = 1;
7327 }
7328 }
7329
7330 if (MINI_WINDOW_P (w) || iheight == 0)
7331 horizontal_type = Qnil;
7332
7333 if (!(NILP (horizontal_type)
7334 || EQ (horizontal_type, Qbottom)
7335 || EQ (horizontal_type, Qt)))
7336 error ("Invalid type of horizontal scroll bar");
7337
7338 if (w->scroll_bar_height != iheight
7339 || !EQ (w->horizontal_scroll_bar_type, horizontal_type))
7340 {
7341 /* Don't change anything if new scroll bar won't fit. */
7342 if ((WINDOW_PIXEL_HEIGHT (w)
7343 - WINDOW_HEADER_LINE_HEIGHT (w)
7344 - WINDOW_MODE_LINE_HEIGHT (w)
7345 - max (iheight, 0))
7346 >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
7347 {
7348 w->scroll_bar_height = iheight;
7349 wset_horizontal_scroll_bar_type (w, horizontal_type);
7350 changed = 1;
7351 }
6885 } 7352 }
6886 return NULL; 7353
7354 return changed ? w : NULL;
6887} 7355}
6888 7356
6889DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, 7357DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6890 Sset_window_scroll_bars, 2, 4, 0, 7358 Sset_window_scroll_bars, 1, 5, 0,
6891 doc: /* Set width and type of scroll bars of window WINDOW. 7359 doc: /* Set width and type of scroll bars of window WINDOW.
6892WINDOW must be a live window and defaults to the selected one. 7360WINDOW must be a live window and defaults to the selected one.
6893 7361
6894Second parameter WIDTH specifies the pixel width for the scroll bar. 7362Second parameter WIDTH specifies the pixel width for the scroll bar.
6895Third parameter VERTICAL-TYPE specifies the type of the vertical scroll 7363Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6896bar: left, right, or nil. 7364bar: left, right, or nil. If WIDTH is nil, use the frame's scroll-bar
6897If WIDTH is nil, use the frame's scroll-bar width. 7365width. If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6898If VERTICAL-TYPE is t, use the frame's scroll-bar type. 7366
6899Fourth parameter HORIZONTAL-TYPE is currently unused. 7367Fourth parameter HEIGHT specifies the pixel height for the scroll bar.
7368Fifth parameter HORIZONTAL-TYPE specifies the type of the vertical
7369scroll bar: nil, bottom, or t. If HEIGHT is nil, use the frame's
7370scroll-bar height. If HORIZONTAL-TYPE is t, use the frame's scroll-bar
7371type.
6900 7372
6901Return t if scroll bars were actually changed and nil otherwise. */) 7373Return t if scroll bars were actually changed and nil otherwise. */)
6902 (Lisp_Object window, Lisp_Object width, 7374 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
6903 Lisp_Object vertical_type, Lisp_Object horizontal_type) 7375 Lisp_Object height, Lisp_Object horizontal_type)
6904{ 7376{
6905 struct window *w 7377 struct window *w
6906 = set_window_scroll_bars (decode_live_window (window), 7378 = set_window_scroll_bars (decode_live_window (window),
6907 width, vertical_type, horizontal_type); 7379 width, vertical_type, height, horizontal_type);
6908 return w ? (apply_window_adjustment (w), Qt) : Qnil; 7380 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6909} 7381}
6910 7382
@@ -6914,19 +7386,20 @@ DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
6914 doc: /* Get width and type of scroll bars of window WINDOW. 7386 doc: /* Get width and type of scroll bars of window WINDOW.
6915WINDOW must be a live window and defaults to the selected one. 7387WINDOW must be a live window and defaults to the selected one.
6916 7388
6917Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE). 7389Value is a list of the form (WIDTH COLS VERTICAL-TYPE HEIGHT LINES
6918If WIDTH is nil or TYPE is t, the window is using the frame's corresponding 7390HORIZONTAL-TYPE). If WIDTH or HEIGHT is nil or TYPE is t, the window is
6919value. */) 7391using the frame's corresponding value. */)
6920 (Lisp_Object window) 7392 (Lisp_Object window)
6921{ 7393{
6922 struct window *w = decode_live_window (window); 7394 struct window *w = decode_live_window (window);
6923 7395
6924 return list4 (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)), 7396 return Fcons (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)),
6925 make_number (WINDOW_SCROLL_BAR_COLS (w)), 7397 list5 (make_number (WINDOW_SCROLL_BAR_COLS (w)),
6926 w->vertical_scroll_bar_type, Qnil); 7398 w->vertical_scroll_bar_type,
7399 make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (w)),
7400 make_number (WINDOW_SCROLL_BAR_LINES (w)),
7401 w->horizontal_scroll_bar_type));
6927} 7402}
6928
6929
6930 7403
6931/*********************************************************************** 7404/***********************************************************************
6932 Smooth scrolling 7405 Smooth scrolling
@@ -7116,7 +7589,9 @@ compare_window_configurations (Lisp_Object configuration1,
7116 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width) 7589 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
7117 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins) 7590 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
7118 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width) 7591 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
7119 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)) 7592 || !EQ (sw1->scroll_bar_height, sw2->scroll_bar_height)
7593 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)
7594 || !EQ (sw1->horizontal_scroll_bar_type, sw2->horizontal_scroll_bar_type))
7120 return 0; 7595 return 0;
7121 } 7596 }
7122 7597
@@ -7170,6 +7645,7 @@ syms_of_window (void)
7170 DEFSYM (Qdelete_window, "delete-window"); 7645 DEFSYM (Qdelete_window, "delete-window");
7171 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window"); 7646 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
7172 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically"); 7647 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
7648 DEFSYM (Qwindow_sanitize_window_sizes, "window--sanitize-window-sizes");
7173 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total"); 7649 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
7174 DEFSYM (Qsafe, "safe"); 7650 DEFSYM (Qsafe, "safe");
7175 DEFSYM (Qdisplay_buffer, "display-buffer"); 7651 DEFSYM (Qdisplay_buffer, "display-buffer");
@@ -7396,12 +7872,14 @@ pixelwise even if this option is nil. */);
7396 defsubr (&Swindow_right_divider_width); 7872 defsubr (&Swindow_right_divider_width);
7397 defsubr (&Swindow_bottom_divider_width); 7873 defsubr (&Swindow_bottom_divider_width);
7398 defsubr (&Swindow_scroll_bar_width); 7874 defsubr (&Swindow_scroll_bar_width);
7875 defsubr (&Swindow_scroll_bar_height);
7399 defsubr (&Swindow_inside_edges); 7876 defsubr (&Swindow_inside_edges);
7400 defsubr (&Swindow_inside_pixel_edges); 7877 defsubr (&Swindow_inside_pixel_edges);
7401 defsubr (&Swindow_inside_absolute_pixel_edges); 7878 defsubr (&Swindow_inside_absolute_pixel_edges);
7402 defsubr (&Scoordinates_in_window_p); 7879 defsubr (&Scoordinates_in_window_p);
7403 defsubr (&Swindow_at); 7880 defsubr (&Swindow_at);
7404 defsubr (&Swindow_point); 7881 defsubr (&Swindow_point);
7882 defsubr (&Swindow_old_point);
7405 defsubr (&Swindow_start); 7883 defsubr (&Swindow_start);
7406 defsubr (&Swindow_end); 7884 defsubr (&Swindow_end);
7407 defsubr (&Sset_window_point); 7885 defsubr (&Sset_window_point);
diff --git a/src/window.h b/src/window.h
index b9c2b1f5ba8..cdf8da93138 100644
--- a/src/window.h
+++ b/src/window.h
@@ -128,21 +128,37 @@ struct window
128 each one can have its own value of point. */ 128 each one can have its own value of point. */
129 Lisp_Object pointm; 129 Lisp_Object pointm;
130 130
131 /* A marker pointing to where in the text point was in this window
132 at the time of last redisplay. The value is saved for the
133 selected window too. */
134 Lisp_Object old_pointm;
135
131 /* No permanent meaning; used by save-window-excursion's 136 /* No permanent meaning; used by save-window-excursion's
132 bookkeeping. */ 137 bookkeeping. */
133 Lisp_Object temslot; 138 Lisp_Object temslot;
134 139
135 /* This window's vertical scroll bar. This field is only for use 140 /* This window's vertical scroll bar. This field is only for use by
136 by the window-system-dependent code which implements the 141 the window-system-dependent code which implements the scroll
137 scroll bars; it can store anything it likes here. If this 142 bars; it can store anything it likes here. If this window is
138 window is newly created and we haven't displayed a scroll bar in 143 newly created and we haven't displayed a scroll bar in it yet, or
139 it yet, or if the frame doesn't have any scroll bars, this is nil. */ 144 if the frame doesn't have any scroll bars, this is nil. */
140 Lisp_Object vertical_scroll_bar; 145 Lisp_Object vertical_scroll_bar;
141 146
142 /* Type of vertical scroll bar. A value of nil means 147 /* Type of vertical scroll bar. A value of nil means
143 no scroll bar. A value of t means use frame value. */ 148 no scroll bar. A value of t means use frame value. */
144 Lisp_Object vertical_scroll_bar_type; 149 Lisp_Object vertical_scroll_bar_type;
145 150
151 /* This window's horizontal scroll bar. This field is only for use
152 by the window-system-dependent code which implements the scroll
153 bars; it can store anything it likes here. If this window is
154 newly created and we haven't displayed a scroll bar in it yet, or
155 if the frame doesn't have any scroll bars, this is nil. */
156 Lisp_Object horizontal_scroll_bar;
157
158 /* Type of horizontal scroll bar. A value of nil means
159 no scroll bar. A value of t means use frame value. */
160 Lisp_Object horizontal_scroll_bar_type;
161
146 /* Display-table to use for displaying chars in this window. 162 /* Display-table to use for displaying chars in this window.
147 Nil means use the buffer's own display-table. */ 163 Nil means use the buffer's own display-table. */
148 Lisp_Object display_table; 164 Lisp_Object display_table;
@@ -209,6 +225,10 @@ struct window
209 the user has set, by set-window-hscroll for example. */ 225 the user has set, by set-window-hscroll for example. */
210 ptrdiff_t min_hscroll; 226 ptrdiff_t min_hscroll;
211 227
228 /* Maximum line length in pixels within window bound by size of
229 window (set up by set_horizontal_scroll_bar). */
230 ptrdiff_t hscroll_whole;
231
212 /* Displayed buffer's text modification events counter as of last time 232 /* Displayed buffer's text modification events counter as of last time
213 display completed. */ 233 display completed. */
214 EMACS_INT last_modified; 234 EMACS_INT last_modified;
@@ -282,6 +302,10 @@ struct window
282 A value of -1 means use frame values. */ 302 A value of -1 means use frame values. */
283 int scroll_bar_width; 303 int scroll_bar_width;
284 304
305 /* Pixel height of scroll bars.
306 A value of -1 means use frame values. */
307 int scroll_bar_height;
308
285 /* Effective height of the mode line, or -1 if not known. */ 309 /* Effective height of the mode line, or -1 if not known. */
286 int mode_line_height; 310 int mode_line_height;
287 311
@@ -355,6 +379,10 @@ struct window
355 /* True if it needs to be redisplayed. */ 379 /* True if it needs to be redisplayed. */
356 bool_bf redisplay : 1; 380 bool_bf redisplay : 1;
357 381
382 /* True if auto hscrolling is currently suspended in this
383 window. */
384 bool_bf suspend_auto_hscroll : 1;
385
358 /* Amount by which lines of this window are scrolled in 386 /* Amount by which lines of this window are scrolled in
359 y-direction (smooth scrolling). */ 387 y-direction (smooth scrolling). */
360 int vscroll; 388 int vscroll;
@@ -403,6 +431,18 @@ wset_vertical_scroll_bar (struct window *w, Lisp_Object val)
403} 431}
404 432
405INLINE void 433INLINE void
434wset_horizontal_scroll_bar (struct window *w, Lisp_Object val)
435{
436 w->horizontal_scroll_bar = val;
437}
438
439INLINE void
440wset_horizontal_scroll_bar_type (struct window *w, Lisp_Object val)
441{
442 w->horizontal_scroll_bar_type = val;
443}
444
445INLINE void
406wset_prev_buffers (struct window *w, Lisp_Object val) 446wset_prev_buffers (struct window *w, Lisp_Object val)
407{ 447{
408 w->prev_buffers = val; 448 w->prev_buffers = val;
@@ -415,8 +455,17 @@ wset_next_buffers (struct window *w, Lisp_Object val)
415} 455}
416 456
417/* True if W is a minibuffer window. */ 457/* True if W is a minibuffer window. */
458#define MINI_WINDOW_P(W) ((W)->mini)
418 459
419#define MINI_WINDOW_P(W) ((W)->mini) 460/* 1 if W is a non-only minibuffer window. */
461/* The first check is redundant and the second overly complicated. */
462#define MINI_NON_ONLY_WINDOW_P(W) \
463 (MINI_WINDOW_P (W) \
464 && (EQ (W->prev, FRAME_ROOT_WINDOW (WINDOW_XFRAME (W)))))
465
466/* 1 if W is a minibuffer-only window. */
467#define MINI_ONLY_WINDOW_P(W) \
468 (MINI_WINDOW_P (W) && NILP (W->prev))
420 469
421/* General window layout: 470/* General window layout:
422 471
@@ -460,16 +509,17 @@ wset_next_buffers (struct window *w, Lisp_Object val)
460#define WINDOW_VERTICAL_COMBINATION_P(W) \ 509#define WINDOW_VERTICAL_COMBINATION_P(W) \
461 (WINDOWP ((W)->contents) && !(W)->horizontal) 510 (WINDOWP ((W)->contents) && !(W)->horizontal)
462 511
463#define WINDOW_XFRAME(W) \ 512/* WINDOW's XFRAME. */
464 (XFRAME (WINDOW_FRAME ((W)))) 513#define WINDOW_XFRAME(W) (XFRAME (WINDOW_FRAME ((W))))
465 514
466/* Return the canonical column width of the frame of window W. */ 515/* Whether WINDOW is a pseudo window. */
516#define WINDOW_PSEUDO_P(W) ((W)->pseudo_window_p)
467 517
518/* Return the canonical column width of the frame of window W. */
468#define WINDOW_FRAME_COLUMN_WIDTH(W) \ 519#define WINDOW_FRAME_COLUMN_WIDTH(W) \
469 (FRAME_COLUMN_WIDTH (WINDOW_XFRAME ((W)))) 520 (FRAME_COLUMN_WIDTH (WINDOW_XFRAME ((W))))
470 521
471/* Return the canonical column width of the frame of window W. */ 522/* Return the canonical column width of the frame of window W. */
472
473#define WINDOW_FRAME_LINE_HEIGHT(W) \ 523#define WINDOW_FRAME_LINE_HEIGHT(W) \
474 (FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W)))) 524 (FRAME_LINE_HEIGHT (WINDOW_XFRAME ((W))))
475 525
@@ -613,6 +663,10 @@ wset_next_buffers (struct window *w, Lisp_Object val)
613#define WINDOW_LEFTMOST_P(W) \ 663#define WINDOW_LEFTMOST_P(W) \
614 (WINDOW_LEFT_PIXEL_EDGE (W) == 0) 664 (WINDOW_LEFT_PIXEL_EDGE (W) == 0)
615 665
666/* True if window W's has no other windows above in its frame. */
667#define WINDOW_TOPMOST_P(W) \
668 (WINDOW_TOP_PIXEL_EDGE (W) == 0)
669
616/* True if window W's has no other windows to its right in its frame. */ 670/* True if window W's has no other windows to its right in its frame. */
617#define WINDOW_RIGHTMOST_P(W) \ 671#define WINDOW_RIGHTMOST_P(W) \
618 (WINDOW_RIGHT_PIXEL_EDGE (W) \ 672 (WINDOW_RIGHT_PIXEL_EDGE (W) \
@@ -629,7 +683,6 @@ wset_next_buffers (struct window *w, Lisp_Object val)
629/* Return the frame column at which the text (or left fringe) in 683/* Return the frame column at which the text (or left fringe) in
630 window W starts. This is different from the `LEFT_EDGE' because it 684 window W starts. This is different from the `LEFT_EDGE' because it
631 does not include a left-hand scroll bar if any. */ 685 does not include a left-hand scroll bar if any. */
632
633#define WINDOW_BOX_LEFT_EDGE_COL(W) \ 686#define WINDOW_BOX_LEFT_EDGE_COL(W) \
634 (WINDOW_LEFT_EDGE_COL (W) \ 687 (WINDOW_LEFT_EDGE_COL (W) \
635 + WINDOW_LEFT_SCROLL_BAR_COLS (W)) 688 + WINDOW_LEFT_SCROLL_BAR_COLS (W))
@@ -644,7 +697,6 @@ wset_next_buffers (struct window *w, Lisp_Object val)
644/* Return the window column before which the text in window W ends. 697/* Return the window column before which the text in window W ends.
645 This is different from WINDOW_RIGHT_EDGE_COL because it does not 698 This is different from WINDOW_RIGHT_EDGE_COL because it does not
646 include a scroll bar or window-separating line on the right edge. */ 699 include a scroll bar or window-separating line on the right edge. */
647
648#define WINDOW_BOX_RIGHT_EDGE_COL(W) \ 700#define WINDOW_BOX_RIGHT_EDGE_COL(W) \
649 (WINDOW_RIGHT_EDGE_COL (W) \ 701 (WINDOW_RIGHT_EDGE_COL (W) \
650 - WINDOW_RIGHT_SCROLL_BAR_COLS (W)) 702 - WINDOW_RIGHT_SCROLL_BAR_COLS (W))
@@ -706,114 +758,108 @@ wset_next_buffers (struct window *w, Lisp_Object val)
706#define WINDOW_FRINGES_WIDTH(W) \ 758#define WINDOW_FRINGES_WIDTH(W) \
707 (WINDOW_LEFT_FRINGE_WIDTH (W) + WINDOW_RIGHT_FRINGE_WIDTH (W)) 759 (WINDOW_LEFT_FRINGE_WIDTH (W) + WINDOW_RIGHT_FRINGE_WIDTH (W))
708 760
709/* Widths of fringes in columns. */
710#define WINDOW_FRINGE_COLS(W) \
711 ((W->left_fringe_width >= 0 \
712 && W->right_fringe_width >= 0) \
713 ? ((WINDOW_FRINGES_WIDTH (W) \
714 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
715 / WINDOW_FRAME_COLUMN_WIDTH (W)) \
716 : FRAME_FRINGE_COLS (WINDOW_XFRAME (W)))
717
718#define WINDOW_LEFT_FRINGE_COLS(W) \
719 ((WINDOW_LEFT_FRINGE_WIDTH ((W)) \
720 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
721 / WINDOW_FRAME_COLUMN_WIDTH (W))
722
723#define WINDOW_RIGHT_FRINGE_COLS(W) \
724 ((WINDOW_RIGHT_FRINGE_WIDTH ((W)) \
725 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
726 / WINDOW_FRAME_COLUMN_WIDTH (W))
727
728/* Are fringes outside display margins in window W. */ 761/* Are fringes outside display margins in window W. */
729#define WINDOW_HAS_FRINGES_OUTSIDE_MARGINS(W) \ 762#define WINDOW_HAS_FRINGES_OUTSIDE_MARGINS(W) \
730 ((W)->fringes_outside_margins) 763 ((W)->fringes_outside_margins)
731 764
732/* Say whether scroll bars are currently enabled for window W, 765/* Say whether vertical scroll bars are currently enabled for window W,
733 and which side they are on. */ 766 and which side they are on. */
734#define WINDOW_VERTICAL_SCROLL_BAR_TYPE(w) \ 767#define WINDOW_VERTICAL_SCROLL_BAR_TYPE(W) \
735 (EQ (w->vertical_scroll_bar_type, Qt) \ 768 (WINDOW_PSEUDO_P (W) \
736 ? FRAME_VERTICAL_SCROLL_BAR_TYPE (WINDOW_XFRAME (w)) \ 769 ? vertical_scroll_bar_none \
737 : EQ (w->vertical_scroll_bar_type, Qleft) \ 770 : EQ (W->vertical_scroll_bar_type, Qt) \
771 ? FRAME_VERTICAL_SCROLL_BAR_TYPE (WINDOW_XFRAME (W)) \
772 : EQ (W->vertical_scroll_bar_type, Qleft) \
738 ? vertical_scroll_bar_left \ 773 ? vertical_scroll_bar_left \
739 : EQ (w->vertical_scroll_bar_type, Qright) \ 774 : EQ (W->vertical_scroll_bar_type, Qright) \
740 ? vertical_scroll_bar_right \ 775 ? vertical_scroll_bar_right \
741 : vertical_scroll_bar_none) \ 776 : vertical_scroll_bar_none)
742 777
743#define WINDOW_HAS_VERTICAL_SCROLL_BAR(w) \ 778#define WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT(W) \
744 (EQ (w->vertical_scroll_bar_type, Qt) \ 779 (WINDOW_VERTICAL_SCROLL_BAR_TYPE (W) == vertical_scroll_bar_left)
745 ? FRAME_HAS_VERTICAL_SCROLL_BARS (WINDOW_XFRAME (w)) \ 780
746 : !NILP (w->vertical_scroll_bar_type)) 781#define WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT(W) \
747 782 (WINDOW_VERTICAL_SCROLL_BAR_TYPE (W) == vertical_scroll_bar_right)
748#define WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT(w) \ 783
749 (EQ (w->vertical_scroll_bar_type, Qt) \ 784#define WINDOW_HAS_VERTICAL_SCROLL_BAR(W) \
750 ? FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (WINDOW_XFRAME (w)) \ 785 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (W) \
751 : EQ (w->vertical_scroll_bar_type, Qleft)) 786 || WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W))
752 787
753#define WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT(w) \ 788/* Say whether horizontal scroll bars are currently enabled for window
754 (EQ (w->vertical_scroll_bar_type, Qt) \ 789 W. Horizontal scrollbars exist for toolkit versions only. */
755 ? FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (WINDOW_XFRAME (w)) \ 790#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
756 : EQ (w->vertical_scroll_bar_type, Qright)) 791#define WINDOW_HAS_HORIZONTAL_SCROLL_BAR(W) \
792 ((WINDOW_PSEUDO_P (W) || MINI_NON_ONLY_WINDOW_P (W)) \
793 ? false \
794 : EQ (W->horizontal_scroll_bar_type, Qt) \
795 ? FRAME_HAS_HORIZONTAL_SCROLL_BARS (WINDOW_XFRAME (W)) \
796 : EQ (W->horizontal_scroll_bar_type, Qbottom) \
797 ? true \
798 : false)
799#else
800#define WINDOW_HAS_HORIZONTAL_SCROLL_BAR(W) false
801#endif
757 802
758/* Width that a scroll bar in window W should have, if there is one. 803/* Width that a scroll bar in window W should have, if there is one.
759 Measured in pixels. If scroll bars are turned off, this is still 804 Measured in pixels. If scroll bars are turned off, this is still
760 nonzero. */ 805 nonzero. */
761#define WINDOW_CONFIG_SCROLL_BAR_WIDTH(w) \ 806#define WINDOW_CONFIG_SCROLL_BAR_WIDTH(W) \
762 (w->scroll_bar_width >= 0 \ 807 (W->scroll_bar_width >= 0 \
763 ? w->scroll_bar_width \ 808 ? W->scroll_bar_width \
764 : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (w))) 809 : FRAME_CONFIG_SCROLL_BAR_WIDTH (WINDOW_XFRAME (W)))
765 810
766/* Width that a scroll bar in window W should have, if there is one. 811/* Width that a scroll bar in window W should have, if there is one.
767 Measured in columns (characters). If scroll bars are turned off, 812 Measured in columns (characters). If scroll bars are turned off,
768 this is still nonzero. */ 813 this is still nonzero. */
769#define WINDOW_CONFIG_SCROLL_BAR_COLS(w) \ 814#define WINDOW_CONFIG_SCROLL_BAR_COLS(W) \
770 (w->scroll_bar_width >= 0 \ 815 (W->scroll_bar_width >= 0 \
771 ? ((w->scroll_bar_width \ 816 ? ((W->scroll_bar_width \
772 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) \ 817 + WINDOW_FRAME_COLUMN_WIDTH (W) - 1) \
773 / WINDOW_FRAME_COLUMN_WIDTH (w)) \ 818 / WINDOW_FRAME_COLUMN_WIDTH (W)) \
774 : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (w))) 819 : FRAME_CONFIG_SCROLL_BAR_COLS (WINDOW_XFRAME (W)))
775 820
776/* Width of left scroll bar in window W, measured in columns 821/* Width of left scroll bar in window W, measured in columns
777 (characters). If scroll bars are on the right in this frame, or 822 (characters). If scroll bars are on the right in this frame, or
778 there are no scroll bars, value is 0. */ 823 there are no scroll bars, value is 0. */
779#define WINDOW_LEFT_SCROLL_BAR_COLS(w) \ 824#define WINDOW_LEFT_SCROLL_BAR_COLS(W) \
780 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \ 825 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (W) \
781 ? (WINDOW_CONFIG_SCROLL_BAR_COLS (w)) \ 826 ? (WINDOW_CONFIG_SCROLL_BAR_COLS (W)) \
782 : 0) 827 : 0)
783 828
784/* Width of right scroll bar in window W, measured in columns 829/* Width of right scroll bar in window W, measured in columns
785 (characters). If scroll bars are on the left in this frame, or there 830 (characters). If scroll bars are on the left in this frame, or there
786 are no scroll bars, value is 0. */ 831 are no scroll bars, value is 0. */
787#define WINDOW_RIGHT_SCROLL_BAR_COLS(w) \ 832#define WINDOW_RIGHT_SCROLL_BAR_COLS(W) \
788 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \ 833 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W) \
789 ? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \ 834 ? WINDOW_CONFIG_SCROLL_BAR_COLS (W) \
790 : 0) 835 : 0)
791 836
792/* Width of a scroll bar in window W, measured in columns. */ 837/* Width of a scroll bar in window W, measured in columns. */
793#define WINDOW_SCROLL_BAR_COLS(w) \ 838#define WINDOW_SCROLL_BAR_COLS(W) \
794 (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \ 839 (WINDOW_HAS_VERTICAL_SCROLL_BAR (W) \
795 ? WINDOW_CONFIG_SCROLL_BAR_COLS (w) \ 840 ? WINDOW_CONFIG_SCROLL_BAR_COLS (W) \
796 : 0) 841 : 0)
797 842
798/* Width of a left scroll bar area in window W, measured in pixels. */ 843/* Width of a left scroll bar area in window W, measured in pixels. */
799#define WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH(w) \ 844#define WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH(W) \
800 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \ 845 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (W) \
801 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \ 846 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (W) \
802 : 0) 847 : 0)
803 848
804/* Width of a right scroll bar area in window W, measured in pixels. */ 849/* Width of a right scroll bar area in window W, measured in pixels. */
805#define WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH(w) \ 850#define WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH(W) \
806 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w) \ 851 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W) \
807 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \ 852 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (W) \
808 : 0) 853 : 0)
809 854
810/* Width of scroll bar area in window W, measured in pixels. */ 855/* Width of scroll bar area in window W, measured in pixels. */
811#define WINDOW_SCROLL_BAR_AREA_WIDTH(w) \ 856#define WINDOW_SCROLL_BAR_AREA_WIDTH(W) \
812 (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) \ 857 (WINDOW_HAS_VERTICAL_SCROLL_BAR (W) \
813 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) \ 858 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (W) \
814 : 0) 859 : 0)
815 860
816/* Return the frame position where the scroll bar of window W starts. */ 861/* Return the frame position where the vertical scroll bar of window W
862 starts. */
817#define WINDOW_SCROLL_BAR_AREA_X(W) \ 863#define WINDOW_SCROLL_BAR_AREA_X(W) \
818 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W) \ 864 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (W) \
819 ? WINDOW_BOX_RIGHT_EDGE_X (W) \ 865 ? WINDOW_BOX_RIGHT_EDGE_X (W) \
@@ -829,6 +875,36 @@ wset_next_buffers (struct window *w, Lisp_Object val)
829 ? 0 \ 875 ? 0 \
830 : FRAME_BOTTOM_DIVIDER_WIDTH (WINDOW_XFRAME (W))) 876 : FRAME_BOTTOM_DIVIDER_WIDTH (WINDOW_XFRAME (W)))
831 877
878/* Height that a scroll bar in window W should have, if there is one.
879 Measured in pixels. If scroll bars are turned off, this is still
880 nonzero. */
881#define WINDOW_CONFIG_SCROLL_BAR_HEIGHT(W) \
882 (W->scroll_bar_height >= 0 \
883 ? W->scroll_bar_height \
884 : FRAME_CONFIG_SCROLL_BAR_HEIGHT (WINDOW_XFRAME (W)))
885
886/* Height that a scroll bar in window W should have, if there is one.
887 Measured in lines (characters). If scroll bars are turned off, this
888 is still nonzero. */
889#define WINDOW_CONFIG_SCROLL_BAR_LINES(W) \
890 (W->scroll_bar_height >= 0 \
891 ? ((W->scroll_bar_height \
892 + WINDOW_FRAME_LINE_HEIGHT (W) - 1) \
893 / WINDOW_FRAME_LINE_HEIGHT (W)) \
894 : FRAME_CONFIG_SCROLL_BAR_LINES (WINDOW_XFRAME (W)))
895
896/* Height of a scroll bar in window W, measured in columns. */
897#define WINDOW_SCROLL_BAR_LINES(W) \
898 (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (W) \
899 ? WINDOW_CONFIG_SCROLL_BAR_LINES (W) \
900 : 0)
901
902/* Height of scroll bar area in window W, measured in pixels. */
903#define WINDOW_SCROLL_BAR_AREA_HEIGHT(W) \
904 (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (W) \
905 ? WINDOW_CONFIG_SCROLL_BAR_HEIGHT (W) \
906 : 0)
907
832/* Height in pixels, and in lines, of the mode line. 908/* Height in pixels, and in lines, of the mode line.
833 May be zero if W doesn't have a mode line. */ 909 May be zero if W doesn't have a mode line. */
834#define WINDOW_MODE_LINE_HEIGHT(W) \ 910#define WINDOW_MODE_LINE_HEIGHT(W) \
@@ -837,67 +913,63 @@ wset_next_buffers (struct window *w, Lisp_Object val)
837 : 0) 913 : 0)
838 914
839#define WINDOW_MODE_LINE_LINES(W) \ 915#define WINDOW_MODE_LINE_LINES(W) \
840 (!! WINDOW_WANTS_MODELINE_P ((W))) 916 (!! WINDOW_WANTS_MODELINE_P (W))
841 917
842/* Height in pixels, and in lines, of the header line. 918/* Height in pixels, and in lines, of the header line.
843 Zero if W doesn't have a header line. */ 919 Zero if W doesn't have a header line. */
844#define WINDOW_HEADER_LINE_HEIGHT(W) \ 920#define WINDOW_HEADER_LINE_HEIGHT(W) \
845 (WINDOW_WANTS_HEADER_LINE_P ((W)) \ 921 (WINDOW_WANTS_HEADER_LINE_P (W) \
846 ? CURRENT_HEADER_LINE_HEIGHT (W) \ 922 ? CURRENT_HEADER_LINE_HEIGHT (W) \
847 : 0) 923 : 0)
848 924
849#define WINDOW_HEADER_LINE_LINES(W) \ 925#define WINDOW_HEADER_LINE_LINES(W) \
850 (!! WINDOW_WANTS_HEADER_LINE_P ((W))) 926 (!! WINDOW_WANTS_HEADER_LINE_P (W))
851 927
852/* Pixel height of window W without mode line and bottom divider. */ 928/* Pixel height of window W without mode line, bottom scroll bar and
929 bottom divider. */
853#define WINDOW_BOX_HEIGHT_NO_MODE_LINE(W) \ 930#define WINDOW_BOX_HEIGHT_NO_MODE_LINE(W) \
854 (WINDOW_PIXEL_HEIGHT ((W)) \ 931 (WINDOW_PIXEL_HEIGHT (W) \
855 - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \ 932 - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \
856 - WINDOW_MODE_LINE_HEIGHT ((W))) 933 - WINDOW_SCROLL_BAR_AREA_HEIGHT (W) \
934 - WINDOW_MODE_LINE_HEIGHT (W))
857 935
858/* Pixel height of window W without mode and header line and bottom 936/* Pixel height of window W without mode and header line and bottom
859 divider. */ 937 divider. */
860#define WINDOW_BOX_TEXT_HEIGHT(W) \ 938#define WINDOW_BOX_TEXT_HEIGHT(W) \
861 (WINDOW_PIXEL_HEIGHT ((W)) \ 939 (WINDOW_PIXEL_HEIGHT ((W)) \
862 - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \ 940 - WINDOW_BOTTOM_DIVIDER_WIDTH (W) \
863 - WINDOW_MODE_LINE_HEIGHT ((W)) \ 941 - WINDOW_SCROLL_BAR_AREA_HEIGHT (W) \
864 - WINDOW_HEADER_LINE_HEIGHT ((W))) 942 - WINDOW_MODE_LINE_HEIGHT (W) \
943 - WINDOW_HEADER_LINE_HEIGHT (W))
944
945/* Return the frame position where the horizontal scroll bar of window W
946 starts. */
947#define WINDOW_SCROLL_BAR_AREA_Y(W) \
948 (WINDOW_TOP_EDGE_Y (W) \
949 + (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (W) \
950 ? WINDOW_BOX_HEIGHT_NO_MODE_LINE (W) : 0))
865 951
866/* Convert window W relative pixel X to frame pixel coordinates. */ 952/* Convert window W relative pixel X to frame pixel coordinates. */
867#define WINDOW_TO_FRAME_PIXEL_X(W, X) \ 953#define WINDOW_TO_FRAME_PIXEL_X(W, X) \
868 ((X) + WINDOW_BOX_LEFT_EDGE_X ((W))) 954 ((X) + WINDOW_BOX_LEFT_EDGE_X ((W)))
869 955
870/* Convert window W relative pixel Y to frame pixel coordinates. */ 956/* Convert window W relative pixel Y to frame pixel coordinates. */
871#define WINDOW_TO_FRAME_PIXEL_Y(W, Y) \ 957#define WINDOW_TO_FRAME_PIXEL_Y(W, Y) \
872 ((Y) + WINDOW_TOP_EDGE_Y ((W))) 958 ((Y) + WINDOW_TOP_EDGE_Y (W))
873 959
874/* Convert frame relative pixel X to window relative pixel X. */ 960/* Convert frame relative pixel X to window relative pixel X. */
875#define FRAME_TO_WINDOW_PIXEL_X(W, X) \ 961#define FRAME_TO_WINDOW_PIXEL_X(W, X) \
876 ((X) - WINDOW_BOX_LEFT_EDGE_X ((W))) 962 ((X) - WINDOW_BOX_LEFT_EDGE_X ((W)))
877 963
878/* Convert frame relative pixel Y to window relative pixel Y. */ 964/* Convert frame relative pixel Y to window relative pixel Y. */
879#define FRAME_TO_WINDOW_PIXEL_Y(W, Y) \ 965#define FRAME_TO_WINDOW_PIXEL_Y(W, Y) \
880 ((Y) - WINDOW_TOP_EDGE_Y ((W))) 966 ((Y) - WINDOW_TOP_EDGE_Y (W))
881 967
882/* Convert a text area relative x-position in window W to frame X 968/* Convert a text area relative x-position in window W to frame X
883 pixel coordinates. */ 969 pixel coordinates. */
884#define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ 970#define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \
885 (window_box_left ((W), TEXT_AREA) + (X)) 971 (window_box_left ((W), TEXT_AREA) + (X))
886 972
887/* True if the background of the window W's fringe that is adjacent to
888 a scroll bar is extended to the gap between the fringe and the bar. */
889
890#define WINDOW_FRINGE_EXTENDED_P(w) \
891 (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) \
892 ? (WINDOW_LEFTMOST_P (w) \
893 && WINDOW_LEFT_FRINGE_WIDTH (w) \
894 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \
895 || WINDOW_LEFT_MARGIN_COLS (w) == 0)) \
896 : (WINDOW_RIGHTMOST_P (w) \
897 && WINDOW_RIGHT_FRINGE_WIDTH (w) \
898 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) \
899 || WINDOW_RIGHT_MARGIN_COLS (w) == 0)))
900
901/* This is the window in which the terminal's cursor should be left when 973/* This is the window in which the terminal's cursor should be left when
902 nothing is being done with it. This must always be a leaf window, and its 974 nothing is being done with it. This must always be a leaf window, and its
903 buffer is selected by the top level editing loop at the end of each command. 975 buffer is selected by the top level editing loop at the end of each command.
@@ -981,11 +1053,6 @@ extern void bset_update_mode_line (struct buffer *b);
981 above already does it, so it's only needed in unusual cases. */ 1053 above already does it, so it's only needed in unusual cases. */
982extern void redisplay_other_windows (void); 1054extern void redisplay_other_windows (void);
983 1055
984/* If *ROWS or *COLS are too small a size for FRAME, set them to the
985 minimum allowable size. */
986
987extern void check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise);
988
989/* Return a pointer to the glyph W's physical cursor is on. Value is 1056/* Return a pointer to the glyph W's physical cursor is on. Value is
990 null if W's current matrix is invalid, so that no meaningful glyph 1057 null if W's current matrix is invalid, so that no meaningful glyph
991 can be returned. */ 1058 can be returned. */
@@ -1010,7 +1077,6 @@ struct glyph *get_phys_cursor_glyph (struct window *w);
1010 CHECK_TYPE (WINDOW_LIVE_P (WINDOW), Qwindow_live_p, WINDOW) 1077 CHECK_TYPE (WINDOW_LIVE_P (WINDOW), Qwindow_live_p, WINDOW)
1011 1078
1012/* These used to be in lisp.h. */ 1079/* These used to be in lisp.h. */
1013
1014extern Lisp_Object Qwindow_live_p; 1080extern Lisp_Object Qwindow_live_p;
1015extern Lisp_Object Vwindow_list; 1081extern Lisp_Object Vwindow_list;
1016 1082
@@ -1024,6 +1090,7 @@ extern int window_body_width (struct window *w, bool);
1024extern void temp_output_buffer_show (Lisp_Object); 1090extern void temp_output_buffer_show (Lisp_Object);
1025extern void replace_buffer_in_windows (Lisp_Object); 1091extern void replace_buffer_in_windows (Lisp_Object);
1026extern void replace_buffer_in_windows_safely (Lisp_Object); 1092extern void replace_buffer_in_windows_safely (Lisp_Object);
1093extern Lisp_Object sanitize_window_sizes (Lisp_Object, Lisp_Object);
1027/* This looks like a setter, but it is a bit special. */ 1094/* This looks like a setter, but it is a bit special. */
1028extern void wset_buffer (struct window *, Lisp_Object); 1095extern void wset_buffer (struct window *, Lisp_Object);
1029extern bool window_outdated (struct window *); 1096extern bool window_outdated (struct window *);
diff --git a/src/xdisp.c b/src/xdisp.c
index cf027a2b72e..bbe810d1a08 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1024,6 +1024,8 @@ window_text_bottom_y (struct window *w)
1024 if (WINDOW_WANTS_MODELINE_P (w)) 1024 if (WINDOW_WANTS_MODELINE_P (w))
1025 height -= CURRENT_MODE_LINE_HEIGHT (w); 1025 height -= CURRENT_MODE_LINE_HEIGHT (w);
1026 1026
1027 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1028
1027 return height; 1029 return height;
1028} 1030}
1029 1031
@@ -1068,6 +1070,7 @@ window_box_height (struct window *w)
1068 eassert (height >= 0); 1070 eassert (height >= 0);
1069 1071
1070 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w); 1072 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
1073 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
1071 1074
1072 /* Note: the code below that determines the mode-line/header-line 1075 /* Note: the code below that determines the mode-line/header-line
1073 height is essentially the same as that contained in the macro 1076 height is essentially the same as that contained in the macro
@@ -1954,8 +1957,8 @@ pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
1954 1957
1955 if (pix_y < 0) 1958 if (pix_y < 0)
1956 pix_y = 0; 1959 pix_y = 0;
1957 else if (pix_y > FRAME_LINES (f)) 1960 else if (pix_y > FRAME_TOTAL_LINES (f))
1958 pix_y = FRAME_LINES (f); 1961 pix_y = FRAME_TOTAL_LINES (f);
1959 } 1962 }
1960 } 1963 }
1961#endif 1964#endif
@@ -2498,7 +2501,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2498 gx = WINDOW_PIXEL_WIDTH (w) - width; 2501 gx = WINDOW_PIXEL_WIDTH (w) - width;
2499 goto row_glyph; 2502 goto row_glyph;
2500 2503
2501 case ON_SCROLL_BAR: 2504 case ON_VERTICAL_SCROLL_BAR:
2502 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) 2505 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2503 ? 0 2506 ? 0
2504 : (window_box_right_offset (w, RIGHT_MARGIN_AREA) 2507 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
@@ -10521,6 +10524,7 @@ with_echo_area_buffer (struct window *w, int which,
10521 { 10524 {
10522 wset_buffer (w, buffer); 10525 wset_buffer (w, buffer);
10523 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE); 10526 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10527 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10524 } 10528 }
10525 10529
10526 bset_undo_list (current_buffer, Qt); 10530 bset_undo_list (current_buffer, Qt);
@@ -10559,7 +10563,7 @@ with_echo_area_buffer_unwind_data (struct window *w)
10559 Vwith_echo_area_save_vector = Qnil; 10563 Vwith_echo_area_save_vector = Qnil;
10560 10564
10561 if (NILP (vector)) 10565 if (NILP (vector))
10562 vector = Fmake_vector (make_number (9), Qnil); 10566 vector = Fmake_vector (make_number (11), Qnil);
10563 10567
10564 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i; 10568 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10565 ASET (vector, i, Vdeactivate_mark); ++i; 10569 ASET (vector, i, Vdeactivate_mark); ++i;
@@ -10571,12 +10575,14 @@ with_echo_area_buffer_unwind_data (struct window *w)
10571 ASET (vector, i, w->contents); ++i; 10575 ASET (vector, i, w->contents); ++i;
10572 ASET (vector, i, make_number (marker_position (w->pointm))); ++i; 10576 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10573 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i; 10577 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10578 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10579 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10574 ASET (vector, i, make_number (marker_position (w->start))); ++i; 10580 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10575 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i; 10581 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10576 } 10582 }
10577 else 10583 else
10578 { 10584 {
10579 int end = i + 6; 10585 int end = i + 8;
10580 for (; i < end; ++i) 10586 for (; i < end; ++i)
10581 ASET (vector, i, Qnil); 10587 ASET (vector, i, Qnil);
10582 } 10588 }
@@ -10608,9 +10614,12 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
10608 set_marker_both (w->pointm, buffer, 10614 set_marker_both (w->pointm, buffer,
10609 XFASTINT (AREF (vector, 5)), 10615 XFASTINT (AREF (vector, 5)),
10610 XFASTINT (AREF (vector, 6))); 10616 XFASTINT (AREF (vector, 6)));
10611 set_marker_both (w->start, buffer, 10617 set_marker_both (w->old_pointm, buffer,
10612 XFASTINT (AREF (vector, 7)), 10618 XFASTINT (AREF (vector, 7)),
10613 XFASTINT (AREF (vector, 8))); 10619 XFASTINT (AREF (vector, 8)));
10620 set_marker_both (w->start, buffer,
10621 XFASTINT (AREF (vector, 9)),
10622 XFASTINT (AREF (vector, 10)));
10614 } 10623 }
10615 10624
10616 Vwith_echo_area_save_vector = vector; 10625 Vwith_echo_area_save_vector = vector;
@@ -11885,7 +11894,7 @@ update_tool_bar (struct frame *f, int save_match_data)
11885 int do_update = FRAME_EXTERNAL_TOOL_BAR (f); 11894 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11886#else 11895#else
11887 int do_update = (WINDOWP (f->tool_bar_window) 11896 int do_update = (WINDOWP (f->tool_bar_window)
11888 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0); 11897 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
11889#endif 11898#endif
11890 11899
11891 if (do_update) 11900 if (do_update)
@@ -12269,16 +12278,9 @@ display_tool_bar_line (struct it *it, int height)
12269} 12278}
12270 12279
12271 12280
12272/* Max tool-bar height. Basically, this is what makes all other windows
12273 disappear when the frame gets too small. Rethink this! */
12274
12275#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
12276 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
12277
12278/* Value is the number of pixels needed to make all tool-bar items of 12281/* Value is the number of pixels needed to make all tool-bar items of
12279 frame F visible. The actual number of glyph rows needed is 12282 frame F visible. The actual number of glyph rows needed is
12280 returned in *N_ROWS if non-NULL. */ 12283 returned in *N_ROWS if non-NULL. */
12281
12282static int 12284static int
12283tool_bar_height (struct frame *f, int *n_rows, bool pixelwise) 12285tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12284{ 12286{
@@ -12347,7 +12349,6 @@ PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12347 12349
12348/* Display the tool-bar of frame F. Value is non-zero if tool-bar's 12350/* Display the tool-bar of frame F. Value is non-zero if tool-bar's
12349 height should be changed. */ 12351 height should be changed. */
12350
12351static int 12352static int
12352redisplay_tool_bar (struct frame *f) 12353redisplay_tool_bar (struct frame *f)
12353{ 12354{
@@ -12369,7 +12370,7 @@ redisplay_tool_bar (struct frame *f)
12369 can turn off tool-bars by specifying tool-bar-lines zero. */ 12370 can turn off tool-bars by specifying tool-bar-lines zero. */
12370 if (!WINDOWP (f->tool_bar_window) 12371 if (!WINDOWP (f->tool_bar_window)
12371 || (w = XWINDOW (f->tool_bar_window), 12372 || (w = XWINDOW (f->tool_bar_window),
12372 WINDOW_PIXEL_HEIGHT (w) == 0)) 12373 WINDOW_TOTAL_LINES (w) == 0))
12373 return 0; 12374 return 0;
12374 12375
12375 /* Set up an iterator for the tool-bar window. */ 12376 /* Set up an iterator for the tool-bar window. */
@@ -12396,14 +12397,7 @@ redisplay_tool_bar (struct frame *f)
12396 12397
12397 if (new_height != WINDOW_PIXEL_HEIGHT (w)) 12398 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12398 { 12399 {
12399 Lisp_Object frame; 12400 x_change_tool_bar_height (f, new_height);
12400 int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
12401 / FRAME_LINE_HEIGHT (f));
12402
12403 XSETFRAME (frame, f);
12404 Fmodify_frame_parameters (frame,
12405 list1 (Fcons (Qtool_bar_lines,
12406 make_number (new_lines))));
12407 /* Always do that now. */ 12401 /* Always do that now. */
12408 clear_glyph_matrix (w->desired_matrix); 12402 clear_glyph_matrix (w->desired_matrix);
12409 f->fonts_changed = 1; 12403 f->fonts_changed = 1;
@@ -12456,14 +12450,11 @@ redisplay_tool_bar (struct frame *f)
12456 12450
12457 if (!NILP (Vauto_resize_tool_bars)) 12451 if (!NILP (Vauto_resize_tool_bars))
12458 { 12452 {
12459 /* Do we really allow the toolbar to occupy the whole frame? */
12460 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12461 int change_height_p = 0; 12453 int change_height_p = 0;
12462 12454
12463 /* If we couldn't display everything, change the tool-bar's 12455 /* If we couldn't display everything, change the tool-bar's
12464 height if there is room for more. */ 12456 height if there is room for more. */
12465 if (IT_STRING_CHARPOS (it) < it.end_charpos 12457 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12466 && it.current_y < max_tool_bar_height)
12467 change_height_p = 1; 12458 change_height_p = 1;
12468 12459
12469 /* We subtract 1 because display_tool_bar_line advances the 12460 /* We subtract 1 because display_tool_bar_line advances the
@@ -12482,15 +12473,13 @@ redisplay_tool_bar (struct frame *f)
12482 /* If row displays tool-bar items, but is partially visible, 12473 /* If row displays tool-bar items, but is partially visible,
12483 change the tool-bar's height. */ 12474 change the tool-bar's height. */
12484 if (MATRIX_ROW_DISPLAYS_TEXT_P (row) 12475 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12485 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y 12476 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12486 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12487 change_height_p = 1; 12477 change_height_p = 1;
12488 12478
12489 /* Resize windows as needed by changing the `tool-bar-lines' 12479 /* Resize windows as needed by changing the `tool-bar-lines'
12490 frame parameter. */ 12480 frame parameter. */
12491 if (change_height_p) 12481 if (change_height_p)
12492 { 12482 {
12493 Lisp_Object frame;
12494 int nrows; 12483 int nrows;
12495 int new_height = tool_bar_height (f, &nrows, 1); 12484 int new_height = tool_bar_height (f, &nrows, 1);
12496 12485
@@ -12502,35 +12491,12 @@ redisplay_tool_bar (struct frame *f)
12502 12491
12503 if (change_height_p) 12492 if (change_height_p)
12504 { 12493 {
12505 /* Current size of the tool-bar window in canonical line 12494 x_change_tool_bar_height (f, new_height);
12506 units. */ 12495 clear_glyph_matrix (w->desired_matrix);
12507 int old_lines = WINDOW_TOTAL_LINES (w); 12496 f->n_tool_bar_rows = nrows;
12508 /* Required size of the tool-bar window in canonical 12497 f->fonts_changed = 1;
12509 line units. */ 12498
12510 int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1) 12499 return 1;
12511 / FRAME_LINE_HEIGHT (f));
12512 /* Maximum size of the tool-bar window in canonical line
12513 units that this frame can allow. */
12514 int max_lines =
12515 WINDOW_TOTAL_LINES (XWINDOW (FRAME_ROOT_WINDOW (f))) - 1;
12516
12517 /* Don't try to change the tool-bar window size and set
12518 the fonts_changed flag unless really necessary. That
12519 flag causes redisplay to give up and retry
12520 redisplaying the frame from scratch, so setting it
12521 unnecessarily can lead to nasty redisplay loops. */
12522 if (new_lines <= max_lines
12523 && eabs (new_lines - old_lines) >= 1)
12524 {
12525 XSETFRAME (frame, f);
12526 Fmodify_frame_parameters (frame,
12527 list1 (Fcons (Qtool_bar_lines,
12528 make_number (new_lines))));
12529 clear_glyph_matrix (w->desired_matrix);
12530 f->n_tool_bar_rows = nrows;
12531 f->fonts_changed = 1;
12532 return 1;
12533 }
12534 } 12500 }
12535 } 12501 }
12536 } 12502 }
@@ -12864,7 +12830,20 @@ hscroll_window_tree (Lisp_Object window)
12864 /* Scroll when cursor is inside this scroll margin. */ 12830 /* Scroll when cursor is inside this scroll margin. */
12865 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w); 12831 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12866 12832
12833 /* If the position of this window's point has explicitly
12834 changed, no more suspend auto hscrolling. */
12835 if (NILP (Fequal (Fwindow_point (window), Fwindow_old_point (window))))
12836 w->suspend_auto_hscroll = 0;
12837
12838 /* Remember window point. */
12839 Fset_marker (w->old_pointm,
12840 ((w == XWINDOW (selected_window))
12841 ? make_number (BUF_PT (XBUFFER (w->contents)))
12842 : Fmarker_position (w->pointm)),
12843 w->contents);
12844
12867 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents)) 12845 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
12846 && w->suspend_auto_hscroll == 0
12868 /* In some pathological cases, like restoring a window 12847 /* In some pathological cases, like restoring a window
12869 configuration into a frame that is much smaller than 12848 configuration into a frame that is much smaller than
12870 the one from which the configuration was saved, we 12849 the one from which the configuration was saved, we
@@ -12877,8 +12856,7 @@ hscroll_window_tree (Lisp_Object window)
12877 inside the left margin and the window is already 12856 inside the left margin and the window is already
12878 hscrolled. */ 12857 hscrolled. */
12879 && ((!row_r2l_p 12858 && ((!row_r2l_p
12880 && ((w->hscroll 12859 && ((w->hscroll && w->cursor.x <= h_margin)
12881 && w->cursor.x <= h_margin)
12882 || (cursor_row->enabled_p 12860 || (cursor_row->enabled_p
12883 && cursor_row->truncated_on_right_p 12861 && cursor_row->truncated_on_right_p
12884 && (w->cursor.x >= text_area_width - h_margin)))) 12862 && (w->cursor.x >= text_area_width - h_margin))))
@@ -15759,6 +15737,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
15759 return rc; 15737 return rc;
15760} 15738}
15761 15739
15740
15762void 15741void
15763set_vertical_scroll_bar (struct window *w) 15742set_vertical_scroll_bar (struct window *w)
15764{ 15743{
@@ -15797,6 +15776,60 @@ set_vertical_scroll_bar (struct window *w)
15797} 15776}
15798 15777
15799 15778
15779void
15780set_horizontal_scroll_bar (struct window *w)
15781{
15782 int start, end, whole, box_width;
15783
15784 if (!MINI_WINDOW_P (w)
15785 || (w == XWINDOW (minibuf_window)
15786 && NILP (echo_area_buffer[0])))
15787 {
15788 struct buffer *b = XBUFFER (w->contents);
15789 struct buffer *old_buffer = NULL;
15790 struct it it;
15791 struct text_pos startp;
15792
15793 if (b != current_buffer)
15794 {
15795 old_buffer = current_buffer;
15796 set_buffer_internal (b);
15797 }
15798
15799 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15800 start_display (&it, w, startp);
15801 it.last_visible_x = INT_MAX;
15802 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
15803 MOVE_TO_X | MOVE_TO_Y);
15804 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
15805 window_box_height (w), -1,
15806 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
15807
15808 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
15809 box_width = window_box_width (w, TEXT_AREA);
15810 end = start + box_width;
15811
15812 /* The following is needed to ensure that if after maximizing a
15813 window we get hscroll > 0, we can still drag the thumb to the
15814 left. */
15815 whole = max (whole, w->hscroll + box_width);
15816 whole = max (whole, end - start);
15817
15818 if (old_buffer)
15819 set_buffer_internal (old_buffer);
15820 }
15821 else
15822 start = end = whole = 0;
15823
15824 w->hscroll_whole = whole;
15825
15826 /* Indicate what this scroll bar ought to be displaying now. */
15827 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15828 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
15829 (w, end - start, whole, start);
15830}
15831
15832
15800/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only 15833/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15801 selected_window is redisplayed. 15834 selected_window is redisplayed.
15802 15835
@@ -16010,6 +16043,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16010 { 16043 {
16011 ptrdiff_t new_pt = marker_position (w->pointm); 16044 ptrdiff_t new_pt = marker_position (w->pointm);
16012 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm); 16045 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16046
16013 if (new_pt < BEGV) 16047 if (new_pt < BEGV)
16014 { 16048 {
16015 new_pt = BEGV; 16049 new_pt = BEGV;
@@ -16749,7 +16783,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16749 redisplay_tool_bar (f); 16783 redisplay_tool_bar (f);
16750#else 16784#else
16751 if (WINDOWP (f->tool_bar_window) 16785 if (WINDOWP (f->tool_bar_window)
16752 && (FRAME_TOOL_BAR_HEIGHT (f) > 0 16786 && (FRAME_TOOL_BAR_LINES (f) > 0
16753 || !NILP (Vauto_resize_tool_bars)) 16787 || !NILP (Vauto_resize_tool_bars))
16754 && redisplay_tool_bar (f)) 16788 && redisplay_tool_bar (f))
16755 ignore_mouse_drag_p = 1; 16789 ignore_mouse_drag_p = 1;
@@ -16789,10 +16823,15 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16789 ; 16823 ;
16790 finish_scroll_bars: 16824 finish_scroll_bars:
16791 16825
16792 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) 16826 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16793 { 16827 {
16794 /* Set the thumb's position and size. */ 16828 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16795 set_vertical_scroll_bar (w); 16829 /* Set the thumb's position and size. */
16830 set_vertical_scroll_bar (w);
16831
16832 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
16833 /* Set the thumb's position and size. */
16834 set_horizontal_scroll_bar (w);
16796 16835
16797 /* Note that we actually used the scroll bar attached to this 16836 /* Note that we actually used the scroll bar attached to this
16798 window, so it shouldn't be deleted at the end of redisplay. */ 16837 window, so it shouldn't be deleted at the end of redisplay. */
@@ -28990,7 +29029,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
28990 else 29029 else
28991 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 29030 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28992 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE 29031 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
28993 || part == ON_SCROLL_BAR) 29032 || part == ON_VERTICAL_SCROLL_BAR
29033 || part == ON_HORIZONTAL_SCROLL_BAR)
28994 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 29034 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28995 else 29035 else
28996 cursor = FRAME_X_OUTPUT (f)->text_cursor; 29036 cursor = FRAME_X_OUTPUT (f)->text_cursor;
@@ -29911,8 +29951,10 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
29911 if (w == 0 || h == 0) 29951 if (w == 0 || h == 0)
29912 { 29952 {
29913 r.x = r.y = 0; 29953 r.x = r.y = 0;
29914 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); 29954 r.width = FRAME_TEXT_WIDTH (f);
29915 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); 29955 r.height = FRAME_TEXT_HEIGHT (f);
29956/** r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); **/
29957/** r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); **/
29916 } 29958 }
29917 else 29959 else
29918 { 29960 {
@@ -30198,8 +30240,9 @@ A value of nil means no special handling of these characters. */);
30198 30240
30199 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer, 30241 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
30200 doc: /* The pointer shape to show in void text areas. 30242 doc: /* The pointer shape to show in void text areas.
30201A value of nil means to show the text pointer. Other options are `arrow', 30243A value of nil means to show the text pointer. Other options are
30202`text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */); 30244`arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
30245`hourglass'. */);
30203 Vvoid_text_area_pointer = Qarrow; 30246 Vvoid_text_area_pointer = Qarrow;
30204 30247
30205 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay, 30248 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
@@ -30694,10 +30737,10 @@ init_xdisp (void)
30694 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f); 30737 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
30695 r->total_cols = FRAME_COLS (f); 30738 r->total_cols = FRAME_COLS (f);
30696 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f); 30739 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
30697 r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f); 30740 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
30698 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f); 30741 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
30699 30742
30700 m->top_line = FRAME_LINES (f) - 1; 30743 m->top_line = FRAME_TOTAL_LINES (f) - 1;
30701 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f); 30744 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
30702 m->total_cols = FRAME_COLS (f); 30745 m->total_cols = FRAME_COLS (f);
30703 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f); 30746 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
diff --git a/src/xfns.c b/src/xfns.c
index 7d87ddbb2b4..1787d0297e6 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1009,7 +1009,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1009#else /* not USE_X_TOOLKIT && not USE_GTK */ 1009#else /* not USE_X_TOOLKIT && not USE_GTK */
1010 FRAME_MENU_BAR_LINES (f) = nlines; 1010 FRAME_MENU_BAR_LINES (f) = nlines;
1011 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f); 1011 FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1012 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1); 1012 adjust_frame_size (f, -1, -1, 2, 1);
1013 if (FRAME_X_WINDOW (f)) 1013 if (FRAME_X_WINDOW (f))
1014 x_clear_under_internal_border (f); 1014 x_clear_under_internal_border (f);
1015 1015
@@ -1064,10 +1064,6 @@ void
1064x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) 1064x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1065{ 1065{
1066 int nlines; 1066 int nlines;
1067#if ! defined (USE_GTK)
1068 int delta, root_height;
1069 int unit = FRAME_LINE_HEIGHT (f);
1070#endif
1071 1067
1072 /* Treat tool bars like menu bars. */ 1068 /* Treat tool bars like menu bars. */
1073 if (FRAME_MINIBUF_ONLY_P (f)) 1069 if (FRAME_MINIBUF_ONLY_P (f))
@@ -1079,11 +1075,18 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1079 else 1075 else
1080 nlines = 0; 1076 nlines = 0;
1081 1077
1082#ifdef USE_GTK 1078 x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1079}
1080
1083 1081
1082/* Set the pixel height of the tool bar of frame F to HEIGHT. */
1083void
1084x_change_tool_bar_height (struct frame *f, int height)
1085{
1086#ifdef USE_GTK
1084 FRAME_TOOL_BAR_LINES (f) = 0; 1087 FRAME_TOOL_BAR_LINES (f) = 0;
1085 FRAME_TOOL_BAR_HEIGHT (f) = 0; 1088 FRAME_TOOL_BAR_HEIGHT (f) = 0;
1086 if (nlines) 1089 if (height)
1087 { 1090 {
1088 FRAME_EXTERNAL_TOOL_BAR (f) = 1; 1091 FRAME_EXTERNAL_TOOL_BAR (f) = 1;
1089 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0) 1092 if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
@@ -1097,39 +1100,25 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1097 free_frame_tool_bar (f); 1100 free_frame_tool_bar (f);
1098 FRAME_EXTERNAL_TOOL_BAR (f) = 0; 1101 FRAME_EXTERNAL_TOOL_BAR (f) = 0;
1099 } 1102 }
1100
1101#else /* !USE_GTK */ 1103#else /* !USE_GTK */
1104 int unit = FRAME_LINE_HEIGHT (f);
1105 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1106 int lines = (height + unit - 1) / unit;
1102 1107
1103 /* Make sure we redisplay all windows in this frame. */ 1108 /* Make sure we redisplay all windows in this frame. */
1104 windows_or_buffers_changed = 60; 1109 windows_or_buffers_changed = 60;
1105 1110
1106 /* DELTA is in pixels now. */
1107 delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
1108 1111
1109 /* Don't resize the tool-bar to more than we have room for. Note: The 1112 /* Recalculate tool bar and frame text sizes. */
1110 calculations below and the subsequent call to resize_frame_windows 1113 FRAME_TOOL_BAR_HEIGHT (f) = height;
1111 are inherently flawed because they can make the toolbar higher than 1114 FRAME_TOOL_BAR_LINES (f) = lines;
1112 the containing frame. */ 1115 FRAME_TEXT_HEIGHT (f)
1113 if (delta > 0) 1116 = FRAME_PIXEL_TO_TEXT_HEIGHT (f, FRAME_PIXEL_HEIGHT (f));
1114 { 1117 FRAME_LINES (f)
1115 root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f))); 1118 = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f));
1116 if (root_height - delta < unit) 1119 /* Store the `tool-bar-lines' and `height' frame parameters. */
1117 { 1120 store_frame_param (f, Qtool_bar_lines, make_number (lines));
1118 delta = root_height - unit; 1121 store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
1119 /* When creating a new frame and toolbar mode is enabled, we
1120 need at least one toolbar line. */
1121 nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1);
1122 }
1123 }
1124
1125 FRAME_TOOL_BAR_LINES (f) = nlines;
1126 FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
1127 resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
1128#if !defined USE_X_TOOLKIT && !defined USE_GTK
1129 if (FRAME_X_WINDOW (f))
1130 x_clear_under_internal_border (f);
1131#endif
1132 adjust_frame_glyphs (f);
1133 1122
1134 /* We also have to make sure that the internal border at the top of 1123 /* We also have to make sure that the internal border at the top of
1135 the frame, below the menu bar or tool bar, is redrawn when the 1124 the frame, below the menu bar or tool bar, is redrawn when the
@@ -1143,30 +1132,52 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1143 clear_current_matrices (f); 1132 clear_current_matrices (f);
1144 } 1133 }
1145 1134
1146 /* If the tool bar gets smaller, the internal border below it 1135 if ((height < old_height) && WINDOWP (f->tool_bar_window))
1147 has to be cleared. It was formerly part of the display 1136 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1148 of the larger tool bar, and updating windows won't clear it. */ 1137
1149 if (delta < 0) 1138 /* Recalculate toolbar height. */
1139 f->n_tool_bar_rows = 0;
1140
1141 adjust_frame_size (f, -1, -1, 4, 0);
1142
1143/** #if !defined USE_X_TOOLKIT **/
1144 if (FRAME_X_WINDOW (f))
1145 x_clear_under_internal_border (f);
1146/** #endif **/
1147
1148#endif /* USE_GTK */
1149}
1150
1151
1152void
1153x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1154{
1155 int border;
1156
1157 CHECK_TYPE_RANGED_INTEGER (int, arg);
1158 border = max (XINT (arg), 0);
1159
1160 if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
1150 { 1161 {
1151 int height = FRAME_INTERNAL_BORDER_WIDTH (f); 1162 FRAME_INTERNAL_BORDER_WIDTH (f) = border;
1152 int width = FRAME_PIXEL_WIDTH (f);
1153 int y = nlines * unit;
1154 1163
1155 /* height can be zero here. */ 1164#ifdef USE_X_TOOLKIT
1156 if (height > 0 && width > 0) 1165 if (FRAME_X_OUTPUT (f)->edit_widget)
1166 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
1167#endif
1168
1169 if (FRAME_X_WINDOW (f) != 0)
1157 { 1170 {
1158 block_input (); 1171 adjust_frame_size (f, -1, -1, 3, 0);
1159 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
1160 0, y, width, height);
1161 unblock_input ();
1162 }
1163 1172
1164 if (WINDOWP (f->tool_bar_window)) 1173#ifdef USE_GTK
1165 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); 1174 xg_clear_under_internal_border (f);
1175#else
1176 x_clear_under_internal_border (f);
1177#endif
1178 }
1166 } 1179 }
1167 1180
1168 run_window_configuration_change_hook (f);
1169#endif /* USE_GTK */
1170} 1181}
1171 1182
1172 1183
@@ -1508,14 +1519,36 @@ x_set_scroll_bar_default_width (struct frame *f)
1508 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit; 1519 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
1509 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw; 1520 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
1510#else 1521#else
1511 /* The width of a non-toolkit scrollbar is at least 14 pixels and a 1522 /* The width of a non-toolkit scrollbar is 14 pixels. */
1512 multiple of the frame's character width. */
1513 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit; 1523 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
1514 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) 1524 FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
1515 = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit; 1525 = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
1516#endif 1526#endif
1517} 1527}
1518 1528
1529void
1530x_set_scroll_bar_default_height (struct frame *f)
1531{
1532 int height = FRAME_LINE_HEIGHT (f);
1533#ifdef USE_TOOLKIT_SCROLL_BARS
1534#ifdef USE_GTK
1535 int min_height = xg_get_default_scrollbar_height ();
1536#else
1537 int min_height = 16;
1538#endif
1539 /* A minimum height of 14 doesn't look good for toolkit scroll bars. */
1540 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
1541 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
1542#else
1543 /* The height of a non-toolkit scrollbar is 14 pixels. */
1544 FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
1545
1546 /* Use all of that space (aside from required margins) for the
1547 scroll bar. */
1548 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = 14;
1549#endif
1550}
1551
1519 1552
1520/* Record in frame F the specified or default value according to ALIST 1553/* Record in frame F the specified or default value according to ALIST
1521 of the parameter named PROP (a Lisp symbol). If no value is 1554 of the parameter named PROP (a Lisp symbol). If no value is
@@ -2756,12 +2789,6 @@ do_unwind_create_frame (Lisp_Object frame)
2756} 2789}
2757 2790
2758static void 2791static void
2759unwind_create_frame_1 (Lisp_Object val)
2760{
2761 inhibit_lisp_code = val;
2762}
2763
2764static void
2765x_default_font_parameter (struct frame *f, Lisp_Object parms) 2792x_default_font_parameter (struct frame *f, Lisp_Object parms)
2766{ 2793{
2767 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); 2794 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
@@ -2865,12 +2892,11 @@ set_machine_and_pid_properties (struct frame *f)
2865DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 2892DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2866 1, 1, 0, 2893 1, 1, 0,
2867 doc: /* Make a new X window, which is called a "frame" in Emacs terms. 2894 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
2868Return an Emacs frame object. 2895Return an Emacs frame object. PARMS is an alist of frame parameters.
2869PARMS is an alist of frame parameters.
2870If the parameters specify that the frame should not have a minibuffer, 2896If the parameters specify that the frame should not have a minibuffer,
2871and do not specify a specific minibuffer window to use, 2897and do not specify a specific minibuffer window to use, then
2872then `default-minibuffer-frame' must be a frame whose minibuffer can 2898`default-minibuffer-frame' must be a frame whose minibuffer can be
2873be shared by the new frame. 2899shared by the new frame.
2874 2900
2875This function is an internal primitive--use `make-frame' instead. */) 2901This function is an internal primitive--use `make-frame' instead. */)
2876 (Lisp_Object parms) 2902 (Lisp_Object parms)
@@ -2880,7 +2906,6 @@ This function is an internal primitive--use `make-frame' instead. */)
2880 Lisp_Object name; 2906 Lisp_Object name;
2881 int minibuffer_only = 0; 2907 int minibuffer_only = 0;
2882 long window_prompting = 0; 2908 long window_prompting = 0;
2883 int width, height;
2884 ptrdiff_t count = SPECPDL_INDEX (); 2909 ptrdiff_t count = SPECPDL_INDEX ();
2885 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 2910 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2886 Lisp_Object display; 2911 Lisp_Object display;
@@ -3002,7 +3027,6 @@ This function is an internal primitive--use `make-frame' instead. */)
3002 } 3027 }
3003 3028
3004 /* Specify the parent under which to make this X window. */ 3029 /* Specify the parent under which to make this X window. */
3005
3006 if (!NILP (parent)) 3030 if (!NILP (parent))
3007 { 3031 {
3008 f->output_data.x->parent_desc = (Window) XFASTINT (parent); 3032 f->output_data.x->parent_desc = (Window) XFASTINT (parent);
@@ -3025,7 +3049,7 @@ This function is an internal primitive--use `make-frame' instead. */)
3025 { 3049 {
3026 fset_name (f, name); 3050 fset_name (f, name);
3027 f->explicit_name = 1; 3051 f->explicit_name = 1;
3028 /* use the frame's title when getting resources for this frame. */ 3052 /* Use the frame's title when getting resources for this frame. */
3029 specbind (Qx_resource_name, name); 3053 specbind (Qx_resource_name, name);
3030 } 3054 }
3031 3055
@@ -3088,6 +3112,14 @@ This function is an internal primitive--use `make-frame' instead. */)
3088#endif 3112#endif
3089 "verticalScrollBars", "ScrollBars", 3113 "verticalScrollBars", "ScrollBars",
3090 RES_TYPE_SYMBOL); 3114 RES_TYPE_SYMBOL);
3115 x_default_parameter (f, parms, Qhorizontal_scroll_bars,
3116#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
3117 Qt,
3118#else
3119 Qnil,
3120#endif
3121 "horizontalScrollBars", "ScrollBars",
3122 RES_TYPE_SYMBOL);
3091 3123
3092 /* Also do the stuff which must be set before the window exists. */ 3124 /* Also do the stuff which must be set before the window exists. */
3093 x_default_parameter (f, parms, Qforeground_color, build_string ("black"), 3125 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
@@ -3120,49 +3152,36 @@ This function is an internal primitive--use `make-frame' instead. */)
3120 dpyinfo_refcount = dpyinfo->reference_count; 3152 dpyinfo_refcount = dpyinfo->reference_count;
3121#endif /* GLYPH_DEBUG */ 3153#endif /* GLYPH_DEBUG */
3122 3154
3123 /* Init faces before x_default_parameter is called for scroll-bar 3155 /* Init faces before x_default_parameter is called for the
3124 parameters because that function calls x_set_scroll_bar_width, 3156 scroll-bar-width parameter because otherwise we end up in
3125 which calls change_frame_size, which calls Fset_window_buffer, 3157 init_iterator with a null face cache, which should not happen. */
3126 which runs hooks, which call Fvertical_motion. At the end, we
3127 end up in init_iterator with a null face cache, which should not
3128 happen. */
3129 init_frame_faces (f); 3158 init_frame_faces (f);
3130 3159
3131 /* PXW: This is a duplicate from below. We have to do it here since 3160 /* The following call of change_frame_size is needed since otherwise
3132 otherwise x_set_tool_bar_lines will work with the character sizes 3161 x_set_tool_bar_lines will already work with the character sizes
3133 installed by init_frame_faces while the frame's pixel size is still 3162 installed by init_frame_faces while the frame's pixel size is
3134 calculated from a character size of 1 and we subsequently hit the 3163 still calculated from a character size of 1 and we subsequently
3135 eassert (height >= 0) assertion in window_box_height. The 3164 hit the (height >= 0) assertion in window_box_height.
3136 non-pixelwise code apparently worked around this because it had one 3165
3137 frame line vs one toolbar line which left us with a zero root 3166 The non-pixelwise code apparently worked around this because it
3138 window height which was obviously wrong as well ... */ 3167 had one frame line vs one toolbar line which left us with a zero
3139 change_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 3168 root window height which was obviously wrong as well ... */
3140 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1, 0, 0, 1); 3169 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
3170 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1);
3141 3171
3142 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't 3172 /* Set the menu-bar-lines and tool-bar-lines parameters. We don't
3143 look up the X resources controlling the menu-bar and tool-bar 3173 look up the X resources controlling the menu-bar and tool-bar
3144 here; they are processed specially at startup, and reflected in 3174 here; they are processed specially at startup, and reflected in
3145 the values of the mode variables. 3175 the values of the mode variables. */
3146 3176
3147 Avoid calling window-configuration-change-hook; otherwise we 3177 x_default_parameter (f, parms, Qmenu_bar_lines,
3148 could get an infloop in next_frame since the frame is not yet in 3178 NILP (Vmenu_bar_mode)
3149 Vframe_list. */ 3179 ? make_number (0) : make_number (1),
3150 { 3180 NULL, NULL, RES_TYPE_NUMBER);
3151 ptrdiff_t count2 = SPECPDL_INDEX (); 3181 x_default_parameter (f, parms, Qtool_bar_lines,
3152 record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code); 3182 NILP (Vtool_bar_mode)
3153 inhibit_lisp_code = Qt; 3183 ? make_number (0) : make_number (1),
3154 3184 NULL, NULL, RES_TYPE_NUMBER);
3155 x_default_parameter (f, parms, Qmenu_bar_lines,
3156 NILP (Vmenu_bar_mode)
3157 ? make_number (0) : make_number (1),
3158 NULL, NULL, RES_TYPE_NUMBER);
3159 x_default_parameter (f, parms, Qtool_bar_lines,
3160 NILP (Vtool_bar_mode)
3161 ? make_number (0) : make_number (1),
3162 NULL, NULL, RES_TYPE_NUMBER);
3163
3164 unbind_to (count2, Qnil);
3165 }
3166 3185
3167 x_default_parameter (f, parms, Qbuffer_predicate, Qnil, 3186 x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
3168 "bufferPredicate", "BufferPredicate", 3187 "bufferPredicate", "BufferPredicate",
@@ -3172,7 +3191,7 @@ This function is an internal primitive--use `make-frame' instead. */)
3172 x_default_parameter (f, parms, Qwait_for_wm, Qt, 3191 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3173 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN); 3192 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3174 x_default_parameter (f, parms, Qfullscreen, Qnil, 3193 x_default_parameter (f, parms, Qfullscreen, Qnil,
3175 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); 3194 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3176 x_default_parameter (f, parms, Qtool_bar_position, 3195 x_default_parameter (f, parms, Qtool_bar_position,
3177 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL); 3196 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
3178 3197
@@ -3213,17 +3232,16 @@ This function is an internal primitive--use `make-frame' instead. */)
3213 x_default_parameter (f, parms, Qscroll_bar_width, Qnil, 3232 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3214 "scrollBarWidth", "ScrollBarWidth", 3233 "scrollBarWidth", "ScrollBarWidth",
3215 RES_TYPE_NUMBER); 3234 RES_TYPE_NUMBER);
3235 x_default_parameter (f, parms, Qscroll_bar_height, Qnil,
3236 "scrollBarHeight", "ScrollBarHeight",
3237 RES_TYPE_NUMBER);
3216 x_default_parameter (f, parms, Qalpha, Qnil, 3238 x_default_parameter (f, parms, Qalpha, Qnil,
3217 "alpha", "Alpha", RES_TYPE_NUMBER); 3239 "alpha", "Alpha", RES_TYPE_NUMBER);
3218 3240
3219 /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. 3241 /* Consider frame official, now. */
3220 Change will not be effected unless different from the current 3242 f->official = true;
3221 FRAME_LINES (f). */ 3243
3222 width = FRAME_TEXT_WIDTH (f); 3244 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1);
3223 height = FRAME_TEXT_HEIGHT (f);
3224 FRAME_TEXT_HEIGHT (f) = 0;
3225 SET_FRAME_WIDTH (f, 0);
3226 change_frame_size (f, width, height, 1, 0, 0, 1);
3227 3245
3228#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 3246#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
3229 /* Create the menu bar. */ 3247 /* Create the menu bar. */
@@ -4961,12 +4979,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
4961 dpyinfo_refcount = dpyinfo->reference_count; 4979 dpyinfo_refcount = dpyinfo->reference_count;
4962#endif /* GLYPH_DEBUG */ 4980#endif /* GLYPH_DEBUG */
4963 4981
4964 /* Init faces before x_default_parameter is called for scroll-bar 4982 /* Init faces before x_default_parameter is called for the
4965 parameters because that function calls x_set_scroll_bar_width, 4983 scroll-bar-width parameter because otherwise we end up in
4966 which calls change_frame_size, which calls Fset_window_buffer, 4984 init_iterator with a null face cache, which should not happen. */
4967 which runs hooks, which call Fvertical_motion. At the end, we
4968 end up in init_iterator with a null face cache, which should not
4969 happen. */
4970 init_frame_faces (f); 4985 init_frame_faces (f);
4971 4986
4972 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 4987 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
@@ -5023,7 +5038,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5023 width = FRAME_COLS (f); 5038 width = FRAME_COLS (f);
5024 height = FRAME_LINES (f); 5039 height = FRAME_LINES (f);
5025 SET_FRAME_COLS (f, 0); 5040 SET_FRAME_COLS (f, 0);
5026 FRAME_LINES (f) = 0; 5041 SET_FRAME_LINES (f, 0);
5027 change_frame_size (f, width, height, 1, 0, 0, 0); 5042 change_frame_size (f, width, height, 1, 0, 0, 0);
5028 5043
5029 /* Add `tooltip' frame parameter's default value. */ 5044 /* Add `tooltip' frame parameter's default value. */
@@ -5081,7 +5096,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo,
5081 below. And the frame needs to be on Vframe_list or making it 5096 below. And the frame needs to be on Vframe_list or making it
5082 visible won't work. */ 5097 visible won't work. */
5083 Vframe_list = Fcons (frame, Vframe_list); 5098 Vframe_list = Fcons (frame, Vframe_list);
5084 5099 f->official = true;
5085 5100
5086 /* Setting attributes of faces of the tooltip frame from resources 5101 /* Setting attributes of faces of the tooltip frame from resources
5087 and similar will increment face_change_count, which leads to the 5102 and similar will increment face_change_count, which leads to the
@@ -6011,17 +6026,19 @@ frame_parm_handler x_frame_parm_handlers[] =
6011 x_set_mouse_color, 6026 x_set_mouse_color,
6012 x_explicitly_set_name, 6027 x_explicitly_set_name,
6013 x_set_scroll_bar_width, 6028 x_set_scroll_bar_width,
6029 x_set_scroll_bar_height,
6014 x_set_title, 6030 x_set_title,
6015 x_set_unsplittable, 6031 x_set_unsplittable,
6016 x_set_vertical_scroll_bars, 6032 x_set_vertical_scroll_bars,
6033 x_set_horizontal_scroll_bars,
6017 x_set_visibility, 6034 x_set_visibility,
6018 x_set_tool_bar_lines, 6035 x_set_tool_bar_lines,
6019 x_set_scroll_bar_foreground, 6036 x_set_scroll_bar_foreground,
6020 x_set_scroll_bar_background, 6037 x_set_scroll_bar_background,
6021 x_set_screen_gamma, 6038 x_set_screen_gamma,
6022 x_set_line_spacing, 6039 x_set_line_spacing,
6023 x_set_fringe_width, 6040 x_set_left_fringe,
6024 x_set_fringe_width, 6041 x_set_right_fringe,
6025 x_set_wait_for_wm, 6042 x_set_wait_for_wm,
6026 x_set_fullscreen, 6043 x_set_fullscreen,
6027 x_set_font_backend, 6044 x_set_font_backend,
diff --git a/src/xmenu.c b/src/xmenu.c
index f4d0921762c..a7d47188ef5 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -627,7 +627,7 @@ update_frame_menubar (struct frame *f)
627 xg_update_frame_menubar (f); 627 xg_update_frame_menubar (f);
628#else 628#else
629 struct x_output *x; 629 struct x_output *x;
630 int columns, rows; 630/** int columns, rows; **/
631 631
632 eassert (FRAME_X_P (f)); 632 eassert (FRAME_X_P (f));
633 633
@@ -639,8 +639,8 @@ update_frame_menubar (struct frame *f)
639 block_input (); 639 block_input ();
640 /* Save the size of the frame because the pane widget doesn't accept 640 /* Save the size of the frame because the pane widget doesn't accept
641 to resize itself. So force it. */ 641 to resize itself. So force it. */
642 columns = FRAME_COLS (f); 642/** columns = FRAME_COLS (f); **/
643 rows = FRAME_LINES (f); 643/** rows = FRAME_LINES (f); **/
644 644
645 /* Do the voodoo which means "I'm changing lots of things, don't try 645 /* Do the voodoo which means "I'm changing lots of things, don't try
646 to refigure sizes until I'm done." */ 646 to refigure sizes until I'm done." */
@@ -662,7 +662,8 @@ update_frame_menubar (struct frame *f)
662 lw_refigure_widget (x->column_widget, True); 662 lw_refigure_widget (x->column_widget, True);
663 663
664 /* Force the pane widget to resize itself with the right values. */ 664 /* Force the pane widget to resize itself with the right values. */
665 EmacsFrameSetCharSize (x->edit_widget, columns, rows); 665/** EmacsFrameSetCharSize (x->edit_widget, columns, rows); **/
666 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 2, 0);
666 unblock_input (); 667 unblock_input ();
667#endif 668#endif
668} 669}
@@ -705,7 +706,7 @@ apply_systemfont_to_menu (struct frame *f, Widget w)
705void 706void
706set_frame_menubar (struct frame *f, bool first_time, bool deep_p) 707set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
707{ 708{
708 xt_or_gtk_widget menubar_widget; 709 xt_or_gtk_widget menubar_widget, old_widget;
709#ifdef USE_X_TOOLKIT 710#ifdef USE_X_TOOLKIT
710 LWLIB_ID id; 711 LWLIB_ID id;
711#endif 712#endif
@@ -718,7 +719,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
718 719
719 eassert (FRAME_X_P (f)); 720 eassert (FRAME_X_P (f));
720 721
721 menubar_widget = f->output_data.x->menubar_widget; 722 menubar_widget = old_widget = f->output_data.x->menubar_widget;
722 723
723 XSETFRAME (Vmenu_updating_frame, f); 724 XSETFRAME (Vmenu_updating_frame, f);
724 725
@@ -1099,7 +1100,15 @@ free_frame_menubar (struct frame *f)
1099 if (x1 == 0 && y1 == 0) 1100 if (x1 == 0 && y1 == 0)
1100 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL); 1101 XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
1101#endif 1102#endif
1102 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); 1103 adjust_frame_size (f, FRAME_TEXT_WIDTH (f),
1104 FRAME_TEXT_HEIGHT (f), 2, 0);
1105 /*
1106 if (frame_inhibit_resize (f, 0))
1107 change_frame_size (f, 0, 0, 0, 0, 0, 1);
1108 else
1109 x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
1110 FRAME_TEXT_HEIGHT (f), 1);
1111 */
1103 } 1112 }
1104 unblock_input (); 1113 unblock_input ();
1105 } 1114 }
diff --git a/src/xterm.c b/src/xterm.c
index 85835a2c7c5..b4eba7fcf82 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -246,11 +246,15 @@ static void x_clip_to_row (struct window *, struct glyph_row *,
246static void x_flush (struct frame *f); 246static void x_flush (struct frame *f);
247static void x_update_begin (struct frame *); 247static void x_update_begin (struct frame *);
248static void x_update_window_begin (struct window *); 248static void x_update_window_begin (struct window *);
249static struct scroll_bar *x_window_to_scroll_bar (Display *, Window); 249static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
250static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, 250static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
251 enum scroll_bar_part *, 251 enum scroll_bar_part *,
252 Lisp_Object *, Lisp_Object *, 252 Lisp_Object *, Lisp_Object *,
253 Time *); 253 Time *);
254static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
255 enum scroll_bar_part *,
256 Lisp_Object *, Lisp_Object *,
257 Time *);
254static int x_handle_net_wm_state (struct frame *, const XPropertyEvent *); 258static int x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
255static void x_check_fullscreen (struct frame *); 259static void x_check_fullscreen (struct frame *);
256static void x_check_expected_move (struct frame *, int, int); 260static void x_check_expected_move (struct frame *, int, int);
@@ -268,6 +272,7 @@ static void x_wm_set_window_state (struct frame *, int);
268static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t); 272static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
269static void x_initialize (void); 273static void x_initialize (void);
270 274
275static int get_current_wm_state (struct frame *, Window, int *, int *);
271 276
272/* Flush display of frame F. */ 277/* Flush display of frame F. */
273 278
@@ -634,10 +639,8 @@ XTframe_up_to_date (struct frame *f)
634} 639}
635 640
636 641
637/* Clear under internal border if any for non-toolkit builds. */ 642/* Clear under internal border if any (GTK has its own version). */
638 643#ifndef USE_GTK
639
640#if !defined USE_X_TOOLKIT && !defined USE_GTK
641void 644void
642x_clear_under_internal_border (struct frame *f) 645x_clear_under_internal_border (struct frame *f)
643{ 646{
@@ -3974,7 +3977,14 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3974 block_input (); 3977 block_input ();
3975 3978
3976 if (dpyinfo->last_mouse_scroll_bar && insist == 0) 3979 if (dpyinfo->last_mouse_scroll_bar && insist == 0)
3977 x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp); 3980 {
3981 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
3982
3983 if (bar->horizontal)
3984 x_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
3985 else
3986 x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
3987 }
3978 else 3988 else
3979 { 3989 {
3980 Window root; 3990 Window root;
@@ -4118,7 +4128,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
4118 { 4128 {
4119 struct scroll_bar *bar; 4129 struct scroll_bar *bar;
4120 4130
4121 bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win); 4131 bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win, 2);
4122 4132
4123 if (bar) 4133 if (bar)
4124 { 4134 {
@@ -4173,7 +4183,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
4173 bits. */ 4183 bits. */
4174 4184
4175static struct scroll_bar * 4185static struct scroll_bar *
4176x_window_to_scroll_bar (Display *display, Window window_id) 4186x_window_to_scroll_bar (Display *display, Window window_id, int type)
4177{ 4187{
4178 Lisp_Object tail, frame; 4188 Lisp_Object tail, frame;
4179 4189
@@ -4198,8 +4208,11 @@ x_window_to_scroll_bar (Display *display, Window window_id)
4198 condemned = Qnil, 4208 condemned = Qnil,
4199 ! NILP (bar)); 4209 ! NILP (bar));
4200 bar = XSCROLL_BAR (bar)->next) 4210 bar = XSCROLL_BAR (bar)->next)
4201 if (XSCROLL_BAR (bar)->x_window == window_id && 4211 if (XSCROLL_BAR (bar)->x_window == window_id
4202 FRAME_X_DISPLAY (XFRAME (frame)) == display) 4212 && FRAME_X_DISPLAY (XFRAME (frame)) == display
4213 && (type = 2
4214 || (type == 1 && XSCROLL_BAR (bar)->horizontal)
4215 || (type == 0 && !XSCROLL_BAR (bar)->horizontal)))
4203 return XSCROLL_BAR (bar); 4216 return XSCROLL_BAR (bar);
4204 } 4217 }
4205 4218
@@ -4237,7 +4250,7 @@ x_window_to_menu_bar (Window window)
4237 4250
4238#ifdef USE_TOOLKIT_SCROLL_BARS 4251#ifdef USE_TOOLKIT_SCROLL_BARS
4239 4252
4240static void x_send_scroll_bar_event (Lisp_Object, int, int, int); 4253static void x_send_scroll_bar_event (Lisp_Object, int, int, int, bool);
4241 4254
4242/* Lisp window being scrolled. Set when starting to interact with 4255/* Lisp window being scrolled. Set when starting to interact with
4243 a toolkit scroll bar, reset to nil when ending the interaction. */ 4256 a toolkit scroll bar, reset to nil when ending the interaction. */
@@ -4251,6 +4264,7 @@ static Lisp_Object window_being_scrolled;
4251/* Id of action hook installed for scroll bars. */ 4264/* Id of action hook installed for scroll bars. */
4252 4265
4253static XtActionHookId action_hook_id; 4266static XtActionHookId action_hook_id;
4267static XtActionHookId horizontal_action_hook_id;
4254 4268
4255static Boolean xaw3d_arrow_scroll; 4269static Boolean xaw3d_arrow_scroll;
4256 4270
@@ -4288,7 +4302,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
4288 struct scroll_bar *bar; 4302 struct scroll_bar *bar;
4289 4303
4290 x_send_scroll_bar_event (window_being_scrolled, 4304 x_send_scroll_bar_event (window_being_scrolled,
4291 scroll_bar_end_scroll, 0, 0); 4305 scroll_bar_end_scroll, 0, 0, 0);
4292 w = XWINDOW (window_being_scrolled); 4306 w = XWINDOW (window_being_scrolled);
4293 bar = XSCROLL_BAR (w->vertical_scroll_bar); 4307 bar = XSCROLL_BAR (w->vertical_scroll_bar);
4294 4308
@@ -4306,6 +4320,49 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
4306 toolkit_scroll_bar_interaction = 0; 4320 toolkit_scroll_bar_interaction = 0;
4307 } 4321 }
4308} 4322}
4323
4324
4325static void
4326xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_name,
4327 XEvent *event, String *params, Cardinal *num_params)
4328{
4329 int scroll_bar_p;
4330 const char *end_action;
4331
4332#ifdef USE_MOTIF
4333 scroll_bar_p = XmIsScrollBar (widget);
4334 end_action = "Release";
4335#else /* !USE_MOTIF i.e. use Xaw */
4336 scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
4337 end_action = "EndScroll";
4338#endif /* USE_MOTIF */
4339
4340 if (scroll_bar_p
4341 && strcmp (action_name, end_action) == 0
4342 && WINDOWP (window_being_scrolled))
4343 {
4344 struct window *w;
4345 struct scroll_bar *bar;
4346
4347 x_send_scroll_bar_event (window_being_scrolled,
4348 scroll_bar_end_scroll, 0, 0, 1);
4349 w = XWINDOW (window_being_scrolled);
4350 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
4351
4352 if (bar->dragging != -1)
4353 {
4354 bar->dragging = -1;
4355 /* The thumb size is incorrect while dragging: fix it. */
4356 set_horizontal_scroll_bar (w);
4357 }
4358 window_being_scrolled = Qnil;
4359#if defined (USE_LUCID)
4360 bar->last_seen_part = scroll_bar_nowhere;
4361#endif
4362 /* Xt timeouts no longer needed. */
4363 toolkit_scroll_bar_interaction = 0;
4364 }
4365}
4309#endif /* not USE_GTK */ 4366#endif /* not USE_GTK */
4310 4367
4311/* Send a client message with message type Xatom_Scrollbar for a 4368/* Send a client message with message type Xatom_Scrollbar for a
@@ -4314,7 +4371,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
4314 amount to scroll of a whole of WHOLE. */ 4371 amount to scroll of a whole of WHOLE. */
4315 4372
4316static void 4373static void
4317x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) 4374x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole, bool horizontal)
4318{ 4375{
4319 XEvent event; 4376 XEvent event;
4320 XClientMessageEvent *ev = &event.xclient; 4377 XClientMessageEvent *ev = &event.xclient;
@@ -4329,7 +4386,9 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
4329 4386
4330 /* Construct a ClientMessage event to send to the frame. */ 4387 /* Construct a ClientMessage event to send to the frame. */
4331 ev->type = ClientMessage; 4388 ev->type = ClientMessage;
4332 ev->message_type = FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar; 4389 ev->message_type = (horizontal
4390 ? FRAME_DISPLAY_INFO (f)->Xatom_Horizontal_Scrollbar
4391 : FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar);
4333 ev->display = FRAME_X_DISPLAY (f); 4392 ev->display = FRAME_X_DISPLAY (f);
4334 ev->window = FRAME_X_WINDOW (f); 4393 ev->window = FRAME_X_WINDOW (f);
4335 ev->format = 32; 4394 ev->format = 32;
@@ -4394,6 +4453,41 @@ x_scroll_bar_to_input_event (const XEvent *event,
4394 ievent->modifiers = 0; 4453 ievent->modifiers = 0;
4395} 4454}
4396 4455
4456/* Transform a horizontal scroll bar ClientMessage EVENT to an Emacs
4457 input event in *IEVENT. */
4458
4459static void
4460x_horizontal_scroll_bar_to_input_event (const XEvent *event,
4461 struct input_event *ievent)
4462{
4463 const XClientMessageEvent *ev = &event->xclient;
4464 Lisp_Object window;
4465 struct window *w;
4466
4467 /* See the comment in the function above. */
4468 intptr_t iw0 = ev->data.l[0];
4469 intptr_t iw1 = ev->data.l[1];
4470 intptr_t iw = (iw0 << 31 << 1) + (iw1 & 0xffffffffu);
4471 w = (struct window *) iw;
4472
4473 XSETWINDOW (window, w);
4474
4475 ievent->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
4476 ievent->frame_or_window = window;
4477 ievent->arg = Qnil;
4478#ifdef USE_GTK
4479 ievent->timestamp = CurrentTime;
4480#else
4481 ievent->timestamp =
4482 XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame)));
4483#endif
4484 ievent->code = 0;
4485 ievent->part = ev->data.l[2];
4486 ievent->x = make_number (ev->data.l[3]);
4487 ievent->y = make_number (ev->data.l[4]);
4488 ievent->modifiers = 0;
4489}
4490
4397 4491
4398#ifdef USE_MOTIF 4492#ifdef USE_MOTIF
4399 4493
@@ -4401,7 +4495,6 @@ x_scroll_bar_to_input_event (const XEvent *event,
4401 4495
4402#define XM_SB_MAX 10000000 4496#define XM_SB_MAX 10000000
4403 4497
4404
4405/* Scroll bar callback for Motif scroll bars. WIDGET is the scroll 4498/* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
4406 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure. 4499 bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
4407 CALL_DATA is a pointer to a XmScrollBarCallbackStruct. */ 4500 CALL_DATA is a pointer to a XmScrollBarCallbackStruct. */
@@ -4412,51 +4505,65 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4412 struct scroll_bar *bar = client_data; 4505 struct scroll_bar *bar = client_data;
4413 XmScrollBarCallbackStruct *cs = call_data; 4506 XmScrollBarCallbackStruct *cs = call_data;
4414 int part = -1, whole = 0, portion = 0; 4507 int part = -1, whole = 0, portion = 0;
4508 int horizontal = bar->horizontal;
4415 4509
4416 switch (cs->reason) 4510 switch (cs->reason)
4417 { 4511 {
4418 case XmCR_DECREMENT: 4512 case XmCR_DECREMENT:
4419 bar->dragging = -1; 4513 bar->dragging = -1;
4420 part = scroll_bar_up_arrow; 4514 part = horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow;
4421 break; 4515 break;
4422 4516
4423 case XmCR_INCREMENT: 4517 case XmCR_INCREMENT:
4424 bar->dragging = -1; 4518 bar->dragging = -1;
4425 part = scroll_bar_down_arrow; 4519 part = horizontal ? scroll_bar_right_arrow : scroll_bar_down_arrow;
4426 break; 4520 break;
4427 4521
4428 case XmCR_PAGE_DECREMENT: 4522 case XmCR_PAGE_DECREMENT:
4429 bar->dragging = -1; 4523 bar->dragging = -1;
4430 part = scroll_bar_above_handle; 4524 part = horizontal ? scroll_bar_before_handle : scroll_bar_above_handle;
4431 break; 4525 break;
4432 4526
4433 case XmCR_PAGE_INCREMENT: 4527 case XmCR_PAGE_INCREMENT:
4434 bar->dragging = -1; 4528 bar->dragging = -1;
4435 part = scroll_bar_below_handle; 4529 part = horizontal ? scroll_bar_after_handle : scroll_bar_below_handle;
4436 break; 4530 break;
4437 4531
4438 case XmCR_TO_TOP: 4532 case XmCR_TO_TOP:
4439 bar->dragging = -1; 4533 bar->dragging = -1;
4440 part = scroll_bar_to_top; 4534 part = horizontal ? scroll_bar_to_leftmost : scroll_bar_to_top;
4441 break; 4535 break;
4442 4536
4443 case XmCR_TO_BOTTOM: 4537 case XmCR_TO_BOTTOM:
4444 bar->dragging = -1; 4538 bar->dragging = -1;
4445 part = scroll_bar_to_bottom; 4539 part = horizontal ? scroll_bar_to_rightmost : scroll_bar_to_bottom;
4446 break; 4540 break;
4447 4541
4448 case XmCR_DRAG: 4542 case XmCR_DRAG:
4449 { 4543 {
4450 int slider_size; 4544 int slider_size;
4451 4545
4452 /* Get the slider size. */
4453 block_input (); 4546 block_input ();
4454 XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL); 4547 XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL);
4455 unblock_input (); 4548 unblock_input ();
4456 4549
4457 whole = XM_SB_MAX - slider_size; 4550 if (horizontal)
4458 portion = min (cs->value, whole); 4551 {
4459 part = scroll_bar_handle; 4552 whole = bar->whole;
4553 portion = (((float) cs->value
4554 / (XM_SB_MAX - slider_size))
4555 * (whole
4556 - ((float) slider_size / XM_SB_MAX) * whole));
4557 portion = max (0, portion);
4558 part = scroll_bar_horizontal_handle;
4559 }
4560 else
4561 {
4562 whole = XM_SB_MAX - slider_size;
4563 portion = min (cs->value, whole);
4564 part = scroll_bar_handle;
4565 }
4566
4460 bar->dragging = cs->value; 4567 bar->dragging = cs->value;
4461 } 4568 }
4462 break; 4569 break;
@@ -4468,7 +4575,7 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4468 if (part >= 0) 4575 if (part >= 0)
4469 { 4576 {
4470 window_being_scrolled = bar->window; 4577 window_being_scrolled = bar->window;
4471 x_send_scroll_bar_event (bar->window, part, portion, whole); 4578 x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
4472 } 4579 }
4473} 4580}
4474 4581
@@ -4497,27 +4604,42 @@ xg_scroll_callback (GtkRange *range,
4497 if (FRAME_DISPLAY_INFO (f)->grabbed != 0 4604 if (FRAME_DISPLAY_INFO (f)->grabbed != 0
4498 && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4)) 4605 && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4))
4499 { 4606 {
4500 part = scroll_bar_handle; 4607 if (bar->horizontal)
4501 whole = gtk_adjustment_get_upper (adj) - 4608 {
4502 gtk_adjustment_get_page_size (adj); 4609 part = scroll_bar_horizontal_handle;
4503 portion = min ((int)value, whole); 4610 whole = (int)(gtk_adjustment_get_upper (adj) -
4504 bar->dragging = portion; 4611 gtk_adjustment_get_page_size (adj));
4505 } 4612 portion = min ((int)value, whole);
4613 bar->dragging = portion;
4614 }
4615 else
4616 {
4617 part = scroll_bar_handle;
4618 whole = gtk_adjustment_get_upper (adj) -
4619 gtk_adjustment_get_page_size (adj);
4620 portion = min ((int)value, whole);
4621 bar->dragging = portion;
4622 }
4623 }
4506 break; 4624 break;
4507 case GTK_SCROLL_STEP_BACKWARD: 4625 case GTK_SCROLL_STEP_BACKWARD:
4508 part = scroll_bar_up_arrow; 4626 part = (bar->horizontal
4627 ? scroll_bar_left_arrow : scroll_bar_up_arrow);
4509 bar->dragging = -1; 4628 bar->dragging = -1;
4510 break; 4629 break;
4511 case GTK_SCROLL_STEP_FORWARD: 4630 case GTK_SCROLL_STEP_FORWARD:
4512 part = scroll_bar_down_arrow; 4631 part = (bar->horizontal
4632 ? scroll_bar_right_arrow : scroll_bar_down_arrow);
4513 bar->dragging = -1; 4633 bar->dragging = -1;
4514 break; 4634 break;
4515 case GTK_SCROLL_PAGE_BACKWARD: 4635 case GTK_SCROLL_PAGE_BACKWARD:
4516 part = scroll_bar_above_handle; 4636 part = (bar->horizontal
4637 ? scroll_bar_before_handle : scroll_bar_above_handle);
4517 bar->dragging = -1; 4638 bar->dragging = -1;
4518 break; 4639 break;
4519 case GTK_SCROLL_PAGE_FORWARD: 4640 case GTK_SCROLL_PAGE_FORWARD:
4520 part = scroll_bar_below_handle; 4641 part = (bar->horizontal
4642 ? scroll_bar_after_handle : scroll_bar_below_handle);
4521 bar->dragging = -1; 4643 bar->dragging = -1;
4522 break; 4644 break;
4523 } 4645 }
@@ -4525,7 +4647,7 @@ xg_scroll_callback (GtkRange *range,
4525 if (part >= 0) 4647 if (part >= 0)
4526 { 4648 {
4527 window_being_scrolled = bar->window; 4649 window_being_scrolled = bar->window;
4528 x_send_scroll_bar_event (bar->window, part, portion, whole); 4650 x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
4529 } 4651 }
4530 4652
4531 return FALSE; 4653 return FALSE;
@@ -4543,7 +4665,7 @@ xg_end_scroll_callback (GtkWidget *widget,
4543 if (WINDOWP (window_being_scrolled)) 4665 if (WINDOWP (window_being_scrolled))
4544 { 4666 {
4545 x_send_scroll_bar_event (window_being_scrolled, 4667 x_send_scroll_bar_event (window_being_scrolled,
4546 scroll_bar_end_scroll, 0, 0); 4668 scroll_bar_end_scroll, 0, 0, bar->horizontal);
4547 window_being_scrolled = Qnil; 4669 window_being_scrolled = Qnil;
4548 } 4670 }
4549 4671
@@ -4567,29 +4689,27 @@ xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4567 float shown; 4689 float shown;
4568 int whole, portion, height; 4690 int whole, portion, height;
4569 enum scroll_bar_part part; 4691 enum scroll_bar_part part;
4692 int horizontal = bar->horizontal;
4570 4693
4571 /* Get the size of the thumb, a value between 0 and 1. */ 4694 /* Get the size of the thumb, a value between 0 and 1. */
4572 block_input (); 4695 block_input ();
4573 XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL); 4696 XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
4574 unblock_input (); 4697 unblock_input ();
4575 4698
4576 whole = 10000000; 4699 if (horizontal)
4577 portion = shown < 1 ? top * whole : 0; 4700 {
4578 4701 whole = bar->whole;
4579 if (shown < 1 && (eabs (top + shown - 1) < 1.0f / height)) 4702 portion = (top * (whole - (shown * whole))) / (1 - shown);
4580 /* Some derivatives of Xaw refuse to shrink the thumb when you reach 4703 portion = max (0, portion);
4581 the bottom, so we force the scrolling whenever we see that we're 4704 part = scroll_bar_horizontal_handle;
4582 too close to the bottom (in x_set_toolkit_scroll_bar_thumb 4705 }
4583 we try to ensure that we always stay two pixels away from the
4584 bottom). */
4585 part = scroll_bar_down_arrow;
4586 else 4706 else
4587 part = scroll_bar_handle; 4707 part = scroll_bar_handle;
4588 4708
4589 window_being_scrolled = bar->window; 4709 window_being_scrolled = bar->window;
4590 bar->dragging = portion; 4710 bar->dragging = portion;
4591 bar->last_seen_part = part; 4711 bar->last_seen_part = part;
4592 x_send_scroll_bar_event (bar->window, part, portion, whole); 4712 x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
4593} 4713}
4594 4714
4595 4715
@@ -4628,12 +4748,13 @@ xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
4628 window_being_scrolled = bar->window; 4748 window_being_scrolled = bar->window;
4629 bar->dragging = -1; 4749 bar->dragging = -1;
4630 bar->last_seen_part = part; 4750 bar->last_seen_part = part;
4631 x_send_scroll_bar_event (bar->window, part, position, height); 4751 x_send_scroll_bar_event (bar->window, part, position, height, bar->horizontal);
4632} 4752}
4633 4753
4634#endif /* not USE_GTK and not USE_MOTIF */ 4754#endif /* not USE_GTK and not USE_MOTIF */
4635 4755
4636#define SCROLL_BAR_NAME "verticalScrollBar" 4756#define SCROLL_BAR_NAME "verticalScrollBar"
4757#define SCROLL_BAR_HORIZONTAL_NAME "horizontalScrollBar"
4637 4758
4638/* Create the widget for scroll bar BAR on frame F. Record the widget 4759/* Create the widget for scroll bar BAR on frame F. Record the widget
4639 and X window of the scroll bar in BAR. */ 4760 and X window of the scroll bar in BAR. */
@@ -4651,6 +4772,18 @@ x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
4651 unblock_input (); 4772 unblock_input ();
4652} 4773}
4653 4774
4775static void
4776x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
4777{
4778 const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
4779
4780 block_input ();
4781 xg_create_horizontal_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
4782 G_CALLBACK (xg_end_scroll_callback),
4783 scroll_bar_name);
4784 unblock_input ();
4785}
4786
4654#else /* not USE_GTK */ 4787#else /* not USE_GTK */
4655 4788
4656static void 4789static void
@@ -4846,6 +4979,208 @@ x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
4846 SET_SCROLL_BAR_X_WIDGET (bar, widget); 4979 SET_SCROLL_BAR_X_WIDGET (bar, widget);
4847 xwindow = XtWindow (widget); 4980 xwindow = XtWindow (widget);
4848 bar->x_window = xwindow; 4981 bar->x_window = xwindow;
4982 bar->whole = 1;
4983 bar->horizontal = 0;
4984
4985 unblock_input ();
4986}
4987
4988static void
4989x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
4990{
4991 Window xwindow;
4992 Widget widget;
4993 Arg av[20];
4994 int ac = 0;
4995 const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
4996 unsigned long pixel;
4997
4998 block_input ();
4999
5000#ifdef USE_MOTIF
5001 /* Set resources. Create the widget. */
5002 XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
5003 XtSetArg (av[ac], XmNminimum, 0); ++ac;
5004 XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
5005 XtSetArg (av[ac], XmNorientation, XmHORIZONTAL); ++ac;
5006 XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_RIGHT), ++ac;
5007 XtSetArg (av[ac], XmNincrement, 1); ++ac;
5008 XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
5009
5010 pixel = f->output_data.x->scroll_bar_foreground_pixel;
5011 if (pixel != -1)
5012 {
5013 XtSetArg (av[ac], XmNforeground, pixel);
5014 ++ac;
5015 }
5016
5017 pixel = f->output_data.x->scroll_bar_background_pixel;
5018 if (pixel != -1)
5019 {
5020 XtSetArg (av[ac], XmNbackground, pixel);
5021 ++ac;
5022 }
5023
5024 widget = XmCreateScrollBar (f->output_data.x->edit_widget,
5025 (char *) scroll_bar_name, av, ac);
5026
5027 /* Add one callback for everything that can happen. */
5028 XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
5029 (XtPointer) bar);
5030 XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
5031 (XtPointer) bar);
5032 XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
5033 (XtPointer) bar);
5034 XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
5035 (XtPointer) bar);
5036 XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
5037 (XtPointer) bar);
5038 XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
5039 (XtPointer) bar);
5040 XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
5041 (XtPointer) bar);
5042
5043 /* Realize the widget. Only after that is the X window created. */
5044 XtRealizeWidget (widget);
5045
5046 /* Set the cursor to an arrow. I didn't find a resource to do that.
5047 And I'm wondering why it hasn't an arrow cursor by default. */
5048 XDefineCursor (XtDisplay (widget), XtWindow (widget),
5049 f->output_data.x->nontext_cursor);
5050
5051#else /* !USE_MOTIF i.e. use Xaw */
5052
5053 /* Set resources. Create the widget. The background of the
5054 Xaw3d scroll bar widget is a little bit light for my taste.
5055 We don't alter it here to let users change it according
5056 to their taste with `emacs*verticalScrollBar.background: xxx'. */
5057 XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
5058 XtSetArg (av[ac], XtNorientation, XtorientHorizontal); ++ac;
5059 /* For smoother scrolling with Xaw3d -sm */
5060 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
5061
5062 pixel = f->output_data.x->scroll_bar_foreground_pixel;
5063 if (pixel != -1)
5064 {
5065 XtSetArg (av[ac], XtNforeground, pixel);
5066 ++ac;
5067 }
5068
5069 pixel = f->output_data.x->scroll_bar_background_pixel;
5070 if (pixel != -1)
5071 {
5072 XtSetArg (av[ac], XtNbackground, pixel);
5073 ++ac;
5074 }
5075
5076 /* Top/bottom shadow colors. */
5077
5078 /* Allocate them, if necessary. */
5079 if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
5080 {
5081 pixel = f->output_data.x->scroll_bar_background_pixel;
5082 if (pixel != -1)
5083 {
5084 if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
5085 FRAME_X_COLORMAP (f),
5086 &pixel, 1.2, 0x8000))
5087 pixel = -1;
5088 f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
5089 }
5090 }
5091 if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
5092 {
5093 pixel = f->output_data.x->scroll_bar_background_pixel;
5094 if (pixel != -1)
5095 {
5096 if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
5097 FRAME_X_COLORMAP (f),
5098 &pixel, 0.6, 0x4000))
5099 pixel = -1;
5100 f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
5101 }
5102 }
5103
5104#ifdef XtNbeNiceToColormap
5105 /* Tell the toolkit about them. */
5106 if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
5107 || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
5108 /* We tried to allocate a color for the top/bottom shadow, and
5109 failed, so tell Xaw3d to use dithering instead. */
5110 /* But only if we have a small colormap. Xaw3d can allocate nice
5111 colors itself. */
5112 {
5113 XtSetArg (av[ac], XtNbeNiceToColormap,
5114 DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16);
5115 ++ac;
5116 }
5117 else
5118 /* Tell what colors Xaw3d should use for the top/bottom shadow, to
5119 be more consistent with other emacs 3d colors, and since Xaw3d is
5120 not good at dealing with allocation failure. */
5121 {
5122 /* This tells Xaw3d to use real colors instead of dithering for
5123 the shadows. */
5124 XtSetArg (av[ac], XtNbeNiceToColormap, False);
5125 ++ac;
5126
5127 /* Specify the colors. */
5128 pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
5129 if (pixel != -1)
5130 {
5131 XtSetArg (av[ac], XtNtopShadowPixel, pixel);
5132 ++ac;
5133 }
5134 pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
5135 if (pixel != -1)
5136 {
5137 XtSetArg (av[ac], XtNbottomShadowPixel, pixel);
5138 ++ac;
5139 }
5140 }
5141#endif
5142
5143 widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
5144 f->output_data.x->edit_widget, av, ac);
5145
5146 {
5147 char const *initial = "";
5148 char const *val = initial;
5149 XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
5150#ifdef XtNarrowScrollbars
5151 XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
5152#endif
5153 XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
5154 if (xaw3d_arrow_scroll || val == initial)
5155 { /* ARROW_SCROLL */
5156 xaw3d_arrow_scroll = True;
5157 /* Isn't that just a personal preference ? --Stef */
5158 XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
5159 }
5160 }
5161
5162 /* Define callbacks. */
5163 XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
5164 XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
5165 (XtPointer) bar);
5166
5167 /* Realize the widget. Only after that is the X window created. */
5168 XtRealizeWidget (widget);
5169
5170#endif /* !USE_MOTIF */
5171
5172 /* Install an action hook that lets us detect when the user
5173 finishes interacting with a scroll bar. */
5174 if (horizontal_action_hook_id == 0)
5175 horizontal_action_hook_id
5176 = XtAppAddActionHook (Xt_app_con, xt_horizontal_action_hook, 0);
5177
5178 /* Remember X window and widget in the scroll bar vector. */
5179 SET_SCROLL_BAR_X_WIDGET (bar, widget);
5180 xwindow = XtWindow (widget);
5181 bar->x_window = xwindow;
5182 bar->whole = 1;
5183 bar->horizontal = 1;
4849 5184
4850 unblock_input (); 5185 unblock_input ();
4851} 5186}
@@ -4862,6 +5197,12 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
4862 xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); 5197 xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
4863} 5198}
4864 5199
5200static void
5201x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole)
5202{
5203 xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
5204}
5205
4865#else /* not USE_GTK */ 5206#else /* not USE_GTK */
4866static void 5207static void
4867x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, 5208x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
@@ -4974,6 +5315,89 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
4974 5315
4975 unblock_input (); 5316 unblock_input ();
4976} 5317}
5318
5319static void
5320x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
5321 int whole)
5322{
5323 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
5324 Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
5325 float top, shown;
5326
5327 block_input ();
5328
5329#ifdef USE_MOTIF
5330 bar->whole = whole;
5331 shown = (float) portion / whole;
5332 top = (float) position / (whole - portion);
5333 {
5334 int size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX);
5335 int value = clip_to_bounds (0, top * (XM_SB_MAX - size), XM_SB_MAX - size);
5336
5337 XmScrollBarSetValues (widget, value, size, 0, 0, False);
5338 }
5339#else /* !USE_MOTIF i.e. use Xaw */
5340 bar->whole = whole;
5341 if (whole == 0)
5342 top = 0, shown = 1;
5343 else
5344 {
5345 top = (float) position / whole;
5346 shown = (float) portion / whole;
5347 }
5348
5349 {
5350 float old_top, old_shown;
5351 Dimension height;
5352 XtVaGetValues (widget,
5353 XtNtopOfThumb, &old_top,
5354 XtNshown, &old_shown,
5355 XtNheight, &height,
5356 NULL);
5357
5358#if 0
5359 /* Massage the top+shown values. */
5360 if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
5361 top = max (0, min (1, top));
5362 else
5363 top = old_top;
5364#if ! defined (HAVE_XAW3D)
5365 /* With Xaw, 'top' values too closer to 1.0 may
5366 cause the thumb to disappear. Fix that. */
5367 top = min (top, 0.99f);
5368#endif
5369 /* Keep two pixels available for moving the thumb down. */
5370 shown = max (0, min (1 - top - (2.0f / height), shown));
5371#if ! defined (HAVE_XAW3D)
5372 /* Likewise with too small 'shown'. */
5373 shown = max (shown, 0.01f);
5374#endif
5375#endif
5376
5377 /* If the call to XawScrollbarSetThumb below doesn't seem to
5378 work, check that 'NARROWPROTO' is defined in src/config.h.
5379 If this is not so, most likely you need to fix configure. */
5380 XawScrollbarSetThumb (widget, top, shown);
5381#if 0
5382 if (top != old_top || shown != old_shown)
5383 {
5384 if (bar->dragging == -1)
5385 XawScrollbarSetThumb (widget, top, shown);
5386 else
5387 {
5388 /* Try to make the scrolling a tad smoother. */
5389 if (!xaw3d_pick_top)
5390 shown = min (shown, old_shown);
5391
5392 XawScrollbarSetThumb (widget, top, shown);
5393 }
5394 }
5395#endif
5396 }
5397#endif /* !USE_MOTIF */
5398
5399 unblock_input ();
5400}
4977#endif /* not USE_GTK */ 5401#endif /* not USE_GTK */
4978 5402
4979#endif /* USE_TOOLKIT_SCROLL_BARS */ 5403#endif /* USE_TOOLKIT_SCROLL_BARS */
@@ -4990,7 +5414,7 @@ x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int positio
4990 scroll bar. */ 5414 scroll bar. */
4991 5415
4992static struct scroll_bar * 5416static struct scroll_bar *
4993x_scroll_bar_create (struct window *w, int top, int left, int width, int height) 5417x_scroll_bar_create (struct window *w, int top, int left, int width, int height, bool horizontal)
4994{ 5418{
4995 struct frame *f = XFRAME (w->frame); 5419 struct frame *f = XFRAME (w->frame);
4996 struct scroll_bar *bar 5420 struct scroll_bar *bar
@@ -5000,7 +5424,10 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
5000 block_input (); 5424 block_input ();
5001 5425
5002#ifdef USE_TOOLKIT_SCROLL_BARS 5426#ifdef USE_TOOLKIT_SCROLL_BARS
5003 x_create_toolkit_scroll_bar (f, bar); 5427 if (horizontal)
5428 x_create_horizontal_toolkit_scroll_bar (f, bar);
5429 else
5430 x_create_toolkit_scroll_bar (f, bar);
5004#else /* not USE_TOOLKIT_SCROLL_BARS */ 5431#else /* not USE_TOOLKIT_SCROLL_BARS */
5005 { 5432 {
5006 XSetWindowAttributes a; 5433 XSetWindowAttributes a;
@@ -5063,8 +5490,12 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
5063#ifdef USE_TOOLKIT_SCROLL_BARS 5490#ifdef USE_TOOLKIT_SCROLL_BARS
5064 { 5491 {
5065#ifdef USE_GTK 5492#ifdef USE_GTK
5066 xg_update_scrollbar_pos (f, bar->x_window, top, 5493 if (horizontal)
5067 left,width, max (height, 1)); 5494 xg_update_horizontal_scrollbar_pos (f, bar->x_window, top,
5495 left, width, max (height, 1));
5496 else
5497 xg_update_scrollbar_pos (f, bar->x_window, top,
5498 left, width, max (height, 1));
5068#else /* not USE_GTK */ 5499#else /* not USE_GTK */
5069 Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); 5500 Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
5070 XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0); 5501 XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0);
@@ -5148,7 +5579,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
5148 5579
5149 /* Draw the empty space above the handle. Note that we can't clear 5580 /* Draw the empty space above the handle. Note that we can't clear
5150 zero-height areas; that means "clear to end of window." */ 5581 zero-height areas; that means "clear to end of window." */
5151 if (start > 0) 5582 if ((inside_width > 0) && (start > 0))
5152 x_clear_area (FRAME_X_DISPLAY (f), w, 5583 x_clear_area (FRAME_X_DISPLAY (f), w,
5153 VERTICAL_SCROLL_BAR_LEFT_BORDER, 5584 VERTICAL_SCROLL_BAR_LEFT_BORDER,
5154 VERTICAL_SCROLL_BAR_TOP_BORDER, 5585 VERTICAL_SCROLL_BAR_TOP_BORDER,
@@ -5173,7 +5604,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
5173 5604
5174 /* Draw the empty space below the handle. Note that we can't 5605 /* Draw the empty space below the handle. Note that we can't
5175 clear zero-height areas; that means "clear to end of window." */ 5606 clear zero-height areas; that means "clear to end of window." */
5176 if (end < inside_height) 5607 if ((inside_width > 0) && (end < inside_height))
5177 x_clear_area (FRAME_X_DISPLAY (f), w, 5608 x_clear_area (FRAME_X_DISPLAY (f), w,
5178 VERTICAL_SCROLL_BAR_LEFT_BORDER, 5609 VERTICAL_SCROLL_BAR_LEFT_BORDER,
5179 VERTICAL_SCROLL_BAR_TOP_BORDER + end, 5610 VERTICAL_SCROLL_BAR_TOP_BORDER + end,
@@ -5205,7 +5636,10 @@ x_scroll_bar_remove (struct scroll_bar *bar)
5205#endif 5636#endif
5206 5637
5207 /* Dissociate this scroll bar from its window. */ 5638 /* Dissociate this scroll bar from its window. */
5208 wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil); 5639 if (bar->horizontal)
5640 wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
5641 else
5642 wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
5209 5643
5210 unblock_input (); 5644 unblock_input ();
5211} 5645}
@@ -5229,8 +5663,6 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5229 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height); 5663 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
5230 top = window_y; 5664 top = window_y;
5231 height = window_height; 5665 height = window_height;
5232
5233 /* Compute the left edge and the width of the scroll bar area. */
5234 left = WINDOW_SCROLL_BAR_AREA_X (w); 5666 left = WINDOW_SCROLL_BAR_AREA_X (w);
5235 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w); 5667 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
5236 5668
@@ -5245,7 +5677,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5245 unblock_input (); 5677 unblock_input ();
5246 } 5678 }
5247 5679
5248 bar = x_scroll_bar_create (w, top, left, width, max (height, 1)); 5680 bar = x_scroll_bar_create (w, top, left, width, max (height, 1), 0);
5249 } 5681 }
5250 else 5682 else
5251 { 5683 {
@@ -5334,6 +5766,138 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5334} 5766}
5335 5767
5336 5768
5769static void
5770XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int position)
5771{
5772 struct frame *f = XFRAME (w->frame);
5773 Lisp_Object barobj;
5774 struct scroll_bar *bar;
5775 int top, height, left, width;
5776 int window_x, window_width;
5777 int pixel_width = WINDOW_PIXEL_WIDTH (w);
5778
5779 /* Get window dimensions. */
5780 window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
5781 left = window_x;
5782 width = window_width;
5783 top = WINDOW_SCROLL_BAR_AREA_Y (w);
5784 height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
5785
5786 /* Does the scroll bar exist yet? */
5787 if (NILP (w->horizontal_scroll_bar))
5788 {
5789 if (width > 0 && height > 0)
5790 {
5791 block_input ();
5792
5793 /* Clear also part between window_width and
5794 WINDOW_PIXEL_WIDTH. */
5795 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5796 left, top, pixel_width, height);
5797 unblock_input ();
5798 }
5799
5800 bar = x_scroll_bar_create (w, top, left, width, height, 1);
5801 }
5802 else
5803 {
5804 /* It may just need to be moved and resized. */
5805 unsigned int mask = 0;
5806
5807 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
5808
5809 block_input ();
5810
5811 if (left != bar->left)
5812 mask |= CWX;
5813 if (top != bar->top)
5814 mask |= CWY;
5815 if (width != bar->width)
5816 mask |= CWWidth;
5817 if (height != bar->height)
5818 mask |= CWHeight;
5819
5820#ifdef USE_TOOLKIT_SCROLL_BARS
5821 /* Move/size the scroll bar widget. */
5822 if (mask)
5823 {
5824 /* Since toolkit scroll bars are smaller than the space reserved
5825 for them on the frame, we have to clear "under" them. */
5826 if (width > 0 && height > 0)
5827 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5828 WINDOW_LEFT_EDGE_X (w), top,
5829 pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w), height);
5830#ifdef USE_GTK
5831 xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, left,
5832 width, height);
5833#else /* not USE_GTK */
5834 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
5835 left, top, width, height, 0);
5836#endif /* not USE_GTK */
5837 }
5838#else /* not USE_TOOLKIT_SCROLL_BARS */
5839
5840 /* Clear areas not covered by the scroll bar because it's not as
5841 wide as the area reserved for it. This makes sure a
5842 previous mode line display is cleared after C-x 2 C-x 1, for
5843 example. */
5844 {
5845 int area_height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
5846 int rest = area_height - height;
5847 if (rest > 0 && width > 0)
5848 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5849 left, top, width, rest);
5850 }
5851
5852 /* Move/size the scroll bar window. */
5853 if (mask)
5854 {
5855 XWindowChanges wc;
5856
5857 wc.x = left;
5858 wc.y = top;
5859 wc.width = width;
5860 wc.height = height;
5861 XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
5862 mask, &wc);
5863 }
5864
5865#endif /* not USE_TOOLKIT_SCROLL_BARS */
5866
5867 /* Remember new settings. */
5868 bar->left = left;
5869 bar->top = top;
5870 bar->width = width;
5871 bar->height = height;
5872
5873 unblock_input ();
5874 }
5875
5876#ifdef USE_TOOLKIT_SCROLL_BARS
5877 x_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
5878#else /* not USE_TOOLKIT_SCROLL_BARS */
5879 /* Set the scroll bar's current state, unless we're currently being
5880 dragged. */
5881 if (bar->dragging == -1)
5882 {
5883 int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width);
5884
5885 if (whole == 0)
5886 x_scroll_bar_set_handle (bar, 0, left_range, 0);
5887 else
5888 {
5889 int start = ((double) position * left_range) / whole;
5890 int end = ((double) (position + portion) * left_range) / whole;
5891 x_scroll_bar_set_handle (bar, start, end, 0);
5892 }
5893 }
5894#endif /* not USE_TOOLKIT_SCROLL_BARS */
5895
5896 XSETVECTOR (barobj, bar);
5897 wset_horizontal_scroll_bar (w, barobj);
5898}
5899
5900
5337/* The following three hooks are used when we're doing a thorough 5901/* The following three hooks are used when we're doing a thorough
5338 redisplay of the frame. We don't explicitly know which scroll bars 5902 redisplay of the frame. We don't explicitly know which scroll bars
5339 are going to be deleted, because keeping track of when windows go 5903 are going to be deleted, because keeping track of when windows go
@@ -5349,17 +5913,22 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
5349static void 5913static void
5350XTcondemn_scroll_bars (struct frame *frame) 5914XTcondemn_scroll_bars (struct frame *frame)
5351{ 5915{
5352 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */ 5916 if (!NILP (FRAME_SCROLL_BARS (frame)))
5353 while (! NILP (FRAME_SCROLL_BARS (frame)))
5354 { 5917 {
5355 Lisp_Object bar; 5918 if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
5356 bar = FRAME_SCROLL_BARS (frame); 5919 {
5357 fset_scroll_bars (frame, XSCROLL_BAR (bar)->next); 5920 /* Prepend scrollbars to already condemned ones. */
5358 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame); 5921 Lisp_Object last = FRAME_SCROLL_BARS (frame);
5359 XSCROLL_BAR (bar)->prev = Qnil; 5922
5360 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame))) 5923 while (!NILP (XSCROLL_BAR (last)->next))
5361 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar; 5924 last = XSCROLL_BAR (last)->next;
5362 fset_condemned_scroll_bars (frame, bar); 5925
5926 XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
5927 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
5928 }
5929
5930 fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
5931 fset_scroll_bars (frame, Qnil);
5363 } 5932 }
5364} 5933}
5365 5934
@@ -5368,47 +5937,84 @@ XTcondemn_scroll_bars (struct frame *frame)
5368 Note that WINDOW isn't necessarily condemned at all. */ 5937 Note that WINDOW isn't necessarily condemned at all. */
5369 5938
5370static void 5939static void
5371XTredeem_scroll_bar (struct window *window) 5940XTredeem_scroll_bar (struct window *w)
5372{ 5941{
5373 struct scroll_bar *bar; 5942 struct scroll_bar *bar;
5374 struct frame *f;
5375 Lisp_Object barobj; 5943 Lisp_Object barobj;
5944 struct frame *f;
5376 5945
5377 /* We can't redeem this window's scroll bar if it doesn't have one. */ 5946 /* We can't redeem this window's scroll bar if it doesn't have one. */
5378 if (NILP (window->vertical_scroll_bar)) 5947 if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
5379 emacs_abort (); 5948 emacs_abort ();
5380 5949
5381 bar = XSCROLL_BAR (window->vertical_scroll_bar); 5950 if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
5382
5383 /* Unlink it from the condemned list. */
5384 f = XFRAME (WINDOW_FRAME (window));
5385 if (NILP (bar->prev))
5386 { 5951 {
5387 /* If the prev pointer is nil, it must be the first in one of 5952 bar = XSCROLL_BAR (w->vertical_scroll_bar);
5388 the lists. */ 5953 /* Unlink it from the condemned list. */
5389 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar)) 5954 f = XFRAME (WINDOW_FRAME (w));
5390 /* It's not condemned. Everything's fine. */ 5955 if (NILP (bar->prev))
5391 return; 5956 {
5392 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f), 5957 /* If the prev pointer is nil, it must be the first in one of
5393 window->vertical_scroll_bar)) 5958 the lists. */
5394 fset_condemned_scroll_bars (f, bar->next); 5959 if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
5960 /* It's not condemned. Everything's fine. */
5961 goto horizontal;
5962 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
5963 w->vertical_scroll_bar))
5964 fset_condemned_scroll_bars (f, bar->next);
5965 else
5966 /* If its prev pointer is nil, it must be at the front of
5967 one or the other! */
5968 emacs_abort ();
5969 }
5395 else 5970 else
5396 /* If its prev pointer is nil, it must be at the front of 5971 XSCROLL_BAR (bar->prev)->next = bar->next;
5397 one or the other! */ 5972
5398 emacs_abort (); 5973 if (! NILP (bar->next))
5974 XSCROLL_BAR (bar->next)->prev = bar->prev;
5975
5976 bar->next = FRAME_SCROLL_BARS (f);
5977 bar->prev = Qnil;
5978 XSETVECTOR (barobj, bar);
5979 fset_scroll_bars (f, barobj);
5980 if (! NILP (bar->next))
5981 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
5399 } 5982 }
5400 else
5401 XSCROLL_BAR (bar->prev)->next = bar->next;
5402 5983
5403 if (! NILP (bar->next)) 5984 horizontal:
5404 XSCROLL_BAR (bar->next)->prev = bar->prev; 5985 if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
5986 {
5987 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
5988 /* Unlink it from the condemned list. */
5989 f = XFRAME (WINDOW_FRAME (w));
5990 if (NILP (bar->prev))
5991 {
5992 /* If the prev pointer is nil, it must be the first in one of
5993 the lists. */
5994 if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
5995 /* It's not condemned. Everything's fine. */
5996 return;
5997 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
5998 w->horizontal_scroll_bar))
5999 fset_condemned_scroll_bars (f, bar->next);
6000 else
6001 /* If its prev pointer is nil, it must be at the front of
6002 one or the other! */
6003 emacs_abort ();
6004 }
6005 else
6006 XSCROLL_BAR (bar->prev)->next = bar->next;
5405 6007
5406 bar->next = FRAME_SCROLL_BARS (f); 6008 if (! NILP (bar->next))
5407 bar->prev = Qnil; 6009 XSCROLL_BAR (bar->next)->prev = bar->prev;
5408 XSETVECTOR (barobj, bar); 6010
5409 fset_scroll_bars (f, barobj); 6011 bar->next = FRAME_SCROLL_BARS (f);
5410 if (! NILP (bar->next)) 6012 bar->prev = Qnil;
5411 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); 6013 XSETVECTOR (barobj, bar);
6014 fset_scroll_bars (f, barobj);
6015 if (! NILP (bar->next))
6016 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
6017 }
5412} 6018}
5413 6019
5414/* Remove all scroll bars on FRAME that haven't been saved since the 6020/* Remove all scroll bars on FRAME that haven't been saved since the
@@ -5493,7 +6099,9 @@ x_scroll_bar_handle_click (struct scroll_bar *bar,
5493 if (! WINDOWP (bar->window)) 6099 if (! WINDOWP (bar->window))
5494 emacs_abort (); 6100 emacs_abort ();
5495 6101
5496 emacs_event->kind = SCROLL_BAR_CLICK_EVENT; 6102 emacs_event->kind = (bar->horizontal
6103 ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
6104 : SCROLL_BAR_CLICK_EVENT);
5497 emacs_event->code = event->xbutton.button - Button1; 6105 emacs_event->code = event->xbutton.button - Button1;
5498 emacs_event->modifiers 6106 emacs_event->modifiers
5499 = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO 6107 = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO
@@ -5505,36 +6113,68 @@ x_scroll_bar_handle_click (struct scroll_bar *bar,
5505 emacs_event->frame_or_window = bar->window; 6113 emacs_event->frame_or_window = bar->window;
5506 emacs_event->arg = Qnil; 6114 emacs_event->arg = Qnil;
5507 emacs_event->timestamp = event->xbutton.time; 6115 emacs_event->timestamp = event->xbutton.time;
5508 { 6116 if (bar->horizontal)
5509 int top_range 6117 {
5510 = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height); 6118 int left_range
5511 int y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER; 6119 = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
6120 int x = event->xbutton.x - HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
5512 6121
5513 if (y < 0) y = 0; 6122 if (x < 0) x = 0;
5514 if (y > top_range) y = top_range; 6123 if (x > left_range) x = left_range;
5515 6124
5516 if (y < bar->start) 6125 if (x < bar->start)
5517 emacs_event->part = scroll_bar_above_handle; 6126 emacs_event->part = scroll_bar_before_handle;
5518 else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE) 6127 else if (x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
5519 emacs_event->part = scroll_bar_handle; 6128 emacs_event->part = scroll_bar_horizontal_handle;
5520 else 6129 else
5521 emacs_event->part = scroll_bar_below_handle; 6130 emacs_event->part = scroll_bar_after_handle;
5522 6131
5523#ifndef USE_TOOLKIT_SCROLL_BARS 6132#ifndef USE_TOOLKIT_SCROLL_BARS
5524 /* If the user has released the handle, set it to its final position. */ 6133 /* If the user has released the handle, set it to its final position. */
5525 if (event->type == ButtonRelease && bar->dragging != -1) 6134 if (event->type == ButtonRelease && bar->dragging != -1)
5526 { 6135 {
5527 int new_start = y - bar->dragging; 6136 int new_start = - bar->dragging;
5528 int new_end = new_start + bar->end - bar->start; 6137 int new_end = new_start + bar->end - bar->start;
5529 6138
5530 x_scroll_bar_set_handle (bar, new_start, new_end, 0); 6139 x_scroll_bar_set_handle (bar, new_start, new_end, 0);
5531 bar->dragging = -1; 6140 bar->dragging = -1;
5532 } 6141 }
5533#endif 6142#endif
5534 6143
5535 XSETINT (emacs_event->x, y); 6144 XSETINT (emacs_event->x, left_range);
5536 XSETINT (emacs_event->y, top_range); 6145 XSETINT (emacs_event->y, x);
5537 } 6146 }
6147 else
6148 {
6149 int top_range
6150 = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
6151 int y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER;
6152
6153 if (y < 0) y = 0;
6154 if (y > top_range) y = top_range;
6155
6156 if (y < bar->start)
6157 emacs_event->part = scroll_bar_above_handle;
6158 else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
6159 emacs_event->part = scroll_bar_handle;
6160 else
6161 emacs_event->part = scroll_bar_below_handle;
6162
6163#ifndef USE_TOOLKIT_SCROLL_BARS
6164 /* If the user has released the handle, set it to its final position. */
6165 if (event->type == ButtonRelease && bar->dragging != -1)
6166 {
6167 int new_start = y - bar->dragging;
6168 int new_end = new_start + bar->end - bar->start;
6169
6170 x_scroll_bar_set_handle (bar, new_start, new_end, 0);
6171 bar->dragging = -1;
6172 }
6173#endif
6174
6175 XSETINT (emacs_event->x, y);
6176 XSETINT (emacs_event->y, top_range);
6177 }
5538} 6178}
5539 6179
5540#ifndef USE_TOOLKIT_SCROLL_BARS 6180#ifndef USE_TOOLKIT_SCROLL_BARS
@@ -5641,6 +6281,75 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
5641} 6281}
5642 6282
5643 6283
6284/* Return information to the user about the current position of the mouse
6285 on the scroll bar. */
6286
6287static void
6288x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
6289 enum scroll_bar_part *part, Lisp_Object *x,
6290 Lisp_Object *y, Time *timestamp)
6291{
6292 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
6293 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
6294 Window w = bar->x_window;
6295 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
6296 int win_x, win_y;
6297 Window dummy_window;
6298 int dummy_coord;
6299 unsigned int dummy_mask;
6300
6301 block_input ();
6302
6303 /* Get the mouse's position relative to the scroll bar window, and
6304 report that. */
6305 if (XQueryPointer (FRAME_X_DISPLAY (f), w,
6306
6307 /* Root, child, root x and root y. */
6308 &dummy_window, &dummy_window,
6309 &dummy_coord, &dummy_coord,
6310
6311 /* Position relative to scroll bar. */
6312 &win_x, &win_y,
6313
6314 /* Mouse buttons and modifier keys. */
6315 &dummy_mask))
6316 {
6317 int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
6318
6319 win_x -= HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
6320
6321 if (bar->dragging != -1)
6322 win_x -= bar->dragging;
6323
6324 if (win_x < 0)
6325 win_x = 0;
6326 if (win_x > left_range)
6327 win_x = left_range;
6328
6329 *fp = f;
6330 *bar_window = bar->window;
6331
6332 if (bar->dragging != -1)
6333 *part = scroll_bar_horizontal_handle;
6334 else if (win_x < bar->start)
6335 *part = scroll_bar_before_handle;
6336 else if (win_x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
6337 *part = scroll_bar_handle;
6338 else
6339 *part = scroll_bar_after_handle;
6340
6341 XSETINT (*y, win_x);
6342 XSETINT (*x, left_range);
6343
6344 f->mouse_moved = 0;
6345 dpyinfo->last_mouse_scroll_bar = NULL;
6346 *timestamp = dpyinfo->last_mouse_movement_time;
6347 }
6348
6349 unblock_input ();
6350}
6351
6352
5644/* The screen has been cleared so we may have changed foreground or 6353/* The screen has been cleared so we may have changed foreground or
5645 background colors, and the scroll bars may need to be redrawn. 6354 background colors, and the scroll bars may need to be redrawn.
5646 Clear out the scroll bars, and ask for expose events, so we can 6355 Clear out the scroll bars, and ask for expose events, so we can
@@ -5783,6 +6492,35 @@ static void xembed_send_message (struct frame *f, Time,
5783 enum xembed_message, 6492 enum xembed_message,
5784 long detail, long data1, long data2); 6493 long detail, long data1, long data2);
5785 6494
6495static void
6496x_net_wm_state (struct frame *f, Window window)
6497{
6498 int value = FULLSCREEN_NONE;
6499 Lisp_Object lval = Qnil;
6500 int sticky = 0;
6501
6502 (void)get_current_wm_state (f, window, &value, &sticky);
6503
6504 switch (value)
6505 {
6506 case FULLSCREEN_WIDTH:
6507 lval = Qfullwidth;
6508 break;
6509 case FULLSCREEN_HEIGHT:
6510 lval = Qfullheight;
6511 break;
6512 case FULLSCREEN_BOTH:
6513 lval = Qfullboth;
6514 break;
6515 case FULLSCREEN_MAXIMIZED:
6516 lval = Qmaximized;
6517 break;
6518 }
6519
6520 store_frame_param (f, Qfullscreen, lval);
6521/** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/
6522}
6523
5786/* Handles the XEvent EVENT on display DPYINFO. 6524/* Handles the XEvent EVENT on display DPYINFO.
5787 6525
5788 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. 6526 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
@@ -5980,6 +6718,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
5980 *finish = X_EVENT_GOTO_OUT; 6718 *finish = X_EVENT_GOTO_OUT;
5981 goto done; 6719 goto done;
5982 } 6720 }
6721 else if (event->xclient.message_type == dpyinfo->Xatom_Horizontal_Scrollbar)
6722 {
6723 x_horizontal_scroll_bar_to_input_event (event, &inev.ie);
6724 *finish = X_EVENT_GOTO_OUT;
6725 goto done;
6726 }
5983#endif /* USE_TOOLKIT_SCROLL_BARS */ 6727#endif /* USE_TOOLKIT_SCROLL_BARS */
5984 6728
5985 /* XEmbed messages from the embedder (if any). */ 6729 /* XEmbed messages from the embedder (if any). */
@@ -6131,7 +6875,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6131 goto OTHER; 6875 goto OTHER;
6132#else /* not USE_TOOLKIT_SCROLL_BARS */ 6876#else /* not USE_TOOLKIT_SCROLL_BARS */
6133 bar = x_window_to_scroll_bar (event->xexpose.display, 6877 bar = x_window_to_scroll_bar (event->xexpose.display,
6134 event->xexpose.window); 6878 event->xexpose.window, 2);
6135 6879
6136 if (bar) 6880 if (bar)
6137 x_scroll_bar_expose (bar, event); 6881 x_scroll_bar_expose (bar, event);
@@ -6695,7 +7439,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6695#ifndef USE_TOOLKIT_SCROLL_BARS 7439#ifndef USE_TOOLKIT_SCROLL_BARS
6696 struct scroll_bar *bar 7440 struct scroll_bar *bar
6697 = x_window_to_scroll_bar (event->xmotion.display, 7441 = x_window_to_scroll_bar (event->xmotion.display,
6698 event->xmotion.window); 7442 event->xmotion.window, 2);
6699 7443
6700 if (bar) 7444 if (bar)
6701 x_scroll_bar_note_movement (bar, &event->xmotion); 7445 x_scroll_bar_note_movement (bar, &event->xmotion);
@@ -6728,6 +7472,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6728#endif 7472#endif
6729 if (f) 7473 if (f)
6730 { 7474 {
7475 x_net_wm_state (f, event->xconfigure.window);
7476
6731#ifndef USE_X_TOOLKIT 7477#ifndef USE_X_TOOLKIT
6732#ifndef USE_GTK 7478#ifndef USE_GTK
6733 int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width); 7479 int width = FRAME_PIXEL_TO_TEXT_WIDTH (f, event->xconfigure.width);
@@ -6838,7 +7584,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6838 { 7584 {
6839 struct scroll_bar *bar 7585 struct scroll_bar *bar
6840 = x_window_to_scroll_bar (event->xbutton.display, 7586 = x_window_to_scroll_bar (event->xbutton.display,
6841 event->xbutton.window); 7587 event->xbutton.window, 2);
6842 7588
6843#ifdef USE_TOOLKIT_SCROLL_BARS 7589#ifdef USE_TOOLKIT_SCROLL_BARS
6844 /* Make the "Ctrl-Mouse-2 splits window" work for toolkit 7590 /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
@@ -7824,10 +8570,10 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
7824 FRAME_COLUMN_WIDTH (f) = font->average_width; 8570 FRAME_COLUMN_WIDTH (f) = font->average_width;
7825 FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); 8571 FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font);
7826 8572
7827 FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); 8573#ifndef USE_X_TOOLKIT \
8574/** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); **/
7828 FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); 8575 FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
7829 8576#endif
7830 compute_fringe_widths (f, 1);
7831 8577
7832 /* Compute character columns occupied by scrollbar. 8578 /* Compute character columns occupied by scrollbar.
7833 8579
@@ -8658,7 +9404,7 @@ x_wait_for_event (struct frame *f, int eventtype)
8658} 9404}
8659 9405
8660 9406
8661/* Change the size of frame F's X window to COLS/ROWS in the case F 9407/* Change the size of frame F's X window to WIDTH/HEIGHT in the case F
8662 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to 9408 doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
8663 top-left-corner window gravity for this size change and subsequent 9409 top-left-corner window gravity for this size change and subsequent
8664 size changes. Otherwise we leave the window gravity unchanged. */ 9410 size changes. Otherwise we leave the window gravity unchanged. */
@@ -8668,23 +9414,39 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height,
8668{ 9414{
8669 int pixelwidth, pixelheight; 9415 int pixelwidth, pixelheight;
8670 9416
8671 check_frame_size (f, &width, &height, pixelwise); 9417/** if (pixelwise) **/
8672 9418/** { **/
8673 compute_fringe_widths (f, 0); 9419/** pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); **/
8674 9420/** pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); **/
8675 pixelwidth = ((pixelwise 9421/** } **/
8676 ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) 9422/** else **/
8677 : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)) 9423/** { **/
8678 + FRAME_TOOLBAR_WIDTH (f)); 9424/** pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width); **/
9425/** pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height); **/
9426/** } **/
9427
9428/** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOLBAR_HEIGHT (f); **/
9429 pixelwidth = (pixelwise
9430 ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width)
9431 : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width));
8679 pixelheight = ((pixelwise 9432 pixelheight = ((pixelwise
8680 ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) 9433 ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height)
8681 : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height)) 9434 : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height)));
8682 + FRAME_MENUBAR_HEIGHT (f) 9435
8683 + FRAME_TOOLBAR_HEIGHT (f)); 9436/** pixelwidth = ((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f))) **/
9437/** + FRAME_SCROLL_BAR_AREA_WIDTH (f) **/
9438/** + FRAME_TOTAL_FRINGE_WIDTH (f) **/
9439/** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
9440
9441/** pixelheight = ((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f))) **/
9442/** + FRAME_TOOLBAR_HEIGHT (f) **/
9443/** + FRAME_SCROLL_BAR_AREA_HEIGHT (f) **/
9444/** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/
9445
8684 if (change_gravity) f->win_gravity = NorthWestGravity; 9446 if (change_gravity) f->win_gravity = NorthWestGravity;
8685 x_wm_set_size_hint (f, 0, 0); 9447 x_wm_set_size_hint (f, 0, 0);
8686 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 9448 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
8687 pixelwidth, pixelheight); 9449 pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f));
8688 9450
8689 9451
8690 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to 9452 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
@@ -8714,7 +9476,7 @@ x_set_window_size_1 (struct frame *f, int change_gravity, int width, int height,
8714 x_wait_for_event (f, ConfigureNotify); 9476 x_wait_for_event (f, ConfigureNotify);
8715 else 9477 else
8716 { 9478 {
8717 change_frame_size (f, width, height, 0, 1, 0, 1); 9479 change_frame_size (f, pixelwidth, pixelheight, 0, 1, 0, 1);
8718 x_sync (f); 9480 x_sync (f);
8719 } 9481 }
8720} 9482}
@@ -8730,8 +9492,9 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
8730{ 9492{
8731 block_input (); 9493 block_input ();
8732 9494
8733 check_frame_size (f, &width, &height, pixelwise); 9495 /* The following breaks our calculations. If it's really needed,
8734 9496 think of something else. */
9497#if 0
8735 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 9498 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
8736 { 9499 {
8737 int text_width, text_height; 9500 int text_width, text_height;
@@ -8754,6 +9517,7 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
8754 9517
8755 change_frame_size (f, text_width, text_height, 0, 1, 0, 1); 9518 change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
8756 } 9519 }
9520#endif
8757 9521
8758#ifdef USE_GTK 9522#ifdef USE_GTK
8759 if (FRAME_GTK_WIDGET (f)) 9523 if (FRAME_GTK_WIDGET (f))
@@ -8767,9 +9531,7 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
8767#else /* not USE_GTK */ 9531#else /* not USE_GTK */
8768 9532
8769 x_set_window_size_1 (f, change_gravity, width, height, pixelwise); 9533 x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
8770#if !defined USE_X_TOOLKIT
8771 x_clear_under_internal_border (f); 9534 x_clear_under_internal_border (f);
8772#endif
8773 9535
8774#endif /* not USE_GTK */ 9536#endif /* not USE_GTK */
8775 9537
@@ -8783,6 +9545,8 @@ x_set_window_size (struct frame *f, int change_gravity, int width, int height, b
8783 cancel_mouse_face (f); 9545 cancel_mouse_face (f);
8784 9546
8785 unblock_input (); 9547 unblock_input ();
9548
9549 do_pending_window_change (0);
8786} 9550}
8787 9551
8788/* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */ 9552/* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
@@ -9419,6 +10183,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
9419 XSizeHints size_hints; 10183 XSizeHints size_hints;
9420 Window window = FRAME_OUTER_WINDOW (f); 10184 Window window = FRAME_OUTER_WINDOW (f);
9421 10185
10186 if (!window)
10187 return;
10188
9422#ifdef USE_X_TOOLKIT 10189#ifdef USE_X_TOOLKIT
9423 if (f->output_data.x->widget) 10190 if (f->output_data.x->widget)
9424 { 10191 {
@@ -9452,8 +10219,6 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
9452 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); 10219 base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
9453 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); 10220 base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
9454 10221
9455 check_frame_size (f, &min_cols, &min_rows, 0);
9456
9457 if (frame_resize_pixelwise) 10222 if (frame_resize_pixelwise)
9458 /* Needed to prevent a bad protocol error crash when making the 10223 /* Needed to prevent a bad protocol error crash when making the
9459 frame size very small. */ 10224 frame size very small. */
@@ -10079,6 +10844,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10079 dpyinfo->vertical_scroll_bar_cursor 10844 dpyinfo->vertical_scroll_bar_cursor
10080 = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow); 10845 = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
10081 10846
10847 dpyinfo->horizontal_scroll_bar_cursor
10848 = XCreateFontCursor (dpyinfo->display, XC_sb_h_double_arrow);
10849
10082 xrdb = x_load_resources (dpyinfo->display, xrm_option, 10850 xrdb = x_load_resources (dpyinfo->display, xrm_option,
10083 resource_name, EMACS_CLASS); 10851 resource_name, EMACS_CLASS);
10084#ifdef HAVE_XRMSETDATABASE 10852#ifdef HAVE_XRMSETDATABASE
@@ -10214,6 +10982,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10214 ATOM_REFS_INIT ("DONE", Xatom_DONE) 10982 ATOM_REFS_INIT ("DONE", Xatom_DONE)
10215 ATOM_REFS_INIT ("PAGE", Xatom_PAGE) 10983 ATOM_REFS_INIT ("PAGE", Xatom_PAGE)
10216 ATOM_REFS_INIT ("SCROLLBAR", Xatom_Scrollbar) 10984 ATOM_REFS_INIT ("SCROLLBAR", Xatom_Scrollbar)
10985 ATOM_REFS_INIT ("HORIZONTAL_SCROLLBAR", Xatom_Horizontal_Scrollbar)
10217 ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED) 10986 ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED)
10218 /* EWMH */ 10987 /* EWMH */
10219 ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state) 10988 ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state)
@@ -10602,6 +11371,7 @@ x_create_terminal (struct x_display_info *dpyinfo)
10602 terminal->popup_dialog_hook = xw_popup_dialog; 11371 terminal->popup_dialog_hook = xw_popup_dialog;
10603#endif 11372#endif
10604 terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; 11373 terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
11374 terminal->set_horizontal_scroll_bar_hook = XTset_horizontal_scroll_bar;
10605 terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars; 11375 terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
10606 terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar; 11376 terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
10607 terminal->judge_scroll_bars_hook = XTjudge_scroll_bars; 11377 terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
diff --git a/src/xterm.h b/src/xterm.h
index 569433e4242..3e92ebd2317 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -175,6 +175,9 @@ struct x_display_info
175 /* The cursor to use for vertical scroll bars. */ 175 /* The cursor to use for vertical scroll bars. */
176 Cursor vertical_scroll_bar_cursor; 176 Cursor vertical_scroll_bar_cursor;
177 177
178 /* The cursor to use for horizontal scroll bars. */
179 Cursor horizontal_scroll_bar_cursor;
180
178 /* The invisible cursor used for pointer blanking. 181 /* The invisible cursor used for pointer blanking.
179 Unused if this display supports Xfixes extension. */ 182 Unused if this display supports Xfixes extension. */
180 Cursor invisible_cursor; 183 Cursor invisible_cursor;
@@ -279,8 +282,8 @@ struct x_display_info
279 /* More atoms for Ghostscript support. */ 282 /* More atoms for Ghostscript support. */
280 Atom Xatom_DONE, Xatom_PAGE; 283 Atom Xatom_DONE, Xatom_PAGE;
281 284
282 /* Atom used in toolkit scroll bar client messages. */ 285 /* Atoms used in toolkit scroll bar client messages. */
283 Atom Xatom_Scrollbar; 286 Atom Xatom_Scrollbar, Xatom_Horizontal_Scrollbar;
284 287
285 /* Atom used in XEmbed client messages. */ 288 /* Atom used in XEmbed client messages. */
286 Atom Xatom_XEMBED, Xatom_XEMBED_INFO; 289 Atom Xatom_XEMBED, Xatom_XEMBED_INFO;
@@ -822,6 +825,14 @@ struct scroll_bar
822 /* Last scroll bar part seen in xaw_jump_callback and xaw_scroll_callback. */ 825 /* Last scroll bar part seen in xaw_jump_callback and xaw_scroll_callback. */
823 enum scroll_bar_part last_seen_part; 826 enum scroll_bar_part last_seen_part;
824#endif 827#endif
828
829#if defined (USE_TOOLKIT_SCROLL_BARS) && !defined (USE_GTK)
830 /* Last value of whole for horizontal scrollbars. */
831 int whole;
832#endif
833
834 /* 1 if the scroll bar is horizontal. */
835 bool horizontal;
825}; 836};
826 837
827/* Turning a lisp vector value into a pointer to a struct scroll_bar. */ 838/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
@@ -868,6 +879,28 @@ struct scroll_bar
868#define VERTICAL_SCROLL_BAR_INSIDE_HEIGHT(f, height) \ 879#define VERTICAL_SCROLL_BAR_INSIDE_HEIGHT(f, height) \
869 ((height) - VERTICAL_SCROLL_BAR_TOP_BORDER - VERTICAL_SCROLL_BAR_BOTTOM_BORDER) 880 ((height) - VERTICAL_SCROLL_BAR_TOP_BORDER - VERTICAL_SCROLL_BAR_BOTTOM_BORDER)
870 881
882/* Return the inside height of a horizontal scroll bar, given the outside
883 height. */
884#define HORIZONTAL_SCROLL_BAR_INSIDE_HEIGHT(f, height) \
885 ((height) \
886 - HORIZONTAL_SCROLL_BAR_TOP_BORDER \
887 - HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER)
888
889/* Return the length of the rectangle within which the left part of the
890 handle must stay. This isn't equivalent to the inside width, because
891 the scroll bar handle has a minimum width.
892
893 This is the real range of motion for the scroll bar, so when we're
894 scaling buffer positions to scroll bar positions, we use this, not
895 HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH. */
896#define HORIZONTAL_SCROLL_BAR_LEFT_RANGE(f, width) \
897 (HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH (f, width) - HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
898
899/* Return the inside width of horizontal scroll bar, given the outside
900 width. See HORIZONTAL_SCROLL_BAR_LEFT_RANGE too. */
901#define HORIZONTAL_SCROLL_BAR_INSIDE_WIDTH(f, width) \
902 ((width) - HORIZONTAL_SCROLL_BAR_LEFT_BORDER - HORIZONTAL_SCROLL_BAR_LEFT_BORDER)
903
871 904
872/* Border widths for scroll bars. 905/* Border widths for scroll bars.
873 906
@@ -885,8 +918,14 @@ struct scroll_bar
885#define VERTICAL_SCROLL_BAR_TOP_BORDER (2) 918#define VERTICAL_SCROLL_BAR_TOP_BORDER (2)
886#define VERTICAL_SCROLL_BAR_BOTTOM_BORDER (2) 919#define VERTICAL_SCROLL_BAR_BOTTOM_BORDER (2)
887 920
921#define HORIZONTAL_SCROLL_BAR_LEFT_BORDER (2)
922#define HORIZONTAL_SCROLL_BAR_RIGHT_BORDER (2)
923#define HORIZONTAL_SCROLL_BAR_TOP_BORDER (2)
924#define HORIZONTAL_SCROLL_BAR_BOTTOM_BORDER (2)
925
888/* Minimum lengths for scroll bar handles, in pixels. */ 926/* Minimum lengths for scroll bar handles, in pixels. */
889#define VERTICAL_SCROLL_BAR_MIN_HANDLE (5) 927#define VERTICAL_SCROLL_BAR_MIN_HANDLE (5)
928#define HORIZONTAL_SCROLL_BAR_MIN_HANDLE (5)
890 929
891/* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT 930/* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT
892 or SELECTION_CLEAR_EVENT, then its contents are really described 931 or SELECTION_CLEAR_EVENT, then its contents are really described
@@ -982,6 +1021,7 @@ x_display_pixel_width (struct x_display_info *dpyinfo)
982 1021
983extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object); 1022extern void x_set_sticky (struct frame *, Lisp_Object, Lisp_Object);
984extern void x_wait_for_event (struct frame *, int); 1023extern void x_wait_for_event (struct frame *, int);
1024extern void x_clear_under_internal_border (struct frame *f);
985 1025
986/* Defined in xselect.c. */ 1026/* Defined in xselect.c. */
987 1027
@@ -1063,10 +1103,6 @@ extern void x_session_close (void);
1063 1103
1064extern Lisp_Object Qx_gtk_map_stock; 1104extern Lisp_Object Qx_gtk_map_stock;
1065 1105
1066#if !defined USE_X_TOOLKIT && !defined USE_GTK
1067extern void x_clear_under_internal_border (struct frame *f);
1068#endif
1069
1070/* Is the frame embedded into another application? */ 1106/* Is the frame embedded into another application? */
1071 1107
1072#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0) 1108#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)