/* Updating of data structures for redisplay.
-Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc.
+Copyright (C) 1985-1988, 1993-1995, 1997-2013 Free Software Foundation,
+Inc.
This file is part of GNU Emacs.
#define DISPEXTERN_INLINE EXTERN_INLINE
-#include <stdio.h>
+#include "sysstdio.h"
#include <unistd.h>
#include "lisp.h"
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
-/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
-
-#include "systime.h"
#include <errno.h>
#include <fpending.h>
+#include <timespec.h>
#if defined (HAVE_TERM_H) && defined (GNU_LINUX)
#include <term.h> /* for tgetent */
struct window *);
static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
struct window *);
-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 clear_window_matrices (struct window *, bool);
static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
-\f
-/* Redisplay preemption timers. */
-
-static EMACS_TIME preemption_period;
-static EMACS_TIME preemption_next_check;
-
/* True upon entry to redisplay means do not assume anything about
current contents of actual terminal frame; clear and redraw it. */
static bool delayed_size_change;
-/* Updated window if != 0. Set by update_window. */
-
-struct window *updated_window;
-
-/* Glyph row updated in update_window_line, and area that is updated. */
-
-struct glyph_row *updated_row;
-int updated_area;
-
/* A glyph for a space. */
struct glyph space_glyph;
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
+
/* Counts of allocated structures. These counts serve to diagnose
memory leaks and double frees. */
static int glyph_matrix_count;
static int glyph_pool_count;
+#endif /* GLYPH_DEBUG and ENABLE_CHECKING */
+
/* If non-null, the frame whose frame matrices are manipulated. If
null, window matrices are worked on. */
add_window_display_history (struct window *w, const char *msg, bool paused_p)
{
char *buf;
+ void *ptr = w;
if (history_idx >= REDISPLAY_HISTORY_SIZE)
history_idx = 0;
snprintf (buf, sizeof redisplay_history[0].trace,
"%"pMu": window %p (`%s')%s\n%s",
history_tick++,
- w,
- ((BUFFERP (w->buffer)
- && STRINGP (BVAR (XBUFFER (w->buffer), name)))
- ? SSDATA (BVAR (XBUFFER (w->buffer), name))
+ ptr,
+ ((BUFFERP (w->contents)
+ && STRINGP (BVAR (XBUFFER (w->contents), name)))
+ ? SSDATA (BVAR (XBUFFER (w->contents), name))
: "???"),
paused_p ? " ***paused***" : "",
msg);
add_frame_display_history (struct frame *f, bool paused_p)
{
char *buf;
+ void *ptr = f;
if (history_idx >= REDISPLAY_HISTORY_SIZE)
history_idx = 0;
sprintf (buf, "%"pMu": update frame %p%s",
history_tick++,
- f, paused_p ? " ***paused***" : "");
+ ptr, paused_p ? " ***paused***" : "");
}
{
struct glyph_matrix *result = xzalloc (sizeof *result);
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
/* Increment number of allocated matrices. This count is used
to detect memory leaks. */
++glyph_matrix_count;
+#endif
/* Set pool and return. */
result->pool = pool;
/* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed.
- The global counter glyph_matrix_count is decremented when a matrix
- is freed. If the count gets negative, more structures were freed
- than allocated, i.e. one matrix was freed more than once or a bogus
- pointer was passed to this function.
+ If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global counter
+ glyph_matrix_count is decremented when a matrix is freed. If the count
+ gets negative, more structures were freed than allocated, i.e. one matrix
+ was freed more than once or a bogus pointer was passed to this function.
If MATRIX->pool is null, this means that the matrix manages its own
glyph memory---this is done for matrices on X frames. Freeing the
{
int i;
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
/* Detect the case that more matrices are freed than were
allocated. */
- if (--glyph_matrix_count < 0)
- emacs_abort ();
+ --glyph_matrix_count;
+ eassert (glyph_matrix_count >= 0);
+#endif
/* Free glyph memory if MATRIX owns it. */
if (matrix->pool == NULL)
/* Return the number of glyphs to reserve for a marginal area of
window W. TOTAL_GLYPHS is the number of glyphs in a complete
display line of window W. MARGIN gives the width of the marginal
- area in canonical character units. MARGIN should be an integer
- or a float. */
+ area in canonical character units. */
static int
-margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin)
+margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin)
{
- int n;
-
- if (NUMBERP (margin))
+ if (margin > 0)
{
- int width = XFASTINT (w->total_cols);
- double d = max (0, XFLOATINT (margin));
+ int width = w->total_cols;
+ double d = max (0, margin);
d = min (width / 2 - 1, d);
- n = (int) ((double) total_glyphs / width * d);
+ return (int) ((double) total_glyphs / width * d);
}
- else
- n = 0;
-
- return n;
+ return 0;
}
/* Return true if ROW's hash value is correct.
Get W's size. */
if (w)
{
- window_box (w, -1, 0, 0, &window_width, &window_height);
+ window_box (w, ANY_AREA, 0, 0, &window_width, &window_height);
header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
header_line_changed_p = header_line_p != matrix->header_line_p;
/* Window end is invalid, if inside of the rows that
are invalidated below. */
- if (INTEGERP (w->window_end_vpos)
- && XFASTINT (w->window_end_vpos) >= i)
- wset_window_end_valid (w, Qnil);
+ if (w->window_end_vpos >= i)
+ w->window_end_valid = 0;
while (i < matrix->nrows)
matrix->rows[i++].enabled_p = 0;
if (f->current_matrix)
clear_glyph_matrix (f->current_matrix);
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Clear the matrix of the menu bar window, if such a window exists.
The menu bar window is currently used to display menus on X when
no toolkit support is compiled in. */
if (WINDOWP (f->menu_bar_window))
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
+#endif
/* Clear the matrix of the tool-bar window, if any. */
if (WINDOWP (f->tool_bar_window))
if (f->desired_matrix)
clear_glyph_matrix (f->desired_matrix);
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
if (WINDOWP (f->menu_bar_window))
clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
+#endif
if (WINDOWP (f->tool_bar_window))
clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
{
while (w)
{
- if (!NILP (w->hchild))
- {
- eassert (WINDOWP (w->hchild));
- clear_window_matrices (XWINDOW (w->hchild), desired_p);
- }
- else if (!NILP (w->vchild))
- {
- eassert (WINDOWP (w->vchild));
- clear_window_matrices (XWINDOW (w->vchild), desired_p);
- }
+ if (WINDOWP (w->contents))
+ clear_window_matrices (XWINDOW (w->contents), desired_p);
else
{
if (desired_p)
else
{
clear_glyph_matrix (w->current_matrix);
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
}
}
See dispextern.h for an overall explanation of glyph pools.
***********************************************************************/
-/* Allocate a glyph_pool structure. The structure returned is
- initialized with zeros. The global variable glyph_pool_count is
- incremented for each pool allocated. */
+/* Allocate a glyph_pool structure. The structure returned is initialized
+ with zeros. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global
+ variable glyph_pool_count is incremented for each pool allocated. */
static struct glyph_pool *
new_glyph_pool (void)
{
struct glyph_pool *result = xzalloc (sizeof *result);
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
/* For memory leak and double deletion checking. */
++glyph_pool_count;
+#endif
return result;
}
/* Free a glyph_pool structure POOL. The function may be called with
- a null POOL pointer. The global variable glyph_pool_count is
- decremented with every pool structure freed. If this count gets
- negative, more structures were freed than allocated, i.e. one
- structure must have been freed more than once or a bogus pointer
- was passed to free_glyph_pool. */
+ a null POOL pointer. If GLYPH_DEBUG and ENABLE_CHECKING are in effect,
+ global variable glyph_pool_count is decremented with every pool structure
+ freed. If this count gets negative, more structures were freed than
+ allocated, i.e. one structure must have been freed more than once or
+ a bogus pointer was passed to free_glyph_pool. */
static void
free_glyph_pool (struct glyph_pool *pool)
{
if (pool)
{
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
/* More freed than allocated? */
--glyph_pool_count;
eassert (glyph_pool_count >= 0);
-
+#endif
xfree (pool->glyphs);
xfree (pool);
}
struct glyph_row *row = matrix->rows;
struct glyph_row *last_text_row = NULL;
struct buffer *saved = current_buffer;
- struct buffer *buffer = XBUFFER (w->buffer);
+ struct buffer *buffer = XBUFFER (w->contents);
int c;
/* This can sometimes happen for a fresh window. */
vertically below other windows. */
in_horz_combination_p
= (!NILP (XWINDOW (window)->parent)
- && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
+ && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (XWINDOW (window)->parent)));
/* For WINDOW and all windows on the same level. */
do
/* Get the dimension of the window sub-matrix for W, depending
on whether this is a combination or a leaf window. */
- if (!NILP (w->hchild))
- dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y,
- dim_only_p,
- window_change_flags);
- else if (!NILP (w->vchild))
- dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
+ if (WINDOWP (w->contents))
+ dim = allocate_matrices_for_frame_redisplay (w->contents, x, y,
dim_only_p,
window_change_flags);
else
}
#endif /* HAVE_WINDOW_SYSTEM */
- return XINT (w->total_cols);
+ return w->total_cols;
}
{
while (w)
{
- if (!NILP (w->vchild))
- allocate_matrices_for_window_redisplay (XWINDOW (w->vchild));
- else if (!NILP (w->hchild))
- allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
+ if (WINDOWP (w->contents))
+ allocate_matrices_for_window_redisplay (XWINDOW (w->contents));
else
{
/* W is a leaf window. */
else
adjust_frame_glyphs_for_frame_redisplay (f);
- /* Don't forget the message buffer and the buffer for
- decode_mode_spec. */
- adjust_frame_message_buffer (f);
+ /* Don't forget the buffer for decode_mode_spec. */
adjust_decode_mode_spec_buffer (f);
f->glyphs_initialized_p = 1;
{
while (w)
{
- if (!NILP (w->hchild))
+ if (WINDOWP (w->contents))
{
- if (showing_window_margins_p (XWINDOW (w->hchild)))
+ if (showing_window_margins_p (XWINDOW (w->contents)))
return 1;
}
- else if (!NILP (w->vchild))
- {
- if (showing_window_margins_p (XWINDOW (w->vchild)))
- return 1;
- }
- else if (!NILP (w->left_margin_cols)
- || !NILP (w->right_margin_cols))
+ else if (w->left_margin_cols > 0 || w->right_margin_cols > 0)
return 1;
w = NILP (w->next) ? 0 : XWINDOW (w->next);
{
w = XWINDOW (window);
- if (!NILP (w->hchild))
- fake_current_matrices (w->hchild);
- else if (!NILP (w->vchild))
- fake_current_matrices (w->vchild);
+ if (WINDOWP (w->contents))
+ fake_current_matrices (w->contents);
else
{
int i;
/* Save away the contents of frame F's current frame matrix. Value is
a glyph matrix holding the contents of F's current frame matrix. */
-static struct glyph_matrix *
+struct glyph_matrix *
save_current_matrix (struct frame *f)
{
int i;
struct glyph_row *from = f->current_matrix->rows + i;
struct glyph_row *to = saved->rows + i;
ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+
to->glyphs[TEXT_AREA] = xmalloc (nbytes);
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
+ to->enabled_p = from->enabled_p;
+ to->hash = from->hash;
+ if (from->used[LEFT_MARGIN_AREA])
+ {
+ nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+ to->glyphs[LEFT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+ memcpy (to->glyphs[LEFT_MARGIN_AREA],
+ from->glyphs[LEFT_MARGIN_AREA], nbytes);
+ to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+ }
+ if (from->used[RIGHT_MARGIN_AREA])
+ {
+ nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+ to->glyphs[RIGHT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+ memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+ from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+ to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+ }
}
return saved;
struct glyph_row *from = saved->rows + i;
struct glyph_row *to = f->current_matrix->rows + i;
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]);
+ nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+ if (nbytes)
+ {
+ memcpy (to->glyphs[LEFT_MARGIN_AREA],
+ from->glyphs[LEFT_MARGIN_AREA], nbytes);
+ to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+ xfree (from->glyphs[LEFT_MARGIN_AREA]);
+ }
+ else
+ to->used[LEFT_MARGIN_AREA] = 0;
+ nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+ if (nbytes)
+ {
+ memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+ from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+ to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+ xfree (from->glyphs[RIGHT_MARGIN_AREA]);
+ }
+ else
+ to->used[RIGHT_MARGIN_AREA] = 0;
}
xfree (saved->rows);
/* Set window dimensions to frame dimensions and allocate or
adjust glyph matrices of W. */
- wset_top_line (w, make_number (0));
- wset_left_col (w, make_number (0));
- wset_total_lines (w, make_number (FRAME_MENU_BAR_LINES (f)));
- wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f)));
+ w->top_line = 0;
+ w->left_col = 0;
+ w->total_lines = FRAME_MENU_BAR_LINES (f);
+ w->total_cols = FRAME_TOTAL_COLS (f);
allocate_matrices_for_window_redisplay (w);
}
#endif /* not USE_X_TOOLKIT && not USE_GTK */
else
w = XWINDOW (f->tool_bar_window);
- wset_top_line (w, make_number (FRAME_MENU_BAR_LINES (f)));
- wset_left_col (w, make_number (0));
- wset_total_lines (w, make_number (FRAME_TOOL_BAR_LINES (f)));
- wset_total_cols (w, make_number (FRAME_TOTAL_COLS (f)));
+ w->top_line = FRAME_MENU_BAR_LINES (f);
+ w->left_col = 0;
+ w->total_lines = FRAME_TOOL_BAR_LINES (f);
+ w->total_cols = FRAME_TOTAL_COLS (f);
allocate_matrices_for_window_redisplay (w);
}
#endif
}
-/* Adjust/ allocate message buffer of frame F.
-
- 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.
-
- (Implementation note: It should be checked if we can free it
- eventually without causing trouble). */
-
-static void
-adjust_frame_message_buffer (struct frame *f)
-{
- FRAME_MESSAGE_BUF (f) = xrealloc (FRAME_MESSAGE_BUF (f),
- FRAME_MESSAGE_BUF_SIZE (f) + 1);
-}
-
-
/* Re-allocate buffer for decode_mode_spec on frame F. */
static void
if (!NILP (f->root_window))
free_window_matrices (XWINDOW (f->root_window));
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Free the dummy window for menu bars without X toolkit and its
glyph matrices. */
if (!NILP (f->menu_bar_window))
w->desired_matrix = w->current_matrix = NULL;
fset_menu_bar_window (f, Qnil);
}
+#endif
/* Free the tool bar window and its glyph matrices. */
if (!NILP (f->tool_bar_window))
{
while (w)
{
- if (!NILP (w->hchild))
- free_window_matrices (XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- free_window_matrices (XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ free_window_matrices (XWINDOW (w->contents));
else
{
/* This is a leaf window. Free its memory and reset fields
FOR_EACH_FRAME (tail, frame)
free_glyphs (XFRAME (frame));
+#if defined GLYPH_DEBUG && defined ENABLE_CHECKING
/* Check that nothing is left allocated. */
- if (glyph_matrix_count)
- emacs_abort ();
- if (glyph_pool_count)
- emacs_abort ();
+ eassert (glyph_matrix_count == 0);
+ eassert (glyph_pool_count == 0);
+#endif
}
screen. We build such a view by constructing a frame matrix from
window matrices in this section.
- Windows that must be updated have their must_be_update_p flag set.
+ Windows that must be updated have their must_be_updated_p flag set.
For all such windows, their desired matrix is made part of the
desired frame matrix. For other windows, their current matrix is
made part of the desired frame matrix.
{
while (w)
{
- if (!NILP (w->hchild))
- build_frame_matrix_from_window_tree (matrix, XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- build_frame_matrix_from_window_tree (matrix, XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ build_frame_matrix_from_window_tree (matrix, XWINDOW (w->contents));
else
build_frame_matrix_from_leaf_window (matrix, w);
{
while (w)
{
- if (!NILP (w->hchild))
- mirror_make_current (XWINDOW (w->hchild), frame_row);
- else if (!NILP (w->vchild))
- mirror_make_current (XWINDOW (w->vchild), frame_row);
+ if (WINDOWP (w->contents))
+ mirror_make_current (XWINDOW (w->contents), frame_row);
else
{
/* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
struct glyph_row *window_row, *window_row_end, *frame_row;
int left, right, x, width;
- /* Preconditions: W must be a leaf window on a tty frame. */
- eassert (NILP (w->hchild) && NILP (w->vchild));
+ /* Preconditions: W must be a live window on a tty frame. */
+ eassert (BUFFERP (w->contents));
eassert (!FRAME_WINDOW_P (f));
left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
while (w && !found)
{
- if (!NILP (w->hchild))
- found = frame_row_to_window (XWINDOW (w->hchild), row);
- else if (!NILP (w->vchild))
- found = frame_row_to_window (XWINDOW (w->vchild), row);
+ if (WINDOWP (w->contents))
+ found = frame_row_to_window (XWINDOW (w->contents), row);
else if (row >= WINDOW_TOP_EDGE_LINE (w)
&& row < WINDOW_BOTTOM_EDGE_LINE (w))
found = w;
{
while (w)
{
- if (!NILP (w->hchild))
- mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
- nlines, copy_from, retained_p);
- else if (!NILP (w->vchild))
- mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
+ if (WINDOWP (w->contents))
+ mirror_line_dance (XWINDOW (w->contents), unchanged_at_top,
nlines, copy_from, retained_p);
else
{
{
while (w)
{
- if (!NILP (w->hchild))
- check_window_matrix_pointers (XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- check_window_matrix_pointers (XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ check_window_matrix_pointers (XWINDOW (w->contents));
else
{
struct frame *f = XFRAME (w->frame);
if (redisplay_dont_pause)
force_p = 1;
- else if (NILP (Vredisplay_preemption_period))
- force_p = 1;
- else if (!force_p && NUMBERP (Vredisplay_preemption_period))
+ else if (!force_p && detect_input_pending_ignore_squeezables ())
{
- double p = XFLOATINT (Vredisplay_preemption_period);
-
- if (detect_input_pending_ignore_squeezables ())
- {
- paused_p = 1;
- goto do_pause;
- }
-
- preemption_period = EMACS_TIME_FROM_DOUBLE (p);
- preemption_next_check = add_emacs_time (current_emacs_time (),
- preemption_period);
+ paused_p = 1;
+ goto do_pause;
}
if (FRAME_WINDOW_P (f))
when pending input is detected. */
update_begin (f);
+#if defined (HAVE_X_WINDOWS) && ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* Update the menu bar on X frames that don't have toolkit
support. */
if (WINDOWP (f->menu_bar_window))
update_window (XWINDOW (f->menu_bar_window), 1);
+#endif
/* Update the tool-bar window, if present. */
if (WINDOWP (f->tool_bar_window))
return paused_p;
}
+/* Update a TTY frame F that has a menu dropped down over some of its
+ glyphs. This is like the second part of update_frame, but it
+ doesn't call build_frame_matrix, because we already have the
+ desired matrix prepared, and don't want it to be overwritten by the
+ text of the normal display. */
+void
+update_frame_with_menu (struct frame *f)
+{
+ struct window *root_window = XWINDOW (f->root_window);
+ bool paused_p;
+
+ eassert (FRAME_TERMCAP_P (f));
+
+ /* We are working on frame matrix basis. Set the frame on whose
+ frame matrix we operate. */
+ set_frame_matrix_frame (f);
+
+ /* Update the display */
+ update_begin (f);
+ /* Force update_frame_1 not to stop due to pending input, and not
+ try scrolling. */
+ paused_p = update_frame_1 (f, 1, 1);
+ update_end (f);
+
+ if (FRAME_TTY (f)->termscript)
+ fflush (FRAME_TTY (f)->termscript);
+ fflush (FRAME_TTY (f)->output);
+ /* Check window matrices for lost pointers. */
+#if GLYPH_DEBUG
+#if 0
+ /* We cannot possibly survive the matrix pointers check, since
+ we have overwritten parts of the frame glyph matrix without
+ making any updates to the window matrices. */
+ check_window_matrix_pointers (root_window);
+#endif
+ add_frame_display_history (f, paused_p);
+#endif
+
+ /* Reset flags indicating that a window should be updated. */
+ set_window_update_flags (root_window, 0);
+}
\f
/************************************************************************
while (w && !paused_p)
{
- if (!NILP (w->hchild))
- paused_p |= update_window_tree (XWINDOW (w->hchild), force_p);
- else if (!NILP (w->vchild))
- paused_p |= update_window_tree (XWINDOW (w->vchild), force_p);
+ if (WINDOWP (w->contents))
+ paused_p |= update_window_tree (XWINDOW (w->contents), force_p);
else if (w->must_be_updated_p)
paused_p |= update_window (w, force_p);
if (redisplay_dont_pause)
force_p = 1;
- else if (NILP (Vredisplay_preemption_period))
- force_p = 1;
- else if (!force_p && NUMBERP (Vredisplay_preemption_period))
- {
- double p = XFLOATINT (Vredisplay_preemption_period);
- preemption_period = EMACS_TIME_FROM_DOUBLE (p);
- preemption_next_check = add_emacs_time (current_emacs_time (),
- preemption_period);
- }
/* Update W. */
update_begin (f);
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
- updated_row = row;
- updated_area = area;
- FRAME_RIF (f)->cursor_to (i, 0, row->y,
- area == TEXT_AREA ? row->x : 0);
+ output_cursor_to (w, i, 0, row->y,
+ area == TEXT_AREA ? row->x : 0);
if (row->used[area])
- FRAME_RIF (f)->write_glyphs (row->glyphs[area],
- row->used[area]);
- FRAME_RIF (f)->clear_end_of_line (-1);
+ FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area],
+ area, row->used[area]);
+ FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
}
row->overlapped_p = 0;
{
struct glyph_matrix *desired_matrix = w->desired_matrix;
bool paused_p;
-#if !PERIODIC_PREEMPTION_CHECKING
int preempt_count = baud_rate / 2400 + 1;
-#endif
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
#ifdef GLYPH_DEBUG
/* Check that W's frame doesn't have glyph matrices. */
#endif
/* Check pending input the first time so that we can quickly return. */
-#if !PERIODIC_PREEMPTION_CHECKING
if (!force_p)
detect_input_pending_ignore_squeezables ();
-#endif
/* If forced to complete the update, or if no input is pending, do
the update. */
struct glyph_row *header_line_row;
int yb;
bool changed_p = 0, mouse_face_overwritten_p = 0;
-#if ! PERIODIC_PREEMPTION_CHECKING
int n_updated = 0;
-#endif
rif->update_window_begin_hook (w);
yb = window_text_bottom_y (w);
- row = desired_matrix->rows;
- end = row + desired_matrix->nrows - 1;
+ row = MATRIX_ROW (desired_matrix, 0);
+ end = MATRIX_MODE_LINE_ROW (desired_matrix);
/* Take note of the header line, if there is one. We will
update it below, after updating all of the window's lines. */
detect_input_pending. If it's done too often,
scrolling large windows with repeated scroll-up
commands will too quickly pause redisplay. */
-#if PERIODIC_PREEMPTION_CHECKING
- if (!force_p)
- {
- EMACS_TIME tm = current_emacs_time ();
- if (EMACS_TIME_LT (preemption_next_check, tm))
- {
- preemption_next_check = add_emacs_time (tm,
- preemption_period);
- if (detect_input_pending_ignore_squeezables ())
- break;
- }
- }
-#else
if (!force_p && ++n_updated % preempt_count == 0)
detect_input_pending_ignore_squeezables ();
-#endif
changed_p |= update_window_line (w, vpos,
&mouse_face_overwritten_p);
/* End the update of window W. Don't set the cursor if we
paused updating the display because in this case,
set_window_cursor_after_update hasn't been called, and
- output_cursor doesn't contain the cursor location. */
+ W->output_cursor doesn't contain the cursor location. */
rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
}
else
AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
static void
-update_marginal_area (struct window *w, int area, int vpos)
+update_marginal_area (struct window *w, struct glyph_row *updated_row,
+ enum glyph_row_area area, int vpos)
{
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
- /* Let functions in xterm.c know what area subsequent X positions
- will be relative to. */
- updated_area = area;
-
/* Set cursor to start of glyphs, write them, and clear to the end
of the area. I don't think that something more sophisticated is
necessary here, since marginal areas will not be the default. */
- rif->cursor_to (vpos, 0, desired_row->y, 0);
+ output_cursor_to (w, vpos, 0, desired_row->y, 0);
if (desired_row->used[area])
- rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]);
- rif->clear_end_of_line (-1);
+ rif->write_glyphs (w, updated_row, desired_row->glyphs[area],
+ area, desired_row->used[area]);
+ rif->clear_end_of_line (w, updated_row, area, -1);
}
Value is true if display has changed. */
static bool
-update_text_area (struct window *w, int vpos)
+update_text_area (struct window *w, struct glyph_row *updated_row, int vpos)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
bool changed_p = 0;
- /* Let functions in xterm.c know what area subsequent X positions
- will be relative to. */
- updated_area = TEXT_AREA;
-
/* If rows are at different X or Y, or rows have different height,
or the current row is marked invalid, write the entire line. */
if (!current_row->enabled_p
&& !(current_row->mode_line_p && vpos > 0))
|| current_row->x != desired_row->x)
{
- rif->cursor_to (vpos, 0, desired_row->y, desired_row->x);
+ output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
if (desired_row->used[TEXT_AREA])
- rif->write_glyphs (desired_row->glyphs[TEXT_AREA],
- desired_row->used[TEXT_AREA]);
+ rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA],
+ TEXT_AREA, desired_row->used[TEXT_AREA]);
/* Clear to end of window. */
- rif->clear_end_of_line (-1);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
changed_p = 1;
/* This erases the cursor. We do this here because
break;
}
- rif->cursor_to (vpos, start_hpos, desired_row->y, start_x);
- rif->write_glyphs (start, i - start_hpos);
+ output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
+ rif->write_glyphs (w, updated_row, start,
+ TEXT_AREA, i - start_hpos);
changed_p = 1;
}
}
/* Write the rest. */
if (i < desired_row->used[TEXT_AREA])
{
- rif->cursor_to (vpos, i, desired_row->y, x);
- rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i);
+ output_cursor_to (w, vpos, i, desired_row->y, x);
+ rif->write_glyphs (w, updated_row, desired_glyph,
+ TEXT_AREA, desired_row->used[TEXT_AREA] - i);
changed_p = 1;
}
{
/* If old row extends to the end of the text area, clear. */
if (i >= desired_row->used[TEXT_AREA])
- rif->cursor_to (vpos, i, desired_row->y,
- desired_row->pixel_width);
- rif->clear_end_of_line (-1);
+ output_cursor_to (w, vpos, i, desired_row->y,
+ desired_row->pixel_width);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
changed_p = 1;
}
else if (desired_row->pixel_width < current_row->pixel_width)
int xlim;
if (i >= desired_row->used[TEXT_AREA])
- rif->cursor_to (vpos, i, desired_row->y,
- desired_row->pixel_width);
+ output_cursor_to (w, vpos, i, desired_row->y,
+ desired_row->pixel_width);
/* If cursor is displayed at the end of the line, make sure
it's cleared. Nowadays we don't have a phys_cursor_glyph
}
else
xlim = current_row->pixel_width;
- rif->clear_end_of_line (xlim);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
changed_p = 1;
}
}
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
bool changed_p = 0;
- /* Set the row being updated. This is important to let xterm.c
- know what line height values are in effect. */
- updated_row = desired_row;
-
/* A row can be completely invisible in case a desired matrix was
built with a vscroll and then make_cursor_line_fully_visible shifts
the matrix. Make sure to make such rows current anyway, since
eassert (desired_row->enabled_p);
/* Update display of the left margin area, if there is one. */
- if (!desired_row->full_width_p
- && !NILP (w->left_margin_cols))
+ if (!desired_row->full_width_p && w->left_margin_cols > 0)
{
changed_p = 1;
- update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
+ update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
/* Setting this flag will ensure the vertical border, if
any, between this window and the one on its left will be
redrawn. This is necessary because updating the left
}
/* Update the display of the text area. */
- if (update_text_area (w, vpos))
+ if (update_text_area (w, desired_row, vpos))
{
changed_p = 1;
if (current_row->mouse_face_p)
}
/* Update display of the right margin area, if there is one. */
- if (!desired_row->full_width_p
- && !NILP (w->right_margin_cols))
+ if (!desired_row->full_width_p && w->right_margin_cols > 0)
{
changed_p = 1;
- update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
+ update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
}
/* Draw truncation marks etc. */
|| desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
|| (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
!= MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
- rif->after_update_window_line_hook (desired_row);
+ rif->after_update_window_line_hook (w, desired_row);
}
/* Update current_row from desired_row. */
make_current (w->desired_matrix, w->current_matrix, vpos);
- updated_row = NULL;
return changed_p;
}
set_window_cursor_after_update (struct window *w)
{
struct frame *f = XFRAME (w->frame);
- struct redisplay_interface *rif = FRAME_RIF (f);
int cx, cy, vpos, hpos;
/* Not intended for frame matrix updates. */
}
/* Window cursor can be out of sync for horizontally split windows.
- Horisontal position is -1 when cursor is on the left fringe. */
+ Horizontal position is -1 when cursor is on the left fringe. */
hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
- rif->cursor_to (vpos, hpos, cy, cx);
+ output_cursor_to (w, vpos, hpos, cy, cx);
}
{
while (w)
{
- if (!NILP (w->hchild))
- set_window_update_flags (XWINDOW (w->hchild), on_p);
- else if (!NILP (w->vchild))
- set_window_update_flags (XWINDOW (w->vchild), on_p);
+ if (WINDOWP (w->contents))
+ set_window_update_flags (XWINDOW (w->contents), on_p);
else
w->must_be_updated_p = on_p;
row_table[row_entry_pool[i].bucket] = NULL;
/* Value is 1 to indicate that we scrolled the display. */
- return 0 < nruns;
+ return nruns > 0;
}
if (preempt_count <= 0)
preempt_count = 1;
-#if !PERIODIC_PREEMPTION_CHECKING
if (!force_p && detect_input_pending_ignore_squeezables ())
{
pause_p = 1;
goto do_pause;
}
-#endif
/* If we cannot insert/delete lines, it's no use trying it. */
if (!FRAME_LINE_INS_DEL_OK (f))
}
}
-#if PERIODIC_PREEMPTION_CHECKING
- if (!force_p)
- {
- EMACS_TIME tm = current_emacs_time ();
- if (EMACS_TIME_LT (preemption_next_check, tm))
- {
- preemption_next_check = add_emacs_time (tm, preemption_period);
- if (detect_input_pending_ignore_squeezables ())
- break;
- }
- }
-#else
if (!force_p && (i - 1) % preempt_count == 0)
detect_input_pending_ignore_squeezables ();
-#endif
update_frame_line (f, i);
}
int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
- if (INTEGERP (w->left_margin_cols))
- x += XFASTINT (w->left_margin_cols);
-
- /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
+ x += max (0, w->left_margin_cols);
cursor_to (f, y, x);
}
}
}
-#if !PERIODIC_PREEMPTION_CHECKING
do_pause:
-#endif
clear_desired_matrices (f);
return pause_p;
/* We used to set current_buffer directly here, but that does the
wrong thing with `face-remapping-alist' (bug#2044). */
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
itdata = bidi_shelve_cache ();
- SET_TEXT_POS_FROM_MARKER (startp, w->start);
- CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
- BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
+ CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
start_display (&it, w, startp);
/* start_display takes into account the header-line row, but IT's
vpos still counts from the glyph row that includes the window's
*dx = x0 + it.first_visible_x - it.current_x;
*dy = *y - it.current_y;
- string = w->buffer;
+ string = w->contents;
if (STRINGP (it.string))
string = it.string;
*pos = it.current;
if (STRINGP (it.string))
BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
else
- BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->buffer),
+ BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->contents),
CHARPOS (pos->pos));
}
FrameCols (FRAME_TTY (f)) = newwidth;
if (WINDOWP (f->tool_bar_window))
- wset_total_cols (XWINDOW (f->tool_bar_window), make_number (newwidth));
+ XWINDOW (f->tool_bar_window)->total_cols = newwidth;
}
FRAME_LINES (f) = newheight;
tty = CURTTY ();
if (tty->termscript != 0)
- {
- block_input ();
- fclose (tty->termscript);
- unblock_input ();
- }
- tty->termscript = 0;
+ {
+ block_input ();
+ fclose (tty->termscript);
+ tty->termscript = 0;
+ unblock_input ();
+ }
if (! NILP (file))
{
file = Fexpand_file_name (file, Qnil);
- tty->termscript = fopen (SSDATA (file), "w");
+ tty->termscript = emacs_fopen (SSDATA (file), "w");
if (tty->termscript == 0)
- report_file_error ("Opening termscript", Fcons (file, Qnil));
+ report_file_error ("Opening termscript", file);
}
return Qnil;
}
if (noninteractive)
putchar (07);
else if (!INTERACTIVE) /* Stop executing a keyboard macro. */
- error ("Keyboard macro terminated by a command ringing the bell");
+ {
+ const char *msg
+ = "Keyboard macro terminated by a command ringing the bell";
+ Fsignal (Quser_error, list1 (build_string (msg)));
+ }
else
ring_bell (XFRAME (selected_frame));
}
duration += XINT (milliseconds) / 1000.0;
}
- if (0 < duration)
+ if (duration > 0)
{
- EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
- wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX),
- EMACS_NSECS (t), 0, 0, Qnil, NULL, 0);
+ struct timespec t = dtotimespec (duration);
+ wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX),
+ t.tv_nsec, 0, 0, Qnil, NULL, 0);
}
return Qnil;
if (INTEGERP (timeout))
{
sec = XINT (timeout);
- if (! (0 < sec))
+ if (sec <= 0)
return Qt;
nsec = 0;
}
return Qt;
else
{
- EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
- sec = min (EMACS_SECS (t), WAIT_READING_MAX);
- nsec = EMACS_NSECS (t);
+ struct timespec t = dtotimespec (seconds);
+ sec = min (t.tv_sec, WAIT_READING_MAX);
+ nsec = t.tv_nsec;
}
}
else if (EQ (timeout, Qt))
goto changed;
}
/* Check that the buffer info matches. */
- for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_LIVE_BUFFER (tail, buf)
{
- buf = XCDR (XCAR (tail));
/* Ignore buffers that aren't included in buffer lists. */
if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
continue;
n = 1;
FOR_EACH_FRAME (tail, frame)
n += 2;
- for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_LIVE_BUFFER (tail, buf)
n += 3;
/* Reallocate the vector if data has grown to need it,
or if it has shrunk a lot. */
ASET (state, idx, XFRAME (frame)->name);
idx++;
}
- for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_LIVE_BUFFER (tail, buf)
{
- buf = XCDR (XCAR (tail));
/* Ignore buffers that aren't included in buffer lists. */
if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
continue;
inverse_video = 0;
cursor_in_echo_area = 0;
- terminal_type = (char *) 0;
/* Now is the time to initialize this; it's used by init_sys_modes
during startup. */
#ifdef HAVE_X11
Vwindow_system_version = make_number (11);
#endif
-#ifdef GNU_LINUX
+#ifdef USE_NCURSES
/* In some versions of ncurses,
tputs crashes if we have not called tgetent.
So call tgetent. */
/* If no window system has been specified, try to use the terminal. */
if (! isatty (0))
- {
- fatal ("standard input is not a tty");
- exit (1);
- }
+ fatal ("standard input is not a tty");
#ifdef WINDOWSNT
terminal_type = "w32console";
#else
- /* Look at the TERM variable. */
- terminal_type = (char *) getenv ("TERM");
+ terminal_type = getenv ("TERM");
#endif
if (!terminal_type)
{
/* Update frame parameters to reflect the new type. */
Fmodify_frame_parameters
- (selected_frame, Fcons (Fcons (Qtty_type,
- Ftty_type (selected_frame)), Qnil));
+ (selected_frame, list1 (Fcons (Qtty_type,
+ Ftty_type (selected_frame))));
if (t->display_info.tty->name)
- Fmodify_frame_parameters (selected_frame,
- Fcons (Fcons (Qtty, build_string (t->display_info.tty->name)),
- Qnil));
+ Fmodify_frame_parameters
+ (selected_frame,
+ list1 (Fcons (Qtty, build_string (t->display_info.tty->name))));
else
- Fmodify_frame_parameters (selected_frame, Fcons (Fcons (Qtty, Qnil),
- Qnil));
+ Fmodify_frame_parameters (selected_frame, list1 (Fcons (Qtty, Qnil)));
}
{
{
return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
}
-
-DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
- Slast_nonminibuf_frame, 0, 0, 0,
- doc: /* Value is last nonminibuffer frame. */)
- (void)
-{
- Lisp_Object frame = Qnil;
-
- if (last_nonminibuf_frame)
- XSETFRAME (frame, last_nonminibuf_frame);
-
- return frame;
-}
\f
/***********************************************************************
Initialization
defsubr (&Ssend_string_to_terminal);
defsubr (&Sinternal_show_cursor);
defsubr (&Sinternal_show_cursor_p);
- defsubr (&Slast_nonminibuf_frame);
#ifdef GLYPH_DEBUG
defsubr (&Sdump_redisplay_history);
doc: /* Non-nil means display update isn't paused when input is detected. */);
redisplay_dont_pause = 1;
-#if PERIODIC_PREEMPTION_CHECKING
- DEFVAR_LISP ("redisplay-preemption-period", Vredisplay_preemption_period,
- doc: /* Period in seconds between checking for input during redisplay.
-This has an effect only if `redisplay-dont-pause' is nil; in that
-case, arriving input preempts redisplay until the input is processed.
-If the value is nil, redisplay is never preempted. */);
- Vredisplay_preemption_period = make_float (0.10);
-#endif
-
#ifdef CANNOT_DUMP
if (noninteractive)
#endif