/* Updating of data structures for redisplay.
-Copyright (C) 1985-1988, 1993-1995, 1997-2014 Free Software Foundation,
+Copyright (C) 1985-1988, 1993-1995, 1997-2015 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 "character.h"
#include "buffer.h"
#include "keyboard.h"
#include "frame.h"
#include "window.h"
#include "commands.h"
#include "disptab.h"
-#include "indent.h"
-#include "intervals.h"
#include "blockinput.h"
-#include "process.h"
-
#include "syssignal.h"
+#include "systime.h"
#include "tparam.h"
#ifdef HAVE_WINDOW_SYSTEM
#include <errno.h>
#include <fpending.h>
-#include <timespec.h>
#ifdef WINDOWSNT
#include "w32.h"
bool display_completed;
-Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
-
/* True means SIGWINCH happened when not safe. */
static bool delayed_size_change;
++history_idx;
snprintf (buf, sizeof redisplay_history[0].trace,
- "%"pMu": window %p (`%s')%s\n%s",
+ "%"pMu": window %p (%s)%s\n%s",
history_tick++,
ptr,
((BUFFERP (w->contents)
for (i = 0; i < matrix->nrows; ++i)
matrix->rows[i].enabled_p = false;
}
+ /* We've disabled the mode-line row, so force redrawing of
+ the mode line, if any, since otherwise it will remain
+ disabled in the current matrix, and expose events won't
+ redraw it. */
+ if (WINDOW_WANTS_MODELINE_P (w))
+ w->update_mode_line = 1;
}
else if (matrix == w->desired_matrix)
{
|| matrix_dim.width != pool->ncolumns);
/* Enlarge the glyph pool. */
- needed = matrix_dim.width;
- if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
+ if (INT_MULTIPLY_WRAPV (matrix_dim.height, matrix_dim.width, &needed))
memory_full (SIZE_MAX);
- needed *= matrix_dim.height;
if (needed > pool->nglyphs)
{
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);
+ memclear (pool->glyphs + old_nglyphs,
+ (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
}
/* Remember the number of rows and columns because (a) we use them
if (FRAME_WINDOW_P (f))
{
- int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
+ /* http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg00194.html */
+ int ch_height = max (FRAME_SMALLEST_FONT_HEIGHT (f), 1);
int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
return (((window_pixel_height + ch_height - 1)
struct frame *f = XFRAME (w->frame);
if (FRAME_WINDOW_P (f))
{
- int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
+ /* http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg00194.html */
+ int ch_width = max (FRAME_SMALLEST_CHAR_WIDTH (f), 1);
/* Compute number of glyphs needed in a glyph row. */
return (((WINDOW_PIXEL_WIDTH (w) + ch_width - 1)
clear_frame (f);
clear_current_matrices (f);
update_end (f);
- windows_or_buffers_changed = 13;
+ fset_redisplay (f);
/* Mark all windows as inaccurate, so that every window will have
its redisplay done. */
mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
{
cx = cy = vpos = hpos = 0;
- if (cursor_in_echo_area >= 0)
- {
- /* If the mini-buffer is several lines high, find the last
- line that has any text on it. Note: either all lines
- are enabled or none. Otherwise we wouldn't be able to
- determine Y. */
- struct glyph_row *row, *last_row;
- struct glyph *glyph;
- int yb = window_text_bottom_y (w);
-
- last_row = NULL;
- row = w->current_matrix->rows;
- while (row->enabled_p
- && (last_row == NULL
- || MATRIX_ROW_BOTTOM_Y (row) <= yb))
- {
- if (row->used[TEXT_AREA]
- && row->glyphs[TEXT_AREA][0].charpos >= 0)
- last_row = row;
- ++row;
- }
+ /* If the mini-buffer is several lines high, find the last
+ line that has any text on it. Note: either all lines
+ are enabled or none. Otherwise we wouldn't be able to
+ determine Y. */
+ struct glyph_row *last_row = NULL;
+ int yb = window_text_bottom_y (w);
- if (last_row)
- {
- struct glyph *start = last_row->glyphs[TEXT_AREA];
- struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
+ for (struct glyph_row *row = w->current_matrix->rows;
+ row->enabled_p && (!last_row || MATRIX_ROW_BOTTOM_Y (row) <= yb);
+ row++)
+ if (row->used[TEXT_AREA] && row->glyphs[TEXT_AREA][0].charpos >= 0)
+ last_row = row;
- while (last > start && last->charpos < 0)
- --last;
+ if (last_row)
+ {
+ struct glyph *start = last_row->glyphs[TEXT_AREA];
+ struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
- for (glyph = start; glyph < last; ++glyph)
- {
- cx += glyph->pixel_width;
- ++hpos;
- }
+ while (last > start && last->charpos < 0)
+ --last;
- cy = last_row->y;
- vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
+ for (struct glyph *glyph = start; glyph < last; glyph++)
+ {
+ cx += glyph->pixel_width;
+ hpos++;
}
+
+ cy = last_row->y;
+ vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
}
}
else
&& EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
{
int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
- int row, col;
+ int col;
- if (cursor_in_echo_area < 0)
+ /* Put cursor at the end of the prompt. If the mini-buffer
+ is several lines high, find the last line that has
+ any text on it. */
+ int row = FRAME_TOTAL_LINES (f);
+ do
{
- /* Negative value of cursor_in_echo_area means put
- cursor at beginning of line. */
- row = top;
+ row--;
col = 0;
- }
- else
- {
- /* Positive value of cursor_in_echo_area means put
- cursor at the end of the prompt. If the mini-buffer
- is several lines high, find the last line that has
- any text on it. */
- row = FRAME_TOTAL_LINES (f);
- do
- {
- --row;
- col = 0;
- if (MATRIX_ROW_ENABLED_P (current_matrix, row))
- {
- /* Frame rows are filled up with spaces that
- must be ignored here. */
- struct glyph_row *r = MATRIX_ROW (current_matrix,
- row);
- struct glyph *start = r->glyphs[TEXT_AREA];
- struct glyph *last = start + r->used[TEXT_AREA];
-
- while (last > start
- && (last - 1)->charpos < 0)
- --last;
-
- col = last - start;
- }
+ if (MATRIX_ROW_ENABLED_P (current_matrix, row))
+ {
+ /* Frame rows are filled up with spaces that
+ must be ignored here. */
+ struct glyph_row *r = MATRIX_ROW (current_matrix, row);
+ struct glyph *start = r->glyphs[TEXT_AREA];
+
+ col = r->used[TEXT_AREA];
+ while (0 < col && start[col - 1].charpos < 0)
+ col--;
}
- while (row > top && col == 0);
+ }
+ while (row > top && col == 0);
- /* Make sure COL is not out of range. */
- if (col >= FRAME_CURSOR_X_LIMIT (f))
+ /* Make sure COL is not out of range. */
+ if (col >= FRAME_CURSOR_X_LIMIT (f))
+ {
+ /* If we have another row, advance cursor into it. */
+ if (row < FRAME_TOTAL_LINES (f) - 1)
{
- /* If we have another row, advance cursor into it. */
- if (row < FRAME_TOTAL_LINES (f) - 1)
- {
- col = FRAME_LEFT_SCROLL_BAR_COLS (f);
- row++;
- }
- /* Otherwise move it back in range. */
- else
- col = FRAME_CURSOR_X_LIMIT (f) - 1;
+ col = FRAME_LEFT_SCROLL_BAR_COLS (f);
+ row++;
}
+ /* Otherwise move it back in range. */
+ else
+ col = FRAME_CURSOR_X_LIMIT (f) - 1;
}
cursor_to (f, row, col);
Fset_buffer (old_current_buffer);
- *dx = x0 + it.first_visible_x - it.current_x;
+ *dx = to_x - it.current_x;
*dy = *y - it.current_y;
string = w->contents;
}
/* Add extra (default width) columns if clicked after EOL. */
- 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);
+ x1 = max (0, it.current_x + it.pixel_width);
+ if (to_x > x1)
+ it.hpos += (to_x - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
*x = it.hpos;
*y = it.vpos;
/* Adjust frame size but make sure x_set_window_size does not
get called. */
- adjust_frame_size (f, new_width, new_height, 5, pretend, Qnil);
+ adjust_frame_size (f, new_width, new_height, 5, pretend,
+ Qchange_frame_size);
}
}
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 is for backwards compatibility.
-\(Not all operating systems support waiting for a fraction of a second.) */)
+(Not all operating systems support waiting for a fraction of a second.) */)
(Lisp_Object seconds, Lisp_Object milliseconds)
{
double duration = extract_float (seconds);
if (duration > 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);
+ struct timespec tend = timespec_add (current_timespec (), t);
+
+ /* wait_reading_process_output returns as soon as it detects
+ output from any subprocess, so we wait in a loop until the
+ time expires. */
+ do {
+ wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX),
+ t.tv_nsec, 0, 0, Qnil, NULL, 0);
+ t = timespec_sub (tend, current_timespec ());
+ } while (timespec_sign (t) > 0);
}
return Qnil;
space_glyph.charpos = -1;
inverse_video = 0;
- cursor_in_echo_area = 0;
+ cursor_in_echo_area = false;
/* Now is the time to initialize this; it's used by init_sys_modes
during startup. */
}
#endif /* SIGWINCH */
- /* If running as a daemon, no need to initialize any frames/terminal. */
+ /* If running as a daemon, no need to initialize any frames/terminal,
+ except on Windows, where we at least want to initialize it. */
+#ifndef WINDOWSNT
if (IS_DAEMON)
return;
+#endif
/* If the user wants to use a window system, we shouldn't bother
initializing the terminal. This is especially important when the
{
#ifdef HAVE_WINDOW_SYSTEM
if (! inhibit_window_system)
- fprintf (stderr, "Please set the environment variable DISPLAY or TERM (see `tset').\n");
+ fprintf (stderr, "Please set the environment variable DISPLAY or TERM (see 'tset').\n");
else
#endif /* HAVE_WINDOW_SYSTEM */
- fprintf (stderr, "Please set the environment variable TERM; see `tset'.\n");
+ fprintf (stderr, "Please set the environment variable TERM; see 'tset'.\n");
exit (1);
}
struct frame *sf = SELECTED_FRAME ();
int width = FRAME_TOTAL_COLS (sf);
int height = FRAME_TOTAL_LINES (sf);
+ int area;
/* If these sizes are so big they cause overflow, just ignore the
change. It's not clear what better we could do. The rest of
the code assumes that (width + 2) * height * sizeof (struct glyph)
does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */
- if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX)
- || INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX)
- || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
- < (width + 2) * height))
+ if (INT_ADD_WRAPV (width, 2, &area)
+ || INT_MULTIPLY_WRAPV (height, area, &area)
+ || min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < area)
fatal ("screen size %dx%d too big", width, height);
}
frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
staticpro (&frame_and_buffer_state);
+ /* This is the "purpose" slot of a display table. */
DEFSYM (Qdisplay_table, "display-table");
+
DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
DEFVAR_INT ("baud-rate", baud_rate,
doc: /* Name of the window system that Emacs uses for the first frame.
The value is a symbol:
nil for a termcap frame (a character-only terminal),
- 'x' for an Emacs frame that is really an X window,
- 'w32' for an Emacs frame that is a window on MS-Windows display,
- 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
- 'pc' for a direct-write MS-DOS frame.
+ `x' for an Emacs frame that is really an X window,
+ `w32' for an Emacs frame that is a window on MS-Windows display,
+ `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
+ `pc' for a direct-write MS-DOS frame.
Use of this variable as a boolean is deprecated. Instead,
use `display-graphic-p' or any of the other `display-*-p'
doc: /* Name of window system through which the selected frame is displayed.
The value is a symbol:
nil for a termcap frame (a character-only terminal),
- 'x' for an Emacs frame that is really an X window,
- 'w32' for an Emacs frame that is a window on MS-Windows display,
- 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
- 'pc' for a direct-write MS-DOS frame.
+ `x' for an Emacs frame that is really an X window,
+ `w32' for an Emacs frame that is a window on MS-Windows display,
+ `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
+ `pc' for a direct-write MS-DOS frame.
Use of this variable as a boolean is deprecated. Instead,
use `display-graphic-p' or any of the other `display-*-p'
DEFVAR_LISP ("standard-display-table", Vstandard_display_table,
doc: /* Display table to use for buffers that specify none.
+It is also used for standard output and error streams.
See `buffer-display-table' for more information. */);
Vstandard_display_table = Qnil;