\f
/* Function prototypes. */
-static struct glyph_matrix *save_current_matrix (struct frame *);
-static void restore_current_matrix (struct frame *, struct glyph_matrix *);
-static int showing_window_margins_p (struct window *);
-static void fake_current_matrices (Lisp_Object);
-static void redraw_overlapping_rows (struct window *, int);
-static void redraw_overlapped_rows (struct window *, int);
-static int count_blanks (struct glyph *, int);
-static int count_match (struct glyph *, struct glyph *,
- struct glyph *, struct glyph *);
-static unsigned line_draw_cost (struct glyph_matrix *, int);
static void update_frame_line (struct frame *, int);
-static struct dim allocate_matrices_for_frame_redisplay
- (Lisp_Object, int, int, int, int *);
static int required_matrix_height (struct window *);
static int required_matrix_width (struct window *);
-static void allocate_matrices_for_window_redisplay (struct window *);
-static int realloc_glyph_pool (struct glyph_pool *, struct dim);
static void adjust_frame_glyphs (struct frame *);
-static struct glyph_matrix *new_glyph_matrix (struct glyph_pool *);
-static void free_glyph_matrix (struct glyph_matrix *);
-static void adjust_glyph_matrix (struct window *, struct glyph_matrix *,
- int, int, struct dim);
static void change_frame_size_1 (struct frame *, int, int, int, int, int);
static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT);
-static void swap_glyph_pointers (struct glyph_row *, struct glyph_row *);
-#if GLYPH_DEBUG
-static int glyph_row_slice_p (struct glyph_row *, struct glyph_row *);
-#endif
static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
struct window *);
static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
struct window *);
-static struct glyph_pool *new_glyph_pool (void);
-static void free_glyph_pool (struct glyph_pool *);
-static void adjust_frame_glyphs_initially (void);
static void adjust_frame_message_buffer (struct frame *);
static void adjust_decode_mode_spec_buffer (struct frame *);
static void fill_up_glyph_row_with_spaces (struct glyph_row *);
-static void build_frame_matrix (struct frame *);
-void clear_current_matrices (struct frame *);
-void scroll_glyph_matrix_range (struct glyph_matrix *, int, int,
- int, int);
static void clear_window_matrices (struct window *, int);
static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
static int scrolling_window (struct window *, int);
static int update_window_line (struct window *, int, int *);
-static void update_marginal_area (struct window *, int, int);
-static int update_text_area (struct window *, int);
-static void make_current (struct glyph_matrix *, struct glyph_matrix *,
- int);
static void mirror_make_current (struct window *, int);
-void check_window_matrix_pointers (struct window *);
#if GLYPH_DEBUG
static void check_matrix_pointers (struct glyph_matrix *,
struct glyph_matrix *);
/* A tick that's incremented each time something is added to the
history. */
-static unsigned history_tick;
+static uprintmax_t history_tick;
static void add_frame_display_history (struct frame *, int);
-static void add_window_display_history (struct window *, char *, int);
\f
/* Add to the redisplay history how window W has been displayed.
MSG is a trace containing the information how W's glyph matrix
has been interrupted for pending input. */
static void
-add_window_display_history (struct window *w, char *msg, int paused_p)
+add_window_display_history (struct window *w, const char *msg, int paused_p)
{
char *buf;
buf = redisplay_history[history_idx].trace;
++history_idx;
- sprintf (buf, "%d: window %p (`%s')%s\n",
+ sprintf (buf, "%"pMu": window %p (`%s')%s\n",
history_tick++,
w,
((BUFFERP (w->buffer)
- && STRINGP (XBUFFER (w->buffer)->name))
- ? SSDATA (XBUFFER (w->buffer)->name)
+ && STRINGP (BVAR (XBUFFER (w->buffer), name)))
+ ? SSDATA (BVAR (XBUFFER (w->buffer), name))
: "???"),
paused_p ? " ***paused***" : "");
strcat (buf, msg);
buf = redisplay_history[history_idx].trace;
++history_idx;
- sprintf (buf, "%d: update frame %p%s",
+ sprintf (buf, "%"pMu": update frame %p%s",
history_tick++,
f, paused_p ? " ***paused***" : "");
}
/* Enlarge MATRIX->rows if necessary. New rows are cleared. */
if (matrix->rows_allocated < dim.height)
{
- int size = dim.height * sizeof (struct glyph_row);
+ ptrdiff_t size = dim.height * sizeof (struct glyph_row);
new_rows = dim.height - matrix->rows_allocated;
matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
memset (matrix->rows + matrix->rows_allocated, 0,
row->visible_height -= min_y - row->y;
if (row->y + row->height > max_y)
row->visible_height -= row->y + row->height - max_y;
+ if (row->fringe_bitmap_periodic_p)
+ row->redraw_fringe_bitmaps_p = 1;
}
}
B without changing glyph pointers in A and B. */
static void
-swap_glyphs_in_rows (a, b)
- struct glyph_row *a, *b;
+swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b)
{
int area;
/* Exchange pointers to glyph memory between glyph rows A and B. */
-static INLINE void
+static inline void
swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
{
int i;
/* Copy glyph row structure FROM to glyph row structure TO, except
that glyph pointers in the structures are left unchanged. */
-static INLINE void
+static inline void
copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
{
struct glyph *pointers[1 + LAST_AREA];
exchanged between TO and FROM. Pointers must be exchanged to avoid
a memory leak. */
-static INLINE void
+static inline void
assign_row (struct glyph_row *to, struct glyph_row *from)
{
swap_glyph_pointers (to, from);
{
if (!row->enabled_p)
{
- unsigned rp = row->reversed_p;
+ int rp = row->reversed_p;
clear_glyph_row (row);
row->enabled_p = 1;
the number of characters in the line. If must_write_spaces is
zero, leading and trailing spaces are ignored. */
-static unsigned int
+static int
line_draw_cost (struct glyph_matrix *matrix, int vpos)
{
struct glyph_row *row = matrix->rows + vpos;
and B have equal contents. MOUSE_FACE_P non-zero means compare the
mouse_face_p flags of A and B, too. */
-static INLINE int
+static inline int
row_equal_p (struct glyph_row *a, struct glyph_row *b, int mouse_face_p)
{
if (a == b)
|| a->cursor_in_fringe_p != b->cursor_in_fringe_p
|| a->left_fringe_bitmap != b->left_fringe_bitmap
|| a->left_fringe_face_id != b->left_fringe_face_id
+ || a->left_fringe_offset != b->left_fringe_offset
|| a->right_fringe_bitmap != b->right_fringe_bitmap
|| a->right_fringe_face_id != b->right_fringe_face_id
+ || a->right_fringe_offset != b->right_fringe_offset
+ || a->fringe_bitmap_periodic_p != b->fringe_bitmap_periodic_p
|| a->overlay_arrow_bitmap != b->overlay_arrow_bitmap
|| a->exact_window_width_line_p != b->exact_window_width_line_p
|| a->overlapped_p != b->overlapped_p
needed = matrix_dim.width * matrix_dim.height;
if (needed > pool->nglyphs)
{
- int size = needed * sizeof (struct glyph);
+ ptrdiff_t size = needed * sizeof (struct glyph);
if (pool->glyphs)
{
stdout.
*/
+void flush_stdout (void) EXTERNALLY_VISIBLE;
+
void
flush_stdout (void)
{
/* Do it for the root window. */
XSETFASTINT (root->top_line, top_margin);
+ XSETFASTINT (root->total_lines, frame_lines - 1 - top_margin);
XSETFASTINT (root->total_cols, frame_cols);
- set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0);
/* Do it for the mini-buffer window. */
XSETFASTINT (mini->top_line, frame_lines - 1);
+ XSETFASTINT (mini->total_lines, 1);
XSETFASTINT (mini->total_cols, frame_cols);
- set_window_height (root->next, 1, 0);
adjust_frame_glyphs (sf);
glyphs_initialized_initially_p = 1;
{
struct glyph_row *from = f->current_matrix->rows + i;
struct glyph_row *to = saved->rows + i;
- size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+ ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes);
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
{
struct glyph_row *from = saved->rows + i;
struct glyph_row *to = f->current_matrix->rows + i;
- size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+ ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
xfree (from->glyphs[TEXT_AREA]);
static void
adjust_frame_message_buffer (struct frame *f)
{
- int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
+ ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
if (FRAME_MESSAGE_BUF (f))
{
function must be called before updates to make explicit that we are
working on frame matrices or not. */
-static INLINE void
+static inline void
set_frame_matrix_frame (struct frame *f)
{
frame_matrix_frame = f;
done in frame matrices, and that we have to perform analogous
operations in window matrices of frame_matrix_frame. */
-static INLINE void
+static inline void
make_current (struct glyph_matrix *desired_matrix, struct glyph_matrix *current_matrix, int row)
{
struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
matrices of leaf window agree with their frame matrices about
glyph pointers. */
-void
+static void
check_window_matrix_pointers (struct window *w)
{
while (w)
static int
window_to_frame_vpos (struct window *w, int vpos)
{
- struct frame *f = XFRAME (w->frame);
-
- xassert (!FRAME_WINDOW_P (f));
+ xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
vpos += WINDOW_TOP_EDGE_LINE (w);
- xassert (vpos >= 0 && vpos <= FRAME_LINES (f));
+ xassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (w->frame)));
return vpos;
}
/* Add glyph row ROW to the scrolling hash table. */
-static INLINE struct row_entry *
+static inline struct row_entry *
add_row_entry (struct glyph_row *row)
{
struct row_entry *entry;
struct glyph_matrix *current_matrix = w->current_matrix;
int yb = window_text_bottom_y (w);
int i, j, first_old, first_new, last_old, last_new;
- int nruns, nbytes, n, run_idx;
+ int nruns, n, run_idx;
+ ptrdiff_t nbytes;
struct row_entry *entry;
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
first_old = first_new = i;
- /* Set last_new to the index + 1 of the last enabled row in the
- desired matrix. */
+ /* Set last_new to the index + 1 of the row that reaches the
+ bottom boundary in the desired matrix. Give up if we find a
+ disabled row before we reach the bottom boundary. */
i = first_new + 1;
- while (i < desired_matrix->nrows - 1
- && MATRIX_ROW (desired_matrix, i)->enabled_p
- && MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i)) <= yb)
- ++i;
+ while (i < desired_matrix->nrows - 1)
+ {
+ int bottom;
- if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
- return 0;
+ if (!MATRIX_ROW (desired_matrix, i)->enabled_p)
+ return 0;
+ bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i));
+ if (bottom <= yb)
+ ++i;
+ if (bottom >= yb)
+ break;
+ }
last_new = i;
- /* Set last_old to the index + 1 of the last enabled row in the
- current matrix. We don't look at the enabled flag here because
- we plan to reuse part of the display even if other parts are
- disabled. */
+ /* Set last_old to the index + 1 of the row that reaches the bottom
+ boundary in the current matrix. We don't look at the enabled
+ flag here because we plan to reuse part of the display even if
+ other parts are disabled. */
i = first_old + 1;
while (i < current_matrix->nrows - 1)
{
/* Copy on the display. */
if (r->current_y != r->desired_y)
{
+ rif->clear_window_mouse_face (w);
rif->scroll_run_hook (w, r);
/* Invalidate runs that copy from where we copied to. */
to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
to_overlapped_p = to->overlapped_p;
- if (!from->mode_line_p && !w->pseudo_window_p
- && (to->left_fringe_bitmap != from->left_fringe_bitmap
- || to->right_fringe_bitmap != from->right_fringe_bitmap
- || to->left_fringe_face_id != from->left_fringe_face_id
- || to->right_fringe_face_id != from->right_fringe_face_id
- || to->overlay_arrow_bitmap != from->overlay_arrow_bitmap))
- from->redraw_fringe_bitmaps_p = 1;
+ from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
assign_row (to, from);
to->enabled_p = 1, from->enabled_p = 0;
to->overlapped_p = to_overlapped_p;
if (newheight != FRAME_LINES (f))
{
- if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
- {
- /* Frame has both root and mini-buffer. */
- XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top_line,
- FRAME_TOP_MARGIN (f));
- set_window_height (FRAME_ROOT_WINDOW (f),
- (newheight
- - 1
- - FRAME_TOP_MARGIN (f)),
- 2);
- XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
- newheight - 1);
- set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
- }
- else
- /* Frame has just one top-level window. */
- set_window_height (FRAME_ROOT_WINDOW (f),
- newheight - FRAME_TOP_MARGIN (f), 2);
+ resize_frame_windows (f, newheight, 0);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
{
- set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 2);
- if (FRAME_HAS_MINIBUF_P (f))
- set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
+ resize_frame_windows (f, new_frame_total_cols, 1);
/* MSDOS frames cannot PRETEND, as they change frame size by
manipulating video hardware. */
}
}
- if (!inhibit_window_system && display_arg
-#ifndef CANNOT_DUMP
- && initialized
-#endif
- )
+ if (!inhibit_window_system && display_arg)
{
Vinitial_window_system = Qx;
#ifdef HAVE_X11
int width = FRAME_TOTAL_COLS (sf);
int height = FRAME_LINES (sf);
- unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
-
/* If these sizes are so big they cause overflow, just ignore the
- change. It's not clear what better we could do. */
- if (total_glyphs / sizeof (struct glyph) / height != width + 2)
+ change. It's not clear what better we could do. The rest of
+ the code assumes that (width + 2) * height * sizeof (struct glyph)
+ does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */
+ if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX)
+ || INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX)
+ || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
+ < (width + 2) * height))
fatal ("screen size %dx%d too big", width, height);
}
frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
staticpro (&frame_and_buffer_state);
- Qdisplay_table = intern_c_string ("display-table");
- staticpro (&Qdisplay_table);
- Qredisplay_dont_pause = intern_c_string ("redisplay-dont-pause");
- staticpro (&Qredisplay_dont_pause);
+ DEFSYM (Qdisplay_table, "display-table");
+ DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
DEFVAR_INT ("baud-rate", baud_rate,
doc: /* *The output baud rate of the terminal.