the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#define DOC_STRINGS_IN_COMMENTS
+
#include <config.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#endif
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#define min(a, b) ((a) < (b) ? (a) : (b))
-
/* 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
override this because their stdio internals differ. */
static unsigned line_draw_cost P_ ((struct glyph_matrix *, int));
static void update_frame_line P_ ((struct frame *, int));
static struct dim allocate_matrices_for_frame_redisplay
- P_ ((Lisp_Object, int, int, struct dim, int, int *));
-static void allocate_matrices_for_window_redisplay P_ ((struct window *,
- struct dim));
+ P_ ((Lisp_Object, int, int, int, int *));
+static void allocate_matrices_for_window_redisplay P_ ((struct window *));
static int realloc_glyph_pool P_ ((struct glyph_pool *, struct dim));
static void adjust_frame_glyphs P_ ((struct frame *));
struct glyph_matrix *new_glyph_matrix P_ ((struct glyph_pool *));
DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
Sdump_redisplay_history, 0, 0, "",
- "Dump redisplay history to stderr.")
- ()
+ /* Dump redisplay history to stderr. */
+ ())
{
int i;
upper window). Invalidate all rows that are no longer part
of the window. */
if (!marginal_areas_changed_p
+ && !header_line_changed_p
+ && new_rows == 0
+ && dim.width == matrix->matrix_w
&& matrix->window_left_x == XFASTINT (w->left)
&& matrix->window_top_y == XFASTINT (w->top)
- && matrix->window_width == window_box_width (w, -1))
+ && matrix->window_width == window_width)
{
- i = 0;
- while (matrix->rows[i].enabled_p
- && (MATRIX_ROW_BOTTOM_Y (matrix->rows + i)
- < matrix->window_height))
- ++i;
+ /* Find the last row in the window. */
+ for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
+ if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
+ {
+ ++i;
+ break;
+ }
/* Window end is invalid, if inside of the rows that
- are invalidated. */
+ are invalidated below. */
if (INTEGERP (w->window_end_vpos)
&& XFASTINT (w->window_end_vpos) >= i)
w->window_end_valid = Qnil;
struct glyph_row *row = &matrix->rows[start];
row->y += dy;
+ row->visible_height = row->height;
if (row->y < min_y)
- row->visible_height = row->height - (min_y - row->y);
- else if (row->y + row->height > max_y)
- row->visible_height = row->height - (row->y + row->height - max_y);
- else
- row->visible_height = row->height;
+ row->visible_height -= min_y - row->y;
+ if (row->y + row->height > max_y)
+ row->visible_height -= row->y + row->height - max_y;
}
}
row->y = y;
row->ascent = row->phys_ascent = 0;
row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame));
-
+ row->visible_height = row->height;
+
if (row->y < min_y)
- row->visible_height = row->height - (min_y - row->y);
- else if (row->y + row->height > max_y)
- row->visible_height = row->height - (row->y + row->height - max_y);
- else
- row->visible_height = row->height;
+ row->visible_height -= min_y - row->y;
+ if (row->y + row->height > max_y)
+ row->visible_height -= row->y + row->height - max_y;
row->enabled_p = 1;
}
#define CHANGED_LEAF_MATRIX (1 << 1)
static struct dim
-allocate_matrices_for_frame_redisplay (window, x, y, ch_dim,
- dim_only_p, window_change_flags)
+allocate_matrices_for_frame_redisplay (window, x, y, dim_only_p,
+ window_change_flags)
Lisp_Object window;
int x, y;
- struct dim ch_dim;
int dim_only_p;
int *window_change_flags;
{
/* Get the dimension of the window sub-matrix for W, depending
on whether this a combination or a leaf window. */
if (!NILP (w->hchild))
- dim = allocate_matrices_for_frame_redisplay (w->hchild, x, y, ch_dim,
+ 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, ch_dim,
+ dim = allocate_matrices_for_frame_redisplay (w->vchild, x, y,
dim_only_p,
window_change_flags);
else
/* Width and height MUST be chosen so that there are no
holes in the frame matrix. */
- dim.width = XINT (w->width);
- dim.height = XINT (w->height);
+ dim.width = required_matrix_width (w);
+ dim.height = required_matrix_height (w);
/* Will matrix be re-allocated? */
if (x != w->desired_matrix->matrix_x
}
+/* Return the required height of glyph matrices for window W. */
+
+int
+required_matrix_height (w)
+ struct window *w;
+{
+#ifdef HAVE_WINDOW_SYSTEM
+ struct frame *f = XFRAME (w->frame);
+
+ if (FRAME_WINDOW_P (f))
+ {
+ int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
+ int window_pixel_height = window_box_height (w) + abs (w->vscroll);
+ return (((window_pixel_height + ch_height - 1)
+ / ch_height)
+ /* One partially visible line at the top and
+ bottom of the window. */
+ + 2
+ /* 2 for top and mode line. */
+ + 2);
+ }
+#endif /* HAVE_WINDOW_SYSTEM */
+
+ return XINT (w->height);
+}
+
+
+/* Return the required width of glyph matrices for window W. */
+
+int
+required_matrix_width (w)
+ struct window *w;
+{
+#ifdef HAVE_WINDOW_SYSTEM
+ struct frame *f = XFRAME (w->frame);
+ if (FRAME_WINDOW_P (f))
+ {
+ int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
+ int window_pixel_width = XFLOATINT (w->width) * CANON_X_UNIT (f);
+
+ /* Compute number of glyphs needed in a glyph row. */
+ return (((window_pixel_width + ch_width - 1)
+ / ch_width)
+ /* 2 partially visible columns in the text area. */
+ + 2
+ /* One partially visible column at the right
+ edge of each marginal area. */
+ + 1 + 1);
+ }
+#endif /* HAVE_WINDOW_SYSTEM */
+
+ return XINT (w->width);
+}
+
+
/* Allocate window matrices for window-based redisplay. W is the
window whose matrices must be allocated/reallocated. CH_DIM is the
size of the smallest character that could potentially be used on W. */
static void
-allocate_matrices_for_window_redisplay (w, ch_dim)
+allocate_matrices_for_window_redisplay (w)
struct window *w;
- struct dim ch_dim;
{
- struct frame *f = XFRAME (w->frame);
-
while (w)
{
if (!NILP (w->vchild))
- allocate_matrices_for_window_redisplay (XWINDOW (w->vchild), ch_dim);
+ allocate_matrices_for_window_redisplay (XWINDOW (w->vchild));
else if (!NILP (w->hchild))
- allocate_matrices_for_window_redisplay (XWINDOW (w->hchild), ch_dim);
+ allocate_matrices_for_window_redisplay (XWINDOW (w->hchild));
else
{
/* W is a leaf window. */
- int window_pixel_width = XFLOATINT (w->width) * CANON_X_UNIT (f);
- int window_pixel_height = window_box_height (w) + abs (w->vscroll);
struct dim dim;
/* If matrices are not yet allocated, allocate them now. */
w->current_matrix = new_glyph_matrix (NULL);
}
- /* Compute number of glyphs needed in a glyph row. */
- dim.width = (((window_pixel_width + ch_dim.width - 1)
- / ch_dim.width)
- /* 2 partially visible columns in the text area. */
- + 2
- /* One partially visible column at the right
- edge of each marginal area. */
- + 1 + 1);
-
- /* Compute number of glyph rows needed. */
- dim.height = (((window_pixel_height + ch_dim.height - 1)
- / ch_dim.height)
- /* One partially visible line at the top and
- bottom of the window. */
- + 2
- /* 2 for top and mode line. */
- + 2);
-
- /* Change matrices. */
+ dim.width = required_matrix_width (w);
+ dim.height = required_matrix_height (w);
adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
}
matrix_dim
= allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
0, top_window_y,
- ch_dim, 1,
+ 1,
&window_change_flags);
/* Add in menu bar lines, if any. */
{
/* Do it for window matrices. */
allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
- 0, top_window_y, ch_dim, 0,
+ 0, top_window_y, 0,
&window_change_flags);
/* Size of frame matrices must equal size of frame. Note
#endif
/* Allocate/reallocate window matrices. */
- allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)),
- ch_dim);
+ allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
/* Allocate/ reallocate matrices of the dummy window used to display
the menu bar under X when no X toolkit support is available. */
XSETFASTINT (w->left, 0);
XSETFASTINT (w->height, FRAME_MENU_BAR_LINES (f));
XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
- allocate_matrices_for_window_redisplay (w, ch_dim);
+ allocate_matrices_for_window_redisplay (w);
}
#endif /* not USE_X_TOOLKIT */
XSETFASTINT (w->left, 0);
XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f));
XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f));
- allocate_matrices_for_window_redisplay (w, ch_dim);
+ allocate_matrices_for_window_redisplay (w);
}
**********************************************************************/
DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
- "Clear frame FRAME and output again what is supposed to appear on it.")
- (frame)
+ /* Clear frame FRAME and output again what is supposed to appear on it. */
+ (frame))
Lisp_Object frame;
{
struct frame *f;
DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
- "Clear and redisplay all visible frames.")
- ()
+ /* Clear and redisplay all visible frames. */
+ ())
{
Lisp_Object tail, frame;
it.current_y = w->cursor.y;
it.end_charpos = PT;
it.stop_charpos = min (PT, it.stop_charpos);
+ it.stop_charpos = max (IT_CHARPOS (it), it.stop_charpos);
/* More than one display element may be returned for PT - 1 if
(i) it's a control character which is translated into `\003' or
implemented for X frames. The implementation uses updated_window
and updated_row. */
updated_row = glyph_row;
+ updated_area = TEXT_AREA;
update_begin (f);
if (rif)
{
{
struct glyph_row *row, *end;
struct glyph_row *mode_line_row;
- struct glyph_row *header_line_row = NULL;
+ struct glyph_row *header_line_row;
int yb, changed_p = 0, mouse_face_overwritten_p = 0, n_updated;
rif->update_window_begin_hook (w);
Adjust y-positions of other rows by the top line height. */
row = desired_matrix->rows;
end = row + desired_matrix->nrows - 1;
+
if (row->mode_line_p)
- header_line_row = row++;
+ {
+ header_line_row = row;
+ ++row;
+ }
+ else
+ header_line_row = NULL;
/* Update the mode line, if necessary. */
mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
goto set_cursor;
}
else if (rc > 0)
+ /* We've scrolled the display. */
force_p = 1;
changed_p = 1;
}
strcpy (w->current_matrix->method, w->desired_matrix->method);
#endif
- /* End of update of window W. */
- rif->update_window_end_hook (w, 1, 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. */
+ rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
}
else
paused_p = 1;
int yb = window_text_bottom_y (w);
last_row = NULL;
- for (row = MATRIX_ROW (w->current_matrix, 0);
- row->enabled_p;
- ++row)
+ 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;
-
- if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
- break;
+ ++row;
}
if (last_row)
{
- struct glyph *start = row->glyphs[TEXT_AREA];
- struct glyph *last = start + row->used[TEXT_AREA] - 1;
+ struct glyph *start = last_row->glyphs[TEXT_AREA];
+ struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
while (last > start && last->charpos < 0)
--last;
***********************************************************************/
DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
- 1, 1, "FOpen termscript file: ",
- "Start writing all terminal output to FILE as well as the terminal.\n\
-FILE = nil means just close any termscript file currently open.")
- (file)
+ 1, 1, "FOpen termscript file: ",
+ /* Start writing all terminal output to FILE as well as the terminal.
+FILE = nil means just close any termscript file currently open. */
+ (file))
Lisp_Object file;
{
if (termscript != 0) fclose (termscript);
DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
- Ssend_string_to_terminal, 1, 1, 0,
- "Send STRING to the terminal without alteration.\n\
-Control characters in STRING will have terminal-dependent effects.")
- (string)
+ Ssend_string_to_terminal, 1, 1, 0,
+ /* Send STRING to the terminal without alteration.
+Control characters in STRING will have terminal-dependent effects. */
+ (string))
Lisp_Object string;
{
/* ??? Perhaps we should do something special for multibyte strings here. */
DEFUN ("ding", Fding, Sding, 0, 1, 0,
- "Beep, or flash the screen.\n\
-Also, unless an argument is given,\n\
-terminate any keyboard macro currently executing.")
- (arg)
+ /* Beep, or flash the screen.
+Also, unless an argument is given,
+terminate any keyboard macro currently executing. */
+ (arg))
Lisp_Object arg;
{
if (!NILP (arg))
***********************************************************************/
DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
- "Pause, without updating display, for SECONDS seconds.\n\
-SECONDS may be a floating-point value, meaning that you can wait for a\n\
-fraction of a second. Optional second arg MILLISECONDS specifies an\n\
-additional wait period, in milliseconds; this may be useful if your\n\
-Emacs was built without floating point support.\n\
-\(Not all operating systems support waiting for a fraction of a second.)")
- (seconds, milliseconds)
+ /* 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.
+\(Not all operating systems support waiting for a fraction of a second. */
+ (seconds, milliseconds))
Lisp_Object seconds, milliseconds;
{
int sec, usec;
DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
- "Perform redisplay, then wait for SECONDS seconds or until input is available.\n\
-SECONDS may be a floating-point value, meaning that you can wait for a\n\
-fraction of a second. Optional second arg MILLISECONDS specifies an\n\
-additional wait period, in milliseconds; this may be useful if your\n\
-Emacs was built without floating point support.\n\
-\(Not all operating systems support waiting for a fraction of a second.)\n\
-Optional third arg NODISP non-nil means don't redisplay, just wait for input.\n\
-Redisplay is preempted as always if input arrives, and does not happen\n\
-if input is available before it starts.\n\
-Value is t if waited the full time with no input arriving.")
- (seconds, milliseconds, nodisp)
+ /* Perform redisplay, then wait for SECONDS seconds or until input is available.
+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.
+\(Not all operating systems support waiting for a fraction of a second.)
+Optional third arg NODISP non-nil means don't redisplay, just wait for input.
+Redisplay is preempted as always if input arrives, and does not happen
+if input is available before it starts.
+Value is t if waited the full time with no input arriving. */
+ (seconds, milliseconds, nodisp))
Lisp_Object seconds, milliseconds, nodisp;
{
int sec, usec;
DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
- Sframe_or_buffer_changed_p, 0, 0, 0,
- "Return non-nil if the frame and buffer state appears to have changed.\n\
-The state variable is an internal vector containing all frames and buffers,\n\
-aside from buffers whose names start with space,\n\
-along with the buffers' read-only and modified flags, which allows a fast\n\
-check to see whether the menu bars might need to be recomputed.\n\
-If this function returns non-nil, it updates the internal vector to reflect\n\
-the current state.\n")
- ()
+ Sframe_or_buffer_changed_p, 0, 0, 0,
+ /* Return non-nil if the frame and buffer state appears to have changed.
+The state variable is an internal vector containing all frames and buffers,
+aside from buffers whose names start with space,
+along with the buffers' read-only and modified flags, which allows a fast
+check to see whether the menu bars might need to be recomputed.
+If this function returns non-nil, it updates the internal vector to reflect
+the current state. */
+ ())
{
Lisp_Object tail, frame, buf;
Lisp_Object *vecp;
DEFUN ("internal-show-cursor", Finternal_show_cursor,
Sinternal_show_cursor, 2, 2, 0,
- "Set the cursor-visibility flag of WINDOW to SHOW.\n\
-WINDOW nil means use the selected window. SHOW non-nil means\n\
-show a cursor in WINDOW in the next redisplay. SHOW nil means\n\
-don't show a cursor.")
- (window, show)
+ /* Set the cursor-visibility flag of WINDOW to SHOW.
+WINDOW nil means use the selected window. SHOW non-nil means
+show a cursor in WINDOW in the next redisplay. SHOW nil means
+don't show a cursor. */
+ (window, show))
Lisp_Object window, show;
{
/* Don't change cursor state while redisplaying. This could confuse
DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
Sinternal_show_cursor_p, 0, 1, 0,
- "Value is non-nil if next redisplay will display a cursor in WINDOW.\n\
-WINDOW nil or omitted means report on the selected window.")
- (window)
+ /* Value is non-nil if next redisplay will display a cursor in WINDOW.
+WINDOW nil or omitted means report on the selected window. */
+ (window))
Lisp_Object window;
{
struct window *w;
Qredisplay_dont_pause = intern ("redisplay-dont-pause");
staticpro (&Qredisplay_dont_pause);
- DEFVAR_INT ("baud-rate", &baud_rate,
- "*The output baud rate of the terminal.\n\
-On most systems, changing this value will affect the amount of padding\n\
-and the other strategic decisions made during redisplay.");
+ DEFVAR_INT ("baud-rate", &baud_rate
+ /* *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,
- "*Non-nil means invert the entire frame display.\n\
-This means everything is in inverse video which otherwise would not be.");
+ DEFVAR_BOOL ("inverse-video", &inverse_video
+ /* *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,
- "*Non-nil means try to flash the frame to represent a bell.");
+ DEFVAR_BOOL ("visible-bell", &visible_bell
+ /* *Non-nil means try to flash the frame to represent a bell. */);
- DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter,
- "*Non-nil means no need to redraw entire frame after suspending.\n\
-A non-nil value is useful if the terminal can automatically preserve\n\
-Emacs's frame display when you reenter Emacs.\n\
-It is up to you to set this variable if your terminal can do that.");
+ DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter
+ /* *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. */);
- DEFVAR_LISP ("window-system", &Vwindow_system,
- "A symbol naming the window-system under which Emacs is running\n\
-\(such as `x'), or nil if emacs is running on an ordinary terminal.");
+ DEFVAR_LISP ("window-system", &Vwindow_system
+ /* A symbol naming the window-system under which Emacs is running
+\(such as `x'), or nil if emacs is running on an ordinary terminal. */);
- DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
- "The version number of the window system in use.\n\
-For X windows, this is 10 or 11.");
+ DEFVAR_LISP ("window-system-version", &Vwindow_system_version
+ /* The version number of the window system in use.
+For X windows, this is 10 or 11. */);
- DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area,
- "Non-nil means put cursor in minibuffer, at end of any message there.");
+ DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area
+ /* Non-nil means put cursor in minibuffer, at end of any message there. */);
- DEFVAR_LISP ("glyph-table", &Vglyph_table,
- "Table defining how to output a glyph code to the frame.\n\
-If not nil, this is a vector indexed by glyph code to define the glyph.\n\
-Each element can be:\n\
- integer: a glyph code which this glyph is an alias for.\n\
- string: output this glyph using that string (not impl. in X windows).\n\
- nil: this glyph mod 524288 is the code of a character to output,\n\
- and this glyph / 524288 is the face number (see `face-id') to use\n\
- while outputting it.");
+ DEFVAR_LISP ("glyph-table", &Vglyph_table
+ /* Table defining how to output a glyph code to the frame.
+If not nil, this is a vector indexed by glyph code to define the glyph.
+Each element can be:
+ integer: a glyph code which this glyph is an alias for.
+ string: output this glyph using that string (not impl. in X windows).
+ nil: this glyph mod 524288 is the code of a character to output,
+ and this glyph / 524288 is the face number (see `face-id') to use
+ while outputting it. */);
Vglyph_table = Qnil;
- DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,
- "Display table to use for buffers that specify none.\n\
-See `buffer-display-table' for more information.");
+ DEFVAR_LISP ("standard-display-table", &Vstandard_display_table
+ /* Display table to use for buffers that specify none.
+See `buffer-display-table' for more information. */);
Vstandard_display_table = Qnil;
- DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause,
- "*Non-nil means update isn't paused when input is detected.");
+ DEFVAR_BOOL ("redisplay-dont-pause", &redisplay_dont_pause
+ /* *Non-nil means update isn't paused when input is detected. */);
redisplay_dont_pause = 0;
/* Initialize `window-system', unless init_display already decided it. */