/* Updating of data structures for redisplay.
- Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc.
+
+Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* cm.h must come after dispextern.h on Windows. */
#include "dispextern.h"
#include "cm.h"
-#include "buffer.h"
#include "character.h"
+#include "buffer.h"
#include "keyboard.h"
#include "frame.h"
#include "termhooks.h"
#include <errno.h>
/* Get number of chars of output now in the buffer of a stdio stream.
- This ought to be built in in stdio, but it isn't. Some s- files
+ This ought to be built in stdio, but it isn't. Some s- files
override this because their stdio internals differ. */
-
#ifdef __GNU_LIBRARY__
/* The s- file might have overridden the definition with one that
works for the system's C library. But we are using the GNU C
library, so this is the right definition for every system. */
-
#ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT
#define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT
#else
#undef PENDING_OUTPUT_COUNT
#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer)
#endif
-#else /* not __GNU_LIBRARY__ */
-#if !defined (PENDING_OUTPUT_COUNT) && HAVE_STDIO_EXT_H && HAVE___FPENDING
+
+/* not __GNU_LIBRARY__ and no PENDING_OUTPUT_COUNT defined */
+#elif !defined (PENDING_OUTPUT_COUNT)
+
+#if HAVE_STDIO_EXT_H && HAVE___FPENDING
#include <stdio_ext.h>
#define PENDING_OUTPUT_COUNT(FILE) __fpending (FILE)
-#endif
-#ifndef PENDING_OUTPUT_COUNT
+#else
#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)
#endif
-#endif /* not __GNU_LIBRARY__ */
-#if defined (HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
+#endif /* not __GNU_LIBRARY__ and no PENDING_OUTPUT_COUNT defined */
+
+#if defined (HAVE_TERM_H) && defined (GNU_LINUX)
#include <term.h> /* for tgetent */
#endif
\f
static int scrolling_window (struct window *, int);
static int update_window_line (struct window *, int, int *);
static void mirror_make_current (struct window *, int);
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
static void check_matrix_pointers (struct glyph_matrix *,
struct glyph_matrix *);
#endif
static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
\f
-/* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
- are supported, so we can check for input during redisplay at
- regular intervals. */
-#ifdef EMACS_HAS_USECS
-#define PERIODIC_PREEMPTION_CHECKING 1
-#else
-#define PERIODIC_PREEMPTION_CHECKING 0
-#endif
-
-#if PERIODIC_PREEMPTION_CHECKING
-
/* Redisplay preemption timers. */
static EMACS_TIME preemption_period;
static EMACS_TIME preemption_next_check;
-#endif
-
/* Nonzero upon entry to redisplay means do not assume anything about
current contents of actual terminal frame; clear and redraw it. */
/* Convert vpos and hpos from frame to window and vice versa.
This may only be used for terminal frames. */
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
static int window_to_frame_vpos (struct window *, int);
static int window_to_frame_hpos (struct window *, int);
"%"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))
+ ((BUFFERP (WVAR (w, buffer))
+ && STRINGP (BVAR (XBUFFER (WVAR (w, buffer)), name)))
+ ? SSDATA (BVAR (XBUFFER (WVAR (w, buffer)), name))
: "???"),
paused_p ? " ***paused***" : "",
msg);
}
-#else /* GLYPH_DEBUG == 0 */
+#else /* not GLYPH_DEBUG */
#define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
#define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
-#endif /* GLYPH_DEBUG == 0 */
-
+#endif /* GLYPH_DEBUG */
-#if defined PROFILING && !HAVE___EXECUTABLE_START
-/* FIXME: only used to find text start for profiling. */
+#if (defined PROFILING \
+ && (defined __FreeBSD__ || defined GNU_LINUX || defined __MINGW32__) \
+ && !HAVE___EXECUTABLE_START)
+/* This function comes first in the Emacs executable and is used only
+ to estimate the text start for profiling. */
void
-safe_bcopy (const char *from, char *to, int size)
+__executable_start (void)
{
abort ();
}
static struct glyph_matrix *
new_glyph_matrix (struct glyph_pool *pool)
{
- struct glyph_matrix *result;
-
- /* Allocate and clear. */
- result = (struct glyph_matrix *) xmalloc (sizeof *result);
- memset (result, 0, sizeof *result);
+ struct glyph_matrix *result = xzalloc (sizeof *result);
/* Increment number of allocated matrices. This count is used
to detect memory leaks. */
if (NUMBERP (margin))
{
- int width = XFASTINT (w->total_cols);
+ int width = XFASTINT (WVAR (w, total_cols));
double d = max (0, XFLOATINT (margin));
d = min (width / 2 - 1, d);
n = (int) ((double) total_glyphs / width * d);
return n;
}
+/* Return non-zero if ROW's hash value is correct, zero if not.
+ Optimized away if ENABLE_CHECKING is not defined. */
+
+static int
+verify_row_hash (struct glyph_row *row)
+{
+ return row->hash == row_hash (row);
+}
/* Adjust glyph matrix MATRIX on window W or on a frame to changed
window sizes.
the matrix means preventing redisplay. */
if (matrix->pool == NULL)
{
- left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
- right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
- xassert (left >= 0 && right >= 0);
+ left = margin_glyphs_to_reserve (w, dim.width, WVAR (w, left_margin_cols));
+ right = margin_glyphs_to_reserve (w, dim.width, WVAR (w, right_margin_cols));
+ eassert (left >= 0 && right >= 0);
marginal_areas_changed_p = (left != matrix->left_margin_glyphs
|| right != matrix->right_margin_glyphs);
each row into the glyph pool. */
if (matrix->pool)
{
- xassert (matrix->pool->glyphs);
+ eassert (matrix->pool->glyphs);
if (w)
{
left = margin_glyphs_to_reserve (w, dim.width,
- w->left_margin_cols);
+ WVAR (w, left_margin_cols));
right = margin_glyphs_to_reserve (w, dim.width,
- w->right_margin_cols);
+ WVAR (w, right_margin_cols));
}
else
left = right = 0;
}
}
- xassert (left >= 0 && right >= 0);
+ eassert (left >= 0 && right >= 0);
matrix->left_margin_glyphs = left;
matrix->right_margin_glyphs = right;
}
/* Number of rows to be used by MATRIX. */
matrix->nrows = dim.height;
- xassert (matrix->nrows >= 0);
+ eassert (matrix->nrows >= 0);
if (w)
{
/* 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)
- w->window_end_valid = Qnil;
+ if (INTEGERP (WVAR (w, window_end_vpos))
+ && XFASTINT (WVAR (w, window_end_vpos)) >= i)
+ WVAR (w, window_end_valid) = Qnil;
while (i < matrix->nrows)
matrix->rows[i++].enabled_p = 0;
ptrdiff_t delta, ptrdiff_t delta_bytes)
{
/* Check that START and END are reasonable values. */
- xassert (start >= 0 && start <= matrix->nrows);
- xassert (end >= 0 && end <= matrix->nrows);
- xassert (start <= end);
+ eassert (start >= 0 && start <= matrix->nrows);
+ eassert (end >= 0 && end <= matrix->nrows);
+ eassert (start <= end);
for (; start < end; ++start)
increment_row_positions (matrix->rows + start, delta, delta_bytes);
void
enable_glyph_matrix_rows (struct glyph_matrix *matrix, int start, int end, int enabled_p)
{
- xassert (start <= end);
- xassert (start >= 0 && start < matrix->nrows);
- xassert (end >= 0 && end <= matrix->nrows);
+ eassert (start <= end);
+ eassert (start >= 0 && start < matrix->nrows);
+ eassert (end >= 0 && end <= matrix->nrows);
for (; start < end; ++start)
matrix->rows[start].enabled_p = enabled_p != 0;
{
int min_y, max_y;
- xassert (start <= end);
- xassert (start >= 0 && start < matrix->nrows);
- xassert (end >= 0 && end <= matrix->nrows);
+ eassert (start <= end);
+ eassert (start >= 0 && start < matrix->nrows);
+ eassert (end >= 0 && end <= matrix->nrows);
min_y = WINDOW_HEADER_LINE_HEIGHT (w);
max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
/* 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);
+ if (WINDOWP (FVAR (f, menu_bar_window)))
+ clear_glyph_matrix (XWINDOW (FVAR (f, menu_bar_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);
+ if (WINDOWP (FVAR (f, tool_bar_window)))
+ clear_glyph_matrix (XWINDOW (FVAR (f, tool_bar_window))->current_matrix);
/* Clear current window matrices. */
- xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
+ eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
}
if (f->desired_matrix)
clear_glyph_matrix (f->desired_matrix);
- if (WINDOWP (f->menu_bar_window))
- clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
+ if (WINDOWP (FVAR (f, menu_bar_window)))
+ clear_glyph_matrix (XWINDOW (FVAR (f, menu_bar_window))->desired_matrix);
- if (WINDOWP (f->tool_bar_window))
- clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
+ if (WINDOWP (FVAR (f, tool_bar_window)))
+ clear_glyph_matrix (XWINDOW (FVAR (f, tool_bar_window))->desired_matrix);
/* Do it for window matrices. */
- xassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
+ eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
}
{
while (w)
{
- if (!NILP (w->hchild))
+ if (!NILP (WVAR (w, hchild)))
{
- xassert (WINDOWP (w->hchild));
- clear_window_matrices (XWINDOW (w->hchild), desired_p);
+ eassert (WINDOWP (WVAR (w, hchild)));
+ clear_window_matrices (XWINDOW (WVAR (w, hchild)), desired_p);
}
- else if (!NILP (w->vchild))
+ else if (!NILP (WVAR (w, vchild)))
{
- xassert (WINDOWP (w->vchild));
- clear_window_matrices (XWINDOW (w->vchild), desired_p);
+ eassert (WINDOWP (WVAR (w, vchild)));
+ clear_window_matrices (XWINDOW (WVAR (w, vchild)), desired_p);
}
else
{
else
{
clear_glyph_matrix (w->current_matrix);
- w->window_end_valid = Qnil;
+ WVAR (w, window_end_valid) = Qnil;
}
}
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
}
clear_glyph_row (row);
row->y = y;
row->ascent = row->phys_ascent = 0;
- row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
+ row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (WVAR (w, frame)));
row->visible_height = row->height;
if (row->y < min_y)
#endif /* 0 */
-/* Exchange pointers to glyph memory between glyph rows A and B. */
+/* Exchange pointers to glyph memory between glyph rows A and B. Also
+ exchange the used[] array and the hash values of the rows, because
+ these should all go together for the row's hash value to be
+ correct. */
static inline void
swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
{
int i;
+ unsigned hash_tem = a->hash;
+
for (i = 0; i < LAST_AREA + 1; ++i)
{
struct glyph *temp = a->glyphs[i];
+
a->glyphs[i] = b->glyphs[i];
b->glyphs[i] = temp;
+ if (i < LAST_AREA)
+ {
+ short used_tem = a->used[i];
+
+ a->used[i] = b->used[i];
+ b->used[i] = used_tem;
+ }
}
+ a->hash = b->hash;
+ b->hash = hash_tem;
}
/* Copy glyph row structure FROM to glyph row structure TO, except
- that glyph pointers in the structures are left unchanged. */
+ that glyph pointers, the `used' counts, and the hash values in the
+ structures are left unchanged. */
static inline void
copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
{
struct glyph *pointers[1 + LAST_AREA];
+ short used[LAST_AREA];
+ unsigned hashval;
/* Save glyph pointers of TO. */
memcpy (pointers, to->glyphs, sizeof to->glyphs);
+ memcpy (used, to->used, sizeof to->used);
+ hashval = to->hash;
/* Do a structure assignment. */
*to = *from;
/* Restore original pointers of TO. */
memcpy (to->glyphs, pointers, sizeof to->glyphs);
+ memcpy (to->used, used, sizeof to->used);
+ to->hash = hashval;
}
is non-zero if the glyph memory of WINDOW_ROW is part of the glyph
memory of FRAME_ROW. */
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
static int
glyph_row_slice_p (struct glyph_row *window_row, struct glyph_row *frame_row)
{
int i;
- xassert (row >= 0 && row < frame_matrix->nrows);
+ eassert (row >= 0 && row < frame_matrix->nrows);
for (i = 0; i < window_matrix->nrows; ++i)
if (glyph_row_slice_p (window_matrix->rows + i,
static inline int
row_equal_p (struct glyph_row *a, struct glyph_row *b, int mouse_face_p)
{
+ eassert (verify_row_hash (a));
+ eassert (verify_row_hash (b));
+
if (a == b)
return 1;
else if (a->hash != b->hash)
static struct glyph_pool *
new_glyph_pool (void)
{
- struct glyph_pool *result;
-
- /* Allocate a new glyph_pool and clear it. */
- result = (struct glyph_pool *) xmalloc (sizeof *result);
- memset (result, 0, sizeof *result);
+ struct glyph_pool *result = xzalloc (sizeof *result);
/* For memory leak and double deletion checking. */
++glyph_pool_count;
{
/* More freed than allocated? */
--glyph_pool_count;
- xassert (glyph_pool_count >= 0);
+ eassert (glyph_pool_count >= 0);
xfree (pool->glyphs);
xfree (pool);
Debug Code
***********************************************************************/
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
/* Flush standard output. This is sometimes useful to call from the debugger.
for (i = 0; i < matrix->nrows; ++i)
for (j = 0; j < matrix->nrows; ++j)
- xassert (i == j
+ eassert (i == j
|| (matrix->rows[i].glyphs[TEXT_AREA]
!= matrix->rows[j].glyphs[TEXT_AREA]));
}
struct glyph_row *
matrix_row (struct glyph_matrix *matrix, int row)
{
- xassert (matrix && matrix->rows);
- xassert (row >= 0 && row < matrix->nrows);
+ eassert (matrix && matrix->rows);
+ eassert (row >= 0 && row < matrix->nrows);
/* That's really too slow for normal testing because this function
is called almost everywhere. Although---it's still astonishingly
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 (WVAR (w, buffer));
int c;
/* This can sometimes happen for a fresh window. */
last_text_row = row;
/* Check that character and byte positions are in sync. */
- xassert (MATRIX_ROW_START_BYTEPOS (row)
+ eassert (MATRIX_ROW_START_BYTEPOS (row)
== CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
- xassert (BYTEPOS (row->start.pos)
+ eassert (BYTEPOS (row->start.pos)
== CHAR_TO_BYTE (CHARPOS (row->start.pos)));
/* CHAR_TO_BYTE aborts when invoked for a position > Z. We can
displaying something like `[Sole completion]' at its end. */
if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
{
- xassert (MATRIX_ROW_END_BYTEPOS (row)
+ eassert (MATRIX_ROW_END_BYTEPOS (row)
== CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
- xassert (BYTEPOS (row->end.pos)
+ eassert (BYTEPOS (row->end.pos)
== CHAR_TO_BYTE (CHARPOS (row->end.pos)));
}
of next row. */
if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
{
- xassert (MATRIX_ROW_END_CHARPOS (row)
+ eassert (MATRIX_ROW_END_CHARPOS (row)
== MATRIX_ROW_START_CHARPOS (next));
- xassert (MATRIX_ROW_END_BYTEPOS (row)
+ eassert (MATRIX_ROW_END_BYTEPOS (row)
== MATRIX_ROW_START_BYTEPOS (next));
- xassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
- xassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
+ eassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
+ eassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
}
row = next;
}
- xassert (w->current_matrix->nrows == w->desired_matrix->nrows);
- xassert (w->desired_matrix->rows != NULL);
+ eassert (w->current_matrix->nrows == w->desired_matrix->nrows);
+ eassert (w->desired_matrix->rows != NULL);
set_buffer_temp (saved);
}
#endif /* 0 */
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
\f
points to the mini-buffer window, if any, which is arranged
vertically below other windows. */
in_horz_combination_p
- = (!NILP (XWINDOW (window)->parent)
- && !NILP (XWINDOW (XWINDOW (window)->parent)->hchild));
+ = (!NILP (WVAR (XWINDOW (window), parent))
+ && !NILP (WVAR (XWINDOW (WVAR (XWINDOW (window), parent)), hchild)));
/* 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,
+ if (!NILP (WVAR (w, hchild)))
+ dim = allocate_matrices_for_frame_redisplay (WVAR (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,
+ else if (!NILP (WVAR (w, vchild)))
+ dim = allocate_matrices_for_frame_redisplay (WVAR (w, vchild), x, y,
dim_only_p,
window_change_flags);
else
|| dim.width != w->desired_matrix->matrix_w
|| dim.height != w->desired_matrix->matrix_h
|| (margin_glyphs_to_reserve (w, dim.width,
- w->left_margin_cols)
+ WVAR (w, left_margin_cols))
!= w->desired_matrix->left_margin_glyphs)
|| (margin_glyphs_to_reserve (w, dim.width,
- w->right_margin_cols)
+ WVAR (w, right_margin_cols))
!= w->desired_matrix->right_margin_glyphs))
*window_change_flags |= CHANGED_LEAF_MATRIX;
hmax = max (hmax, dim.height);
/* Next window on same level. */
- window = w->next;
+ window = WVAR (w, next);
}
while (!NILP (window));
required_matrix_height (struct window *w)
{
#ifdef HAVE_WINDOW_SYSTEM
- struct frame *f = XFRAME (w->frame);
+ struct frame *f = XFRAME (WVAR (w, frame));
if (FRAME_WINDOW_P (f))
{
required_matrix_width (struct window *w)
{
#ifdef HAVE_WINDOW_SYSTEM
- struct frame *f = XFRAME (w->frame);
+ struct frame *f = XFRAME (WVAR (w, frame));
if (FRAME_WINDOW_P (f))
{
int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
}
#endif /* HAVE_WINDOW_SYSTEM */
- return XINT (w->total_cols);
+ return XINT (WVAR (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 (!NILP (WVAR (w, vchild)))
+ allocate_matrices_for_window_redisplay (XWINDOW (WVAR (w, vchild)));
+ else if (!NILP (WVAR (w, hchild)))
+ allocate_matrices_for_window_redisplay (XWINDOW (WVAR (w, hchild)));
else
{
/* W is a leaf window. */
adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
}
- w = NILP (w->next) ? NULL : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? NULL : XWINDOW (WVAR (w, next));
}
}
adjust_frame_glyphs_initially (void)
{
struct frame *sf = SELECTED_FRAME ();
- struct window *root = XWINDOW (sf->root_window);
- struct window *mini = XWINDOW (root->next);
+ struct window *root = XWINDOW (FVAR (sf, root_window));
+ struct window *mini = XWINDOW (WVAR (root, next));
int frame_lines = FRAME_LINES (sf);
int frame_cols = FRAME_COLS (sf);
int top_margin = FRAME_TOP_MARGIN (sf);
/* 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);
+ XSETFASTINT (WVAR (root, top_line), top_margin);
+ XSETFASTINT (WVAR (root, total_lines), frame_lines - 1 - top_margin);
+ XSETFASTINT (WVAR (root, total_cols), frame_cols);
/* 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);
+ XSETFASTINT (WVAR (mini, top_line), frame_lines - 1);
+ XSETFASTINT (WVAR (mini, total_lines), 1);
+ XSETFASTINT (WVAR (mini, total_cols), frame_cols);
adjust_frame_glyphs (sf);
glyphs_initialized_initially_p = 1;
{
while (w)
{
- if (!NILP (w->hchild))
+ if (!NILP (WVAR (w, hchild)))
{
- if (showing_window_margins_p (XWINDOW (w->hchild)))
+ if (showing_window_margins_p (XWINDOW (WVAR (w, hchild))))
return 1;
}
- else if (!NILP (w->vchild))
+ else if (!NILP (WVAR (w, vchild)))
{
- if (showing_window_margins_p (XWINDOW (w->vchild)))
+ if (showing_window_margins_p (XWINDOW (WVAR (w, vchild))))
return 1;
}
- else if (!NILP (w->left_margin_cols)
- || !NILP (w->right_margin_cols))
+ else if (!NILP (WVAR (w, left_margin_cols))
+ || !NILP (WVAR (w, right_margin_cols)))
return 1;
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
return 0;
}
{
struct window *w;
- for (; !NILP (window); window = w->next)
+ for (; !NILP (window); window = WVAR (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 (!NILP (WVAR (w, hchild)))
+ fake_current_matrices (WVAR (w, hchild));
+ else if (!NILP (WVAR (w, vchild)))
+ fake_current_matrices (WVAR (w, vchild));
else
{
int i;
- struct frame *f = XFRAME (w->frame);
+ struct frame *f = XFRAME (WVAR (w, frame));
struct glyph_matrix *m = w->current_matrix;
struct glyph_matrix *fm = f->current_matrix;
- xassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
- xassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
+ eassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
+ eassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
for (i = 0; i < m->matrix_h; ++i)
{
struct glyph_row *r = m->rows + i;
struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
- xassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
+ eassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
&& r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
r->enabled_p = fr->enabled_p;
save_current_matrix (struct frame *f)
{
int i;
- struct glyph_matrix *saved;
-
- saved = (struct glyph_matrix *) xmalloc (sizeof *saved);
- memset (saved, 0, sizeof *saved);
+ struct glyph_matrix *saved = xzalloc (sizeof *saved);
saved->nrows = f->current_matrix->nrows;
- saved->rows = (struct glyph_row *) xmalloc (saved->nrows
- * sizeof *saved->rows);
- memset (saved->rows, 0, saved->nrows * sizeof *saved->rows);
+ saved->rows = xzalloc (saved->nrows * sizeof *saved->rows);
for (i = 0; i < saved->nrows; ++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] = (struct glyph *) xmalloc (nbytes);
+ to->glyphs[TEXT_AREA] = xmalloc (nbytes);
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
}
/* Size of frame matrices must equal size of frame. Note
that we are called for X frames with window widths NOT equal
to the frame width (from CHANGE_FRAME_SIZE_1). */
- xassert (matrix_dim.width == FRAME_COLS (f)
+ eassert (matrix_dim.width == FRAME_COLS (f)
&& matrix_dim.height == FRAME_LINES (f));
/* Pointers to glyph memory in glyph rows are exchanged during
static void
adjust_frame_glyphs_for_window_redisplay (struct frame *f)
{
- xassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
+ eassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
/* Allocate/reallocate window matrices. */
allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
{
/* Allocate a dummy window if not already done. */
struct window *w;
- if (NILP (f->menu_bar_window))
+ if (NILP (FVAR (f, menu_bar_window)))
{
- f->menu_bar_window = make_window ();
- w = XWINDOW (f->menu_bar_window);
- XSETFRAME (w->frame, f);
+ FVAR (f, menu_bar_window) = make_window ();
+ w = XWINDOW (FVAR (f, menu_bar_window));
+ XSETFRAME (WVAR (w, frame), f);
w->pseudo_window_p = 1;
}
else
- w = XWINDOW (f->menu_bar_window);
+ w = XWINDOW (FVAR (f, menu_bar_window));
/* Set window dimensions to frame dimensions and allocate or
adjust glyph matrices of W. */
- XSETFASTINT (w->top_line, 0);
- XSETFASTINT (w->left_col, 0);
- XSETFASTINT (w->total_lines, FRAME_MENU_BAR_LINES (f));
- XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
+ XSETFASTINT (WVAR (w, top_line), 0);
+ XSETFASTINT (WVAR (w, left_col), 0);
+ XSETFASTINT (WVAR (w, total_lines), FRAME_MENU_BAR_LINES (f));
+ XSETFASTINT (WVAR (w, total_cols), FRAME_TOTAL_COLS (f));
allocate_matrices_for_window_redisplay (w);
}
#endif /* not USE_X_TOOLKIT && not USE_GTK */
/* Allocate/ reallocate matrices of the tool bar window. If we
don't have a tool bar window yet, make one. */
struct window *w;
- if (NILP (f->tool_bar_window))
+ if (NILP (FVAR (f, tool_bar_window)))
{
- f->tool_bar_window = make_window ();
- w = XWINDOW (f->tool_bar_window);
- XSETFRAME (w->frame, f);
+ FVAR (f, tool_bar_window) = make_window ();
+ w = XWINDOW (FVAR (f, tool_bar_window));
+ XSETFRAME (WVAR (w, frame), f);
w->pseudo_window_p = 1;
}
else
- w = XWINDOW (f->tool_bar_window);
+ w = XWINDOW (FVAR (f, tool_bar_window));
- XSETFASTINT (w->top_line, FRAME_MENU_BAR_LINES (f));
- XSETFASTINT (w->left_col, 0);
- XSETFASTINT (w->total_lines, FRAME_TOOL_BAR_LINES (f));
- XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
+ XSETFASTINT (WVAR (w, top_line), FRAME_MENU_BAR_LINES (f));
+ XSETFASTINT (WVAR (w, left_col), 0);
+ XSETFASTINT (WVAR (w, total_lines), FRAME_TOOL_BAR_LINES (f));
+ XSETFASTINT (WVAR (w, total_cols), FRAME_TOTAL_COLS (f));
allocate_matrices_for_window_redisplay (w);
}
#endif
static void
adjust_frame_message_buffer (struct frame *f)
{
- ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
-
- if (FRAME_MESSAGE_BUF (f))
- {
- char *buffer = FRAME_MESSAGE_BUF (f);
- char *new_buffer = (char *) xrealloc (buffer, size);
- FRAME_MESSAGE_BUF (f) = new_buffer;
- }
- else
- FRAME_MESSAGE_BUF (f) = (char *) xmalloc (size);
+ FRAME_MESSAGE_BUF (f) = xrealloc (FRAME_MESSAGE_BUF (f),
+ FRAME_MESSAGE_BUF_SIZE (f) + 1);
}
static void
adjust_decode_mode_spec_buffer (struct frame *f)
{
- f->decode_mode_spec_buffer
- = (char *) xrealloc (f->decode_mode_spec_buffer,
- FRAME_MESSAGE_BUF_SIZE (f) + 1);
+ f->decode_mode_spec_buffer = xrealloc (f->decode_mode_spec_buffer,
+ FRAME_MESSAGE_BUF_SIZE (f) + 1);
}
f->glyphs_initialized_p = 0;
/* Release window sub-matrices. */
- if (!NILP (f->root_window))
- free_window_matrices (XWINDOW (f->root_window));
+ if (!NILP (FVAR (f, root_window)))
+ free_window_matrices (XWINDOW (FVAR (f, root_window)));
/* Free the dummy window for menu bars without X toolkit and its
glyph matrices. */
- if (!NILP (f->menu_bar_window))
+ if (!NILP (FVAR (f, menu_bar_window)))
{
- struct window *w = XWINDOW (f->menu_bar_window);
+ struct window *w = XWINDOW (FVAR (f, menu_bar_window));
free_glyph_matrix (w->desired_matrix);
free_glyph_matrix (w->current_matrix);
w->desired_matrix = w->current_matrix = NULL;
- f->menu_bar_window = Qnil;
+ FVAR (f, menu_bar_window) = Qnil;
}
/* Free the tool bar window and its glyph matrices. */
- if (!NILP (f->tool_bar_window))
+ if (!NILP (FVAR (f, tool_bar_window)))
{
- struct window *w = XWINDOW (f->tool_bar_window);
+ struct window *w = XWINDOW (FVAR (f, tool_bar_window));
free_glyph_matrix (w->desired_matrix);
free_glyph_matrix (w->current_matrix);
w->desired_matrix = w->current_matrix = NULL;
- f->tool_bar_window = Qnil;
+ FVAR (f, tool_bar_window) = Qnil;
}
/* Release frame glyph matrices. Reset fields to zero in
{
while (w)
{
- if (!NILP (w->hchild))
- free_window_matrices (XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- free_window_matrices (XWINDOW (w->vchild));
+ if (!NILP (WVAR (w, hchild)))
+ free_window_matrices (XWINDOW (WVAR (w, hchild)));
+ else if (!NILP (WVAR (w, vchild)))
+ free_window_matrices (XWINDOW (WVAR (w, vchild)));
else
{
/* This is a leaf window. Free its memory and reset fields
}
/* Next window on same level. */
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
}
int i;
/* F must have a frame matrix when this function is called. */
- xassert (!FRAME_WINDOW_P (f));
+ eassert (!FRAME_WINDOW_P (f));
/* Clear all rows in the frame matrix covered by window matrices.
Menu bar lines are not covered by windows. */
{
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 (!NILP (WVAR (w, hchild)))
+ build_frame_matrix_from_window_tree (matrix, XWINDOW (WVAR (w, hchild)));
+ else if (!NILP (WVAR (w, vchild)))
+ build_frame_matrix_from_window_tree (matrix, XWINDOW (WVAR (w, vchild)));
else
build_frame_matrix_from_leaf_window (matrix, w);
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
}
}
else
{
- xassert (window_row->enabled_p);
+ eassert (window_row->enabled_p);
/* Only when a desired row has been displayed, we want
the corresponding frame row to be updated. */
SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
}
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
/* Window row window_y must be a slice of frame row
frame_y. */
- xassert (glyph_row_slice_p (window_row, frame_row));
+ eassert (glyph_row_slice_p (window_row, frame_row));
/* If rows are in sync, we don't have to copy glyphs because
frame and window share glyphs. */
/* Convert the glyph's specified face to a realized (cache) face. */
if (lface_id > 0)
{
- int face_id = merge_faces (XFRAME (w->frame),
+ int face_id = merge_faces (XFRAME (WVAR (w, frame)),
Qt, lface_id, DEFAULT_FACE_ID);
SET_GLYPH_FACE (*glyph, face_id);
}
/* If we are called on frame matrices, perform analogous operations
for window matrices. */
if (frame_matrix_frame)
- mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
+ mirror_make_current (XWINDOW (FVAR (frame_matrix_frame, root_window)), row);
}
{
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 (!NILP (WVAR (w, hchild)))
+ mirror_make_current (XWINDOW (WVAR (w, hchild)), frame_row);
+ else if (!NILP (WVAR (w, vchild)))
+ mirror_make_current (XWINDOW (WVAR (w, vchild)), frame_row);
else
{
/* Row relative to window W. Don't use FRAME_TO_WINDOW_VPOS
}
}
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
}
int i;
/* Make a copy of the original rows. */
- old_rows = (struct glyph_row *) alloca (nlines * sizeof *old_rows);
+ old_rows = alloca (nlines * sizeof *old_rows);
memcpy (old_rows, new_rows, nlines * sizeof *old_rows);
/* Assign new rows, maybe clear lines. */
{
int enabled_before_p = new_rows[i].enabled_p;
- xassert (i + unchanged_at_top < matrix->nrows);
- xassert (unchanged_at_top + copy_from[i] < matrix->nrows);
+ eassert (i + unchanged_at_top < matrix->nrows);
+ eassert (unchanged_at_top + copy_from[i] < matrix->nrows);
new_rows[i] = old_rows[copy_from[i]];
new_rows[i].enabled_p = enabled_before_p;
/* Do the same for window matrices, if MATRIX is a frame matrix. */
if (frame_matrix_frame)
- mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
+ mirror_line_dance (XWINDOW (FVAR (frame_matrix_frame, root_window)),
unchanged_at_top, nlines, copy_from, retained_p);
}
static void
sync_window_with_frame_matrix_rows (struct window *w)
{
- struct frame *f = XFRAME (w->frame);
+ struct frame *f = XFRAME (WVAR (w, frame));
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. */
- xassert (NILP (w->hchild) && NILP (w->vchild));
- xassert (!FRAME_WINDOW_P (f));
+ eassert (NILP (WVAR (w, hchild)) && NILP (WVAR (w, vchild)));
+ eassert (!FRAME_WINDOW_P (f));
- left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
- right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
+ left = margin_glyphs_to_reserve (w, 1, WVAR (w, left_margin_cols));
+ right = margin_glyphs_to_reserve (w, 1, WVAR (w, right_margin_cols));
x = w->current_matrix->matrix_x;
width = w->current_matrix->matrix_w;
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 (!NILP (WVAR (w, hchild)))
+ found = frame_row_to_window (XWINDOW (WVAR (w, hchild)), row);
+ else if (!NILP (WVAR (w, vchild)))
+ found = frame_row_to_window (XWINDOW (WVAR (w, vchild)), row);
else if (row >= WINDOW_TOP_EDGE_LINE (w)
&& row < WINDOW_BOTTOM_EDGE_LINE (w))
found = w;
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
return found;
{
while (w)
{
- if (!NILP (w->hchild))
- mirror_line_dance (XWINDOW (w->hchild), unchanged_at_top,
+ if (!NILP (WVAR (w, hchild)))
+ mirror_line_dance (XWINDOW (WVAR (w, hchild)), unchanged_at_top,
nlines, copy_from, retained_p);
- else if (!NILP (w->vchild))
- mirror_line_dance (XWINDOW (w->vchild), unchanged_at_top,
+ else if (!NILP (WVAR (w, vchild)))
+ mirror_line_dance (XWINDOW (WVAR (w, vchild)), unchanged_at_top,
nlines, copy_from, retained_p);
else
{
struct glyph_row *old_rows;
/* Make a copy of the original rows of matrix m. */
- old_rows = (struct glyph_row *) alloca (m->nrows * sizeof *old_rows);
+ old_rows = alloca (m->nrows * sizeof *old_rows);
memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows);
for (i = 0; i < nlines; ++i)
{
/* A copy between windows. This is an infrequent
case not worth optimizing. */
- struct frame *f = XFRAME (w->frame);
+ struct frame *f = XFRAME (WVAR (w, frame));
struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
struct window *w2;
struct glyph_matrix *m2;
}
/* Next window on same level. */
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
}
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
/* Check that window and frame matrices agree about their
understanding where glyphs of the rows are to find. For each
{
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 (!NILP (WVAR (w, hchild)))
+ check_window_matrix_pointers (XWINDOW (WVAR (w, hchild)));
+ else if (!NILP (WVAR (w, vchild)))
+ check_window_matrix_pointers (XWINDOW (WVAR (w, vchild)));
else
{
- struct frame *f = XFRAME (w->frame);
+ struct frame *f = XFRAME (WVAR (w, frame));
check_matrix_pointers (w->desired_matrix, f->desired_matrix);
check_matrix_pointers (w->current_matrix, f->current_matrix);
}
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
}
}
}
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
\f
VPOS and HPOS translations
**********************************************************************/
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
/* Translate vertical position VPOS which is relative to window W to a
vertical position relative to W's frame. */
static int
window_to_frame_vpos (struct window *w, int vpos)
{
- xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
- xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
+ eassert (!FRAME_WINDOW_P (XFRAME (WVAR (w, frame))));
+ eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
vpos += WINDOW_TOP_EDGE_LINE (w);
- xassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (w->frame)));
+ eassert (vpos >= 0 && vpos <= FRAME_LINES (XFRAME (WVAR (w, frame))));
return vpos;
}
static int
window_to_frame_hpos (struct window *w, int hpos)
{
- xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
+ eassert (!FRAME_WINDOW_P (XFRAME (WVAR (w, frame))));
hpos += WINDOW_LEFT_EDGE_COL (w);
return hpos;
}
{
/* 1 means display has been paused because of pending input. */
int paused_p;
- struct window *root_window = XWINDOW (f->root_window);
+ struct window *root_window = XWINDOW (FVAR (f, root_window));
if (redisplay_dont_pause)
force_p = 1;
-#if PERIODIC_PREEMPTION_CHECKING
else if (NILP (Vredisplay_preemption_period))
force_p = 1;
else if (!force_p && NUMBERP (Vredisplay_preemption_period))
{
- EMACS_TIME tm;
double p = XFLOATINT (Vredisplay_preemption_period);
- int sec, usec;
if (detect_input_pending_ignore_squeezables ())
{
goto do_pause;
}
- sec = (int) p;
- usec = (p - sec) * 1000000;
-
- EMACS_GET_TIME (tm);
- EMACS_SET_SECS_USECS (preemption_period, sec, usec);
- EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ preemption_period = EMACS_TIME_FROM_DOUBLE (p);
+ preemption_next_check = add_emacs_time (current_emacs_time (),
+ preemption_period);
}
-#endif
if (FRAME_WINDOW_P (f))
{
/* 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);
+ if (WINDOWP (FVAR (f, menu_bar_window)))
+ update_window (XWINDOW (FVAR (f, menu_bar_window)), 1);
/* Update the tool-bar window, if present. */
- if (WINDOWP (f->tool_bar_window))
+ if (WINDOWP (FVAR (f, tool_bar_window)))
{
- struct window *w = XWINDOW (f->tool_bar_window);
+ struct window *w = XWINDOW (FVAR (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_tool_bar_string;
- f->current_tool_bar_string = f->desired_tool_bar_string;
- f->desired_tool_bar_string = tem;
+ tem = FVAR (f, current_tool_bar_string);
+ FVAR (f, current_tool_bar_string) = FVAR (f,
+ desired_tool_bar_string);
+ FVAR (f, desired_tool_bar_string) = tem;
}
}
}
/* Check window matrices for lost pointers. */
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
check_window_matrix_pointers (root_window);
add_frame_display_history (f, paused_p);
#endif
}
-#if PERIODIC_PREEMPTION_CHECKING
do_pause:
-#endif
/* Reset flags indicating that a window should be updated. */
set_window_update_flags (root_window, 0);
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 (!NILP (WVAR (w, hchild)))
+ paused_p |= update_window_tree (XWINDOW (WVAR (w, hchild)), force_p);
+ else if (!NILP (WVAR (w, vchild)))
+ paused_p |= update_window_tree (XWINDOW (WVAR (w, vchild)), force_p);
else if (w->must_be_updated_p)
paused_p |= update_window (w, force_p);
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
return paused_p;
if (redisplay_dont_pause)
force_p = 1;
-#if PERIODIC_PREEMPTION_CHECKING
else if (NILP (Vredisplay_preemption_period))
force_p = 1;
else if (!force_p && NUMBERP (Vredisplay_preemption_period))
{
- EMACS_TIME tm;
double p = XFLOATINT (Vredisplay_preemption_period);
- int sec, usec;
-
- sec = (int) p;
- usec = (p - sec) * 1000000;
-
- EMACS_GET_TIME (tm);
- EMACS_SET_SECS_USECS (preemption_period, sec, usec);
- EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ preemption_period = EMACS_TIME_FROM_DOUBLE (p);
+ preemption_next_check = add_emacs_time (current_emacs_time (),
+ preemption_period);
}
-#endif
/* Update W. */
update_begin (f);
if (row->used[RIGHT_MARGIN_AREA])
rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
- /* Record in neighbour rows that ROW overwrites part of
+ /* Record in neighbor rows that ROW overwrites part of
their display. */
if (overlaps & OVERLAPS_PRED)
MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
int preempt_count = baud_rate / 2400 + 1;
#endif
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
/* Check that W's frame doesn't have glyph matrices. */
- xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
+ eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
#endif
/* Check pending input the first time so that we can quickly return. */
rif->update_window_begin_hook (w);
yb = window_text_bottom_y (w);
-
- /* If window has a header line, update it before everything else.
- Adjust y-positions of other rows by the header line height. */
row = desired_matrix->rows;
end = row + desired_matrix->nrows - 1;
+ /* Take note of the header line, if there is one. We will
+ update it below, after updating all of the window's lines. */
if (row->mode_line_p)
{
header_line_row = row;
/* Update the rest of the lines. */
for (; row < end && (force_p || !input_pending); ++row)
+ /* scrolling_window resets the enabled_p flag of the rows it
+ reuses from current_matrix. */
if (row->enabled_p)
{
int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
#if PERIODIC_PREEMPTION_CHECKING
if (!force_p)
{
- EMACS_TIME tm, dif;
- EMACS_GET_TIME (tm);
- EMACS_SUB_TIME (dif, preemption_next_check, tm);
- if (EMACS_TIME_NEG_P (dif))
+ EMACS_TIME tm = current_emacs_time ();
+ if (EMACS_TIME_LT (preemption_next_check, tm))
{
- EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ preemption_next_check = add_emacs_time (tm,
+ preemption_period);
if (detect_input_pending_ignore_squeezables ())
break;
}
#endif
}
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
/* Remember the redisplay method used to display the matrix. */
strcpy (w->current_matrix->method, w->desired_matrix->method);
#endif
else
paused_p = 1;
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
/* check_current_matrix_flags (w); */
add_window_display_history (w, w->current_matrix->method, paused_p);
#endif
struct glyph *glyph = ¤t_row->glyphs[TEXT_AREA][i - 1];
int left, right;
- rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
+ rif->get_glyph_overhangs (glyph, XFRAME (WVAR (w, frame)),
&left, &right);
can_skip_p = (right == 0 && !abort_skipping);
}
{
int left, right;
- rif->get_glyph_overhangs (current_glyph, XFRAME (w->frame),
+ rif->get_glyph_overhangs (current_glyph,
+ XFRAME (WVAR (w, frame)),
&left, &right);
while (left > 0 && i > 0)
{
has to be cleared, if and only if we did a write_glyphs
above. This is made sure by setting desired_stop_pos
appropriately above. */
- xassert (i < desired_row->used[TEXT_AREA]
+ eassert (i < desired_row->used[TEXT_AREA]
|| ((desired_row->used[TEXT_AREA]
== current_row->used[TEXT_AREA])
&& MATRIX_ROW_EXTENDS_FACE_P (current_row)));
if (desired_row->mode_line_p
|| desired_row->visible_height > 0)
{
- xassert (desired_row->enabled_p);
+ 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))
+ && !NILP (WVAR (w, left_margin_cols)))
{
changed_p = 1;
update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
/* Update display of the right margin area, if there is one. */
if (!desired_row->full_width_p
- && !NILP (w->right_margin_cols))
+ && !NILP (WVAR (w, right_margin_cols)))
{
changed_p = 1;
update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
static void
set_window_cursor_after_update (struct window *w)
{
- struct frame *f = XFRAME (w->frame);
+ struct frame *f = XFRAME (WVAR (w, frame));
struct redisplay_interface *rif = FRAME_RIF (f);
int cx, cy, vpos, hpos;
/* Not intended for frame matrix updates. */
- xassert (FRAME_WINDOW_P (f));
+ eassert (FRAME_WINDOW_P (f));
if (cursor_in_echo_area
&& !NILP (echo_area_buffer[0])
{
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 (!NILP (WVAR (w, hchild)))
+ set_window_update_flags (XWINDOW (WVAR (w, hchild)), on_p);
+ else if (!NILP (WVAR (w, vchild)))
+ set_window_update_flags (XWINDOW (WVAR (w, vchild)), on_p);
else
w->must_be_updated_p = on_p;
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ w = NILP (WVAR (w, next)) ? 0 : XWINDOW (WVAR (w, next));
}
}
ptrdiff_t i = row->hash % row_table_size;
entry = row_table[i];
+ eassert (entry || verify_row_hash (row));
while (entry && !row_equal_p (entry->row, row, 1))
entry = entry->next;
j = last_old;
while (i - 1 > first_new
&& j - 1 > first_old
- && MATRIX_ROW (current_matrix, i - 1)->enabled_p
- && (MATRIX_ROW (current_matrix, i - 1)->y
- == MATRIX_ROW (desired_matrix, j - 1)->y)
- && !MATRIX_ROW (desired_matrix, j - 1)->redraw_fringe_bitmaps_p
+ && MATRIX_ROW (current_matrix, j - 1)->enabled_p
+ && (MATRIX_ROW (current_matrix, j - 1)->y
+ == MATRIX_ROW (desired_matrix, i - 1)->y)
+ && !MATRIX_ROW (desired_matrix, i - 1)->redraw_fringe_bitmaps_p
&& row_equal_p (MATRIX_ROW (desired_matrix, i - 1),
MATRIX_ROW (current_matrix, j - 1), 1))
--i, --j;
for (i = first_new; i < last_new; ++i)
{
- xassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
+ eassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
entry = add_row_entry (MATRIX_ROW (desired_matrix, i));
++entry->new_uses;
entry->new_line_number = i;
{
rif->clear_window_mouse_face (w);
rif->scroll_run_hook (w, r);
+ }
+
+ /* Truncate runs that copy to where we copied to, and
+ invalidate runs that copy from where we copied to. */
+ for (j = nruns - 1; j > i; --j)
+ {
+ struct run *p = runs[j];
+ int truncated_p = 0;
- /* Invalidate runs that copy from where we copied to. */
- for (j = i + 1; j < nruns; ++j)
+ if (p->nrows > 0
+ && p->desired_y < r->desired_y + r->height
+ && p->desired_y + p->height > r->desired_y)
{
- struct run *p = runs[j];
+ if (p->desired_y < r->desired_y)
+ {
+ p->nrows = r->desired_vpos - p->desired_vpos;
+ p->height = r->desired_y - p->desired_y;
+ truncated_p = 1;
+ }
+ else
+ {
+ int nrows_copied = (r->desired_vpos + r->nrows
+ - p->desired_vpos);
+
+ if (p->nrows <= nrows_copied)
+ p->nrows = 0;
+ else
+ {
+ int height_copied = (r->desired_y + r->height
+ - p->desired_y);
+
+ p->current_vpos += nrows_copied;
+ p->desired_vpos += nrows_copied;
+ p->nrows -= nrows_copied;
+ p->current_y += height_copied;
+ p->desired_y += height_copied;
+ p->height -= height_copied;
+ truncated_p = 1;
+ }
+ }
+ }
- if ((p->current_y >= r->desired_y
+ if (r->current_y != r->desired_y
+ /* The condition below is equivalent to
+ ((p->current_y >= r->desired_y
&& p->current_y < r->desired_y + r->height)
- || (p->current_y + p->height >= r->desired_y
+ || (p->current_y + p->height > r->desired_y
&& (p->current_y + p->height
- < r->desired_y + r->height)))
- p->nrows = 0;
+ <= r->desired_y + r->height)))
+ because we have 0 < p->height <= r->height. */
+ && p->current_y < r->desired_y + r->height
+ && p->current_y + p->height > r->desired_y)
+ p->nrows = 0;
+
+ /* Reorder runs by copied pixel lines if truncated. */
+ if (truncated_p && p->nrows > 0)
+ {
+ int k = nruns - 1;
+
+ while (runs[k]->nrows == 0 || runs[k]->height < p->height)
+ k--;
+ memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
+ runs[k] = p;
}
}
to_overlapped_p = to->overlapped_p;
from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
assign_row (to, from);
- to->enabled_p = 1, from->enabled_p = 0;
+ /* The above `assign_row' actually does swap, so if we had
+ an overlap in the copy destination of two runs, then
+ the second run would assign a previously disabled bogus
+ row. But thanks to the truncation code in the
+ preceding for-loop, we no longer have such an overlap,
+ and thus the assigned row should always be enabled. */
+ eassert (to->enabled_p);
+ from->enabled_p = 0;
to->overlapped_p = to_overlapped_p;
}
}
int pause_p;
int preempt_count = baud_rate / 2400 + 1;
- xassert (current_matrix && desired_matrix);
+ eassert (current_matrix && desired_matrix);
if (baud_rate != FRAME_COST_BAUD_RATE (f))
calculate_costs (f);
#if PERIODIC_PREEMPTION_CHECKING
if (!force_p)
{
- EMACS_TIME tm, dif;
- EMACS_GET_TIME (tm);
- EMACS_SUB_TIME (dif, preemption_next_check, tm);
- if (EMACS_TIME_NEG_P (dif))
+ EMACS_TIME tm = current_emacs_time ();
+ if (EMACS_TIME_LT (preemption_next_check, tm))
{
- EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
+ preemption_next_check = add_emacs_time (tm, preemption_period);
if (detect_input_pending_ignore_squeezables ())
break;
}
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);
+ if (INTEGERP (WVAR (w, left_margin_cols)))
+ x += XFASTINT (WVAR (w, left_margin_cols));
/* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
cursor_to (f, y, x);
int unchanged_at_top, unchanged_at_bottom;
int window_size;
int changed_lines;
- int *old_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
- int *new_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
- int *draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
- int *old_draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
+ int *old_hash = alloca (FRAME_LINES (frame) * sizeof (int));
+ int *new_hash = alloca (FRAME_LINES (frame) * sizeof (int));
+ int *draw_cost = alloca (FRAME_LINES (frame) * sizeof (int));
+ int *old_draw_cost = alloca (FRAME_LINES (frame) * sizeof (int));
register int i;
int free_at_end_vpos = FRAME_LINES (frame);
struct glyph_matrix *current_matrix = frame->current_matrix;
/* 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 (WVAR (w, buffer));
itdata = bidi_shelve_cache ();
- SET_TEXT_POS_FROM_MARKER (startp, w->start);
+ SET_TEXT_POS_FROM_MARKER (startp, WVAR (w, start));
CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
start_display (&it, w, startp);
*dx = x0 + it.first_visible_x - it.current_x;
*dy = *y - it.current_y;
- string = w->buffer;
+ string = WVAR (w, buffer);
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 (WVAR (w, buffer)),
CHARPOS (pos->pos));
}
if (newwidth == 0)
newwidth = FRAME_COLS (f);
- /* Compute width of windows in F.
- This is the width of the frame without vertical scroll bars. */
- new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
-
+ /* Compute width of windows in F. */
/* Round up to the smallest acceptable size. */
check_frame_size (f, &newheight, &newwidth);
+ /* This is the width of the frame with vertical scroll bars and fringe
+ columns. Do this after rounding - see discussion of bug#9723. */
+ new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
+
/* If we're not changing the frame size, quit now. */
- /* Frame width may be unchanged but the text portion may change, for example,
- fullscreen and remove/add scroll bar. */
+ /* Frame width may be unchanged but the text portion may change, for
+ example, fullscreen and remove/add scroll bar. */
if (newheight == FRAME_LINES (f)
- && newwidth == FRAME_COLS (f) // text portion unchanged
- && new_frame_total_cols == FRAME_TOTAL_COLS (f)) // frame width unchanged
+ /* Text portion unchanged? */
+ && newwidth == FRAME_COLS (f)
+ /* Frame width unchanged? */
+ && new_frame_total_cols == FRAME_TOTAL_COLS (f))
return;
BLOCK_INPUT;
if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
FrameCols (FRAME_TTY (f)) = newwidth;
- if (WINDOWP (f->tool_bar_window))
- XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth);
+ if (WINDOWP (FVAR (f, tool_bar_window)))
+ XSETFASTINT (WVAR (XWINDOW (FVAR (f, tool_bar_window)), total_cols), newwidth);
}
FRAME_LINES (f) = newheight;
Sleeping, Waiting
***********************************************************************/
-/* Convert a positive value DURATION to a seconds count *PSEC plus a
- microseconds count *PUSEC, rounding up. On overflow return the
- maximal value. */
-void
-duration_to_sec_usec (double duration, int *psec, int *pusec)
-{
- int MILLION = 1000000;
- int sec = INT_MAX, usec = MILLION - 1;
-
- if (duration < INT_MAX + 1.0)
- {
- int s = duration;
- double usdouble = (duration - s) * MILLION;
- int usfloor = usdouble;
- int usceil = usfloor + (usfloor < usdouble);
-
- if (usceil < MILLION)
- {
- sec = s;
- usec = usceil;
- }
- else if (sec < INT_MAX)
- {
- sec = s + 1;
- usec = 0;
- }
- }
-
- *psec = sec;
- *pusec = usec;
-}
-
DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
doc: /* Pause, without updating display, for SECONDS seconds.
SECONDS may be a floating-point value, meaning that you can wait for a
fraction of a second. Optional second arg MILLISECONDS specifies an
-additional wait period, in milliseconds; this may be useful if your
-Emacs was built without floating point support.
+additional wait period, in milliseconds; this is for backwards compatibility.
\(Not all operating systems support waiting for a fraction of a second.) */)
(Lisp_Object seconds, Lisp_Object milliseconds)
{
- int sec, usec;
double duration = extract_float (seconds);
if (!NILP (milliseconds))
duration += XINT (milliseconds) / 1000.0;
}
- if (! (0 < duration))
- return Qnil;
-
- duration_to_sec_usec (duration, &sec, &usec);
-
-#ifndef EMACS_HAS_USECS
- if (sec == 0 && usec != 0)
- error ("Millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
-#endif
-
- wait_reading_process_output (sec, usec, 0, 0, Qnil, NULL, 0);
+ if (0 < duration)
+ {
+ 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);
+ }
return Qnil;
}
Lisp_Object
sit_for (Lisp_Object timeout, int reading, int do_display)
{
- int sec, usec;
+ intmax_t sec;
+ int nsec;
swallow_events (do_display);
if (do_display >= 2)
redisplay_preserve_echo_area (2);
- if (EQ (timeout, Qt))
+ if (INTEGERP (timeout))
{
- sec = 0;
- usec = 0;
+ sec = XINT (timeout);
+ if (! (0 < sec))
+ return Qt;
+ nsec = 0;
}
- else
+ else if (FLOATP (timeout))
{
- double duration = extract_float (timeout);
-
- if (! (0 < duration))
+ double seconds = XFLOAT_DATA (timeout);
+ if (! (0 < seconds))
return Qt;
-
- duration_to_sec_usec (duration, &sec, &usec);
+ else
+ {
+ EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
+ sec = min (EMACS_SECS (t), WAIT_READING_MAX);
+ nsec = EMACS_NSECS (t);
+ }
}
+ else if (EQ (timeout, Qt))
+ {
+ sec = 0;
+ nsec = 0;
+ }
+ else
+ wrong_type_argument (Qnumberp, timeout);
+
#ifdef SIGIO
gobble_input (0);
#endif
- wait_reading_process_output (sec, usec, reading ? -1 : 1, do_display,
+ wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
Qnil, NULL, 0);
return detect_input_pending () ? Qnil : Qt;
DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
- doc: /* Perform redisplay if no input is available.
-If optional arg FORCE is non-nil or `redisplay-dont-pause' is non-nil,
-perform a full redisplay even if input is available.
-Return t if redisplay was performed, nil otherwise. */)
+ doc: /* Perform redisplay.
+Optional arg FORCE, if non-nil, prevents redisplay from being
+preempted by arriving input, even if `redisplay-dont-pause' is nil.
+If `redisplay-dont-pause' is non-nil (the default), redisplay is never
+preempted by arriving input, so FORCE does nothing.
+
+Return t if redisplay was performed, nil if redisplay was preempted
+immediately by pending input. */)
(Lisp_Object force)
{
ptrdiff_t count;
goto changed;
if (vecp == end)
goto changed;
- if (!EQ (*vecp++, XFRAME (frame)->name))
+ if (!EQ (*vecp++, FVAR (XFRAME (frame), name)))
goto changed;
}
/* Check that the buffer info matches. */
FOR_EACH_FRAME (tail, frame)
{
*vecp++ = frame;
- *vecp++ = XFRAME (frame)->name;
+ *vecp++ = FVAR (XFRAME (frame), name);
}
for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
{
#ifdef HAVE_X11
Vwindow_system_version = make_number (11);
#endif
-#if defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
+#ifdef GNU_LINUX
/* In some versions of ncurses,
tputs crashes if we have not called tgetent.
So call tgetent. */
defsubr (&Sinternal_show_cursor_p);
defsubr (&Slast_nonminibuf_frame);
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
defsubr (&Sdump_redisplay_history);
#endif
DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
DEFVAR_INT ("baud-rate", baud_rate,
- doc: /* *The output baud rate of the terminal.
+ doc: /* The output baud rate of the terminal.
On most systems, changing this value will affect the amount of padding
and the other strategic decisions made during redisplay. */);
DEFVAR_BOOL ("inverse-video", inverse_video,
- doc: /* *Non-nil means invert the entire frame display.
+ doc: /* Non-nil means invert the entire frame display.
This means everything is in inverse video which otherwise would not be. */);
DEFVAR_BOOL ("visible-bell", visible_bell,
- doc: /* *Non-nil means try to flash the frame to represent a bell.
+ doc: /* Non-nil means try to flash the frame to represent a bell.
See also `ring-bell-function'. */);
DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter,
- doc: /* *Non-nil means no need to redraw entire frame after suspending.
+ doc: /* Non-nil means no need to redraw entire frame after suspending.
A non-nil value is useful if the terminal can automatically preserve
Emacs's frame display when you reenter Emacs.
It is up to you to set this variable if your terminal can do that. */);
Vstandard_display_table = Qnil;
DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
- doc: /* *Non-nil means display update isn't paused when input is detected. */);
+ 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: /* *The period in seconds between checking for input during redisplay.
-If input is detected, redisplay is pre-empted, and the input is processed.
-If nil, never pre-empt redisplay. */);
+ 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