#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
-/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
-
-#include "systime.h"
#include <errno.h>
#include <fpending.h>
+#include <timespec.h>
#if defined (HAVE_TERM_H) && defined (GNU_LINUX)
#include <term.h> /* for tgetent */
static bool delayed_size_change;
-/* Glyph row updated in update_window_line, and area that is updated. */
-
-struct glyph_row *updated_row;
-int updated_area;
-
/* A glyph for a space. */
struct glyph space_glyph;
/* Return the number of glyphs to reserve for a marginal area of
window W. TOTAL_GLYPHS is the number of glyphs in a complete
display line of window W. MARGIN gives the width of the marginal
- area in canonical character units. MARGIN should be an integer
- or a float. */
+ area in canonical character units. */
static int
-margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin)
+margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin)
{
- int n;
-
- if (NUMBERP (margin))
+ if (margin > 0)
{
int width = w->total_cols;
- double d = max (0, XFLOATINT (margin));
+ double d = max (0, margin);
d = min (width / 2 - 1, d);
- n = (int) ((double) total_glyphs / width * d);
+ return (int) ((double) total_glyphs / width * d);
}
- else
- n = 0;
-
- return n;
+ return 0;
}
/* Return true if ROW's hash value is correct.
Get W's size. */
if (w)
{
- window_box (w, -1, 0, 0, &window_width, &window_height);
+ window_box (w, ANY_AREA, 0, 0, &window_width, &window_height);
header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
header_line_changed_p = header_line_p != matrix->header_line_p;
/* Window end is invalid, if inside of the rows that
are invalidated below. */
- if (INTEGERP (w->window_end_vpos)
- && XFASTINT (w->window_end_vpos) >= i)
+ if (w->window_end_vpos >= i)
w->window_end_valid = 0;
while (i < matrix->nrows)
if (showing_window_margins_p (XWINDOW (w->contents)))
return 1;
}
- else if (!NILP (w->left_margin_cols) || !NILP (w->right_margin_cols))
+ else if (w->left_margin_cols > 0 || w->right_margin_cols > 0)
return 1;
w = NILP (w->next) ? 0 : XWINDOW (w->next);
/* Save away the contents of frame F's current frame matrix. Value is
a glyph matrix holding the contents of F's current frame matrix. */
-static struct glyph_matrix *
+struct glyph_matrix *
save_current_matrix (struct frame *f)
{
int i;
struct glyph_row *from = f->current_matrix->rows + i;
struct glyph_row *to = saved->rows + i;
ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+
to->glyphs[TEXT_AREA] = xmalloc (nbytes);
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
+ to->enabled_p = from->enabled_p;
+ to->hash = from->hash;
+ if (from->used[LEFT_MARGIN_AREA])
+ {
+ nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+ to->glyphs[LEFT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+ memcpy (to->glyphs[LEFT_MARGIN_AREA],
+ from->glyphs[LEFT_MARGIN_AREA], nbytes);
+ to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+ }
+ if (from->used[RIGHT_MARGIN_AREA])
+ {
+ nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+ to->glyphs[RIGHT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes);
+ memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+ from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+ to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+ }
}
return saved;
struct glyph_row *from = saved->rows + i;
struct glyph_row *to = f->current_matrix->rows + i;
ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
xfree (from->glyphs[TEXT_AREA]);
+ nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
+ if (nbytes)
+ {
+ memcpy (to->glyphs[LEFT_MARGIN_AREA],
+ from->glyphs[LEFT_MARGIN_AREA], nbytes);
+ to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
+ xfree (from->glyphs[LEFT_MARGIN_AREA]);
+ }
+ else
+ to->used[LEFT_MARGIN_AREA] = 0;
+ nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
+ if (nbytes)
+ {
+ memcpy (to->glyphs[RIGHT_MARGIN_AREA],
+ from->glyphs[RIGHT_MARGIN_AREA], nbytes);
+ to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
+ xfree (from->glyphs[RIGHT_MARGIN_AREA]);
+ }
+ else
+ to->used[RIGHT_MARGIN_AREA] = 0;
}
xfree (saved->rows);
return paused_p;
}
+/* Update a TTY frame F that has a menu dropped down over some of its
+ glyphs. This is like the second part of update_frame, but it
+ doesn't call build_frame_matrix, because we already have the
+ desired matrix prepared, and don't want it to be overwritten by the
+ text of the normal display. */
+void
+update_frame_with_menu (struct frame *f)
+{
+ struct window *root_window = XWINDOW (f->root_window);
+ bool paused_p;
+
+ eassert (FRAME_TERMCAP_P (f));
+
+ /* We are working on frame matrix basis. Set the frame on whose
+ frame matrix we operate. */
+ set_frame_matrix_frame (f);
+
+ /* Update the display */
+ update_begin (f);
+ /* Force update_frame_1 not to stop due to pending input, and not
+ try scrolling. */
+ paused_p = update_frame_1 (f, 1, 1);
+ update_end (f);
+
+ if (FRAME_TTY (f)->termscript)
+ fflush (FRAME_TTY (f)->termscript);
+ fflush (FRAME_TTY (f)->output);
+ /* Check window matrices for lost pointers. */
+#if GLYPH_DEBUG
+#if 0
+ /* We cannot possibly survive the matrix pointers check, since
+ we have overwritten parts of the frame glyph matrix without
+ making any updates to the window matrices. */
+ check_window_matrix_pointers (root_window);
+#endif
+ add_frame_display_history (f, paused_p);
+#endif
+
+ /* Reset flags indicating that a window should be updated. */
+ set_window_update_flags (root_window, 0);
+}
\f
/************************************************************************
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
{
- updated_row = row;
- updated_area = area;
- FRAME_RIF (f)->cursor_to (w, i, 0, row->y,
- area == TEXT_AREA ? row->x : 0);
+ output_cursor_to (w, i, 0, row->y,
+ area == TEXT_AREA ? row->x : 0);
if (row->used[area])
- FRAME_RIF (f)->write_glyphs (w, row->glyphs[area],
- row->used[area]);
- FRAME_RIF (f)->clear_end_of_line (w, -1);
+ FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area],
+ area, row->used[area]);
+ FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
}
row->overlapped_p = 0;
/* End the update of window W. Don't set the cursor if we
paused updating the display because in this case,
set_window_cursor_after_update hasn't been called, and
- output_cursor doesn't contain the cursor location. */
+ W->output_cursor doesn't contain the cursor location. */
rif->update_window_end_hook (w, !paused_p, mouse_face_overwritten_p);
}
else
AREA can be either LEFT_MARGIN_AREA or RIGHT_MARGIN_AREA. */
static void
-update_marginal_area (struct window *w, int area, int vpos)
+update_marginal_area (struct window *w, struct glyph_row *updated_row,
+ enum glyph_row_area area, int vpos)
{
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
- /* Let functions in xterm.c know what area subsequent X positions
- will be relative to. */
- updated_area = area;
-
/* Set cursor to start of glyphs, write them, and clear to the end
of the area. I don't think that something more sophisticated is
necessary here, since marginal areas will not be the default. */
- rif->cursor_to (w, vpos, 0, desired_row->y, 0);
+ output_cursor_to (w, vpos, 0, desired_row->y, 0);
if (desired_row->used[area])
- rif->write_glyphs (w, desired_row->glyphs[area], desired_row->used[area]);
- rif->clear_end_of_line (w, -1);
+ rif->write_glyphs (w, updated_row, desired_row->glyphs[area],
+ area, desired_row->used[area]);
+ rif->clear_end_of_line (w, updated_row, area, -1);
}
Value is true if display has changed. */
static bool
-update_text_area (struct window *w, int vpos)
+update_text_area (struct window *w, struct glyph_row *updated_row, int vpos)
{
struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
bool changed_p = 0;
- /* Let functions in xterm.c know what area subsequent X positions
- will be relative to. */
- updated_area = TEXT_AREA;
-
/* If rows are at different X or Y, or rows have different height,
or the current row is marked invalid, write the entire line. */
if (!current_row->enabled_p
&& !(current_row->mode_line_p && vpos > 0))
|| current_row->x != desired_row->x)
{
- rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
+ output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
if (desired_row->used[TEXT_AREA])
- rif->write_glyphs (w, desired_row->glyphs[TEXT_AREA],
- desired_row->used[TEXT_AREA]);
+ rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA],
+ TEXT_AREA, desired_row->used[TEXT_AREA]);
/* Clear to end of window. */
- rif->clear_end_of_line (w, -1);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
changed_p = 1;
/* This erases the cursor. We do this here because
break;
}
- rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
- rif->write_glyphs (w, start, i - start_hpos);
+ output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
+ rif->write_glyphs (w, updated_row, start,
+ TEXT_AREA, i - start_hpos);
changed_p = 1;
}
}
/* Write the rest. */
if (i < desired_row->used[TEXT_AREA])
{
- rif->cursor_to (w, vpos, i, desired_row->y, x);
- rif->write_glyphs (w, desired_glyph, desired_row->used[TEXT_AREA] - i);
+ output_cursor_to (w, vpos, i, desired_row->y, x);
+ rif->write_glyphs (w, updated_row, desired_glyph,
+ TEXT_AREA, desired_row->used[TEXT_AREA] - i);
changed_p = 1;
}
{
/* If old row extends to the end of the text area, clear. */
if (i >= desired_row->used[TEXT_AREA])
- rif->cursor_to (w, vpos, i, desired_row->y,
- desired_row->pixel_width);
- rif->clear_end_of_line (w, -1);
+ output_cursor_to (w, vpos, i, desired_row->y,
+ desired_row->pixel_width);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
changed_p = 1;
}
else if (desired_row->pixel_width < current_row->pixel_width)
int xlim;
if (i >= desired_row->used[TEXT_AREA])
- rif->cursor_to (w, vpos, i, desired_row->y,
- desired_row->pixel_width);
+ output_cursor_to (w, vpos, i, desired_row->y,
+ desired_row->pixel_width);
/* If cursor is displayed at the end of the line, make sure
it's cleared. Nowadays we don't have a phys_cursor_glyph
}
else
xlim = current_row->pixel_width;
- rif->clear_end_of_line (w, xlim);
+ rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
changed_p = 1;
}
}
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
bool changed_p = 0;
- /* Set the row being updated. This is important to let xterm.c
- know what line height values are in effect. */
- updated_row = desired_row;
-
/* A row can be completely invisible in case a desired matrix was
built with a vscroll and then make_cursor_line_fully_visible shifts
the matrix. Make sure to make such rows current anyway, since
eassert (desired_row->enabled_p);
/* Update display of the left margin area, if there is one. */
- if (!desired_row->full_width_p
- && !NILP (w->left_margin_cols))
+ if (!desired_row->full_width_p && w->left_margin_cols > 0)
{
changed_p = 1;
- update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
+ update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
/* Setting this flag will ensure the vertical border, if
any, between this window and the one on its left will be
redrawn. This is necessary because updating the left
}
/* Update the display of the text area. */
- if (update_text_area (w, vpos))
+ if (update_text_area (w, desired_row, vpos))
{
changed_p = 1;
if (current_row->mouse_face_p)
}
/* Update display of the right margin area, if there is one. */
- if (!desired_row->full_width_p
- && !NILP (w->right_margin_cols))
+ if (!desired_row->full_width_p && w->right_margin_cols > 0)
{
changed_p = 1;
- update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
+ update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
}
/* Draw truncation marks etc. */
/* Update current_row from desired_row. */
make_current (w->desired_matrix, w->current_matrix, vpos);
- updated_row = NULL;
return changed_p;
}
set_window_cursor_after_update (struct window *w)
{
struct frame *f = XFRAME (w->frame);
- struct redisplay_interface *rif = FRAME_RIF (f);
int cx, cy, vpos, hpos;
/* Not intended for frame matrix updates. */
Horizontal position is -1 when cursor is on the left fringe. */
hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
- rif->cursor_to (w, vpos, hpos, cy, cx);
+ output_cursor_to (w, vpos, hpos, cy, cx);
}
int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
- if (INTEGERP (w->left_margin_cols))
- x += XFASTINT (w->left_margin_cols);
-
- /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
+ x += max (0, w->left_margin_cols);
cursor_to (f, y, x);
}
}
wrong thing with `face-remapping-alist' (bug#2044). */
Fset_buffer (w->contents);
itdata = bidi_shelve_cache ();
- SET_TEXT_POS_FROM_MARKER (startp, w->start);
- CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
- BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
+ CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
start_display (&it, w, startp);
/* start_display takes into account the header-line row, but IT's
vpos still counts from the glyph row that includes the window's
if (duration > 0)
{
- EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
- wait_reading_process_output (min (EMACS_SECS (t), WAIT_READING_MAX),
- EMACS_NSECS (t), 0, 0, Qnil, NULL, 0);
+ struct timespec t = dtotimespec (duration);
+ wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX),
+ t.tv_nsec, 0, 0, Qnil, NULL, 0);
}
return Qnil;
return Qt;
else
{
- EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
- sec = min (EMACS_SECS (t), WAIT_READING_MAX);
- nsec = EMACS_NSECS (t);
+ struct timespec t = dtotimespec (seconds);
+ sec = min (t.tv_sec, WAIT_READING_MAX);
+ nsec = t.tv_nsec;
}
}
else if (EQ (timeout, Qt))
{
return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
}
-
-DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
- Slast_nonminibuf_frame, 0, 0, 0,
- doc: /* Value is last nonminibuffer frame. */)
- (void)
-{
- Lisp_Object frame = Qnil;
-
- if (last_nonminibuf_frame)
- XSETFRAME (frame, last_nonminibuf_frame);
-
- return frame;
-}
\f
/***********************************************************************
Initialization
defsubr (&Ssend_string_to_terminal);
defsubr (&Sinternal_show_cursor);
defsubr (&Sinternal_show_cursor_p);
- defsubr (&Slast_nonminibuf_frame);
#ifdef GLYPH_DEBUG
defsubr (&Sdump_redisplay_history);