This function attempts to redisplay a window by reusing parts of
its existing display. It finds and reuses the part that was not
- changed, and redraws the rest.
+ changed, and redraws the rest. (The "id" part in the function's
+ name stands for "insert/delete", not for "identification" or
+ somesuch.)
. try_window
optimizations were successful, redisplay calls redisplay_windows,
which performs a full redisplay of all windows.
+ Note that there's one more important optimization up Emacs's
+ sleeve, but it is related to actually redrawing the potentially
+ changed portions of the window/frame, not to reproducing the
+ desired matrices of those potentially changed portions. Namely,
+ the function update_frame and its subroutines, which you will find
+ in dispnew.c, compare the desired matrices with the current
+ matrices, and only redraw the portions that changed. So it could
+ happen that the functions in this file for some reason decide that
+ the entire desired matrix needs to be regenerated from scratch, and
+ still only parts of the Emacs display, or even nothing at all, will
+ be actually delivered to the glass, because update_frame has found
+ that the new and the old screen contents are similar or identical.
+
Desired matrices.
Desired matrices are always built per Emacs window. The function
/* Get the next character, maybe multibyte. */
p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
- if (it->multibyte_p && !ASCII_BYTE_P (*p))
+ if (it->multibyte_p && !ASCII_CHAR_P (*p))
it->c = STRING_CHAR_AND_LENGTH (p, it->len);
else
it->c = *p, it->len = 1;
for (i = 0; i < nbytes; i += char_bytes)
{
c = string_char_and_length (msg + i, &char_bytes);
- work[0] = (ASCII_CHAR_P (c)
- ? c
- : multibyte_char_to_unibyte (c));
+ work[0] = CHAR_TO_BYTE8 (c);
insert_1_both (work, 1, 1, 1, 0, 0);
}
}
{
int i, no_message_p, window_height_changed_p;
- /* Temporarily disable garbage collections while displaying the echo
- area. This is done because a GC can print a message itself.
- That message would modify the echo area buffer's contents while a
- redisplay of the buffer is going on, and seriously confuse
- redisplay. */
- ptrdiff_t count = inhibit_garbage_collection ();
-
/* If there is no message, we must call display_echo_area_1
nevertheless because it resizes the window. But we will have to
reset the echo_area_buffer in question to nil at the end because
if (no_message_p)
echo_area_buffer[i] = Qnil;
- unbind_to (count, Qnil);
return window_height_changed_p;
}
#endif /* !USE_GTK && !HAVE_NS */
-#if defined USE_GTK || defined HAVE_NS
-EXFUN (Ftool_bar_height, 2) ATTRIBUTE_CONST;
-EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
-#endif
-
DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
0, 2, 0,
doc: /* Return the number of lines occupied by the tool bar of FRAME.
selected_window is redisplayed.
We can return without actually redisplaying the window if fonts has been
- changed on window's frame. In that case, redisplay_internal will retry. */
+ changed on window's frame. In that case, redisplay_internal will retry.
+
+ As one of the important parts of redisplaying a window, we need to
+ decide whether the previous window-start position (stored in the
+ window's w->start marker position) is still valid, and if it isn't,
+ recompute it. Some details about that:
+
+ . The previous window-start could be in a continuation line, in
+ which case we need to recompute it when the window width
+ changes. See compute_window_start_on_continuation_line and its
+ call below.
+
+ . The text that changed since last redisplay could include the
+ previous window-start position. In that case, we try to salvage
+ what we can from the current glyph matrix by calling
+ try_scrolling, which see.
+
+ . Some Emacs command could force us to use a specific window-start
+ position by setting the window's force_start flag, or gently
+ propose doing that by setting the window's optional_new_start
+ flag. In these cases, we try using the specified start point if
+ that succeeds (i.e. the window desired matrix is successfully
+ recomputed, and point location is within the window). In case
+ of optional_new_start, we first check if the specified start
+ position is feasible, i.e. if it will allow point to be
+ displayed in the window. If using the specified start point
+ fails, e.g., if new fonts are needed to be loaded, we abort the
+ redisplay cycle and leave it up to the next cycle to figure out
+ things.
+
+ . Note that the window's force_start flag is sometimes set by
+ redisplay itself, when it decides that the previous window start
+ point is fine and should be kept. Search for "goto force_start"
+ below to see the details. Like the values of window-start
+ specified outside of redisplay, these internally-deduced values
+ are tested for feasibility, and ignored if found to be
+ unfeasible.
+
+ . Note that the function try_window, used to completely redisplay
+ a window, accepts the window's start point as its argument.
+ This is used several times in the redisplay code to control
+ where the window start will be, according to user options such
+ as scroll-conservatively, and also to ensure the screen line
+ showing point will be fully (as opposed to partially) visible on
+ display. */
static void
redisplay_window (Lisp_Object window, bool just_this_one_p)
eassert (XMARKER (w->start)->buffer == buffer);
eassert (XMARKER (w->pointm)->buffer == buffer);
+ /* We come here again if we need to run window-text-change-functions
+ below. */
restart:
reconsider_clip_changes (w);
frame_line_height = default_line_pixel_height (w);
&& !current_buffer->prevent_redisplay_optimizations_p
&& !window_outdated (w));
- /* Run the window-bottom-change-functions
+ /* Run the window-text-change-functions
if it is possible that the text on the screen has changed
(either due to modification of the text, or any other reason). */
if (!current_matrix_up_to_date_p
&& !b->clip_changed
&& !b->prevent_redisplay_optimizations_p
&& !window_outdated (w)
+ /* We rely below on the cursor coordinates to be up to date, but
+ we cannot trust them if some command moved point since the
+ last complete redisplay. */
+ && w->last_point == BUF_PT (b)
&& w->cursor.vpos >= 0
&& w->cursor.vpos < w->current_matrix->nrows
&& (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
case '@':
{
- ptrdiff_t count = inhibit_garbage_collection ();
Lisp_Object val = call1 (intern ("file-remote-p"),
BVAR (current_buffer, directory));
- unbind_to (count, Qnil);
if (NILP (val))
return "-";
sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
str = buf;
}
- for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
+ for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
code[len] = font->driver->encode_char (font, str[len]);
upper_len = (len + 1) / 2;
font->driver->text_extents (font, code, upper_len,
/* Allocate the buffer for frame titles.
Also used for `format-mode-line'. */
int size = 100;
- mode_line_noprop_buf = xmalloc (size);
+ mode_line_noprop_buf = xmalloc_atomic (size);
mode_line_noprop_buf_end = mode_line_noprop_buf + size;
mode_line_noprop_ptr = mode_line_noprop_buf;
mode_line_target = MODE_LINE_DISPLAY;