static void free_glyph_matrix P_ ((struct glyph_matrix *));
static void adjust_glyph_matrix P_ ((struct window *, struct glyph_matrix *,
int, int, struct dim));
-static void change_frame_size_1 P_ ((struct frame *, int, int, int, int));
+static void change_frame_size_1 P_ ((struct frame *, int, int, int, int, int));
static void swap_glyphs_in_rows P_ ((struct glyph_row *, struct glyph_row *));
static void swap_glyph_pointers P_ ((struct glyph_row *, struct glyph_row *));
static int glyph_row_slice_p P_ ((struct glyph_row *, struct glyph_row *));
int));
static void mirror_make_current P_ ((struct window *, int));
void check_window_matrix_pointers P_ ((struct window *));
+#if GLYPH_DEBUG
static void check_matrix_pointers P_ ((struct glyph_matrix *,
struct glyph_matrix *));
+#endif
static void mirror_line_dance P_ ((struct window *, int, int, int *, char *));
static int update_window_tree P_ ((struct window *, int));
static int update_window P_ ((struct window *, int));
\f
/* The currently selected frame. In a single-frame version, this
- variable always holds the address of the_only_frame. */
+ variable always equals the_only_frame. */
-struct frame *selected_frame;
+Lisp_Object selected_frame;
/* A frame which is not just a mini-buffer, or 0 if there are no such
frames. This is usually the most recent such frame that was
int i;
int new_rows;
int marginal_areas_changed_p = 0;
- int top_line_changed_p = 0;
- int top_line_p = 0;
+ int header_line_changed_p = 0;
+ int header_line_p = 0;
int left = -1, right = -1;
int window_x, window_y, window_width, window_height;
/* See if W had a top line that has disappeared now, or vice versa. */
if (w)
{
- top_line_p = WINDOW_WANTS_TOP_LINE_P (w);
- top_line_changed_p = top_line_p != matrix->top_line_p;
+ header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
+ header_line_changed_p = header_line_p != matrix->header_line_p;
}
- matrix->top_line_p = top_line_p;
+ matrix->header_line_p = header_line_p;
/* Do nothing if MATRIX' size, position, vscroll, and marginal areas
haven't changed. This optimization is important because preserving
if (!marginal_areas_changed_p
&& !fonts_changed_p
- && !top_line_changed_p
+ && !header_line_changed_p
&& matrix->window_top_y == XFASTINT (w->top)
&& matrix->window_height == window_height
&& matrix->window_vscroll == w->vscroll
if (w == NULL
|| row == matrix->rows + dim.height - 1
- || (row == matrix->rows && matrix->top_line_p))
+ || (row == matrix->rows && matrix->header_line_p))
{
row->glyphs[TEXT_AREA]
= row->glyphs[LEFT_MARGIN_AREA];
its own memory. Allocate glyph memory from the heap. */
if (dim.width > matrix->matrix_w
|| new_rows
- || top_line_changed_p
+ || header_line_changed_p
|| marginal_areas_changed_p)
{
struct glyph_row *row = matrix->rows;
/* The mode line never has marginal areas. */
if (row == matrix->rows + dim.height - 1
- || (row == matrix->rows && matrix->top_line_p))
+ || (row == matrix->rows && matrix->header_line_p))
{
row->glyphs[TEXT_AREA]
= row->glyphs[LEFT_MARGIN_AREA];
xassert (start >= 0 && start < matrix->nrows);
xassert (end >= 0 && end <= matrix->nrows);
- min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
+ min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
for (; start < end; ++start)
if (WINDOWP (f->menu_bar_window))
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
- /* Clear the matrix of the toolbar window, if any. */
- if (WINDOWP (f->toolbar_window))
- clear_glyph_matrix (XWINDOW (f->toolbar_window)->current_matrix);
+ /* Clear the matrix of the tool-bar window, if any. */
+ if (WINDOWP (f->tool_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
/* Clear current window matrices. */
xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
if (WINDOWP (f->menu_bar_window))
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
- if (WINDOWP (f->toolbar_window))
- clear_glyph_matrix (XWINDOW (f->toolbar_window)->desired_matrix);
+ if (WINDOWP (f->tool_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
/* Do it for window matrices. */
xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
{
int min_y, max_y;
- min_y = WINDOW_DISPLAY_TOP_LINE_HEIGHT (w);
+ min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w);
clear_glyph_row (row);
static void
adjust_frame_glyphs_initially ()
{
- struct window *root = XWINDOW (selected_frame->root_window);
+ struct frame *sf = SELECTED_FRAME ();
+ struct window *root = XWINDOW (sf->root_window);
struct window *mini = XWINDOW (root->next);
- int frame_height = FRAME_HEIGHT (selected_frame);
- int frame_width = FRAME_WIDTH (selected_frame);
- int top_margin = FRAME_TOP_MARGIN (selected_frame);
+ int frame_height = FRAME_HEIGHT (sf);
+ int frame_width = FRAME_WIDTH (sf);
+ int top_margin = FRAME_TOP_MARGIN (sf);
/* Do it for the root window. */
XSETFASTINT (root->top, top_margin);
XSETFASTINT (root->width, frame_width);
- set_window_height (selected_frame->root_window,
- frame_height - 1 - top_margin, 0);
+ set_window_height (sf->root_window, frame_height - 1 - top_margin, 0);
/* Do it for the mini-buffer window. */
XSETFASTINT (mini->top, frame_height - 1);
XSETFASTINT (mini->width, frame_width);
set_window_height (root->next, 1, 0);
- adjust_frame_glyphs (selected_frame);
+ adjust_frame_glyphs (sf);
glyphs_initialized_initially_p = 1;
}
}
#endif /* not USE_X_TOOLKIT */
- /* Allocate/ reallocate matrices of the toolbar window. If we don't
- have a toolbar window yet, make one. */
- if (NILP (f->toolbar_window))
+ /* Allocate/ reallocate matrices of the tool bar window. If we
+ don't have a tool bar window yet, make one. */
+ if (NILP (f->tool_bar_window))
{
- f->toolbar_window = make_window ();
- w = XWINDOW (f->toolbar_window);
+ f->tool_bar_window = make_window ();
+ w = XWINDOW (f->tool_bar_window);
XSETFRAME (w->frame, f);
w->pseudo_window_p = 1;
}
else
- w = XWINDOW (f->toolbar_window);
+ w = XWINDOW (f->tool_bar_window);
XSETFASTINT (w->top, FRAME_MENU_BAR_LINES (f));
XSETFASTINT (w->left, 0);
- XSETFASTINT (w->height, FRAME_TOOLBAR_LINES (f));
+ XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f));
XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
allocate_matrices_for_window_redisplay (w, ch_dim);
}
/* Adjust/ allocate message buffer of frame F.
- The global variables echo_area_glyphs and previous_echo_area_glyphs
- may be pointing to the frames message buffer and must be relocated
- if the buffer is reallocated.
-
Note that the message buffer is never freed. Since I could not
find a free in 19.34, I assume that freeing it would be
problematic in some way and don't do it either.
{
char *buffer = FRAME_MESSAGE_BUF (f);
char *new_buffer = (char *) xrealloc (buffer, size);
-
- if (buffer == echo_area_glyphs)
- echo_area_glyphs = new_buffer;
- if (buffer == previous_echo_glyphs)
- previous_echo_glyphs = new_buffer;
-
FRAME_MESSAGE_BUF (f) = new_buffer;
}
else
f->menu_bar_window = Qnil;
}
- /* Free the toolbar window and its glyph matrices. */
- if (!NILP (f->toolbar_window))
+ /* Free the tool bar window and its glyph matrices. */
+ if (!NILP (f->tool_bar_window))
{
- struct window *w = XWINDOW (f->toolbar_window);
+ struct window *w = XWINDOW (f->tool_bar_window);
free_glyph_matrix (w->desired_matrix);
free_glyph_matrix (w->current_matrix);
w->desired_matrix = w->current_matrix = NULL;
- f->toolbar_window = Qnil;
+ f->tool_bar_window = Qnil;
}
/* Release frame glyph matrices. Reset fields to zero in
direct_output_for_insert (g)
int g;
{
- register struct frame *f = selected_frame;
+ register struct frame *f = SELECTED_FRAME ();
struct window *w = XWINDOW (selected_window);
struct it it, it2;
struct glyph_row *glyph_row;
/* Give up if buffer appears in two places. */
|| buffer_shared > 1
/* Give up if w is mini-buffer and a message is being displayed there */
- || (MINI_WINDOW_P (w)
- && (echo_area_glyphs || STRINGP (echo_area_message)))
+ || (MINI_WINDOW_P (w) && !NILP (echo_area_buffer[0]))
/* Give up for hscrolled mini-buffer because display of the prompt
is handled specially there (see display_line). */
|| (MINI_WINDOW_P (w) && XFASTINT (w->hscroll))
/* Make room for new glyphs, then insert them. */
xassert (end - glyphs - n >= 0);
- safe_bcopy (glyphs, glyphs + n, (end - glyphs - n) * sizeof (*end));
+ safe_bcopy ((char *) glyphs, (char *) (glyphs + n),
+ (end - glyphs - n) * sizeof (*end));
bcopy (it.glyph_row->glyphs[TEXT_AREA], glyphs, n * sizeof *glyphs);
glyph_row->used[TEXT_AREA] = min (glyph_row->used[TEXT_AREA] + n,
end - glyph_row->glyphs[TEXT_AREA]);
TRACE ((stderr, "direct output for insert\n"));
- unchanged_modified = MODIFF;
- beg_unchanged = GPT - BEG;
+ UNCHANGED_MODIFIED = MODIFF;
+ BEG_UNCHANGED = GPT - BEG;
XSETFASTINT (w->last_point, PT);
w->last_cursor = w->cursor;
XSETFASTINT (w->last_modified, MODIFF);
direct_output_forward_char (n)
int n;
{
- struct frame *f = selected_frame;
+ struct frame *f = SELECTED_FRAME ();
struct window *w = XWINDOW (selected_window);
struct glyph_row *row;
if (!NILP (Vshow_trailing_whitespace))
return 0;
+ /* Give up if we are showing a message or just cleared the message
+ because we might need to resize the echo area window. */
+ if (!NILP (echo_area_buffer[0]) || !NILP (echo_area_buffer[1]))
+ return 0;
+
+ /* Give up if we don't know where the cursor is. */
+ if (w->cursor.vpos < 0)
+ return 0;
+
row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
if (PT <= MATRIX_ROW_START_BYTEPOS (row)
update_window (XWINDOW (f->menu_bar_window), 1);
/* Update the tool-bar window, if present. */
- if (WINDOWP (f->toolbar_window))
+ if (WINDOWP (f->tool_bar_window))
{
Lisp_Object tem;
- struct window *w = XWINDOW (f->toolbar_window);
+ struct window *w = XWINDOW (f->tool_bar_window);
/* Update tool-bar window. */
if (w->must_be_updated_p)
/* Swap tool-bar strings. We swap because we want to
reuse strings. */
- tem = f->current_toolbar_string;
- f->current_toolbar_string = f->desired_toolbar_string;
- f->desired_toolbar_string = tem;
- f->n_current_toolbar_items = f->n_desired_toolbar_items;
+ tem = f->current_tool_bar_string;
+ f->current_tool_bar_string = f->desired_tool_bar_string;
+ f->desired_tool_bar_string = tem;
+ f->n_current_tool_bar_items = f->n_desired_tool_bar_items;
/* Swap tool-bar items. We swap because we want to
reuse vectors. */
- tem = f->current_toolbar_items;
- f->current_toolbar_items = f->desired_toolbar_items;
- f->desired_toolbar_items = tem;
+ tem = f->current_tool_bar_items;
+ f->current_tool_bar_items = f->desired_tool_bar_items;
+ f->desired_tool_bar_items = tem;
}
}
struct window *w;
int force_p;
{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
struct glyph_matrix *desired_matrix = w->desired_matrix;
int paused_p;
int preempt_count = baud_rate / 2400 + 1;
extern int input_pending;
+#if GLYPH_DEBUG
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
extern struct frame *updating_frame;
+#endif
/* Check that W's frame doesn't have glyph matrices. */
xassert (FRAME_WINDOW_P (f));
{
struct glyph_row *row, *end;
struct glyph_row *mode_line_row;
- struct glyph_row *top_line_row = NULL;
+ struct glyph_row *header_line_row = NULL;
int yb, changed_p = 0;
rif->update_window_begin_hook (w);
row = desired_matrix->rows;
end = row + desired_matrix->nrows - 1;
if (row->mode_line_p)
- top_line_row = row++;
+ header_line_row = row++;
/* Update the mode line, if necessary. */
mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
/* Try reusing part of the display by inserting/deleting lines. */
if (row < end && !desired_matrix->no_scrolling_p)
{
- int rc = scrolling_window (w, top_line_row != NULL);
+ int rc = scrolling_window (w, header_line_row != NULL);
if (rc < 0)
{
/* All rows were found to be equal. */
/* Update the top mode line after scrolling because a new top
line would otherwise overwrite lines at the top of the window
that can be scrolled. */
- if (top_line_row && top_line_row->enabled_p)
+ if (header_line_row && header_line_row->enabled_p)
{
- top_line_row->y = 0;
+ header_line_row->y = 0;
update_window_line (w, 0);
changed_p = 1;
}
/* Not intended for frame matrix updates. */
xassert (FRAME_WINDOW_P (f));
- if ((cursor_in_echo_area
- /* If we are showing a message instead of the mini-buffer,
- show the cursor for the message instead of for the
- (now hidden) mini-buffer contents. */
- || (XWINDOW (minibuf_window) == w
- && EQ (minibuf_window, echo_area_window)
- && (echo_area_glyphs || STRINGP (echo_area_message))))
+ if (cursor_in_echo_area
+ && !NILP (echo_area_buffer[0])
+ /* If we are showing a message instead of the mini-buffer,
+ show the cursor for the message instead. */
+ && XWINDOW (minibuf_window) == w
+ && EQ (minibuf_window, echo_area_window)
/* These cases apply only to the frame that contains
the active mini-buffer window. */
&& FRAME_HAS_MINIBUF_P (f)
int yb = window_text_bottom_y (w);
last_row = NULL;
- for (row = MATRIX_ROW (w->current_matrix, 0);; ++row)
+ for (row = MATRIX_ROW (w->current_matrix, 0);
+ row->enabled_p;
+ ++row)
{
if (row->used[TEXT_AREA]
&& row->glyphs[TEXT_AREA][0].charpos >= 0)
if (last_row)
{
struct glyph *start = row->glyphs[TEXT_AREA];
- struct glyph *last = start + row->used[TEXT_AREA];
+ struct glyph *last = start + row->used[TEXT_AREA] - 1;
- while (last > start && (last - 1)->charpos < 0)
+ while (last > start && last->charpos < 0)
--last;
for (glyph = start; glyph < last; ++glyph)
/* Try to reuse part of the current display of W by scrolling lines.
- TOP_LINE_P non-zero means W has a top mode line.
+ HEADER_LINE_P non-zero means W has a top mode line.
The algorithm is taken from Communications of the ACM, Apr78 "A
Technique for Isolating Differences Between Files." It should take
1 if we did scroll. */
static int
-scrolling_window (w, top_line_p)
+scrolling_window (w, header_line_p)
struct window *w;
- int top_line_p;
+ int header_line_p;
{
struct symbol
{
int yb = window_text_bottom_y (w);
/* Skip over rows equal at the start. */
- i = top_line_p ? 1 : 0;
+ i = header_line_p ? 1 : 0;
while (i < current_matrix->nrows - 1
&& MATRIX_ROW_ENABLED_P (current_matrix, i)
&& MATRIX_ROW_ENABLED_P (desired_matrix, i)
(now hidden) mini-buffer contents. */
|| (EQ (minibuf_window, selected_window)
&& EQ (minibuf_window, echo_area_window)
- && (echo_area_glyphs || STRINGP (echo_area_message))))
+ && !NILP (echo_area_buffer[0])))
/* These cases apply only to the frame that contains
the active mini-buffer window. */
&& FRAME_HAS_MINIBUF_P (f)
{
/* Frame rows are filled up with spaces that
must be ignored here. */
- int i;
struct glyph_row *r = MATRIX_ROW (current_matrix,
row);
struct glyph *start = r->glyphs[TEXT_AREA];
else
reassert_line_highlight (desired_row->inverse_p, vpos);
+ /* Current row not enabled means it has unknown contents. We must
+ write the whole desired line in that case. */
must_write_whole_line_p = !current_row->enabled_p;
if (must_write_whole_line_p)
{
- /* A line that is not enabled is empty. */
obody = 0;
olen = 0;
}
else
{
- /* A line not empty in the current matrix. */
obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
olen = current_row->used[TEXT_AREA];
if (! current_row->inverse_p)
{
- /* Ignore trailing spaces. */
+ /* Ignore trailing spaces, if we can. */
if (!must_write_spaces)
while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
olen--;
}
else
{
- /* For an inverse-video line, remember we gave it spaces all
- the way to the frame edge so that the reverse video
- extends all the way across. */
+ /* For an inverse-video line, make sure it's filled with
+ spaces all the way to the frame edge so that the reverse
+ video extends all the way across. */
while (olen < FRAME_WIDTH (frame) - 1)
obody[olen++] = space_glyph;
}
/* If display line has unknown contents, write the whole line. */
if (must_write_whole_line_p)
{
+ /* Ignore spaces at the end, if we can. */
if (!must_write_spaces)
while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
--nlen;
+ /* Write the contents of the desired line. */
if (nlen)
{
- cursor_to (vpos, 0);
+ cursor_to (vpos, 0);
write_glyphs (nbody, nlen);
}
- cursor_to (vpos, nlen);
- clear_end_of_line (olen);
+ /* Don't call clear_end_of_line if we already wrote the whole
+ line. The cursor will not be at the right margin in that
+ case but in the line below. */
+ if (nlen < FRAME_WINDOW_WIDTH (frame))
+ {
+ cursor_to (vpos, nlen);
+ clear_end_of_line (FRAME_WINDOW_WIDTH (frame));
+ }
+
make_current (desired_matrix, current_matrix, vpos);
return;
}
if (mode_line_p)
row = MATRIX_MODE_LINE_ROW (w->current_matrix);
else
- row = MATRIX_TOP_LINE_ROW (w->current_matrix);
+ row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
if (row->mode_line_p && row->enabled_p)
{
and bitmap area width. */
if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
x += FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
- x += FRAME_FLAGS_AREA_WIDTH (f);
+ x += FRAME_LEFT_FLAGS_AREA_WIDTH (f);
/* Find the glyph under X. If we find one with a string object,
it's the one we were looking for. */
{
if (FRAME_TERMCAP_P (XFRAME (frame)))
{
- change_frame_size (XFRAME (frame), height, width, 0, 1);
+ change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
break;
}
}
#endif /* SIGWINCH */
-/* Do any change in frame size that was requested by a signal. */
+/* Do any change in frame size that was requested by a signal. SAFE
+ non-zero means this function is called from a place where it is
+ safe to change frame sizes while a redisplay is in progress. */
void
-do_pending_window_change ()
+do_pending_window_change (safe)
+ int safe;
{
/* If window_change_signal should have run before, run it now. */
+ if (redisplaying_p && !safe)
+ return;
+
while (delayed_size_change)
{
Lisp_Object tail, frame;
int width = FRAME_NEW_WIDTH (f);
if (height != 0 || width != 0)
- change_frame_size (f, height, width, 0, 0);
+ change_frame_size (f, height, width, 0, 0, safe);
}
}
}
If DELAY is non-zero, then assume we're being called from a signal
handler, and queue the change for later - perhaps the next
redisplay. Since this tries to resize windows, we can't call it
- from a signal handler. */
+ from a signal handler.
+
+ SAFE non-zero means this function is called from a place where it's
+ safe to change frame sizes while a redisplay is in progress. */
void
-change_frame_size (f, newheight, newwidth, pretend, delay)
+change_frame_size (f, newheight, newwidth, pretend, delay, safe)
register struct frame *f;
- int newheight, newwidth, pretend, delay;
+ int newheight, newwidth, pretend, delay, safe;
{
Lisp_Object tail, frame;
FOR_EACH_FRAME (tail, frame)
if (! FRAME_WINDOW_P (XFRAME (frame)))
change_frame_size_1 (XFRAME (frame), newheight, newwidth,
- pretend, delay);
+ pretend, delay, safe);
}
else
- change_frame_size_1 (f, newheight, newwidth, pretend, delay);
+ change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe);
}
static void
-change_frame_size_1 (f, newheight, newwidth, pretend, delay)
+change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
register struct frame *f;
- int newheight, newwidth, pretend, delay;
+ int newheight, newwidth, pretend, delay, safe;
{
int new_frame_window_width;
- unsigned int total_glyphs;
int count = specpdl_ptr - specpdl;
/* If we can't deal with the change now, queue it for later. */
- if (delay)
+ if (delay || (redisplaying_p && !safe))
{
FRAME_NEW_HEIGHT (f) = newheight;
FRAME_NEW_WIDTH (f) = newwidth;
if (FRAME_TERMCAP_P (f) && !pretend)
FrameCols = newwidth;
- if (WINDOWP (f->toolbar_window))
- XSETFASTINT (XWINDOW (f->toolbar_window)->width, newwidth);
+ if (WINDOWP (f->tool_bar_window))
+ XSETFASTINT (XWINDOW (f->tool_bar_window)->width, newwidth);
}
FRAME_HEIGHT (f) = newheight;
term_init (terminal_type);
{
- int width = FRAME_WINDOW_WIDTH (selected_frame);
- int height = FRAME_HEIGHT (selected_frame);
+ struct frame *sf = SELECTED_FRAME ();
+ int width = FRAME_WINDOW_WIDTH (sf);
+ int height = FRAME_HEIGHT (sf);
unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
}
adjust_frame_glyphs_initially ();
- calculate_costs (selected_frame);
+ calculate_costs (XFRAME (selected_frame));
#ifdef SIGWINCH
#ifndef CANNOT_DUMP