#endif
#endif /* not __GNU_LIBRARY__ */
-#if defined(HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
+#if defined (HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES)
#include <term.h> /* for tgetent */
#endif
\f
static int required_matrix_width (struct window *);
static void adjust_frame_glyphs (struct frame *);
static void change_frame_size_1 (struct frame *, int, int, int, int, int);
-static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT);
+static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
struct window *);
buf = redisplay_history[history_idx].trace;
++history_idx;
- sprintf (buf, "%"pMu": window %p (`%s')%s\n",
- history_tick++,
- w,
- ((BUFFERP (w->buffer)
- && STRINGP (BVAR (XBUFFER (w->buffer), name)))
- ? SSDATA (BVAR (XBUFFER (w->buffer), name))
- : "???"),
- paused_p ? " ***paused***" : "");
- strcat (buf, msg);
+ 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))
+ : "???"),
+ paused_p ? " ***paused***" : "",
+ msg);
}
/* Enlarge MATRIX->rows if necessary. New rows are cleared. */
if (matrix->rows_allocated < dim.height)
{
- ptrdiff_t size = dim.height * sizeof (struct glyph_row);
+ int old_alloc = matrix->rows_allocated;
new_rows = dim.height - matrix->rows_allocated;
- matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
- memset (matrix->rows + matrix->rows_allocated, 0,
- new_rows * sizeof *matrix->rows);
- matrix->rows_allocated = dim.height;
+ matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
+ new_rows, INT_MAX, sizeof *matrix->rows);
+ memset (matrix->rows + old_alloc, 0,
+ (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
}
else
new_rows = 0;
while (row < end)
{
row->glyphs[LEFT_MARGIN_AREA]
- = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
- (dim.width
- * sizeof (struct glyph)));
+ = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
+ dim.width, sizeof (struct glyph));
/* The mode line never has marginal areas. */
if (row == matrix->rows + dim.height - 1
void
increment_matrix_positions (struct glyph_matrix *matrix, int start, int end,
- EMACS_INT delta, EMACS_INT delta_bytes)
+ ptrdiff_t delta, ptrdiff_t delta_bytes)
{
/* Check that START and END are reasonable values. */
xassert (start >= 0 && start <= matrix->nrows);
static void
increment_row_positions (struct glyph_row *row,
- EMACS_INT delta, EMACS_INT delta_bytes)
+ ptrdiff_t delta, ptrdiff_t delta_bytes)
{
int area, i;
struct glyph *end = beg + row->used[TEXT_AREA];
int len;
Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
- int glyph_table_len = GLYPH_TABLE_LENGTH;
+ ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
/* Ignore trailing and leading spaces if we can. */
if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
static int
realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
{
- int needed;
+ ptrdiff_t needed;
int changed_p;
changed_p = (pool->glyphs == 0
|| matrix_dim.width != pool->ncolumns);
/* Enlarge the glyph pool. */
- needed = matrix_dim.width * matrix_dim.height;
+ needed = matrix_dim.width;
+ if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
+ memory_full (SIZE_MAX);
+ needed *= matrix_dim.height;
if (needed > pool->nglyphs)
{
- ptrdiff_t size = needed * sizeof (struct glyph);
-
- if (pool->glyphs)
- {
- pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
- memset (pool->glyphs + pool->nglyphs, 0,
- size - pool->nglyphs * sizeof (struct glyph));
- }
- else
- {
- pool->glyphs = (struct glyph *) xmalloc (size);
- memset (pool->glyphs, 0, size);
- }
-
- pool->nglyphs = needed;
+ ptrdiff_t old_nglyphs = pool->nglyphs;
+ pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
+ needed - old_nglyphs, -1, sizeof *pool->glyphs);
+ memset (pool->glyphs + old_nglyphs, 0,
+ (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
}
/* Remember the number of rows and columns because (a) we use them
SET_GLYPH_FROM_CHAR (right_border_glyph, '|');
if (dp
- && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc))
- && GLYPH_CODE_CHAR_VALID_P (gc))
+ && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc)))
{
SET_GLYPH_FROM_GLYPH_CODE (right_border_glyph, gc);
spec_glyph_lookup_face (w, &right_border_glyph);
int new_line_number;
/* Bucket index of this row_entry in the hash table row_table. */
- int bucket;
+ ptrdiff_t bucket;
/* The row described by this entry. */
struct glyph_row *row;
that we need a larger one. */
static struct row_entry *row_entry_pool;
-static int row_entry_pool_size;
+static ptrdiff_t row_entry_pool_size;
/* Index of next free entry in row_entry_pool. */
-static int row_entry_idx;
+static ptrdiff_t row_entry_idx;
/* The hash table used during scrolling, and the table's size. This
table is used to quickly identify equal rows in the desired and
current matrix. */
static struct row_entry **row_table;
-static int row_table_size;
+static ptrdiff_t row_table_size;
/* Vectors of pointers to row_entry structures belonging to the
current and desired matrix, and the size of the vectors. */
static struct row_entry **old_lines, **new_lines;
-static int old_lines_size, new_lines_size;
+static ptrdiff_t old_lines_size, new_lines_size;
/* A pool to allocate run structures from, and its size. */
static struct run *run_pool;
-static int runs_size;
+static ptrdiff_t runs_size;
/* A vector of runs of lines found during scrolling. */
add_row_entry (struct glyph_row *row)
{
struct row_entry *entry;
- int i = row->hash % row_table_size;
+ ptrdiff_t i = row->hash % row_table_size;
entry = row_table[i];
while (entry && !row_equal_p (entry->row, row, 1))
struct glyph_matrix *desired_matrix = w->desired_matrix;
struct glyph_matrix *current_matrix = w->current_matrix;
int yb = window_text_bottom_y (w);
- int i, j, first_old, first_new, last_old, last_new;
- int nruns, n, run_idx;
- ptrdiff_t nbytes;
+ ptrdiff_t i;
+ int j, first_old, first_new, last_old, last_new;
+ int nruns, run_idx;
+ ptrdiff_t n;
struct row_entry *entry;
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
if (last_new == first_new)
return 0;
+ /* Check for integer overflow in size calculation.
+
+ If next_almost_prime checks (N) for divisibility by 2..10, then
+ it can return at most N + 10, e.g., next_almost_prime (1) == 11.
+ So, set next_almost_prime_increment_max to 10.
+
+ It's just a coincidence that next_almost_prime_increment_max ==
+ NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were
+ 13, then next_almost_prime_increment_max would be 14, e.g.,
+ because next_almost_prime (113) would be 127. */
+ {
+ verify (NEXT_ALMOST_PRIME_LIMIT == 11);
+ enum { next_almost_prime_increment_max = 10 };
+ ptrdiff_t row_table_max =
+ (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
+ - next_almost_prime_increment_max);
+ ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
+ if (current_nrows_max < current_matrix->nrows)
+ memory_full (SIZE_MAX);
+ }
+
/* Reallocate vectors, tables etc. if necessary. */
if (current_matrix->nrows > old_lines_size)
- {
- old_lines_size = current_matrix->nrows;
- nbytes = old_lines_size * sizeof *old_lines;
- old_lines = (struct row_entry **) xrealloc (old_lines, nbytes);
- }
+ old_lines = xpalloc (old_lines, &old_lines_size,
+ current_matrix->nrows - old_lines_size,
+ INT_MAX, sizeof *old_lines);
if (desired_matrix->nrows > new_lines_size)
- {
- new_lines_size = desired_matrix->nrows;
- nbytes = new_lines_size * sizeof *new_lines;
- new_lines = (struct row_entry **) xrealloc (new_lines, nbytes);
- }
+ new_lines = xpalloc (new_lines, &new_lines_size,
+ desired_matrix->nrows - new_lines_size,
+ INT_MAX, sizeof *new_lines);
- n = desired_matrix->nrows + current_matrix->nrows;
- if (3 * n > row_table_size)
+ n = desired_matrix->nrows;
+ n += current_matrix->nrows;
+ if (row_table_size < 3 * n)
{
- row_table_size = next_almost_prime (3 * n);
- nbytes = row_table_size * sizeof *row_table;
- row_table = (struct row_entry **) xrealloc (row_table, nbytes);
- memset (row_table, 0, nbytes);
+ ptrdiff_t size = next_almost_prime (3 * n);
+ row_table = xnrealloc (row_table, size, sizeof *row_table);
+ row_table_size = size;
+ memset (row_table, 0, size * sizeof *row_table);
}
if (n > row_entry_pool_size)
- {
- row_entry_pool_size = n;
- nbytes = row_entry_pool_size * sizeof *row_entry_pool;
- row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes);
- }
+ row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
+ n - row_entry_pool_size,
+ -1, sizeof *row_entry_pool);
if (desired_matrix->nrows > runs_size)
{
+ runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
+ run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
runs_size = desired_matrix->nrows;
- nbytes = runs_size * sizeof *runs;
- runs = (struct run **) xrealloc (runs, nbytes);
- nbytes = runs_size * sizeof *run_pool;
- run_pool = (struct run *) xrealloc (run_pool, nbytes);
}
nruns = run_idx = 0;
/* Char insertion/deletion cost vector, from term.c */
-#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS((f))])
+#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))])
/* Perform a frame-based update on line VPOS in frame FRAME. */
}
/* Add extra (default width) columns if clicked after EOL. */
- x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
+ x1 = max (0, it.current_x + it.pixel_width - it.first_visible_x);
if (x0 > x1)
it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
Lisp_Object
mode_line_string (struct window *w, enum window_part part,
- int *x, int *y, EMACS_INT *charpos, Lisp_Object *object,
+ int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
int *dx, int *dy, int *width, int *height)
{
struct glyph_row *row;
Lisp_Object
marginal_area_string (struct window *w, enum window_part part,
- int *x, int *y, EMACS_INT *charpos, Lisp_Object *object,
+ int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
int *dx, int *dy, int *width, int *height)
{
struct glyph_row *row = w->current_matrix->rows;
change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int pretend, int delay, int safe)
{
int new_frame_total_cols;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
/* If we can't deal with the change now, queue it for later. */
if (delay || (redisplaying_p && !safe))
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
(Lisp_Object seconds, Lisp_Object milliseconds)
{
int sec, usec;
+ double duration = extract_float (seconds);
- if (NILP (milliseconds))
- XSETINT (milliseconds, 0);
- else
- CHECK_NUMBER (milliseconds);
- usec = XINT (milliseconds) * 1000;
+ if (!NILP (milliseconds))
+ {
+ CHECK_NUMBER (milliseconds);
+ duration += XINT (milliseconds) / 1000.0;
+ }
- {
- double duration = extract_float (seconds);
- sec = (int) duration;
- usec += (duration - sec) * 1000000;
- }
+ 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
- /* Assure that 0 <= usec < 1000000. */
- if (usec < 0)
- {
- /* We can't rely on the rounding being correct if usec is negative. */
- if (-1000000 < usec)
- sec--, usec += 1000000;
- else
- sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
- }
- else
- sec += usec / 1000000, usec %= 1000000;
-
- if (sec < 0 || (sec == 0 && usec == 0))
- return Qnil;
-
wait_reading_process_output (sec, usec, 0, 0, Qnil, NULL, 0);
return Qnil;
if (do_display >= 2)
redisplay_preserve_echo_area (2);
- if (INTEGERP (timeout))
- {
- sec = XINT (timeout);
- usec = 0;
- }
- else if (FLOATP (timeout))
- {
- double seconds = XFLOAT_DATA (timeout);
- sec = (int) seconds;
- usec = (int) ((seconds - sec) * 1000000);
- }
- else if (EQ (timeout, Qt))
+ if (EQ (timeout, Qt))
{
sec = 0;
usec = 0;
}
else
- wrong_type_argument (Qnumberp, timeout);
+ {
+ double duration = extract_float (timeout);
+
+ if (! (0 < duration))
+ return Qt;
- if (sec == 0 && usec == 0 && !EQ (timeout, Qt))
- return Qt;
+ duration_to_sec_usec (duration, &sec, &usec);
+ }
#ifdef SIGIO
gobble_input (0);
Return t if redisplay was performed, nil otherwise. */)
(Lisp_Object force)
{
- int count;
+ ptrdiff_t count;
swallow_events (1);
if ((detect_input_pending_run_timers (1)
)
{
Vinitial_window_system = Qns;
- Vwindow_system_version = make_number(10);
+ Vwindow_system_version = make_number (10);
adjust_frame_glyphs_initially ();
return;
}
{
/* For the initial frame, we don't have any way of knowing what
are the foreground and background colors of the terminal. */
- struct frame *sf = SELECTED_FRAME();
+ struct frame *sf = SELECTED_FRAME ();
FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;