X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/1399490e2bb58e1e7212d7a8469e1286ced9423a..29aa2b718c072c78d0fda78ae40b0a0d2e32bdbd:/src/window.c diff --git a/src/window.c b/src/window.c index 76432f8bb6..cb505eda81 100644 --- a/src/window.c +++ b/src/window.c @@ -20,8 +20,6 @@ along with GNU Emacs. If not, see . */ #include -#define WINDOW_INLINE EXTERN_INLINE - #include #include "lisp.h" @@ -39,19 +37,12 @@ along with GNU Emacs. If not, see . */ #include "blockinput.h" #include "intervals.h" #include "termhooks.h" /* For FRAME_TERMINAL. */ - -#ifdef HAVE_X_WINDOWS -#include "xterm.h" -#endif /* HAVE_X_WINDOWS */ -#ifdef HAVE_NTGUI -#include "w32term.h" -#endif +#ifdef HAVE_WINDOW_SYSTEM +#include TERM_HEADER +#endif /* HAVE_WINDOW_SYSTEM */ #ifdef MSDOS #include "msdos.h" #endif -#ifdef HAVE_NS -#include "nsterm.h" -#endif Lisp_Object Qwindowp, Qwindow_live_p; static Lisp_Object Qwindow_valid_p; @@ -66,14 +57,11 @@ static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; static int displayed_window_lines (struct window *); static int count_windows (struct window *); static int get_leaf_windows (struct window *, struct window **, int); -static void window_scroll (Lisp_Object, EMACS_INT, int, int); -static void window_scroll_pixel_based (Lisp_Object, int, int, int); -static void window_scroll_line_based (Lisp_Object, int, int, int); -static int freeze_window_start (struct window *, void *); +static void window_scroll (Lisp_Object, EMACS_INT, bool, int); +static void window_scroll_pixel_based (Lisp_Object, int, bool, int); +static void window_scroll_line_based (Lisp_Object, int, bool, int); static Lisp_Object window_list (void); static int add_window_to_list (struct window *, void *); -static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object, - Lisp_Object); static Lisp_Object next_window (Lisp_Object, Lisp_Object, Lisp_Object, int); static void decode_next_window_args (Lisp_Object *, Lisp_Object *, @@ -90,6 +78,14 @@ static void window_resize_apply (struct window *, bool); static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); static void select_window_1 (Lisp_Object, bool); +static struct window *set_window_fringes (struct window *, Lisp_Object, + Lisp_Object, Lisp_Object); +static struct window *set_window_margins (struct window *, Lisp_Object, + Lisp_Object); +static struct window *set_window_scroll_bars (struct window *, Lisp_Object, + Lisp_Object, Lisp_Object); +static void apply_window_adjustment (struct window *); + /* This is the window in which the terminal's cursor should be left when nothing is being done with it. This must always be a leaf window, and its buffer is selected by @@ -154,16 +150,6 @@ wset_display_table (struct window *w, Lisp_Object val) w->display_table = val; } static void -wset_left_fringe_width (struct window *w, Lisp_Object val) -{ - w->left_fringe_width = val; -} -static void -wset_left_margin_cols (struct window *w, Lisp_Object val) -{ - w->left_margin_cols = val; -} -static void wset_new_normal (struct window *w, Lisp_Object val) { w->new_normal = val; @@ -194,21 +180,6 @@ wset_pointm (struct window *w, Lisp_Object val) w->pointm = val; } static void -wset_right_fringe_width (struct window *w, Lisp_Object val) -{ - w->right_fringe_width = val; -} -static void -wset_right_margin_cols (struct window *w, Lisp_Object val) -{ - w->right_margin_cols = val; -} -static void -wset_scroll_bar_width (struct window *w, Lisp_Object val) -{ - w->scroll_bar_width = val; -} -static void wset_start (struct window *w, Lisp_Object val) { w->start = val; @@ -241,6 +212,17 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val) w->horizontal = horflag; } +/* Nonzero if leaf window W doesn't reflect the actual state + of displayed buffer due to its text or overlays change. */ + +bool +window_outdated (struct window *w) +{ + struct buffer *b = XBUFFER (w->contents); + return (w->last_modified < BUF_MODIFF (b) + || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)); +} + struct window * decode_live_window (register Lisp_Object window) { @@ -490,7 +472,6 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) CHECK_LIVE_WINDOW (window); w = XWINDOW (window); - w->frozen_window_start_p = 0; /* Make the selected window's buffer current. */ Fset_buffer (w->contents); @@ -559,15 +540,7 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap) than one window. It also matters when redisplay_window has altered point after scrolling, because it makes the change only in the window. */ - { - register ptrdiff_t new_point = marker_position (XWINDOW (window)->pointm); - if (new_point < BEGV) - SET_PT (BEGV); - else if (new_point > ZV) - SET_PT (ZV); - else - SET_PT (new_point); - } + set_point_from_marker (XWINDOW (window)->pointm); } DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, @@ -972,7 +945,7 @@ calc_absolute_offset (struct window *w, int *add_x, int *add_y) #endif #ifdef FRAME_TOOLBAR_TOP_HEIGHT *add_y += FRAME_TOOLBAR_TOP_HEIGHT (f); -#elif FRAME_TOOLBAR_HEIGHT +#elif defined (FRAME_TOOLBAR_HEIGHT) *add_y += FRAME_TOOLBAR_HEIGHT (f); #endif #ifdef FRAME_NS_TITLEBAR_HEIGHT @@ -1355,7 +1328,7 @@ struct check_window_data static int check_window_containing (struct window *w, void *user_data) { - struct check_window_data *cw = (struct check_window_data *) user_data; + struct check_window_data *cw = user_data; enum window_part found; int continue_p = 1; @@ -1404,6 +1377,7 @@ window_from_coordinates (struct frame *f, int x, int y, cw.window = &window, cw.x = x, cw.y = y; cw.part = part; foreach_window (f, check_window_containing, &cw); +#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS) /* If not found above, see if it's in the tool bar window, if a tool bar exists. */ if (NILP (window) @@ -1416,6 +1390,7 @@ window_from_coordinates (struct frame *f, int x, int y, *part = ON_TEXT; window = f->tool_bar_window; } +#endif return window; } @@ -1508,12 +1483,10 @@ if it isn't already recorded. */) || !w->window_end_valid || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) && !noninteractive) { struct text_pos startp; - ptrdiff_t charpos = marker_position (w->start); struct it it; struct buffer *old_buffer = NULL; void *itdata = NULL; @@ -1531,12 +1504,7 @@ if it isn't already recorded. */) `-l' containing a call to `rmail' with subsequent other commands. At the end, W->start happened to be BEG, while rmail had already narrowed the buffer. */ - if (charpos < BEGV) - SET_TEXT_POS (startp, BEGV, BEGV_BYTE); - else if (charpos > ZV) - SET_TEXT_POS (startp, ZV, ZV_BYTE); - else - SET_TEXT_POS_FROM_MARKER (startp, w->start); + CLIP_TEXT_POS_FROM_MARKER (startp, w->start); itdata = bidi_shelve_cache (); start_display (&it, w, startp); @@ -1550,7 +1518,7 @@ if it isn't already recorded. */) set_buffer_internal (old_buffer); } else - XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos)); + XSETINT (value, BUF_Z (b) - w->window_end_pos); return value; } @@ -1606,9 +1574,8 @@ overriding motion of point in order to display at this exact start. */) if (NILP (noforce)) w->force_start = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; - if (!EQ (window, selected_window)) + if (w != XWINDOW (selected_window)) + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; return pos; @@ -1722,8 +1689,7 @@ Return nil if window display is not up-to-date. In that case, use || windows_or_buffers_changed || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) return Qnil; if (NILP (line)) @@ -2040,16 +2006,17 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag) n->desired_matrix = n->current_matrix = 0; n->vscroll = 0; memset (&n->cursor, 0, sizeof (n->cursor)); - memset (&n->last_cursor, 0, sizeof (n->last_cursor)); memset (&n->phys_cursor, 0, sizeof (n->phys_cursor)); - n->phys_cursor_type = -1; + n->last_cursor_vpos = 0; +#ifdef HAVE_WINDOW_SYSTEM + n->phys_cursor_type = NO_CURSOR; n->phys_cursor_width = -1; +#endif n->must_be_updated_p = 0; n->pseudo_window_p = 0; - wset_window_end_vpos (n, make_number (0)); - wset_window_end_pos (n, make_number (0)); + n->window_end_vpos = 0; + n->window_end_pos = 0; n->window_end_valid = 0; - n->frozen_window_start_p = 0; } tem = o->next; @@ -2158,7 +2125,7 @@ delete_deletable_window (Lisp_Object window) static int add_window_to_list (struct window *w, void *user_data) { - Lisp_Object *list = (Lisp_Object *) user_data; + Lisp_Object *list = user_data; Lisp_Object window; XSETWINDOW (window, w); *list = Fcons (window, *list); @@ -2213,12 +2180,13 @@ window_list (void) a window means search the frame that window belongs to, a frame means consider windows on that frame, only. */ -static int -candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf, Lisp_Object all_frames) +static bool +candidate_window_p (Lisp_Object window, Lisp_Object owindow, + Lisp_Object minibuf, Lisp_Object all_frames) { struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); - int candidate_p = 1; + bool candidate_p = 1; if (!BUFFERP (w->contents)) candidate_p = 0; @@ -2855,7 +2823,7 @@ window-start value is reasonable when this function is called. */) block_input (); if (!FRAME_INITIAL_P (f)) { - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); /* We are going to free the glyph matrices of WINDOW, and with that we might lose any information about glyph rows that have @@ -2865,11 +2833,7 @@ window-start value is reasonable when this function is called. */) frame's up-to-date hook that mouse highlight was overwritten, so that it will arrange for redisplaying the highlight. */ if (EQ (hlinfo->mouse_face_window, window)) - { - hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; - hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; - hlinfo->mouse_face_window = Qnil; - } + reset_mouse_highlight (hlinfo); } free_window_matrices (r); @@ -2983,7 +2947,7 @@ window-start value is reasonable when this function is called. */) } } - adjust_glyphs (f); + adjust_frame_glyphs (f); unblock_input (); run_window_configuration_change_hook (f); @@ -3020,7 +2984,7 @@ replace_buffer_in_windows_safely (Lisp_Object buffer) minimum allowable size. */ void -check_frame_size (FRAME_PTR frame, int *rows, int *cols) +check_frame_size (struct frame *frame, int *rows, int *cols) { /* For height, we have to see: how many windows the frame has at minimum (one or two), @@ -3064,15 +3028,12 @@ adjust_window_margins (struct window *w) if (WINDOW_RIGHT_MARGIN_COLS (w) > 0) { if (WINDOW_LEFT_MARGIN_COLS (w) > 0) - { - wset_left_margin_cols (w, make_number (margin_cols / 2)); - wset_right_margin_cols (w, make_number (margin_cols / 2)); - } + w->left_margin_cols = w->right_margin_cols = margin_cols / 2; else - wset_right_margin_cols (w, make_number (margin_cols)); + w->right_margin_cols = margin_cols; } else - wset_left_margin_cols (w, make_number (margin_cols)); + w->left_margin_cols = margin_cols; return 1; } @@ -3086,18 +3047,18 @@ run_funs (Lisp_Object funs) call0 (XCAR (funs)); } -static Lisp_Object +static void select_window_norecord (Lisp_Object window) { - return WINDOW_LIVE_P (window) - ? Fselect_window (window, Qt) : selected_window; + if (WINDOW_LIVE_P (window)) + Fselect_window (window, Qt); } -static Lisp_Object +static void select_frame_norecord (Lisp_Object frame) { - return FRAME_LIVE_P (XFRAME (frame)) - ? Fselect_frame (frame, Qt) : selected_frame; + if (FRAME_LIVE_P (XFRAME (frame))) + Fselect_frame (frame, Qt); } void @@ -3120,7 +3081,7 @@ run_window_configuration_change_hook (struct frame *f) if (SELECTED_FRAME () != f) { - record_unwind_protect (select_frame_norecord, Fselected_frame ()); + record_unwind_protect (select_frame_norecord, selected_frame); select_frame_norecord (frame); } @@ -3135,7 +3096,7 @@ run_window_configuration_change_hook (struct frame *f) buffer))) { ptrdiff_t inner_count = SPECPDL_INDEX (); - record_unwind_protect (select_window_norecord, Fselected_window ()); + record_unwind_protect (select_window_norecord, selected_window); select_window_norecord (window); run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, buffer)); @@ -3186,9 +3147,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1)); bset_display_time (b, Fcurrent_time ()); - wset_window_end_pos (w, make_number (0)); - wset_window_end_vpos (w, make_number (0)); - memset (&w->last_cursor, 0, sizeof w->last_cursor); + w->window_end_pos = 0; + w->window_end_vpos = 0; + w->last_cursor_vpos = 0; if (!(keep_margins_p && samebuf)) { /* If we're not actually changing the buffer, don't reset hscroll and @@ -3207,8 +3168,6 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, buffer); w->start_at_line_beg = 0; w->force_start = 0; - w->last_modified = 0; - w->last_overlay_modified = 0; } /* Maybe we could move this into the `if' but it's not obviously safe and I doubt it's worth the trouble. */ @@ -3228,28 +3187,14 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, if (!keep_margins_p) { /* Set left and right marginal area width etc. from buffer. */ - - /* This may call adjust_window_margins three times, so - temporarily disable window margins. */ - Lisp_Object save_left = w->left_margin_cols; - Lisp_Object save_right = w->right_margin_cols; - - wset_left_margin_cols (w, Qnil); - wset_right_margin_cols (w, Qnil); - - Fset_window_fringes (window, - BVAR (b, left_fringe_width), BVAR (b, right_fringe_width), - BVAR (b, fringes_outside_margins)); - - Fset_window_scroll_bars (window, - BVAR (b, scroll_bar_width), - BVAR (b, vertical_scroll_bar_type), Qnil); - - wset_left_margin_cols (w, save_left); - wset_right_margin_cols (w, save_right); - - Fset_window_margins (window, - BVAR (b, left_margin_cols), BVAR (b, right_margin_cols)); + set_window_fringes (w, BVAR (b, left_fringe_width), + BVAR (b, right_fringe_width), + BVAR (b, fringes_outside_margins)); + set_window_scroll_bars (w, BVAR (b, scroll_bar_width), + BVAR (b, vertical_scroll_bar_type), Qnil); + set_window_margins (w, BVAR (b, left_margin_cols), + BVAR (b, right_margin_cols)); + apply_window_adjustment (w); } if (run_hooks_p) @@ -3385,10 +3330,8 @@ temp_output_buffer_show (register Lisp_Object buf) if (!NILP (Vtemp_buffer_show_function)) call1 (Vtemp_buffer_show_function, buf); - else + else if (WINDOW_LIVE_P (window = display_buffer (buf, Qnil, Qnil))) { - window = display_buffer (buf, Qnil, Qnil); - if (!EQ (XWINDOW (window)->frame, selected_frame)) Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); Vminibuf_scroll_window = window; @@ -3410,7 +3353,7 @@ temp_output_buffer_show (register Lisp_Object buf) Note: Both Fselect_window and select_window_norecord may set-buffer to the buffer displayed in the window, so we need to save the current buffer. --stef */ - record_unwind_protect (Fset_buffer, prev_buffer); + record_unwind_protect (restore_buffer, prev_buffer); record_unwind_protect (select_window_norecord, prev_window); Fselect_window (window, Qt); Fset_buffer (w->contents); @@ -3469,8 +3412,6 @@ make_window (void) wset_start (w, Fmake_marker ()); wset_pointm (w, Fmake_marker ()); wset_vertical_scroll_bar_type (w, Qt); - wset_window_end_pos (w, make_number (0)); - wset_window_end_vpos (w, make_number (0)); /* These Lisp fields are marked specially so they're not set to nil by allocate_window. */ wset_prev_buffers (w, Qnil); @@ -3479,8 +3420,13 @@ make_window (void) /* Initialize non-Lisp data. Note that allocate_window zeroes out all non-Lisp data, so do it only for slots which should not be zero. */ w->nrows_scale_factor = w->ncols_scale_factor = 1; - w->phys_cursor_type = -1; + w->left_fringe_width = w->right_fringe_width = -1; + w->mode_line_height = w->header_line_height = -1; +#ifdef HAVE_WINDOW_SYSTEM + w->phys_cursor_type = NO_CURSOR; w->phys_cursor_width = -1; +#endif + w->scroll_bar_width = -1; w->column_number_displayed = -1; /* Reset window_list. */ @@ -3669,10 +3615,6 @@ window_resize_apply (struct window *w, bool horflag) c = NILP (c->next) ? 0 : XWINDOW (c->next); } } - - /* Clear out some redisplay caches. */ - w->last_modified = 0; - w->last_overlay_modified = 0; } @@ -3707,7 +3649,7 @@ be applied on the Elisp level. */) windows_or_buffers_changed++; FRAME_WINDOW_SIZES_CHANGED (f) = 1; - adjust_glyphs (f); + adjust_frame_glyphs (f); unblock_input (); run_window_configuration_change_hook (f); @@ -3947,15 +3889,15 @@ set correctly. See the code of `split-window' for how this is done. */) } n->window_end_valid = 0; - memset (&n->last_cursor, 0, sizeof n->last_cursor); + n->last_cursor_vpos = 0; /* Get special geometry settings from reference window. */ - wset_left_margin_cols (n, r->left_margin_cols); - wset_right_margin_cols (n, r->right_margin_cols); - wset_left_fringe_width (n, r->left_fringe_width); - wset_right_fringe_width (n, r->right_fringe_width); + n->left_margin_cols = r->left_margin_cols; + n->right_margin_cols = r->right_margin_cols; + n->left_fringe_width = r->left_fringe_width; + n->right_fringe_width = r->right_fringe_width; n->fringes_outside_margins = r->fringes_outside_margins; - wset_scroll_bar_width (n, r->scroll_bar_width); + n->scroll_bar_width = r->scroll_bar_width; wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); /* Directly assign orthogonal coordinates and sizes. */ @@ -3977,7 +3919,7 @@ set correctly. See the code of `split-window' for how this is done. */) block_input (); window_resize_apply (p, horflag); - adjust_glyphs (f); + adjust_frame_glyphs (f); /* Set buffer of NEW to buffer of reference window. Don't run any hooks. */ set_window_buffer (new, r->contents, 0, 1); @@ -4106,7 +4048,7 @@ Signal an error when WINDOW is the only window on its frame. */) recombine_windows (sibling); } - adjust_glyphs (f); + adjust_frame_glyphs (f); if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f))) /* We deleted the frame's selected window. */ @@ -4191,11 +4133,9 @@ grow_mini_window (struct window *w, int delta) /* Grow the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines -= XINT (value); - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; - adjust_glyphs (f); + adjust_frame_glyphs (f); unblock_input (); } } @@ -4227,12 +4167,9 @@ shrink_mini_window (struct window *w) /* Shrink the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines = 1; - - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; - adjust_glyphs (f); + adjust_frame_glyphs (f); unblock_input (); } /* If the above failed for whatever strange reason we must make a @@ -4273,7 +4210,7 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini windows_or_buffers_changed++; FRAME_WINDOW_SIZES_CHANGED (f) = 1; - adjust_glyphs (f); + adjust_frame_glyphs (f); unblock_input (); run_window_configuration_change_hook (f); @@ -4337,7 +4274,7 @@ window_internal_height (struct window *w) respectively. */ static void -window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) +window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror) { immediate_quit = 1; n = clip_to_bounds (INT_MIN, n, INT_MAX); @@ -4358,7 +4295,7 @@ window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) descriptions. */ static void -window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) +window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror) { struct it it; struct window *w = XWINDOW (window); @@ -4368,6 +4305,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) int vscrolled = 0; int x, y, rtop, rbot, rowh, vpos; void *itdata = NULL; + int window_total_lines; + int frame_line_height = default_line_pixel_height (w); SET_TEXT_POS_FROM_MARKER (start, w->start); /* Scrolling a minibuffer window via scroll bar when the echo area @@ -4411,7 +4350,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) if (rtop || rbot) /* partially visible */ { int px; - int dy = WINDOW_FRAME_LINE_HEIGHT (w); + int dy = frame_line_height; if (whole) dy = max ((window_box_height (w) - next_screen_context_lines * dy), @@ -4454,8 +4393,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) w->contents); w->start_at_line_beg = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4497,7 +4434,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) if (whole) { ptrdiff_t start_pos = IT_CHARPOS (it); - int dy = WINDOW_FRAME_LINE_HEIGHT (w); + int dy = frame_line_height; dy = max ((window_box_height (w) - next_screen_context_lines * dy), dy) * n; @@ -4544,7 +4481,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) visible. */ w->vscroll = (it.last_visible_y - it.current_y + it.max_ascent + it.max_descent); - adjust_glyphs (it.f); + adjust_frame_glyphs (it.f); } else { @@ -4600,8 +4537,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) bytepos = marker_byte_position (w->start); w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4614,10 +4549,12 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) /* Move PT out of scroll margins. This code wants current_y to be zero at the window start position even if there is a header line. */ + window_total_lines + = w->total_lines * WINDOW_FRAME_LINE_HEIGHT (w) / frame_line_height; this_scroll_margin = max (0, scroll_margin); this_scroll_margin - = min (this_scroll_margin, w->total_lines / 4); - this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); + = min (this_scroll_margin, window_total_lines / 4); + this_scroll_margin *= frame_line_height; if (n > 0) { @@ -4722,7 +4659,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) See the comment of window_scroll for parameter descriptions. */ static void -window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) +window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror) { register struct window *w = XWINDOW (window); /* Fvertical_motion enters redisplay, which can trigger @@ -4734,7 +4671,7 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) register ptrdiff_t pos, pos_byte; register int ht = window_internal_height (w); register Lisp_Object tem; - int lose; + bool lose; Lisp_Object bolp; ptrdiff_t startpos = marker_position (w->start); ptrdiff_t startbyte = marker_byte_position (w->start); @@ -4798,8 +4735,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) set_marker_restricted_both (w->start, w->contents, pos, pos_byte); w->start_at_line_beg = !NILP (bolp); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -5095,7 +5030,6 @@ displayed_window_lines (struct window *w) { struct it it; struct text_pos start; - ptrdiff_t charpos = marker_position (w->start); int height = window_box_height (w); struct buffer *old_buffer; int bottom_y; @@ -5112,12 +5046,7 @@ displayed_window_lines (struct window *w) /* In case W->start is out of the accessible range, do something reasonable. This happens in Info mode when Info-scroll-down calls (recenter -1) while W->start is 1. */ - if (charpos < BEGV) - SET_TEXT_POS (start, BEGV, BEGV_BYTE); - else if (charpos > ZV) - SET_TEXT_POS (start, ZV, ZV_BYTE); - else - SET_TEXT_POS_FROM_MARKER (start, w->start); + CLIP_TEXT_POS_FROM_MARKER (start, w->start); itdata = bidi_shelve_cache (); start_display (&it, w, start); @@ -5168,7 +5097,7 @@ and redisplay normally--don't erase and redraw the frame. */) struct window *w = XWINDOW (selected_window); struct buffer *buf = XBUFFER (w->contents); struct buffer *obuf = current_buffer; - int center_p = 0; + bool center_p = 0; ptrdiff_t charpos, bytepos; EMACS_INT iarg IF_LINT (= 0); int this_scroll_margin; @@ -5187,9 +5116,9 @@ and redisplay normally--don't erase and redraw the frame. */) /* Invalidate pixel data calculated for all compositions. */ for (i = 0; i < n_compositions; i++) composition_table[i]->font = NULL; - +#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS) WINDOW_XFRAME (w)->minimize_tool_bar_window_p = 1; - +#endif Fredraw_frame (WINDOW_FRAME (w)); SET_FRAME_GARBAGED (WINDOW_XFRAME (w)); } @@ -5451,7 +5380,7 @@ struct save_window_data Lisp_Object saved_windows; /* All fields above are traced by the GC. - From `fame-cols' down, the fields are ignored by the GC. */ + From `frame-cols' down, the fields are ignored by the GC. */ int frame_cols, frame_lines, frame_menu_bar_lines; int frame_tool_bar_lines; @@ -5513,7 +5442,7 @@ the return value is nil. Otherwise the value is t. */) struct Lisp_Vector *saved_windows; Lisp_Object new_current_buffer; Lisp_Object frame; - FRAME_PTR f; + struct frame *f; ptrdiff_t old_point = -1; CHECK_WINDOW_CONFIGURATION (configuration); @@ -5611,17 +5540,25 @@ the return value is nil. Otherwise the value is t. */) || data->frame_cols != previous_frame_cols) change_frame_size (f, data->frame_lines, data->frame_cols, 0, 0, 0); -#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS) +#ifdef HAVE_MENUS if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines) - x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), - make_number (0)); + { +#ifdef HAVE_WINDOW_SYSTEM + if (FRAME_WINDOW_P (f)) + x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), + make_number (0)); + else /* TTY or MSDOS */ +#endif + set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), + make_number (0)); + } +#endif #ifdef HAVE_WINDOW_SYSTEM if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines) x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines), make_number (0)); -#endif #endif /* "Swap out" point from the selected window's buffer @@ -5700,12 +5637,12 @@ the return value is nil. Otherwise the value is t. */) w->hscroll = XFASTINT (p->hscroll); w->min_hscroll = XFASTINT (p->min_hscroll); wset_display_table (w, p->display_table); - wset_left_margin_cols (w, p->left_margin_cols); - wset_right_margin_cols (w, p->right_margin_cols); - wset_left_fringe_width (w, p->left_fringe_width); - wset_right_fringe_width (w, p->right_fringe_width); + w->left_margin_cols = XINT (p->left_margin_cols); + w->right_margin_cols = XINT (p->right_margin_cols); + w->left_fringe_width = XINT (p->left_fringe_width); + w->right_fringe_width = XINT (p->right_fringe_width); w->fringes_outside_margins = !NILP (p->fringes_outside_margins); - wset_scroll_bar_width (w, p->scroll_bar_width); + w->scroll_bar_width = XINT (p->scroll_bar_width); wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); wset_dedicated (w, p->dedicated); wset_combination_limit (w, p->combination_limit); @@ -5731,9 +5668,6 @@ the return value is nil. Otherwise the value is t. */) } } - w->last_modified = 0; - w->last_overlay_modified = 0; - if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) /* If saved buffer is alive, install it. */ { @@ -5812,15 +5746,24 @@ the return value is nil. Otherwise the value is t. */) || previous_frame_cols != FRAME_COLS (f)) change_frame_size (f, previous_frame_lines, previous_frame_cols, 0, 0, 0); -#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS) +#ifdef HAVE_MENUS if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) - x_set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines), - make_number (0)); + { +#ifdef HAVE_WINDOW_SYSTEM + if (FRAME_WINDOW_P (f)) + x_set_menu_bar_lines (f, + make_number (previous_frame_menu_bar_lines), + make_number (0)); + else /* TTY or MSDOS */ +#endif + set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines), + make_number (0)); + } +#endif #ifdef HAVE_WINDOW_SYSTEM if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f)) x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines), make_number (0)); -#endif #endif /* Now, free glyph matrices in windows that were not reused. */ @@ -5832,7 +5775,7 @@ the return value is nil. Otherwise the value is t. */) ++n; } - adjust_glyphs (f); + adjust_frame_glyphs (f); unblock_input (); /* Scan dead buffer windows. */ @@ -5869,6 +5812,12 @@ the return value is nil. Otherwise the value is t. */) return (FRAME_LIVE_P (f) ? Qt : Qnil); } +void +restore_window_configuration (Lisp_Object configuration) +{ + Fset_window_configuration (configuration); +} + /* If WINDOW is an internal window, recursively delete all child windows reachable via the next and contents slots of WINDOW. Otherwise setup @@ -5998,12 +5947,12 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i) XSETFASTINT (p->hscroll, w->hscroll); XSETFASTINT (p->min_hscroll, w->min_hscroll); p->display_table = w->display_table; - p->left_margin_cols = w->left_margin_cols; - p->right_margin_cols = w->right_margin_cols; - p->left_fringe_width = w->left_fringe_width; - p->right_fringe_width = w->right_fringe_width; + p->left_margin_cols = make_number (w->left_margin_cols); + p->right_margin_cols = make_number (w->right_margin_cols); + p->left_fringe_width = make_number (w->left_fringe_width); + p->right_fringe_width = make_number (w->right_fringe_width); p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; - p->scroll_bar_width = w->scroll_bar_width; + p->scroll_bar_width = make_number (w->scroll_bar_width); p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; p->dedicated = w->dedicated; p->combination_limit = w->combination_limit; @@ -6144,11 +6093,46 @@ saved by this function. */) XSETWINDOW_CONFIGURATION (tem, data); return (tem); } + +/* Called after W's margins, fringes or scroll bars was adjusted. */ + +static void +apply_window_adjustment (struct window *w) +{ + eassert (w); + adjust_window_margins (w); + clear_glyph_matrix (w->current_matrix); + w->window_end_valid = 0; + windows_or_buffers_changed++; + adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w))); +} + /*********************************************************************** Marginal Areas ***********************************************************************/ +static struct window * +set_window_margins (struct window *w, Lisp_Object left_width, + Lisp_Object right_width) +{ + int left, right; + + /* FIXME: what about margins that are too wide? */ + left = (NILP (left_width) ? 0 + : (CHECK_NATNUM (left_width), XINT (left_width))); + right = (NILP (right_width) ? 0 + : (CHECK_NATNUM (right_width), XINT (right_width))); + + if (w->left_margin_cols != left || w->right_margin_cols != right) + { + w->left_margin_cols = left; + w->right_margin_cols = right; + return w; + } + return NULL; +} + DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, 2, 3, 0, doc: /* Set width of marginal areas of window WINDOW. @@ -6157,41 +6141,14 @@ WINDOW must be a live window and defaults to the selected one. Second arg LEFT-WIDTH specifies the number of character cells to reserve for the left marginal area. Optional third arg RIGHT-WIDTH does the same for the right marginal area. A nil width parameter -means no margin. */) +means no margin. + +Return t if any margin was actually changed and nil otherwise. */) (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width) { - struct window *w = decode_live_window (window); - - /* Translate negative or zero widths to nil. - Margins that are too wide have to be checked elsewhere. */ - - if (!NILP (left_width)) - { - CHECK_NUMBER (left_width); - if (XINT (left_width) <= 0) - left_width = Qnil; - } - - if (!NILP (right_width)) - { - CHECK_NUMBER (right_width); - if (XINT (right_width) <= 0) - right_width = Qnil; - } - - if (!EQ (w->left_margin_cols, left_width) - || !EQ (w->right_margin_cols, right_width)) - { - wset_left_margin_cols (w, left_width); - wset_right_margin_cols (w, right_width); - - adjust_window_margins (w); - - ++windows_or_buffers_changed; - adjust_glyphs (XFRAME (WINDOW_FRAME (w))); - } - - return Qnil; + struct window *w = set_window_margins (decode_live_window (window), + left_width, right_width); + return w ? (apply_window_adjustment (w), Qt) : Qnil; } @@ -6206,7 +6163,8 @@ as nil. */) (Lisp_Object window) { struct window *w = decode_live_window (window); - return Fcons (w->left_margin_cols, w->right_margin_cols); + return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil, + w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil); } @@ -6215,6 +6173,31 @@ as nil. */) Fringes ***********************************************************************/ +static struct window * +set_window_fringes (struct window *w, Lisp_Object left_width, + Lisp_Object right_width, Lisp_Object outside_margins) +{ + int left, right, outside = !NILP (outside_margins); + + left = (NILP (left_width) ? -1 + : (CHECK_NATNUM (left_width), XINT (left_width))); + right = (NILP (right_width) ? -1 + : (CHECK_NATNUM (right_width), XINT (right_width))); + + /* Do nothing on a tty or if nothing to actually change. */ + if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) + && (w->left_fringe_width != left + || w->right_fringe_width != right + || w->fringes_outside_margins != outside)) + { + w->left_fringe_width = left; + w->right_fringe_width = right; + w->fringes_outside_margins = outside; + return w; + } + return NULL; +} + DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 2, 4, 0, doc: /* Set the fringe widths of window WINDOW. @@ -6227,37 +6210,16 @@ frame's default fringe width. Default fringe widths can be set with the command `set-fringe-style'. If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes outside of the display margins. By default, fringes are drawn between -display marginal areas and the text area. */) - (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins) -{ - struct window *w = decode_live_window (window); - int outside = !NILP (outside_margins); - - if (!NILP (left_width)) - CHECK_NATNUM (left_width); - if (!NILP (right_width)) - CHECK_NATNUM (right_width); - - /* Do nothing on a tty. */ - if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) - && (!EQ (w->left_fringe_width, left_width) - || !EQ (w->right_fringe_width, right_width) - || w->fringes_outside_margins != outside)) - { - wset_left_fringe_width (w, left_width); - wset_right_fringe_width (w, right_width); - w->fringes_outside_margins = outside; - - adjust_window_margins (w); - - clear_glyph_matrix (w->current_matrix); - w->window_end_valid = 0; - - ++windows_or_buffers_changed; - adjust_glyphs (XFRAME (WINDOW_FRAME (w))); - } +display marginal areas and the text area. - return Qnil; +Return t if any fringe was actually changed and nil otherwise. */) + (Lisp_Object window, Lisp_Object left_width, + Lisp_Object right_width, Lisp_Object outside_margins) +{ + struct window *w + = set_window_fringes (decode_live_window (window), + left_width, right_width, outside_margins); + return w ? (apply_window_adjustment (w), Qt) : Qnil; } @@ -6282,29 +6244,14 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */) Scroll bars ***********************************************************************/ -DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, - Sset_window_scroll_bars, 2, 4, 0, - doc: /* Set width and type of scroll bars of window WINDOW. -WINDOW must be a live window and defaults to the selected one. - -Second parameter WIDTH specifies the pixel width for the scroll bar; -this is automatically adjusted to a multiple of the frame column width. -Third parameter VERTICAL-TYPE specifies the type of the vertical scroll -bar: left, right, or nil. -If WIDTH is nil, use the frame's scroll-bar width. -If VERTICAL-TYPE is t, use the frame's scroll-bar type. -Fourth parameter HORIZONTAL-TYPE is currently unused. */) - (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, Lisp_Object horizontal_type) +static struct window * +set_window_scroll_bars (struct window *w, Lisp_Object width, + Lisp_Object vertical_type, Lisp_Object horizontal_type) { - struct window *w = decode_live_window (window); - - if (!NILP (width)) - { - CHECK_RANGED_INTEGER (width, 0, INT_MAX); + int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width))); - if (XINT (width) == 0) - vertical_type = Qnil; - } + if (iwidth == 0) + vertical_type = Qnil; if (!(NILP (vertical_type) || EQ (vertical_type, Qleft) @@ -6312,22 +6259,37 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */) || EQ (vertical_type, Qt))) error ("Invalid type of vertical scroll bar"); - if (!EQ (w->scroll_bar_width, width) + if (w->scroll_bar_width != iwidth || !EQ (w->vertical_scroll_bar_type, vertical_type)) { - wset_scroll_bar_width (w, width); + w->scroll_bar_width = iwidth; wset_vertical_scroll_bar_type (w, vertical_type); + return w; + } + return NULL; +} - adjust_window_margins (w); - - clear_glyph_matrix (w->current_matrix); - w->window_end_valid = 0; +DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, + Sset_window_scroll_bars, 2, 4, 0, + doc: /* Set width and type of scroll bars of window WINDOW. +WINDOW must be a live window and defaults to the selected one. - ++windows_or_buffers_changed; - adjust_glyphs (XFRAME (WINDOW_FRAME (w))); - } +Second parameter WIDTH specifies the pixel width for the scroll bar; +this is automatically adjusted to a multiple of the frame column width. +Third parameter VERTICAL-TYPE specifies the type of the vertical scroll +bar: left, right, or nil. +If WIDTH is nil, use the frame's scroll-bar width. +If VERTICAL-TYPE is t, use the frame's scroll-bar type. +Fourth parameter HORIZONTAL-TYPE is currently unused. - return Qnil; +Return t if scroll bars was actually changed and nil otherwise. */) + (Lisp_Object window, Lisp_Object width, + Lisp_Object vertical_type, Lisp_Object horizontal_type) +{ + struct window *w + = set_window_scroll_bars (decode_live_window (window), + width, vertical_type, horizontal_type); + return w ? (apply_window_adjustment (w), Qt) : Qnil; } @@ -6408,7 +6370,7 @@ If PIXELS-P is non-nil, the return value is VSCROLL. */) /* Adjust glyph matrix of the frame if the virtual display area becomes larger than before. */ if (w->vscroll < 0 && w->vscroll < old_dy) - adjust_glyphs (f); + adjust_frame_glyphs (f); /* Prevent redisplay shortcuts. */ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1; @@ -6456,38 +6418,6 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u return cont; } - -/* Freeze or unfreeze the window start of W unless it is a - mini-window or the selected window. FREEZE_P non-null means freeze - the window start. */ - -static int -freeze_window_start (struct window *w, void *freeze_p) -{ - if (MINI_WINDOW_P (w) - || (WINDOWP (selected_window) /* Can be nil in corner cases. */ - && (w == XWINDOW (selected_window) - || (MINI_WINDOW_P (XWINDOW (selected_window)) - && ! NILP (Vminibuf_scroll_window) - && w == XWINDOW (Vminibuf_scroll_window))))) - freeze_p = NULL; - - w->frozen_window_start_p = freeze_p != NULL; - return 1; -} - - -/* Freeze or unfreeze the window starts of all leaf windows on frame - F, except the selected window and a mini-window. FREEZE_P non-zero - means freeze the window start. */ - -void -freeze_window_starts (struct frame *f, bool freeze_p) -{ - foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0)); -} - - /*********************************************************************** Initialization ***********************************************************************/ @@ -6596,7 +6526,6 @@ init_window_once (void) Vterminal_frame = selected_frame; minibuf_window = f->minibuffer_window; selected_window = f->selected_window; - last_nonminibuf_frame = f; window_initialized = 1; }